简介
通常我们得到了一段视频,可能只需要其中部分区域的内容,其他的可以认为是我们不关注的内容。
比如我们做分类识别,需要某种样本,利用了摄像头进行拍摄
,但是我们的需要的内容只在视频中的某个固定区域内出现了,我们只想要保存该部分区域内的视频
,然后利用脚本完成按帧截取
,从而完成数据集的收集。
工具应用场景
- 需求:需要的样本目标只会出现在一个固定的视野内。
- 设置:手动指定原视频中我们感兴趣的区域
- 输出:将原视频中我们指定的感兴趣区域截取下来存储为avi视频格式
- 用途:后续可以配合对视频截取图像的脚本来完成样本的收集
演示
流程图
代码
包含了详细注释,不懂函数啥意思的同学自己查一下!
已经对参考文章的代码进行了重构,更加结构化便于理解!
使用
- 1.
camera = cv2.VideoCapture('/home/cheng/Desktop/1.mp4')
这一行输入自己的视频路径 - 2.运行代码后对画面点击两次,分别是想要选择的
区域左上角
,想要选择的区域右下角
,然后敲击回车
完全选择。 - 3.在截取的过程中,如果视频太长按下
q
键进行退出
import cv2
import numpy as np
def OnMouseAction(event,x,y,flags,param): # 鼠标触发记录点位
global coor_x, coor_y, coor
if event == cv2.EVENT_LBUTTONDOWN:
print("左键点击")
print("%s" %x,y)
coor_x ,coor_y = x ,y
coor_m = [coor_x,coor_y]
coor = np.row_stack((coor,coor_m))
elif event==cv2.EVENT_LBUTTONUP:
cv2.line(img, (coor_x, coor_y), (coor_x, coor_y), (255, 255, 0), 7)
def video_info(camera, fp在这里插入图片描述s):
if (camera.isOpened()): # 判断视频是否成功打开
print('视频已打开')
else:
print('视频打开失败!')
print('视频帧率:%d fps' %fps) # 获取视频帧率
size = (int(camera.get(cv2.CAP_PROP_FRAME_WIDTH)),
int(camera.get(cv2.CAP_PROP_FRAME_HEIGHT)))
print ('原视频尺寸:'+str(size)) # 输出视频尺寸
def get_chosse_action(img, OnMouseAction):
while True:
cv2.imshow('IImage',img)
cv2.setMouseCallback('IImage',OnMouseAction)
k = cv2.waitKey(1) & 0xFF
if k == ord(' '): # 空格完成退出操作
break
cv2.destroyAllWindows() # 关闭页面
def output_choose_vedio(coor, frame):
Video_choose = frame[coor[1,1]:coor[2,1],coor[1,0]:coor[2,0]]
out.write(Video_choose)
cv2.imshow('Video_choose', Video_choose)
def get_sum_image(frame, coor, Width_choose, Height_choose):
global emptyImage
emptyImage = np.zeros((Width_choose * 10, Height_choose * 2, 3), np.uint8)
gray_lwpCV = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # 转灰度图
frame_data = np.array(gray_lwpCV) # 每一帧循环存入数组
box_data = frame_data[coor[1,1]:coor[2,1], coor[1,0]:coor[2,0]] # 取矩形目标区域
pixel_sum = np.sum(box_data, axis=1) # 行求和q
for i in range(Height_choose):
cv2.rectangle(emptyImage, (int(i*2), int((Width_choose-pixel_sum[i]//255)*10)), (int((i+1)*2), int(Width_choose)*10), (255, 0, 0), 1)
emptyImage = cv2.resize(emptyImage, (320, 240))
coor_x,coor_y, emptyImage = -1, -1, 0 # 初始值并无意义,只是先定义一下供后面的global赋值改变用于全局变量
coor = np.array([[1,1]])
fourcc = cv2.VideoWriter_fourcc(*'XVID') # 使用XVID编码器
camera = cv2.VideoCapture('/home/cheng/Desktop/1.mp4') # 从文件读取视频,Todo:只需要修改成自己的视频路径即可进行测试
fps = camera.get(cv2.CAP_PROP_FPS) # 获取视频帧率
grabbed, img = camera.read() # 逐帧采集视频流
video_info(camera, fps)
get_chosse_action(img, OnMouseAction)
Width_choose = coor[2,0]-coor[1,0] # 选中区域的宽
Height_choose = coor[2, 1] - coor[1, 1] # 选中区域的高
print("视频选中区域的宽:%d" %Width_choose,'\n'"视频选中区域的高:%d" %Height_choose)
out = cv2.VideoWriter('output_test1.avi',fourcc, camera.get(cv2.CAP_PROP_FPS), (Width_choose,Height_choose)) # 参数分别是:保存的文件名、编码器、帧率、视频宽高
def main():
while True:
grabbed, frame = camera.read() # 逐帧采集视频流,如果读取结束则退出
if not grabbed:
break
output_choose_vedio(coor, frame) # 输出选定区域内的视频
get_sum_image(frame, coor, Width_choose, Height_choose) # 得到选定区域内的求和图
cv2.rectangle(frame, tuple(coor[1,:]), tuple(coor[2,:]), (0, 255, 0), 2) # 在原视频显示选定的框的范围
cv2.imshow('lwpCVWindow', frame) # 显示采集到的视频流
cv2.imshow('sum', emptyImage) # 显示画出的条形图
key = cv2.waitKey(1) & 0xFF
if key == ord('q'): # 按Q推出
break
out.release()
camera.release()
cv2.destroyAllWindows()
if __name__ == '__main__':
main()