How can I zero out weak elements near stronger ones in the matrix?

I have a pixel matrix containing several dots and a lot of zero elements. Of those non-zero points, I want to drop those that have a stronger point in the range N with a matrix. Range - Euclidean distance between pixels.

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 

Update: This is what I came to. It iterates over all non-zero pixels and compares the current pixel with the largest of the neighboring areas. However, the area contains many pixels. Instead of selecting a region through index offsets, I need to somehow select a circular region. Moreover, I would appreciate it if there was a shorter path, perhaps replacing the loops with Matlab built-in functions like conv2 or imfilter .

 % 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 
+6
source share
3 answers

basic workflow to solve this problem can be described as described below -

  • Sort all nonzero points.
  • Start at the point with the highest point and set all nonzero points in your N-neighborhood to zeros.
  • Do the same for the second highest and set all non-zeros in your N-neighborhood to zeros , excluding non-zero points with a higher value than the current one . This exclusive part can be implemented using the very useful MATLAB triu inside codes.
  • Continue until any non-zero point is covered. Of course, as you move up this ladder, the search will be less, since the offer exception has been discussed previously.

These steps can be implemented using a vectorized approach without using special toolkits and assuming that A as an input is

 %// Distance parameter N = 2; %// Find all non-zero points and then sort them in descending manner [x,y] = find(A~=0) pts = [xy] [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; 

Associated functional code (for finding squares of Euclidean distances) -

 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; 

Code Execution -

 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 
+2
source

If you have an image processing toolbar (or one of the free alternatives mentioned in Try Hard answer ) installed, you can do this quite easily:

The imdilate function is basically a rolling max. filter. So what we do, for each pixel we are looking for a maximum in the neighborhood indicated by your radius R Then we compare the actual value with the maximum found, and if it is less, we set the value to zero.

 function A = zeroOutWeakElements(A, R) [X,Y] = ndgrid(-ceil(R):ceil(R)); neighborhood = (X.^2 + Y.^2)<=R^2; A(imdilate(A,neighborhood)>A) = 0; 

For large full matrices and small distances, this will also be significantly faster than the current solution. The benefits will wear out with sparse matrices and large radii, but I think you should check the evidence to be sure which is best.

+3
source

There are various freely available substitutes for MATLAB functions for image processing; for example, you can look into octave , or if that doesn't suit you, see, for example, this source , although it requires mex compilation.

You are looking for a filter with a sharp shutdown. Filters are a standard toolbar tool. Start by looking at the documentation of tools like imfilter and possibly imdilate and imopen .

+1
source

Source: https://habr.com/ru/post/982200/


All Articles