【QT】基于⼈脸识别的打卡系统(QT+Opencv+SQLite)--实
现过程
交流号:245022761(IT项⽬交流)
⽬录
⼯具准备
1、安装Opencv,并添加到环境变量中  F:\Qt\opencv64\x64\mingw\bin
2、将Opencv下的⼈脸检测分类器(haarcascade_l)拷贝到⾃⼰的⼯程下
3、opencv3的⼈脸识别库拷贝到⾃⼰的⼯程下(src整个⽂件夹、face整个⽂件夹、face.hpp)
下载地址:
⼯程结构解析
rectangle函数opencv
⼀图看懂⼯程结构
配置⽂件中加⼊opencv相关⽂件
# 添加src⽬录下的源⽂件
SOURCES += \
main.cpp \
faceattendance.cpp\
src/bif.cpp \
src/eigen_faces.cpp \
src/face_alignment.cpp \
src/face_basic.cpp \
src/facemark.cpp \
src/facemarkAAM.cpp \
src/facemarkLBF.cpp \
src/facerec.cpp \
src/fisher_faces.cpp \
src/getlandmarks.cpp \
src/lbph_faces.cpp \
src/mace.cpp \
src/predict_collector.cpp \
src/regtree.cpp \
src/trainFacemark.cpp \
admiwin.cpp \
train.cpp \
recordwin.cpp
HEADERS += \
faceattendance.h\
face/bif.hpp \
face/face_alignment.hpp \
face/facemark.hpp \
face/facemark_train.hpp \
face/facemarkAAM.hpp \
face/facemarkLBF.hpp \
face/facerec.hpp \
face/mace.hpp \
face/predict_collector.hpp \
src/face_alignmentimpl.hpp \
src/face_utils.hpp \
src/precomp.hpp \
face.hpp \
admiwin.h \
train.h \
recordwin.h
FORMS += \
faceattendance.ui \
admiwin.ui \
recordwin.ui
INCLUDEPATH +=F:\Qt\opencv64\include INCLUDEPATH +=F:\Qt\opencv64\include\opencv INCLUDEPATH +=F:\Qt\opencv64\include\opencv2
LIBS += F:\Qt\opencv64\x64\mingw\lib\libopencv*代码实现
(1)检测⼈脸
出⼀张图⽚的⼈脸部分并矩形框出
#include <opencv2/opencv.hpp>
using namespace cv;
装载⼈脸识别分类器  cascada.load("F:\\814_FaceAttendance\\tools\\haarcascade_l")
void AdmiWin::showImage()
{
Mat temp;//临时保存RGB图像
cap>>frame;//摄像头读取头像
cvtColor(frame, frame_gray, COLOR_BGR2GRAY);//转灰度化,减少运算
cascada.detectMultiScale(frame_gray, faces, 1.1, 4,
CV_HAAR_DO_ROUGH_SEARCH,
Size(70, 70),
Size(1000, 1000));
ui->label_count->setText("face=" + QString::number(faces.size()));
//qDebug()<<"检测到⼈脸个数:" + QString::number(faces.size());
/
/识别到的脸⽤矩形圈出
for (int i = 0; i < faces.size(); i++)
{
rectangle(frame, faces[i], Scalar(255, 0, 0), 2, 8, 0);
}
cvtColor(frame, temp, CV_BGR2RGB);//BGR convert to RGB
QImage Qtemp = QImage((const unsigned char*)(temp.data),
QImage::Format_RGB888);
ui->label_face->setScaledContents(true);
ui->label_face->setPixmap(QPixmap::fromImage(Qtemp));
ui->label_face->show();
}
(2)采集头像
采集的头像路径⽂件夹名称为⼯号,⽅便匹配,图⽚以数字命名
/**
* @brief 采集头像
*/
void AdmiWin::on_pushButton_cap_clicked()
{
if(!ui->lineEdit_num->text().isEmpty())
{
//当只有⼀个⼈脸时,开始拍照
if (faces.size() == 1)
{
pic_num ++;
ui->label_tip->setText("已经采集头像第" + QString::number(pic_num) + "张");
Mat faceROI = frame_gray(faces[0]);//在灰度图中将圈出的脸所在区域裁剪出
::resize(faceROI, myFace, Size(92, 112));//将兴趣域size为92*112
//在 faces[0].tl()的左上⾓上⾯写序号
putText(frame, to_string(pic_num), faces[0].tl(), 3, 1.2, (0, 0, 225), 2, 0);
Mat temp;//临时保存RGB图像
cvtColor(frame, temp, CV_BGR2RGB);//BGR convert to RGB
QImage Qtemp = QImage((const unsigned char*)(temp.data),
QImage::Format_RGB888);
ui->label_face_2->setScaledContents(true);
ui->label_face_2->setPixmap(QPixmap::fromImage(Qtemp));
ui->label_face_2->show();
//图⽚的存放位置
QString dir_str = "F:\\Qt\\workplaces\\814_FaceAttendance\\att_faces\\"
+ ui->lineEdit_num->text() + "\\" + QString::number(pic_num) + ".jpg";
/
/string filename = format("%s%d.jpg",pic_num);
string filename = StdString();
imwrite(filename, myFace);//存在当前⽬录下
}
}
else {
QMessageBox::about(NULL, "提⽰", "请输⼊⼯号!");
}
}
(3)训练模型
模型训练部分封装成线程(耗时太久,开启线程运⾏),训练完成后⽣成⼀下三个⽂件
头⽂件