2017-02-13 198 views
8

我在检测圆圈区域时遇到问题。 我用opencv的HoughCircles函数试了一下。然而,尽管图像非常相似,但功能的参数必须不同才能检测到圆圈。python opencv - blob检测或圆圈检测

我尝试的另一种方法是迭代每个像素,并检查当前像素是否是白色。 如果是这种情况,那么检查该区域是否有斑点物体(斑点中心距离小于阈值)。如果有,则将像素追加到blob,如果没有,则创建一个新的blob。 这也没有正常工作。

有没有人有一个想法,我可以如何使这项工作(90%的检测)? 我附上了一个示例图像和另一个图像,我标记了圆圈。 谢谢!

example

example with arrows

UPDATE: 谢谢你的帮助迄今为止! 这是我获得的轮廓和面积过滤它们的代码:

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_filtered_area

这是我通过圆过滤部分,它直接在下面,我通过区域过滤代码:

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

+0

非常老的代码。但你可以检查这个。 https://github.com/bipul21/Colored-Ball-Tracking –

+0

'(面积/周长*周长)'这对我来说看起来很奇怪。你确定,你没有忘记任何括号? – Moritz

+0

是的,你是对的。 圆形度= 4 * math.pi *(面积/(周长*周长)) – cmplx96

回答

4

作为一个起点,你可能会开始:

    • 使用cv2.findContours()
    • 遍历每个轮廓找出给定图像中的所有轮廓
    • 计算面积,如果轮廓的面积在给定范围内,比如70 < area < 150。这将滤出一些非常小的和大的轮廓。
    • 使用面积阈值过滤轮廓后,需要检查轮廓边缘的数量,可以使用以下方法: cv2.approxPolyDP(),对于圆圈长度(大约)必须> 8,但是可以是< 23。 应用一些更复杂的操作来检测这里的圆圈。

你应该尝试实施这种做法,更新,你将从此编写代码的问题。

编辑: 如@Miki建议的,有一种检测更好,更洁净的方式,如果几何形状使用圆= 4PI(面积/周长^ 2)是圆形形状的,并且决定的阈值如0.9,以检查形状是否为圆形。为完美圆circularity == 1。你可以根据你的需要微调这个门槛。

您可以参考arcLength来查找轮廓的周长,并使用contourArea来获得计算圆度所需的轮廓面积。

+4

我会用_circularity_来衡量一个形状是一个圆的大小:“圆形度定义为:A衡量形状是多么接近圆形,例如一个正六边形比圆形有更高的圆形度,被定义为(\ frac {4 * \ pi * Area} {perimeter * perimeter})。这意味着圆的圆度为1,圆的正方形为0.785,依此类推。 – Miki

+1

非常感谢@Miki – ZdaR

1

我们可以尝试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() 

enter image description here