关于识别

最初方案 OpenCV

原方案是使用OpenCV通过图像处理根据阈值转换成黑白的二值图,并通过一些降噪及处理使图像更平滑,最终根据像素大小超过临界大小的的最大连通图是否是符合一个比较圆的区域来判断是否是网球。

# 预处理 - 高斯模糊减少噪声
blurred_img = cv2.GaussianBlur(frame, (5, 5), 0)
# 中值滤波进一步减少噪声
median_blur = cv2.medianBlur(blurred_img, 5)
# 转换为 HSV 颜色空间
hsv = cv2.cvtColor(median_blur, cv2.COLOR_BGR2HSV)
# 创建颜色掩膜
mask = cv2.inRange(hsv, self.lower, self.upper)
# 形态学操作(消除噪声)
# 定义结构元素(核),例如 5x5 的矩形
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
# 开运算,先腐蚀再膨胀,用于去除小的噪点
mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel, iterations=1)
ma=mask
# 闭运算,先膨胀再腐蚀,用于填充孔洞
mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel, iterations=3)
mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel, iterations=2)
mask = cv2.GaussianBlur(mask, (5, 5), 0)
# 查找轮廓
contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# 轮询处理每个轮廓
for cnt in contours:
    # 计算是圆形的概率
    circularity = 4 * np.pi * area / (perimeter * perimeter)
    # 要检测区域的像素大小要在临界大小内,且圆形率要大于0.8
    if area > min_area and area < max_area and circularity > 0.8:
        # 认为是网球,则进行后面的处理