基于opencv人脸识别

基于opencv人脸识别一、准备所有代码上传至https://pan.baidu.com/s/1ETUetRnU83iytb6ZcE5GUQ提取码:0jei环境:win10,vs2013,opencv3.2注:每个代码都可以在vs中单独运行该项目所有文件如下:其中只需要使用的文件如下:详细代码://这个是生成照片的代码#include<opencv2…

大家好,又见面了,我是你们的朋友全栈君。

一、准备

链接:代码+数据集
提取码:led1 

环境:win10,vs2013,opencv3.2

注:每个代码都可以在vs中单独运行

该项目所有文件如下:

基于opencv人脸识别

其中只需要使用的文件如下:

基于opencv人脸识别

详细代码:

//这个是生成照片的代码
#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

//cv库,哈尔检测人脸使用的配置文件
string haar_face_datapath = "E:/opencv/install/etc/haarcascades/haarcascade_frontalface_alt_tree.xml";


int main(int argc, char** argv) {
	//打开摄像头
	VideoCapture capture(0); 
	if (!capture.isOpened()) {
		printf("could not open camera...\n");
		return -1;
	}
	Size S = Size((int)capture.get(CV_CAP_PROP_FRAME_WIDTH), (int)capture.get(CV_CAP_PROP_FRAME_HEIGHT));
	int fps = capture.get(CV_CAP_PROP_FPS);

	//人脸检测库
	CascadeClassifier faceDetector;
	//人脸检测函数
	faceDetector.load(haar_face_datapath);


	Mat frame;
	namedWindow("camera-demo", CV_WINDOW_AUTOSIZE);
	vector<Rect> faces;
	int count = 0;
	while (capture.read(frame)) {
		flip(frame, frame, 1);
		faceDetector.detectMultiScale(frame, faces, 1.1, 1, 0, Size(100, 120), Size(380, 400));
		for (int i = 0; i < faces.size(); i++) {
			if (count % 10 == 0) {
				Mat dst;
				//重新把照片大小改成模板的大小
				resize(frame(faces[i]), dst, Size(112, 92));
				//保存照片
				imwrite(format("D:/else//led/face_%d.jpg", count), dst);
			}
			rectangle(frame, faces[i], Scalar(0, 0, 255), 2, 8, 0);
		}
		imshow("camera-demo", frame);
		char c = waitKey(10);
		//按键退出截图
		if (c == 27) {
			break;
		}
		count++;
	}

	capture.release();

	waitKey(0);
	return 0;
}
//这个是生成csv文件的教程,直接用shell命令,不需要写代码


1. 打开cmd


2. 输入 F: (因为我的文件在F盘)  注意一定要先进入F盘才可以后续操作,不然会显示找不到文件


3. 输入cd 文件路径,点回车


4. 输入dir /b/s/p/w *.jpg>at.csv 注意,我的文件格式为.jpg
#include <opencv2/opencv.hpp>
#include <opencv2/face.hpp>
#include <iostream>

using namespace cv;
using namespace cv::face;
using namespace std;

int main(int argc, char** argv) {
	
	//加载自己的csv文件
	string filename = string("D:/else/wyz/at.csv");
	ifstream file(filename.c_str(), ifstream::in);
	if (!file) {
		printf("could not load file correctly...\n");
		return -1;
	}

	string line, path, classlabel;
	vector<Mat> images;
	vector<int> labels;
	char separator = ';';
	while (getline(file, line)) {
		stringstream liness(line);
		getline(liness, path, separator);
		getline(liness, classlabel);
		if (!path.empty() && !classlabel.empty()) {
			//printf("path : %s\n", path.c_str());
			images.push_back(imread(path, 0));
			labels.push_back(atoi(classlabel.c_str()));
		}
	}

	if (images.size() < 1 || labels.size() < 1) {
		printf("invalid image path...\n");
		return -1;
	}

	int height = images[0].rows;
	int width = images[0].cols;
	printf("height : %d, width : %d\n", height, width);

	Mat testSample = images[images.size() - 1];
	int testLabel = labels[labels.size() - 1];
	images.pop_back();
	labels.pop_back();

	// train it,训练自己的模型,到这里已经完成训练操作
	Ptr<BasicFaceRecognizer> model = createEigenFaceRecognizer();
	model->train(images, labels);
	model->save("D:/else/wyz/led_wyz.xml");


	/* 以下两个方法训练模型同样操作
	Ptr<FaceRecognizer> model1 = createFisherFaceRecognizer();
	model1->train(images, labels);
	model1->save("MyFaceFisherModel.xml");

	Ptr<FaceRecognizer> model2 = createLBPHFaceRecognizer();
	model2->train(images, labels);
	model2->save("MyFaceLBPHModel.xml");
	*/



	/* 以下内容用于检测验证自己重建的人脸模,可以直接跳过,本代码全部注释掉了
	// recognition face
	int predictedLabel = model->predict(testSample);
	printf("actual label : %d, predict label :  %d\n", testLabel, predictedLabel);

	Mat eigenvalues = model->getEigenValues();
	Mat W = model->getEigenVectors();
	Mat mean = model->getMean();
	Mat meanFace = mean.reshape(1, height);
	Mat dst;
	if (meanFace.channels() == 1) {
		normalize(meanFace, dst, 0, 255, NORM_MINMAX, CV_8UC1);
	}
	else if (meanFace.channels() == 3) {
		normalize(meanFace, dst, 0, 255, NORM_MINMAX, CV_8UC3);
	}
	imshow("Mean Face", dst);



	// show eigen faces
	for (int i = 0; i < min(25, W.cols); i++) {
		Mat ev = W.col(i).clone();
		Mat grayscale;
		Mat eigenFace = ev.reshape(1, height);
		if (eigenFace.channels() == 1) {
			normalize(eigenFace, grayscale, 0, 255, NORM_MINMAX, CV_8UC1);
		}
		else if (eigenFace.channels() == 3) {
			normalize(eigenFace, grayscale, 0, 255, NORM_MINMAX, CV_8UC3);
		}
		Mat colorface;
		applyColorMap(grayscale, colorface, COLORMAP_JET);
		char* winTitle = new char[128];
		sprintf(winTitle, "eigenface_%d", i);
		imshow(winTitle, colorface);
	}


	// 重建人脸
	for (int num = min(25, W.cols); num < min(W.cols, 300); num += 1) {
		Mat evs = Mat(W, Range::all(), Range(0, num));
		Mat projection = LDA::subspaceProject(evs, mean, images[0].reshape(1, 1));
		Mat reconstruction = LDA::subspaceReconstruct(evs, mean, projection);

		Mat result = reconstruction.reshape(1, height);
		if (result.channels() == 1) {
			normalize(result, reconstruction, 0, 255, NORM_MINMAX, CV_8UC1);
		}
		else if (result.channels() == 3) {
			normalize(result, reconstruction, 0, 255, NORM_MINMAX, CV_8UC3);
		}
		char* winTitle = new char[128];
		sprintf(winTitle, "recon_face_%d", num);
		imshow(winTitle, reconstruction);
	}
	*/

	waitKey(0);
	return 0;
}

二、原理

原理1.PCA(主成分分析)原理

通过对高维数据分析发现他们的相同与不同表达为 一个低维数据模式

主成分不变 

细微损失 

高维数据到低维数据

原理2.API调用

主要是使用其中的三个函数,来训练自己的数据,函数如下:

// train it
	Ptr<BasicFaceRecognizer> model = createEigenFaceRecognizer();
	model->train(images, labels);
	model->save("D:/else/wyz/led_wyz.xml");
	
	Ptr<FaceRecognizer> model1 = createFisherFaceRecognizer();
	model1->train(images, labels);
	model1->save("MyFaceFisherModel.xml");

	Ptr<FaceRecognizer> model2 = createLBPHFaceRecognizer();
	model2->train(images, labels);
	model2->save("MyFaceLBPHModel.xml");
	

三、步骤

1. 算法实现步骤

  1. 数据:ORL  att_faces   OpenCV的数据 10个人、每人10张照片
  2. 一个图像N宽*N高*N个  112*92*100个矩阵
  3. 平均脸 矩阵计算得到均值
  4. 特征脸 矩阵计算得到特征值
  5. 开始、读训练数据、计算平均脸、计算协方差矩阵、计算特征值、特征矩阵、 PAC降维、子空间模型、检测
  6. 生成CSV文件
  7. 生成自己的xml
  8. 训练
  9. 识别
  10.  识别率
  11.  结果分析

四、结果

结果1.方差均值作用

图像RGB矩阵

空白背景方差不为0,均值为0

基于opencv人脸识别

基于opencv人脸识别

基于opencv人脸识别

结果2.PCA应用

  1. 灰度图像
  2. 描边,画出边缘

    基于opencv人脸识别

  1. XY表示所有轮廓,N*X*Y
  2. PCA处理,得到协方差矩阵,得到特征值特征向量

             N行2列表示所有的点

             得到轮廓中心位置

基于opencv人脸识别

             Eigen得到特征值

基于opencv人脸识别

结果3..Eigenface算法

  1. 数据:ORL  att_faces   OpenCV的数据 10个人、每人10张照片

      基于opencv人脸识别

      平均脸

      基于opencv人脸识别

      2. 一个图像N宽*N高*N个  112*92*100个矩阵

      3.平均脸 矩阵计算得到均值

      4.特征脸 矩阵计算得到特征值

      5.开始、读训练数据、计算平均脸、计算协方差矩阵、计算特征值、特征矩阵、 PAC降维、子空间模型、检测

      6.生成CSV文件

      7.生成自己的xml

       基于opencv人脸识别

     8.训练

     9.识别

       基于opencv人脸识别

    10. 识别率:

         基于opencv人脸识别

         基于opencv人脸识别

     11. 侧脸影响

        基于opencv人脸识别

     12.暗光条件下,找不到人脸,识别率也降低

        基于opencv人脸识别

结果4.Fisher算法

  1. 由fisher发现,于是命名FisherFace
  2. 基于LDA降维,求两个对象之间的内差和外差,得到离散矩阵,求特征值特 征向量
  3. FishFace识别在光照上有所进步,光的明暗影响不是很大

        基于opencv人脸识别

     4.识别率问题,因为这里光亮作为主要因素,光亮无法做到细微控制,这里不做详细比较

       基于opencv人脸识别

     5.人脸上半部分处在黑暗环境,与EigenFace比较,差不多同一张图片,这张图能识别出来

      基于opencv人脸识别

结果5.LBPH算法

此算法和前两种的比较,主要是在光照和侧脸角度上有所加强,这里不再多做比较。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/135733.html原文链接:https://javaforall.net

赞 (0)
全栈程序员-站长的头像全栈程序员-站长

相关推荐

  • label标签的用法「建议收藏」

    label标签的用法「建议收藏」label标签for属性

    2022年8月2日
  • pycharm快捷键和常规设置[通俗易懂]

    pycharm快捷键和常规设置[通俗易懂]记录下我常用的pycharm快捷键和设置(Windows10)1、更换背景:文件—设置—-外观与行为—外观—背景图像本来是没想到设置背景图像的。脑子一抽换了一个,感觉发现了新大陆。(程序员鼓励师)2、列模式Alt+Shift+鼠标左键可以批量选中并修改3、Ctrl+E打开最近文件。多用于打开了多个文件时快速定位。也可以在tab标签里找,不过tab打开多了就会挤压之前标签,看起来特别费劲。4、Ctrl+B快速定位变量在哪定义的快速定位函数定义代码5、Shift+Enter

    2022年8月27日
  • spring boot 系列之六:深入理解spring boot的自动配置[通俗易懂]

    我们知道,springboot自动配置功能可以根据不同情况来决定spring配置应该用哪个,不应该用哪个,举个例子:Spring的JdbcTemplate是不是在Classpath里面?如果是,并

    2022年2月16日
  • Python基本数据类型有哪些

    Python基本数据类型有哪些1.基本数据类型1.数字类型:整型(int),浮点型(float),复数类型(complex)2.字符串类型:str3.逻辑类型:boolTrueFalse4.列表类型:list[]有序可修改5.元组类型:tuple()有序不可修改6.集合类型:set{}无序不重复7.字典类型:dict{key:value}无序2.整形中的四种进制…

    2022年5月24日
  • h5页面 请在微信客户端打开链接_电脑版微信网页授权提示请在微信客户端打开链接?…

    h5页面 请在微信客户端打开链接_电脑版微信网页授权提示请在微信客户端打开链接?…访问以下链接会跳转到公众号授权,手机版微信可以正常访问,mac版微信也可以正常,在window版微信上会跳转到白屏页面查看页面源代码,里面显示”请在微信客户端打开链接“WECHAT_EMPTY_TITLE::-webkit-scrollbar{width:12px!important;height:12px!important;}::-webkit-scrollbar-track:…

    2022年6月7日
  • VUE组件封装_vue使用组件

    VUE组件封装_vue使用组件什么是组件化:组件化就是将一个页面拆分成一个个小的功能模块,每个功能模块完成属于自己这部分独立的功能,使得整个页面的管理和维护变得非常容易。Vue组件化思想 组件化是Vue中的重要思想,当我们对vue的基本知识有了一定的基础就要开始封装组件了 它提供了一种抽象,让我们可以开发出一个个独立可复用的小组件来构造我们的应用。组件树。组件化思想的应用 1.在项目中充分利用组件化的思想 2.尽可能的将也页面拆分成一个个小的可复用的组件 3.好处:代码更加方便组织和管理,扩展性也更强一.注

    2022年9月23日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号