首先要利用VideoCapture读入视频信息。采用颜色追踪的方法来确定小球位置,查找遮罩图的轮廓,确定该轮廓的包围框,将包围框的中心作为乒乓球的位置,更新乒乓球位置
具体代码:
import cv2
import numpy as np
def empty(a):
pass
def draw_direction(img, lx, ly, nx, ny):
dx = nx - lx
dy = ny - ly
if abs(dx) < 4 and abs(dy) < 4:
dx = 0
dy = 0
else:
r = (dx**2 + dy**2)**0.5
dx = int(dx/r*40)
dy = int(dy/r*40)
cv2.arrowedLine(img, (60, 100), (60+dx, 100+dy), (0, 255, 0), 2)#窗口设定
frameWidth = 640
frameHeight = 480
cap = cv2.VideoCapture("pingpangqiu.mp4")
cap.set(3, frameWidth)
cap.set(4, frameHeight)
cap.set(10, 80) # 设置亮度
pulse_ms = 30
lower = np.array([4, 180, 156]) # 橙色乒乓球4<=h<=32
upper = np.array([32, 255, 255])
targetPos_x = 0
targetPos_y = 0
lastPos_x = 0
lastPos_y = 0
while True:
_, img = cap.read()
imgHsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
imgMask = cv2.inRange(imgHsv, lower, upper) # 获取遮罩
imgOutput = cv2.bitwise_and(img, img, mask=imgMask)
contours, hierarchy = cv2.findContours(imgMask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) # 查找轮廓
imgMask = cv2.cvtColor(imgMask, cv2.COLOR_GRAY2BGR) # 转换后,后期才能够与原画面拼接,否则与原图维数不同
orange_lower = np.array([11, 43, 46])
orange_upper = np.array([25, 255, 255]) # 颜色色域
img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) # 转换为hsv
mask = cv2.inRange(img_hsv, orange_lower, orange_upper) # mask 启动
mask = cv2.erode(mask, None, iterations=2)
mask = cv2.GaussianBlur(mask, (3, 3), 0)
# erode 和 GaussianBlur 是用来使得图片或视频更加模糊的 这样可以突出色彩,色彩追踪也会更加精准
imgStack = np.hstack([img, imgOutput])
cv2.imshow('Horizontal Stacking', imgStack) # 显示
cv2.imshow('mask', mask)
if cv2.waitKey(pulse_ms) & 0xFF == ord('q'): # 按下“q”退出
print("Quit\n")
break
cap.release()
cv2.destroyAllWindows()