Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

since it's std::vectors, all we need is a fitting 'less' operator, then we just sort() it.

// dummy data for demonstration:
vector<vector<Point>> contours(4);
contours[0].push_back(Point(3,111));
contours[0].push_back(Point(3,121));
contours[1].push_back(Point(81,13));
contours[1].push_back(Point(84,14));
contours[2].push_back(Point(33,55));
contours[2].push_back(Point(36,57));
contours[3].push_back(Point(133,25));
contours[3].push_back(Point(136,27));
for ( int i=0; i<contours.size(); i++ )
    cerr << Mat(contours[i]) << endl;

struct contour_sorter // 'less' for contours
{
    bool operator ()( const vector<Point>& a, const vector<Point> & b )
    {
        Rect ra(boundingRect(a));
        Rect rb(boundingRect(b));
        // scale factor for y should be larger than img.width
        return ( (ra.x + 1000*ra.y) < (rb.x + 1000*rb.y) );
    }
};

// apply it to the contours:
std::sort(contours.begin(), contours.end(), contour_sorter());

for ( int i=0; i<contours.size(); i++ )
    cerr << Mat(contours[i]) << endl;

[3, 111;  3, 121]
[81, 13;  84, 14]
[33, 55;  36, 57]
[133, 25;  136, 27]

[81, 13;  84, 14]
[133, 25;  136, 27]
[33, 55;  36, 57]
[3, 111;  3, 121]

since it's std::vectors, all we need is a fitting 'less' operator, then we just sort() it.

// dummy mock data for demonstration:
vector<vector<Point>> contours(4);
contours[0].push_back(Point(3,111));
contours[0].push_back(Point(3,121));
contours[1].push_back(Point(81,13));
contours[1].push_back(Point(84,14));
contours[2].push_back(Point(33,55));
contours[2].push_back(Point(36,57));
contours[3].push_back(Point(133,25));
contours[3].push_back(Point(136,27));
for ( int i=0; i<contours.size(); i++ )
    cerr << Mat(contours[i]) << endl;

struct contour_sorter // 'less' for contours
{
    bool operator ()( const vector<Point>& a, const vector<Point> & b )
    {
        Rect ra(boundingRect(a));
        Rect rb(boundingRect(b));
        // scale factor for y should be larger than img.width
        return ( (ra.x + 1000*ra.y) < (rb.x + 1000*rb.y) );
    }
};

// apply it to the contours:
std::sort(contours.begin(), contours.end(), contour_sorter());

for ( int i=0; i<contours.size(); i++ )
    cerr << Mat(contours[i]) << endl;

[3, 111;  3, 121]
[81, 13;  84, 14]
[33, 55;  36, 57]
[133, 25;  136, 27]

[81, 13;  84, 14]
[133, 25;  136, 27]
[33, 55;  36, 57]
[3, 111;  3, 121]

since it's std::vectors, all we need is a fitting 'less' operator, then we can just sort() it.

// mock data for demonstration:
vector<vector<Point>> contours(4);
contours[0].push_back(Point(3,111));
contours[0].push_back(Point(3,121));
contours[1].push_back(Point(81,13));
contours[1].push_back(Point(84,14));
contours[2].push_back(Point(33,55));
contours[2].push_back(Point(36,57));
contours[3].push_back(Point(133,25));
contours[3].push_back(Point(136,27));
for ( int i=0; i<contours.size(); i++ )
    cerr << Mat(contours[i]) << endl;

struct contour_sorter // 'less' for contours
{
    bool operator ()( const vector<Point>& a, const vector<Point> & b )
    {
        Rect ra(boundingRect(a));
        Rect rb(boundingRect(b));
        // scale factor for y should be larger than img.width
        return ( (ra.x + 1000*ra.y) < (rb.x + 1000*rb.y) );
    }
};

// apply it to the contours:
std::sort(contours.begin(), contours.end(), contour_sorter());

for ( int i=0; i<contours.size(); i++ )
    cerr << Mat(contours[i]) << endl;

[3, 111;  3, 121]
[81, 13;  84, 14]
[33, 55;  36, 57]
[133, 25;  136, 27]

[81, 13;  84, 14]
[133, 25;  136, 27]
[33, 55;  36, 57]
[3, 111;  3, 121]