【问题标题】:OpenCV Convex Hull coordinatesOpenCV 凸壳坐标
【发布时间】:2018-05-17 07:13:48
【问题描述】:

我想找到凸包,以便在纸上均匀手绘三角形的边缘。使用图像处理进行平滑是不够的,因为我也需要检测这个三角形,如果使用 approxPolyDP 函数,手绘三角形往往有三个以上的点。 approxPolyDP 函数可以正确识别三角形的凸包。

问题是,我在图像中还有其他形状,在这些形状上创建了凸包。

Before convex hull is used: Notice the contour labelled 3

After convex hull is used: the end points have been joined and the contour labelled 3 forms a triangle

现在我想以某种方式排除轮廓 3 被检测为三角形。 为此,我的策略是从名为 hullMop 的 ArrayList 中完全删除此轮廓。这是因为我的三角形检测函数使用来自 hullMop 的轮廓,因此它甚至不会检查标记为 3 的轮廓。

extcontours 是使用凸包之前的轮廓。 此函数检查来自 hullMop 的点是否在 extcontours 内。如果不是,则必须从 hullMop 中删除,因为它们是由于凸包而生成的额外点集,或者换句话说,第二张图像中的红线。

现在,我觉得我的概念有一个漏洞。 openCV 文档说凸包返回原始数组的点的子集,换句话说,就是 extcontours 的点的子集。

我的问题是,我如何获得由 convexHull 函数创建的红线点。我不想使用 findContours 因为我觉得有更好的方法。

private void RemoveFalseHullTriangles(ArrayList<MatOfPoint> extcontours, ArrayList<MatOfPoint> hullMop, int width, int height) {
    //if every single point of hullmop doesnt touch or isn't inside extcontours, then that point must be the red line
    MatOfPoint2f Contours2f = new MatOfPoint2f();
    double [] newA = new double[2];
    int hullCounter = 0;
    A: for(int i =0;i<extcontours.size();i++) {
        MatOfPoint ExtCnt = extcontours.get(i);
        MatOfPoint HullCnt = hullMop.get(hullCounter);
        ExtCnt.convertTo(Contours2f, CvType.CV_32F);
        B: for (int j = 0; j < HullCnt.rows(); j++) {
            double[] pt = new double[2];
            pt[0] = HullCnt.get(j,0)[0];
            pt[1] = HullCnt.get(j,0)[1];

            if (Math.abs(Imgproc.pointPolygonTest(Contours2f, new Point(pt), true)) > 40) {
                    //Remove index from HullMop
                hullMop.remove(hullCounter);
                hullCounter--;
                break B;
            }


        }
        hullCounter++;
    }
}

因为 hullMop 只有 extcontours 点的子集,所以在使用凸包后,我可能永远不知道标记为 3 的轮廓红线的点。 除了使用 findContours 之外,还有其他方法可以获取凸包生成的红线的坐标吗?

【问题讨论】:

  • 我认为this question/answer 可能有助于回答您的问题。这里真正的问题不是如何获得凸包的点(这些点是您所说的轮廓点的子集),而是如何测试轮廓是否闭合(凸包总是关闭轮廓)。
  • 顺便说一下我在上面链接的那个答案:当回答者说“子轮廓”时,他们的意思是有一个轮廓是形状的外部,而轮廓是形状的内部。子轮廓是完全包含在另一个轮廓中的轮廓——因此闭合形状被定义为其中包含另一个轮廓的轮廓。
  • 我将绘制凸包并使用 distanceTransform 查找输入图像中没有对应关系的所有像素位置。

标签: android opencv image-processing convex-hull opencv-contour


【解决方案1】:

正如 Alexandar Reynolds 所提到的,问题实际上是首先检测开放轮廓并在找到凸包之前排除这些轮廓。 这里解释了寻找开放轮廓的方法: Recognize open and closed shapes opencv

基本上,如果外部轮廓在层次结构中没有子轮廓,则它是一个开放轮廓,必须在找到凸包之前将其排除(对于我的情况)。

【讨论】:

    猜你喜欢
    • 2018-10-27
    • 2012-06-13
    • 2011-08-21
    • 2013-07-09
    • 2016-09-28
    • 2012-06-28
    • 2015-02-07
    • 1970-01-01
    • 2021-11-07
    相关资源
    最近更新 更多