我有一个视频,中间有一个移动的红球,我希望程序在整个视频中返回该对象的位置。我在网上阅读了很多例子,但我不太确定在 opencv 中什么是最好的方法。
import cv2
import numpy as np
coords = []
# Open the video
cap = cv2.VideoCapture('video-4.mp4')
# Initialize frame counter
while(1):
# Take each frame
_, frame = cap.read()
# Convert BGR to HSV
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
# define range of blue color in HSV
lower_red = np.array([100, 150, 0])
upper_red = np.array([140, 255, 255])
imgThreshHigh = cv2.inRange(hsv, lower_red, upper_red)
thresh = imgThreshHigh.copy()
countours,_ = cv2.findContours(thresh, cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
for cnt in countours:
area = cv2.contourArea(cnt)
best_cnt = cnt
M = cv2.moments(best_cnt)
cx,cy = int(M['m10']/M['m00']), int(M['m01']/M['m00'])
coord = cx, cy
print(coord)
cv2.imshow('frame',frame)
cv2.imshow('Object',thresh)
k = cv2.waitKey(5) & 0xFF
if k == 27:
break
cv2.destroyAllWindows()
我不知道为什么,但它只处理视频的几帧,而不是全部。
答案 0 :(得分:1)
我不清楚 best_cnt
轮廓是如何选择的。现在它只是选择最后一个。我认为它的目的是按大小过滤以确保选择小红色圆圈,但它并没有这样做。也许丢帧的发生是因为列表中的最后一个轮廓不是红色圆圈。
我会尝试按大小过滤并使轮廓小于给定的最大面积。
此外,看起来红色滤色器范围已关闭。我只能检测到球将红色过滤器值更改为:
lower_red = np.array([170, 0, 190])
upper_red = np.array([179, 255, 255])
为此,我计算了红色圆圈周围小区域中的最小值和最大值:
plt.imshow(hsv[255:275, 170:190, :])
np.min(hsv[255:275, 170:190, :], axis=0)
np.max(hsv[255:275, 170:190, :], axis=0)
并选择最小值和最大值,以便为红色在不同帧中的变化提供一些摆动空间。这需要使用视频中的所有帧进行微调,以确保使用这些限制不会遗漏任何红色阴影。