在开源视频网站随便找一个测试视频,计算光流, 由于flow是二维的向量,可以通过mean操作得出当前光流的方向。还可以使用FFMPEG倒放一下视频,看看计算的光流方向是否相反ffmpeg -i Car.mp4 -vf reverse -af areverse car.mp4
。
MASK
mask 使用 cv2.bitwise_and(image, image, mask=mask) 二维mask矩阵初始化为0,值设置为255为显示部分
- 简单方形模板
# 制作模板
mask = np.zeros(frame1.shape[:2], dtype="uint8")# 二维mask矩阵初始化为0,值设置为255为显示部分
cv2.rectangle(mask, (541, 192), (955, 557), 255, -1)
# 在mask中设置255的区域 宽度设置为-1为填充 ,颜色255 =(255,255,2555)
- 多边形模板
pts = np.array([[100, 50], [200, 50], [250, 250], [50, 250],[100, 50]], np.int32)#pts = np.array([[1013, 0],[715, 1605],[1060, 1610],[1151, 2],], np.int32)
cv2.fillPoly(mask, [pts], (255, 255, 255))# cv2.fillPoly(mask, [pts1,pts2], (255, 255, 255))
# 或
# pts = np.array([[100, 50], [200, 50], [250, 250], [50, 250]], np.int32)
# cv2.fillConvexPoly(mask, pts, (255, 255, 255))
import cv2
import numpy as np
cv2.namedWindow('Original', 0)
cv2.resizeWindow('Original', 600, 500)
cv2.namedWindow('Mask', 0)
cv2.resizeWindow('Mask', 600, 500)
cv2.namedWindow('RES', 0)
cv2.resizeWindow('RES', 600, 500)
cap = cv2.VideoCapture(cv2.samples.findFile("carr.mp4"))
ret, image = cap.read()
cv2.imshow("Original", image)
mask = np.zeros(image.shape[:2], dtype="uint8")# 二维mask矩阵初始化为0,值设置为255为显示部分
cv2.rectangle(mask, (0, 90), (290, 450), 255, -1)# 在mask中设置255的区域
cv2.imshow("Mask", mask)
masked = cv2.bitwise_and(image, image, mask=mask)
cv2.imshow("RES", masked)
cv2.waitKey(0)
调整MASK的位置
cv2.rectangle(mask, (541, 192), (955, 557), 255, -1)
代码
带有MASK的代码
# 略修改与注释
import numpy as np
import cv2
cap = cv2.VideoCapture(cv2.samples.findFile("carr.mp4"))
cv2.namedWindow('original frame', 0)
cv2.resizeWindow('original frame', 600, 500)
cv2.namedWindow('optical vis', 0)
cv2.resizeWindow('optical vis', 600, 500)
ret, frame1 = cap.read()
# 制作模板
mask = np.zeros(frame1.shape[:2], dtype="uint8")# 二维mask矩阵初始化为0,值设置为255为显示部分
cv2.rectangle(mask, (541, 192), (955, 557), 255, -1)# 在mask中设置255的区域
prvs = cv2.cvtColor(frame1, cv2.COLOR_BGR2GRAY)
hsv = np.zeros_like(frame1)
hsv[..., 1] = 255
while(1):
ret, frame2 = cap.read()
frame2 = cv2.bitwise_and(frame2, frame2, mask=mask)# 使用模板
if not ret:
print('No frames grabbed!')
break
next = cv2.cvtColor(frame2, cv2.COLOR_BGR2GRAY)
flow = cv2.calcOpticalFlowFarneback(prvs, next, None, 0.5, 3, 15, 3, 5, 1.2, 0)# 计算光流(只需要前后帧和一些参数即可)
# 由于flow是二维的向量,可以通过mean操作得出,当前光流的方向
print(np.mean(flow[:,:,1]))
mag, ang = cv2.cartToPolar(flow[..., 0], flow[..., 1])# 转为极坐标
# 用hsv矩阵 (480, 640, 3) 保存
hsv[..., 0] = ang*180/np.pi/2
hsv[..., 2] = cv2.normalize(mag, None, 0, 255, cv2.NORM_MINMAX)
bgr = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)# 转为彩色图像
cv2.imshow("original frame", frame2)
cv2.imshow('optical vis', bgr)
k = cv2.waitKey(30) & 0xff
k = cv2.waitKey(30) & 0xff
prvs = next
cv2.destroyAllWindows()
去掉可视化
import numpy as np
import cv2
cap = cv2.VideoCapture(cv2.samples.findFile("carr.mp4"))
cv2.namedWindow('original frame', 0)
cv2.resizeWindow('original frame', 600, 500)
# cv2.namedWindow('optical vis', 0)
# cv2.resizeWindow('optical vis', 600, 500)
ret, frame1 = cap.read()
# 制作模板
mask = np.zeros(frame1.shape[:2], dtype="uint8")# 二维mask矩阵初始化为0,值设置为255为显示部分
cv2.rectangle(mask, (541, 192), (955, 557), 255, -1)# 在mask中设置255的区域
prvs = cv2.cvtColor(frame1, cv2.COLOR_BGR2GRAY)
# hsv = np.zeros_like(frame1)
# hsv[..., 1] = 255
while(1):
ret, frame2 = cap.read()
frame2 = cv2.bitwise_and(frame2, frame2, mask=mask)# 使用模板
if not ret:
print('No frames grabbed!')
break
next = cv2.cvtColor(frame2, cv2.COLOR_BGR2GRAY)
flow = cv2.calcOpticalFlowFarneback(prvs, next, None, 0.5, 3, 15, 3, 5, 1.2, 0)# 计算光流(只需要前后帧和一些参数即可)
# 由于flow是二维的向量,可以通过mean操作得出,当前光流的方向
print(np.mean(flow[:,:,1]))
# mag, ang = cv2.cartToPolar(flow[..., 0], flow[..., 1])# 转为极坐标
# # 用hsv矩阵 (480, 640, 3) 保存
# hsv[..., 0] = ang*180/np.pi/2
# hsv[..., 2] = cv2.normalize(mag, None, 0, 255, cv2.NORM_MINMAX)
#
#
#
# bgr = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)# 转为彩色图像
# cv2.imshow("original frame", frame2)
# cv2.imshow('optical vis', bgr)
# k = cv2.waitKey(30) & 0xff
# k = cv2.waitKey(30) & 0xff
prvs = next
cv2.destroyAllWindows()
或
import numpy as np
import cv2
cap = cv2.VideoCapture(cv2.samples.findFile("carr.mp4"))
ret, frame1 = cap.read()
# 制作模板
mask = np.zeros(frame1.shape[:2], dtype="uint8")# 二维mask矩阵初始化为0,值设置为255为显示部分
cv2.rectangle(mask, (541, 192), (955, 557), 255, -1)# 在mask中设置255的区域
prvs = cv2.cvtColor(frame1, cv2.COLOR_BGR2GRAY)
while(1):
ret, frame2 = cap.read()
frame2 = cv2.bitwise_and(frame2, frame2, mask=mask)# 使用模板
next = cv2.cvtColor(frame2, cv2.COLOR_BGR2GRAY)
flow = cv2.calcOpticalFlowFarneback(prvs, next, None, 0.5, 3, 15, 3, 5, 1.2, 0)# 计算光流(只需要前后帧和一些参数即可)
# 由于flow是二维的向量,可以通过mean操作得出,当前光流的方向
print(np.mean(flow[:,:,1]))
prvs = next
cv2.destroyAllWindows()
cuda加速 略
- 换个cuda环境
conda install pytorch==1.8.1 torchvision==0.9.1 torchaudio==0.8.1 cudatoolkit=10.2 -c pytorch