Remove duplicate locations and replace by a single one
4 views (last 30 days)
Show older comments
Hi.
I am trying to locate the 6 dots in my frequency domain image (its the FFT of a hexagonal array of spots)
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/159538/image.png)
Using a technique called "template matching" via matlabs function c=normxcorr2(template,Raw), I'm able to locate the 6 best matches. However, as below some of the matches occur that are 2 for the same object (just displaced by say 1 pixel in the image)
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/159540/image.png)
the location x, y and actual intensity of the 6 matches are:
75.0000 204.0000 0.7882
75.0000 205.0000 0.7882
140.0000 315.0000 0.7607
268.0000 93.0000 0.7607
333.0000 203.0000 0.7555
333.0000 204.0000 0.7555
How can I replace similar locations that are within say 10 pixels in either x or y of each other with the one that has the highest intensity. If the intensities are the same just pick the first one?
Thanks for any help Jason
1 Comment
Adam
on 6 Jan 2017
It would rather depend on the specific case as to what is best to do with cases up to 10 pixels away and with different intensities. In your example it is easy as they are 1 pixel apart and the same intensities.
The surface of the correlations could vary hugely over 10 pixels in both x and y though with massive dips between the two or it could be very smooth in which case averaging the x and y to take a centred location would make sense. Clearly in the first example with a very varied correlation this would not make sense though. But that comes back to the specific interpretation. Maybe if your correlation surface is so varied as to have big dips between two points within 10 pixels of each other then these should be considered as independent of each other anyway. Maybe this is a scenario that can never happen in your case?
In the example you give a simple variation of the unique function where you give a distance tolerance and pick the first or average would work fine.
Accepted Answer
Walter Roberson
on 6 Jan 2017
https://www.mathworks.com/help/matlab/ref/uniquetol.html
17 Comments
Walter Roberson
on 9 Jan 2017
aveA(k,:) = max(A(ia{k},:), 1);
In the case where there was only a single row, max by default works along the columns.
But I suspect you want something closer to
[~, maxidx] = max(A(ia{k},3));
aveA(k,:) = A(ik{k(maxidx)},:);
More Answers (2)
Image Analyst
on 6 Jan 2017
The way I find spikes in spectra that look like that is to first flatten the hump with adapthisteq(). Then maybe some noise reduction if needed. Then imregionalmax() or simple thresholding. Then if there are still small noise specs, call bwareaopen(). At this point you should have fairly large round spots. Finally call regionprops() to get the centroids of those spots.
2 Comments
Image Analyst
on 6 Jan 2017
Edited: Image Analyst
on 6 Jan 2017
You must not be doing it correctly. Try varying some of the parameters.
For what it's worth, attached is a demo where I take the log of the spectrum to sort of flatten it, and then threshold and filter.
People could help more if you'd attach your original image.
Kelly Kearney
on 10 Jan 2017
x = [...
75
75
140
268
333
333];
y = [...
204
205
315
93
203
204];
z = rand(size(x));
[xyunq, ixy] = findclump([x y], 10);
zmax = accumarray(ixy, z, [max(ixy) 1], @max);
[~,row] = ismember([(1:max(ixy))' zmax], [ixy z], 'rows');
Original points:
[x y z]
ans =
75 204 0.25999
75 205 0.78686
140 315 0.51158
268 93 0.56253
333 203 0.68479
333 204 0.092397
Clumped points, keeping one with highest z value:
[x(row) y(row) z(row)]
ans =
75 205 0.78686
140 315 0.51158
268 93 0.56253
333 203 0.68479
See Also
Categories
Find more on Matrix Indexing in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!