简体   繁体   English

python opencv - blob检测或圆检测

[英]python opencv - blob detection or circle detection

I am having problems detecting circle areas. 我在检测圆形区域时遇到问题。 I tried it with the HoughCircles function from opencv. 我尝试使用opencv中的HoughCircles函数。 However even though the images are pretty similar the parameters for the funtion have to be different in order to detect the cirles. 然而,即使图像非常相似,功能的参数也必须不同以便检测圆圈。

Another approach I tried was to iterate over every pixel and check if the current pixel is white. 我尝试的另一种方法是迭代每个像素并检查当前像素是否为白色。 If this is the case then check if there is a blob object in the area (distance to blob center smaller than a threshold). 如果是这种情况,则检查区域中是否存在blob对象(距离blob中心的距离小于阈值)。 If there is, append the pixel to the blob, if not then create a new blob. 如果有,请将像素附加到blob,如果没有,则创建一个新blob。 This also didn't work properly. 这也无法正常工作。

Has anyone a idea how I can make this work (90% detection) ? 有谁知道如何使这项工作(90%检测)? I attached a example image and another image where I marked the cirles. 我附上了一个示例图像和另一个我标记了圆圈的图像。 Thanks! 谢谢!

例

箭头的例子

UPDATE: Thank you for the help so far! 更新:感谢您的帮助到目前为止! This is the code where I acquire the contours and filter them by area: 这是我获取轮廓并按区域过滤它们的代码:

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)

This works pretty neat. 这非常整洁。 I drew them on the image: 我把它们画在图像上: contours_filtered_area

This is the part where I filtered by circularity, it goes straight below the code where I filter by 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)

However, the new list 'contours_cirles' is empty. 但是,新列表'contours_cirles'为空。 I printed 'circularity' in the loop and the values are all between 10 000 and 100 000. 我在循环中打印了'圆形',值都在10 000到10万之间。

UPDATE #2: After correcting the missing brackets it is working now! 更新#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)

Thanks a lot guys! 非常感谢! :) :)

example_done

As a starting point you may start with: 作为起点,您可以从以下开始:

  • Find all the contours in the given image using cv2.findContours() 使用cv2.findContours()查找给定图像中的所有轮廓
  • Iterate over each contour: 迭代每个轮廓:
    • calculate the area, if the area of contour is in a given range say 70 < area < 150 . 计算面积,如果轮廓面积在给定范围内,则说70 < area < 150 This will filter out some extremely smaller and large contours. 这将过滤掉一些极小和大的轮廓。
    • After filtering the contours with the area threshold, you need to check the number of edges of contour, which can be done using: cv2.approxPolyDP() , for a circle len(approx) must be > 8 but < 23. Or you may apply some more sophisticated operations to detect circles here. 使用区域阈值过滤轮廓后,需要检查轮廓边缘的数量,可以使用以下cv2.approxPolyDP()完成: cv2.approxPolyDP() ,对于圆圈len(大约)必须> 8但<23。或者您可以在这里应用一些更复杂的操作来检测圆圈。

You should try to implement this approach and update the question with the code that you will write henceforth. 您应该尝试实现此方法并使用您将在此后编写的代码更新问题。

EDIT: As suggested by @Miki, there is a better and cleaner way of detecting if a geometrical shape is of circular shape using circularity = 4pi(area/perimeter^2) , and decide a threshold such as 0.9, to check if the shape is circular. 编辑:正如@Miki所建议的那样,使用圆度= 4pi(面积/周长^ 2)检测几何形状是否为圆形形状并确定一个阈值(如0.9)以检查形状是否更好更清晰是循环的。 For perfect circle circularity == 1 . 对于完美的圆形circularity == 1 You may fine tune this threshold as per your needs. 您可以根据需要微调此阈值。

You may consult arcLength to find the perimeter of the contour and contourArea to get the area of the contour which are required to calculate the circularity. 您可以查阅arcLength以查找轮廓和contourArea的周长,以获得计算圆度所需的轮廓区域。

We could try Hough Transformation too to detect the circles in the image and play with the thresholds to get the desired result (detected circles in green boundary lines with red dots as centers): 我们也可以尝试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()

在此输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM