Python+OpenCV+pyQt5錄製雙目攝像頭視頻
起因
說起來錄製視頻,我們可能有很多的軟件,但是比較坑的是,好像很少的軟件支持能夠同時錄製兩個攝像頭的視頻,於是我們用python自己寫一個。要是OpenCV+python。貌似很簡單就能OK的事情,但是,我們的項目不是一般要展示給老師看嘛。誰願意看一個沒有界面的錄製過程是吧~,最後會附上源代碼~
依賴的包
在這裏,我直接把import的包寫出來了各位可以進行對號入座,然後就能知道需要安裝哪個包啦!
import cv2
import numpy as np
from PyQt5.QtWidgets import (QMainWindow, QApplication, QFileDialog)
import threading
import threadpool
from CvPyGui import ImageCvQtContainer
from CvPyGui.ui import gui
界面設計
pyqt的界面可以用designer進行構造,這裏因爲是雙目攝像頭,我們構造的界面就是這樣子的了:
其中TextLabel就是用來進行顯示圖像的,這裏更新圖像的代碼如下:
class Image(QWidget):
"""Common base for the images"""
def __init__(self, name, label):
super().__init__()
# Label (frame) where the original image will be located, with scaling
self.frame_lbl = label
def updateImage(self, opencv_rgb_image):
self.cv_img_rgb = opencv_rgb_image
height, width, channel = self.cv_img_rgb.shape
bytesPerLine = 3 * width
self.q_image = QImage(self.cv_img_rgb.data, width,
height, bytesPerLine, QImage.Format_RGB888)
self.frame_lbl.setPixmap(QPixmap.fromImage(self.q_image))
def saveImage(self):
# Function for saving the processed image
filter = "Images (*.png *.jpg)"
image_path, _ = QFileDialog.getSaveFileName(self, filter=filter)
cv_img_bgr = cv2.cvtColor(
self.cv_img_rgb, cv2.COLOR_RGB2BGR)
cv2.imwrite(image_path, cv_img_bgr)
我們也知道,視頻是一幀一幀的進行播放的。所以,我們在播放的時候實際上就是在更新每一幀的畫面了。
OpenCV的視頻獲取
使用OpenCV獲取視頻很簡單
cap = cv2.VideoCapture(int(text))
cap.set(6 ,cv2.VideoWriter_fourcc('M', 'J', 'P', 'G') );
cap.set(3,w);
cap.set(4,h);
global update1
update1 = 1
global shotmark1
ret, frame = cap.read()
這樣就能夠獲取到一幀圖像了,其中cap.set()
函數用來設置相機的參數,本來應該有宏定義的,但是在python裏面老是報錯,直接用數字替代了,其中3就是獲取視頻的寬度像素,4是高度,這個要和攝像頭手冊上的參數一致。一般的Webcam有兩種圖像獲取格式:一種是YUV2格式這種事10bit回傳的數據,理論上質量更好,但是有個很大的問題是分辨率高的時候,幀率就會變得十分低。另一種格式是MJPEG格式,這個是使用了壓縮技術得到的視頻流。通過這個格式,手冊上說在1920x1080分辨率下都能獲得30fps的表現,而YUV2只有5fps(後來發現,這個就是坑爹的,信了就怪了)。cap.set(6 ,cv2.VideoWriter_fourcc(‘M’, ‘J’, ‘P’, ‘G’) );這個參數就是使用MJPEG格式來讀取攝像頭的數據。
多線程
剛纔我們呢也提到了,cap.read()
這個函數是獲取到了一幀圖像,但是呢。我們要的是動畫啊,要是寫個循環的話,又會吧進程卡死在循環中,照成假死的狀態,所以對於圖像的繪製,一定要使用多線程技術。在這裏我不僅要吐槽一下了。學了好多年計算機,講了很多串行算法和編程,一講到多線程,無非就是打印個Hello World!,根本就沒有什麼實踐,理論倒是學了很多,感覺用的時候頭真的好大!
其實這裏的多線程也沒有什麼是吧,就是起調一下。但是要注意的是要控制線程的退出,在python這個我引入的多線程包裏面,賊坑的是沒有外界控制線程退出的辦法!所以,我設置了一個全局變量,使用判斷全局變量的值來判斷是否讓子線程繼續下去。
結尾
實際上,還有分辨率/幀率設置功能呢,只不過懶得寫了!!!3
GitHub:https://github.com/anonymouslycn/bjtu_BinocularCameraRecord
路過的還新希望你能夠高擡貴手給個Star吖~~ 筆芯~~