ImageEn for Delphi and C++ Builder ImageEn for Delphi and C++ Builder

 

ImageEn Forum
Profile    Join    Active Topics    Forum FAQ    Search this forumSearch
 All Forums
 ImageEn Library for Delphi, C++ and .Net
 ImageEn and IEvolution Support Forum
 IEApplyThreshold issue

Note: You must be registered in order to post a reply.
To register, click here. Registration is FREE!

View 
UserName:
Password:
Format  Bold Italicized Underline  Align Left Centered Align Right  Horizontal Rule  Insert Hyperlink   Browse for an image to attach to your post Browse for a zip to attach to your post Insert Code  Insert Quote Insert List
   
Message 

 

Emoji
Smile [:)] Big Smile [:D] Cool [8D] Blush [:I]
Tongue [:P] Evil [):] Wink [;)] Black Eye [B)]
Frown [:(] Shocked [:0] Angry [:(!] Sleepy [|)]
Kisses [:X] Approve [^] Disapprove [V] Question [?]

 
Check here to subscribe to this topic.
   

T O P I C    R E V I E W
timfa Posted - Oct 24 2024 : 10:17:52
I think you have a potential bug in the IEApplyThreshold procedure in the imageenproc.pas unit.

I am simply performing a threshold operation where all pixels below ThresholdValue (e.g., 128) are being set to 0 or 255 in one case or the opposite 255 or 0 in an alternate case. I have a TIEBitmap object named ThresholdImage and makes the following call (the alternate case):

            ThresholdImage.Proc.Threshold(
                        CreateRGB(ThresholdValue,ThresholdValue,ThresholdValue),
                        CreateRGB(ThresholdValue,ThresholdValue,ThresholdValue),
                        CreateRGB(255,255,255), CreateRGB(0,0,0) );

This function in turn calls:
procedure IEApplyThreshold(Bitmap: TIEBitmap; DownLimit, UpLimit, DownVal, UpVal: TRGB; X1, Y1, X2, Y2: Integer; OnProgress: TIEProgressEvent; Sender: TObject);


And in this procedure the following code executes:
for x := X1 to X2 do
    begin
      e := pRGB(ei);
      if (e^.r <= DownLimit.r) then
        e^.r := DownVal.r;
      if (e^.g <= DownLimit.g) then
        e^.g := DownVal.g;
      if (e^.b <= DownLimit.b) then
        e^.b := DownVal.b;
      if (e^.r > UpLimit.r) then
        e^.r := UpVal.r;
      if (e^.g > UpLimit.g) then
        e^.g := UpVal.g;
      if (e^.b > UpLimit.b) then
        e^.b := UpVal.b;
      inc(ei, i);
    end;


What happens in the case I presented is if the first IF for each r, g, b value is true it executes e^.r := DownVal.r which sets the value to 255. Then, further down it executes "if (e^.r > UpLimit.r)" and since we already changed e^.r in the first IF to 255, this second IF is true and sets e^.r := UpVal.r, i.e., it sets it to 0. I think this is wrong.

I think the code should be changed to:

      if (e^.r <= DownLimit.r) then
        e^.r := DownVal.r
      else if (e^.r > UpLimit.r) then
        e^.r := UpVal.r;

      if (e^.g <= DownLimit.g) then
        e^.g := DownVal.g
      else if (e^.g > UpLimit.g) then
        e^.g := UpVal.g;

      if (e^.b <= DownLimit.b) then
        e^.b := DownVal.b
      else if (e^.b > UpLimit.b) then
        e^.b := UpVal.b;

Thank you for considering this issue.


Tim F
4   L A T E S T    R E P L I E S    (Newest First)
xequte Posted - Nov 15 2024 : 18:58:36
Thanks for the suggestions, Tim. We have implemented both your suggested changes in the current beta. You can email me for it.


Nigel
Xequte Software
www.imageen.com
timfa Posted - Nov 13 2024 : 17:49:23
Hello Nigel,

I'm ordering the values as I am because in one case I am looking for a black object in the image or in the other case I'm looking for a white object. In either case, I want the item
found to appear in the threshold image as white and the pixels that don't pass the threshold test to be black. The code I wanted to use was:

      if aSetting.ThresholdMethod = tmManual then
      begin
         ThresholdValue := aSetting.Threshold;
         if aSetting.MeasureMethod = mmBlackCircle then
         begin
            MinThreshold := 0;
            MaxThreshold := ThresholdValue;
            ThresholdImage.Proc.Threshold(
                        CreateRGB(ThresholdValue,ThresholdValue,ThresholdValue),
                        CreateRGB(ThresholdValue,ThresholdValue,ThresholdValue),
                        CreateRGB(255,255,255), CreateRGB(0,0,0) );
         end
         else
         begin
            MinThreshold := ThresholdValue;
            MaxThreshold := 255;
            ThresholdImage.Proc.Threshold(
                        CreateRGB(ThresholdValue,ThresholdValue,ThresholdValue),
                        CreateRGB(ThresholdValue,ThresholdValue,ThresholdValue),
                        CreateRGB(0,0,0), CreateRGB(255,255,255) );
         end;

My workaround to this bug was...

         // Set all values <= MinThreshold to 0 (black), and all values > MaxThreshold
         // also to 0 (black).
         ThresholdImage.Proc.Threshold( CreateRGB(MinThreshold,MinThreshold,MinThreshold),
                        CreateRGB(MaxThreshold,MaxThreshold,MaxThreshold),
                        CreateRGB(0,0,0), CreateRGB(0,0,0) );
         // Set all non-zero values to 255 (White). (Actually, a value of 1 is unaltered.)
         ThresholdImage.Proc.Threshold( CreateRGB(0,0,0), CreateRGB(1,1,1),
                        CreateRGB(0,0,0), CreateRGB(255,255,255) );


The documentation for the Threshold procedure never says anything about expecting values to be in a certain order wrt magnitude...
"First overload assigns the DownVal color to all colors smaller or equal to DownLimit, and UpVal to all colors greater than UpLimit."
This is not the behavior of this procedure under the conditions I identified.


On another matter, it would be nice if your procedure TImageEnProc.ConvertToBWThreshold were changed to a function that returned the threshold value that was derived when the argument is -1 or -2 or the passed in value when it isn't -1 or -2.

Thank you.


Tim F
xequte Posted - Nov 03 2024 : 21:33:39
Hi Tim

Just to clarify, why are you not ordering your up/down values (i.e. CreateRGB(0,0,0) , CreateRGB(255,255,255) ) as would be expected?

Nigel
Xequte Software
www.imageen.com
xequte Posted - Oct 24 2024 : 18:29:59
Thanks for the report, Tim,

I'll need to investigate this when I am back in the office in early November.

Nigel
Xequte Software
www.imageen.com