我正在Matlab中实现某种泛洪填充算法,给定二进制图像中的起始像素,将输出仅包含可直接连接到它的像素的二进制图像。
基本上,让
foo =
1 1 1
1 0 0
1 0 1
调用flood_fill(foo,1,1)
会产生
1 1 1
1 0 0
1 0 0
现在,我对Matlab很新。我最初以递归样式实现flood_fill
,但Matlab的值传递行为使得处理大图像的效率非常低。为了解决这个问题,我重新实现了flood_fill
这样的
function [outImage] = flood_fill(inImage,start_x,start_y)
width = size(inImage,2);
height = size(inImage,1);
outImage = zeros(height,width);
points = [];
points = [points; [start_x start_y]];
while size(points,1)>0
point = points(1,:);
points = points(2:end,:);
y=point(2);
x=point(1);
outImage(y,x)=1;
if (y>1 && (outImage(y-1,x)==0) && (inImage(y-1,x)==1))
points = [points; [x y-1]];
end
if (y<height && (outImage(y+1,x)==0) && (inImage(y+1,x)==1))
points = [points; [x y+1]];
end
if (x>1 && (outImage(y,x-1)==0) && (inImage(y,x-1)==1))
points = [points; [x-1 y]];
end
if (x<width && (outImage(y,x+1)==0) && (inImage(y,x+1)==1))
points = [points; [x+1 y]];
end
end
end
现在,这适用于小型矩阵/图像,但也可以永久保存在大型图像上。我怀疑为什么大量的数组调整大小正在进行中。通常(在C ++中),我使用无序链表并将其用作堆栈(从头部移除并插入)以避免代价高昂的数组调整大小。
Matlab中是否存在这样的数据结构?如果没有,我可以用什么Matlab成语?也许是内置功能?
答案 0 :(得分:2)
您搜索的名为bwselect
的函数:
foo=[1 1 1; 1 0 0; 1 0 1]
b=bwselect(foo,1, 1)
请注意,您还可以定义第四个输入n
(例如:bwselect(foo,1,1,n)
),其值可以为4以指定4个连接区域,或者8可以指定8个连接区域。
答案 1 :(得分:1)
Adiel回答了你的第二个问题“也许是一个内置函数?”。至于第一部分:
我不熟悉MATLAB中的链表。但是,您可以通过初始化点矩阵的大小来显着加快功能,并且在此之后不要更改大小。预初始化应该始终在MATLAB中完成。如果该函数不适用于固定大小的矩阵,我总是建议您尝试重写该函数。
针对您的具体情况:
function [outImage] = flood_fill(inImage,start_x,start_y)
width = size(inImage,2);
height = size(inImage,1);
outImage = zeros(height,width);
points = zeros(nnz(inImage),2); % I take it this is the maximum size
points(1,:) = [start_x start_y];
k = 1; % Increment row number in points
while size(points,1)>0
k = k + 1;
y=points(k, 2);
x=points(k, 1);
我理解你一般都有编程技巧,所以我相信你应该能够将剩下的代码改编成新的格式。 (我没时间通过它并重写它)。我很确定它会更快地运行 更多 !