【问题标题】:Detecting triangles in OpenCV Approxpoly在 OpenCV Approxpoly 中检测三角形
【发布时间】:2014-03-02 17:46:51
【问题描述】:

我正在尝试使用 OpenCV4Android SDK 和我的 Android 手机摄像头检测形状(三角形和正方形)。 到目前为止,我需要修改这部分代码,但我不确定如何使用 openCv Approxpoly 函数来检测这些形状 任何帮助将不胜感激。

public void process(Mat rgbaImage) 
        {
            Imgproc.pyrDown(rgbaImage, mPyrDownMat);
            Imgproc.pyrDown(mPyrDownMat, mPyrDownMat);

        Imgproc.cvtColor(mPyrDownMat, mHsvMat, Imgproc.COLOR_RGB2HSV_FULL);

        Core.inRange(mHsvMat, mLowerBound, mUpperBound, mMask);
        Imgproc.dilate(mMask, mDilatedMask, new Mat());

        List<MatOfPoint> contours = new ArrayList<MatOfPoint>();

        Imgproc.findContours(mDilatedMask, contours, mHierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);

        // Find max contour area
        double maxArea = 0;
        Iterator<MatOfPoint> each = contours.iterator();
        while (each.hasNext()) 
        {
            MatOfPoint wrapper = each.next();
            double area = Imgproc.contourArea(wrapper);
            if (area > maxArea)
                maxArea = area;
        }

        //Imgproc.approxPolyDP(mSpectrum, approxCurve, epsilon, closed);

        // Filter contours by area and resize to fit the original image size
        mContours.clear();
        each = contours.iterator();

        while (each.hasNext()) 
        {
            MatOfPoint contour = each.next();
            if (Imgproc.contourArea(contour) > mMinContourArea*maxArea) 
            {
                Core.multiply(contour, new Scalar(4,4), contour);
                mContours.add(contour);
            }
        }
    }

【问题讨论】:

    标签: java android opencv computer-vision


    【解决方案1】:

    这有点繁琐,因为轮廓检测返回的类型和 approxPolyDP 所期望的类型略有不同。看看我开发的这个功能几乎可以满足您的需求:

    public static boolean isContourSquare(MatOfPoint thisContour) {
    
        Rect ret = null;
    
        MatOfPoint2f thisContour2f = new MatOfPoint2f();
        MatOfPoint approxContour = new MatOfPoint();
        MatOfPoint2f approxContour2f = new MatOfPoint2f();
    
        thisContour.convertTo(thisContour2f, CvType.CV_32FC2);
    
        Imgproc.approxPolyDP(thisContour2f, approxContour2f, 2, true);
    
        approxContour2f.convertTo(approxContour, CvType.CV_32S);
    
        if (approxContour.size().height == 4) {
            ret = Imgproc.boundingRect(approxContour);
        }
    
        return (ret != null);
    }
    

    好的,所以要在你的代码中使用这个函数,我会使用这样的东西:

    public static List<MatOfPoint> getSquareContours(List<MatOfPoint> contours) {
    
        List<MatOfPoint> squares = null;
    
        for (MatOfPoint c : contours) {
    
            if ((ContourUtils.isContourSquare(c)) {
    
                if (squares == null)
                    squares = new ArrayList<MatOfPoint>();
                squares.add(c);
            }
        }
    
        return squares;
    }
    

    所以在你的代码之后:

     Imgproc.findContours(mDilatedMask, contours, mHierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);
    

    您可以这样拨打电话:

    List<MatOfPoint> squareContours = getSquareContours(contours);
    

    squareContours 将只有方形轮廓(或三角形,如果你说,你在检查 approxContour.size().height 时使用值 3)

    然后您可以继续执行其余代码,如下所示:

    // Filter contours by area and resize to fit the original image size
        mContours.clear();
        each = squareContours.iterator();
    
        while (each.hasNext()) 
        {
            MatOfPoint contour = each.next();
            if (Imgproc.contourArea(contour) > mMinContourArea*maxArea) 
            {
                Core.multiply(contour, new Scalar(4,4), contour);
                mContours.add(contour);
            }
        }
    

    【讨论】:

    • 我想我明白代码在做什么,但是我如何在上面的代码上实现呢?我想为了检测三角形,轮廓大小应该是 3。
    猜你喜欢
    • 2018-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-29
    • 1970-01-01
    相关资源
    最近更新 更多