嵌入式Linux QT+OpenCV基于人脸识别的考勤系统 项目

此项目是基于人脸识别的考勤系统开发,包括如下模块:

1、人脸识别考勤系统GUI界面设计,包括:

(1)Qt环境(window环境/linux环境) ;

(2)Qt工程创建分析;

(3) Qt基本组件Qwidget QMainWindow,Qdialog,QLineEdit,Qlabel, QPushButton ;

(4)Qt界面布局,设计人脸识别考勤系统界面搭建;

(5)考勤机界面设计 (考勤默认界面, 数据录入界面,数据查询界面)。

2、考勤机界面逻辑与数据库实现,主要包括:

(1)Qt窗口切换

(2)Qt窗口间数据传递;

(3)人脸识别考勤机数据库及数据表的设计

3、人脸识别算法,主要包括:

(1)人脸识别算法分析及程序开发;

(2)opencv环境搭建;

(3)opencv采集人脸图像的程序开发;

(4)seetface人脸识别算法及程序开发。

4、人脸识别算法与Qt界面结合实现,主要包括:

(1)人脸检测及在Qt界面上的显示程序开发;

(2)人脸特征点提取及程序开发;

(3)人脸跟踪在Qt上显示;

(4)人脸信息采集存入数据库的编程;

(5)Qt线程Qthread应用,通过信号实现数据交换。
5、QT开发环境下的人脸识别考勤系统机整合调试,主要包括:

(1)在线程中处理人脸比对编程;

(2)比对数据写入考勤数据库的程序实现;

(3)在Qt界面显示比对结果并且提示考勤成功的程序开发;

(4)项目优化综合调试。

下述为QT的UI界面。

这里就是我们的代码层级结构了。

我们先看main.c

cpp 复制代码
#include "faceproject.h"

#include <QApplication>
#include "seeta/FaceDetector.h" //人脸检测
#include "seeta/FaceRecognizer.h"
#include "seeta/FaceLandmarker.h"
#include "opencv.hpp"
#include <QDebug>
#include "QSqlDatabase"
#include <QSqlQuery>
#include <QSqlError>
using namespace  seeta;
using namespace  cv;


int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    qRegisterMetaType<Mat>("Mat");
    qRegisterMetaType<Mat>("Mat&");

    //打开数据库
    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName("./data/user.db");
    if(!db.open())
    {
        qDebug()<<db.lastError().text();
    }
    //创建一个表格
    QString createsql = "create table if not exists user (userid varchar(64) primary key,faceid int,username text, partment text, facename text)";
    QSqlQuery query ;
    query.exec(createsql);

    //创建一个表格
    createsql = "create table if not exists  userrecord (id integer primary key autoincrement, userid varchar(64), cktime datatime)";
    if(!query.exec(createsql))
    {
        qDebug()<<query.lastError().text();
    }

    FaceProject w;
    w.show();
    return a.exec();
}

功能解析

  • 程序主框架

    • QApplication 是 Qt 桌面应用程序的核心类,用于管理应用的生命周期。
    • FaceProject w; w.show(); 表示创建了一个名为 FaceProject 的主窗口对象,并将其显示。
  • SeetaFace 初始化

    • seeta::FaceDetector, seeta::FaceRecognizer, 和 seeta::FaceLandmarker 分别是 SeetaFace SDK 提供的三大功能模块,用于人脸检测、识别、和关键点标注。虽然这些模块没有在代码中直接调用,但它们被 #include 引入,表明可能在其他地方会使用。
  • OpenCV 的支持

    • cv::Mat 是 OpenCV 中的图像数据结构。
    • qRegisterMetaType<Mat>("Mat")qRegisterMetaType<Mat>("Mat&")cv::Mat 类型注册到 Qt 的元对象系统中,方便在信号与槽机制中传递 OpenCV 的图像对象。
  • SQLite 数据库操作

    • 打开数据库
cpp 复制代码
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("./data/user.db");
  • 打开或创建一个 SQLite 数据库文件,路径为相对路径 ./data/user.db

  • 创建表格

    • user:存储用户的基本信息。
cpp 复制代码
create table if not exists user (
    userid varchar(64) primary key,
    faceid int,
    username text,
    partment text,
    facename text
);
  • userid 是用户唯一标识符。
  • faceid 可能存储人脸特征 ID。
  • 其他字段存储用户姓名、部门、和人脸数据文件名等。

userrecord:存储用户的考勤记录。

cpp 复制代码
create table if not exists userrecord (
    id integer primary key autoincrement,
    userid varchar(64),
    cktime datetime
);
  • id 是记录的自增主键。
  • userid 关联用户表的 userid
  • cktime 是记录的时间戳。

错误处理

  • 如果数据库打开失败,输出错误信息:
cpp 复制代码
if(!db.open())
{
    qDebug()<<db.lastError().text();
}
  • 如果表格创建失败,输出 SQL 错误信息:
cpp 复制代码
if(!query.exec(createsql))
{
    qDebug()<<query.lastError().text();
}

主窗口启动

  • FaceProject 是一个自定义的类,继承自 QWidget 或其子类。w.show() 表示显示主窗口,return a.exec(); 开始事件循环。

下述就是SeetaFace 人脸识别库的应用的代码段了

cpp 复制代码
seeta::ModelSetting FaceProject::FTSetting = seeta::ModelSetting("./model/fd_2_00.dat",seeta::ModelSetting::CPU,0);

FTSetting 是人脸检测模型的设置,使用 SeetaFace 库加载 fd_2_00.dat 模型,指定使用 CPU 模式。

cpp 复制代码
FaceProject::FaceProject(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::FaceProject)
    , mFTracker(FTSetting)
{
    ui->setupUi(this);
    capture.open(0);
    if(!capture.isOpened()) {
        qDebug()<<"open error";
    }
    Mat tempImage = imread("./image/background.jpeg"); // 显示的背景
    tempImage.copyTo(backImage, mark2Image); // 截取除去头像外的背景
    circ1Image = imread("./image/frontcircle.png");
    circ2Image = imread("./image/backcircle.png");

    // 初始化线程--识别(识别完后会收到query信号)
    mthread = new QThread();
    connect(this, &FaceProject::sendMat, &mRecognier, &QRecognizer::queryFace);
    mRecognier.moveToThread(mthread);
    mthread->start();
    connect(&mRecognier, &QRecognizer::query, this, &FaceProject::queryResult);
    
    startTimer(100); // 启动定时器,每100毫秒执行一次

    camflag = false;
    model = new QSqlTableModel();
    model->setTable("user");
    model->select();
    ui->tableView->setModel(model);
}
  • 人脸检测初始化 :创建 mFTracker 对象并初始化 SeetaFace 模型(fd_2_00.dat)。
  • 摄像头初始化 :使用 OpenCV 打开默认的摄像头设备(capture.open(0))。
  • 图片初始化:加载背景图和两个圆形头像图,用于显示用户头像。
  • 线程和信号连接 :初始化识别线程 mthread,并将 sendMat 信号连接到 mRecognier.queryFace 函数,完成异步的人脸识别操作。
cpp 复制代码
QString selectsql = QString("select * from user where faceid=%1").arg(index);
QSqlQuery query;
query.exec(selectsql);
if(query.next()) {
    QSqlRecord record = query.record();
    QString numberstr = record.value("userid").toString();
    QString namestr = record.value("username").toString();
    QString partstr = record.value("partment").toString();
    QString facepath = record.value("facename").toString();
    
    ui->numberLb->setText(numberstr);
    ui->nameLb->setText(namestr);
    ui->partLb->setText(partstr);
    ui->timeLb->setText(QTime::currentTime().toString("hh:mm:ss"));
    
    Mat faceImage = imread(facepath.toUtf8().data());
    showHeader(faceImage);
    
    if (oldid != index && index != -1) {
        oldid = index;
        QString insertsql = QString("insert into userrecord(userid, cktime) values('%1','%2')")
                            .arg(numberstr).arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"));
        if (!query.exec(insertsql)) {
            qDebug() << query.lastError().text();
        }
    }
}
  • 根据检测到的 index 查询数据库中的用户信息(user 表)并显示。
  • 如果找到该用户的记录,会显示用户的 useridusernamepartment 等信息。
  • 将考勤记录插入 userrecord 表中,保存当前时间戳。
cpp 复制代码
void FaceProject::showHeader(Mat &image) {
    cv::resize(image, image, cv::Size(160, 160));
    Mat circular;
    image.copyTo(circular, circ2Image);  // 使用圆形图像遮罩
    addWeighted(circular, 1, circ1Image, 1, 3, image);  // 将圆形头像图合并到原图
    QImage image1(image.data, 160, 160, image.step, QImage::Format_RGB888);
    ui->label_2->setPixmap(QPixmap::fromImage(image1));
}

将用户的头像调整为 160x160 大小,并加上圆形遮罩效果。

cpp 复制代码
void FaceProject::showFaceVideo(Mat &image) {
    cv::resize(image, image, cv::Size(480, 480));
    cvtColor(image, image, COLOR_BGR2RGB);  // 转换颜色空间
    QImage vimage(image.data, 480, 480, image.step, QImage::Format_RGB888);
    ui->label->setPixmap(QPixmap::fromImage(vimage));
}

将摄像头采集到的视频流调整为 480x480 并显示在界面上。

相关推荐
Scott9999HH3 小时前
【IIoT流量实战】蒸汽管道阀门全关却仍有流量?用 Python 实现涡街信号 FFT 频谱分析与温压全补偿积算网关,深度拆解靠谱的涡街流量计厂家硬核技术标准
开发语言·python
Yana.nice3 小时前
Linux 只保留 30 天内日志(find命令删除日志文件)
linux·运维·chrome
码智社4 小时前
AES加密原理详解及Java实现加解密实战
java·开发语言
AI云海4 小时前
python 列表、元组、集合和字典
开发语言·python
萧瑟余晖5 小时前
JDK 26 新特性详解
java·开发语言
马优晨5 小时前
Freemarker 完整讲解(后端 Java 模板引擎)
java·开发语言·freemarker·freemarker 完整讲解·freemarker模板引擎
DFT计算杂谈7 小时前
无 Root 权限在 Tesla K80 零门槛部署 DeepSeek 大模型
linux·服务器·网络·数据库·机器学习
人邮异步社区7 小时前
怎么把C语言学到精通?
c语言·开发语言
心平气和量大福大8 小时前
C#-WPF-控件-TextBox 数据绑定
开发语言·c#·wpf
ttwuai8 小时前
Cursor 生成 CRUD 后,Go 后台接口别只测 200:JWT、RBAC 和 tenant_id 怎么验
开发语言·后端·golang