如何在此掩码中分割出感兴趣区域
How to segment out the region of interest in this mask
你好,我得到了如下的蒙版,我试着分割出左边的面板。
我用的是分水岭法,所以希望它return左边面板只有一个值。
D = bwdist(~mask);
imshow(D,[],'InitialMagnification','fit');
Di = -D;
Di(~mask) = -Inf;
L = watershed(Di);
Lrgb = label2rgb(L,'jet');
imshow(Lrgb);
但是我得到了这个,谁能帮我解决这个问题,或者你在细分方面有更好的建议。
我实际上发现有一个 matlab 函数 bwconncomp 可以标记组件。
components = bwconncomp(mask);
c_ind = components.PixelIdxList;
参考你的答案,使用bwconncomp
当然是一个有效的方法,但这里的问题是如果你看书脊,左右页是相连的。因此,如果您尝试按照您的建议进行操作,整本书将被标记为一个对象,而这可能不是您想要的。因此,我的建议是先 分离 页面,然后在完成后应用标签算法。
具有垂直线结构元素的简单形态学开放过滤器应该可以解决问题。为了获得好的结果,我使用了一条长度为 100 的线。您还有一些不必要的边框像素,图像实际上是 RGB。因此,我要将图像转换为二进制然后清除边框:
mask = imclearborder(im2bw(imread('http://i.stack.imgur.com/xUyDQ.png')));
我直接从 Whosebug 读入了你的图片。接下来,我们将应用我所说的形态学:
se = strel('line', 100, 90);
out = imopen(mask, se);
strel
的第二个输入是线的长度,因为 'line'
是您使用的标志 - 这表示线结构元素,第三个输入是方向线。 90 表示 90 度,或垂直线。
接下来,我们可以使用bwlabel
代替bwconncomp
...不仅因为它使用起来更简单,而且速度更快。 bwlabel
为您提供了一个标签矩阵,用于标记图像中的每个唯一对象。对象按列优先顺序标记,即从上到下,从左到右。
这意味着左侧页面将被赋予标签#1....因此您可以这样做来提取左侧页面:
left_page = label == 1;
imshow(left_page);
我们得到这张图片:
根据@rayryeng 的要求,这里有一个非常简单的替代方法。
im = imread('xUyDQ.png');
im = im2bw(im);
im = imerode(im, ones(6));
结果...
向后扩张...
im = imdilate(im, ones(6));
figure, imshow(im)
您当然可以通过将 6 减小到更小的值来获得更小的侵蚀。发生的事情是,我基本上是在用一个自定义结构元素进行侵蚀,该元素是一个 6x6 的矩阵 - 实际上发生的是在边界上 6 个像素被更改为零,因此您可以在页面之间获得所需的分隔正在找。
你好,我得到了如下的蒙版,我试着分割出左边的面板。
我用的是分水岭法,所以希望它return左边面板只有一个值。
D = bwdist(~mask);
imshow(D,[],'InitialMagnification','fit');
Di = -D;
Di(~mask) = -Inf;
L = watershed(Di);
Lrgb = label2rgb(L,'jet');
imshow(Lrgb);
但是我得到了这个,谁能帮我解决这个问题,或者你在细分方面有更好的建议。
我实际上发现有一个 matlab 函数 bwconncomp 可以标记组件。
components = bwconncomp(mask);
c_ind = components.PixelIdxList;
参考你的答案,使用bwconncomp
当然是一个有效的方法,但这里的问题是如果你看书脊,左右页是相连的。因此,如果您尝试按照您的建议进行操作,整本书将被标记为一个对象,而这可能不是您想要的。因此,我的建议是先 分离 页面,然后在完成后应用标签算法。
具有垂直线结构元素的简单形态学开放过滤器应该可以解决问题。为了获得好的结果,我使用了一条长度为 100 的线。您还有一些不必要的边框像素,图像实际上是 RGB。因此,我要将图像转换为二进制然后清除边框:
mask = imclearborder(im2bw(imread('http://i.stack.imgur.com/xUyDQ.png')));
我直接从 Whosebug 读入了你的图片。接下来,我们将应用我所说的形态学:
se = strel('line', 100, 90);
out = imopen(mask, se);
strel
的第二个输入是线的长度,因为 'line'
是您使用的标志 - 这表示线结构元素,第三个输入是方向线。 90 表示 90 度,或垂直线。
接下来,我们可以使用bwlabel
代替bwconncomp
...不仅因为它使用起来更简单,而且速度更快。 bwlabel
为您提供了一个标签矩阵,用于标记图像中的每个唯一对象。对象按列优先顺序标记,即从上到下,从左到右。
这意味着左侧页面将被赋予标签#1....因此您可以这样做来提取左侧页面:
left_page = label == 1;
imshow(left_page);
我们得到这张图片:
根据@rayryeng 的要求,这里有一个非常简单的替代方法。
im = imread('xUyDQ.png');
im = im2bw(im);
im = imerode(im, ones(6));
结果...
向后扩张...
im = imdilate(im, ones(6));
figure, imshow(im)
您当然可以通过将 6 减小到更小的值来获得更小的侵蚀。发生的事情是,我基本上是在用一个自定义结构元素进行侵蚀,该元素是一个 6x6 的矩阵 - 实际上发生的是在边界上 6 个像素被更改为零,因此您可以在页面之间获得所需的分隔正在找。