ImageEn for Delphi and C++ Builder ImageEn for Delphi and C++ Builder
ImageEn Forum
Profile    Join    Active Topics    Forum FAQ    Search this forumSearch
Forum membership is Free!  Click Join to sign-up
Username:
Password:
Save Password
Forgot your Password?

 All Forums
 ImageEn Library for Delphi, C++ and .Net
 ImageEn and IEvolution Support Forum
 Replace color in whole image?
 New Topic  Reply to Topic
 Printer Friendly
Author Previous Topic Topic Next Topic  

PeterPanino

496 Posts

Posted - Apr 15 2021 :  14:41:12  Show Profile  Reply
Which is the best/fastest method to replace explicitly a specific color in the WHOLE image, using a custom TOLERANCE?

I have tried the \Demos\ImageAnalysis\Palette demo. It works, but it has no way to set a tolerance.

Would I have to scan all pixels in the image and check whether a pixel's color is in the range of tolerance and then change its color, or is there a BUILT-IN function for this purpose in ImageEn?

The concept of "Tolerance" in this context has to be better defined:
Using the HSL color model, Tolerance could be defined as:
Hue tolerance
Saturation tolerance
Lightness tolerance

This means that a function that replaces a color should have these parameters:

procedure TformMain.ReplaceColor(aSourceColor, aTargetColor: TColor; AHueTolerance, ASatTolerance, ALumTolerance: Integer);
begin
  for each Pixel in AllImagePixels do
  begin
    if ((Pixel.Hue - aSourceColor.Hue) < AHueTolerance) and ((Pixel.Sat - aSourceColor.Sat) < ASatTolerance) and ((Pixel.Lum - aSourceColor.Lum) < ALumTolerance) then
      Pixel.Color := aTargetColor;
  end;
end;


Is this pseudo-code logical?

What do you think?

PeterPanino

496 Posts

Posted - Apr 16 2021 :  06:20:36  Show Profile  Reply
A completely different approach would be TImageEnProc.CastColorRange, for example:

procedure TForm1.btnTestClick(Sender: TObject);
const
  T = 10; // tolerance value
var
  rgb: TRGB;
begin
  rgb := TColor2TRGB( $00FEFE ); // this is a color in the image
  imgTest.Proc.CastColorRange(
    TRGB2TColor(CreateRGB(rgb.r + T, rgb.g + T, rgb.b + T)), // BeginColor
    TRGB2TColor(CreateRGB(rgb.r - T, rgb.g - T, rgb.b - T)), // EndColor
    clRed); // CastColor
end;


Would that be a viable option?
Go to Top of Page

PeterPanino

496 Posts

Posted - Apr 16 2021 :  06:49:06  Show Profile  Reply
The best results until now I had with this function:

procedure TForm1.btnTestClick(Sender: TObject);
const
  T = 10; // tolerance value
var
  H, S, V: Integer;
begin
  ColorToHSV($0001FD, H, S, V); // this is a color in the image

  imgTest.Proc.CastColorRange(
    HSVToColor(H, S + T, V - T), // BeginColor
    HSVToColor(H, S - T, V + T), // EndColor
    clBlue); // CastColor
end;
Go to Top of Page

xequte

6040 Posts

Posted - Apr 16 2021 :  18:24:05  Show Profile  Reply
Hi Peter

That should work well enough. You could also write a routine to iterate the scanlines. That is quite straightforward:

https://www.imageen.com/help/TIEBitmap.ScanLine.html

Nigel
Xequte Software
www.imageen.com
Go to Top of Page

PeterPanino

496 Posts

Posted - Apr 17 2021 :  09:29:15  Show Profile  Reply
I invite you all to run my ReplaceColorTest demo project and tell me any bugs and suggestions:



attach/PeterPanino/202141792839_ReplaceColorTest.zip
95.34 KB
Go to Top of Page

PeterPanino

496 Posts

Posted - Apr 17 2021 :  13:18:41  Show Profile  Reply
I made some interesting color experiments with this demo, for example:

Go to Top of Page

xequte

6040 Posts

Posted - Apr 20 2021 :  01:59:36  Show Profile  Reply
That works nicely. It is similar to chromakey (green screen) removal.

Nigel
Xequte Software
www.imageen.com
Go to Top of Page
  Previous Topic Topic Next Topic  
 New Topic  Reply to Topic
 Printer Friendly
Jump To: