Ask Your Question

Brk's profile - activity

2020-10-23 09:21:01 -0600 received badge  Student (source)
2020-04-03 03:32:47 -0600 received badge  Popular Question (source)
2017-01-18 06:16:20 -0600 received badge  Scholar (source)
2017-01-18 06:16:06 -0600 received badge  Supporter (source)
2017-01-17 06:53:23 -0600 received badge  Editor (source)
2017-01-17 06:40:47 -0600 asked a question Closing contours with approxPolyDP or convexHull

Hello OpenCV Community,

I'm currently trying to close the contours on the right of this picture: Sample . The reason for the opened contour lies in kabeja, a library to convert DXF files to images. It seems that on some images it doesn't convert the last pixel column (or row) and thats why the Sample picture is open.

I had the idea to use Core.copyMakeBorder() in Opencv, to add some space to the picture. After that I tried to use Imgproc.approxPolyDP() to close the contour, but this doesn't work. I tried this with different Epsilon values: Eps3 Eps50 Eps125

The reason for that is maybe that the contour surrounds the line. It never closes the contour where i want it to do.

I tried another method using Imgproc.convexHull(), which delivers this one: ConvexHull. This could be useful for me, but i have no idea how to take out the part of the convex hull i need and merge it together with the contour to close it.

I hope that someone has an idea.

Here is my method for Imgproc.approxPolyDP()

public static ArrayList<MatOfPoint> makeComplete(Mat mat) {
    System.out.println("makeComplete: START");
    Mat dst = new Mat();
    Core.copyMakeBorder(mat, dst, 10, 10, 10, 10, Core.BORDER_CONSTANT);

    ArrayList<MatOfPoint> cnts = Tools.getContours(dst);
    ArrayList<MatOfPoint2f> opened = new ArrayList<>();

    //convert to MatOfPoint2f to use approxPolyDP
    for (MatOfPoint m : cnts) {
        MatOfPoint2f temp = new MatOfPoint2f(m.toArray());
        opened.add(temp);
        System.out.println("First loop runs");
    }

    ArrayList<MatOfPoint> closed = new ArrayList<>();
    for (MatOfPoint2f conts : opened) {
        MatOfPoint2f temp = new MatOfPoint2f();
        Imgproc.approxPolyDP(conts, temp, 3, true);
        MatOfPoint closedTemp = new MatOfPoint(temp.toArray());
        closed.add(closedTemp);
        System.out.println("Second loop runs");
    }

    System.out.println("makeComplete: END");
    return closed;
}

And here the code for Imgproc.convexHull()

 public static ArrayList<MatOfPoint> getConvexHull(Mat mat) {
    Mat dst = new Mat();
    Core.copyMakeBorder(mat, dst, 10, 10, 10, 10, Core.BORDER_CONSTANT);

    ArrayList<MatOfPoint> cnts = Tools.getContours(dst);
    ArrayList<MatOfPoint> out = new ArrayList<MatOfPoint>();
    MatOfPoint mopIn = cnts.get(0);
    MatOfInt hull = new MatOfInt();
    Imgproc.convexHull(mopIn, hull, false);

    MatOfPoint mopOut = new MatOfPoint();
    mopOut.create((int) hull.size().height, 1, CvType.CV_32SC2);

    for (int i = 0; i < hull.size().height; i++) {
        int index = (int) hull.get(i, 0)[0];
        double[] point = new double[]{
                mopIn.get(index, 0)[0], mopIn.get(index, 0)[1]
        };
        mopOut.put(i, 0, point);
    }

    out.add(mopOut);
    return out;
}

Best regards, Brk