基于Opencv3和QT实现人脸识别 您所在的位置:网站首页 人脸识别正在升级是什么意思 基于Opencv3和QT实现人脸识别

基于Opencv3和QT实现人脸识别

2024-07-17 14:05| 来源: 网络整理| 查看: 265

前言:

    什么是OpenCV?可能还有人不清楚吧,简单地说,OpenCV——Open Source Computer Vision Library,即开源计算机视觉库,它是基于C语言和部分C++语言来开发,可用于计算机视觉、图像处理以及模式识别和跟踪。

  由于网上有很多Opencv源码编译的教程,这里我就直接拿编译好的Opencv在QT Create使用,首先先强调一下我使用的环境,针对的不同环境选择的版本也不同

我的电脑配置是Win10、qt-opensource-windows-x86-5.12.0,选择的opencv是64位的opencv3.4.4

一、Opencv的安装及使用  1、将编译好的Opecv库中的bin添加到环境变量中

  将opencv的bin目录找到 :D:\opencv64\x64\mingw\bin

【P.S以上内容根据安装的Opencv库的路径,自行修改】

点开电脑的属性——>高级系统变量——>环境变量——>系统变量的Path——>点击新建——>将bin的目录添加进去

记住一定要点击确定,完成后,建议重启电脑

2、在QT项目中配置OPencv

创建一个Qt桌面项目;

在.pro文件的底部添加

 在main.cpp的代码

如果图片正常显示出来,那么恭喜你,opencv库在QT配置成功

 二、利用Opencv实现人脸识别

Opecv在QT中配置成功,接下来我们就来实现人脸识别,人脸识别分三个步骤:1、图片采集和预处理   2、训练模型  3、将训练好的模型进行人脸识别

1、图片的采集和预处理

(1)下载数据集

    本次用的数据集是opencv给出的教程里面的第一个数据集:The AT&T Facedatabase。又称ORL人脸数据库,40个人,每人10张照片。照片在不同时间、不同光照、不同表情(睁眼闭眼、笑或者不笑)、不同人脸细节(戴眼镜或者不戴眼镜)下采集。所有的图像都在一个黑暗均匀的背景下采集的,正面竖直人脸(有些有有轻微旋转)。

下载下来的文件名是 att_faces  ,里面一共有40个文件夹,每个文件夹里面有10张图片。且每张图片都进行了预处理。

(2)采集自己的图片,对图片进行预处理

   想要识别自己,单有别人的数据集还是不行的,还需要自己人脸的照片才行。这就需要我们收采集自己的照片,对采集的照片进行预处理,然后和上面的那个数据集一起来训练模型

使用Opencv官方训练好的人脸检测分类器(haarcascade_frontalface_alt2.xml)对采集的图片进行预处理。这个人脸识别分类器的路径是:D:\opencv64\etc\haarcascades\haarcascade_frontalface_alt2.xml,将此文件拷贝到工程目录文件下。

源代码:

#include #include #include #include using namespace std; using namespace cv; int main() { CascadeClassifier cascada; //将opencv官方训练好的人脸识别分类器拷贝到自己的工程目录中 cascada.load("F:\\video\\pic\\haarcascade_frontalface_alt2.xml"); VideoCapture cap(0); //0表示电脑自带的,如果用一个外接摄像头,将0变成1 Mat frame, myFace; int pic_num = 1; while (1) { //摄像头读图像 cap >> frame; vector faces;//vector容器存检测到的faces Mat frame_gray; 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)); printf("检测到人脸个数:%d\n", faces.size()); //识别到的脸用矩形圈出 for (int i = 0; i < faces.size(); i++) { rectangle(frame, faces[i], Scalar(255, 0, 0), 2, 8, 0); } //当只有一个人脸时,开始拍照 if (faces.size() == 1) { Mat faceROI = frame_gray(faces[0]);//在灰度图中将圈出的脸所在区域裁剪出 //cout train(images, labels); model->save("MyFacePCAModel.xml");//保存路径可自己设置,但注意用“\\” Ptr model1 = face::FisherFaceRecognizer::create(); model1->train(images, labels); model1->save("MyFaceFisherModel.xml"); Ptr model2 = face::LBPHFaceRecognizer::create(); model2->train(images, labels); model2->save("MyFaceLBPHModel.xml");

训练模型的源代码 

每个函数的作用都写再代码上,大家只需要合并这三个函数即可成功训练模型

#include #include "face.hpp" //添加到工程目录的 #include #include #include #include #include #include using namespace std; using namespace cv; static Mat norm_0_255(InputArray _src) { Mat src = _src.getMat(); // 创建和返回一个归一化后的图像矩阵: Mat dst; switch (src.channels()) { case 1: cv::normalize(_src, dst, 0, 255, NORM_MINMAX, CV_8UC1); break; case 3: cv::normalize(_src, dst, 0, 255, NORM_MINMAX, CV_8UC3); break; default: src.copyTo(dst); break; } return dst; } //使用CSV文件去读图像和标签,主要使用stringstream和getline方法 static void read_csv(const string& filename, vector& images, vector& labels, char separator = ';') { ifstream file(filename.c_str(), ifstream::in); if (!file) { string error_message = "No valid input file was given, please check the given filename."; CV_Error(CV_StsBadArg, error_message); } string line, path, classlabel; while (getline(file, line)) //从文本文件中读取一行字符,未指定限定符默认限定符为“/n” { stringstream liness(line);//这里采用stringstream主要作用是做字符串的分割 getline(liness, path, separator);//读入图片文件路径以分好作为限定符 getline(liness, classlabel);//读入图片标签,默认限定符 if (!path.empty() && !classlabel.empty()) //如果读取成功,则将图片和对应标签压入对应容器中 { images.push_back(imread(path, 0)); labels.push_back(atoi(classlabel.c_str())); } } } int main() { //读取你的CSV文件路径. string fn_csv = "F:\\video\\ccc\\at.txt"; // 2个容器来存放图像数据和对应的标签 vector images; vector labels; // 读取数据. 如果文件不合法就会出错 // 输入的文件名已经有了. try { read_csv(fn_csv, images, labels); //从csv文件中批量读取训练数据 } catch (cv::Exception& e) { cerr predict(testSample, predictedLabel, confidence); string result_message = format("Predicted class = %d / Actual class = %d.", predictedLabel, testLabel); string result_message1 = format("Predicted class = %d / Actual class = %d.", predictedLabel1, testLabel); string result_message2 = format("Predicted class = %d / Actual class = %d.", predictedLabel2, testLabel); cout


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

      专题文章
        CopyRight 2018-2019 实验室设备网 版权所有