MATLAB Answers


imbinarize vs im2bw

Asked by Cesar Moreno on 19 Sep 2019 at 16:09
Latest activity Edited by Cesar Moreno on 21 Sep 2019 at 21:12
I am being told by MATLAB that im2bw is no longer recommended and instead imbinarize should be used. I cannot, however, figure out how to change my code to derive the same output as im2bw. Here is my function:
[bw_img, bw_label] = wingMorphFilter2(~, label)
label(label == 2) = 1;
label(label == 3) = 2;
label(label == 4) = 2;
rgb_img = label2rgb(label);
bw_img = im2bw(rgb_img);
bw_img = imcomplement(bw_img);
bw_img = imclearborder(bw_img);
bw_img = bwareafilt(bw_img,7);
bw_img = imfill(bw_img,'holes');
se = strel('disk', 8);
bw_img = imerode(bw_img,se);
bw_img = imfill(bw_img,'holes');
bw_img = bwareafilt(bw_img,7);
bw_img = imdilate(bw_img,se);


Sign in to comment.

1 Answer

Walter Roberson
Answer by Walter Roberson
on 19 Sep 2019 at 18:15
 Accepted Answer

label2rgb(label) is equivalent to label2rgb(label, 'jet') which triggers 'jet' to be executed with no parameters. When jet is executed, it checks to see if there is a current figure, and if so then it finds the number of rows of the figure's colormap, and if there is no current figure then it finds the number of rows of the graphics root object DefaultFigureColormap . Historically for Windows the default figure colormap had 64 rows, but if I recall correctly that was changed to 256, I think it was R2019a. Therefore the meaning of the label2rgb line depends upon how many colors are in the current colormap. It would be better if the code were rewritten to be independent of the current colormap.
The colormap generated by jet() is a double() colormap. But if the label array happens to be uint8 or uint16 or uint32 datatype, then it converts the colormap to the same uint* datatype . Unfortunately at the moment we cannot tell whether your label array is double or uint8.
im2bw(), presented with RGB data that is double(), does an rgb2gray() on the data, and then compares the results to the threshold, with the threshold defaulting to 0.5.
imb2bw(), presented with RGB data that is uint8, does an rgb2gray() on the ata, and then compres the results to the threshold, with the threshold defaulting to half of the maximum of the integer class (so 128 for uint8)
Therefore, you can replace your
bw_img = im2bw(rgb_img);
if isfloat(rgb_img)
bw_img = rgb2gray(rgb_img) > 0.5;
bw_img = rgb2gray(rgb_img) >= 128;
which you can then optimize if you know the datatype of your label array.
Now, what is being tested is the brightness of the color induced by the label according to the jet colormap. The jet colormap happens to be such that for 256 colors, the color of the first entry is brighter than 1/2, and the color of entries 76 to 203 is greater than 1/2, and the colors of entries 2 to 75 and 204 to 256 are less than 1/2. This would pick out the first cluster, and clusters 76 to 203, and nothing else.
Your code
label(label == 2) = 1;
label(label == 3) = 2;
label(label == 4) = 2;
hints that your data range in your label matrix is possibly 0 to 4 before the assigmments, and possibly 0 to 2 after the assignments. Or maybe it is 1 or 2 after the assignments, it is hard to tell from the snippet. But if so, if nothing in the label matrix is greater than 2 after those lines, then why go through all the trouble of doing the label2rgb and im2bw? Why not just say
bw_img = label == 1;
or in terms of the label image before those three assignment statements,
bw_img = ismember(label, [1 2]);

  1 Comment

Cesar Moreno on 21 Sep 2019 at 21:11
Great, this worked perfectly. Thank you!

Sign in to comment.