OpenCV圈像形状检测及其区域

时间:2017-03-20 15:28:32

标签: c++ opencv geometry hough-transform

enter image description here我的图像有一个圆形状,包含另一个相似的形状。我正在尝试找到这两种形状的区域。我正在使用openCv c ++ Hough圆检测,但它没有检测到形状。 OpenCV中是否还有其他功能可用于检测形状并查找区域?

[编辑]图片已添加。

这是我的示例代码

int main()
{
  Mat src, gray;
  src = imread( "detect_circles_simple.jpg", 1 );resize(src,src,Size(640,480));
  cvtColor( src, gray, CV_BGR2GRAY );
  // Reduce the noise so we avoid false circle detection
  GaussianBlur( gray, gray, Size(9, 9), 2, 2 );

  vector<Vec3f> circles;

  // Apply the Hough Transform to find the circles
  HoughCircles( gray, circles, CV_HOUGH_GRADIENT, 1, 30, 200, 50, 0, 0 );
  cout << "No. of circles : " << circles.size()<<endl;
  // Draw the circles detected
  for( size_t i = 0; i < circles.size(); i++ )
  {
      Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
      int radius = cvRound(circles[i][2]);
      circle( src, center, 3, Scalar(0,255,0), -1, 8, 0 );// circle center     
      circle( src, center, radius, Scalar(0,0,255), 3, 8, 0 );// circle outline
      cout << "center : " << center << "\nradius : " << radius << endl;
   }
  exit(0);
  // Show your results
  namedWindow( "Hough Circle Transform Demo", CV_WINDOW_AUTOSIZE );
  imshow( "Hough Circle Transform Demo", src );

  waitKey(0);
  return 0;
}

2 个答案:

答案 0 :(得分:6)

我有类似的方法。

img1 = cv2.imread('disc1.jpg', 1)
img2 = img1.copy()
img = cv2.cvtColor(img1,cv2.COLOR_BGR2GRAY)

#--- Blur the gray scale image
img = cv2.GaussianBlur(img,(5, 5),0)

#--- Perform Canny edge detection (in my case lower = 84 and upper = 255, because I resized the image, may vary in your case)
edges = cv2.Canny(img, lower, upper)
cv2.imshow('Edges', edges )

enter image description here

#---Find and draw all existing contours
_, contours , _= cv2.findContours(edged, cv2.RETR_TREE, 1)
rep = cv2.drawContours(img1, contours, -1, (0,255,0), 3)
cv2.imshow(Contours',rep)

enter image description here

由于您正在分析圆形边缘的形状,因此在这种情况下确定轮廓的偏心率将有所帮助。

#---Determine eccentricity
cnt = contours
for i in range(0, len(cnt)):
    ellipse = cv2.fitEllipse(cnt[i])
    (center,axes,orientation) =ellipse
    majoraxis_length = max(axes)
    minoraxis_length = min(axes)
    eccentricity=(np.sqrt(1-(minoraxis_length/majoraxis_length)**2))
    cv2.ellipse(img2,ellipse,(0,0,255),2)

cv2.imshow('Detected ellipse', img2)

enter image description here

现在根据eccentricity变量给出的值,您可以得出轮廓是否为圆形的结论。阈值取决于您认为是圆形或近似圆形。

答案 1 :(得分:1)

如果你有完整的形状(边缘完全或几乎连接),通常更容易边缘检测 - &gt;轮廓 - &gt;分析轮廓形状。

当你只有一条线或圆的小片段时,霍夫线或圆非常有用,但调整起来很棘手

编辑:尝试使用cv :: adaptiveTnreshold获取边缘,然后使用cv :: findContours。

对于每个轮廓,将区域与周长进行比较,以查看它是否适合作为目标。然后执行cv :: fitEllipse检查它是否是一个圆并获得准确的中心。 FindCOntours还有一个模式,可以告诉你哪些轮廓在哪些轮廓内,哪些轮廓在另一个轮圈内很容易找到。

您可能(根据光线)找到具有2个或更多轮廓的相同圆圈,即。对于内缘和外缘。