0

I am trying to calculate the distance between coordinates. I am detecting the movement from camera/video (using for tennis ball tracking/ OpenCV library) and saving the coordinates of all candidates so that means the ball movement and also the player or whatever noise there could be.

I store the coordinates in vector of points and also writing them to an excel file. So now I have my excel file with the 1 column = frame count, 2 column = number of candidates on that frame, and after that all the x and y coordinates.

QUESTION: What I want to do is calculate the distance of each point with all the points in the next frame. Let's say my excel with coordinates looks like that:

frame nr candidates X Y X Y X Y X Y 1 3 x1 y1 x2 y2 x3 y3 2 4 x5 y5 x6 y6 x7 y7 x8 y8 3 1 x9 y9 4 2 x10 y10 x11 y12 

Now I want to calculate all the distances so the x1,y1 and x5,y5 distance, x1,y1 and x6,y6. x1,y1 and x7,y7. x1,y1 and x8,y8 then x2,y2 and x5,y5 and so on. So if i have 3 candidates in the 1st frame and 4 on the 2nd frame I would need to get 12 distances. Then the same thing with 2nd and 3rd : x5,y5 and x9,y9 then x6,y6 and x9,y9... 3rd and 4th and so on.... d = sqrt((x2-x1)^2 + (y2-y1)^2) is the formula that I want to use. How could i do this? I know how could I do it if I had only 2 points, found an example code see below, but when i have a lot of coordinates how could i accomplish that?

#include <stdio.h> #include <iostream> #include <vector> using std::cout; using std::cin; //2 dimensional vector struct struct points { float x, y; }; int main() { int Dimensions = 0; float r; std::vector<points> pointvect; // vector declaration cout << "Set dimension of vector"; cin >> Dimensions; //with struct only 2D accepted for (int i = 0; i<Dimensions; i++) { // Input coordinates x, ye pointvect.resize(pointvect.size() + 1); //This will make pointvect be able to hold 1 more point at the end cout << "Input x:"; cin >> pointvect[i].x; //assign values cout << "Input y:"; cin >> pointvect[i].y; } for (int i = 0; i<pointvect.size() - 1; i++) { cout << "Distance between " << pointvect[i].x << "," << pointvect[i].y << " and " << pointvect[i + 1].x << "," << pointvect[i + 1].y << std::endl; //Pythagorean Theorem (also used to calculate distance can be found by taking sqrt ( (y2 - y1)^2 + (x2-x1)^2 ) float Distance = sqrt(pow((pointvect[i].y - pointvect[i + 1].y), 2) + pow((pointvect[i].x - pointvect[i + 1].x), 2)); cout << "Distance:" << Distance << std::endl; } system("pause"); return 0; } 

So i hope my question is understandable. Thank you in advance!

7
  • 2
    There is a lot of noise in the above question. How does the fact you are using xls matter to the question, for example? Commented Aug 7, 2014 at 17:22
  • Did you ever run your code? You are going out of bounds here: for (int i = 0; i<pointvect.size() - 1; i++)...float Distance = sqrt(pow((pointvect[i].y - pointvect[i + 1].y), 2) + pow((pointvect[i].x - pointvect[i + 1].x), 2)); You are looping up to size() - 1, but accessing an element at vector[size] (see the i + 1 index). Commented Aug 7, 2014 at 17:27
  • he is only looping up until just before pointvect.size()-1 since he is using less than operator, not lessthan+equal. So he's still within the bounds of the array. Commented Aug 7, 2014 at 17:37
  • @Lochemage - ok, my mistake. I see that < is being used. Commented Aug 7, 2014 at 17:44
  • @OP What do you want to do with all of the distances you find? Commented Aug 7, 2014 at 18:12

2 Answers 2

4

You would make things a lot easier if you rearrranged your data so that you create seperate vectors for each frame. Right now, you're munging all the data into one vector.

Even better, a std::map<int, std::vector<points>> would seem to be a better fit. You would then associate the frame number with the vector of points, making things a lot easier.

#include <map> #include <vector> #include <cmath> #include <iostream> struct points { float x, y; points(float px=0, float py=0) : x(px), y(py) {} }; typedef std::vector<points> PointVector; typedef std::map<int, PointVector> MapPointVector; float CalculateDistance(const points& p1, const points& p2) { float diffY = p1.y - p2.y; float diffX = p1.x - p2.x; return sqrt((diffY * diffY) + (diffX * diffX)); } void DisplayDistances(const MapPointVector& mp, int v1, int v2) { MapPointVector::const_iterator it1 = mp.find(v1); MapPointVector::const_iterator it2 = mp.find(v2); if (it1 != mp.end() && it2 != mp.end()) { const PointVector& vec1 = it1->second; const PointVector& vec2 = it2->second; for (size_t i = 0; i < vec1.size(); ++i) { for (size_t j = 0; j < vec2.size(); ++j) std::cout << CalculateDistance(vec1[i], vec2[j]) << "\n"; } } } int main() { MapPointVector mp; PointVector v1; PointVector v2; // assume v1 and v2 have been filled with info v1.push_back(points(1, 2)); v1.push_back(points(10, 20)); v1.push_back(points(5, 10)); v1.push_back(points(0, 0)); v2.push_back(points(11, 21)); v2.push_back(points(13, 20)); v2.push_back(points(5, 8)); v2.push_back(points(1, 1)); // associate them with frame 1 and frame 2 mp[1] = v1; mp[2] = v2; DisplayDistances(mp, 1, 2); // display the distances for frame 1 and frame 2. } 

This examples not only shows the nested loop, but also the usage of the std::map to associate the frame number with the sample set of data. The DisplayDistances function takes the frames we want to get the distances from and displays them.

Sign up to request clarification or add additional context in comments.

5 Comments

If the frames start at 0 and increment by 1 every time, wouldn't it be better to just use another vector and not have to worry about the map overhead?
If the frames start at 0 and increment by 1 every time If that can be guaranteed to be the case for now and later, maybe. Since using a map is simple, why not remove all doubt and use it?
The only way the map lookup and insert speed will match that of a vector is if you use hashing, which will mean that iterating will give you an undefined order, so that's not an option. Vectors just seem the easier more intuitive option here. To each his own though, I can see where you're coming from. :)
Thank you McKenzie this works exactly how I wanted. But in this example it does it with 2 frames/vectors. What if i have 200 of them? How would it look like then?
frames do start at 0 and increment by 1.
1

I store the candidates in a vector of points. You would use a nested for loop:

double dist(Point p, Point q) { return std::sqrt((p.x-q.x)*(p.x-q.x) + (p.y-q.y)*(p.y-q.y)); } ... std::vector<double> distances; for(int a=0; a<frame1.size(); a++) { for(int b=0; b<frame2.size(); b++) { distances.push_back( dist(frame1.at(a), frame2.at(b)) ); } } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.