虽然我意识到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 **手册,但它对我没有帮助:我如何在某种程度上可靠地检测圆圈,除此图像中的圆圈外什么都没有?
使用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)
我使用HoughCircles
找到中心,正如documentation笔记中所建议的那样。
然后我用floodFill
来填充圆圈。请注意,最左边的圆圈非常靠近边缘。如果图像模糊,洪水填充将进入背景。
披露:我是OpenCV Wrapper的作者。尚未添加Hough Circles和洪水填充。