Opencv EigenFace人脸识别算法详解

简要:

EigenFace是基于PCA降维的人脸识别算法,PCA是使整体数据降维后的方差最大,没有考虑降维后类间的变化。 它是将图像每一个像素当作一维特征,然后用SVM或其它机器学习算法进行训练。但这样维数太多,根本无法计算。我这里用的是ORL人脸数据库,英国剑桥实验室拍摄的,有40位志愿者的人脸,在不同表情不同光照下每位志愿者拍摄10张,共有400张图片,大小为112*92,所以如果把每个像素当做特征拿来训练的话,一张人脸就有10304维特征,这么高维的数据根本无法处理。所以需要先对数据进行降维,去掉一些冗余的特征。

第一步:将ORL人脸图片的地址统一放在一个文件里,等会通过对该文件操作,将图片全部加载进来。

//ofstream一般对文件进行读写操作,ifstream一般对文件进行读操作
ofstream file;
 file.open("path.txt");//新建并打开文件
 char str[50] = {};
 for (int i = 1; i <= 40; i++) {
 for (int j = 1; j <= 10; j++) {
  sprintf_s(str, "orl_faces/s%d/%d.pgm;%d", i, j, i);//将数字转换成字符
  file << str << endl;//写入
 }
 }

得到路劲文件如下图所示:

 第二步:读入模型需要输入的数据,即用来训练的图像vector<Mat>images和标签vector<int>labels

string filename = string("path.txt");
 ifstream file(filename);
 if (!file) {
    printf("could not load file");
  }
 vector<Mat>images;
 vector<int>labels;
 char separator = ';';
 string line,path, classlabel;
 while (getline(file,line)) {
 stringstream lines(line);
 getline(lines, path, separator);
 getline(lines, classlabel);
 images.push_back(imread(path, 0));
 labels.push_back(atoi(classlabel.c_str()));//atoi(ASCLL to int)将字符串转换为整数型
 }

第三步:加载、训练、预测模型

Ptr<BasicFaceRecognizer> model = EigenFaceRecognizer::create();
 model->train(images, labels);
 int predictedLabel = model->predict(testSample);
 printf("actual label:%d,predict label :%d\n", testLabel, predictedLabel);

补充:

1、显示平均脸

//计算特征值特征向量及平均值
 Mat vals = model->getEigenValues();//89*1
 printf("%d,%d\n", vals.rows, vals.cols);
 Mat vecs = model->getEigenVectors();//10324*89
 printf("%d,%d\n", vecs.rows, vecs.cols);
 Mat mean = model->getMean();//1*10304
 printf("%d,%d\n", mean.rows, mean.cols);

 //显示平均脸
 Mat meanFace = mean.reshape(1, height);//第一个参数为通道数,第二个参数为多少行
 normalize(meanFace, meanFace, 0, 255, NORM_MINMAX, CV_8UC1);
 imshow("Mean Face", meanFace);

2、显示前部分特征脸

//显示特征脸
 for (int i = 0; i<min(10, vals.rows); i++) {
 Mat feature_vec = vecs.col(i).clone();
 Mat feature_face= feature_vec.reshape(1, height);
 normalize(feature_face, feature_face, 0, 255, NORM_MINMAX, CV_8UC1);
 Mat colorface;
 applyColorMap(feature_face, colorface, COLORMAP_BONE);

 sprintf_s(win_title, "eigenface%d", i);
 imshow(win_title, colorface);
 }

3、对第一张人脸在特征向量空间进行人脸重建(分别基于前10,20,30,40,50,60个特征向量进行人脸重建)

//重建人脸
 for (int i = min(10, vals.rows); i <min(61, vals.rows); i+=10) {
 Mat vecs_space = Mat(vecs, Range::all(), Range(0, i));
 Mat projection = LDA::subspaceProject(vecs_space, mean, images[0].reshape(1, 1));//投影到子空间
 Mat reconstruction = LDA::subspaceReconstruct(vecs_space, mean, projection);//重建
 Mat result = reconstruction.reshape(1, height);
 normalize(result, result, 0, 255, NORM_MINMAX, CV_8UC1);
 //char wintitle[40] = {};
 sprintf_s(win_title, "recon face %d", i);
 imshow(win_title, result);
 }

完整代码如下:

#include<opencv2\opencv.hpp>
#include<opencv2\face.hpp>
using namespace cv;
using namespace face;
using namespace std;
char win_title[40] = {};

int main(int arc, char** argv) {
 namedWindow("input",CV_WINDOW_AUTOSIZE);

 //读入模型需要输入的数据,用来训练的图像vector<Mat>images和标签vector<int>labels
 string filename = string("path.txt");
 ifstream file(filename);
 if (!file) { printf("could not load file"); }
 vector<Mat>images;
 vector<int>labels;
 char separator = ';';
 string line,path, classlabel;
 while (getline(file,line)) {
 stringstream lines(line);
 getline(lines, path, separator);
 getline(lines, classlabel);
 //printf("%d\n", atoi(classlabel.c_str()));
 images.push_back(imread(path, 0));
 labels.push_back(atoi(classlabel.c_str()));//atoi(ASCLL to int)将字符串转换为整数型
 }
 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();

 //加载,训练,预测
 Ptr<BasicFaceRecognizer> model = EigenFaceRecognizer::create();
 model->train(images, labels);
 int predictedLabel = model->predict(testSample);
 printf("actual label:%d,predict label :%d\n", testLabel, predictedLabel);

 //计算特征值特征向量及平均值
 Mat vals = model->getEigenValues();//89*1
 printf("%d,%d\n", vals.rows, vals.cols);
 Mat vecs = model->getEigenVectors();//10324*89
 printf("%d,%d\n", vecs.rows, vecs.cols);
 Mat mean = model->getMean();//1*10304
 printf("%d,%d\n", mean.rows, mean.cols);

 //显示平均脸
 Mat meanFace = mean.reshape(1, height);//第一个参数为通道数,第二个参数为多少行
 normalize(meanFace, meanFace, 0, 255, NORM_MINMAX, CV_8UC1);
 imshow("Mean Face", meanFace);

 //显示特征脸
 for (int i = 0; i<min(10, vals.rows); i++) {
 Mat feature_vec = vecs.col(i).clone();
 Mat feature_face= feature_vec.reshape(1, height);
 normalize(feature_face, feature_face, 0, 255, NORM_MINMAX, CV_8UC1);
 Mat colorface;
 applyColorMap(feature_face, colorface, COLORMAP_BONE);

 sprintf_s(win_title, "eigenface%d", i);
 imshow(win_title, colorface);
 }

 //重建人脸
 for (int i = min(10, vals.rows); i <min(61, vals.rows); i+=10) {
 Mat vecs_space = Mat(vecs, Range::all(), Range(0, i));
 Mat projection = LDA::subspaceProject(vecs_space, mean, images[0].reshape(1, 1));
 Mat reconstruction = LDA::subspaceReconstruct(vecs_space, mean, projection);
 Mat result = reconstruction.reshape(1, height);
 normalize(result, result, 0, 255, NORM_MINMAX, CV_8UC1);
 //char wintitle[40] = {};
 sprintf_s(win_title, "recon face %d", i);
 imshow(win_title, result);
 }

 waitKey(0);
 return 0;
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • opencv 做人脸识别 opencv 人脸匹配分析

    机器学习 机器学习的目的是把数据转换成信息. 机器学习通过从数据里提取规则或模式来把数据转成信息. 人脸识别 人脸识别通过级联分类器对特征的分级筛选来确定是否是人脸. 每个节点的正确识别率很高,但正确拒绝率很低. 任一节点判断没有人脸特征则结束运算,宣布不是人脸. 全部节点通过,则宣布是人脸. 工业上,常用人脸识别技术来识别物体. 对图片进行识别 复制代码 代码如下: #include "opencv2/core/core.hpp" #include "opencv2/obj

  • OpenCV实现人脸识别

    主要有以下步骤: 1.人脸检测 2.人脸预处理 3.从收集的人脸训练机器学习算法 4.人脸识别 5.收尾工作 人脸检测算法: 基于Haar的脸部检测器的基本思想是,对于面部正面大部分区域而言,会有眼睛所在区域应该比前额和脸颊更暗,嘴巴应该比脸颊更暗等情形.它通常执行大约20个这样的比较来决定所检测的对象是否为人脸,实际上经常会做上千次. 基于LBP的人脸检测器基本思想与基于Haar的人脸检测器类似,但它比较的是像素亮度直方图,例如,边缘.角落和平坦区域的直方图. 这两种人脸检测器可通过训练大的图

  • OPENCV+JAVA实现人脸识别

    本文实例为大家分享了JAVA实现人脸识别的具体代码,供大家参考,具体内容如下 官方下载 安装文件 ,以win7为例,下载opencv-2.4.13.3-vc14.exe 安装后,在build目录下 D:\opencv\build\java,获取opencv-2413.jar,copy至项目目录 同时需要dll文件 与 各 识别xml文件,进行不同特征的识别(人脸,侧脸,眼睛等) dll目录:D:\opencv\build\java\x64\opencv_java2413.dll xml目录:D:

  • 基于OpenCV的PHP图像人脸识别技术

    openCV是一个开源的用C/C++开发的计算机图形图像库,非常强大,研究资料很齐全.本文重点是介绍如何使用php来调用其中的局部的功能.人脸侦查技术只是openCV一个应用分支. 1.安装 从源代码编译成一个动态的so文件. 1.1.安装 OpenCV (OpenCV 1.0.0) 下载地址:http://sourceforge.net/project/showfiles.php?group_id=22870&package_id=16948 #tar xvzf OpenCV-1.0.0.ta

  • Opencv LBPH人脸识别算法详解

    简要:  LBPH(Local Binary PatternsHistograms)局部二进制编码直方图,建立在LBPH基础之上的人脸识别法基本思想如下:首先以每个像素为中心,判断与周围像素灰度值大小关系,对其进行二进制编码,从而获得整幅图像的LBP编码图像:再将LBP图像分为个区域,获取每个区域的LBP编码直方图,继而得到整幅图像的LBP编码直方图,通过比较不同人脸图像LBP编码直方图达到人脸识别的目的,其优点是不会受到光照.缩放.旋转和平移的影响. #include<opencv2\open

  • 详解如何用OpenCV + Python 实现人脸识别

    下午的时候,配好了OpenCV的Python环境,OpenCV的Python环境搭建.于是迫不及待的想体验一下opencv的人脸识别,如下文. 必备知识 Haar-like 通俗的来讲,就是作为人脸特征即可. Haar特征值反映了图像的灰度变化情况.例如:脸部的一些特征能由矩形特征简单的描述,如:眼睛要比脸颊颜色要深,鼻梁两侧比鼻梁颜色要深,嘴巴比周围颜色要深等. opencv api 要想使用opencv,就必须先知道其能干什么,怎么做.于是API的重要性便体现出来了.就本例而言,使用到的函数

  • Opencv EigenFace人脸识别算法详解

    简要: EigenFace是基于PCA降维的人脸识别算法,PCA是使整体数据降维后的方差最大,没有考虑降维后类间的变化. 它是将图像每一个像素当作一维特征,然后用SVM或其它机器学习算法进行训练.但这样维数太多,根本无法计算.我这里用的是ORL人脸数据库,英国剑桥实验室拍摄的,有40位志愿者的人脸,在不同表情不同光照下每位志愿者拍摄10张,共有400张图片,大小为112*92,所以如果把每个像素当做特征拿来训练的话,一张人脸就有10304维特征,这么高维的数据根本无法处理.所以需要先对数据进行降

  • Java OpenCV实现人脸识别过程详解

    准备 : 下载openCV安装包 :  https://opencv.org/ 安装包安装之后支持多种语言环境,此处使用Java,在Eclipse中引入 openCV目录下的java/opencv-320.jar,同时配置openCV库路径. Eclipse配置openCV 代码实现 : package test; import org.opencv.core.Core; import org.opencv.core.Mat; import org.opencv.core.MatOfRect;

  • python计算机视觉opencv卡号识别示例详解

    目录 一.模板预处理 1.将模板设置为二值图 2.检测模板的轮廓 3.对模板轮廓排序,并将数字和轮廓一一对应,以字典存储 4.备注 二.图片预处理 1.初始化卷积核 2.图片预处理第一部分 3.图像预处理第二部分 三.轮廓处理 1.大轮廓过滤 2.小轮廓分割 模板图片如下: 需识别的图片如下: 一.模板预处理 1.将模板设置为二值图 2.检测模板的轮廓 3.对模板轮廓排序,并将数字和轮廓一一对应,以字典存储 排序的函数如下: 排序并存储: 4.备注 ①每一个数字对应的是二值图截出来的那个数字图的

  • C++ OpenCV实现图像双三次插值算法详解

    目录 前言 一.图像双三次插值算法原理 二.C++ OpenCV代码 1.计算权重矩阵 2.遍历插值 3. 测试及结果 前言 近期在学习一些传统的图像处理算法,比如传统的图像插值算法等.传统的图像插值算法包括邻近插值法.双线性插值法和双三次插值法,其中邻近插值法和双线性插值法在网上都有很详细的介绍以及用c++编写的代码.但是,网上关于双三次插值法的原理介绍虽然很多,也有对应的代码,但是大多都不是很详细.因此基于自己对原理的理解,自己编写了图像双三次插值算法的c++ opencv代码,在这里记录一

  • Python基于OpenCV库Adaboost实现人脸识别功能详解

    本文实例讲述了Python基于OpenCV库Adaboost实现人脸识别功能.分享给大家供大家参考,具体如下: 以前用Matlab写神经网络的面部眼镜识别算法,研究算法逻辑,采集大量训练数据,迭代,计算各感知器的系数...相当之麻烦~而现在运用调用pythonOpenCV库Adaboost算法,无需知道算法逻辑,无需进行模型训练,人脸识别变得相当之简单了. 需要用到的库是opencv(open source computer vision),下载安装方式如下: 使用pip install num

  • Python基于Opencv来快速实现人脸识别过程详解(完整版)

    前言 随着人工智能的日益火热,计算机视觉领域发展迅速,尤其在人脸识别或物体检测方向更为广泛,今天就为大家带来最基础的人脸识别基础,从一个个函数开始走进这个奥妙的世界. 首先看一下本实验需要的数据集,为了简便我们只进行两个人的识别,选取了beyond乐队的主唱黄家驹和贝斯手黄家强,这哥俩长得有几分神似,这也是对人脸识别的一个考验: 两个文件夹,一个为训练数据集,一个为测试数据集,训练数据集中有两个文件夹0和1,之前看一些资料有说这里要遵循"slabel"命名规则,但后面处理起来比较麻烦,

  • python Opencv实现停车位识别思路详解

    目录 1.实现的思路 2.整体代码实战 3.停车位视频下载 1.实现的思路 (1)首先使用一个处理画框的程序,将图片中的有车和无车的停车位给画出来,并且保存坐标(如果画错了,将鼠标移至要删除的框中,右击鼠标,即可删除): #定义回调函数 def mouseClick(events,x,y,flags,params): #按下鼠标左键,将点击的坐标(x,y)保存到position列表中 if (events&cv2.EVENT_LBUTTONDOWN==cv2.EVENT_LBUTTONDOWN)

  • OpenCV图像颜色反转算法详解

    前言 图像颜色的反转,比较简单的思路就是使用255减去当前值,从而得到反转后的图像.原始图片: 1.灰度图像的颜色反转 import cv2 import numpy as np # 灰度 0-255 255-当前灰度值 img = cv2.imread('image0.jpg', 1) imgInfo = img.shape height = imgInfo[0] width = imgInfo[1] gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) d

  • Opencv创建车牌图片识别系统方法详解

    目录 前言 包含功能 软件版本 软件架构 参考文档 效果图展示 车牌检测过程 图片车牌文字识别过程 部分核心代码 前言 这是一个基于spring boot + maven + opencv 实现的图像识别及训练的Demo项目 包含车牌识别.人脸识别等功能,贯穿样本处理.模型训练.图像处理.对象检测.对象识别等技术点 java语言的深度学习项目,在整个开源社区来说都相对较少: 拥有完整的训练过程.检测.识别过程的开源项目更是少之又少!! 包含功能 蓝.绿.黄车牌检测及车牌号码识别 网上常见的轮廓提

随机推荐