Recent

Author Topic: [SOLVED] Average color  (Read 664 times)

BubikolRamios

  • Sr. Member
  • ****
  • Posts: 380
[SOLVED] Average color
« on: January 10, 2026, 11:13:54 pm »
So, doing same as https://stackoverflow.com/questions/7722281/get-average-color-of-an-image, which is not solved, and getting same thing, not what I expect.
Expected would be , calc avg of r,g,b of forinstance white pixel and red pixel and get bright red. How to do that ?

like +/-, does not do expected
(if I find white pixel that is not surrounded by white, calc avg of +- 2px horizontaly including central white)

Code: Pascal  [Select][+][-]
  1. r1 := 0; g1:= 0; b1 := 0;
  2.             for i :=(0-floor(StrToInt(HorizontalSmoothingEdit.text)/2)) to floor(StrToInt(HorizontalSmoothingEdit.text)/2) do
  3.             begin
  4.  
  5.  
  6.                  RedGreenBlue(image.Canvas.Pixels[x+i,y],r,g,b);
  7.                  r1 := r1 + r;
  8.                  g1 := g1 + g;
  9.                  b1 := b1 + b;
  10.            end;
  11.  
  12.            r1 := round(r1/ StrToInt(HorizontalSmoothingEdit.text));
  13.            g1 := round(g1/StrToInt(HorizontalSmoothingEdit.text));
  14.            b1 := round(b1/StrToInt(HorizontalSmoothingEdit.text));
  15.  
  16.            image1.Canvas.Pixels[x,y] :=  RGBToColor(r1,g1,b1);  
  17.  

« Last Edit: January 11, 2026, 07:25:50 am by BubikolRamios »
lazarus 3.2-fpc-3.2.2-win32/win64

LeP

  • Full Member
  • ***
  • Posts: 103
Re: Average color
« Reply #1 on: January 11, 2026, 12:07:14 am »
I think that is not the case.

The RGB space it's a simple representation.

Red is $0000FF;
White is $FFFFFF;

You cannot have a RED more bright then Red in the RGB representation ...
You must act in others color spaces (color planes).

jamie

  • Hero Member
  • *****
  • Posts: 7493
Re: Average color
« Reply #2 on: January 11, 2026, 12:42:09 am »
I don't know what you are using for variable types because that could overflow a Byte if that is what you are using for the R,G,B etc.

Turn on RangeCheck. and maybe show us the size of variables you are using for the summing.

Jamie
The only true wisdom is knowing you know nothing

wp

  • Hero Member
  • *****
  • Posts: 13336
Re: Average color
« Reply #3 on: January 11, 2026, 12:55:19 am »
Not carefully tested, but basically this should work:

Code: Pascal  [Select][+][-]
  1. uses
  2.   FPImage, IntfGraphics;
  3.  
  4. function AverageColor(ABitmap: TCustomBitmap): TColor;
  5. var
  6.   img: TLazIntfImage;
  7.   r, g, b: Integer;
  8.   c: TFPColor;
  9.   x, y, n: Integer;
  10. begin
  11.   r := 0;
  12.   g := 0;
  13.   b := 0;
  14.   img := ABitmap.CreateIntfImage;
  15.   try
  16.     for y := 0 to img.Height-1 do
  17.       for x := 0 to img.Width-1 do
  18.       begin
  19.         c := img.Colors[x, y];   // FPColor has 16 bits per channel
  20.         r := r + c.Red shr 8;    // --> remove the right-most 8 bits
  21.         g := g + c.Green shr 8;
  22.         b := b + c.Blue shr 8;
  23.       end;
  24.     n := img.Width * img.Height;
  25.     r := round(r / n);
  26.     g := round(g / n);
  27.     b := round(b / n);
  28.     Result := RGBToColor(r, g, b);
  29.   finally
  30.     img.Free;
  31.   end;
  32. end;  
« Last Edit: January 11, 2026, 01:16:00 am by wp »

BubikolRamios

  • Sr. Member
  • ****
  • Posts: 380
Re: Average color
« Reply #4 on: January 11, 2026, 07:22:14 am »
I don't know what you are using for variable types because that could overflow a Byte if that is what you are using for the R,G,B etc.

Turn on RangeCheck. and maybe show us the size of variables you are using for the summing.

Jamie

Jeah, that was it, overlooked, byte there should be integer
Code: Pascal  [Select][+][-]
  1.    r1: integer = 0;
  2.    g1: integer = 0;
  3.    b1: integer = 0;
  4.  

First result of 27 pixels wide horizontal averaging. Melting white lines into surrounding colors:

« Last Edit: January 11, 2026, 07:24:52 am by BubikolRamios »
lazarus 3.2-fpc-3.2.2-win32/win64

Thaddy

  • Hero Member
  • *****
  • Posts: 18711
  • To Europe: simply sell USA bonds: dollar collapses
Re: [SOLVED] Average color
« Reply #5 on: January 11, 2026, 02:35:51 pm »
Shouldn't the gray scales be weighted? I mean I remember the r, g and b values can't be treated as equal?
// cardinal prevents overflow, but needs a mask $ff00 or a shr 8 and $ff
Code: Pascal  [Select][+][-]
  1. function RGBToGray(R, G, B: Cardinal): Byte;
  2. begin
  3.   Result := (R * 299 + G * 587 + B * 114) div 1000;
  4. end;
Will add complete example later.

[edit]
I remembered right, but consulted Claude and CoPilot to confirm.
CoPilot suggested the same weights:
Code: Pascal  [Select][+][-]
  1. function RGBToGray(R, G, B: Cardinal): Byte;
  2. begin
  3.   Result := (R * 299 + G * 587 + B * 114) div 1000;
  4. end;
But that only works with rangechecks off...If that is not an objection.

« Last Edit: January 11, 2026, 02:58:55 pm by Thaddy »
If Europe sells their USA bonds the USD will collapse. Europe can affort that given average state debts. The USA can't affort that. Just an advice...

jamie

  • Hero Member
  • *****
  • Posts: 7493
Re: [SOLVED] Average color
« Reply #6 on: January 11, 2026, 03:49:12 pm »
an Exchange table works much faster!

Too bad FPC didn't have an intrinsic XCHG function that would compile down to a true ASM XCHG END instruction, it would make faster DSP and Graphics among other things.


Jamie
The only true wisdom is knowing you know nothing

Thaddy

  • Hero Member
  • *****
  • Posts: 18711
  • To Europe: simply sell USA bonds: dollar collapses
Re: [SOLVED] Average color
« Reply #7 on: January 11, 2026, 04:07:11 pm »
@Jamie

That does not in any way help the weight you have to apply for proper gray scale.
If Europe sells their USA bonds the USD will collapse. Europe can affort that given average state debts. The USA can't affort that. Just an advice...

Khrys

  • Sr. Member
  • ****
  • Posts: 383
Re: [SOLVED] Average color
« Reply #8 on: January 12, 2026, 08:09:26 am »
All this talk about about summing colors and only one reply even mentions color spaces?  :o

It doesn't make physical sense to directly add sRGB colors; if you don't take gamma into account, the result will be too dark (see the attached gradient comparison).

The (mostly) correct way would be to normalize each channel to the range 0.0 - 1.0, raise it to 2.2, calculate the average, undo the raising (e.g. by using 1 / 2.2 ≈ 0.4545 as the exponent) and finally scale back to 0 - 255. Much more computationally expensive of course, so you'll need to decide if the quality improvement is worth it.

TL;DR: Please linearize your colors before doing math on them  :P

Nimbus

  • Jr. Member
  • **
  • Posts: 80
Re: [SOLVED] Average color
« Reply #9 on: January 12, 2026, 09:36:38 am »
A bit of minutephysics on the matters

https://www.youtube.com/watch?v=LKnqECcg6Gw

BubikolRamios

  • Sr. Member
  • ****
  • Posts: 380
Re: [SOLVED] Average color
« Reply #10 on: January 12, 2026, 06:30:50 pm »
lazarus 3.2-fpc-3.2.2-win32/win64

LeP

  • Full Member
  • ***
  • Posts: 103
Re: [SOLVED] Average color
« Reply #11 on: January 12, 2026, 06:51:24 pm »
If you are interested (or anyone else), this is an old documentation (still valid) from Halcon (MvTec product).

https://www.mvtec.com/doc/halcon/13/en/trans_from_rgb.html

You can go around to find what you need: https://www.mvtec.com/products/halcon/work-with-halcon/documentation#c16422

Of course most of documentation is about Halcon, but there are plenty of usefull inofmations there.

 

TinyPortal © 2005-2018