在 Python/Opencv 中使用不同颜色的球跟踪高尔夫球 [英] golf ball tracking in Python/Opencv with different color balls
问题描述
只是寻找一些关于如何解决不同颜色球跟踪高尔夫球问题的建议.
我已经探索过使用 absdiff() 来获取帧之间的差异以跟踪球,但它也可以获取球员和球杆的运动.此外,使用 HSV 拾取特定颜色的球,但我希望能够拾取大多数颜色(白色、黄色、橙色、蓝色).谢谢.
- 对每一帧进行预处理
应用
GaussianBlur
gaussian_blurr = cv2.GaussianBlur(frame, (22, 22), 0)
您可以更改参数,以上参数只是示例.
假设下面是您的原始框架:
高斯模糊将是:
我们应用
GaussianBlur
来减少噪声和异常值.将帧转换为 HSV 比例.
hsv = cv2.cvtColor(blurred, cv2.COLOR_BGR2HSV)
转换
hsv
使我们能够检测当前帧中的球.应用
inRange
方法:greenLower = (29, 86, 6)绿色上层 = (64, 255, 255)掩码 = cv2.inRange(hsv, greenLower, greenUpper)
通过定义我们的上边界和下边界,我们通过声明 29 < 来定位框架中的球.色相值64, 86 <饱和度<255, 6 <值<255.
应用
erode
和dilate
:mask = cv2.erode(mask, None, iterations=2)掩码 = cv2.dilate(掩码,无,迭代 = 2)
erode
和dilate
通常用于图像预处理.erode
移除对象边界上的像素.dilate
连接由空格分隔的区域.现在,如果我们合并所有帧,最终将是:
最终球的质心:
现在,对于不同种类的球,您需要声明上界和下界,就像我们声明了greenUpper
和greenLower
.然后应用从 1 开始的步骤.
完整代码:
导入 cv2导入 imutils导入时间绿色低 = (29, 86, 6)绿色上层 = (64, 255, 255)vs = cv2.VideoCapture(input.mp4")时间.sleep(2.0)为真:_, frame = vs.read()如果框架是无:休息模糊 = cv2.GaussianBlur(frame, (11, 11), 0)宽度,高度 = frame.shape[:2]hsv = cv2.cvtColor(模糊,cv2.COLOR_BGR2HSV)掩码 = cv2.inRange(hsv, greenLower, greenUpper)掩码 = cv2.erode(掩码,无,迭代 = 2)掩码 = cv2.dilate(掩码,无,迭代 = 2)cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)cnts = imutils.grab_contours(cnts)中心 = 无如果 len(cnts) >0:c = max(cnts, key=cv2.contourArea)((x, y), 半径) = cv2.minEnclosureCircle(c)M = cv2.moments(c)center = (int(M[m10"]/M[m00"]), int(M[m01"]/M[m00"]))# 看清质心如果半径 >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(框架",框架)如果 cv2.waitKey(1) &0xFF == ord('q'):休息与释放()cv2.destroyAllWindows()
Just looking for some suggestions on how to approach the problem of golf ball tracking with different color balls.
I've explored using absdiff() to get the difference between frames to track the balls but it also picks up the player and club movement. Also, using HSV to pick up specific color balls but I want to be able to pick up most colors (white, yellow, orange, blue). Thanks.
-
- Do preprocess each frame
Apply
GaussianBlur
gaussian_blurr = cv2.GaussianBlur(frame, (22, 22), 0)
You can change the parameters, the above parameters are just examples.
Assume below is your original frame:
Gaussian Blur will be:
We apply
GaussianBlur
for reducing noise and outliers.Convert the frame to the HSV scale.
hsv = cv2.cvtColor(blurred, cv2.COLOR_BGR2HSV)
Converting
hsv
enable us to detect the ball in the current frame.Apply
inRange
method:greenLower = (29, 86, 6) greenUpper = (64, 255, 255) mask = cv2.inRange(hsv, greenLower, greenUpper)
By defining our upper and lower boundaries, we locate the ball in the frame by declaring, 29 < Hue values < 64, 86 < Saturation < 255, 6 < Value < 255.
Apply
erode
anddilate
:mask = cv2.erode(mask, None, iterations=2) mask = cv2.dilate(mask, None, iterations=2)
erode
anddilate
are commonly used for preprocessing images.erode
removes pixels on object boundaries.dilate
connecting areas that are separated by spaces. source -
- Find the center of the ball
Find Contours
cnts = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
Contours are used in shape detection and recognition. The output will be an array of ball location. We need the largest contours in the mask to find the center.
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"]))
minClosingCircle
will cover the object with minimum area.moments
will return the weighted area. sourceUpdated: If you want to see the centroid of the ball add the following:
cv2.circle(frame, center, 5, (0, 0, 255), -1)
Result:
Now, if we combine all frames, the final will be:
Final with the centroid of the ball:
Now, for different kinds of balls, you need to declare upper and lower bounds, as we declared greenUpper
and greenLower
. Then apply the steps starting from 1.
Full Code:
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()
这篇关于在 Python/Opencv 中使用不同颜色的球跟踪高尔夫球的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!