Problem with setThreshold command - update

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Problem with setThreshold command - update

Straub, Volko A. (Dr.)
Thanks Gabriel for the suggestion, but unfortunately it doesn't resolve the issue.

However, following further tests, I figured out that it all depends on the interplay between the display range of the 16-bit image, the setThreshold command and the 'Find Maxima' function. I attach a test image and some macro code below that illustrates the behaviour.

If the display range is set to the full dynamic range of the 16-bit image, the setThreshold command behaves as expected, i.e. it includes all pixels with a value between the lower and upper threshold limits. The 'Find Maxima' can then be used to create segmented particles in the part of the image that has been thresholded.

However, if the lower display range is set to a value larger than the lowest pixel value in the image, using the same setThreshold command appears to result in the inclusion of pixels that have pixel values below the lower threshold value, which I found surprising. Nevertheless, creating a selection after the setThreshold command results in an identical selection to the previous one. So, for the purpose of the creation of a selection based on threshold, the fact that the display doesn't reflect the actually selected pixels is not really an issue. It also doesn't appear to affect the use of a subsequent 'Find Maxima' command to create segmented particles based on the applied threshold with the 'Above lower threshold' option active.

If the lower display range  is set to a value larger than the lower threshold value, running the setThreshold value appears to result in the selection of the whole image. But as before, creating a selection based on the threshold still produces the same result as for the previous two images. So for that purpose it is again not an issue - just a minor inconvenience that the display doesn't accurately  reflect the data. However, running the 'Find Maxima' command to create segmented particles based on the applied threshold with the 'Above lower threshold' option active now results in a completely different output. So, in this case it appears to critically depend on the display range and which pixels are part of the threshold as indicated on the display.

Why is there a discrepancy between the pixels that are actual part of the thresholded selection and those that are shown to be part of the selection?
And is there a bug in the Find Maxima command that results in pixels being included in the segmented particles when the 'Above threshold' option is set?
Is there anybody that can explain this to me?

Thanks,
Volko


image=getTitle();
getStatistics(area, mean, min, max, std, histogram);
print("Original - Area: "+area+"Minimum: "+min+" Maximum: "+max);
resetMinAndMax();
run("Duplicate...","title=[Threshold on full display range]");
setThreshold(2000,max);
run("Create Selection");
getStatistics(area, mean, min, max, std, histogram);
print("Selection 1 - Area: "+area+"Minimum: "+min+" Maximum: "+max);
run("Find Maxima...", "noise=2000 output=[Segmented Particles] above");

selectWindow(image);
run("Duplicate...","title=[Threshold after changing display range to 1500-max]");
setMinAndMax(1500,max);
setThreshold(2000,max);
run("Create Selection");
getStatistics(area, mean, min, max, std, histogram);
print("Selection 2 - Area: "+area+"Minimum: "+min+" Maximum: "+max);
run("Find Maxima...", "noise=2000 output=[Segmented Particles] above");

selectWindow(image);
run("Duplicate...","title=[Threshold after changing display range to 2100-max]");
setMinAndMax(2100,max);
setThreshold(2000,max);
run("Create Selection");
getStatistics(area, mean, min, max, std, histogram);
print("Selection 3 - Area: "+area+"Minimum: "+min+" Maximum: "+max);
run("Find Maxima...", "noise=2000 output=[Segmented Particles] above");


-----Original Message-----
From: Gabriel Landini [mailto:[hidden email]]
Sent: 19 June 2018 09:47
To: [hidden email]
Subject: Re: Problem with setThreshold command

I wonder if this is due to the way that you get the create selection (which I believe should be forced to detect the binarised pixels after the local threshold.

Try adding between the Local threshold and the Create selection lines:

setThreshold(255,255);

Cheers

Gabriel


On Tuesday, 19 June 2018 07:06:34 BST you wrote:

> Dear All,
>
>
> I have encountered some strange, inconsistent behaviour using the
> setThreshold command in a macro.
>
> I have included the macro code below. The macro is used to apply a
> local thresholding method to a 16-bit image. There is some initial
> filtering of the image before converting the image to an 8-bit image
> in order to apply the Bernsen local threshold method. The thresholded
> 8-bit image is then used to create a selection that is restored to the
> original image. The area outside of the selection is set to zero and
> the threshold is set to include all values in the selected area. The
> reason for this is that I want to use the Find Maxima function to
> create segmented particles of the areas that are within the selection
> by using the 'Above lower threshold' option (unfortunately there is no
> option to restrict the creation of segmented particles to a selection).
>
> Now, here is the strange thing, for most images the code works fine,
> but occasionally the last setThreshold command doesn't appear to be
> executed correctly and the whole image is selected. However, when it
> does select the whole image and I then manually select the Adjust ->
> Threshold command, the dialog shows the correct lower threshold and
> the image is updated to correctly reflect the threshold settings. So,
> I thought that it may be an issue with the display not being refreshed
> quickly enough, and including a
> wait(1000) before the setThreshold command indeed appears to solve the
> issue at some occasions, but not always.
>
> Unfortunately, even after lots of testing for a few days, I can't come
> up with a reliable way to reproduce the error consistently - the same
> image might process fine at one run (and once it has done it okay, it
> seems to be okay if the code is run repeatedly), but closing and
> re-loading the same image might result in a different result. It also
> doesn't seem to be strictly image size related (my starting images are
> about 2000 x 2000
> pixels) as sometimes cropping a larger image can solve the problem,
> but at other occasions the problem persists with a smaller image.
>
> Just for completeness, I am currently using the Fiji-ImageJ 1.51s
> version with Java 1.8.0_66 (64 bit).
>
>
> Does anybody have an idea what might be going on and how this can be
> resolved?
>
> Thanks for your help,
>
> Volko
>
>
>
>
> curImage=getTitle();
> run("Duplicate...","title=Original");
> run("Select None");
> getStatistics(area, mean, min, max, std, histogram);
> print("Original:",area,min,max);
>
> run("Duplicate...","title=Soma");
> run("Median...", "radius=10");
>
> getStatistics(area, mean, min, max, std, histogram);
> print("Filtered:",area,min,max);
>
> setMinAndMax(min,max);
> run("8-bit");
> run("Auto Local Threshold", "method=Bernsen radius=25 parameter_1=0
> parameter_2=0 white"); run("Create Selection");
>
> selectWindow("Original");
> run("Restore Selection");
> run("Clear Outside");
>
> getStatistics(area, mean, min, max, std, histogram);
> getMinAndMax(minD,maxD); //wait(1000); setThreshold(min,maxD);
> getThreshold(lower,upper); print(lower,upper);
>
>
>
> --
> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html

test.tif (523K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Problem with setThreshold command - update

Michael Schmid-3
Hi Volko,

thank you for providing a nice, reproducible example!

I think I have an idea what causes the problem:
With the commands
  setMinAndMax(2100,max);
  setThreshold(2000,max);
everything shown in the image becomes thresholded (red).
Showing the threshold is done by modifying the lookup table (LUT), which
is now red for all pixel values.

Then ImageJ thinks that the image has an inverted LUT (the macro command
"is('Inverting LUT')" yields 1, i.e., true).

If the image has an inverted LUT, "Find Maxima" regards low pixel values
as maxima (unless "Light background" is checked), causing all the trouble.

--

If my analysis is right, this problem needs some modifications in the
inner workings of ImageJ. Here are a few thoughts (for Wayne):

- ImageProcessor.isInvertedLut():
Instead of checking for an ascending step as a criterion for a
non-inverting LUT, one could check for the absence of a descending step.
This would solve the problem in the current case, but now images with an
inverting LUT would get the problem.

- ImageProcessor.isInvertedLut() could use the baseCM (when existing)
instead of the current color model for thresholded images. I guess that
this would be a clean solution

Then, ImageProcessor.resetThreshold() probably won't need the
   "inversionTested = false;" statement?

Maybe ImageProcessor.isPseudoColorLut() should also use the baseCM (when
existing) for thresholded images?

- As an alternative, in principle, one could always check for an
inverted LUT (if not done so already) before setThreshold, but I think
that using the baseCM would be the cleaner option.

Best,

Michael
________________________________________________________________
On 20/06/2018 12:14, Straub, Volko A. (Dr.) wrote:

> Thanks Gabriel for the suggestion, but unfortunately it doesn't resolve the issue.
>
> However, following further tests, I figured out that it all depends on the interplay between the display range of the 16-bit image, the setThreshold command and the 'Find Maxima' function. I attach a test image and some macro code below that illustrates the behaviour.
>
> If the display range is set to the full dynamic range of the 16-bit image, the setThreshold command behaves as expected, i.e. it includes all pixels with a value between the lower and upper threshold limits. The 'Find Maxima' can then be used to create segmented particles in the part of the image that has been thresholded.
>
> However, if the lower display range is set to a value larger than the lowest pixel value in the image, using the same setThreshold command appears to result in the inclusion of pixels that have pixel values below the lower threshold value, which I found surprising. Nevertheless, creating a selection after the setThreshold command results in an identical selection to the previous one. So, for the purpose of the creation of a selection based on threshold, the fact that the display doesn't reflect the actually selected pixels is not really an issue. It also doesn't appear to affect the use of a subsequent 'Find Maxima' command to create segmented particles based on the applied threshold with the 'Above lower threshold' option active.
>
> If the lower display range  is set to a value larger than the lower threshold value, running the setThreshold value appears to result in the selection of the whole image. But as before, creating a selection based on the threshold still produces the same result as for the previous two images. So for that purpose it is again not an issue - just a minor inconvenience that the display doesn't accurately  reflect the data. However, running the 'Find Maxima' command to create segmented particles based on the applied threshold with the 'Above lower threshold' option active now results in a completely different output. So, in this case it appears to critically depend on the display range and which pixels are part of the threshold as indicated on the display.
>
> Why is there a discrepancy between the pixels that are actual part of the thresholded selection and those that are shown to be part of the selection?
> And is there a bug in the Find Maxima command that results in pixels being included in the segmented particles when the 'Above threshold' option is set?
> Is there anybody that can explain this to me?
>
> Thanks,
> Volko
>
>
> image=getTitle();
> getStatistics(area, mean, min, max, std, histogram);
> print("Original - Area: "+area+"Minimum: "+min+" Maximum: "+max);
> resetMinAndMax();
> run("Duplicate...","title=[Threshold on full display range]");
> setThreshold(2000,max);
> run("Create Selection");
> getStatistics(area, mean, min, max, std, histogram);
> print("Selection 1 - Area: "+area+"Minimum: "+min+" Maximum: "+max);
> run("Find Maxima...", "noise=2000 output=[Segmented Particles] above");
>
> selectWindow(image);
> run("Duplicate...","title=[Threshold after changing display range to 1500-max]");
> setMinAndMax(1500,max);
> setThreshold(2000,max);
> run("Create Selection");
> getStatistics(area, mean, min, max, std, histogram);
> print("Selection 2 - Area: "+area+"Minimum: "+min+" Maximum: "+max);
> run("Find Maxima...", "noise=2000 output=[Segmented Particles] above");
>
> selectWindow(image);
> run("Duplicate...","title=[Threshold after changing display range to 2100-max]");
> setMinAndMax(2100,max);
> setThreshold(2000,max);
> run("Create Selection");
> getStatistics(area, mean, min, max, std, histogram);
> print("Selection 3 - Area: "+area+"Minimum: "+min+" Maximum: "+max);
> run("Find Maxima...", "noise=2000 output=[Segmented Particles] above");
>
>
> -----Original Message-----
> From: Gabriel Landini [mailto:[hidden email]]
> Sent: 19 June 2018 09:47
> To: [hidden email]
> Subject: Re: Problem with setThreshold command
>
> I wonder if this is due to the way that you get the create selection (which I believe should be forced to detect the binarised pixels after the local threshold.
>
> Try adding between the Local threshold and the Create selection lines:
>
> setThreshold(255,255);
>
> Cheers
>
> Gabriel
>
>
> On Tuesday, 19 June 2018 07:06:34 BST you wrote:
>> Dear All,
>>
>>
>> I have encountered some strange, inconsistent behaviour using the
>> setThreshold command in a macro.
>>
>> I have included the macro code below. The macro is used to apply a
>> local thresholding method to a 16-bit image. There is some initial
>> filtering of the image before converting the image to an 8-bit image
>> in order to apply the Bernsen local threshold method. The thresholded
>> 8-bit image is then used to create a selection that is restored to the
>> original image. The area outside of the selection is set to zero and
>> the threshold is set to include all values in the selected area. The
>> reason for this is that I want to use the Find Maxima function to
>> create segmented particles of the areas that are within the selection
>> by using the 'Above lower threshold' option (unfortunately there is no
>> option to restrict the creation of segmented particles to a selection).
>>
>> Now, here is the strange thing, for most images the code works fine,
>> but occasionally the last setThreshold command doesn't appear to be
>> executed correctly and the whole image is selected. However, when it
>> does select the whole image and I then manually select the Adjust ->
>> Threshold command, the dialog shows the correct lower threshold and
>> the image is updated to correctly reflect the threshold settings. So,
>> I thought that it may be an issue with the display not being refreshed
>> quickly enough, and including a
>> wait(1000) before the setThreshold command indeed appears to solve the
>> issue at some occasions, but not always.
>>
>> Unfortunately, even after lots of testing for a few days, I can't come
>> up with a reliable way to reproduce the error consistently - the same
>> image might process fine at one run (and once it has done it okay, it
>> seems to be okay if the code is run repeatedly), but closing and
>> re-loading the same image might result in a different result. It also
>> doesn't seem to be strictly image size related (my starting images are
>> about 2000 x 2000
>> pixels) as sometimes cropping a larger image can solve the problem,
>> but at other occasions the problem persists with a smaller image.
>>
>> Just for completeness, I am currently using the Fiji-ImageJ 1.51s
>> version with Java 1.8.0_66 (64 bit).
>>
>>
>> Does anybody have an idea what might be going on and how this can be
>> resolved?
>>
>> Thanks for your help,
>>
>> Volko
>>
>>
>>
>>
>> curImage=getTitle();
>> run("Duplicate...","title=Original");
>> run("Select None");
>> getStatistics(area, mean, min, max, std, histogram);
>> print("Original:",area,min,max);
>>
>> run("Duplicate...","title=Soma");
>> run("Median...", "radius=10");
>>
>> getStatistics(area, mean, min, max, std, histogram);
>> print("Filtered:",area,min,max);
>>
>> setMinAndMax(min,max);
>> run("8-bit");
>> run("Auto Local Threshold", "method=Bernsen radius=25 parameter_1=0
>> parameter_2=0 white"); run("Create Selection");
>>
>> selectWindow("Original");
>> run("Restore Selection");
>> run("Clear Outside");
>>
>> getStatistics(area, mean, min, max, std, histogram);
>> getMinAndMax(minD,maxD); //wait(1000); setThreshold(min,maxD);
>> getThreshold(lower,upper); print(lower,upper);
>>
>>
>>
>> --
>> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>
> --
> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>
> --
> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
|

Re: Problem with setThreshold command - update

Straub, Volko A. (Dr.)
Thanks Michael,

At least now that I figured out what is going on, I can work around it in my macro code to avoid situations of the lower threshold being set to values below the lower lower end of the display range.

Best regards,

Volko

________________________________
From: Michael Schmid <[hidden email]>
Sent: 20 June 2018 12:18:06
To: [hidden email]
Subject: Re: Problem with setThreshold command - update

Hi Volko,

thank you for providing a nice, reproducible example!

I think I have an idea what causes the problem:
With the commands
  setMinAndMax(2100,max);
  setThreshold(2000,max);
everything shown in the image becomes thresholded (red).
Showing the threshold is done by modifying the lookup table (LUT), which
is now red for all pixel values.

Then ImageJ thinks that the image has an inverted LUT (the macro command
"is('Inverting LUT')" yields 1, i.e., true).

If the image has an inverted LUT, "Find Maxima" regards low pixel values
as maxima (unless "Light background" is checked), causing all the trouble.

--

If my analysis is right, this problem needs some modifications in the
inner workings of ImageJ. Here are a few thoughts (for Wayne):

- ImageProcessor.isInvertedLut():
Instead of checking for an ascending step as a criterion for a
non-inverting LUT, one could check for the absence of a descending step.
This would solve the problem in the current case, but now images with an
inverting LUT would get the problem.

- ImageProcessor.isInvertedLut() could use the baseCM (when existing)
instead of the current color model for thresholded images. I guess that
this would be a clean solution

Then, ImageProcessor.resetThreshold() probably won't need the
   "inversionTested = false;" statement?

Maybe ImageProcessor.isPseudoColorLut() should also use the baseCM (when
existing) for thresholded images?

- As an alternative, in principle, one could always check for an
inverted LUT (if not done so already) before setThreshold, but I think
that using the baseCM would be the cleaner option.

Best,

Michael
________________________________________________________________
On 20/06/2018 12:14, Straub, Volko A. (Dr.) wrote:

> Thanks Gabriel for the suggestion, but unfortunately it doesn't resolve the issue.
>
> However, following further tests, I figured out that it all depends on the interplay between the display range of the 16-bit image, the setThreshold command and the 'Find Maxima' function. I attach a test image and some macro code below that illustrates the behaviour.
>
> If the display range is set to the full dynamic range of the 16-bit image, the setThreshold command behaves as expected, i.e. it includes all pixels with a value between the lower and upper threshold limits. The 'Find Maxima' can then be used to create segmented particles in the part of the image that has been thresholded.
>
> However, if the lower display range is set to a value larger than the lowest pixel value in the image, using the same setThreshold command appears to result in the inclusion of pixels that have pixel values below the lower threshold value, which I found surprising. Nevertheless, creating a selection after the setThreshold command results in an identical selection to the previous one. So, for the purpose of the creation of a selection based on threshold, the fact that the display doesn't reflect the actually selected pixels is not really an issue. It also doesn't appear to affect the use of a subsequent 'Find Maxima' command to create segmented particles based on the applied threshold with the 'Above lower threshold' option active.
>
> If the lower display range  is set to a value larger than the lower threshold value, running the setThreshold value appears to result in the selection of the whole image. But as before, creating a selection based on the threshold still produces the same result as for the previous two images. So for that purpose it is again not an issue - just a minor inconvenience that the display doesn't accurately  reflect the data. However, running the 'Find Maxima' command to create segmented particles based on the applied threshold with the 'Above lower threshold' option active now results in a completely different output. So, in this case it appears to critically depend on the display range and which pixels are part of the threshold as indicated on the display.
>
> Why is there a discrepancy between the pixels that are actual part of the thresholded selection and those that are shown to be part of the selection?
> And is there a bug in the Find Maxima command that results in pixels being included in the segmented particles when the 'Above threshold' option is set?
> Is there anybody that can explain this to me?
>
> Thanks,
> Volko
>
>
> image=getTitle();
> getStatistics(area, mean, min, max, std, histogram);
> print("Original - Area: "+area+"Minimum: "+min+" Maximum: "+max);
> resetMinAndMax();
> run("Duplicate...","title=[Threshold on full display range]");
> setThreshold(2000,max);
> run("Create Selection");
> getStatistics(area, mean, min, max, std, histogram);
> print("Selection 1 - Area: "+area+"Minimum: "+min+" Maximum: "+max);
> run("Find Maxima...", "noise=2000 output=[Segmented Particles] above");
>
> selectWindow(image);
> run("Duplicate...","title=[Threshold after changing display range to 1500-max]");
> setMinAndMax(1500,max);
> setThreshold(2000,max);
> run("Create Selection");
> getStatistics(area, mean, min, max, std, histogram);
> print("Selection 2 - Area: "+area+"Minimum: "+min+" Maximum: "+max);
> run("Find Maxima...", "noise=2000 output=[Segmented Particles] above");
>
> selectWindow(image);
> run("Duplicate...","title=[Threshold after changing display range to 2100-max]");
> setMinAndMax(2100,max);
> setThreshold(2000,max);
> run("Create Selection");
> getStatistics(area, mean, min, max, std, histogram);
> print("Selection 3 - Area: "+area+"Minimum: "+min+" Maximum: "+max);
> run("Find Maxima...", "noise=2000 output=[Segmented Particles] above");
>
>
> -----Original Message-----
> From: Gabriel Landini [mailto:[hidden email]]
> Sent: 19 June 2018 09:47
> To: [hidden email]
> Subject: Re: Problem with setThreshold command
>
> I wonder if this is due to the way that you get the create selection (which I believe should be forced to detect the binarised pixels after the local threshold.
>
> Try adding between the Local threshold and the Create selection lines:
>
> setThreshold(255,255);
>
> Cheers
>
> Gabriel
>
>
> On Tuesday, 19 June 2018 07:06:34 BST you wrote:
>> Dear All,
>>
>>
>> I have encountered some strange, inconsistent behaviour using the
>> setThreshold command in a macro.
>>
>> I have included the macro code below. The macro is used to apply a
>> local thresholding method to a 16-bit image. There is some initial
>> filtering of the image before converting the image to an 8-bit image
>> in order to apply the Bernsen local threshold method. The thresholded
>> 8-bit image is then used to create a selection that is restored to the
>> original image. The area outside of the selection is set to zero and
>> the threshold is set to include all values in the selected area. The
>> reason for this is that I want to use the Find Maxima function to
>> create segmented particles of the areas that are within the selection
>> by using the 'Above lower threshold' option (unfortunately there is no
>> option to restrict the creation of segmented particles to a selection).
>>
>> Now, here is the strange thing, for most images the code works fine,
>> but occasionally the last setThreshold command doesn't appear to be
>> executed correctly and the whole image is selected. However, when it
>> does select the whole image and I then manually select the Adjust ->
>> Threshold command, the dialog shows the correct lower threshold and
>> the image is updated to correctly reflect the threshold settings. So,
>> I thought that it may be an issue with the display not being refreshed
>> quickly enough, and including a
>> wait(1000) before the setThreshold command indeed appears to solve the
>> issue at some occasions, but not always.
>>
>> Unfortunately, even after lots of testing for a few days, I can't come
>> up with a reliable way to reproduce the error consistently - the same
>> image might process fine at one run (and once it has done it okay, it
>> seems to be okay if the code is run repeatedly), but closing and
>> re-loading the same image might result in a different result. It also
>> doesn't seem to be strictly image size related (my starting images are
>> about 2000 x 2000
>> pixels) as sometimes cropping a larger image can solve the problem,
>> but at other occasions the problem persists with a smaller image.
>>
>> Just for completeness, I am currently using the Fiji-ImageJ 1.51s
>> version with Java 1.8.0_66 (64 bit).
>>
>>
>> Does anybody have an idea what might be going on and how this can be
>> resolved?
>>
>> Thanks for your help,
>>
>> Volko
>>
>>
>>
>>
>> curImage=getTitle();
>> run("Duplicate...","title=Original");
>> run("Select None");
>> getStatistics(area, mean, min, max, std, histogram);
>> print("Original:",area,min,max);
>>
>> run("Duplicate...","title=Soma");
>> run("Median...", "radius=10");
>>
>> getStatistics(area, mean, min, max, std, histogram);
>> print("Filtered:",area,min,max);
>>
>> setMinAndMax(min,max);
>> run("8-bit");
>> run("Auto Local Threshold", "method=Bernsen radius=25 parameter_1=0
>> parameter_2=0 white"); run("Create Selection");
>>
>> selectWindow("Original");
>> run("Restore Selection");
>> run("Clear Outside");
>>
>> getStatistics(area, mean, min, max, std, histogram);
>> getMinAndMax(minD,maxD); //wait(1000); setThreshold(min,maxD);
>> getThreshold(lower,upper); print(lower,upper);
>>
>>
>>
>> --
>> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>
> --
> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>
> --
> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
|

Re: Problem with setThreshold command - update

Wayne Rasband-2
In reply to this post by Michael Schmid-3
> On Jun 20, 2018, at 7:18 AM, Michael Schmid <[hidden email]> wrote:
>
> Hi Volko,
>
> thank you for providing a nice, reproducible example!
>
> I think I have an idea what causes the problem:
> With the commands
> setMinAndMax(2100,max);
> setThreshold(2000,max);
> everything shown in the image becomes thresholded (red).
> Showing the threshold is done by modifying the lookup table (LUT), which is now red for all pixel values.
>
> Then ImageJ thinks that the image has an inverted LUT (the macro command "is('Inverting LUT')" yields 1, i.e., true).

The latest ImageJ daily build (1.52e6) fixes a bug that sometimes caused is('Inverting LUT’) to incorrectly return ‘true’ with thresholded images.

-wayne

> If the image has an inverted LUT, "Find Maxima" regards low pixel values as maxima (unless "Light background" is checked), causing all the trouble.
>
> --
>
> If my analysis is right, this problem needs some modifications in the inner workings of ImageJ. Here are a few thoughts (for Wayne):
>
> - ImageProcessor.isInvertedLut():
> Instead of checking for an ascending step as a criterion for a non-inverting LUT, one could check for the absence of a descending step.
> This would solve the problem in the current case, but now images with an inverting LUT would get the problem.
>
> - ImageProcessor.isInvertedLut() could use the baseCM (when existing) instead of the current color model for thresholded images. I guess that this would be a clean solution
>
> Then, ImageProcessor.resetThreshold() probably won't need the
>  "inversionTested = false;" statement?
>
> Maybe ImageProcessor.isPseudoColorLut() should also use the baseCM (when existing) for thresholded images?
>
> - As an alternative, in principle, one could always check for an inverted LUT (if not done so already) before setThreshold, but I think that using the baseCM would be the cleaner option.
>
> Best,
>
> Michael
> ________________________________________________________________
> On 20/06/2018 12:14, Straub, Volko A. (Dr.) wrote:
>> Thanks Gabriel for the suggestion, but unfortunately it doesn't resolve the issue.
>> However, following further tests, I figured out that it all depends on the interplay between the display range of the 16-bit image, the setThreshold command and the 'Find Maxima' function. I attach a test image and some macro code below that illustrates the behaviour.
>> If the display range is set to the full dynamic range of the 16-bit image, the setThreshold command behaves as expected, i.e. it includes all pixels with a value between the lower and upper threshold limits. The 'Find Maxima' can then be used to create segmented particles in the part of the image that has been thresholded.
>> However, if the lower display range is set to a value larger than the lowest pixel value in the image, using the same setThreshold command appears to result in the inclusion of pixels that have pixel values below the lower threshold value, which I found surprising. Nevertheless, creating a selection after the setThreshold command results in an identical selection to the previous one. So, for the purpose of the creation of a selection based on threshold, the fact that the display doesn't reflect the actually selected pixels is not really an issue. It also doesn't appear to affect the use of a subsequent 'Find Maxima' command to create segmented particles based on the applied threshold with the 'Above lower threshold' option active.
>> If the lower display range  is set to a value larger than the lower threshold value, running the setThreshold value appears to result in the selection of the whole image. But as before, creating a selection based on the threshold still produces the same result as for the previous two images. So for that purpose it is again not an issue - just a minor inconvenience that the display doesn't accurately  reflect the data. However, running the 'Find Maxima' command to create segmented particles based on the applied threshold with the 'Above lower threshold' option active now results in a completely different output. So, in this case it appears to critically depend on the display range and which pixels are part of the threshold as indicated on the display.
>> Why is there a discrepancy between the pixels that are actual part of the thresholded selection and those that are shown to be part of the selection?
>> And is there a bug in the Find Maxima command that results in pixels being included in the segmented particles when the 'Above threshold' option is set?
>> Is there anybody that can explain this to me?
>> Thanks,
>> Volko
>> image=getTitle();
>> getStatistics(area, mean, min, max, std, histogram);
>> print("Original - Area: "+area+"Minimum: "+min+" Maximum: "+max);
>> resetMinAndMax();
>> run("Duplicate...","title=[Threshold on full display range]");
>> setThreshold(2000,max);
>> run("Create Selection");
>> getStatistics(area, mean, min, max, std, histogram);
>> print("Selection 1 - Area: "+area+"Minimum: "+min+" Maximum: "+max);
>> run("Find Maxima...", "noise=2000 output=[Segmented Particles] above");
>> selectWindow(image);
>> run("Duplicate...","title=[Threshold after changing display range to 1500-max]");
>> setMinAndMax(1500,max);
>> setThreshold(2000,max);
>> run("Create Selection");
>> getStatistics(area, mean, min, max, std, histogram);
>> print("Selection 2 - Area: "+area+"Minimum: "+min+" Maximum: "+max);
>> run("Find Maxima...", "noise=2000 output=[Segmented Particles] above");
>> selectWindow(image);
>> run("Duplicate...","title=[Threshold after changing display range to 2100-max]");
>> setMinAndMax(2100,max);
>> setThreshold(2000,max);
>> run("Create Selection");
>> getStatistics(area, mean, min, max, std, histogram);
>> print("Selection 3 - Area: "+area+"Minimum: "+min+" Maximum: "+max);
>> run("Find Maxima...", "noise=2000 output=[Segmented Particles] above");
>> -----Original Message-----
>> From: Gabriel Landini [mailto:[hidden email]]
>> Sent: 19 June 2018 09:47
>> To: [hidden email]
>> Subject: Re: Problem with setThreshold command
>> I wonder if this is due to the way that you get the create selection (which I believe should be forced to detect the binarised pixels after the local threshold.
>> Try adding between the Local threshold and the Create selection lines:
>> setThreshold(255,255);
>> Cheers
>> Gabriel
>> On Tuesday, 19 June 2018 07:06:34 BST you wrote:
>>> Dear All,
>>>
>>>
>>> I have encountered some strange, inconsistent behaviour using the
>>> setThreshold command in a macro.
>>>
>>> I have included the macro code below. The macro is used to apply a
>>> local thresholding method to a 16-bit image. There is some initial
>>> filtering of the image before converting the image to an 8-bit image
>>> in order to apply the Bernsen local threshold method. The thresholded
>>> 8-bit image is then used to create a selection that is restored to the
>>> original image. The area outside of the selection is set to zero and
>>> the threshold is set to include all values in the selected area. The
>>> reason for this is that I want to use the Find Maxima function to
>>> create segmented particles of the areas that are within the selection
>>> by using the 'Above lower threshold' option (unfortunately there is no
>>> option to restrict the creation of segmented particles to a selection).
>>>
>>> Now, here is the strange thing, for most images the code works fine,
>>> but occasionally the last setThreshold command doesn't appear to be
>>> executed correctly and the whole image is selected. However, when it
>>> does select the whole image and I then manually select the Adjust ->
>>> Threshold command, the dialog shows the correct lower threshold and
>>> the image is updated to correctly reflect the threshold settings. So,
>>> I thought that it may be an issue with the display not being refreshed
>>> quickly enough, and including a
>>> wait(1000) before the setThreshold command indeed appears to solve the
>>> issue at some occasions, but not always.
>>>
>>> Unfortunately, even after lots of testing for a few days, I can't come
>>> up with a reliable way to reproduce the error consistently - the same
>>> image might process fine at one run (and once it has done it okay, it
>>> seems to be okay if the code is run repeatedly), but closing and
>>> re-loading the same image might result in a different result. It also
>>> doesn't seem to be strictly image size related (my starting images are
>>> about 2000 x 2000
>>> pixels) as sometimes cropping a larger image can solve the problem,
>>> but at other occasions the problem persists with a smaller image.
>>>
>>> Just for completeness, I am currently using the Fiji-ImageJ 1.51s
>>> version with Java 1.8.0_66 (64 bit).
>>>
>>>
>>> Does anybody have an idea what might be going on and how this can be
>>> resolved?
>>>
>>> Thanks for your help,
>>>
>>> Volko
>>>
>>>
>>>
>>>
>>> curImage=getTitle();
>>> run("Duplicate...","title=Original");
>>> run("Select None");
>>> getStatistics(area, mean, min, max, std, histogram);
>>> print("Original:",area,min,max);
>>>
>>> run("Duplicate...","title=Soma");
>>> run("Median...", "radius=10");
>>>
>>> getStatistics(area, mean, min, max, std, histogram);
>>> print("Filtered:",area,min,max);
>>>
>>> setMinAndMax(min,max);
>>> run("8-bit");
>>> run("Auto Local Threshold", "method=Bernsen radius=25 parameter_1=0
>>> parameter_2=0 white"); run("Create Selection");
>>>
>>> selectWindow("Original");
>>> run("Restore Selection");
>>> run("Clear Outside");
>>>
>>> getStatistics(area, mean, min, max, std, histogram);
>>> getMinAndMax(minD,maxD); //wait(1000); setThreshold(min,maxD);
>>> getThreshold(lower,upper); print(lower,upper);

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
|

Re: Problem with setThreshold command - update

Wayne Rasband-2
In reply to this post by Straub, Volko A. (Dr.)
> On Jun 20, 2018, at 6:14 AM, Straub, Volko A. (Dr.) <[hidden email]> wrote:
>
> Thanks Gabriel for the suggestion, but unfortunately it doesn't resolve the issue.
>
> However, following further tests, I figured out that it all depends on the interplay between the display range of the 16-bit image, the setThreshold command and the 'Find Maxima' function. I attach a test image and some macro code below that illustrates the behaviour.

The issues illustrated by this test macro are fixed in the latest ImageJ daily build (1.52e10). It fixes a bug that caused the is('Inverting LUT’) macro function to sometimes incorrectly return 'true' with thresholded images. It also fixes a thresholding bug that caused pixels in 16-bit images to be highlighted in red even though they were not within the threshold range.  Here is a macro that reproduces the second bug:

   run("M51 Galaxy (177K, 16-bits)");
   makeRectangle(140, 238, 32, 32);
   run("To Selection");
   setThreshold(2820, 65535);
   run("Create Selection”);

-wayne


> If the display range is set to the full dynamic range of the 16-bit image, the setThreshold command behaves as expected, i.e. it includes all pixels with a value between the lower and upper threshold limits. The 'Find Maxima' can then be used to create segmented particles in the part of the image that has been thresholded.
>
> However, if the lower display range is set to a value larger than the lowest pixel value in the image, using the same setThreshold command appears to result in the inclusion of pixels that have pixel values below the lower threshold value, which I found surprising. Nevertheless, creating a selection after the setThreshold command results in an identical selection to the previous one. So, for the purpose of the creation of a selection based on threshold, the fact that the display doesn't reflect the actually selected pixels is not really an issue. It also doesn't appear to affect the use of a subsequent 'Find Maxima' command to create segmented particles based on the applied threshold with the 'Above lower threshold' option active.
>
> If the lower display range  is set to a value larger than the lower threshold value, running the setThreshold value appears to result in the selection of the whole image. But as before, creating a selection based on the threshold still produces the same result as for the previous two images. So for that purpose it is again not an issue - just a minor inconvenience that the display doesn't accurately  reflect the data. However, running the 'Find Maxima' command to create segmented particles based on the applied threshold with the 'Above lower threshold' option active now results in a completely different output. So, in this case it appears to critically depend on the display range and which pixels are part of the threshold as indicated on the display.
>
> Why is there a discrepancy between the pixels that are actual part of the thresholded selection and those that are shown to be part of the selection?
> And is there a bug in the Find Maxima command that results in pixels being included in the segmented particles when the 'Above threshold' option is set?
> Is there anybody that can explain this to me?
>
> Thanks,
> Volko
>
>
> image=getTitle();
> getStatistics(area, mean, min, max, std, histogram);
> print("Original - Area: "+area+"Minimum: "+min+" Maximum: "+max);
> resetMinAndMax();
> run("Duplicate...","title=[Threshold on full display range]");
> setThreshold(2000,max);
> run("Create Selection");
> getStatistics(area, mean, min, max, std, histogram);
> print("Selection 1 - Area: "+area+"Minimum: "+min+" Maximum: "+max);
> run("Find Maxima...", "noise=2000 output=[Segmented Particles] above");
>
> selectWindow(image);
> run("Duplicate...","title=[Threshold after changing display range to 1500-max]");
> setMinAndMax(1500,max);
> setThreshold(2000,max);
> run("Create Selection");
> getStatistics(area, mean, min, max, std, histogram);
> print("Selection 2 - Area: "+area+"Minimum: "+min+" Maximum: "+max);
> run("Find Maxima...", "noise=2000 output=[Segmented Particles] above");
>
> selectWindow(image);
> run("Duplicate...","title=[Threshold after changing display range to 2100-max]");
> setMinAndMax(2100,max);
> setThreshold(2000,max);
> run("Create Selection");
> getStatistics(area, mean, min, max, std, histogram);
> print("Selection 3 - Area: "+area+"Minimum: "+min+" Maximum: "+max);
> run("Find Maxima...", "noise=2000 output=[Segmented Particles] above");
>
>
> -----Original Message-----
> From: Gabriel Landini [mailto:[hidden email]]
> Sent: 19 June 2018 09:47
> To: [hidden email]
> Subject: Re: Problem with setThreshold command
>
> I wonder if this is due to the way that you get the create selection (which I believe should be forced to detect the binarised pixels after the local threshold.
>
> Try adding between the Local threshold and the Create selection lines:
>
> setThreshold(255,255);
>
> Cheers
>
> Gabriel
>
>
> On Tuesday, 19 June 2018 07:06:34 BST you wrote:
>> Dear All,
>>
>>
>> I have encountered some strange, inconsistent behaviour using the
>> setThreshold command in a macro.
>>
>> I have included the macro code below. The macro is used to apply a
>> local thresholding method to a 16-bit image. There is some initial
>> filtering of the image before converting the image to an 8-bit image
>> in order to apply the Bernsen local threshold method. The thresholded
>> 8-bit image is then used to create a selection that is restored to the
>> original image. The area outside of the selection is set to zero and
>> the threshold is set to include all values in the selected area. The
>> reason for this is that I want to use the Find Maxima function to
>> create segmented particles of the areas that are within the selection
>> by using the 'Above lower threshold' option (unfortunately there is no
>> option to restrict the creation of segmented particles to a selection).
>>
>> Now, here is the strange thing, for most images the code works fine,
>> but occasionally the last setThreshold command doesn't appear to be
>> executed correctly and the whole image is selected. However, when it
>> does select the whole image and I then manually select the Adjust ->
>> Threshold command, the dialog shows the correct lower threshold and
>> the image is updated to correctly reflect the threshold settings. So,
>> I thought that it may be an issue with the display not being refreshed
>> quickly enough, and including a
>> wait(1000) before the setThreshold command indeed appears to solve the
>> issue at some occasions, but not always.
>>
>> Unfortunately, even after lots of testing for a few days, I can't come
>> up with a reliable way to reproduce the error consistently - the same
>> image might process fine at one run (and once it has done it okay, it
>> seems to be okay if the code is run repeatedly), but closing and
>> re-loading the same image might result in a different result. It also
>> doesn't seem to be strictly image size related (my starting images are
>> about 2000 x 2000
>> pixels) as sometimes cropping a larger image can solve the problem,
>> but at other occasions the problem persists with a smaller image.
>>
>> Just for completeness, I am currently using the Fiji-ImageJ 1.51s
>> version with Java 1.8.0_66 (64 bit).
>>
>>
>> Does anybody have an idea what might be going on and how this can be
>> resolved?
>>
>> Thanks for your help,
>>
>> Volko
>>
>>
>>
>>
>> curImage=getTitle();
>> run("Duplicate...","title=Original");
>> run("Select None");
>> getStatistics(area, mean, min, max, std, histogram);
>> print("Original:",area,min,max);
>>
>> run("Duplicate...","title=Soma");
>> run("Median...", "radius=10");
>>
>> getStatistics(area, mean, min, max, std, histogram);
>> print("Filtered:",area,min,max);
>>
>> setMinAndMax(min,max);
>> run("8-bit");
>> run("Auto Local Threshold", "method=Bernsen radius=25 parameter_1=0
>> parameter_2=0 white"); run("Create Selection");
>>
>> selectWindow("Original");
>> run("Restore Selection");
>> run("Clear Outside");
>>
>> getStatistics(area, mean, min, max, std, histogram);
>> getMinAndMax(minD,maxD); //wait(1000); setThreshold(min,maxD);
>> getThreshold(lower,upper); print(lower,upper);

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html