Closed. This question does not meet Stack Overflow guidelines。它当前不接受答案。












想改善这个问题吗?更新问题,以便将其作为on-topic用于堆栈溢出。

2个月前关闭。



Improve this question




只是在寻找有关如何解决不同颜色的高尔夫球的跟踪问题的一些建议。
我已经探索过使用absdiff()来获取跟踪球的帧之间的差异,但是它也可以吸收球员和俱乐部的运动。另外,使用HSV拾取特定的颜色球,但我希望能够拾取大多数颜色(白色,黄色,橙色,蓝色)。谢谢。

最佳答案


  • 对每个帧进行预处理
  • 应用GaussianBlur
    gaussian_blurr = cv2.GaussianBlur(frame, (22, 22), 0)
    
    您可以更改参数,以上参数仅是示例。
    假设下面是您的原始框架:
    python - 使用不同颜色的球在Python/Opencv中进行高尔夫球跟踪-LMLPHP
    高斯模糊将是:
    python - 使用不同颜色的球在Python/Opencv中进行高尔夫球跟踪-LMLPHP
    我们应用GaussianBlur来减少噪声和离群值。
  • 将帧转换为HSV比例。
    hsv = cv2.cvtColor(blurred, cv2.COLOR_BGR2HSV)
    
    python - 使用不同颜色的球在Python/Opencv中进行高尔夫球跟踪-LMLPHP
    转换hsv使我们能够检测当前帧中的球。
  • 应用inRange方法:
    greenLower = (29, 86, 6)
    greenUpper = (64, 255, 255)
    
    mask = cv2.inRange(hsv, greenLower, greenUpper)
    
    python - 使用不同颜色的球在Python/Opencv中进行高尔夫球跟踪-LMLPHP
    通过定义上下边界,我们声明29
  • 应用erodedilate:
    mask = cv2.erode(mask, None, iterations=2)
    mask = cv2.dilate(mask, None, iterations=2)
    
    python - 使用不同颜色的球在Python/Opencv中进行高尔夫球跟踪-LMLPHP
  • erodedilate通常用于预处理图像。erode删除对象边界上的像素。
    用空格分隔的dilate连接区域。 source

  • 找到球的中心

  • 查找轮廓
    cnts = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    
    等高线用于形状检测和识别。输出将是球位置的数组。我们需要蒙版中最大的轮廓来找到中心。
    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将覆盖面积最小的对象。moments将返回加权区域。 source
    更新:如果要查看球的质心,请添加以下内容:

    cv2.circle(frame, center, 5, (0, 0, 255), -1)
    
    结果:
    python - 使用不同颜色的球在Python/Opencv中进行高尔夫球跟踪-LMLPHP
  • 现在,如果我们合并所有框架,最终将是:
  • python - 使用不同颜色的球在Python/Opencv中进行高尔夫球跟踪-LMLPHP
  • 以球的质心为最终值:
  • python - 使用不同颜色的球在Python/Opencv中进行高尔夫球跟踪-LMLPHP

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

    关于python - 使用不同颜色的球在Python/Opencv中进行高尔夫球跟踪,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/63730808/

    10-14 15:52
    查看更多