【问题标题】:filtering lines and curves in background subtraction in opencv在opencv中过滤背景减法中的线条和曲线
【发布时间】:2014-07-13 13:24:13
【问题描述】:

我正在使用 opencv 中的背景减法进行对象跟踪。我拍摄了一段足球视频样本,我的目标是跟踪球员并过滤掉更大的场地标记。由于非静态摄像头,大线条也被检测为移动,如下图所示:

我利用霍夫变换来检测线条,在设置适当的阈值后,能够过滤中途的线条,图像如下所示:

现在我担心过滤这两条弧线。

问题 1. 我可以通过哪些方式做到这一点?如何利用弧(长而细)和播放器(紧凑的斑点)的“属性”差异?

此外,霍夫变换函数有时会报告许多误报(将高瘦球员检测为直线,甚至将 2 名球员连接以显示较长的线)。

问题2.如何规定“待检测”线的最大厚度,并保持严格的标准“只”检测线?

谢谢。

【问题讨论】:

    标签: c++ c opencv image-processing hough-transform


    【解决方案1】:

    我有一个用于类似功能的旧脚本。不幸的是,它是 Python 并且不使用霍夫变换函数。不过,您可能会发现它很有用。

    get_blobs 是重要功能,__main__ 是示例用法。

    import cv2
    
    def get_blobs(thresh, maxblobs, maxmu03, iterations=1):
        """
        Return a 2-tuple list of the locations of large white blobs.
        `thresh` is a black and white threshold image.
        No more than `maxblobs` will be returned.
        Moments with a mu03 larger than `maxmu03` are ignored.
        Before sampling for blobs, the image will be eroded `iterations` times.
        """
        # Kernel specifies an erosion on direct pixel neighbours.
        kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, (3, 3))
        # Remove noise and thin lines by eroding/dilating blobs.
        thresh = cv2.erode(thresh, kernel, iterations=iterations)
        thresh = cv2.dilate(thresh, kernel, iterations=iterations-1)
    
        # Calculate the centers of the contours.
        contours = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[0]
        moments = map(cv2.moments, contours)
    
        # Filter out the moments that are too tall.
        moments = filter(lambda k: abs(k['mu03']) <= maxmu03, moments)
        # Select the largest moments.
        moments = sorted(moments, key=lambda k: k['m00'], reverse=True)[:maxblobs]
        # Return the centers of the moments.
        return [(m['m10'] / m['m00'], m['m01'] / m['m00']) for m in moments if m['m00'] != 0]
    
    if __name__ == '__main__':
        # Load an image and mark the 14 largest blobs.
        image = cv2.imread('input.png')
        bwImage = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
        trackers = get_blobs(bwImage, 14, 50000, 3)
        for tracker in trackers:
            cv2.circle(image, tuple(int(x) for x in tracker), 3, (0, 0, 255), -1)
        cv2.imwrite('output.png', image)
    

    从您的第一张图片开始:

    该算法使用erosion 将斑点与线条分开。

    Moments 然后用于过滤掉高大和小的斑点。矩也用于定位每个 blob 的中心。

    get_blobs 返回玩家位置的 2 元组列表。您可以在最后一张图片上看到它们。

    就目前而言,脚本真的很混乱。可以直接使用,不过我发帖主要是想给大家一些思路。

    【讨论】:

      猜你喜欢
      • 2016-06-19
      • 1970-01-01
      • 1970-01-01
      • 2011-12-19
      • 2014-03-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多