user2447036
user2447036

Reputation:

OpenCV contour axis sort

I got this problem. I've found contours in my picture. Approximate them and all that stuff. Now, I want to sort them by Y axis and then by X axis. Is that possible?I'm using std::sort twice for this and I always get sort for one axis only. Please answer ASAP. Thanks

bool operator()(vector<Point> c1,vector<Point>c2){
    double a=boundingRect( Mat(c1)).y;
    double b=boundingRect( Mat(c2)).y;
    return a<b;
    }

This is an example for Y axis. Using same for X axis (y=>x).

Upvotes: 0

Views: 1621

Answers (2)

cxyzs7
cxyzs7

Reputation: 1227

Maybe your teacher wanted you to sort them by Y first, and if the Ys are the same, sort by X. If that's the case, you should write your comparator like

bool operator()(const vector<Point>& c1, const vector<Point>& c2) {
  // get bounding boxes for c1 and c2
  cv::Rect bbox1 = boundingRect(cv::Mat(c1));
  cv::Rect bbox2 = boundingRect(cv::Mat(c2));
  // if c1's top is lower than c2's bottom, order should be c2 c1
  if (c1.y > c2.y+c2.height-1) {
    return false;
  }
  // if c2's top is lower than c1's bottom, order should be c1 c2
  if (c2.y > c1.y+c1.height-1) {
    return true; 
  }
  // they have overlap in y direction, just sort them by their x
  return c1.x < c2.x;
}

Upvotes: 3

Aurelius
Aurelius

Reputation: 11329

This could be most succinctly accomplished using std::tie, if you have access to C++11 features.

bool operator()(vector<Point> c1,vector<Point>c2)
{
    double a=boundingRect( Mat(c1)).y;
    double b=boundingRect( Mat(c2)).y;
    return std::tie(a.y, a.x) < std::tie(b.y, b.x);
}

You then only need to call std::sort once.

Upvotes: 0

Related Questions