Qt 使用摄像头通过openCV进行人脸识别

2024-08-21 12:48

本文主要是介绍Qt 使用摄像头通过openCV进行人脸识别,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Qt 使用摄像头通过openCV进行人脸识别

  • 资源下载
  • 环境信息
  • 1. 下载cpenCV和opencv_contrib源码
  • 2. 安装CMake
  • 3. 编译openCV
    • 开始编译
  • 4. 新建工程调用openCV
  • 5. openCV中的基础人脸检测调用
  • 6. 人脸识别
    • 人脸库创建
    • 人脸识别
  • CMake过程可能会有的问题

资源下载

如果想快速开始使用,可以直接使用编译好的,可跳过本文的前3步,由于CSDN上传文件大小限制就分卷压缩上传了(解压保存的路径最好是英文,代码中会用到):

  • 不包含opencv_contrib编译的库:
    卷一:https://download.csdn.net/download/u012902367/11079135
    卷二:https://download.csdn.net/download/u012902367/11079147
    卷三:https://download.csdn.net/download/u012902367/11079153
    第四小节的demo工程:https://download.csdn.net/download/u012902367/11079205
  • 包含opencv_contrib编译的库:
    https://download.csdn.net/download/u012902367/11103882
  • 解决报错的文件(本文最后有提到)
    https://download.csdn.net/download/sunny_lc/9474246
    https://download.csdn.net/download/u012902367/11099517

环境信息

由于版本众多,各个版本之间编译过程可能有所区别,本文选择了一个历史版本(提醒一下不同版本使用方法会存在差异,如果读者想要按照下面的方式尝试,第一次建议选择和笔者同样的版本,成功以后再尝试新版本,还有就是本文所选择的路径在代码中会用到,如果读者怕麻烦修改,甚至可以把盘符和安装路径设置成与本文一致),如下是本文所用的环境参数:

  • 操作系统:win10
    在这里插入图片描述

  • mingw32-make
    在这里插入图片描述

  • CMake-3.14.1-win64-x64
    在这里插入图片描述

  • opencv_contrib-3.2.0
    在这里插入图片描述

  • opencv-3.2.0

1. 下载cpenCV和opencv_contrib源码

  • 从官网获取到安装程序:
    在这里插入图片描述在这里插入图片描述
    如果官网下载太慢可以选择再CSDN里面搜索下载:
    在这里插入图片描述

下载下来过后运行安装,请选择纯英文路径:
在这里插入图片描述
等待安装完成:
在这里插入图片描述

  • 也可以在git上获取,同时把opencv_contrib下载下来,注意:opencv和opencv_contrib两个版本一定要一致

在这里插入图片描述
把两个都下载下来,下面那一个包含了一些其它模块功能,比如常用的人脸识别。在这里插入图片描述
保存在纯英文路径,路径中最好也不要有特殊符号。

2. 安装CMake

官方下载CMake:https://cmake.org/download/
在这里插入图片描述
下载完后双击安装,安装到纯英文路径,安装完后把bin目录加入环境变量:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
环境变量配置:
在这里插入图片描述
顺便也将Qt的环境变量配置一下
在这里插入图片描述

3. 编译openCV

本文就具体描述包含opencv_contrib的编译,不想包含他只需要不添加他的路径就好了,其它的步骤完全一样。
为了cmake正常通过,先下载几个文件放到opencv_contrib的\modules\xfeatures2d\src目录,在CMake过程中也会下载,但是笔者尝试了很多遍都下载失败了,所以就事先把这几个文件都下载下来放到指定目录下就安全多了,当然如果不包含opencv_contrib就可以不要做这一步。需要添加的文件如下:
在这里插入图片描述
运行安装的CMake。选择路径:
在这里插入图片描述
注意: 若果是选择的使用exe安装的openCV,路径是选择的source。如果是通过git获取的会发现解压出来和exe安装的source下文件一样,选择到对应的目录即可:
在这里插入图片描述
在这里插入图片描述

如果是选择git下载解压下来的会发下解压出来的文件目录和exe安装的source文件加下目录几乎一样。

选择好后点击左下角Configure出现如下对话框,照图选择选择:
在这里插入图片描述
在这里插入图片描述
等待配置完成,过程可能需要等待几分钟,在配置的过程中需要下载一些文件,最好有vpn:
在这里插入图片描述
完成过后在列表中勾选 WITH_QT和 WITH_OPENGL(在靠后一点位置),并选择opencv_contrib的路径:
在这里插入图片描述
在这里插入图片描述
勾选过后再点击Configure等待运行完成,出现Configuring done,如果还有红色就再点一次Configure,直到界面没有红色框:
在这里插入图片描述
再点击Generate:
在这里插入图片描述
完成过后即可关闭此窗口。

开始编译

使用cmd到最开始自己新建的目录下执行mingw32-make
在这里插入图片描述

也可以目录下在按住shift点击鼠标右键:
在这里插入图片描述
在这个目录下执行mingw32-make
在这里插入图片描述
等待编译完成,根据电脑配置,过程可能需要15~30分钟:
在这里插入图片描述
继续执行mingw32-make install,并等待结束:
在这里插入图片描述
结束后把如下路径添加到环境变量(注意看这个路径位置):
在这里插入图片描述
在这里插入图片描述

4. 新建工程调用openCV

如果不想敲可以直接下载这个应用的工程源码。
新建一个应用:
在这里插入图片描述
在这里插入图片描述
.pro文件下添加如下代码,注意里面的路径需要换成读者自己安装的路径

INCLUDEPATH+=D:/openCV3_2/build/install/include/opencv \D:/openCV3_2/build/install/include/opencv2 \D:/openCV3_2/build/install/include
LIBS += -L D:/openCV3_2/build/install/x86/mingw/lib/libopencv_*.a

在这里插入图片描述
布局文件中就有两个QLabel,3个QPushButton,为了让读者看得清楚点把两个QLabel背景设置成了绿色,这个对使用没有一点影响,读者可以不用管这个颜色,其中对象的名字也写在图里面了:(camera,photo,open,take,close)
在这里插入图片描述
mainwindow.h代码

#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include <QDebug>
#include <QTimer>
#include <QImage>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/objdetect/objdetect.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/opencv.hpp>using namespace cv;
using namespace std;namespace Ui {
class MainWindow;
}class MainWindow : public QMainWindow
{Q_OBJECTpublic:explicit MainWindow(QWidget *parent = 0);~MainWindow();QImage  Mat2QImage(Mat cvImg);
private slots:void openCamara();      // 打开摄像头void readFarme();       // 读取当前帧信息void closeCamara();     // 关闭摄像头。void takingPictures();  // 拍照private:Ui::MainWindow *ui;QTimer          *timer;QImage          imag;Mat             cap,cap_gray,cap_tmp; //定义一个Mat变量,用于存储每一帧的图像VideoCapture    capture; //声明视频读入类
};#endif // MAINWINDOW_H

mainwindow.cpp代码

#include "mainwindow.h"
#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui->setupUi(this);timer   = new QTimer(this);connect(timer, SIGNAL(timeout()), this, SLOT(readFarme()));  // 时间到,读取当前摄像头信息connect(ui->open, SIGNAL(clicked()), this, SLOT(openCamara()));connect(ui->take, SIGNAL(clicked()), this, SLOT(takingPictures()));connect(ui->close, SIGNAL(clicked()), this, SLOT(closeCamara()));
}//打开摄像头
void MainWindow::openCamara()
{capture.open(0);    //从摄像头读入视频如果设备只有一个摄像头就传入参数0qDebug("open");if (!capture.isOpened()) //先判断是否打开摄像头{qDebug("err");}timer->start(20);              // 开始计时,20ms获取一帧
}//读取摄像头信息
void MainWindow::readFarme()
{capture>>cap; //读取当前帧if (!cap.empty()) //判断当前帧是否捕捉成功 **这步很重要{imag = Mat2QImage(cap);imag = imag.scaled(ui->camera->width(), ui->camera->height(),Qt::IgnoreAspectRatio, Qt::SmoothTransformation);//设置图片大小和label的长宽一致//imshow(name, cap); //若当前帧捕捉成功,显示ui->camera->setPixmap(QPixmap::fromImage(imag));  // 将图片显示到label上}elseqDebug("can not ");}// 拍照
void MainWindow::takingPictures()
{capture>>cap; //读取当前帧if (!cap.empty()) //判断当前帧是否捕捉成功 **这步很重要{imag = Mat2QImage(cap);imag = imag.scaled(ui->photo->width(), ui->photo->height(),Qt::IgnoreAspectRatio, Qt::SmoothTransformation);//设置图片大小和label的长宽一致//imshow(name, cap); //若当前帧捕捉成功,显示ui->photo->setPixmap(QPixmap::fromImage(imag));  // 将图片显示到label上}elseqDebug("can not ");
}//关闭摄像头,释放资源,必须释放***
void MainWindow::closeCamara()
{timer->stop();         // 停止读取数据。
}// 图片转换(网上抄的)
QImage  MainWindow::Mat2QImage(Mat cvImg)
{QImage qImg;if(cvImg.channels()==3)     //3 channels color image{cv::cvtColor(cvImg,cvImg,CV_BGR2RGB);qImg =QImage((const unsigned char*)(cvImg.data),cvImg.cols, cvImg.rows,cvImg.cols*cvImg.channels(),QImage::Format_RGB888);}else if(cvImg.channels()==1)                    //grayscale image{qImg =QImage((const unsigned char*)(cvImg.data),cvImg.cols,cvImg.rows,cvImg.cols*cvImg.channels(),QImage::Format_Indexed8);}else{qImg =QImage((const unsigned char*)(cvImg.data),cvImg.cols,cvImg.rows,cvImg.cols*cvImg.channels(),QImage::Format_RGB888);}return qImg;
}MainWindow::~MainWindow()
{delete ui;
}

需要把如下的文件全部拷贝到应用编译生成的.exe文件同级目录下,否则会编译出错:
在这里插入图片描述
在这里插入图片描述
到此就可以编译成功运行了,左边的是摄像头实时图像,右边是点击拍照后保存的图片:
在这里插入图片描述

5. openCV中的基础人脸检测调用

openCV资源里面有一些现成的.xml文件,就是用来检测人脸的,这些文件在本文最开始openCV的安装路径下就可以找到:
在这里插入图片描述
本文就测试两个就一个是眼睛检测,一个是人脸检测并用方框圈出来,是在上面的工程中修改的,只修改了如下两处:

  • 将如下代码放入到mainwindow.h中:
    CascadeClassifier eye_Classifier;  //载入分类器CascadeClassifier face_cascade;    //载入分类器//vector 是个类模板 需要提供明确的模板实参 vector<Rect>则是个确定的类 模板的实例化  需要指点std域名才可以用:using namespace std;vector<Rect> eyeRect;vector<Rect> faceRect;vector<Rect> faces;

在这里插入图片描述

  • 修改mainwindow.cppreadFarme()方法的内容为如下:
void MainWindow::readFarme()
{capture>>cap; //读取当前帧if (!cap.empty()) //判断当前帧是否捕捉成功 **这步很重要{cvtColor(cap, cap_gray, CV_BGR2GRAY);//转为灰度图equalizeHist(cap_gray, cap_gray);//直方图均衡化,增加对比度方便处理//加载分类训练器,OpenCv官方文档提供的xml文档,可以直接调用//xml文档路径,  opencv\sources\data\haarcascadesif (!eye_Classifier.load("D:\\opencvSet\\opencv\\sources\\data\\haarcascades\\haarcascade_eye.xml"))  //需要将xml文档放在自己指定的路径下{qDebug("Load haarcascade_eye.xml failed!");return;}if (!face_cascade.load("D:\\opencvSet\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_alt.xml")){qDebug("Load haarcascade_frontalface_alt failed!");return;}//检测关于眼睛部位位置eye_Classifier.detectMultiScale(cap_gray, eyeRect, 1.1, 2, 0 | CV_HAAR_SCALE_IMAGE, Size(30, 30));//检测for (size_t eyeIdx = 0; eyeIdx < eyeRect.size(); eyeIdx++){rectangle(cap, eyeRect[eyeIdx], Scalar(0, 0, 255));   //用红色矩形画出检测到的位置}//检测关于脸部位置face_cascade.detectMultiScale(cap_gray, faceRect, 1.1, 2, 0 | CV_HAAR_SCALE_IMAGE, Size(30, 30));//检测for (size_t i = 0; i < faceRect.size(); i++){rectangle(cap, faceRect[i], Scalar(0, 255, 0));      //用绿色矩形画出检测到的位置}imag = Mat2QImage(cap);     // 将Mat转换成QImage对象来显示imag = imag.scaled(ui->camera->width(), ui->camera->height(),Qt::IgnoreAspectRatio, Qt::SmoothTransformation);//设置图片大小和label的长宽一致//imshow(name, cap); //若当前帧捕捉成功,显示ui->camera->setPixmap(QPixmap::fromImage(imag));  // 将图片显示到label上}elseqDebug("can not ");
}

效果如下:
在这里插入图片描述
可以看出官方提供分类训练器也有一些误检测。

6. 人脸识别

分清两个概念:

  • 人脸检测:检测出画面中是否存在人脸。
  • 人脸识别:根据人脸特征识别出这个人具体是谁。

上一小节已经利用opencv现成的人脸模型实现了检测人脸,这一小节就描写一下如何利用opencv提供的平台实现人脸识别,这里得所谓的人脸识别实际就是从摄像头视频或者照片里面查找人脸,然后把查找到的人脸处理成指定大小,再与人脸库对比,获取到对比结果。

人脸库创建

为了提高识别率最好准备各个角度的面部照片(测试过jpg和pgm两种格式均可),就像下面一样,同一个人有10张不同角度的照片:
在这里插入图片描述

可以直接下载Database of Faces下来作为自己的参考人脸库:
在这里插入图片描述
下载完解压出来有如下目录:
在这里插入图片描述
共40个文件夹,每一个文件夹里面为同一个人的不同角度10张图片,是pgm格式的,windows的图片查看软件打不开,不过可以是使用opencv提供的方法来查看,代码的路径就是刚才下载下来的文件第一个人脸:

Mat img;
img = imread("C:/Users/XF/Desktop/orl_faces/s1/1.pgm", CV_LOAD_IMAGE_GRAYSCALE);
imshow("img", img);

在这里插入图片描述
准备我们自己需要的人脸照片处理跟下载下来为图片参数一致,人脸图为灰度图,大小为92*112,保存为第41个文件夹,如果自己需要添加几个人的面部信息就按照如此规律往后添加即可:
在这里插入图片描述
网上看的文章很多都会有一个类似如下的文本文件:
在这里插入图片描述
这个文件主要是给代码快速获取图片路径的,所说的标签也仅仅只是表示这张图片代表的是库里面的第几个人,所以这个文件不是必要的,本文就不用这个文件直接手动来获取,我想这样读者会更容易理解,
如下代码就是用来生成人脸库的, 当然这里只选了几个人的脸部照片,要把每一个都添加进去靠动手输入是很麻烦,这也就是为什么会有上面那个文本文档来保存路径和标签信息,通过读取文档里面的路径和标签信息可以快速准简单的实现如下功能,也是一劳永逸:

void MainWindow::on_pushButton_clicked()
{vector<Mat> images;Mat img;img = imread("C:/Users/XF/Desktop/orl_faces/s1/1.pgm", CV_LOAD_IMAGE_GRAYSCALE);images.push_back(img); // 将图片 添加到images中img = imread("C:/Users/XF/Desktop/orl_faces/s1/2.pgm", CV_LOAD_IMAGE_GRAYSCALE);images.push_back(img); // 将图片 添加到images中img = imread("C:/Users/XF/Desktop/orl_faces/s1/3.pgm", CV_LOAD_IMAGE_GRAYSCALE);images.push_back(img); // 将图片 添加到images中img = imread("C:/Users/XF/Desktop/orl_faces/s1/4.pgm", CV_LOAD_IMAGE_GRAYSCALE);images.push_back(img); // 将图片 添加到images中img = imread("C:/Users/XF/Desktop/orl_faces/s1/5.pgm", CV_LOAD_IMAGE_GRAYSCALE);images.push_back(img); // 将图片 添加到images中img = imread("C:/Users/XF/Desktop/orl_faces/s1/6.pgm", CV_LOAD_IMAGE_GRAYSCALE);images.push_back(img); // 将图片 添加到images中img = imread("C:/Users/XF/Desktop/orl_faces/s1/7.pgm", CV_LOAD_IMAGE_GRAYSCALE);images.push_back(img); // 将图片 添加到images中img = imread("C:/Users/XF/Desktop/orl_faces/s1/8.pgm", CV_LOAD_IMAGE_GRAYSCALE);images.push_back(img); // 将图片 添加到images中img = imread("C:/Users/XF/Desktop/orl_faces/s1/9.pgm", CV_LOAD_IMAGE_GRAYSCALE);images.push_back(img); // 将图片 添加到images中img = imread("C:/Users/XF/Desktop/orl_faces/s1/10.pgm", CV_LOAD_IMAGE_GRAYSCALE);images.push_back(img); // 将图片 添加到images中img = imread("C:/Users/XF/Desktop/orl_faces/s2/1.pgm", CV_LOAD_IMAGE_GRAYSCALE);images.push_back(img); // 将图片 添加到images中img = imread("C:/Users/XF/Desktop/orl_faces/s2/2.pgm", CV_LOAD_IMAGE_GRAYSCALE);images.push_back(img); // 将图片 添加到images中img = imread("C:/Users/XF/Desktop/orl_faces/s2/3.pgm", CV_LOAD_IMAGE_GRAYSCALE);images.push_back(img); // 将图片 添加到images中img = imread("C:/Users/XF/Desktop/orl_faces/s2/4.pgm", CV_LOAD_IMAGE_GRAYSCALE);images.push_back(img); // 将图片 添加到images中img = imread("C:/Users/XF/Desktop/orl_faces/s2/5.pgm", CV_LOAD_IMAGE_GRAYSCALE);images.push_back(img); // 将图片 添加到images中img = imread("C:/Users/XF/Desktop/orl_faces/s2/6.pgm", CV_LOAD_IMAGE_GRAYSCALE);images.push_back(img); // 将图片 添加到images中img = imread("C:/Users/XF/Desktop/orl_faces/s2/7.pgm", CV_LOAD_IMAGE_GRAYSCALE);images.push_back(img); // 将图片 添加到images中img = imread("C:/Users/XF/Desktop/orl_faces/s2/8.pgm", CV_LOAD_IMAGE_GRAYSCALE);images.push_back(img); // 将图片 添加到images中img = imread("C:/Users/XF/Desktop/orl_faces/s2/9.pgm", CV_LOAD_IMAGE_GRAYSCALE);images.push_back(img); // 将图片 添加到images中img = imread("C:/Users/XF/Desktop/orl_faces/s2/10.pgm", CV_LOAD_IMAGE_GRAYSCALE);images.push_back(img); // 将图片 添加到images中img = imread("C:/Users/XF/Desktop/orl_faces/s3/1.pgm", CV_LOAD_IMAGE_GRAYSCALE);images.push_back(img); // 将图片 添加到images中img = imread("C:/Users/XF/Desktop/orl_faces/s3/2.pgm", CV_LOAD_IMAGE_GRAYSCALE);images.push_back(img); // 将图片 添加到images中img = imread("C:/Users/XF/Desktop/orl_faces/s3/3.pgm", CV_LOAD_IMAGE_GRAYSCALE);images.push_back(img); // 将图片 添加到images中img = imread("C:/Users/XF/Desktop/orl_faces/s3/4.pgm", CV_LOAD_IMAGE_GRAYSCALE);images.push_back(img); // 将图片 添加到images中img = imread("C:/Users/XF/Desktop/orl_faces/s3/5.pgm", CV_LOAD_IMAGE_GRAYSCALE);images.push_back(img); // 将图片 添加到images中img = imread("C:/Users/XF/Desktop/orl_faces/s3/6.pgm", CV_LOAD_IMAGE_GRAYSCALE);images.push_back(img); // 将图片 添加到images中img = imread("C:/Users/XF/Desktop/orl_faces/s3/7.pgm", CV_LOAD_IMAGE_GRAYSCALE);images.push_back(img); // 将图片 添加到images中img = imread("C:/Users/XF/Desktop/orl_faces/s3/8.pgm", CV_LOAD_IMAGE_GRAYSCALE);images.push_back(img); // 将图片 添加到images中img = imread("C:/Users/XF/Desktop/orl_faces/s3/9.pgm", CV_LOAD_IMAGE_GRAYSCALE);images.push_back(img); // 将图片 添加到images中img = imread("C:/Users/XF/Desktop/orl_faces/s3/10.pgm", CV_LOAD_IMAGE_GRAYSCALE);images.push_back(img); // 将图片 添加到images中img = imread("C:/Users/XF/Desktop/face_jpg/1.jpg", CV_LOAD_IMAGE_GRAYSCALE);images.push_back(img); // 将图片 添加到images中img = imread("C:/Users/XF/Desktop/face_jpg/2.jpg", CV_LOAD_IMAGE_GRAYSCALE);images.push_back(img); // 将图片 添加到images中img = imread("C:/Users/XF/Desktop/face_jpg/3.jpg", CV_LOAD_IMAGE_GRAYSCALE);images.push_back(img); // 将图片 添加到images中img = imread("C:/Users/XF/Desktop/face_jpg/4.jpg", CV_LOAD_IMAGE_GRAYSCALE);images.push_back(img); // 将图片 添加到images中img = imread("C:/Users/XF/Desktop/face_jpg/5.jpg", CV_LOAD_IMAGE_GRAYSCALE);images.push_back(img); // 将图片 添加到images中img = imread("C:/Users/XF/Desktop/face_jpg/6.jpg", CV_LOAD_IMAGE_GRAYSCALE);images.push_back(img); // 将图片 添加到images中img = imread("C:/Users/XF/Desktop/face_jpg/7.jpg", CV_LOAD_IMAGE_GRAYSCALE);images.push_back(img); // 将图片 添加到images中img = imread("C:/Users/XF/Desktop/face_jpg/8.jpg", CV_LOAD_IMAGE_GRAYSCALE);images.push_back(img); // 将图片 添加到images中img = imread("C:/Users/XF/Desktop/face_jpg/9.jpg", CV_LOAD_IMAGE_GRAYSCALE);images.push_back(img); // 将图片 添加到images中img = imread("C:/Users/XF/Desktop/face_jpg/10.jpg", CV_LOAD_IMAGE_GRAYSCALE);images.push_back(img); // 将图片 添加到images中vector<int> labels;labels.push_back(0);labels.push_back(0);labels.push_back(0);labels.push_back(0);labels.push_back(0);labels.push_back(0);labels.push_back(0);labels.push_back(0);labels.push_back(0);labels.push_back(0);labels.push_back(1);labels.push_back(1);labels.push_back(1);labels.push_back(1);labels.push_back(1);labels.push_back(1);labels.push_back(1);labels.push_back(1);labels.push_back(1);labels.push_back(1);labels.push_back(2);labels.push_back(2);labels.push_back(2);labels.push_back(2);labels.push_back(2);labels.push_back(2);labels.push_back(2);labels.push_back(2);labels.push_back(2);labels.push_back(2);labels.push_back(3);labels.push_back(3);labels.push_back(3);labels.push_back(3);labels.push_back(3);labels.push_back(3);labels.push_back(3);labels.push_back(3);labels.push_back(3);labels.push_back(3);Ptr<FaceRecognizer> model = createEigenFaceRecognizer();model->train(images, labels);model->save("MyFacePCAModel.xml");
}

可以看得出上面是通过一个按钮来实现开始训练自己的人脸库,运行过后会在exe的上一级目录下多一个MyFacePCAModel.xml文件:
在这里插入图片描述

人脸识别

有了它就可以开始进行识别了,也就不再新建工程了,其它代码和上一小节的工程中代码一致,只是修改了readFarme()方法如下,里面有些路径需要修改成自己电脑中文件所在路径

//读取摄像头信息
void MainWindow::readFarme()
{capture>>cap; //读取当前帧if (!cap.empty()) //判断当前帧是否捕捉成功 **这步很重要{cvtColor(cap, cap_gray, CV_BGR2GRAY);   //转为灰度图equalizeHist(cap_gray, cap_gray);       //直方图均衡化,增加对比度方便处理if (!face_cascade.load("D:\\openCV3_2\\opencv-3.2.0\\data\\haarcascades\\haarcascade_frontalface_alt.xml")){qDebug("Load haarcascade_frontalface_alt failed!");return;}Ptr<FaceRecognizer> modelPCA = createEigenFaceRecognizer();modelPCA->load("E:\\workspace\\Qt_workspace\\build-face-Desktop_Qt_5_11_1_MinGW_32bit-Debug\\MyFacePCAModel.xml");//加载分类器if (!eye_Classifier.load("D:\\openCV3_2\\opencv-3.2.0\\data\\haarcascades\\haarcascade_eye.xml"))  //需要将xml文档放在自己指定的路径下{qDebug("Load haarcascade_eye.xml failed!");return;}//检测关于脸部位置face_cascade.detectMultiScale(cap_gray, faceRect, 1.1, 3, 0 | CV_HAAR_DO_ROUGH_SEARCH, Size(50, 50));//检测for (size_t i = 0; i < faceRect.size(); i++){rectangle(cap, faceRect[i], Scalar(0, 255, 0));      //用绿色矩形画出检测到的位置Mat faceROI = cap_gray(faceRect[i]);int predictPCA = 0;Mat face_test;Point text_lb;// 不加前面的cv::的话resize()方法会和MainWindow中的resize()冲突。cv::resize(faceROI,face_test,Size(92, 112));imshow("frame", face_test);//测试图像应该是灰度图predictPCA = modelPCA->predict(face_test);qDebug("%d",predictPCA);if(predictPCA==3)  // 这个3也就是上面labels.push_back(3);和图片是一一对应的{string name = "xufan";  // 文本提示text_lb = Point(faceRect[i].x, faceRect[i].y);putText(cap, name, text_lb, FONT_HERSHEY_COMPLEX, 1, Scalar(0, 0, 255));}//imshow("frame", faceROI);//检测关于眼睛部位位置int eye_num=0;eye_Classifier.detectMultiScale(faceROI, eyeRect, 1.1, 1, 0 | CV_HAAR_DO_ROUGH_SEARCH, Size(30, 30));//检测for (size_t j = 0; j < eyeRect.size(); j++){Rect rect(faceRect[i].x + eyeRect[j].x, faceRect[i].y + eyeRect[j].y, eyeRect[j].width, eyeRect[j].height);rectangle(cap, rect, Scalar(255, 0, 0));   //用蓝色矩形画出检测到的位置eye_num++;if(eye_num==2)break;}}imag = Mat2QImage(cap);     // 将Mat转换成QImage对象来显示imag = imag.scaled(ui->camera->width(), ui->camera->height(),Qt::IgnoreAspectRatio, Qt::SmoothTransformation);//设置图片大小和label的长宽一致ui->camera->setPixmap(QPixmap::fromImage(imag));  // 将图片显示到label上}elseqDebug("can not ");
}

运行过后就会出现就可以识别到视频中的人脸:
在这里插入图片描述

CMake过程可能会有的问题

CMake时会下载几个文件,下载失败会导致提示工程不可用,可直接手动从网上下载然后按照如下操作,添加到源文件中即可,如下所用到资源在本文最上面可以找到连接,添加文件如下:

  1. 将 opencv_ffmpeg.dll和opencv_ffmpeg_64.dll 复制到openCv资源的3rdparty\ffmpeg目录下
    在这里插入图片描述
  2. 将 ippicv_windows_20151201.zip 解压到:\3rdparty\ippicv\unpack 如果没有unpack文件夹,新建一个。形成这样的目录树: \3rdparty\ippicv\unpack\ippicv_win…,请仔细对比路径:
    在这里插入图片描述
  3. opencv_contrib里面的添加如下文件。
    在这里插入图片描述

这篇关于Qt 使用摄像头通过openCV进行人脸识别的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1093208

相关文章

中文分词jieba库的使用与实景应用(一)

知识星球:https://articles.zsxq.com/id_fxvgc803qmr2.html 目录 一.定义: 精确模式(默认模式): 全模式: 搜索引擎模式: paddle 模式(基于深度学习的分词模式): 二 自定义词典 三.文本解析   调整词出现的频率 四. 关键词提取 A. 基于TF-IDF算法的关键词提取 B. 基于TextRank算法的关键词提取

使用SecondaryNameNode恢复NameNode的数据

1)需求: NameNode进程挂了并且存储的数据也丢失了,如何恢复NameNode 此种方式恢复的数据可能存在小部分数据的丢失。 2)故障模拟 (1)kill -9 NameNode进程 [lytfly@hadoop102 current]$ kill -9 19886 (2)删除NameNode存储的数据(/opt/module/hadoop-3.1.4/data/tmp/dfs/na

Hadoop数据压缩使用介绍

一、压缩原则 (1)运算密集型的Job,少用压缩 (2)IO密集型的Job,多用压缩 二、压缩算法比较 三、压缩位置选择 四、压缩参数配置 1)为了支持多种压缩/解压缩算法,Hadoop引入了编码/解码器 2)要在Hadoop中启用压缩,可以配置如下参数

Makefile简明使用教程

文章目录 规则makefile文件的基本语法:加在命令前的特殊符号:.PHONY伪目标: Makefilev1 直观写法v2 加上中间过程v3 伪目标v4 变量 make 选项-f-n-C Make 是一种流行的构建工具,常用于将源代码转换成可执行文件或者其他形式的输出文件(如库文件、文档等)。Make 可以自动化地执行编译、链接等一系列操作。 规则 makefile文件

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

pdfmake生成pdf的使用

实际项目中有时会有根据填写的表单数据或者其他格式的数据,将数据自动填充到pdf文件中根据固定模板生成pdf文件的需求 文章目录 利用pdfmake生成pdf文件1.下载安装pdfmake第三方包2.封装生成pdf文件的共用配置3.生成pdf文件的文件模板内容4.调用方法生成pdf 利用pdfmake生成pdf文件 1.下载安装pdfmake第三方包 npm i pdfma

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

业务中14个需要进行A/B测试的时刻[信息图]

在本指南中,我们将全面了解有关 A/B测试 的所有内容。 我们将介绍不同类型的A/B测试,如何有效地规划和启动测试,如何评估测试是否成功,您应该关注哪些指标,多年来我们发现的常见错误等等。 什么是A/B测试? A/B测试(有时称为“分割测试”)是一种实验类型,其中您创建两种或多种内容变体——如登录页面、电子邮件或广告——并将它们显示给不同的受众群体,以查看哪一种效果最好。 本质上,A/B测