我正在为任务编程,找到图像x
中给定像素D
的邻居,该公式可以表示为:
显示像素y
的公式满足与像素x
的距离为1,则它们是像素x
的邻居。这是我的matlab代码。但是,它仍然需要很长时间才能找到。你能建议一个更快的方法吗?非常感谢你
%-- Find the neighborhood of one pixel
% x is pixel coordinate
% nrow, ncol is size of image
function N = find_neighbor(x,nrow,ncol)
i = x(1);
j = x(2);
I1 = i+1;
if (I1 > nrow)
I1 = nrow;
end
I2 = i-1;
if (I2 < 1)
I2 = 1;
end
J1 = j+1;
if (J1 > ncol)
J1 = ncol;
end
J2 = j-1;
if (J2 < 1)
J2 = 1;
end
N = [I1, I2, i, i; j, j, J1, J2];
例如:ncol=128; nrow=128; x =[30;110]
然后输出
N =31 29 30 30; 110 110 111 109]
用于在循环中调用函数
x=[30 31 32 33; 110 123 122 124]
for i=1:length(x)
N = find_neighbor(x(:,i),nrow,ncol);
end
答案 0 :(得分:3)
这是使用bsxfun
的矢量化方法:
% define four neighbors as coordinate differences
d = [-1 0 ; 1 0 ; 0 -1 ; 0 1]';
% add to pixel coordinates
N = bsxfun(@plus, x, permute(d, [1 3 2]));
% make one long list for the neighbors of all pixels together
N = reshape(N, 2, []);
% identify out-of-bounds coordinates
ind = (N(1, :) < 1) | (N(1, :) > nrow) | (N(2, :) < 1) | (N(2, :) > ncol);
% and remove those "neighbors"
N(:, ind) = [];
permute
用于将四个不同邻居的“维度”移动到第三个数组索引中。这样,使用bsxfun
,我们得到每对原始像素坐标与每对相对邻居坐标的组合。越界检查假定nrow
属于第一个坐标,ncol
属于第二个坐标。
使用
ncol=128;
nrow=128;
x = [30 31 32 33; 110 123 122 124];
结果是
N =
29 30 31 32 31 32 33 34 30 31 32 33 30 31 32 33
110 123 122 124 110 123 122 124 109 122 121 123 111 124 123 125
不同像素的不同邻居最终可能是同一像素,因此列表中可能存在重复。如果您只想要每个结果像素一次,请使用
% remove duplicates?
N = unique(N', 'rows')';
获取
N =
29 30 30 30 31 31 31 32 32 32 33 33 33 34
110 109 111 123 110 122 124 121 123 124 122 123 125 124
答案 1 :(得分:1)
当多次调用小函数时,Matlab的性能非常糟糕。 Matlab方法是尽可能地进行矢量化。代码的矢量化版本:
function N = find_neighbor(x,nrow,ncol)
N = [min(x(1,:)+1,nrow), max(x(1,:)-1,1), x(1,:), x(1,:); x(2,:), x(2,:),min(x(2,:)+1,ncol), max(x(2,:)-1,1)];
end
和用法
x=[30 31 32 33; 110 123 122 124]
N = find_neighbor(x,nrow,ncol);
顺便说一句,对于边框上的像素,您的解决方案总是提供4个邻居。这是错的。例如,(1,1)的邻居应该只有(2,1)和(1,2),而你加上两个额外的(1,1)。 对此的解决方案非常简单 - 删除图像外的所有邻居
function N = find_neighbor(x,nrow,ncol)
N = [x(1,:)+1, x(1,:)-1, x(1,:), x(1,:); x(2,:), x(2,:),x(2,:)+1, x(2,:)-1];
N(:,N(1,:)<1 | N(1,:)> nrow | N(2,:)<1 | N(2,:)>ncol)=[];
end