c++ - opencv背景减法中的过滤线和曲线

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

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

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

现在我关心的是过滤这 2 个弧。

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

此外,Hough 变换函数有时会报告许多误报(将高瘦玩家检测为直线,甚至连接 2 个玩家以显示更长的线)。

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

谢谢。

最佳答案

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

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)

从你的第一张图片开始:

Input Image

算法使用erosion将 Blob 与线条分开。

Erosion

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

Output Image

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

就目前而言,脚本真的很乱。随意直接使用它,但我发布它主要是为了给你一些想法。

关于c++ - opencv背景减法中的过滤线和曲线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23841852/

相关文章:

matlab - 使用 OpenCV 的相机校准结果使用 matlab 显示相机方向

php - C++ 输出未在 PHP 中显示

C++ 随机整型函数

在特定索引处具有非常大的数组的 C 段错误

c - 如何检查IP地址是否对应于C中的localhost

c++ - 处理图像的多重转换

c++ - C++ 中的 3 维 vector -传递给函数之前的部分大小定义

c++ - 将带有换行符的字符串写入文本文件c++

mysql - 在静态库中链接 Mysqllib (MAC OS X.8.4, Xcode 4.6.3)

c++ - 这段 OpenCV 代码是在 GPU 上运行还是在 CPU 上运行?