我正在使用opencv中的背景减法进行对象跟踪。我拍了一个样本足球视频,我的目标是跟踪球员并过滤掉更大的场标记。由于非静态相机,大线也会像在此图像中一样被检测为移动:
我利用霍夫变换检测线条,在设置了适当的阈值后,能够过滤中途线,图像显示如下:
现在我担心过滤这两个弧。
问题1.我有什么办法可以做到这一点?我怎样才能利用"属性中的差异"弧(长和细)和一个玩家(一个紧凑的blob)有?
此外,Hough变换功能有时会报告许多误报(将一个高瘦的玩家视为一条直线,甚至连接两个玩家以显示更长的一条线)。
问题2.以何种方式指定要检测的"的最大厚度"线和并保持严格的标准,以检测线"只有"?
感谢。
答案 0 :(得分:1)
我有一个旧脚本,周围有类似的功能。不幸的是,它是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)
从第一张图片开始:
该算法使用erosion将blob与行分开。
然后使用
Moments过滤掉高大和小的斑点。时刻也用于定位每个斑点的中心。
get_blobs
返回玩家位置的2元组列表。您可以在最后一张图片上看到它们。
目前看来,剧本非常混乱。随意使用它,但我发布它主要是为了给你一些想法。