只是寻找一些关于如何解决不同颜色球的高尔夫球跟踪问题的建议。
我探索过使用absdiff()来获取帧之间的差异来跟踪球,但它也可以获取球员和球杆的运动。另外,使用 HSV 来拾取特定颜色的球,但我希望能够拾取大多数颜色(白色、黄色、橙色、蓝色)。谢谢。
申请GaussianBlur
gaussian_blurr = cv2.GaussianBlur(frame, (22, 22), 0)
Run Code Online (Sandbox Code Playgroud)
您可以更改参数,以上参数只是示例。
假设下面是您的原始框架:
高斯模糊将是:
我们申请GaussianBlur减少噪音和异常值。
将框架转换为 HSV 比例。
hsv = cv2.cvtColor(blurred, cv2.COLOR_BGR2HSV)
Run Code Online (Sandbox Code Playgroud)
转换hsv使我们能够检测当前帧中的球。
申请inRange方法:
greenLower = (29, 86, 6)
greenUpper = (64, 255, 255)
mask = cv2.inRange(hsv, greenLower, greenUpper)
Run Code Online (Sandbox Code Playgroud)
通过定义上下边界,我们通过声明 29 < 色调值 < 64、86 < 饱和度 < 255、6 < 值 < 255 来将球定位在框架中。
申请erode并dilate:
mask = cv2.erode(mask, None, iterations=2)
mask = cv2.dilate(mask, None, iterations=2)
Run Code Online (Sandbox Code Playgroud)
erode常用dilate于图像预处理。
erode删除对象边界上的像素。
dilate连接由空格分隔的区域。来源
寻找轮廓
cnts = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
Run Code Online (Sandbox Code Playgroud)
轮廓用于形状检测和识别。输出将是球位置的数组。我们需要掩模中最大的轮廓来找到中心。
c = max(cnts, key=cv2.contourArea)
((x, y), radius) = cv2.minEnclosingCircle(c)
M = cv2.moments(c)
center = (int(M["m10"] / M["m00"]), int(M["m01"] / M["m00"]))
Run Code Online (Sandbox Code Playgroud)
minClosingCircle将以最小面积覆盖物体。
moments将返回加权面积。来源
更新:如果您想查看球的质心,请添加以下内容:
cv2.circle(frame, center, 5, (0, 0, 255), -1)
Run Code Online (Sandbox Code Playgroud)
结果:
现在,如果我们组合所有帧,最终结果将是:
现在,对于不同类型的球,您需要声明上限和下限,正如我们声明的greenUpper和greenLower。然后应用从 1 开始的步骤。
完整代码:
import cv2
import imutils
import time
greenLower = (29, 86, 6)
greenUpper = (64, 255, 255)
vs = cv2.VideoCapture("input.mp4")
time.sleep(2.0)
while True:
_, frame = vs.read()
if frame is None:
break
blurred = cv2.GaussianBlur(frame, (11, 11), 0)
width, height = frame.shape[:2]
hsv = cv2.cvtColor(blurred, cv2.COLOR_BGR2HSV)
mask = cv2.inRange(hsv, greenLower, greenUpper)
mask = cv2.erode(mask, None, iterations=2)
mask = cv2.dilate(mask, None, iterations=2)
cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
center = None
if len(cnts) > 0:
c = max(cnts, key=cv2.contourArea)
((x, y), radius) = cv2.minEnclosingCircle(c)
M = cv2.moments(c)
center = (int(M["m10"] / M["m00"]), int(M["m01"] / M["m00"]))
# To see the centroid clearly
if radius > 10:
cv2.circle(frame, (int(x), int(y)), int(radius), (0, 255, 255), 5)
cv2.imwrite("circled_frame.png", cv2.resize(frame, (int(height / 2), int(width / 2))))
cv2.circle(frame, center, 5, (0, 0, 255), -1)
cv2.imshow("Frame", frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
vs.release()
cv2.destroyAllWindows()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6715 次 |
| 最近记录: |