【问题标题】:OpenCV - Closing contours (Java)OpenCV - 闭合轮廓(Java)
【发布时间】:2023-03-18 21:14:01
【问题描述】:

我目前正在尝试关闭这张图片右侧的轮廓: Sample。 轮廓打开的原因在于kabeja,这是一个将DXF文件转换为图像的库。似乎在某些图像上它不会转换最后一个像素列(或行),这就是示例图片打开的原因。

我的想法是在 Opencv 中使用Core.copyMakeBorder(),为图片添加一些空间。之后我尝试使用Imgproc.approxPolyDP() 关闭轮廓,但这不起作用。我尝试了不同的 Epsilon 值:图片编辑:不能发布超过 2 个链接

原因可能是轮廓围绕着线。它永远不会关闭我想要它做的轮廓。

我尝试了另一种使用Imgproc.convexHull() 的方法,它提供了这个:ConvexHull。 这可能对我有用,但我不知道如何取出我需要的凸包部分并将其与轮廓合并以关闭它。

希望有人有想法。

这是我的 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;
}

这里是 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;
}

最好的问候, 刹车

【问题讨论】:

    标签: java opencv image-processing opencv-contour


    【解决方案1】:

    假设假设是正确的,最后一行(对于类似的列)没有转换(即丢失),然后尝试以下操作。假设 x 从左到右,y 从上到下。我们在图像底部添加一排空(白色?)像素,然后从左到右。下面是伪代码:

    // EMPTY - value of backgroung e.g. white for the sample image
    PixelType curPixel = EMPTY;
    int y = height - 1; // last row, the one we added
    for (int x = 0; x < width; ++x)
    {
        // img(y,x) - current pixel, is "empty"
        // img (y-1, x) - pixel above the current
        if (img(y-1, x) != img(y, x))
        {
            // pixel above isn't empty, so we make current pixel non-empty
            img(y, x) = img(y-1, x);
            // if we were drawing, then stop, otherwise - start
            if (curPixel == EMPTY)
                curPixel = img(y-1, x);
            else
                curPixel = EMPTY;
        }
        else
        {
            img(y, x) = curPixel; 
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2011-10-03
      • 1970-01-01
      • 2014-09-28
      • 2018-10-12
      • 1970-01-01
      • 2013-08-04
      • 2021-07-26
      • 2017-06-05
      • 1970-01-01
      相关资源
      最近更新 更多