Pyqt5 创建相机应用程序

Pyqt5 创建相机应用程序

PyQt5是Python中最受欢迎的GUI库之一,它允许开发人员轻松创建桌面应用程序。在本文档中,我们将逐步介绍使用PyQt5创建相机应用程序的过程。相机应用程序将允许用户拍照、查看照片甚至保存照片。

PyQt5的优点有哪些

PyQt5是流行的跨平台GUI工具包Qt的Python绑定。以下是PyQt5的一些优点:

  • 跨平台 - PyQt5是一个跨平台工具包,意味着使用它开发的应用程序可以在多个平台上运行,如Windows、Mac OS X和Linux。

  • 丰富的小部件集 - PyQt5提供了丰富的小部件集,包括按钮、标签、文本框、表格等等。这使得创建复杂的图形用户界面变得容易。

  • 高性能 - PyQt5通过OpenGL集成提供高性能的图形渲染。这使得处理大量数据时,GUI仍然平滑和响应。

  • 易于学习 - PyQt5是建立在Python编程语言之上的,Python以其简单性和易用性而闻名。这使得开发人员可以轻松学习和使用PyQt5在他们的项目中。

  • 开源 - PyQt5是一个开源项目,这意味着开发人员可以访问其源代码并为其开发做出贡献。这也意味着PyQt5可以免费使用,无需任何许可费用。

  • 庞大的社区 - PyQt5拥有庞大的开发人员和用户社区,他们积极投入到其开发和支持工作中。这使得在你的项目中使用PyQt5时很容易找到帮助、文档和示例。

总的来说,PyQt5是一个强大而灵活的工具包,用于使用Python开发跨平台图形用户界面。

先决条件

在我们开始任务之前,需要在您的系统上安装以下内容:

建议的设置列表:

  • pip install pyqt5, open-cv, numpy

  • 您预计会有访问任何独立的IDE,如VS-Code、PyCharm、Atom或Sublime text。

  • 甚至可以使用在线Python编译器,如Kaggle.com、Google Cloud平台或任何其他平台。

  • Python的最新版本。在撰写本文时,我使用的是3.10.9版本。

  • 对Jupyter笔记本的使用了解。

  • 了解和应用虚拟环境将是有益的,但不是必需的。

  • 也预计个人对统计学和数学有良好的理解。

安装所需的库

第一步是确保所有必要的库都已安装。我们将需要PyQt5,OpenCV和NumPy来创建相机应用程序。以下命令可用于安装所需的库。

语法

pip install PyQt5
pip install opencv-python-headless
pip install numpy

创建主窗口

主窗口是任何应用程序的骨架。在这里,所有的用户界面元素将被放置。在这个相机应用程序中,我们将创建一个主窗口,该窗口将有一个相机视频流,一个用于拍摄照片的按钮和一个用于保存照片的按钮。

为了创建主窗口,我们将创建一个新的PyQt5项目并导入所需的库。

import sys
import cv2
import numpy as np
from PyQt5.QtCore import Qt, QTimer, QThread, pyqtSignal
from PyQt5.QtGui import QImage, QPixmap
from PyQt5.QtWidgets import QApplication, QDialog, QMainWindow, QStatusBar, QToolBar, QAction, QFileDialog, QLabel

接下来,我们将创建一个QMainWindow并设置窗口标题、状态栏和工具栏。

class MainWindow(QMainWindow):
   def __init__(self):
      super().__init__()

      self.setWindowTitle("Camera Application")
      self.statusBar().showMessage("Ready")
      self.toolbar = QToolBar()
      self.addToolBar(self.toolbar)
      self.label = QLabel()
      self.label.setAlignment(Qt.AlignCenter)
      self.setCentralWidget(self.label)

我们还会添加一个QLabel来显示摄像头的视频。

self.camera = CameraThread()
   self.camera.image.connect(self.update_image)
   self.camera.start()

   capture_action = QAction("Capture", self.toolbar)
   capture_action.setShortcut("Space")

   capture_action.triggered.connect(self.capture_photo)
   self.toolbar.addAction(capture_action)

捕获和保存照片

为了捕获照片,我们将创建一个QAction,并将其连接到一个方法,该方法将从摄像头源中捕获当前帧。

def update_image(self, frame):
   frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
   image = QImage(frame, frame.shape[1], frame.shape[0], QImage.Format_RGB888)
   self.label.setPixmap(QPixmap.fromImage(image))

   def capture_photo(self):
      frame = self.camera.frame
      frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
      image = QImage(frame, frame.shape[1], frame.shape[0], QImage.Format_RGB888)
      filename, _ = QFileDialog.getSaveFileName(self, "Save Photo", "", "JPEG Image (*.jpg)")
      if filename:
         image.save(filename, "jpg")

capture_photo方法会从相机视频流中捕获当前帧,将其转换为QImage,并使用QFileDialog将其保存到文件中。

创建相机线程

我们将使用一个单独的线程来捕获相机的视频流。这样做可以防止GUI在捕获视频流时冻结。

class CameraThread(QThread):
   image = pyqtSignal(np.ndarray)

   def __init__(self):
      super().__init__()
      self.capture = None

   def start_capture(self):
      self.capture = cv2.VideoCapture(0)

   def stop_capture(self):
      if self.capture:
         self.capture.release()
         self.capture = None

   def run(self):
      self.start_capture()
      while True:
         ret, frame = self.capture.read()
         if ret:
            self.image.emit(frame)

   def stop(self):
      self.stop_capture()
      super().stop()

最终代码

让我们来检查下面的最终程序和附加代码

import sys
import cv2
import numpy as np
from PyQt5.QtCore import Qt, QTimer, QThread, pyqtSignal
from PyQt5.QtGui import QImage, QPixmap
from PyQt5.QtWidgets import QApplication, QDialog, QMainWindow, QStatusBar, QToolBar, QAction, QFileDialog, QLabel

class MainWindow(QMainWindow):
   def __init__(self):
      super().__init__()

      self.setWindowTitle("Camera Application")
      self.statusBar().showMessage("Ready")
      self.toolbar = QToolBar()
      self.addToolBar(self.toolbar)
      self.label = QLabel()
      self.label.setAlignment(Qt.AlignCenter)
      self.setCentralWidget(self.label)

      self.camera = CameraThread()
      self.camera.image.connect(self.update_image)
      self.camera.start()

      capture_action = QAction("Capture", self.toolbar)
      capture_action.setShortcut("Space")

      capture_action.triggered.connect(self.capture_photo)
      self.toolbar.addAction(capture_action)

   def update_image(self, frame):
      frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
      image = QImage(frame, frame.shape[1], frame.shape[0], QImage.Format_RGB888)
      self.label.setPixmap(QPixmap.fromImage(image))

   def capture_photo(self):
      frame = self.camera.frame
      frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
      image = QImage(frame, frame.shape[1], frame.shape[0], QImage.Format_RGB888)
      filename, _ = QFileDialog.getSaveFileName(self, "Save Photo", "", "JPEG Image (*.jpg)")
      if filename:
         image.save(filename, "jpg")

class CameraThread(QThread):
   image = pyqtSignal(np.ndarray)

   def __init__(self):
      super().__init__()
      self.capture = None

   def start_capture(self):
      self.capture = cv2.VideoCapture(0)

   def stop_capture(self):
      if self.capture:
         self.capture.release()
         self.capture = None

   def run(self):
      self.start_capture()
      while True:
         ret, frame = self.capture.read()
         if ret:
            self.image.emit(frame)

   def stop(self):
      self.stop_capture()
      super().stop()

输出

由于隐私规则,本程序只能产生图像形式的输出。除此之外,我无法提供我的图像,而且人们可能因以下原因难以获取输出。因此,读者应该牢记以下可能的错误。

  • 摄像头连接不正确或无法工作。请检查摄像头是否正确连接并正常工作。
  • 程序没有权限访问摄像头。请检查您的系统设置,确保程序有访问摄像头的权限。
  • 程序配置不正确。请检查代码以确保摄像头设置和PyQt5信号正确设置。
  • 使用的OpenCV版本可能存在问题。尝试更新或重新安装OpenCV
  • 使用的PyQt5版本可能存在问题。尝试更新或重新安装PyQt5。

结论

在本文中,我们学习了如何使用Pyqt5创建摄像头应用程序。我们涵盖了必要库的安装,创建主窗口,创建摄像头线程,显示摄像头视频流以及拍摄/保存照片。有了这些知识,任何开发人员都可以使用Pyqt5创建令人印象深刻的涉及摄像头视频流的桌面应用程序。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程