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://www.mzph.cn/bicheng/47770.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LVS+Nginx高可用集群---keepalived原理与实战

1.高可用集群架构keepalived双机主备原理 高可用&#xff1a;(HA) 部署nginx存在两台nginx。当主节点的nginx宕机停止服务的时候&#xff0c;nginx备用机起到跟nginx(主) keepalived的概念&#xff1a;解决单点故障&#xff1b;组件免费&#xff1b;可以实现高可用HA机制&…

【音视频 | HTTP协议】HTTP协议详细介绍(HTTP方法、报文格式、报文头部字段、状态码)

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; &#x1f923;本文内容&#x1f923;&a…

推出全新的ZL3079x、ZL3069x、ZL3066x同步器,优化用于5G运输和无线基础设施设备

一、单通道、双通道和三通道IEEE1588/SyncE网络同步器 ZL3079x提供1个、2个和三个独立的组合硬件和软件平台定时通道&#xff0c;包括IEEE 1588-2008精确时间协议栈和同步算法。该设备使用miTimePLL定时技术&#xff0c;为5G传输和无线基础设施设备提供新的改进功能。该器件非…

阿里云ACP云计算高级攻城狮通用知识

&#x1f525;概述 阿里云云计算高级工程师ACP认证是面向使用阿里云云计算产品的架构、开发、运维类人员的专业技术认证&#xff0c;主要考核考生利用阿里云云计算技术服务体系设计稳定、安全、高性能、易扩展、低成本的企业云计算架构的能力。 前提&#xff1a;在写适用人群…

Spring后端框架复习总结

之前写的博客太杂,最近想把后端框架的知识点再系统的过一遍,主要是Spring Boot和Mybatis相关,带着自己的理解使用简短的话把一些问题总结一下,尤其是开发中和面试中的高频问题,基础知识点可以参考之前写java后端专栏,这篇不再赘述。 目录 Spring什么是AOP?底层原理?事务…

word的进阶

Word的基本操作 这里主要用到的软件是WPS软件。 一、创建一个文档 第一种&#xff1a;快捷键&#xff1a;ctrln第二种&#xff1a;通过界面鼠标点击 二、设置文档背景 更换过的背景如下&#xff1a; 三、章节、目录导航的设置 四、插入目录页 五、对历史文档进行管理 六、…

大数减法c++

这里写目录标题 key key 检查减数和被减数的大小&#xff0c;大的放前&#xff0c;小的放后确定结果是正数&#xff0c;还是负数&#xff0c;即符号位从低位开始减如果a[i]<b[i]&#xff0c;则向高位借1当10&#xff0c;a[i1]–;a[i]10 #include <iostream> #include…

Java_MyBatisPlus

MyBatisPlus属于是MyBatis的拓展&#xff0c;不影响原MyBatis框架下的代码运行&#xff0c;并对MyBatis框架进行拓展及优化。 使用步骤&#xff1a; 注意&#xff1a;继承BaseMapper时要填写泛型为要操作的实体类。 基本原理&#xff1a; MyBatisPlus通过扫描实体类&#xff…

怎么给PDF文件设置加密保护?有哪些方法?

pdf作为一种便携式文档&#xff0c;是展示内容的首选&#xff0c;目前也已广泛应用于交换和分享等&#xff0c;例如内部报告以及商业提案等。然而&#xff0c;在如今的数字化时代&#xff0c;随着越来越多的企业将其文档存储和在线分享&#xff0c;pdf文件也可能面临安全隐私泄…

深入理解ADB:Android调试桥详解与使用指南

&#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a;Android ⛳️ 功不唐捐&#xff0c;玉汝于成 目录 前言 正文 1. 什么是ADB&#xff1f; ADB的基本原理&#xff1a; 2. ADB的安装与配置 安装ADB工具集&#xff1a; 配置ADB环境变量&am…

人大金仓数据库驱动导入maven

1.去人大金仓官网去查找合适的驱动人大金仓-成为世界卓越的数据库产品与服务提供商 2.下载解压后 执行下面的代码 mvn install:install-file -DgroupIdkingbase -DartifactIdkingbase8 -Dversion8 -DfileF:\1foryou\foryou-report\kingbase8-8.6.0.jar -Dpackagingjar -Dgene…

FastAPI -- 第三弹(自定义响应、中间件、代理、WebSockets)

路径操作的高级配置 OpenAPI 的 operationId from fastapi import FastAPIapp FastAPI()# 通过 operation_id 参数设置 app.get("/items/", operation_id"some_specific_id_you_define") async def read_items():return [{"item_id": "F…

使用LVS+NGinx+Netty实现数据接入

数据接入 链接参考文档 LVSKeepalived项目 车辆数据上收&#xff0c;TBox通过TCP协议连接到TSP平台 建立连接后进行数据上传。也可借由该连接实现远程控制等操作。 通过搭建 LV—NGinx—Netty实现高并发数据接入 LVS&#xff1a;四层负载均衡&#xff08;位于内核层&#x…

Odoo17架构概述

多层架构 Odoo遵循多层架构&#xff0c;这意味着演示&#xff0c;业务逻辑和数据存储是分开的。更具体地说&#xff0c;它使用三层架构。 UI展示层 UI表示层是 HTML5、JavaScript 和 CSS 的组合。 应用程序的最顶层是用户界面。界面的主要功能是将任务和结果转换为用户可以理…

【数据结构】二叉树———Lesson2

Hi~&#xff01;这里是奋斗的小羊&#xff0c;很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~~ &#x1f4a5;&#x1f4a5;个人主页&#xff1a;奋斗的小羊 &#x1f4a5;&#x1f4a5;所属专栏&#xff1a;C语言 &#x1f680;本系列文章为个人学习…

Uniapp 组件 props 属性为 undefined

问题 props 里的属性值都是 undefined 代码 可能的原因 组件的名字要这样写&#xff0c;这个官方文档有说明

【Django】网上蛋糕商城后台-商品管理

1.商品管理功能 当管理员点击商品管理时&#xff0c;发送服务器请求 path(admin/goods_list/, viewsAdmin.goods_list), # 处理商品列表请求 def goods_list(request):try:type request.GET["type"]except:type 0try:ym request.GET["ym"]except:ym …

Spring Cloud Loadbalancer 的使用

一、默认负载均衡策略 Spring Cloud LoadBalancer 默认的负载均衡策略是轮询。 轮询效果示例 我们需要示例一个请求分发到不同的模块上&#xff0c;所以我们需要创建多模块项目。 新建 Spring Boot &#xff08;3.0.2&#xff09;的 Maven 项目&#xff08;JDK 17&#xff09…

ETL数据集成丨通过ETLCloud工具,将Oracle数据实时同步至Doris中

ETLCloud是一个全面的数据集成平台&#xff0c;专注于解决大数据量和高合规要求环境下的数据集成需求。采用先进的技术架构&#xff0c;如微服务和全Web可视化的集成设计&#xff0c;为用户提供了一站式的数据处理解决方案。 主要特点和功能包括&#xff1a; 实时数据处理&…

【已解决】Django连接MySQL启动报错Did you install mysqlclient?

在终端执行python manage.py makemigrations报错问题汇总 错误1&#xff1a;已安装mysqlclient&#xff0c;提示Did you install mysqlclient? 当你看到这样的错误信息&#xff0c;表明Django尝试加载MySQLdb模块但未找到&#xff0c;因为MySQLdb已被mysqlclient替代。 【解…