Otsu thresholding different result


I have been applying for some time the Otsu threshold to my greyscale 3D stacks (I cannot share a sample image because of non-disclosure agreements).
I usualy use: Image>Adjust>Threshold> Otsu (applied to the stack and using the stack histogram)

I recently tried the Auto Threshold Plugin just to double-check the results (Image>Adjust>Auto threshold>Otsu (applied to the stack and using the stack histogram)

To my surprise, the threshold using the “Adjust>Threshold” provided a value of 141, and the second method, “Auto Threshold”, found the threshold at 140!
I really thought that the algorithm was the same to both cases, and therefore the value would be the same. What could be the reason for such difference?

I just want to add that I wrote the Otsu method in Python and it provided a value of 141, so I guess that the algorithm in “Auto Threshold” either has a bug or I’m not apllying it to the stack correctly?

Thank you for your comments in advance.

1 Like

Hi @pedgalher ,

it is possible that both implementations are correct even though they differ. If I remember correctly, in the original paper, a histogram bin is selected but it’s not specified if the upper or lower bound, or mean of that bin is supposed to be the final threshold. See also related discussion:

What’s important is that you document which method and which implementation you used in your paper so that others can reproduce your science.



Hi @pedgalher, adding to @haesleinhuepf’s answer, check out the ‘Important notes’ on the Auto Threshold page, which further describe how and why the thresholds might differ without any bug being involved.


Hi both,

Thank you for your answers. This now makes complete sense since I would have been very surprised threse was a bug in the code. When I read the original Otsu paper I didn’t think about the possibility of implementing the threshold algorithm in different ways, so I’ll go through the “Auto Threshold” code and see how it is done there.



There might be an issue about what you are considering to be foreground and background to find the threshold value. Eg. 0…140 is foreground, and 141…255 is background. So your threshold is 140 when looking for black holes, but if you want to find supernovas on the same image, the threshold would be 141. That is the boundary value of the thresholded phase cannot be the same value in the background phase. Check this in the applet where and click on the “Dark background” box. The threshold does change by 1 unit when you do that.
The algorithm does not change, but the value at which you decide whether to change the current pixel to 0 or 255 does.



Thank you for your comment.
I just checked it using the “Adjust>Threshold” and my foreground is [0,141], and the background is [142, 255] after checking the “Dark background” box. This is the same result I got running the Python implementation.



Just to close this question, I just want to mention that I figured out what was happening and what was the cause of the difference betwen the thresholds:

  • Looking at the image histogram, it happens that right at the value 141, the counts are zero, and therefore the sum of intra-class variance is the same, so setting the threshold at 140 or 141 doesnt make a difference, and therefore

  • My python code and the “Adjust>Threshold” take as threshold the last greyvalue of a set of values with the same variance (141 in this case), but the “Auto-Threshold” takes the first value of that set, therefore 140.

Therefore all the algoithms are correct.