3
votes

Just clarifying a point about the Otsu thresholding method that lacks definition in the documentation & wikipedia articles. If you apply the Otsu method (in matlab the function graythresh) it returns a threshold value between 0 and 1.

Given 2 hypothetical grayscale images:

  • dark (with pixel intensities in the range of 0 to 100) and
  • light (with pixel intensities in the range of 155 to 255)

If I got an Otsu threshold of 0.75 for both dark and light images respectively, what grayscale pixel intensity would it map to in each case?

  • dark -> 75 and light -> 231 E.g. relative to the range of values in each image
  • dark -> 75 and light -> 191 E.g. relative to the range 0 to max pixel value
  • dark -> 191 and light -> 191 E.g. relative to the full range of grayscale pixel values (0-255)?
4
Hmm, now we've got some dissenting answers. I've unset the question as answered, anyone else want to weigh in?David Parks
Ratbert's answer is correct. You should mark his as accepted. The 0.75 is with respect to the dynamic range of your grayscale images. You can verify this by looking at the source of graythresh by doing open graythresh in the MATLAB command prompt. For the dark images, 0.75 is 75% of the way between 0 - 100, and so 75 is the answer. For the light image, 75% of the way is 155 + (255-155)*0.75 ~ 230.... I upvoted Ratbert's answer.rayryeng
I've read all of these answers, but I'm not convinced @Ratbert is correct. If graythresh returned a value relative to the range of its input, why would a = graythresh(uint8([10 20])) return a different value than b = graythresh(uint8([20 30]))? Look at what Ratbert suggests the threshold of a is: a * (20 - 10) + 10, which is 10.5686, whereas Anand suggests that the threshold is a * 255, which is 14.5. The second calculation makes a lot more sense!Numeri
It's been a while since I looked into this, and to provide more concrete evidence for or against Anand I'm going to have to devote some more time to it (which I'd like to). I haven't been able to do so yet, if anyone else with interest wants to do some follow up investigative work and weight in it'll be most welcome. My intuition still is that Ratbert's answer is right, which my original follow up seemed to support. But to argue it further requires more effort.David Parks

4 Answers

2
votes

The accepted answer by @Ratbert makes the incorrect claims that

The correct answer is the first one

and

graythresh uses the min and max values in the image as boundaries, which is the most logical behavior.

and rayryeng appears to agree with it. David Parks appears to have empirically verified it.

The correct answer is given by Anand which strangely seems to have a negative vote. He explains very convincingly that

full range of grayscale pixel values' depends on the data type of the input image

As he explains,

this is the third option

except for the fact that the dark image could not possibly get a threshold of 0.75.

First let us clarify the difference between the claims for the simplest case, in clear MATLAB, so there is no confusion. For an image with values ranging from min to max, the question poses three possibilities which, when translated to an equation are:

  1. threshold = min + (max-min) * graythresh
  2. threshold = max * graythresh
  3. threshold = 255 * graythresh

Suppose the image consists of just two points one with an intensity of 0, and the other with 100. This means dark = uint8([0 100]);. A second image light = dark+155;. When we compute 255*graythresh(dark) we get exactly 49.5. When we compute 255*graythresh(light) we get exactly 204.5. These answers make it patently obvious that the third option is the only possibility.

There is one further fine point. If you try 255*graythresh(uint8(1:2)) the answer is 1, and not 1.5. So it appears that if you are using greythresh to threshold an image, you should use image <= 255*graythesh(image) with a less-than-or-equal-to, rather than a plain less-than.

1
votes

Your third answer seems most right to me, with the clarification that 'full range of grayscale pixel values' depends on the data type of the input image. For example, for a uint8 image, an Otsu threshold of 0.75 corresponds to around 191. For a uint16 image, this would correspond to 49151.

1
votes

Well, for posterity sake I did a comparison of the approaches mentioned before. I took a typical image with a full range of grayscale pixel intensities, then took a dark and light version of the same image and got the graythresh value for each. I Applied the Otsu threshold using each of the above mappings.

The light image pretty clearly demonstrates that the algorithm is producing a threshold over the range of the images' pixel intensities. Were we to assume a full range of pixel intensities, the Otsu algorithm would be producing a threshold below any actually present in the image, which doesn't make much sense, at least presuming the existing black background is transparent/irrelevant.

I suppose someone could make an argument for assuming the full range of pixel intensities if you assume the existing black part of the image were relevant darkness. I would certainly welcome comments there.

Full size images seen below

Comparison of grayscale intensity obtained from OTSU threshold


Amending my words above: When I blacken all but the top half of the light image and take the Otsu threshold again I get the same threshold value of 0.3020. Were the dark parts of the image relevant to the Otsu threshold being produced the extra darkness would have affected the value, therefore, Ratbert's answer is empirically demonstrated as correct.

Further test

0
votes

The correct answer is the first one :

dark = 75 and light = 230, relative to the range of values in each image

graythresh uses the min and max values in the image as boundaries, which is the most logical behavior.