STM32全栈嵌入式人脸识别考勤系统:融合OpenCV、Qt和SQLite的解决方案

1. 项目概述

本项目旨在设计并实现一个基于STM32的全栈人脸识别考勤系统。该系统结合了嵌入式开发、计算机视觉和数据库技术,实现了自动人脸检测、识别和考勤记录功能。

主要特点:

  • 使用STM32F4系列微控制器作为主控制器
  • 采用OpenCV进行人脸检测和识别
  • Qt开发跨平台桌面应用程序,实现友好的用户界面
  • SQLite嵌入式数据库存储员工信息和考勤记录
  • 支持实时考勤、数据统计分析和报表生成

2. 系统设计

2.1 硬件设计

主要硬件模块及功能:

  • STM32F407VGT6微控制器:系统的核心,负责协调各个模块工作
  • OV7670摄像头模块:捕获实时图像,用于人脸检测和识别
  • 3.5寸TFT LCD显示屏:显示系统界面和识别结果
  • AS608指纹识别模块:作为辅助识别手段
  • RC522 RFID读卡器:用于员工卡识别,提供备用签到方式
  • ESP8266 WiFi模块:实现与服务器的无线通信,上传考勤数据

2.2 软件设计

3. 代码实现

3.1 人脸检测

以下是使用OpenCV实现人脸检测的代码示例:

#include <opencv2/opencv.hpp>
#include <opencv2/objdetect.hpp>using namespace cv;class FaceDetector {
private:CascadeClassifier face_cascade;public:FaceDetector(const std::string& cascade_file) {// 加载Haar级联分类器if (!face_cascade.load(cascade_file)) {throw std::runtime_error("Error loading face cascade file");}}std::vector<Rect> detectFaces(const Mat& frame) {Mat gray;std::vector<Rect> faces;// 转换为灰度图像cvtColor(frame, gray, COLOR_BGR2GRAY);// 执行人脸检测face_cascade.detectMultiScale(gray, faces, 1.1, 3, 0, Size(30, 30));return faces;}void drawFaces(Mat& frame, const std::vector<Rect>& faces) {for (const auto& face : faces) {rectangle(frame, face, Scalar(255, 0, 0), 2);}}
};

代码说明:

  1. FaceDetector类封装了人脸检测功能。
  2. 构造函数加载Haar级联分类器文件。
  3. detectFaces方法接收一帧图像,返回检测到的人脸矩形区域。
  4. drawFaces方法在原图上绘制检测到的人脸矩形框。

 

3.2 人脸识别

下面是使用LBPH算法实现人脸识别的代码示例:

#include <opencv2/face.hpp>
#include <opencv2/opencv.hpp>using namespace cv;
using namespace cv::face;class FaceRecognizer {
private:Ptr<LBPHFaceRecognizer> model;public:FaceRecognizer() {model = LBPHFaceRecognizer::create();}void train(const std::vector<Mat>& faces, const std::vector<int>& labels) {model->train(faces, labels);}void predict(const Mat& face, int& label, double& confidence) {model->predict(face, label, confidence);}void saveModel(const std::string& filename) {model->save(filename);}void loadModel(const std::string& filename) {model->read(filename);}
};

代码说明:

  1. FaceRecognizer类封装了LBPH人脸识别器的功能。
  2. 构造函数创建LBPH人脸识别器实例。
  3. train方法用于训练模型。
  4. predict方法进行人脸识别,返回预测的标签和置信度。
  5. saveModelloadModel方法用于保存和加载训练好的模型。

3.3 数据库操作

使用SQLite进行数据库操作的代码示例:

#include <sqlite3.h>
#include <string>
#include <stdexcept>
#include <iostream>class Database {
private:sqlite3* db;static int callback(void* data, int argc, char** argv, char** azColName) {// 处理查询结果的回调函数for(int i = 0; i < argc; i++) {std::cout << azColName[i] << " = " << (argv[i] ? argv[i] : "NULL") << std::endl;}std::cout << std::endl;return 0;}public:Database(const std::string& dbName) {if (sqlite3_open(dbName.c_str(), &db) != SQLITE_OK) {throw std::runtime_error("Can't open database: " + std::string(sqlite3_errmsg(db)));}}~Database() {sqlite3_close(db);}void executeQuery(const std::string& sql) {char* errMsg = nullptr;int rc = sqlite3_exec(db, sql.c_str(), callback, 0, &errMsg);if (rc != SQLITE_OK) {std::string error = "SQL error: " + std::string(errMsg);sqlite3_free(errMsg);throw std::runtime_error(error);}}void insertEmployee(const std::string& name, int id) {std::string sql = "INSERT INTO employees (name, id) VALUES ('" + name + "', " + std::to_string(id) + ");";executeQuery(sql);}void recordAttendance(int employeeId, const std::string& timestamp) {std::string sql = "INSERT INTO attendance (employee_id, timestamp) VALUES (" + std::to_string(employeeId) + ", '" + timestamp + "');";executeQuery(sql);}
};

代码说明:

  1. Database类封装了SQLite数据库的基本操作。
  2. 构造函数打开数据库连接,析构函数关闭连接。
  3. executeQuery方法执行SQL查询,使用回调函数处理结果。
  4. insertEmployee方法插入新员工记录。
  5. recordAttendance方法记录考勤信息。

3.4 Qt界面实现

以下是使用Qt实现主界面的代码示例:

#include <QMainWindow>
#include <QPushButton>
#include <QVBoxLayout>
#include <QMessageBox>class MainWindow : public QMainWindow {Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr) : QMainWindow(parent) {setWindowTitle("人脸识别考勤系统");QWidget *centralWidget = new QWidget(this);QVBoxLayout *layout = new QVBoxLayout(centralWidget);QPushButton *btnAttendance = new QPushButton("考勤签到", this);QPushButton *btnManage = new QPushButton("员工管理", this);QPushButton *btnReport = new QPushButton("考勤报表", this);layout->addWidget(btnAttendance);layout->addWidget(btnManage);layout->addWidget(btnReport);setCentralWidget(centralWidget);connect(btnAttendance, &QPushButton::clicked, this, &MainWindow::onAttendanceClicked);connect(btnManage, &QPushButton::clicked, this, &MainWindow::onManageClicked);connect(btnReport, &QPushButton::clicked, this, &MainWindow::onReportClicked);}
private slots:void onAttendanceClicked() {// 打开考勤签到界面QMessageBox::information(this, "考勤签到", "正在打开摄像头进行人脸识别...");// 这里可以调用人脸识别和考勤记录的相关函数}void onManageClicked() {// 打开员工管理界面QMessageBox::information(this, "员工管理", "正在打开员工管理界面...");// 这里可以实现一个新的对话框或窗口来管理员工信息}void onReportClicked() {// 生成考勤报表QMessageBox::information(this, "考勤报表", "正在生成考勤报表...");// 这里可以实现报表生成和显示的功能}
};// 主函数
int main(int argc, char *argv[]) {QApplication app(argc, argv);MainWindow mainWindow;mainWindow.show();return app.exec();
}

代码说明:

  1. MainWindow类继承自QMainWindow,实现了主界面的布局和功能。
  2. 构造函数中创建了三个按钮:考勤签到、员工管理和考勤报表。
  3. 使用QVBoxLayout垂直布局来排列按钮。
  4. 通过connect函数将按钮的点击事件与相应的槽函数连接。
  5. 三个槽函数onAttendanceClickedonManageClickedonReportClicked分别处理不同按钮的点击事件。
  6. 主函数创建并显示主窗口,启动Qt事件循环。

3.5 STM32与Qt通信

以下是STM32与Qt程序通过串口通信的示例代码:

// STM32端代码(使用HAL库)
#include "stm32f4xx_hal.h"UART_HandleTypeDef huart2;void UART_Init(void) {huart2.Instance = USART2;huart2.Init.BaudRate = 115200;huart2.Init.WordLength = UART_WORDLENGTH_8B;huart2.Init.StopBits = UART_STOPBITS_1;huart2.Init.Parity = UART_PARITY_NONE;huart2.Init.Mode = UART_MODE_TX_RX;huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;HAL_UART_Init(&huart2);
}void SendData(uint8_t* data, uint16_t size) {HAL_UART_Transmit(&huart2, data, size, HAL_MAX_DELAY);
}// Qt端代码
#include <QSerialPort>
#include <QSerialPortInfo>class SerialCommunication : public QObject {Q_OBJECTpublic:SerialCommunication(QObject *parent = nullptr) : QObject(parent) {serial = new QSerialPort(this);connect(serial, &QSerialPort::readyRead, this, &SerialCommunication::handleReadyRead);}bool openPort(const QString &portName) {serial->setPortName(portName);serial->setBaudRate(QSerialPort::Baud115200);return serial->open(QIODevice::ReadWrite);}void closePort() {if (serial->isOpen()) {serial->close();}}void sendData(const QByteArray &data) {if (serial->isOpen()) {serial->write(data);}}private slots:void handleReadyRead() {QByteArray data = serial->readAll();emit dataReceived(data);}signals:void dataReceived(const QByteArray &data);private:QSerialPort *serial;
};// 在主窗口中使用SerialCommunication类
class MainWindow : public QMainWindow {Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr) : QMainWindow(parent) {serialComm = new SerialCommunication(this);connect(serialComm, &SerialCommunication::dataReceived, this, &MainWindow::onDataReceived);// 初始化串口if (serialComm->openPort("COM3")) {  // 根据实际情况修改串口名qDebug() << "Serial port opened successfully";} else {qDebug() << "Failed to open serial port";}}private slots:void onDataReceived(const QByteArray &data) {// 处理接收到的数据qDebug() << "Received data:" << data;// 这里可以添加对接收数据的处理逻辑}void sendCommandToSTM32(const QString &command) {serialComm->sendData(command.toUtf8());}private:SerialCommunication *serialComm;
};

代码说明:

  1. SerialCommunication类封装了Qt串口通信的功能。
  2. openPort方法用于打开指定的串口。
  3. closePort方法用于关闭串口。
  4. sendData方法用于发送数据到STM32。
  5. handleReadyRead槽函数处理接收到的数据,并通过信号dataReceived发送出去。
  6. MainWindow类中,我们创建了SerialCommunication实例,并连接了数据接收的信号和槽。
  7. onDataReceived槽函数用于处理从STM32接收到的数据。
  8. sendCommandToSTM32方法用于向STM32发送命令。

3.6 人脸识别与考勤逻辑集成

以下是将人脸识别与考勤逻辑集成到Qt应用程序中的示例代码:

#include <QCamera>
#include <QCameraImageCapture>
#include <QTimer>
#include <QDateTime>
#include <opencv2/opencv.hpp>class AttendanceSystem : public QObject {Q_OBJECTpublic:AttendanceSystem(QObject *parent = nullptr) : QObject(parent) {faceDetector = new FaceDetector("haarcascade_frontalface_default.xml");faceRecognizer = new FaceRecognizer();database = new Database("attendance.db");camera = new QCamera(this);imageCapture = new QCameraImageCapture(camera);connect(imageCapture, &QCameraImageCapture::imageCaptured, this, &AttendanceSystem::processCapturedImage);// 每5秒捕获一次图像QTimer *timer = new QTimer(this);connect(timer, &QTimer::timeout, this, &AttendanceSystem::captureImage);timer->start(5000);}public slots:void startAttendance() {camera->start();}void stopAttendance() {camera->stop();}private slots:void captureImage() {imageCapture->capture();}void processCapturedImage(int id, const QImage &preview) {cv::Mat frame = QImageToMat(preview);std::vector<cv::Rect> faces = faceDetector->detectFaces(frame);for (const auto& face : faces) {cv::Mat faceROI = frame(face);int label;double confidence;faceRecognizer->predict(faceROI, label, confidence);if (confidence < 80.0) { // 假设置信度阈值为80recordAttendance(label);emit attendanceRecorded(label);}}}void recordAttendance(int employeeId) {QDateTime currentTime = QDateTime::currentDateTime();QString timestamp = currentTime.toString("yyyy-MM-dd hh:mm:ss");database->recordAttendance(employeeId, timestamp.toStdString());}private:FaceDetector *faceDetector;FaceRecognizer *faceRecognizer;Database *database;QCamera *camera;QCameraImageCapture *imageCapture;cv::Mat QImageToMat(const QImage &image) {cv::Mat mat;switch (image.format()) {case QImage::Format_RGB888:mat = cv::Mat(image.height(), image.width(), CV_8UC3, (void*)image.constBits(), image.bytesPerLine());cv::cvtColor(mat, mat, cv::COLOR_RGB2BGR);break;case QImage::Format_ARGB32_Premultiplied:mat = cv::Mat(image.height(), image.width(), CV_8UC4, (void*)image.constBits(), image.bytesPerLine());cv::cvtColor(mat, mat, cv::COLOR_RGBA2BGR);break;default:break;}return mat;}signals:void attendanceRecorded(int employeeId);
};

代码说明:

  1. AttendanceSystem 类集成了整个考勤系统的核心功能,包括摄像头控制、图像处理、人脸识别和考勤记录。

  2. 构造函数中:

    • 初始化 FaceDetectorFaceRecognizer 和 Database 对象。
    • 设置 QCamera 和 QCameraImageCapture 用于图像捕获。
    • 创建一个定时器,每5秒触发一次图像捕获。
  3. startAttendance() 和 stopAttendance() 方法用于启动和停止考勤过程。

  4. captureImage() 槽函数被定时器触发,用于捕获摄像头图像。

  5. processCapturedImage() 是核心处理函数:

    • 将 QImage 转换为 OpenCV 的 Mat 格式。
    • 使用 FaceDetector 检测人脸。
    • 对每个检测到的人脸进行识别。
    • 如果识别置信度高于阈值,则记录考勤。
  6. recordAttendance() 方法将考勤记录保存到数据库中,包括员工ID和时间戳。

  7. QImageToMat() 是一个辅助函数,用于将 Qt 的 QImage 转换为 OpenCV 的 Mat 格式。

  8. 类中定义了 attendanceRecorded 信号,当成功记录考勤时发出,可用于更新UI或通知其他组件。

  9. 整个系统通过定时捕获图像、检测人脸、识别身份、记录考勤的流程,实现了自动化的考勤功能。

  10. 该设计允许系统在后台持续运行,不需要人工干预即可完成考勤过程。

  11. 通过调整人脸识别的置信度阈值(此处设为80.0),可以平衡系统的准确性和灵敏度。

  12. 系统集成了数据库操作,确保考勤记录能够被永久保存和后续查询。

4. 项目总结

4.1 主要成果

  1. 成功实现了基于STM32和Qt的全栈人脸识别考勤系统。
  2. 集成了实时人脸检测和识别功能,提高了考勤效率。
  3. 开发了友好的用户界面,方便管理员操作和数据查询。
  4. 实现了考勤数据的自动化记录和统计分析功能。

4.2 技术亮点

  1. 采用OpenCV进行图像处理和人脸识别,提高了识别的准确性。
  2. 使用Qt框架开发跨平台桌面应用,提升了用户体验。
  3. 集成SQLite数据库,实现了高效的数据管理和查询。
  4. STM32与Qt的串口通信实现,使硬件控制更加灵活。

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/3249277.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

Pytorch学习笔记day3——用神经网络学习一组函数

好的&#xff0c;我们开始吧。首先第一个问题&#xff0c;神经网络的本质是什么&#xff1f;是古典主义的人类的神经元吗&#xff1f;绝对不是&#xff0c;他只是一个优化函数 y f θ ( x ) y f_{\theta}(x) yfθ​(x) 这和小学学到的线性函数拟合并无本质区别。只是其中参数…

汇编教程1

本教程主要教大家如何使用vscode插件编写汇编语言&#xff0c;这样更方便&#xff0c;不用在32位虚拟机中编写汇编语言&#xff0c;后续的汇编实验代码都是使用vscode编写&#xff0c;话不多说&#xff0c;开始教学 安装vscode 如果已经安装过vscode&#xff0c;可以跳过这一…

Django 请求和响应

1、请求 &#xff08;1&#xff09;get请求 用户直接在浏览器输入网址&#xff0c;参数直接在url中携带 http://127.0.0.1:8000/login/?a1&b%221243%22 &#xff08;2&#xff09;post请求 在html使用post,login.html <!DOCTYPE html> <html lang"en&…

操作系统发展简史(Unix/Linux 篇 + DOS/Windows 篇)+ Mac 与 Microsoft 之风云争霸

操作系统发展简史&#xff08;Unix/Linux 篇&#xff09; 说到操作系统&#xff0c;大家都不会陌生。我们天天都在接触操作系统 —— 用台式机或笔记本电脑&#xff0c;使用的是 windows 和 macOS 系统&#xff1b;用手机、平板电脑&#xff0c;则是 android&#xff08;安卓&…

el-select选择器修改背景颜色

<!--* FilePath: topSearch.vue* Author: 是十九呐* Date: 2024-07-18 09:46:03* LastEditTime: 2024-07-18 10:42:03 --> <template><div class"topSearch-container"><div class"search-item"><div class"item-name&quo…

Hadoop-36 HBase 3节点云服务器集群 HBase Shell 增删改查 全程多图详细 列族 row key value filter

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; HadoopHDFSMapReduceHiveFlumeSqoopZookeeperHBase 正在 章节内容 上一节我们完成了&#xff1a; 集群的…

内部类+图书管理系统

内部类图书管理系统 1. 实例内部类1.1 实例内部类的结构1.2 实例内部类的一些问题1.2.1 如何在main中创建实例内部类对象&#xff1f;1.2.2 内部类成员变量被static修饰问题&#xff1f;1.2.3 内部类和外部类变量重名的调用问题&#xff1f;1.2.4 外部类访问内部类变量的问题 2…

浅谈C嘎嘎入门基础

看到这篇文章的童鞋或许会有疑惑&#xff0c;这不是之前 已经出过了吗&#xff0c;是的但是之前那篇文章可能不太好理解&#xff0c;因此我再写一篇便于大家理解的文章 那么上一篇文章已经帮大家过渡到C嘎嘎了&#xff0c;那么这篇文章我们继续讲解C嘎嘎的知识点。 C嘎嘎中的引…

【面试题】数据结构:堆排序的排序思想?

堆排序的排序思想&#xff1f; 堆排序是一种高效的排序算法&#xff0c;其基本思想是利用堆这种数据结构来实现排序。堆是一种特殊的完全二叉树&#xff0c;通常用数组来表示。堆排序的基本步骤如下&#xff1a; 1. 构建初始堆&#xff1a; 将待排序的数组转换成一个最大堆&a…

在RK3568上如何烧录MAC?

这里我们用RKDevInfoWriteTool 1.1.4版本 下载地址&#xff1a;https://pan.baidu.com/s/1Y5uNhkyn7D_CjdT98GrlWA?pwdhm30 提 取 码&#xff1a;hm30 烧录过程&#xff1a; 1. 解压RKDevInfoWriteTool_Setup_V1.4_210527.7z 进入解压目录&#xff0c;双击运行RKDevInfo…

Java案例斗地主游戏

目录 一案例要求&#xff1a; 二具体代码&#xff1a; 一案例要求&#xff1a; &#xff08;由于暂时没有学到通信知识&#xff0c;所以只会发牌&#xff0c;不会设计打牌游戏&#xff09; 二具体代码&#xff1a; Ⅰ&#xff1a;主函数 package three;public class test {…

【BUG】已解决:zipfile.BadZipFile: File is not a zip file

已解决&#xff1a;zipfile.BadZipFile: File is not a zip file 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页&#xff0c;我是博主英杰&#xff0c;211科班出身&#xff0c;就职于医疗科技公司&#xff0c;热衷分享知识&#xff0c;武汉城市开发…

如何在项目中使用线程池自定义拒绝策略

首先呢&#xff0c;我设计了一个图表在我的项目里面&#xff0c;为了方便展示&#xff0c;我只修改一个字段&#xff0c;线程池设置参数 (2,4,30, TimeUnit.SECONDS, new ArrayBlockingQueue<>(4),new RJ()); 然后通过循环持续的进行增加任务&#xff0c;目的修改数据库的…

机器人开源调度系统OpenTCS-6最新版本地源码运行

OpenTCS 项目使用 Gradle 而不是 Maven&#xff0c;那么需要使用 Gradle 来导入和构建项目。在 IntelliJ IDEA 中导入和运行使用 Gradle 的项目&#xff0c;可以按照以下步骤进行操作&#xff1a; 克隆 OpenTCS 源码 首先&#xff0c;克隆 OpenTCS 的源码到本地。您可以使用以…

Jenkins-zookeeper-docker-xxljob-rancher

文章目录 Jenkins实战1 新建任务需要的配置pipeline Zookeeper基础 Docker基础实操windows11 docker mysql DockerhouseDockerhubxxl-Job基础实战 Rancher基础思考 实战1 Rancher的某个namespace的scale为0 Jenkins 实战 1 新建任务需要的配置pipeline 该代码是Jenkinsfile&…

腾讯元宝上线“3D角色梦工厂”:快速生成专属3D角色!

7月16日&#xff0c;腾讯旗下大模型应用“腾讯元宝”上线“3D角色梦工厂”&#xff0c;允许用户通过上传一张五官清晰的正面头像&#xff0c;并选择不同的角色模板&#xff0c;迅速生成个人3D角色&#xff01; 技术特点 “3D角色梦工厂”将大模型生成技术与3D应用相结合&#…

Java跨平台的原理是什么?JDK,JRE,JVM三者的作用和区别?xxx.java和xxx.class有什么区别?看这一篇就够了

目录 1. Java跨平台相关问题 1.1 什么是跨平台(平台无关性)&#xff1f; 1.2 跨平台(平台无关性)的好处&#xff1f; 1.3 编译原理基础&#xff08;Java程序编译过程&#xff09; 1.4Java跨平台的是实现原理&#xff1f; 1.4.1 JVM(Java虚拟机) 1.4.2 Class文件 1.4.3 …

阿尔泰科技工业电脑IPC-8363工控机

概述&#xff1a; IPC-8363是一款支持 LGA 1200 Intel 10th/11th Generation Core™ i9/i7/i5/i3, Celeron and Pentium processor 的工业电脑。配置2组独立 SO-DIMM DDR4 2666/2933MHz内存&#xff0c;最大可扩展至128GB。 主要技术指标&#xff1a; 产品图示&#xff1a; 系…

PyTorch 深度学习实践-循环神经网络(高级篇)

视频指路 参考博客笔记 参考笔记二 文章目录 上课笔记总代码练习 上课笔记 个人能力有限&#xff0c;重看几遍吧&#xff0c;第一遍基本看不懂 名字的每个字母都是一个特征x1,x2,x3…&#xff0c;一个名字是一个序列 rnn用GRU 用ASCII表作为词典&#xff0c;长度为128&#x…

加密传输及相关安全验证:

1.1. 加密&#xff1a; 1.1.1. 对称加密&#xff1a; 特点&#xff1a;加解密用一个密钥&#xff0c;加解密效率高&#xff0c;速度快&#xff0c;有密钥交互的问题问题&#xff1a;双方如何交互对称密钥的问题&#xff0c;用非对称密钥的公钥加密对称密钥的混合加密方式常用…