Author |
Topic  |
|
Dudskoni
4 Posts |
Posted - Oct 28 2012 : 15:21:35
|
I am using the following function to find the difference between two colors defined in Lab. The problem is that I am getting intermittently the error “Invalid floating point operation” error when using this function. I am sure there is no sqrt of negative number or division by zero. What is going on? Is there a better way of doing this using Imageen? thanks function find_difference(lab1, lab2: array of Extended) : Extended; var _c1,_c2,_dc,_dl,_da,_db,_dh,_first,_second,_third : Extended; begin _c1 := sqrt(sqr(lab1[1])+sqr(lab1[2])); _c2 := sqrt(sqr(lab2[1])+sqr(lab2[2])); _dc := (_c1)-(_c2); _dl := lab1[0]-lab2[0]; _da := lab1[1]-lab2[1]; _db := lab1[2]-lab2[2]; _dh := sqrt(sqr(_da)+sqr(_db)-sqr(_dc)); _first := _dl; _second := _dc/(1+0.045*_c1); _third := _dh/(1+0.015*_c1); result := sqrt(sqr(_first)+sqr(_second)+sqr(_third)); end;
reference: CIE94 - http://en.wikipedia.org/wiki/Color_difference#CIE76
|
|
w2m
   
USA
1990 Posts |
Posted - Oct 28 2012 : 17:57:32
|
I am not an expert with respect to colors.... but show us how you are adding the color values to Lab1 and Lab2. That may be the problem and not the function. When I run the function on Delphi 2010 here, I do not get any exceptions, but the result for the colors I selected returned a color difference of 0.
procedure TFormColorDifference.cxButton1Click(Sender: TObject); var iColorDifference: Extended; begin FLab1[0] := Color1.ColorValue; FLab1[1] := Color3.ColorValue; FLab2[2] := Color5.ColorValue; FLab2[0] := Color2.ColorValue; FLab2[1] := Color4.ColorValue; FLab2[1] := Color6.ColorValue; iColorDifference := FindColorDifference(FLab1, FLab1); LabelColorDifference1.Caption := 'Color Difference: ' + FloatToStr(iColorDifference); end;
William Miller Email: w2m@frontiernet.net EBook: http://www.imageen.com/ebook/ Apprehend: http://www.frontiernet.net/~w2m/index.html |
 |
|
Dudskoni
4 Posts |
Posted - Oct 29 2012 : 15:02:41
|
Dear William
Thanks for your kind assistance. This is the way I call this funcion in the main. The program works fine with the black and white part but when I add the orange and other colors the error comes up. First I know there is no need to a for loop for each color but this is something I've tried. I am no expert in Delphi so I am in trial error process now.
/////loop for black color for i:= ImageEnView1.SelY1 to ImageEnView1.SelY2 do for j:= ImageEnView1.SelX1 to ImageEnView1.SelX2 do if ImageEnView1.isPointinsideSelection(j, i) then begin color := ImageEnView1.IEBitmap.Pixels[j,i]; lab2[0] := rgbtolab(color)[0]; lab2[1] := rgbtolab(color)[1]; lab2[2] := rgbtolab(color)[2];
//black definition lab1[0] := 0; lab1[1] := 0; lab1[2] := 0; difference := find_difference(lab1, lab2); if (difference < 20) then begin inc(black); ImageEnview1.IEBitmap.pixels_ie24RGB[j, i] := CreateRGB(0, 0, 0); end; end; ///// end loop color black
////loop for white color for i:= ImageEnView1.SelY1 to ImageEnView1.SelY2 do for j:= ImageEnView1.SelX1 to ImageEnView1.SelX2 do if ImageEnView1.isPointinsideSelection(j, i) then begin color := ImageEnView1.IEBitmap.Pixels[j,i]; lab4[0] := rgbtolab(color)[0]; lab4[1] := rgbtolab(color)[1]; lab4[2] := rgbtolab(color)[2];
//White definition lab3[0] := 100; lab3[1] := 1; lab3[2] := 1; difference := find_difference(lab3, lab4); if (difference < 20) then begin inc(white); ImageEnview1.IEBitmap.pixels_ie24RGB[j, i] := CreateRGB(255, 255, 255); end; end; //// end loop white color
////loop for orange color for i:= ImageEnView1.SelY1 to ImageEnView1.SelY2 do for j:= ImageEnView1.SelX1 to ImageEnView1.SelX2 do if ImageEnView1.isPointinsideSelection(j, i) then begin color := ImageEnView1.IEBitmap.Pixels[j,i]; lab6[0]:= rgbtolab(color)[0]; lab6[1] := rgbtolab(color)[1]; lab6[2] := rgbtolab(color)[2];
//Orange definition lab5[0] := 67; lab5[1] := 43; lab5[2] := 74;
difference := find_difference(lab5, lab6); if (difference < 20) then begin inc(orange); ImageEnview1.IEBitmap.pixels_ie24RGB[j, i] := CreateRGB(255, 128, 0); end; end; //// end loop orange
This is the rgbtolab funcion:
function rgbtolab (RGBparaconveter: TRGB) : tdoublearray; var _RGBToFind_r, _RGBToFind_g, _RGBToFind_b, _x, _y, _z, _l,_a,_b : double; begin _RGBToFind_r := RGBparaconveter.r / 255; _RGBToFind_g := RGBparaconveter.g / 255; _RGBToFind_b := RGBparaconveter.b / 255;
// adjusting values if(_RGBToFind_r > 0.04045) then begin _RGBToFind_r := (_RGBToFind_r+0.055)/1.055; _RGBToFind_r := Power(_RGBToFind_r,2.4); end else _RGBToFind_r := _RGBToFind_r / 12.92;
if(_RGBToFind_g > 0.04045) then begin _RGBToFind_g := (_RGBToFind_g+0.055) / 1.055; _RGBToFind_g := Power(_RGBToFind_g,2.4); end else _RGBToFind_g := _RGBToFind_g / 12.92;
if (_RGBToFind_b>0.04045) then begin _RGBToFind_b := (_RGBToFind_b+0.055) / 1.055; _RGBToFind_b := Power(_RGBToFind_b,2.4); end else _RGBToFind_b := _RGBToFind_b / 12.92;
_RGBToFind_r := _RGBToFind_r*100; _RGBToFind_g := _RGBToFind_g*100; _RGBToFind_b := _RGBToFind_b*100;
_x := (_RGBToFind_r * 0.4124 + _RGBToFind_g * 0.3576 + _RGBToFind_b * 0.1805)/95.047; _y := (_RGBToFind_r * 0.2126 + _RGBToFind_g * 0.7152 + _RGBToFind_b * 0.0722)/100; _z := (_RGBToFind_r * 0.0193 + _RGBToFind_g * 0.1192 + _RGBToFind_b * 0.9505)/108.883;
if (_x>0.008856) then begin _x := power(_x,1/3); end else _x := (7.787*_x) + (16/116);
if (_y>0.008856) then begin _y := power(_y,1/3); end else _y := (7.787*_y) + (16/116);
if (_z>0.008856) then begin _z := power(_z,1/3); end else _z := (7.787*_z) + (16/116);
_l:= (116*_y) -16; _a:= 500*(_x-_y); _b:= 200*(_y-_z);
result[0] := round(_l); result[1] := round(_a); result[2] := round(_b); end;
|
 |
|
|
Topic  |
|
|
|