Search code examples
javaandroidopencvjavacv

Android OpenCV Find contours


I need to extract the largest contour of an image. This is the code i'm currently using. gathered of a few snippets online

List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
Imgproc.findContours(outerBox, contours, new Mat(), Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);
double maxArea = -1;
int maxAreaIdx = -1;
for (int idx = 0; idx < contours.size(); idx++) {
    Mat contour = contours.get(idx);
    double contourarea = Imgproc.contourArea(contour);
    if (contourarea > maxArea) {
        maxArea = contourarea;
        maxAreaIdx = idx;
    }
}

and it seems to work. however, I'm not quite sure how to go about from here. I tried using Imgproc.floodFill, but I'm not quite sure how. this function requires a mast Mat of the same size as the original Mat +2 horizontal and +2 vertical. When I ran this on the contour contours.get(maxAreaIdx), it gave me an error. The code:

Mat mask = Mat.zeros(contour.rows() + 2, contour.cols() + 2, CvType.CV_8UC1);
int area = Imgproc.floodFill(contour, mask, new Point(0,0), new Scalar(255, 255, 255));

The error:

11-18 19:07:49.406: E/cv::error()(3117): OpenCV Error: Unsupported format or combination of formats () in void cvFloodFill(CvArr*, CvPoint, CvScalar, CvScalar, CvScalar, CvConnectedComp*, int, CvArr*), file /home/oleg/sources/opencv/modules/imgproc/src/floodfill.cpp, line 621

So basically my question is, how can I, after finding the contour with the largest area, to "highlight" it? I want everything else to be black, and the contour to be white

Thanks!


Solution

  • You can use the DrawContours function in OpenCV : http://docs.opencv.org/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html?highlight=drawcontours#drawcontours

    Or you can use this implementation in C++ (you can find the equivalent in Java in the OpenCV doc, just type OpenCV + the name of the function on google)

    Mat src = imread("your image"); int row = src.rows; int col = src.cols;
        //Create contour
    vector<vector<Point> > contours; 
    vector<Vec4i> hierarchy;
    Mat src_copy = src.clone();
        findContours( src_copy, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE);
    
    // Create Mask
    Mat_<uchar> mask(row,col);    
    for (int j=0; j<row; j++)
        for (int i=0; i<col; i++)
            {
                if ( pointPolygonTest( contours[0], Point2f(i,j),false) =0)
                {mask(j,i)=255;}
                else
                {mask(j,i)=0;}
            };
    

    try contours[1], contours[2]... to find the biggest one

    This is for displaying your contour:

    namedWindow("Contour",CV_WINDOW_AUTOSIZE);
    imshow("Contour", mask);