在 Python/Opencv 中使用不同颜色的球跟踪高尔夫球 [英] golf ball tracking in Python/Opencv with different color balls

查看:223
本文介绍了在 Python/Opencv 中使用不同颜色的球跟踪高尔夫球的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

只是寻找一些关于如何解决不同颜色球跟踪高尔夫球问题的建议.

我已经探索过使用 absdiff() 来获取帧之间的差异以跟踪球,但它也可以获取球员和球杆的运动.此外,使用 HSV 拾取特定颜色的球,但我希望能够拾取大多数颜色(白色、黄色、橙色、蓝色).谢谢.

解决方案

    1. 对每一帧进行预处理


    • 应用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.

    • 应用erodedilate:

      mask = cv2.erode(mask, None, iterations=2)掩码 = cv2.dilate(掩码,无,迭代 = 2)

    erodedilate 通常用于图像预处理.

    erode 移除对象边界上的像素.

    dilate 连接由空格分隔的区域.

  • 现在,如果我们合并所有帧,最终将是:


  • 最终球的质心:


现在,对于不同种类的球,您需要声明上界和下界,就像我们声明了greenUppergreenLower.然后应用从 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.

解决方案

    1. 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 and dilate:

      mask = cv2.erode(mask, None, iterations=2)
      mask = cv2.dilate(mask, None, iterations=2)
      

    erode and dilate are commonly used for preprocessing images.

    erode removes pixels on object boundaries.

    dilate connecting areas that are separated by spaces. source

    1. 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. source

    Updated: 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆