尽管我意识到OpenCV的HoughCircles
没有“一刀切”的设置,但即使找到一组合理的参数,我也遇到了很多麻烦。
我的输入图像是下面的照片,其中包含一些非常明显的大黑圈以及周围的一些噪点:
我尝试使用p1
和p2
参数,以尝试准确地检测到四个黑圈(以及可选的顶部胶带卷-不需要,但是我不需要介意它是否匹配)。
import numpy as np
import cv2
gray = frame = cv2.imread('testframe2.png')
gray = cv2.cvtColor(gray, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray,(5,5),0)
# gray = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 5, 2)
p1 = 200
p2 = 55
while True:
out = cv2.cvtColor(gray, cv2.COLOR_GRAY2BGR)
circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, 1, 10, param1=p1, param2=p2, minRadius=10, maxRadius=0)
if circles is not None:
for (x, y, r) in circles[0]:
cv2.rectangle(out, (int(x - r), int(y - r)), (int(x + r), int(y + r)), (255, 0, 0))
cv2.putText(out, "r = %d" % int(r), (int(x + r), int(y)), cv2.FONT_HERSHEY_SIMPLEX, 0.3, (255, 0, 0))
cv2.putText(out, "p: (%d, %d)" % (p1, p2), (0, 100), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 4)
cv2.imshow('debug', out)
if cv2.waitKey(0) & 0xFF == ord('x'):
break
elif cv2.waitKey(0) & 0xFF == ord('q'):
p1 += 5
elif cv2.waitKey(0) & 0xFF == ord('a'):
p1 -= 5
elif cv2.waitKey(0) & 0xFF == ord('w'):
p2 += 5
elif cv2.waitKey(0) & 0xFF == ord('s'):
p2 -= 5
cv2.destroyAllWindows()
似乎我能做的最好的事情是多次检测到一个大圆圈,但根本检测不到一个小圆圈,或会得到很多误报:
我已经阅读了F **手册,但是它对我没有进一步的帮助:如何在某种程度上可靠地检测出圆圈,而这张图中的圆圈除外?
答案 0 :(得分:0)
使用HoughCircles
参数进行了一些手动调整,但这可以提供您想要的结果。我使用了OpenCV Wrapper library,它只是简化了一些事情。
import cv2
import opencv_wrapper as cvw
import numpy as np
frame = cv2.imread("tape.png")
gray = cvw.bgr2gray(frame)
thresh = cvw.threshold_otsu(gray, inverse=True)
opened = cvw.morph_open(thresh, 9)
circles = cv2.HoughCircles(
opened, cv2.HOUGH_GRADIENT, 1, 10, param1=100, param2=17, minRadius=5, maxRadius=-1
)
if circles is not None:
circles = np.around(circles).astype(int)
for circle in circles[0]:
cv2.floodFill(thresh, None, (circle[0], circle[1]), 155)
only_circles = thresh.copy()
only_circles[only_circles != 155] = 0
contours = cvw.find_external_contours(only_circles)
cvw.draw_contours(frame, contours, (255, 0, 255), thickness=2)
cv2.imwrite("tape_result.png", frame)
根据documentation注释中的建议,我使用HoughCircles
仅查找中心。
然后我用floodFill
填充了圆圈。请注意,最左边的圆非常靠近边缘。如果图像模糊,则洪水填充将进入背景。
披露:我是OpenCV Wrapper的作者。尚未添加霍夫环和洪水填充。