2014-03-02 146 views
0

我试图使用OpenCV4Android SDK和我的Android手机相机检测形状(三角形和正方形)。 到目前为止,我需要修改这部分的代码,但我不知道如何使用openCv Approxpoly函数来检测这些形状 任何帮助将不胜感激。在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); 
      } 
     } 
    } 

回答

3

由于轮廓检测返回的类型略有不同,以及PolyPolyDP期望的类型稍有不同。看看这个功能,我开发了几乎做你在找什么:

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只会有方形轮廓(或三角形,如果像你说的,你使用值3检查approxContour.size()高度时。)

,那么你可以用剩下的代码如下继续:

// 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); 
     } 
    } 
+0

我想我明白代码在做什么,但是如何在上面的代码中实现?我想为了检测三角形,轮廓尺寸应该是3。 – Iker