天天看点

Python+OpenCv:视频流的任意局部特征的提取和保存

背景:

  • 在拍摄的视频中,通常感兴趣的区域只占其中一部分。如果能只对感兴趣区域ROI进行保存或者进行分析,无疑会带来很大的方便。尤其需要感兴趣的区域的特征时,去掉视频中的无关信息能大大节省计算量,提高计算速度。

介绍:

  • 开发环境:Python3.5+Opencv3.4.1
  • 针对对象:视频中的目标区域不会出现大范围转移,最好是在一个固定的视野内
  • 任务要求:手动指定任意目标区域进行分析,并单独保存指定区域的视频流
程序流程如下:
Python+OpenCv:视频流的任意局部特征的提取和保存

效果示意:

Python+OpenCv:视频流的任意局部特征的提取和保存

源程序:

import cv2
import numpy as np
coor_x,coor_y = -, - # 初始值并无意义,只是为了能够使用np.row_stack函数

"""定义视频编码器
FourCC全称Four-Character Codes,代表四字符代码 (four character code), 
它是一个32位的标示符,其实就是typedef unsigned int FOURCC;
是一种独立标示视频数据流格式的四字符代码。
因此cv2.VideoWriter_fourcc()函数的作用是输入四个字符代码即可得到对应的视频编码器。
"""
fourcc = cv2.VideoWriter_fourcc(*'XVID') # 使用XVID编码器
camera = cv2.VideoCapture('细胞极体拨动合成视频.wmv') # 从文件读取视频,Todo:只需要修改成自己的视频路径即可进行测试
fps = camera.get(cv2.CAP_PROP_FPS)# 获取视频帧率
print('视频帧率:%d fps' %fps)

# 判断视频是否成功打开
if (camera.isOpened()):
    print('视频已打开')
else:
    print('视频打开失败!')

# # 测试用,查看视频size
size = (int(camera.get(cv2.CAP_PROP_FRAME_WIDTH)),
       int(camera.get(cv2.CAP_PROP_FRAME_HEIGHT)))
print ('视频尺寸:'+repr(size))
coor = np.array([[,]]) # Todo:初始值并无意义,只是为了能够使用np.row_stack函数

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), (, , ), )
    elif event==cv2.EVENT_RBUTTONDOWN :
        print("右键点击")
    elif flags==cv2.EVENT_FLAG_LBUTTON:
        print("左鍵拖曳")
    elif event==cv2.EVENT_MBUTTONDOWN :
        print("中键点击")
'''
创建回调函数的函数setMouseCallback();
下面把回调函数与OpenCV窗口绑定在一起
'''
grabbed, img = camera.read() # 逐帧采集视频流
cv2.namedWindow('Image')
cv2.setMouseCallback('Image',OnMouseAction)
while():
    cv2.imshow('Image',img)
    k=cv2.waitKey() & 
    if k==ord(' '): # 空格退出操作
        break
cv2.destroyAllWindows() # 关闭页面

Width_choose = coor[,]-coor[,] # 选中区域的宽
Height_choose = coor[, ] - coor[, ] # 选中区域的高
print("视频选中区域的宽:%d" %Width_choose,'\n'"视频选中区域的高:%d" %Height_choose)
out = cv2.VideoWriter('output_test1.avi',fourcc, fps, (Width_choose,Height_choose)) # 参数分别是:保存的文件名、编码器、帧率、视频宽高
Video_choose = np.zeros((Width_choose, Height_choose, ), np.uint8)

while True:
    grabbed, frame = camera.read() # 逐帧采集视频流
    if not grabbed:
        break
    gray_lwpCV = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # 转灰度图
    frame_data = np.array(gray_lwpCV)  # 每一帧循环存入数组
    box_data = frame_data[coor[,]:coor[,], coor[,]:coor[,]] # 取矩形目标区域
    pixel_sum = np.sum(box_data, axis=) # 行求和q
    x = range(Height_choose)
    emptyImage = np.zeros((Width_choose * , Height_choose * , ), np.uint8)
    Video_choose = frame[coor[,]:coor[,],coor[,]:coor[,]]
    out.write(Video_choose)
    cv2.imshow('Video_choose', Video_choose)
    for i in x:
        cv2.rectangle(emptyImage, (i*, (Width_choose-pixel_sum[i]//)*), ((i+)*, Width_choose*), (, , ), )
    emptyImage = cv2.resize(emptyImage, (, ))
    lwpCV_box = cv2.rectangle(frame, tuple(coor[,:]), tuple(coor[,:]), (, , ), )

    cv2.imshow('lwpCVWindow', frame) # 显示采集到的视频流
    cv2.imshow('sum', emptyImage)  # 显示画出的条形图
    key = cv2.waitKey() & 
    if key == ord('q'):
        break
out.release()
camera.release()
cv2.destroyAllWindows()
           

Note:

  • 程序中已经加入详细的中文注释,如果有不懂的地方欢迎评论

Reference:

https://blog.csdn.net/lwplwf/article/details/71155727