CV2中求轮廓最小外接圆的反向操作:最大内接圆求解与缺陷检测
最大内接圆实现方案
OpenCV没有内置cv2.minEnclosingCircle对应的反向接口,但是可以通过距离变换快速实现最大内接圆计算,步骤如下:
- 生成轮廓区域的二值掩码:创建和输入图像同尺寸的单通道黑图,调用
cv2.drawContours将目标轮廓内部填充为白色,得到掩码图。 - 执行距离变换:调用
cv2.distanceTransform对掩码图做距离计算,输出结果中每个像素的取值为该点到最近的轮廓边缘的距离。 - 提取最大内接圆参数:调用
cv2.minMaxLoc找到距离变换结果中的最大值,对应的坐标就是内接圆圆心,最大值本身就是内接圆半径。
参考代码:
import numpy as np import cv2 # 假设已提前读取灰度图gray,已检测得到目标轮廓contour # 生成轮廓填充掩码 mask = np.zeros_like(gray, dtype=np.uint8) cv2.drawContours(mask, [contour], -1, 255, cv2.FILLED) # 距离变换 dist_res = cv2.distanceTransform(mask, cv2.DIST_L2, 3) # 获取最大内接圆参数 _, max_radius, _, center = cv2.minMaxLoc(dist_res) # 绘制验证:cv2.circle(img, (int(center[0]), int(center[1])), int(max_radius), (0,255,0), 2)
缺陷区域直接识别方法
不需要计算内接圆也可以快速定位不圆的异常区域,利用你已经得到的最小外接圆参数即可实现,逻辑更简单:最小外接圆上所有边界点到圆心的距离都是外接圆半径,原轮廓上和外接圆半径差值超过阈值的区域就是缺陷区域。
实现步骤:
- 提取
cv2.minEnclosingCircle返回的圆心坐标(cx, cy)和半径r - 遍历轮廓上的所有点,计算每个点到圆心的欧氏距离
- 筛选出距离和r差值超过预设阈值的点,聚类后即可得到缺陷的坐标范围
参考代码:
(cx, cy), r = cv2.minEnclosingCircle(contour) defect_points = [] # 阈值可根据实际图像分辨率、精度要求调整 threshold = 3 for pt in contour: x, y = pt[0] dist = np.sqrt((x - cx)**2 + (y - cy)**2) # 右上角凹陷类缺陷满足dist < r - threshold的判定条件,直接筛选即可 if dist < r - threshold: defect_points.append((x, y))
如果需要更精准的缺陷范围,可对筛选出的defect_points做最小外接矩形计算,直接得到缺陷的bounding box。
内容的提问来源于stack exchange,提问作者Matthias
相关产品推荐
相关产品推荐

