基于opencv与pyqt5的人脸检测照相机

基于opencv与pyqt5的人脸检测照相机

先放代码

import sys
import cv2
from PyQt5.QtCore import QTimer, Qt, QDateTime
from PyQt5.QtGui import QImage, QPixmap
from PyQt5.QtWidgets import QApplication, QLabel, QVBoxLayout, QWidget, QPushButton, QMessageBox


class CameraWidget(QWidget):
    def __init__(self):
        super().__init__()

        self.camera = cv2.VideoCapture(0)  # 打开摄像头

        self.image_label = QLabel(self)  # 显示图像的Label
        layout = QVBoxLayout(self)
        layout.addWidget(self.image_label)

        self.timer = QTimer()  # 定时器,用于不断读取图像
        self.timer.timeout.connect(self.update_frame)

        self.start_button = QPushButton('开始摄像头', self)  # 开始摄像头按钮
        self.start_button.clicked.connect(self.start_camera)
        layout.addWidget(self.start_button)

        self.pause_button = QPushButton('暂停摄像头', self)  # 暂停摄像头按钮
        self.pause_button.clicked.connect(self.pause_camera)
        layout.addWidget(self.pause_button)

        self.capture_button = QPushButton('拍照', self)  # 拍照按钮
        self.capture_button.clicked.connect(self.capture_image)
        layout.addWidget(self.capture_button)

        self.start_camera()  # 默认开始摄像头

        self.resize(800, 600)  # 设置窗口初始大小

    def start_camera(self):
        if not self.timer.isActive():
            self.timer.start(30)  # 启动定时器

    def pause_camera(self):
        if self.timer.isActive():
            self.timer.stop()  # 停止定时器

    def update_frame(self):
        ret, frame = self.camera.read()  # 读取摄像头图像
        if ret:
            frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)  # 转换颜色空间

            gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)  # 转换为灰度图像
            # 加载人脸检测器
            face = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
            # 加载眼睛检测器
            eye = cv2.CascadeClassifier('haarcascade_eye.xml')
            faces = face.detectMultiScale(gray)  # 执行人脸检测
            for x, y, w, h in faces:
                cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 0, 0), 2)  # 绘制矩形标注人脸
                roi_eye = gray[y:y + h, x:x + w]  # 根据人脸获得眼睛的检测范围
                eyes = eye.detectMultiScale(roi_eye)  # 在人脸范围内检测眼睛
                for (ex, ey, ew, eh) in eyes:  # 标注眼睛
                    cv2.circle(frame[y:y + h, x:x + w], (int(ex + ew / 2),
                                                       int(ey + eh / 2)), int(max(ew, eh) / 2), (0, 255, 0), 2)

            image = QImage(frame, frame.shape[1], frame.shape[0], QImage.Format_RGB888)
            pixmap = QPixmap.fromImage(image)
            self.image_label.setPixmap(
                pixmap.scaled(self.image_label.size().width() - 20, self.image_label.size().height() - 20,
                              Qt.KeepAspectRatio))

    def capture_image(self):
        ret, frame = self.camera.read()  # 读取摄像头图像
        if ret:
            current_datetime = QDateTime.currentDateTime()  # 获取当前日期和时间
            timestamp = current_datetime.toString("yyyyMMdd_hhmmss")  # 格式化为时间戳字符串
            filename = f"captured_image_{timestamp}.jpg"  # 组合文件名
            cv2.imwrite(filename, frame)  # 将图像保存到指定路径
            QMessageBox.information(self, "拍照成功", "照片已成功保存!")


if __name__ == "__main__":
    app = QApplication(sys.argv)

    widget = CameraWidget()
    widget.show()

    sys.exit(app.exec_())

解释

这是一个基于 PyQt5 和 OpenCV 的摄像头应用程序。它可以打开摄像头并实时显示图像,还可以在图像中检测人脸和眼睛,并进行标注。用户可以通过点击按钮来开始、暂停摄像头以及拍照。

程序逻辑如下:

  1. 导入所需的模块。
  2. 创建一个继承自 QWidget 的 CameraWidget 类。
  3. 在 CameraWidget 中初始化摄像头,设置界面布局,创建按钮和图像标签,并连接按钮的点击事件。
  4. 实现 start_camera 方法,在方法内启动定时器,定时读取摄像头图像。
  5. 实现 pause_camera 方法,在方法内停止定时器,暂停读取摄像头图像。
  6. 实现 update_frame 方法,在方法内读取摄像头图像,转换颜色空间,并使用人脸和眼睛检测器进行人脸和眼睛的检测和标注。然后将处理后的图像显示在图像标签上。
  7. 实现 capture_image 方法,在方法内读取摄像头图像,并根据当前日期和时间生成一个文件名,并将图像保存到指定路径。同时弹出消息框提示拍照成功。
  8. 在主程序中创建 QApplication 实例,创建 CameraWidget 实例并显示,最后进入事件循环。