How to remove rows in a nested for loop?

2 views (last 30 days)
S.
S. on 14 Jan 2022
Edited: S. on 13 Apr 2022
I have a matrix Detected_center and a matrix Original_center with in each row a x and y coordinate. I want to compare each time one row of the Detected_center matrix with all the rows in the Original_center matrix and calculate the distance. If the row of the Detected_center is paired with a row of the Original_center as the minimal distance is within a threshold, I want that this row is removed from the Original_center matrix for the sake of computational time.
Can any help me out how to do this in a save way? The beneath way is not save as the nested for loop should change in length.
Threshold = 0.2
for i = 1:length(Detected_center)
for j = 1:length(Original_center)
Distance(j,1) = ...
end
[Min_Distance, position] = min(Distance);
if Min_Distance < Threshold
TP = TP + 1;
Original_center(position,:) = []; %Remove row from matrix, as it is coupled
else
FP = FP + 1;
end
end
Blue center is from the matrix Detected_center, and the red centers are the centers of the matrix Original_center. The distances are calculated from the blue center to all red centers with pythagoras. If the distance between the red center which is the closest to the blue center falls within the threshold, it should be removed from the matrix Original_center.
  8 Comments
S.
S. on 18 Jan 2022
Well, it decreases the change that you get the same distances, if you have integers it's more likely you will get the exact same distances.

Sign in to comment.

Accepted Answer

Matt J
Matt J on 20 Jan 2022
Edited: Matt J on 20 Jan 2022
It should start with the column (and therefore the Detected_center point) with the overall shortest distance to a Original_center point and then move on to the next Detected_center
This new processing rule can be implemented as follows,
Distances=pdist2(Original_center,Detected_center);
[M,N]=size(Distances);
discard=false(M,1);
while any(isfinite(Distances),'all')
[d,Rows]=min(Distances,[],1);
[dmin,col]=min(d);
if dmin<Threshold
row=Rows(col);
discard(row)=1;
Distances(row,:)=inf;
end
Distances(:,col)=inf;
end
Original_center(discard,:)=[];
TP=nnz(discard);
FP=M-TP;
  4 Comments
S.
S. on 8 Apr 2022
A small question about this. How would you write this is pseudocode to make it easy to understand for other readers? Do you have any ideas about that? I have some idea in mind aswell.

Sign in to comment.

More Answers (2)

Matt J
Matt J on 14 Jan 2022
Edited: Matt J on 14 Jan 2022
discard=ismembertol(Original_center,Detected_center,Threshold,'ByRows',1,'DataScale',1);
Original_center(discard,:)=[];
  7 Comments
S.
S. on 18 Jan 2022
Well, the centers in Original_center are the actual coordinates of oranges in a picture and the Detected_center are the predicted coordinates of the oranges in the picture of the oranges. So for a robot arm to grab the orange, I think the Euclidean distance is necessary and most suitable. If you think something else would be more appropriate, feel free to mention.

Sign in to comment.


Matt J
Matt J on 17 Jan 2022
For Euclidean distance,
discard=any( pdist2(Original_center,Detected_center)<Threshold ,2);
Original_center(discard,:)=[];
  8 Comments
S.
S. on 20 Jan 2022
The problem is, however, you calculate all the distances, while I calculate less distances, as if a pair is coupled the row is deleted. This is actually not the main issue, because there is now the following issue with the code. If you for example have the following distances with a threshold of 15:
If you use this code (my comment), the first Detected_center point will be coupled to the last row (first column), as that is the point with the minimal distance (8 pixels), while the last Detected_center point will NOT be coupled to any point as the first Detected_center point is already coupled to the last Detected_center point: 1 TP and 1 FP. --> So coupling seems not to be smart.
If you use this code (your comment), the first and last Detected_center point will be coupled to the last row (last Original center point), as it is for both the minimal distance: 2 TP
However, the correct way, is that the first Detected_center point is coupled to the second Original_center point, and the last Detected_center point will be coupled to the last Original_center point: 2 TP. How can I deal with/incorporate this? This is the only thing the software is sensitive to (I think). --> It should start with the column (and therefore the Detected_center point) with the overall shortest distance to a Original_center point and then move on to the next Detected_center point with the second overall shortest distance to a Original_center point etc.

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!