我正在尝试实施SIFT算法。我有一个矩阵,比如D,维度(3,m,n)。对于矩阵中间层中的每个点,即A(2,:,:)(Matlab是1索引),我需要找到该点的3x3邻域中的局部最小值。我这样做的方式是一种非常天真的方式如下:
img = D(2, :, :);
for r = 2:size(img, 1)-1
for c = 2:size(img, 2)-1
nbr = D(:, (r-1):(r+1), (c-1):(c+1));
if abs(D(2,r,c) - min(nbr(:))) <= eps(0.5) || abs(D(2,r,c) - max(nbr(:))) <= eps(0.5)
x = [x; r];
y = [y; c];
end
end
end
但这种计算速度极慢。反正这样做更快吗?
答案 0 :(得分:0)
您可以尝试使用此代码:
Nr = size(D, 2); Nc = size(D, 3);
[r0,c0] = meshgrid(-1:1, -1:1);
[r,c] = meshgrid(2:Nr-1, 2:Nc-1);
r = r(:);
c = c(:);
nbr1 = squeeze(D(1, :, :));
nbr2 = squeeze(D(2, :, :));
nbr3 = squeeze(D(3, :, :));
ind1 = bsxfun(@plus,r,r0(:)') + (bsxfun(@plus,c,c0(:)')-1)*Nr;
nbr0 = nbr2(r + (c-1)*Nr);
nbrx = [nbr1(ind1), nbr2(ind1), nbr3(ind1)];
condition = abs(nbr0-min(nbrx,[],2)) <= eps(0.5) | abs(nbr0-max(nbrx,[],2)) <= eps(0.5);
x = r(condition);
y = c(condition);
[x,y]
大型矩阵应该更快。
要避免使用squeeze
功能,请重新排序索引(dimension (m, n, 3)
而不是dimension (3, m, n)
)。因此:
Nr = size(D, 1); Nc = size(D, 2);
nbr1 = D(:, :, 1);
nbr2 = D(:, :, 2);
nbr3 = D(:, :, 3);