python opencv - 斑点检测或圆检测
python opencv - blob detection or circle detection
我在检测圆形区域时遇到问题。
我用 opencv 的 HoughCircles 函数试过了。然而,即使图像非常相似,函数的参数也必须不同才能检测到圆圈。
我尝试的另一种方法是遍历每个像素并检查当前像素是否为白色。
如果是这种情况,则检查该区域中是否存在斑点对象(到斑点中心的距离小于阈值)。如果存在,则将像素附加到 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' 是空的。我在循环中打印了 'circularity',值都在 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)
非常感谢你们! :)
作为起点,您可以从:
- 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.
您应该尝试实施此方法并使用您以后将编写的代码更新问题。
编辑:
正如@Miki 所建议的,有一种更好更简洁的方法来检测几何形状是否为圆形,使用 circularity = 4pi(area/perimeter^2),并确定一个阈值,例如 0.9,以检查形状是否为圆形。对于正圆circularity == 1
。您可以根据需要微调此阈值。
可参考arcLength to find the perimeter of the contour and contourArea计算圆度所需的轮廓面积
我们也可以尝试 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()
我在检测圆形区域时遇到问题。 我用 opencv 的 HoughCircles 函数试过了。然而,即使图像非常相似,函数的参数也必须不同才能检测到圆圈。
我尝试的另一种方法是遍历每个像素并检查当前像素是否为白色。 如果是这种情况,则检查该区域中是否存在斑点对象(到斑点中心的距离小于阈值)。如果存在,则将像素附加到 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' 是空的。我在循环中打印了 'circularity',值都在 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)
非常感谢你们! :)
作为起点,您可以从:
- 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.
您应该尝试实施此方法并使用您以后将编写的代码更新问题。
编辑:
正如@Miki 所建议的,有一种更好更简洁的方法来检测几何形状是否为圆形,使用 circularity = 4pi(area/perimeter^2),并确定一个阈值,例如 0.9,以检查形状是否为圆形。对于正圆circularity == 1
。您可以根据需要微调此阈值。
可参考arcLength to find the perimeter of the contour and contourArea计算圆度所需的轮廓面积
我们也可以尝试 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()