Remove centroid locations of objects that are too close

Hi, I have a list of centroid locations of spots in an image (xf, yf). The spots are randomly distributed. I want to remove the centroid locations that are too close to each other, or say within a distance of d. I've got to the following but not sure what to do next. Also is there a better way to do this ratrher than use loops?
%using a loop
M=[];
for j=1:length(xf)
for i=1:length(xf)
dx=xf(j)-xf(i);
dy=yf(j)-yf(i);
dr=sqrt(power(dx,2)+power(dy,2));
M(j,1)=xf(j);
M(j,2)=yf(j);
M(j,3)=xf(i);
M(j,4)=yf(i);
M(j,5)=dr;
end
end

댓글 수: 2

If two spots are less than d apart should both be removed? If not, by what criterion do you decide which spot remains?
To me it sounds like both are to be removed. This is easily done with pdist2.

댓글을 달려면 로그인하십시오.

 채택된 답변

Matt J
Matt J 2022년 8월 9일
편집: Matt J 2022년 8월 9일
A=[xf(:) yf(:)];
D=pdist2(A,A);
D(D==0)=inf; %retroactive EDIT
keep = all(D>d,1);
xf=xf(keep);
yf=yf(keep);

댓글 수: 7

Jason
Jason 2022년 8월 9일
편집: Jason 2022년 8월 9일
Thankyou Matt. Its almost there. Its not removing the 2nd centroid of the "close pair" of objects.
I've set the cut of distance to be 40.
A and D from your code gives this:
A =
15.88 18.43
33.48 14.99
53.49 37.71
D =
0 17.94 42.27
17.94 0 30.27
42.27 30.27 0
This is my Matrix where col 1,2 are centroids of each spot, col 3,4 are then centroid of all other spots, col 5 is the distance between all pairs of spots.:
M =
15.88 18.43 15.88 18.43 0
15.88 18.43 33.48 14.99 17.94
15.88 18.43 53.49 37.71 42.27
33.48 14.99 15.88 18.43 17.94
33.48 14.99 33.48 14.99 0
33.48 14.99 53.49 37.71 30.27
53.49 37.71 15.88 18.43 42.27
53.49 37.71 33.48 14.99 30.27
53.49 37.71 53.49 37.71 0
Make sure you are using my most updated version. Your D matrix should have NaNs along the diagonal. Not zeros.
I see now that D should have Infs along the diagonals, not NaNs, but even so with d=40, none of your objects are sufficiently remote, so all centroids get removed. With d=30, one blob remains.
A =[
15.88 18.43
33.48 14.99
53.49 37.71]; d=30;
D=pdist2(A,A);
D(D==0)=Inf
D = 3×3
Inf 17.9330 42.2638 17.9330 Inf 30.2754 42.2638 30.2754 Inf
keep = all(D>d,1)
keep = 1×3 logical array
0 0 1
A=A(keep,:)
A = 1×2
53.4900 37.7100
Perfect, thanks. Can you explain the bit about replacing the Nan with Inf, I don't follow this part.
Thanks
Jason
We don't want to consider the distance between an object and itself, so we need to set the diagonal of D to something that will automatically satisfy the distance cut-off criterion.
Of course, its clear now, thankyou
Just to add, when I had over 400 objects, akthough i do other operations, using the for loop took 110s.using the pdist2 approach took just under 2s. Remarkable!

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

yes,sir,may be use pdist2, such as
xf = rand(1, 10);
yf = rand(1, 10);
%using a loop
M=[];
for j=1:length(xf)
for i=1:length(xf)
dx=xf(j)-xf(i);
dy=yf(j)-yf(i);
dr=sqrt(power(dx,2)+power(dy,2));
M(end+1,1)=xf(j);
M(end,2)=yf(j);
M(end,3)=xf(i);
M(end,4)=yf(i);
M(end,5)=dr;
end
end
% second method
A=[xf(:) yf(:)];
B=pdist2(A,A);
C=B';
C=C(:);
isequal(M(:,end),C)
ans = logical
1

카테고리

도움말 센터File Exchange에서 Image Processing and Computer Vision에 대해 자세히 알아보기

제품

릴리스

R2022a

질문:

2022년 8월 8일

댓글:

2022년 8월 9일

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by