2

I do not get why a segmentation obtained by using multithresh on an "original" double image is different from a segmentation using the same parameters on the same image scaled by mat2gray.

E.g.:

testimage = randi(100,[200 200]);
figure;imagesc(testimage)


threshs = multithresh(testimage,5);
l0 = imquantize(testimage,threshs);

threshs = multithresh(mat2gray(testimage),5);
l1 = imquantize(mat2gray(testimage),threshs);

Here, in my case l1 is different from l0 in 808 pixels. Why? The relative differences between pixels in testimage and mat2gray(testimage) should be equivalent, just the absolute differences change. How is this important to multithresh?

user1809923
  • 1,235
  • 3
  • 12
  • 27
  • My guess is that an image with range `0-max(img)>1` is treated as a `0-255` image, and that has an influence in multitresh – Ander Biguri Jul 04 '16 at 15:31
  • @AnderBiguri: what exactly would that mean? What happens to value > 255? The behaviour is present also when testimage is double, btw. Also note that it appears to me that testimage is scaled to [0 1] when it is of type float (see line 224 of multithresh) – user1809923 Jul 05 '16 at 06:36

1 Answers1

2

You are indirectly running into a floating precision error. If we modify a little your code, just to visualize it

testimage = randi(100,[200 200]);
figure;imagesc(testimage)

gray_image=mat2gray(testimage);

threshs1 = multithresh(testimage,5);
l0 = imquantize(testimage,threshs1);

threshs2 = multithresh(gray_image,5);
l1 = imquantize(gray_image,threshs2);

%For this example
threshs1
%threshs1 =
%       17.6941    34.0000    50.6941    67.0000    83.6941

threshs2
%threshs2 =
%        0.1686     0.3333     0.5020     0.6667     0.8353

Then we find one of the discrepant points in both original matrices

find(l0~=l1,1)
%ans =
%    67

testimage(67)
%ans =
%    34

gray_image(67)
%ans =
%    0.3333

And Here is where the floating precision comes into play

testimage(67)==threshs1(2)  % 34 == 34.0000
%ans =
%     1

gray_image(67)==threshs2(2) % 0.3333 == 0.3333
%ans =
%     0

The value of 1/3 is not properly saved into binary, see here for an explanation why, imquantize must be comparing the values of the image to the thresholds with a >= or similar, and it would pass in one case and fail in the other.

Sadly I cannot see a simple way to modify your code to make sure l0 and l1 are equal in every case.

Noel Segura Meraz
  • 2,265
  • 1
  • 12
  • 17
  • interesting, thanks for the answer! Now I am wondering why thresh2 is not thresh1 ./ 100 in the first place... – user1809923 Jul 05 '16 at 09:15
  • I'm guessing that has to do with the mapping of `mat2gray` from `testimage` to `gray_image`. `gray_image` is not `testimage./100` either, so I don't see how thresholds would be – Noel Segura Meraz Jul 05 '16 at 09:32
  • yes, true, because the smallest value in testimage usually will be 1 (and not 0!). Therefore, threshs2 = (threshs1-1) / (100-1). – user1809923 Jul 05 '16 at 10:35