python opencv - 斑点检测或圆形检测
问题描述
我在检测圆形区域时遇到问题.我用opencv的HoughCircles函数试过了.然而,即使图像非常相似,函数的参数也必须不同才能检测到圆圈.
I am having problems detecting circle areas. I tried it with the HoughCircles function from opencv. However even though the images are pretty similar the parameters for the funtion have to be different in order to detect the cirles.
我尝试的另一种方法是遍历每个像素并检查当前像素是否为白色.如果是这种情况,则检查该区域中是否存在 blob 对象(到 blob 中心的距离小于阈值).如果有,将像素附加到 blob,如果没有,则创建一个新 blob.这也不能正常工作.
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). If there is, append the pixel to the blob, if not then create a new blob. This also didn't work properly.
有谁知道我怎样才能完成这项工作(90% 检测)?我附上了一个示例图像和另一个我标记了圆圈的图像.谢谢!
Has anyone a idea how I can make this work (90% detection) ? 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:
这是我按循环过滤的部分,它直接位于我按区域过滤的代码下方:
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)
但是,新列表contours_cirles"是空的.我在循环中打印了圆度",值都在 10 000 到 100 000 之间.
However, the new list 'contours_cirles' is empty. I printed 'circularity' in the loop and the values are all between 10 000 and 100 000.
更新 #2:纠正丢失的括号后,它现在可以工作了!
UPDATE #2: After correcting the missing brackets it is working now!
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)
非常感谢各位!:)
解决方案
作为一个起点,你可以从:
As a starting point you may start with:
- 使用
cv2.findContours() 查找给定图像中的所有轮廓
- 遍历每个轮廓:
- 计算面积,如果等高线的面积在给定范围内,比如
70 <面积<150代码>.这将过滤掉一些非常小的和大轮廓.
- 使用面积阈值过滤轮廓后,您需要检查轮廓的边缘数,可以使用以下方法完成:
cv2.approxPolyDP()
,对于一个圆 len(approx) 必须 > 8 但 <23. 或者你可以在这里应用一些更复杂的操作来检测圆圈.
- Find all the contours in the given image using
cv2.findContours()
- Iterate over each contour:
- calculate the area, if the area of contour is in a given range say
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.
- calculate the area, if the area of contour is in a given range say
您应该尝试实施此方法并使用您以后编写的代码更新问题.
You should try to implement this approach and update the question with the code that you will write henceforth.
正如@Miki 所建议的,有一种更好、更简洁的方法来检测几何形状是否为圆形,使用 circarity = 4pi(area/perimeter^2),并确定阈值,例如 0.9,检查形状是否为圆形.对于正圆
circarity == 1
.您可以根据需要微调此阈值.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. For perfect circle
circularity == 1
. You may fine tune this threshold as per your needs.您可以参考 arcLength 找到周长轮廓和 contourArea 的面积计算圆度所需的轮廓.
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.
- 计算面积,如果等高线的面积在给定范围内,比如
相关文章