天天看點

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