【PYQT项目】摄像头拍照保存

1.实现目标

  使用OpenCV-Python调用笔记本电脑摄像头,使用QT绘制图形界面,当按下拍照时,照片显示在屏幕,按下保存时,该照片可以保存在指定路径。

2.Qt designer绘制界面

pyqt

3.将.ui文件转为.py文件

pyuic5 -o ui_MainWindow.py MainWindow.ui

4.ui_MainWindow.py文件

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'MainWindow.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.


from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtMultimediaWidgets import QCameraViewfinder


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(963, 603)
        self.centralWidget = QtWidgets.QWidget(MainWindow)
        self.centralWidget.setObjectName("centralWidget")
        self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.centralWidget)
        self.verticalLayout_3.setContentsMargins(3, 3, 3, 3)
        self.verticalLayout_3.setSpacing(3)
        self.verticalLayout_3.setObjectName("verticalLayout_3")
        self.groupBox_2 = QtWidgets.QGroupBox(self.centralWidget)
        self.groupBox_2.setMaximumSize(QtCore.QSize(16777215, 60))
        self.groupBox_2.setTitle("")
        self.groupBox_2.setObjectName("groupBox_2")
        self.gridLayout = QtWidgets.QGridLayout(self.groupBox_2)
        self.gridLayout.setContentsMargins(11, 5, 11, 5)
        self.gridLayout.setHorizontalSpacing(12)
        self.gridLayout.setVerticalSpacing(6)
        self.gridLayout.setObjectName("gridLayout")
        self.label = QtWidgets.QLabel(self.groupBox_2)
        self.label.setMaximumSize(QtCore.QSize(80, 16777215))
        self.label.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
        self.label.setObjectName("label")
        self.gridLayout.addWidget(self.label, 0, 0, 1, 1)
        self.comboCamera = QtWidgets.QComboBox(self.groupBox_2)
        self.comboCamera.setMinimumSize(QtCore.QSize(150, 20))
        self.comboCamera.setObjectName("comboCamera")
        self.gridLayout.addWidget(self.comboCamera, 0, 1, 1, 1)
        self.verticalLayout_3.addWidget(self.groupBox_2)
        self.splitter = QtWidgets.QSplitter(self.centralWidget)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.splitter.sizePolicy().hasHeightForWidth())
        self.splitter.setSizePolicy(sizePolicy)
        self.splitter.setOrientation(QtCore.Qt.Horizontal)
        self.splitter.setHandleWidth(5)
        self.splitter.setObjectName("splitter")
        self.splitter.setStretchFactor(1, 1)
        self.groupBox = QtWidgets.QGroupBox(self.splitter)
        self.groupBox.setMinimumSize(QtCore.QSize(476, 0))
        self.groupBox.setMaximumSize(QtCore.QSize(16777215, 16777215))
        self.groupBox.setObjectName("groupBox")
        self.gridLayout_2 = QtWidgets.QGridLayout(self.groupBox)
        self.gridLayout_2.setContentsMargins(11, 11, 11, 11)
        self.gridLayout_2.setSpacing(6)
        self.gridLayout_2.setObjectName("gridLayout_2")
        self.viewFinder = QCameraViewfinder(self.groupBox)
        self.viewFinder.setMinimumSize(QtCore.QSize(0, 0))
        self.viewFinder.setObjectName("viewFinder")
        self.gridLayout_2.addWidget(self.viewFinder, 0, 0, 1, 1)
        self.groupBox_3 = QtWidgets.QGroupBox(self.splitter)
        self.groupBox_3.setMinimumSize(QtCore.QSize(476, 0))
        self.groupBox_3.setMaximumSize(QtCore.QSize(16777215, 16777215))
        self.groupBox_3.setObjectName("groupBox_3")
        self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.groupBox_3)
        self.verticalLayout_2.setContentsMargins(11, 11, 11, 11)
        self.verticalLayout_2.setSpacing(6)
        self.verticalLayout_2.setObjectName("verticalLayout_2")
        self.LabImage = QtWidgets.QLabel(self.groupBox_3)
        self.LabImage.setMinimumSize(QtCore.QSize(0, 0))
        self.LabImage.setAlignment(QtCore.Qt.AlignCenter)
        self.LabImage.setObjectName("LabImage")
        self.verticalLayout_2.addWidget(self.LabImage)
        self.verticalLayout_3.addWidget(self.splitter)
        MainWindow.setCentralWidget(self.centralWidget)
        self.menuBar = QtWidgets.QMenuBar(MainWindow)
        self.menuBar.setGeometry(QtCore.QRect(0, 0, 963, 23))
        self.menuBar.setObjectName("menuBar")
        MainWindow.setMenuBar(self.menuBar)
        self.mainToolBar = QtWidgets.QToolBar(MainWindow)
        self.mainToolBar.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon)
        self.mainToolBar.setObjectName("mainToolBar")
        MainWindow.addToolBar(QtCore.Qt.TopToolBarArea, self.mainToolBar)
        self.statusBar = QtWidgets.QStatusBar(MainWindow)
        self.statusBar.setObjectName("statusBar")
        MainWindow.setStatusBar(self.statusBar)
        self.actStartCamera = QtWidgets.QAction(MainWindow)
        self.actStartCamera.setEnabled(False)
        self.actStartCamera.setObjectName("actStartCamera")
        self.actStopCamera = QtWidgets.QAction(MainWindow)
        self.actStopCamera.setEnabled(False)
        self.actStopCamera.setObjectName("actStopCamera")
        self.actCapture = QtWidgets.QAction(MainWindow)
        self.actCapture.setEnabled(False)
        self.actCapture.setObjectName("actCapture")
        self.actQuit = QtWidgets.QAction(MainWindow)
        self.actQuit.setObjectName("actQuit")
        self.mainToolBar.addAction(self.actStartCamera)
        self.mainToolBar.addSeparator()
        self.mainToolBar.addAction(self.actStopCamera)
        self.mainToolBar.addSeparator()
        self.mainToolBar.addAction(self.actCapture)
        self.mainToolBar.addSeparator()
        self.mainToolBar.addAction(self.actQuit)

        self.retranslateUi(MainWindow)
        self.actQuit.triggered.connect(MainWindow.close)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "camera"))
        self.label.setText(_translate("MainWindow", "摄像头设备"))
        self.groupBox.setTitle(_translate("MainWindow", "摄像头预览"))
        self.groupBox_3.setTitle(_translate("MainWindow", "抓取的图片"))
        self.LabImage.setText(_translate("MainWindow", "抓取的图片"))
        self.actStartCamera.setText(_translate("MainWindow", "开启摄像头"))
        self.actStartCamera.setToolTip(_translate("MainWindow", "开启摄像头"))
        self.actStopCamera.setText(_translate("MainWindow", "关闭摄像头"))
        self.actStopCamera.setToolTip(_translate("MainWindow", "关闭摄像头"))
        self.actCapture.setText(_translate("MainWindow", "拍照"))
        self.actCapture.setToolTip(_translate("MainWindow", "拍照"))
        self.actQuit.setText(_translate("MainWindow", "退出"))
        self.actQuit.setToolTip(_translate("MainWindow", "退出"))
#from QCameraViewfinder import QCameraViewfinder
import res_rc

5.myMainWindow.py文件(调用ui_MainWindow.py)

import sys

import cv2
from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel, QFileDialog

from PyQt5.QtCore import pyqtSlot, Qt

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]


        print(str(len(cameras)) + " camera find!")
        if len(cameras) > 0:
            self.__iniCamera()  # 初始化摄像头
            self.__iniImageCapture()  # 初始化静态画图
            self.camera.start()

    def __iniCamera(self):  # 创建 QCamera对象
        camInfo = QCameraInfo.defaultCamera()  # 获取缺省摄像头
        #camInfo = QCameraInfo.availableCameras()  # 获取所有摄像头

        self.ui.comboCamera.addItem(camInfo.description())  # 摄像头描述
        #self.ui.comboCamera.addItem(camInfo.)

        self.ui.comboCamera.setCurrentIndex(0)
        self.camera = QCamera(camInfo)  # 创建摄像头对象
        self.camera.setViewfinder(self.ui.viewFinder)  # 设置取景框预览
        self.camera.setCaptureMode(QCamera.CaptureStillImage)  # 抓取静态图片模式

        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)  # 缓冲区格式

        dest = QCameraImageCapture.CaptureToFile  # 保存到文件(必定执行)

        self.capturer.setCaptureDestination(dest)  # 保存目标

        self.capturer.readyForCaptureChanged.connect(self.do_imageReady)

        self.capturer.imageCaptured.connect(self.do_imageCaptured)

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

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

    @pyqtSlot()  # 关闭摄像头
    def on_actStopCamera_triggered(self):
        self.camera.stop()
        print("关闭摄像头")

    def do_cameraStateChanged(self, state):
        if (state == QCamera.UnloadedState):
            self.__LabCameraState.setText("摄像头状态: UnloadedState")
        elif (state == QCamera.LoadedState):
            self.__LabCameraState.setText("摄像头状态: LoadedState")
        elif (state == QCamera.ActiveState):
            self.__LabCameraState.setText("摄像头状态: 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)
        print("摄像头可以拍照")

    def do_imageCaptured(self, imageID, preview):  # 图片被抓取到内存
        print("捕捉图片")
        # preview是 QImage
        # H = self.ui.LabImage.height()
        # W = self.ui.LabImage.width()
        H = 1200
        W = 900

        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("图片正在保存")

        file_path = QFileDialog.getSaveFileName(self, "保存文件", "C:\\Users\\zty\\Desktop",
                                                "jpeg files (*.jpeg);;all files(*.*)")

        scaledImage.save(file_path[0], "jpeg")

    def do_imageSaved(self, imageID, fileName):  # 图片被保存
        try:
            self.__LabImageID.setText("图片文件ID:%d" % imageID)
            self.__LabImageFile.setText("图片保存为: " + fileName)
            resize_img = cv2.resize(imageID, dsize=(1200, 900))
            cv2.imwrite(fileName, resize_img)
            print("保存图片")
        except:
            print("未选择保存文件")


if __name__ == "__main__":
    app = QApplication(sys.argv)
    form = QmyMainWindow()
    form.show()
    sys.exit(app.exec_())

6.主程序入口appMain.py(非必须)

import sys

from PyQt5.QtWidgets import QApplication

from myMainWindow import QmyMainWindow

app = QApplication(sys.argv)  # 创建GUI应用程序

mainform = QmyMainWindow()  # 创建主窗体

mainform.show()  # 显示主窗体

sys.exit(app.exec_())

7.效果

效果

  • 3
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值