此项目是基于人脸识别的考勤系统开发,包括如下模块:
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
#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 数据库操作
-
打开数据库:
-
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("./data/user.db");
-
打开或创建一个 SQLite 数据库文件,路径为相对路径
./data/user.db
。 -
创建表格:
-
表
user
:存储用户的基本信息。
-
create table if not exists user (userid varchar(64) primary key,faceid int,username text,partment text,facename text
);
userid
是用户唯一标识符。faceid
可能存储人脸特征 ID。- 其他字段存储用户姓名、部门、和人脸数据文件名等。
表 userrecord
:存储用户的考勤记录。
create table if not exists userrecord (id integer primary key autoincrement,userid varchar(64),cktime datetime
);
id
是记录的自增主键。userid
关联用户表的userid
。cktime
是记录的时间戳。
错误处理
- 如果数据库打开失败,输出错误信息:
if(!db.open())
{qDebug()<<db.lastError().text();
}
- 如果表格创建失败,输出 SQL 错误信息:
if(!query.exec(createsql))
{qDebug()<<query.lastError().text();
}
主窗口启动
FaceProject
是一个自定义的类,继承自QWidget
或其子类。w.show()
表示显示主窗口,return a.exec();
开始事件循环。
下述就是SeetaFace 人脸识别库的应用的代码段了
seeta::ModelSetting FaceProject::FTSetting = seeta::ModelSetting("./model/fd_2_00.dat",seeta::ModelSetting::CPU,0);
FTSetting
是人脸检测模型的设置,使用 SeetaFace 库加载 fd_2_00.dat
模型,指定使用 CPU 模式。
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
函数,完成异步的人脸识别操作。
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
表)并显示。 - 如果找到该用户的记录,会显示用户的
userid
、username
、partment
等信息。 - 将考勤记录插入
userrecord
表中,保存当前时间戳。
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 大小,并加上圆形遮罩效果。
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 并显示在界面上。