【问题标题】:Matlab: binary image open to minimum rectangle sizeMatlab:二进制图像打开到最小矩形大小
【发布时间】:2014-01-20 10:58:25
【问题描述】:

我有一个二值图像:

我正在尝试查看 100x150 的矩形是否适合地图上的任何空白区域。 我尝试创建一个矩形 strel,然后侵蚀和扩大图片以消除任何小于需要的区域:

se = strel('rectangle',[150, 100]);
BW = imerode(BW,se);
BW = imdilate(BW,se);

不幸的是,它过早地发现了一个洞

只有 80x150。我认为侵蚀失败了,因为它靠墙并且只需要一半宽度,但不知道如何修复它。

另外,如果我走错了路,请随时纠正我。最终,我只需要找到至少有 100x150 大小的空白区域的左上角即可。

【问题讨论】:

  • 查看文档,imerode中的区域和所有其他功能都是白色区域。试试BW = imerode(~BW,se);

标签: image matlab binary


【解决方案1】:

下面的方法效果很好,运行速度也很快。它有一些嵌套循环,但您可能可以进一步优化性能,我主要只是想让它为您工作。但请记住,如果您注释掉 fprintf() 和绘图命令,将会加快速度。

我从您的 Stack 帖子中下载了您的图片,但我认为我下载的版本与您正在使用的原始数据具有不同的大小 (398x398),因此在查看下面的结果时请记住这一点。

如代码中所示,您提供宽度 (w) 和高度 (h),然后算法返回矩形可以适合的所有 (col, row) 位置。

旁注: 我相信这为Bin packing problem 的 2D 版本提供了解决方案,但我不确定,如果是这样,您可以查看上面的链接您感兴趣。

无论哪种方式,它都是一个很好的计算问题示例,可以相当快地进行穷举搜索。

为了验证结果,我添加了简单的矩形绘图。请记住,如果矩形适合多个位置,则多个矩形的图开始看起来相当混乱,因为它们被反复绘制在另一个之上(带有偏移)。

作为仅找到单个矩形的示例,我使用:w = 29; h = 102;,然后结果显示该特定矩形可以容纳的唯一位置,左上角 = (row = 295, col = 368)(此矩形大小可能仅适用于我下载的您的数据版本):

总而言之,我首先加载数据,然后转换为二进制映射(0 和 1):

% Note: '0' = black; '1' = white
data = round(im2double(rgb2gray(imread(filepath))));
figure(1);imshow(data); set(gcf,'Color',[1 1 1]);
hold on;

输入搜索的宽度和高度:

w = 29;
h = 102;

sze = size(data);
numRows = sze(1);
numCols = sze(2);

接下来我们只做一个搜索,看看每行和每列位置适合什么:

for col = 1:numCols - w - 1
    for row = 1:numRows - h - 1
        doesFit = fitshere(data, row,col, w, h);
        if (doesFit == 1)
            fprintf('row = %d; col = %d \n',row,col);
            colX = [col col+w col+w col col];
            colY = [row row row+h row+h row];
            line(colX,colY,'Color','r','linewidth',2);
        end
    end
end

hold off;

您将需要以下函数来检查给定的矩形是否可以放入数组中:

function [val] = fitshere(data, row, col, w, h)
val = 1;
for i = col:col + w
    for j = row:row + h
        if (data(j,i) == 0) % if this is true, we are in the black!
            val = 0;
            return;
        end
    end
end
return;

如果您想知道您的矩形是否完全适合(比如width X heightheight X width),您只需在交换宽度和高度后重复搜索即可。

希望这会有所帮助。

【讨论】:

  • Roybatty,非常感谢!您的解决方案效果很好。你对垃圾箱包装也是正确的。这本质上是给定深度的 3D 装箱问题的自上而下视图。
【解决方案2】:

让我们用一些 matlab 习语来做这件事

M=binaryImage;
sz=size(M);
nrows = 100;
ncols = 150 ;

colsum = cumsum(M,1);
cols_are_good = colsum(nrows+1:end,:)-colsum(1:end-nrows+1,:)==0; 
    %  nrows empty rows below this point. in this column
rows_are_also_good = cols_are_good(:,ncols+1:end)-cols_are_good(:,1:end+1-ncols)==0;

而 Bob 是你的叔叔,最后一个变量在所有下面有 nrows 的地方都包含 1,并且每个地方都有 ncols 到一边

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-25
    • 1970-01-01
    • 2015-09-19
    相关资源
    最近更新 更多