如何将矩阵中较强元素附近的弱元素归零?

dan*_*jar 6 matlab distance image-processing matrix vectorization

我有一个包含一些点和许多零元素的像素矩阵.从那些非零点开始,我想丢弃那些在矩阵N范围内具有更强点的那些点.范围是像素之间的欧氏距离.

input  = [0.0 0.0 0.0 0.9 0.0 0.0 
          0.0 0.0 0.2 0.0 0.0 0.5 
          0.0 0.0 0.7 0.0 0.0 0.0 
          0.0 0.4 0.1 0.0 0.0 0.0];

output = [0.0 0.0 0.0 0.9 0.0 0.0   % 0.7 is the largest number in range
          0.0 0.0 0.0 0.0 0.0 0.5   % 0.2 got removed; was next to 0.9 and 0.7
          0.0 0.0 0.7 0.0 0.0 0.0   % 0.7 is the largest number in range
          0.0 0.0 0.0 0.0 0.0 0.0]; % 0.1 and 0.4 both got removed; were next to 0.7
Run Code Online (Sandbox Code Playgroud)

更新:这是我到目前为止所提出的.它迭代所有非零像素,并将当前像素与邻域中的最大像素进行比较.但是,邻域包含许多像素.我不是通过索引偏移来选择区域,而是以某种方式选择圆形区域.此外,如果有一个更短的方法,我可能会感激,也许用内置的Matlab函数替换循环,如conv2imfilter.

% Discard points near stronger points
points = find(Image > 0);
radius = args.Results.min_dist;
for i = 1:size(points)
    [index_y, index_x] = ind2sub(size(Image), points(i));
    %  Find neighborhood
    from_x = max(index_x-radius, 1);
    from_y = max(index_y-radius, 1);
    to_x = min(index_x+radius, size(Image, 2));
    to_y = min(index_y+radius, size(Image, 1));
    neighbors = Image(from_y:to_y, from_x:to_x);
    % Discard if there is a stronger neighbor
    largest = max(max(neighbors));
    if Image(index_y, index_x) < largest
        Image(index_y, index_x) = 0;
    end
end
Run Code Online (Sandbox Code Playgroud)

Div*_*kar 2

解决这个问题的方法basic workflow可以描述如下 -

  1. 对所有非零点进行排序。
  2. 从最高值点开始,将其 N 邻域内的所有非零点设置为零。
  3. 对第二高的非零点执行相同的操作,并将其 N 邻域内的所有非零点设置为零,排除比当前值更高的非零点triu这个排除部分可以通过代码中非常有用的 MATLAB 工具来实现。
  4. 继续下去,直到覆盖所有非零点。当然,当我们沿着这个阶梯向下移动时,由于前面讨论的排除条款,需要搜索的点将会减少。

这些步骤可以通过矢量化方法来实现,不使用特殊的工具箱并假设A输入 -

%// Distance parameter
N = 2; 

%// Find all non-zero points and then sort them in descending manner
[x,y] = find(A~=0)
pts = [x y]
[val,sorted_idx] = sort(A(A~=0),'descend')
pts = pts(sorted_idx,:)

%// Find euclidean distances
distmat = sqrt(squared_dist(pts,pts))

%// Find points to be removed (set to zero); then calculate their linear indices
rm_pts = pts(any(triu(distmat<N,1),1),:)
rm_lin_idx = sub2ind(size(A),rm_pts(:,1),rm_pts(:,2))

%// Use those linear indices to set those in the input as zeros
out = A;
out(rm_lin_idx) = 0;
Run Code Online (Sandbox Code Playgroud)

相关函数代码(求欧氏距离平方)-

function sq_distmat = squared_dist(A,B)

[nA,dim] = size(A);
nB = size(B,1);

A_ext = ones(nA,dim*3);
A_ext(:,2:3:end) = -2*A;
A_ext(:,3:3:end) = A.^2;

B_ext = ones(nB,dim*3);
B_ext(:,1:3:end) = B.^2;
B_ext(:,2:3:end) = B;

sq_distmat = A_ext * B_ext.';

return;
Run Code Online (Sandbox Code Playgroud)

代码运行-

A =
         0         0         0    0.9000         0         0
         0         0    0.2000         0         0    0.5000
         0         0    0.7000         0         0         0
         0    0.4000    0.1000         0         0         0
out =
         0         0         0    0.9000         0         0
         0         0         0         0         0    0.5000
         0         0    0.7000         0         0         0
         0         0         0         0         0         0
Run Code Online (Sandbox Code Playgroud)