这是我的形象 a.png
进行二值化我尝试使用此代码。
im=rgb2gray(I);
maxp=uint16(max(max(im)));
minp=uint16(min(min(im)));
bw=im2bw(im,(double(minp+maxp))/(1.42*255));
bw=~bw;
imm=bw;
但我需要通过otsu进行二值化。我可以使用otsu方法获得良好的二进制输出吗? 请帮忙
感谢
答案 0 :(得分:0)
MATLAB有自己的Otsu thresholding实现,称为multithresh
。在您的情况下,获取分段图像的代码应该是这样的:
im=rgb2gray(I); % convert image to grayscale
thresh = multithresh(im); % find one threshold (using Otsu method)
segmented_im = imquantize(im, thresh); % segment image
imagesc(segmented_im); % show segmented image
我还没有测试过,所以我不知道它对你的影像有多好。
修改
我测试了它,并没有按预期工作。其中一个问题是,当像素强度存在明显的双峰分布时,Otsu的方法效果很好。你的形象缺乏这种双峰性。在灰度转换后调用imhist(im)
会导致此问题(由我添加评论):
正如您所看到的,分布几乎是三角形的,multithresh
选择的阈值是第一个,而您想要第二个。我想到的第一个解决方法(特别是如果数据集中的所有图像与您发布的图像类似,即具有相似的强度分布)是使multithresh
输出两个阈值,然后选择最后一个(最高的一个:
thresholds = multithresh(im, 2);
thresh = thresholds(end);
然后如上所述继续进行图像分割。第二种方法导致这种分割:
编辑2(将它们放在一起):
确实输出segmented_im
不是二进制图像,而是标签图像。将其转换为二进制图像非常容易。我将直接包含下一个代码段中的所有代码:
im=rgb2gray(I); % convert image to grayscale
thresholds = multithresh(im, 2); % find two thresholds using Otsu
thresh = thresholds(end); % select larger one
segmented_im = imquantize(im, thresh); % segment image
segmented_im(segmented_im == 1) = 0; % make background black (0)
segmented_im(segmented_im == 2) = 255; % make foreground white (255)
binary_im = im2bw(segmented_im); % make binary (logical) image
imshow(binary_im); % show binary image
binary_im
是一个逻辑矩阵,背景为false(0),前景为true(1)。 segmented_im
是一个双矩阵,背景为0,前景为255。我希望这符合你的目的!