【问题标题】:Create mask from bwtraceboundary in Matlab在 Matlab 中从 bwtraceboundary 创建掩码
【发布时间】:2015-08-30 11:03:48
【问题描述】:

我正在尝试创建一个蒙版(或类似结果),以擦除未附加到边界包围的对象的二进制图像片段。我看到这个线程 (http://www.mathworks.com/matlabcentral/answers/120579-converting-boundary-to-mask) 从 bwboundaries 执行此操作,但我无法对其进行适当的更改。我的目标是使用此代码来隔离此地形图的连接部分,并去除多余的部分。我需要保留有界区域内的结构,因为然后我将使用 bwboundaries 创建主要对象的“内部”结构的附加边界线。

以下是我的代码,它首先通过搜索黑色区域的左下角像素来开始跟踪来创建单个边界线。它只是寻找不是完全白色的图像的第一列并选择最后一个黑色像素。第二部分是创建内部边界线。请注意,我正在尝试这两个步骤的过程,但是如果有一种方法可以只用一个方法来完成,我也想听听这个解决方案。最终,我只想要主要的大黑色区域及其内部的孔的边界,同时摆脱多余的部分。

 figName='Images/BookTrace_1';

BW = imread([figName,'.png']);
    BW=im2bw(BW);
    imshow(BW,[]);

    for j=1:size(BW,2)
        if sum(BW(:,j))~=sum(BW(:,1))
            corner=BW(:,j);
            c=j-1;
            break
        end
    end
    r=find(corner==0);
    r=r(end);

    outline = bwtraceboundary(BW,[r c],'W',8,Inf,'counterclockwise');
    hold on;
    plot(outline(:,2),outline(:,1),'g','LineWidth',2);


[B,L] = bwboundaries(BW);
hold on
for k = 1:length(B)
    boundary = B{k};
    plot(boundary(:,2), boundary(:,1), 'g', 'LineWidth', 2)
end

非常感谢任何建议或提示。如果有问题,请告诉我,我会更新帖子。谢谢!

编辑:为澄清起见,我的最终目标如下图所示。我需要追踪连接到主要对象的所有外部和内部边界,同时消除任何未连接到它的备用小块。

【问题讨论】:

    标签: image matlab image-processing mask boundary


    【解决方案1】:

    这很简单。我实际上不会使用上面的代码,而是使用图像处理工具箱。有一个内置功能可以删除任何接触图像边框的白色像素。使用imclearborder 函数。

    该函数将返回一个新的二进制图像,其中任何接触图像边界的像素都将被删除。鉴于您的代码,它非常简单:

    out = imclearborder(BW);
    

    以上面的图像为例,我将对其进行阈值处理,以便移除绿线......或者更确切地说与其他白色像素合并,我将调用上面的函数:

    BW = imread('http://i.stack.imgur.com/jhLOw.png'); %// Read from StackOverflow
    BW = im2bw(BW); %// Convert to binary
    out = imclearborder(BW); %// Remove pixels along border
    imshow(out); %// Show image
    

    我们得到:


    如果您想要相反的效果,即您想要保留边界并删除内部所有其他内容,只需通过复制原始图像创建一个新图像,然后使用上面的输出将这些像素位置归零。

    out2 = BW; %// Make copy
    out2(out) = 0; %// Set pixels not belonging to boundary to 0
    imshow(out2); %// Show image
    

    因此我们得到:

    编辑

    鉴于上述期望的输出,我相信我现在知道你想要什么。您希望为每组像素填充孔并沿着所需结果的边界进行跟踪。我们将其分为两类这一事实将很有用。对于那些在内部的物体,使用imfill 函数并指定holes 选项来填充任何黑洞,使它们变成白色。对于外部的对象,这将需要一些工作。我要做的是反转图像,使黑色的像素变为白色,反之亦然,然后使用bwareaopen 函数清除任何面积低于一定数量的像素。这将移除沿外部区域边界的那些小的孤立黑色区域。完成后,重新反转图像。这样做的效果是小孔将被消除。我为该区域选择了 500 像素的阈值...似乎效果很好。

    因此,使用上述变量作为参考,这样做:

    %// Fill holes for both regions separately
    out_fill = imfill(out, 'holes');
    out2_fill = ~bwareaopen(~out2, 500);
    
    %// Merge together
    final_out = out_fill | out2_fill; 
    

    这是我们得到的:

    如果您想要像示例中那样漂亮的绿色边框来说明这一点,您可以这样做:

    perim = bwperim(final_out);
    red = final_out;
    green = final_out;
    blue = final_out;
    red(perim) = 0;
    blue(perim) = 0;
    out_colour = 255*uint8(cat(3, red, green, blue));
    imshow(out_colour);
    

    上面的代码找到物体的周长,然后我们创建一个新的图像,其中沿周长的红色和蓝色通道设置为0,同时将绿色通道设置为255。

    我们得到这个:

    您可以忽略图像周围的绿色像素边框。这只是我沿图像中对象查找周长的方式的副作用。事实上,你提供给我的图像有一个围绕整个区域的白色像素边框,所以我不确定这是否是有意的,或者这是否是整个宏伟计划的一部分。


    为了整合成一个工作示例以便您可以复制并粘贴到 MATLAB 中,以下是一个代码块中的所有代码:

    %// Pre-processing
    BW = imread('http://i.stack.imgur.com/jhLOw.png'); %// Read from StackOverflow
    BW = im2bw(BW); %// Convert to binary
    
    out = imclearborder(BW); %// Remove pixels along border
    
    %// Obtain pixels that are along border
    out2 = BW; %// Make copy
    out2(out) = 0; %// Set pixels not belonging to boundary to 0
    
    %// Fill holes for both regions separately
    out_fill = imfill(out, 'holes');
    out2_fill = ~bwareaopen(~out2, 500);
    
    %// Merge together
    final_out = out_fill | out2_fill; 
    
    %// Show final output
    figure;
    imshow(final_out);
    
    %// Bonus - Show perimeter of output in green
    perim = bwperim(final_out);
    red = final_out;
    green = final_out;
    blue = final_out;
    red(perim) = 0;
    blue(perim) = 0;
    out_colour = 255*uint8(cat(3, red, green, blue));
    figure;
    imshow(out_colour);
    

    【讨论】:

    • 这是一个很棒的功能!不过我很抱歉,我想我可能不清楚我需要什么。我想删除绿色边框之外的所有内容,但将所有内容保留在里面。所以,这两个选项只能给我一个,除非我误解了?
    • @jmolaro 对不起,我不明白...如果您想删除绿色边框之外的所有内容,那不是第二种选择吗?你能告诉我理想的输出是什么样的吗?
    • @jmolaro - 好的,你想删除图像中被绿色描绘的那些像素吗?我还是不太明白你想要什么。
    • @jmolaro - 很抱歉不是真的。您想要的输出描述说明了一件事,但您的图像说明了另一件事。你给我看的图像基本上描绘了图像中所有白色物体的所有边界。这与 “我需要跟踪连接到主要对象的所有外部和内部边界,同时消除任何未连接到它的备用小块。”....我是我为你提供的第二个选项。
    • 你看到我的图片和你的图片中删除的部分了吗?比如,顶部的黑色小岛?此外,在您的第二个选项中,许多白色“湖”从黑色物体内部消失了。
    猜你喜欢
    • 1970-01-01
    • 2010-09-21
    • 2021-10-13
    • 1970-01-01
    • 2016-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多