25

我在检测圆形区域时遇到问题。我用opencv的HoughCircles函数试过了。然而,即使图像非常相似,函数的参数也必须不同才能检测到圆圈。

我尝试的另一种方法是遍历每个像素并检查当前像素是否为白色。如果是这种情况,则检查该区域中是否存在 blob 对象(到 blob 中心的距离小于阈值)。如果有,将像素附加到 blob,如果没有,则创建一个新 blob。这也无法正常工作。

有谁知道我怎样才能完成这项工作(90% 检测)?我附上了一个示例图像和另一个我标记了圆圈的图像。谢谢!

例子

带箭头的例子

更新: 感谢您到目前为止的帮助!这是我获取轮廓并按区域过滤它们的代码:

im = cv2.imread('extract_blue.jpg')
imgray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
im_gauss = cv2.GaussianBlur(imgray, (5, 5), 0)
ret, thresh = cv2.threshold(im_gauss, 127, 255, 0)
# get contours
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

contours_area = []
# calculate area and filter into new array
for con in contours:
    area = cv2.contourArea(con)
    if 1000 < area < 10000:
        contours_area.append(con)

这很整洁。我在图片上画了它们: 轮廓过滤区域

这是我按循环过滤的部分,它直接位于我按区域过滤的代码下方:

contours_cirles = []

# check if contour is of circular shape
for con in contours_area:
    perimeter = cv2.arcLength(con, True)
    area = cv2.contourArea(con)
    if perimeter == 0:
        break
    circularity = 4*math.pi*(area/perimeter*perimeter)
    print circularity
    if 0.8 < circularity < 1.2:
        contours_cirles.append(con)

但是,新列表“contours_cirles”是空的。我在循环中打印了“圆度”,值都在 10 000 到 100 000 之间。

更新#2: 纠正丢失的括号后,它现在可以工作了!

contours_cirles = []

# check if contour is of circular shape
for con in contours_area:
    perimeter = cv2.arcLength(con, True)
    area = cv2.contourArea(con)
    if perimeter == 0:
        break
    circularity = 4*math.pi*(area/(perimeter*perimeter))
    print circularity
    if 0.7 < circularity < 1.2:
        contours_cirles.append(con)

非常感谢你们!:)

example_done

4

2 回答 2

9

作为起点,您可以从以下内容开始:

  • 查找给定图像中的所有轮廓使用cv2.findContours()
  • 迭代每个轮廓:
    • 如果轮廓区域在给定范围内,请计算面积70 < area < 150。这将过滤掉一些非常小和大的轮廓。
    • 使用面积阈值过滤轮廓后,您需要检查轮廓的边缘数,这可以使用: cv2.approxPolyDP(),对于圆形 len(approx) 必须 > 8 但 < 23。或者您可以应用一些更复杂的操作在这里检测圆圈。

您应该尝试实现此方法并使用您以后编写的代码更新问题。

编辑: 正如@Miki 所建议的,有一种更好、更简洁的方法来检测几何形状是否为圆形,使用 circleity = 4pi(area/perimeter^2)并确定一个阈值,例如 0.9,以检查形状是否是圆形的。为完美圆circularity == 1。您可以根据需要微调此阈值。

您可以参考arcLength来找到轮廓的周长和contourArea来获得计算圆度所需的轮廓面积。

于 2017-02-13T12:28:57.500 回答
4

我们也可以尝试Hough Transformation检测图像中的圆圈并使用阈值来获得所需的结果(以红点为中心的绿色边界线中检测到的圆圈):

import cv2
import numpy as np

img = cv2.imread('rbv2g.jpg',0)
img = cv2.medianBlur(img,5)
cimg = cv2.cvtColor(img,cv2.COLOR_GRAY2BGR)

circles = cv2.HoughCircles(img,cv2.HOUGH_GRADIENT,1,10,
                            param1=50,param2=12,minRadius=0,maxRadius=20)

circles = np.uint16(np.around(circles))
for i in circles[0,:]:
    # draw the outer circle
    cv2.circle(cimg,(i[0],i[1]),i[2],(0,255,0),2)
    # draw the center of the circle
    cv2.circle(cimg,(i[0],i[1]),2,(0,0,255),3)

cv2.imshow('detected circles',cimg)
cv2.waitKey(0)
cv2.destroyAllWindows()

在此处输入图像描述

于 2017-02-14T06:04:44.537 回答