Matlab:二进制图像打开到最小矩形大小

时间:2014-01-02 21:37:01

标签: image matlab binary

我有二进制图片:

enter image description here

我试图看看100x150矩形是否适合地图上的任何空白区域。 我试着创建一个矩形的strel&然后腐蚀&扩大图片以摆脱任何小于所需的区域:

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

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

enter image description here

只有80x150。我认为侵蚀是失败的,因为它是靠在墙上和只需要宽度的一半,但不知道如何解决它。

另外,如果我走错了路,请随意让我直截了当。最后,我只需要找到一个空白区域的左上角至少大到100x150。

2 个答案:

答案 0 :(得分:2)

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

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

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

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

无论哪种方式,它都是计算问题的一个很好的例子,其中详尽的搜索可以很快进行。

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

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

enter image description here

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

% 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),则可以在交换宽度和高度后重复搜索。

希望这有帮助。

答案 1 :(得分:1)

让我们用一些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;

而鲍勃是你的叔叔,最后一个变量在所有地方都有1个,它们下方有明显的颜色,并且每个地方都有ncols到一边