使用 OpenCV 霍夫变换-圆检测,对周围背景比较敏感,容易误识别,不受控。若你也有此困惑,建议试试本文中的方法,识别效果佳,能够很好地排除类圆矩形的干扰,话不多说直接上代码。
代码
一、实现类
import math
import cv2
class CircleDetector(object):
'''
Parameters
----------
img: ndarray
A color image.
threshold: int or float
Image binary threshold.
minRadius: int or float
Minimum value of circle radius.
maxRadius: int or flaot
Maximum value of circle radius.
Returns
-------
A tuple of (center(x, y), size(w, h), angle)
'''
def detectCircles(self, image, threshold, minRadius, maxRadius):
circles = list()
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blur_image = cv2.GaussianBlur(gray_image, (5, 5), 0)
ret, thresh = cv2.threshold(gray_image, threshold, 255, cv2.THRESH_BINARY)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5), (-1, -1))
thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel, (-1, -1))
thresh = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, (-1, -1))
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
for cnt in contours:
if len(cnt) < 5:
continue
area = cv2.contourArea(cnt)
if area < (minRadius**2) * math.pi or area > (maxRadius**2) * math.pi:
continue
arc_length = cv2.arcLength(cnt, True)
radius = arc_length / (2 * math.pi)
if not (minRadius < radius and radius < maxRadius):
continue
ellipse = cv2.fitEllipse(cnt)
ratio = float(ellipse[1][0]) / float(ellipse[1][1])
if ratio > 0.9 and ratio < 1.1:
corner = cv2.approxPolyDP(cnt, 0.02 * arc_length, True)
cornerNum = len(corner)
if cornerNum > 4: # 当cornerNum=4时,识别矩形;而cornerNum>4时,识别圆
circles.append(ellipse)
return circles
二、使用
import cv2
from detector.circle_detector import CircleDetector
if __name__ == '__main__':
src = 0
cap = cv2.VideoCapture(src)
detector = CircleDetector()
while True:
if not cap.isOpened():
print('相机未打开')
break
ret, frame = cap.read()
if not ret:
continue
circles = detector.detectCircles(frame, 158, 50, 200)
img = frame.copy()
for circle in circles:
cv2.circle(img, (int(circle[0][0]), int(circle[0][1])), int(20), (0, 255, 0), thickness=5)
cv2.imshow('image', img)
key = cv2.waitKey(int(1000/30)) & 0xFF
if key == ord(' '):
break
三、注意事项
如果遇到无法识别,或者误识别,注意调整参数。文章来源:https://www.toymoban.com/news/detail-620902.html
- 确保你图中所绘圆的半径在[minRadius, maxRadius]之间。
- 建议使用白背景黑圆作为识别目标,否之请自行调整Threshold,直到识别效果达到最佳状态(可以查看二值化图片进行分析)。
效果图
文章来源地址https://www.toymoban.com/news/detail-620902.html
到了这里,关于【OpenCV】高精度识别圆(支持复杂场景下的圆)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!