1

I have to do develop a similar algorithm as in Remove top section of image above border line to detect text document, but in Java 1.8 using JavaCV.

The method signature in Python is

cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)

However in Java it appears to be:

MatVector mt = new MatVector();
findContours(dst, mt, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);

I'm stuck into finding the contours and sorting them from biggest to lowest. How do I go about sorting from biggest to lower contours?

My code:

         Mat image = imread(imagePath);
         Mat gray = new Mat();
         cvtColor(mat, gray, COLOR_BGR2GRAY);
         Mat grayImg = convertToGray(mat);
         GaussianBlur(grayImg, grayImg, new Size(3, 3), 0);
         Mat dst = new Mat();
         threshold(grayImg, dst, 0, 255,THRESH_BINARY + THRESH_OTSU);

        // Find contours and sort for largest contour
        MatVector mt = new MatVector();
        findContours(dst, mt, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);

How to access contours suggestion from https://github.com/bytedeco/javacv/issues/1270:

    // 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
    }
}

Thank you

Napkins
  • 33
  • 4
  • 1
    Use the contourArea() feature equivalent. See https://docs.opencv.org/4.1.1/d3/dc0/group__imgproc__shape.html#ga2c759ed9f497d4a618048a2f56dc97f1. Then sort on area. – fmw42 Sep 25 '20 at 19:12

1 Answers1

0

As @fmw42 said, I refactored the code to look into the contourArea().

See below,

    Mat mask = new Mat();
    Mat gray = new Mat();
    Mat denoised = new Mat();
    Mat bin = new Mat();
    Mat hierarchy = new Mat();
    MatVector contours = new MatVector();

    cvtColor(mat, gray, COLOR_BGR2GRAY);
    //Normalize
    GaussianBlur(gray, denoised, new Size(5, 5), 0);
    threshold(denoised, mask, 0, 255, THRESH_BINARY_INV | THRESH_OTSU);
    normalize(gray, gray, 0, 255, NORM_MINMAX, -1, mask);
    // Convert image to binary
    threshold(gray, bin, 150, 255, THRESH_BINARY);
    // Find contours
    findContours(bin, contours, hierarchy, RETR_TREE, CHAIN_APPROX_NONE);
    long contourCount = contours.size();
    System.out.println("Countour count " + contourCount);

    double maxArea = 0;
    int maxAreaId = 0;
    for (int i = 0; i < contourCount; ++i) {
        // Calculate the area of each contour
        Mat contour = contours.get(i);
        double area = contourArea(contour);
        if(area > maxArea){
            maxAreaId = i;
            maxArea = area;
        }

    }
Napkins
  • 33
  • 4