2

I am working on an OpenCV code in C++ that basically tries to detect the boundary points of a page in an image. I use the findCountours() function to find the contours and after that, I try to find quads using the approxPolyDP() function and consider only quads with only 4 points. My code is based mostly on the squares.cpp code in the OpenCV samples.

It worked and returned 4 Points. And I was happy...but this happiness was not to last. :( I soon realised that the order in which the Points are returned appears to be random (different for different images). I want the algorithm to return the 4 Points in only a particular order (say, Top-left, then Top-right, then Bottom-right and then Bottom-left.

Getting the points in the same fixed order is critical for my application and hence, my question is "Is there any way to fix the order in which these points are detected and returned by the algorithm" (the code is almost same as the squares.cpp example of OpenCV). Any help will be really appreciated. And goes without saying, TIA. :D

Iceflame007
  • 147
  • 2
  • 11
  • convexHull has the option to order point cw or ccw. You can call convexHull on your four points. – Miki Aug 19 '15 at 21:17
  • @Miki , thanks for your suggestion but I think th problem with that approach is the starting point is not fixed. If the page is tilted towards right, then the bottom most point i.e, point with least Y coordinate (which is used by Convex Hull as starting point I think) is the Bottom-right corner of the Page. Similarly, when the page is tilted towards left, it takes the Bottom-Left point as the starting point. Hence, the order is not same in both cases. – Iceflame007 Aug 19 '15 at 21:33
  • 1
    Why not sort those points to your desired order? – Balaji R Aug 20 '15 at 02:51
  • 2
    Yeah, since you only have 4 points, sorting them yourself shouldn't be too much trouble – HenningJ Aug 20 '15 at 10:19

1 Answers1

0

If pointsVector is of type vector<cv::Point> and it has exactly the four coordinates of the rectangle or square that you need, use the following code.

struct sortY {
    bool operator() (cv::Point pt1, cv::Point pt2) { return (pt1.y < pt2.y);}
} mySortY;
struct sortX {
    bool operator() (cv::Point pt1, cv::Point pt2) { return (pt1.x < pt2.x);}
} mySortX;
std::sort(pointsVector.begin(),pointsVector.end(),mySortY);
std::sort(pointsVector.begin(),pointsVector.begin()+2,mySortX);
std::sort(pointsVector.begin()+2,pointsVector.end(),mySortX);

The above code will sort the pointsVector in the following order: topLeft, topRight, bottomLeft, bottomRight

r4ghu
  • 75
  • 2
  • 6