javacv icon indicating copy to clipboard operation
javacv copied to clipboard

Accessing points returned by findContours()

Open b005t3r opened this issue 5 years ago • 3 comments

In C++ findContours() returns a vector<vector<Point> > which makes accessing each point in a contour quite easy, but I see no way of doing such thing with JavaCV? Is there a way to access these point with MatVectors and Mats?

b005t3r avatar Aug 13 '19 12:08 b005t3r

Should work fine with indexers yes: http://bytedeco.org/news/2014/12/23/third-release/ We could change the signature to PointVectorVector if that works better. Could you give it a try and let me know?

saudet avatar Aug 14 '19 01:08 saudet

I gave it a try and actually figured out how to access points from MatVector and how to populate a MatVector with points. Here are the examples:

// accessing contours
MatVector contours = ...
for (int i = 0; i < contours.size(); ++i) {
    IntIndexer points = contours.get(i).createIndexer();
    int size = (int) points.size(0); // points are stored in a Mat with a single column and multiple rows, since size(0), each element has two channels - for x and y - so the type is CV_32SC2 for integer points
    
    for (int j = 0; j < size; ++j) {
        int x = points.get(2 * j);
        int y = points.get(2 * j + 1);

        // do something with x and y
    }
}
// creating contours in the format e.g. drawContours() uses
MatVector contours = new MatVector();
int numContours = ...

for(int i = 0; i < numContours; ++i) {
    int pointsPerContour = ...

    // CV_32SC2 - 32-bit signed values, 2 channels
    Mat points = new Mat(pointsPerContour, 1, CV_32SC2);
    IntIndexer pointsIndexer = points.createIndexer();
    
    for(int j = 0; j < pointsPerContour; ++j) {
        pointsIndexer.put(2 * j, /* value for x */);
        pointsIndexer.put(2 * j + 1, /* value for y */);
    }

    contours.push_back(points);
}

b005t3r avatar Aug 14 '19 07:08 b005t3r

For those who come here in the future, looking for a way to deconstruct a MatVector... no need for messing around with Indexers.

        MatVector contours=new MatVector();
        findContours(edges, contours, new Mat(), RETR_LIST, CHAIN_APPROX_SIMPLE);

        for(int i=0;i<contours.size();i++) {
            Mat contour = contours.get(i);
            Rect contourBb=boundingRect(contour);
            // Now you can use contourBb.x(); contourBb.y(); contourBb.width(); contourBb.height();
        }

msmuenchen avatar Dec 27 '23 23:12 msmuenchen