Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Closing contours with approxPolyDP or convexHull

Hello OpenCV Community,

I'm currently trying to close the contours on the right of this picture: PIC . 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: PICs

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: PIC. 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;
}

I will edit this post to add the pictures after I have the rights for it to do.

Best regards, Brk

Closing contours with approxPolyDP or convexHull

Hello OpenCV Community,

I'm currently trying to close the contours on the right of this picture: PICSample . 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: PICsEps3 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: PICConvexHull. 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;
}

I will edit this post to add the pictures after I have the rights for it to do.

Best regards, Brk