基于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 的摄像头应用程序。它可以打开摄像头并实时显示图像,还可以在图像中检测人脸和眼睛,并进行标注。用户可以通过点击按钮来开始、暂停摄像头以及拍照。
程序逻辑如下:
- 导入所需的模块。
- 创建一个继承自 QWidget 的 CameraWidget 类。
- 在 CameraWidget 中初始化摄像头,设置界面布局,创建按钮和图像标签,并连接按钮的点击事件。
- 实现 start_camera 方法,在方法内启动定时器,定时读取摄像头图像。
- 实现 pause_camera 方法,在方法内停止定时器,暂停读取摄像头图像。
- 实现 update_frame 方法,在方法内读取摄像头图像,转换颜色空间,并使用人脸和眼睛检测器进行人脸和眼睛的检测和标注。然后将处理后的图像显示在图像标签上。
- 实现 capture_image 方法,在方法内读取摄像头图像,并根据当前日期和时间生成一个文件名,并将图像保存到指定路径。同时弹出消息框提示拍照成功。
- 在主程序中创建 QApplication 实例,创建 CameraWidget 实例并显示,最后进入事件循环。