El uso de la cámara PyQt5: una descripción general del funcionamiento de la cámara y su uso para tomar fotografías

1. Descripción general funcional
El módulo multimedia PyQt5 proporciona varias clases para operaciones de cámara, que se pueden usar para obtener información del dispositivo de la cámara, tomar fotografías y grabar videos a través de la cámara.

La realización de funciones del módulo multimedia Qt depende de la plataforma. En la plataforma Windows, el módulo multimedia Qt depende de dos complementos: uno es un complemento que utiliza la API Microsoft DirectShow, DirectShow se introdujo en Windows 98 y gradualmente quedó obsoleto después de Windows XP; el otro es un complemento para Windows Media Foundation (WMF), el complemento WMF se introdujo en Windows Vista como reemplazo de DirectShow.

El complemento WMF en Qt actualmente no puede proporcionar soporte para la cámara. El complemento DirectShow proporciona soporte limitado para la cámara. En la actualidad, solo puede mostrar el visor y capturar imágenes fijas, y la mayoría de las demás funciones no son compatibles. Por lo tanto, actualmente en la plataforma Windows, el control de cámara de Qt no admite la función de grabación de video ni las funciones de video subyacentes, como el uso de QVideoProbe para detectar fotogramas de video.

El módulo multimedia de PyQt5 no puede realizar la función de grabación de la cámara en la plataforma Windows.

2. Clases y funciones principales
++++++++++++++++++++++++++++
QCameraInfo: clase de información del dispositivo de cámara

availableCameras(): Devuelve una lista de tipos de QCameraInfo, indicando las cámaras disponibles en el sistema.

defaultCamera(): devuelve un objeto QCameraInfo, que es la información del dispositivo de cámara predeterminado del sistema.

descripción(): Devuelve la descripción del dispositivo de la cámara.

deviceName(): Devuelve el nombre del dispositivo de la cámara.

position(): el valor de retorno es el tipo de enumeración QCamera.Position, que indica la posición de la cámara.
Por ejemplo, un teléfono móvil generalmente tiene dos cámaras, el tipo de posición de la cámara frontal es QCamera.FrontFace, el tipo de posición de la cámara trasera es QCamera.BackFace y la posición no especificada es QCamera.UnspecifiedPosition.
+++++++++++++++++++++++++++
QCamera: la clase para operar la cámara. Al crear un objeto QCamera, se debe pasar un objeto QCameraInfo como parámetro.

setViewfinder(visor): especifique un visor de objetos QVideoWidget o QGraphicsVideoItem para la cámara como visor para la vista previa de la imagen de la cámara. Generalmente, se utiliza un objeto de clase QCameraViewfinder para la vista previa de la cámara y su clase principal es QVideoWidget.

setCaptureMode(modo): Se utiliza para configurar el modo de trabajo de la cámara, el parámetro modo es el tipo de enumeración QCamera.CaptureModes, el cual tiene los siguientes valores: QCamera.CaptureViewfinder (modo visor, la cámara solo se usa
para vista previa);
QCamera.CaptureStillImage (modo de captura de imágenes fijas);
QCamera.CaptureVideo (modo de grabación de vídeo).

isCaptureModeSupported (modo), para determinar si la cámara admite un determinado modo de trabajo, el modo de parámetro es el tipo de enumeración QCamera.CaptureModes.

searchAndLock(): se ejecuta antes de tomar una fotografía y se utiliza para bloquear la exposición de la cámara, el balance de blancos y otros parámetros cuando el obturador está medio presionado.

desbloquear(): Ejecutado después de tomar una fotografía, usado para desbloquear.
+++++++++++++++++++++++++++++
QCameraImageCapture: controla la cámara para capturar imágenes fijas

setEncodingSettings(configuración): establece la codificación de la imagen tomada. La configuración es del tipo QImageEncoderSettings. La configuración incluye el esquema de codificación, la resolución y la calidad de la imagen.

setBufferFormat (formato): establece el formato de la imagen en el búfer de la cámara. El formato del parámetro es el tipo de enumeración QVideoFrame.PixelFormat, que tiene docenas de valores. Aquí se usa QVideoFrame.Format_Jpeg, es decir, se usa el formato JPEG.

setCaptureDestination(destino): se utiliza para establecer la forma de guardar las imágenes capturadas, el destino es el tipo de enumeración QCameraImageCapture.CaptureDestination, tiene los dos valores siguientes: QCameraImageCapture.CaptureToBuffer (
la imagen capturada se guarda en el búfer y la señal
imageCaptured() se emitirá, la imagen en el búfer se puede extraer en la función de ranura de esta señal); - QCameraImageCapture.CaptureToFile (la imagen capturada se guarda automáticamente en la carpeta "imagen" del directorio de usuario y la señal imageSaved() se emitirá después de guardar la imagen)
. Si está configurado en CaptureToBuffer, solo se emitirá la señal imageCaptured() y la imagen aparecerá en el búfer y no se guardará automáticamente como un archivo, ni se emitirá la señal imageCaptured(); y si es configurado en CaptureToFile, se emitirán ambas señales.

Las funciones de las tres señales de QCameraImageCapture y las funciones de ranura asociadas son las siguientes.

readyForCaptureChanged (listo): la señal se emite cuando cambia el estado de si la cámara puede tomar fotografías, y el parámetro bool listo solo se usa para controlar el estado de habilitación del botón de la cámara.

imageCaptured(imageID, vista previa) se emite después de capturar la imagen en el búfer. imageID es el número de la imagen, que se acumula automáticamente cada vez que se toma una foto. La vista previa es de tipo QImage, que es la imagen capturada. En la función de ranura asociada, muestre el contenido de esta imagen en el componente QLabel LabImage en la interfaz.

La señal imageSaved(imageID, fileName) se emite después de guardar la imagen como un archivo, donde fileName es el nombre del archivo guardado automáticamente. El ID de imagen y el nombre de archivo fileName se muestran en la función de ranura asociada.
+++++++++++++++++++++++++++
QMediaRecorder: grabación de vídeo mediante cámara y dispositivos de entrada de audio

3. Implementación del código
inserte la descripción de la imagen aquí
El lado izquierdo del área de trabajo de esta ventana es la visualización de vista previa de la cámara, que es un componente QCameraViewfinder, y el lado derecho es la visualización de las fotografías capturadas, que es un componente QLabel. Se utiliza un diseño dividido entre dos componentes de GroupBox.

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)    #调用父类构造函数,创建窗体
      self.ui = Ui_MainWindow()     #创建UI对象
      self.ui.setupUi(self)       #构造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() #初始化静态画图
         self.camera.start()

##  ==============自定义功能函数========================
   def __iniCamera(self):   ##创建 QCamera对象
      camInfo=QCameraInfo.defaultCamera()    #获取缺省摄像头,QCameraInfo
      self.ui.comboCamera.addItem(camInfo.description())    #摄像头描述
      self.ui.comboCamera.setCurrentIndex(0)

      self.camera=QCamera(camInfo)  #创建摄像头对象
      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):  ##创建 QCameraImageCapture对象
      self.capturer = QCameraImageCapture(self.camera)
      settings=QImageEncoderSettings()    #拍照设置
      settings.setCodec("image/jpeg")     #设置抓图图形编码
      settings.setResolution(640, 480)    #分辨率
      settings.setQuality(QMultimedia.HighQuality)    #图片质量
      self.capturer.setEncodingSettings(settings) 

      self.capturer.setBufferFormat(QVideoFrame.Format_Jpeg)   #缓冲区格式

      if self.ui.chkBoxSaveToFile.isChecked():
         dest=QCameraImageCapture.CaptureToFile    #保存到文件
      else:
         dest=QCameraImageCapture.CaptureToBuffer  #保存到缓冲区
      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处理函数==========================
        
        
##  ==========由connectSlotsByName()自动连接的槽函数============        
   @pyqtSlot(bool)   ##设置保存方式
   def on_chkBoxSaveToFile_clicked(self,checked):
      if checked:
         dest=QCameraImageCapture.CaptureToFile    #保存到文件
      else:
         dest=QCameraImageCapture.CaptureToBuffer  #保存到缓冲区
      self.capturer.setCaptureDestination(dest)    #保存目标

   @pyqtSlot()   ##拍照
   def on_actCapture_triggered(self): 
      QSound.play("shutter.wav")    #播放快门音效
      self.camera.searchAndLock()   #快门半按下时锁定摄像头参数
      self.capturer.capture()       #拍照
      self.camera.unlock()          #快门按钮释放时解除锁定

   @pyqtSlot()   ##打开摄像头
   def on_actStartCamera_triggered(self):
      self.camera.start()

   @pyqtSlot()  ##关闭摄像头
   def on_actStopCamera_triggered(self):
      self.camera.stop()
      
   
        
   ##  =============自定义槽函数===============================        
   def do_cameraStateChanged(self,state):    ##摄像头状态变化
      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): ##图片被抓取到内存
                                          #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)    #创建GUI应用程序
   form=QmyMainWindow()            #创建窗体
   form.show()
   sys.exit(app.exec_())

Supongo que te gusta

Origin blog.csdn.net/qq_35412059/article/details/129699413
Recomendado
Clasificación