简体   繁体   中英

How to get the largest value from ArrayList<MatOfPoint>?

For starters, I'm trying to draw contours and convexhull on matrix in OpenCV Android. I followed these codes to my program shown like this:

/// Start contourImg
    Log.i(TAG, "called contourImg");

//init
    List<MatOfInt> hull         = new ArrayList<MatOfInt>();
    List<Point[]> hullPoints    = new ArrayList<Point[]>();
    List<MatOfPoint> hullMOP    = new ArrayList<MatOfPoint>();
    List<MatOfPoint> contours   = new ArrayList<MatOfPoint>();
    Mat overlay     = input.clone();
    Mat hierarchy   = new Mat(mask.rows(), mask.cols(), CvType.CV_8UC1, new Scalar(0));
    Point titik1    = new Point(0,0);

    Imgproc.findContours(mask, contours, hierarchy, Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_SIMPLE, titik1);

//Find the convex hull
    for (int i = 0; i < contours.size(); i++) {
        hull.add(new MatOfInt());
    }
    for (int i = 0; i < contours.size(); i++) {
        Imgproc.convexHull(contours.get(i), hull.get(i), false);
    }

// Convert MatOfInt to MatOfPoint for drawing convex hull

// Loop over all contours   
    for (int i = 0; i < contours.size(); i++) {
        Point[] points = new Point[hull.get(i).rows()];

    // Loop over all points that need to be hulled in current contour
        for (int j = 0; j < hull.get(i).rows(); j++) {
            int index = (int) hull.get(i).get(j,  0)[0];
            points[j] = new Point(contours.get(i).get(index, 0)[0], contours.get(i).get(index, 0)[1]);
        }
        hullPoints.add(points);
    }

// Convert Point arrays into MatOfPoint
    for (int i = 0; i < hullPoints.size(); i++) {
        MatOfPoint mop = new MatOfPoint();
        mop.fromArray(hullPoints.get(i));
        hullMOP.add(mop);
    }

// Draw contours + hull results
    for (int i = 0; i < contours.size(); i++) {
        Imgproc.drawContours(overlay, contours, i, green);
        Imgproc.drawContours(overlay, hullMOP, i, red); 
    }

Basically, the output will draw the obtained contours and convexhulls in green and red respectively. Unfortunately, the drawing becomes too absurd that small contours and convexhulls are being drawn as well.

Edit: this is image example. Notice the smaller red and green regions those are also appeared, while I want them not to appear.

凸包图像示例

The question is: how should I manipulate the hullMOP arraylist so that I get the index pointing to MatOfPoint with only consists of largest contours and convexhull? I tried to apply the same thinking as Imgproc.boundingRect() method by try finding the largest area (as follows):

for (int i = 0; i < contours.size(); i++) {
    boundRect[i] = Imgproc.boundingRect(polyMOP.get(i));
}
Rect bigRect = new Rect();
for (int i = 0; i < boundRect.length; i++) {
    if (bigRect.area() < boundRect[i].area()) {
        bigRect = boundRect[i];
    }
}
Core.rectangle(image3, bigRect.tl(), bigRect.br(), green, 2);

, but I can't get any hit. Any advice will help. Thanks before.

I'm sorry if it's a little bit too late.

I think you can use Imgproc.contourArea to check the largest area of both hullMOP and contours .

Here is an example:

Mat maxContour = null;
double maxContourarea=0;
for (int idx = 0; idx < contours.size(); idx++) {
    Mat contour = contours.get(idx);
    double contourarea = Imgproc.contourArea(contour);
    if (contourarea > maxContourarea){
        maxContourarea = contourarea;
        maxContour = contour;
    }
}

and hence maxContour will contain the largest contour with maxContourarea is the area value.

You can use Imgproc.RETR_EXTERNAL .
CV_RETR_EXTERNAL retrieves only the extreme outer contours. It sets hierarchy[i][2]=hierarchy[i][3]=-1 for all the contours. In other words, use Imgproc.findContours(mask, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE, titik1) .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM