1、功能概述
PyQt5多媒體模塊為攝像頭操作提供了幾個類,可以用于獲取攝像頭設備信息,通過攝像頭進行拍照和錄像。
Qt多媒體模塊的功能實現(xiàn)是依賴于平臺的。在Windows平臺上,Qt多媒體模塊依賴于兩個插件:一個是使用Microsoft DirectShow API的插件,DirectShow在Windows 98引入,在Windows XP以后就逐漸過時了;另一個是Windows Media Foundation(WMF)的插件,WMF插件在Windows Vista引入,用于替代DirectShow。
Qt中的WMF插件目前無法提供攝像頭支持,對攝像頭的有限支持是由DirectShow插件提供的,目前只能顯示取景器和抓取靜態(tài)圖片,其他大部分功能不支持。所以,目前在Windows平臺上,Qt的攝像頭控制不支持視頻錄制功能,也不支持底層的視頻功能,例如使用QVideoProbe探測視頻幀。
PyQt5的多媒體模塊在Windows平臺上也無法實現(xiàn)攝像頭錄像功能。
2、主要類與函數(shù)
++++++++++++++++++++++++++++
QCameraInfo:攝像頭設備信息類
availableCameras():返回QCameraInfo類型的列表,表示系統(tǒng)可用的攝像頭。
defaultCamera():返回一個QCameraInfo對象,是系統(tǒng)默認的攝像頭設備信息。
description():返回攝像頭設備描述。
deviceName():返回攝像頭設備名稱。
position():返回值是枚舉類型QCamera.Position,表示攝像頭的位置。
例如手機一般有兩個攝像頭,前置攝像頭位置類型為QCamera.FrontFace,后置攝像頭位置類型為QCamera.BackFace,未指定位置的是QCamera.UnspecifiedPosition。
++++++++++++++++++++++++++++
QCamera:操作攝像頭的類,創(chuàng)建QCamera對象時需傳遞一個QCameraInfo對象作為參數(shù)。
setViewfinder(viewfinder):為攝像頭指定一個QVideoWidget或QGraphicsVideoItem對象viewfinder作為取景器,用于攝像頭圖像預覽。一般使用一個QCameraViewfinder類對象用于攝像頭預覽,其父類是QVideoWidget。
setCaptureMode(mode):用于設置攝像頭工作模式,參數(shù)mode是枚舉類型QCamera. CaptureModes,有以下幾種取值:
QCamera.CaptureViewfinder(取景器模式,攝像頭僅用于預覽);
QCamera.CaptureStillImage(抓取靜態(tài)圖片模式);
QCamera.CaptureVideo(視頻錄制模式)。
isCaptureModeSupported(mode),判斷攝像頭是否支持某種工作模式,參數(shù)mode是枚舉類型QCamera.CaptureModes。
searchAndLock():拍照之前執(zhí)行,用于在快門半按下時鎖定攝像頭的曝光、白平衡等參數(shù)
unlock():拍照后執(zhí)行,用于解除鎖定。
++++++++++++++++++++++++++++
QCameraImageCapture:控制攝像頭進行靜態(tài)圖片的抓取
setEncodingSettings(settings):設置拍照圖片的編碼,settings是QImageEncoderSettings類型,設置內(nèi)容包括編碼方案、分辨率、圖片質(zhì)量等。
setBufferFormat(format):設置拍照緩沖區(qū)的圖片的格式,參數(shù)format是枚舉類型QVideoFrame.PixelFormat,有幾十種取值,這里用QVideoFrame.Format_Jpeg,也就是使用JPEG格式。
setCaptureDestination(destination):用于設置所拍攝圖片的保存方式,destination是枚舉類型QCameraImageCapture.CaptureDestination,有以下兩種取值:
QCameraImageCapture.CaptureToBuffer(拍攝的圖片保存在緩沖區(qū)里,會發(fā)射信號
imageCaptured(),在此信號的槽函數(shù)里可以提取緩沖區(qū)中的圖片); - QCameraImageCapture.CaptureToFile(拍攝的圖片自動保存文件到用戶目錄的“圖片”
文件夾里,保存圖片后會發(fā)射imageSaved()信號)。 如果設置為CaptureToBuffer,就只會發(fā)射imageCaptured()信號,圖片出現(xiàn)在緩沖區(qū),不會自動保存為文件,也不會發(fā)射imageCaptured()信號;而如果設置為CaptureToFile,兩個信號都會被發(fā)射。
QCameraImageCapture的3個信號及關聯(lián)的槽函數(shù)的作用如下。
readyForCaptureChanged(ready):信號在攝像頭是否可以拍照的狀態(tài)變化時發(fā)射,bool型參數(shù)ready正好用于控制拍照按鈕的使能狀態(tài)。
imageCaptured(imageID, preview)在圖像被抓取到緩沖區(qū)后發(fā)射,imageID是圖像的編號,每次拍照時自動累加,preview是QImage類型,是拍攝的圖片。在關聯(lián)的槽函數(shù)里,將此圖片的內(nèi)容顯示到界面上的QLabel組件LabImage上。
imageSaved(imageID, fileName)信號在圖片保存為文件后發(fā)射,fileName是自動保存的文件名稱。在關聯(lián)的槽函數(shù)里顯示了imageID和文件名fileName。
++++++++++++++++++++++++++++
QMediaRecorder:通過攝像頭和音頻輸入設備進行視頻錄制文章來源:http://www.zghlxwxcb.cn/news/detail-453796.html
3、代碼實現(xiàn)
這個窗口工作區(qū)的左側(cè)是攝像頭預覽顯示,是一個QCameraViewfinder組件,右側(cè)是拍攝照片的顯示,是一個QLabel組件。兩個GroupBox組件之間使用了分割布局。文章來源地址http://www.zghlxwxcb.cn/news/detail-453796.html
from PyQt5.QtGui import QImage,QPixmap
from PyQt5.QtMultimedia import (QCameraInfo,QCameraImageCapture,
QImageEncoderSettings,QMultimedia,QVideoFrame,QSound,QCamera)
from ui_MainWindow import Ui_MainWindow
class QmyMainWindow(QMainWindow):
def __init__(self, parent = None):
super().__init__(parent) #調(diào)用父類構(gòu)造函數(shù),創(chuàng)建窗體
self.ui = Ui_MainWindow() #創(chuàng)建UI對象
self.ui.setupUi(self) #構(gòu)造UI界面
self.__LabCameraState = QLabel("攝像頭state:")
self.__LabCameraState.setMinimumWidth(150)
self.ui.statusBar.addWidget(self.__LabCameraState)
self.__LabImageID = QLabel("圖片文件ID:")
self.__LabImageID.setMinimumWidth(100)
self.ui.statusBar.addWidget(self.__LabImageID)
self.__LabImageFile = QLabel("") #保存的圖片文件名
self.ui.statusBar.addPermanentWidget(self.__LabImageFile)
self.camera = None #QCamera對象
cameras = QCameraInfo.availableCameras() #list[QCameraInfo]
if len(cameras)>0:
self.__iniCamera() #初始化攝像頭
self.__iniImageCapture() #初始化靜態(tài)畫圖
self.camera.start()
## ==============自定義功能函數(shù)========================
def __iniCamera(self): ##創(chuàng)建 QCamera對象
camInfo=QCameraInfo.defaultCamera() #獲取缺省攝像頭,QCameraInfo
self.ui.comboCamera.addItem(camInfo.description()) #攝像頭描述
self.ui.comboCamera.setCurrentIndex(0)
self.camera=QCamera(camInfo) #創(chuàng)建攝像頭對象
self.camera.setViewfinder(self.ui.viewFinder) #設置取景框預覽
## camera.setCaptureMode(QCamera.CaptureViewfinder) #預覽
self.camera.setCaptureMode(QCamera.CaptureStillImage) #設置為抓圖
## camera.setCaptureMode(QCamera.CaptureVideo)
mode=QCamera.CaptureStillImage
supported=self.camera.isCaptureModeSupported(mode)
self.ui.checkStillImage.setChecked(supported) #支持拍照
supported=self.camera.isCaptureModeSupported(QCamera.CaptureVideo)
self.ui.checkVideo.setChecked(supported) #支持視頻錄制
supported=self.camera.exposure().isAvailable()
self.ui.checkExposure.setChecked(supported) #支持曝光補償
supported=self.camera.focus().isAvailable()
self.ui.checkFocus.setChecked(supported) #支持變焦
self.camera.stateChanged.connect(self.do_cameraStateChanged)
def __iniImageCapture(self): ##創(chuàng)建 QCameraImageCapture對象
self.capturer = QCameraImageCapture(self.camera)
settings=QImageEncoderSettings() #拍照設置
settings.setCodec("image/jpeg") #設置抓圖圖形編碼
settings.setResolution(640, 480) #分辨率
settings.setQuality(QMultimedia.HighQuality) #圖片質(zhì)量
self.capturer.setEncodingSettings(settings)
self.capturer.setBufferFormat(QVideoFrame.Format_Jpeg) #緩沖區(qū)格式
if self.ui.chkBoxSaveToFile.isChecked():
dest=QCameraImageCapture.CaptureToFile #保存到文件
else:
dest=QCameraImageCapture.CaptureToBuffer #保存到緩沖區(qū)
self.capturer.setCaptureDestination(dest) #保存目標
self.capturer.readyForCaptureChanged.connect(self.do_imageReady)
self.capturer.imageCaptured.connect(self.do_imageCaptured)
self.capturer.imageSaved.connect(self.do_imageSaved)
## ==============event處理函數(shù)==========================
## ==========由connectSlotsByName()自動連接的槽函數(shù)============
@pyqtSlot(bool) ##設置保存方式
def on_chkBoxSaveToFile_clicked(self,checked):
if checked:
dest=QCameraImageCapture.CaptureToFile #保存到文件
else:
dest=QCameraImageCapture.CaptureToBuffer #保存到緩沖區(qū)
self.capturer.setCaptureDestination(dest) #保存目標
@pyqtSlot() ##拍照
def on_actCapture_triggered(self):
QSound.play("shutter.wav") #播放快門音效
self.camera.searchAndLock() #快門半按下時鎖定攝像頭參數(shù)
self.capturer.capture() #拍照
self.camera.unlock() #快門按鈕釋放時解除鎖定
@pyqtSlot() ##打開攝像頭
def on_actStartCamera_triggered(self):
self.camera.start()
@pyqtSlot() ##關閉攝像頭
def on_actStopCamera_triggered(self):
self.camera.stop()
## =============自定義槽函數(shù)===============================
def do_cameraStateChanged(self,state): ##攝像頭狀態(tài)變化
if (state==QCamera.UnloadedState):
self.__LabCameraState.setText("攝像頭state: UnloadedState")
elif (state==QCamera.LoadedState):
self.__LabCameraState.setText("攝像頭state: LoadedState")
elif (state==QCamera.ActiveState):
self.__LabCameraState.setText("攝像頭state: ActiveState")
self.ui.actStartCamera.setEnabled(state!=QCamera.ActiveState)
self.ui.actStopCamera.setEnabled(state==QCamera.ActiveState)
def do_imageReady(self,ready): ##是否可以拍照了
self.ui.actCapture.setEnabled(ready)
def do_imageCaptured(self,imageID,preview): ##圖片被抓取到內(nèi)存
#preview是 QImage
H=self.ui.LabImage.height()
W=self.ui.LabImage.width()
scaledImage = preview.scaled(W,H,
Qt.KeepAspectRatio, Qt.SmoothTransformation)
self.ui.LabImage.setPixmap(QPixmap.fromImage(scaledImage))
self.__LabImageID.setText("圖片文件ID:%d"%imageID)
self.__LabImageFile.setText("圖片保存為: ")
def do_imageSaved(self,imageID,fileName): ##圖片被保存
self.__LabImageID.setText("圖片文件ID:%d"%imageID)
self.__LabImageFile.setText("圖片保存為: "+fileName)
## ============窗體測試程序 ================================
if __name__ == "__main__": #用于當前窗體測試
app = QApplication(sys.argv) #創(chuàng)建GUI應用程序
form=QmyMainWindow() #創(chuàng)建窗體
form.show()
sys.exit(app.exec_())
到了這里,關于PyQt5攝像頭的使用--攝像頭操作概述及使用攝像頭拍照的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!