从OpenCV2.4开始,加入了新的类FaceRecognizer,我们可以使用它便捷地进行人脸识别实验。本文既介绍代码使用,又介绍算法原理。(他写的源代码,我们可以在OpenCV的opencv\modules\contrib\doc\facerec\src下找到,当然也可以在他的github中找到,如果你想研究源码,自然可以去看看,不复杂)
目前支持的算法有
Eigenfaces特征脸createEigenFaceRecognizer()
Fisherfaces createFisherFaceRecognizer()
LocalBinary Patterns Histograms局部二值直方图 createLBPHFaceRecognizer()
下面所有的例子中的代码在OpenCV安装目录下的samples/cpp下面都能找到,所有的代码商用或者学习都是免费的。
1.2.人脸识别Face Recognition
对人类来说,人脸识别很容易。文献[Tu06]告诉我们,仅仅是才三天的婴儿已经可以区分周围熟悉的人脸了。那么对于计算机来说,到底有多难?其实,迄今为止,我们对于人类自己为何可以区分不同的人所知甚少。是人脸内部特征(眼睛、鼻子、嘴巴)还是外部特征(头型、发际线)对于人类识别更有效?我们怎么分析一张图像,大脑是如何对它编码的?David Hubel和TorstenWiesel向我们展示,我们的大脑针对不同的场景,如线、边、角或者运动这些局部特征有专门的神经细胞作出反应。显然我们没有把世界看成零散的块块,我们的视觉皮层必须以某种方式把不同的信息来源转化成有用的模式。自动人脸识别就是如何从一幅图像中提取有意义的特征,把它们放入一种有用的表示方式,然后对他们进行一些分类。基于几何特征的人脸的人脸识别可能是最直观的方法来识别人脸。第一个自动人脸识别系统在[Kanade73]中又描述:标记点(眼睛、耳朵、鼻子等的位置)用来构造一个特征向量(点与点之间的距离、角度等)。通过计算测试和训练图像的特征向量的欧氏距离来进行识别。这样的方法对于光照变化很稳健,但也有巨大的缺点:标记点的确定是很复杂的,即使是使用最先进的算法。一些几何特征人脸识别近期工作在文献[Bru92]中有描述。一个22维的特征向量被用在一个大数据库上,单靠几何特征不能提供足够的信息用于人脸识别。
特征脸方法在文献[TP91]中有描述,他描述了一个全面的方法来识别人脸:面部图像是一个点,这个点是从高维图像空间找到它在低维空间的表示,这样分类变得很简单。低维子空间低维是使用主元分析(Principal Component Analysis,PCA)找到的,它可以找拥有最大方差的那个轴。虽然这样的转换是从最佳重建角度考虑的,但是他没有把标签问题考虑进去。[gm:读懂这段需要一些机器学习知识]。想象一个情况,如果变化是基于外部来源,比如光照。轴的最大方差不一定包含任何有鉴别性的信息,因此此时的分类是不可能的。因此,一个使用线性鉴别(Linear Discriminant Analysis,LDA)的特定类投影方法被提出来解决人脸识别问题[BHK97]。其中一个基本的想法就是,使类内方差最小的同时,使类外方差最大。
近年来,各种局部特征提取方法出现。为了避免输入的图像的高维数据,仅仅使用的局部特征描述图像的方法被提出,提取的特征(很有希望的)对于局部遮挡、光照变化、小样本等情况更强健。有关局部特征提取的方法有盖伯小波(Gabor Waelets)([Wiskott97]),离散傅立叶变换(DiscreteCosinus Transform,DCT)([Messer06]),局部二值模式(LocalBinary Patterns,LBP)([AHP04])。使用什么方法来提取时域空间的局部特征依旧是一个开放性的研究问题,因为空间信息是潜在有用的信息。
1.3.人脸库Face Database
我们先获取一些数据来进行实验吧。我不想在这里做一个幼稚的例子。我们在研究人脸识别,所以我们需要一个真的人脸图像!你可以自己创建自己的数据集,也可以从这里(http://face-rec.org/databases/)下载一个。
AT&TFacedatabase又称ORL人脸数据库,40个人,每人10张照片。照片在不同时间、不同光照、不同表情(睁眼闭眼、笑或者不笑)、不同人脸细节(戴眼镜或者不戴眼镜)下采集。所有的图像都在一个黑暗均匀的背景下采集的,正面竖直人脸(有些有有轻微旋转)。
YaleFacedatabase A ORL数据库对于初始化测试比较适合,但它是一个简单的数据库,特征脸已经可以达到97%的识别率,所以你使用其他方法很难得到更好的提升。Yale人脸数据库是一个对于初始实验更好的数据库,因为识别问题更复杂。这个数据库包括15个人(14个男人,1个女人),每一个都有11个灰度图像,大小是320*243像素。数据库中有光照变化(中心光照、左侧光照、右侧光照)、表情变化(开心、正常、悲伤、瞌睡、惊讶、眨眼)、眼镜(戴眼镜或者没戴)。
坏消息是它不可以公开下载,可能因为原来的服务器坏了。但我们可以找到一些镜像(比如 theMIT)但我不能保证它的完整性。如果你需要自己剪裁和校准图像,可以阅读我的笔记(bytefish.de/blog/fisherfaces)。
ExtendedYale Facedatabase B 此数据库包含38个人的2414张图片,并且是剪裁好的。这个数据库重点是测试特征提取是否对光照变化强健,因为图像的表情、遮挡等都没变化。我认为这个数据库太大,不适合这篇文章的实验,我建议使用ORL数据库。
1.3.1. 准备数据
我们从网上下了数据,下了我们需要在程序中读取它,我决定使用CSV文件读取它。一个CSV文件包含文件名,紧跟一个标签。
/path/to/image.ext0
假设/path/to/image.ext是图像,就像你在windows下的c:/faces/person0/image0.jpg。最后我们给它一个标签0。这个标签类似代表这个人的名字,所以同一个人的照片的标签都一样。我们对下载的ORL数据库进行标识,可以获取到如下结果:
./at/s1/1.pgm0
./at/s1/2.pgm0
...
./at/s2/1.pgm1
./at/s2/2.pgm1
...
./at/s40/1.pgm39
./at/s40/2.pgm39
想象我已经把图像解压缩在D:/data/at下面,而CSV文件在D:/data/at.txt。下面你根据自己的情况修改替换即可。一旦你成功建立CSV文件,就可以像这样运行示例程序:
facerec_demo.exe D:/data/at.txt
1.3.2 Creating the CSV File
你不需要手工来创建一个CSV文件,我已经写了一个Python程序来做这事。
[gm:说一个我实现的方法
如果你会cmd命令,或者称DOS命令,那么你打开命令控制台。假设我们的图片放在J:下的Faces文件夹下,可以输入如下语句:
J:\Faces\ORL>dir /b/s *.bmp >at.txt
然后你打开at.txt文件可能看到如下内容(后面的0,1..标签是自己加的):
。。。。
J:\Faces\ORL\s1\1.bmp0
J:\Faces\ORL\s1\10.bmp0
J:\Faces\ORL\s1\2.bmp0
J:\Faces\ORL\s1\3.bmp0
J:\Faces\ORL\s1\4.bmp0
J:\Faces\ORL\s1\5.bmp0
J:\Faces\ORL\s1\6.bmp0
J:\Faces\ORL\s1\7.bmp0
J:\Faces\ORL\s1\8.bmp0
J:\Faces\ORL\s1\9.bmp0
J:\Faces\ORL\s10\1.bmp1
J:\Faces\ORL\s10\10.bmp1
J:\Faces\ORL\s10\2.bmp1
J:\Faces\ORL\s10\3.bmp1
J:\Faces\ORL\s10\4.bmp1
J:\Faces\ORL\s10\5.bmp1
J:\Faces\ORL\s10\6.bmp1
。。。。
自然还有c++编程等方法可以做得更好,看这篇文章反响,如果很多人需要,我就把这部分的代码写出来。(遍历多个文件夹,标上标签)
]
特征脸Eigenfaces
我们讲过,图像表示的问题是他的高维问题。二维灰度图像p*q大小,是一个m=qp维的向量空间,所以一个100*100像素大小的图像就是10,000维的图像空间。问题是,是不是所有的维数空间对我们来说都有用?我们可以做一个决定,如果数据有任何差异,我们可以通过寻找主元来知道主要信息。主成分分析(Principal Component Analysis,PCA)是KarlPearson (1901)独立发表的,而 Harold Hotelling (1933)把一些可能相关的变量转换成一个更小的不相关的子集。想法是,一个高维数据集经常被相关变量表示,因此只有一些的维上数据才是有意义的,包含最多的信息。PCA方法寻找数据中拥有最大方差的方向,被称为主成分。
算法描述Algorithmic Description
令 表示一个随机特征,其中 .
计算均值向量
计算协方差矩阵 S
计算 的特征值和对应的特征向量
对特征值进行递减排序,特征向量和它顺序一致. K个主成分也就是k个最大的特征值对应的特征向量。
x的K个主成份:
其中 .
PCA基的重构:
其中 .
然后特征脸通过下面的方式进行人脸识别:
A. 把所有的训练数据投影到PCA子空间
B. 把待识别图像投影到PCA子空间
C. 找到训练数据投影后的向量和待识别图像投影后的向量最近的那个。
还有一个问题有待解决。比如我们有400张图片,每张100*100像素大小,那么PCA需要解决协方差矩阵 的求解,而X的大小是10000*400,那么我们会得到10000*10000大小的矩阵,这需要大概0.8GB的内存。解决这个问题不容易,所以我们需要另一个计策。就是转置一下再求,特征向量不变化。文献 [Duda01]中有描述。
[gm:这个PCA还是自己搜着看吧,这里的讲的不清楚,不适合初学者看]
OpenCV中使用特征脸Eigenfaces in OpenCV
给出示例程序源代码
#include "opencv2/core/core.hpp"
#include "opencv2/contrib/contrib.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
#include <fstream>
#include <sstream>
usingnamespace cv
usingnamespace std
static Mat norm_0_255(InputArray _src) {
Mat src = _src.getMat()
// 创建和返回一个归一化后的图像矩阵:
Mat dst
switch(src.channels()) {
case1:
cv::normalize(_src, dst, 0,255, NORM_MINMAX, CV_8UC1)
break
case3:
cv::normalize(_src, dst, 0,255, NORM_MINMAX, CV_8UC3)
break
default:
src.copyTo(dst)
break
}
return dst
}
//使用CSV文件去读图像和标签,主要使用stringstream和getline方法
staticvoid read_csv(const string&filename, vector<Mat>&images, vector<int>&labels, char separator ='') {
std::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)) {
stringstream liness(line)
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(int argc, constchar*argv[]) {
// 检测合法的命令,显示用法
// 如果没有参数输入则退出!.
if (argc <2) {
cout <<"usage: "<<argv[0]<<" <csv.ext><output_folder>"<<endl
exit(1)
}
string output_folder
if (argc ==3) {
output_folder = string(argv[2])
}
//读取你的CSV文件路径.
string fn_csv = string(argv[1])
// 2个容器来存放图像数据和对应的标签
vector<Mat>images
vector<int>labels
// 读取数据. 如果文件不合法就会出错
// 输入的文件名已经有了.
try {
read_csv(fn_csv, images, labels)
} catch (cv::Exception&e) {
cerr <<"Error opening file \""<<fn_csv <<"\". Reason: "<<e.msg <<endl
// 文件有问题,我们啥也做不了了,退出了
exit(1)
}
// 如果没有读取到足够图片,我们也得退出.
if(images.size()<=1) {
string error_message ="This demo needs at least 2 images to work. Please add more images to your data set!"
CV_Error(CV_StsError, error_message)
}
// 得到第一张照片的高度. 在下面对图像
// 变形到他们原始大小时需要
int height = images[0].rows
// 下面的几行代码仅仅是从你的数据集中移除最后一张图片
//[gm:自然这里需要根据自己的需要修改,他这里简化了很多问题]
Mat testSample = images[images.size() -1]
int testLabel = labels[labels.size() -1]
images.pop_back()
labels.pop_back()
// 下面几行创建了一个特征脸模型用于人脸识别,
// 通过CSV文件读取的图像和标签训练它。
// T这里是一个完整的PCA变换
//如果你只想保留10个主成分,使用如下代码
// cv::createEigenFaceRecognizer(10)
//
// 如果你还希望使用置信度阈值来初始化,使用以下语句:
// cv::createEigenFaceRecognizer(10, 123.0)
//
// 如果你使用所有特征并且使用一个阈值,使用以下语句:
// cv::createEigenFaceRecognizer(0, 123.0)
//
Ptr<FaceRecognizer>model = createEigenFaceRecognizer()
model->train(images, labels)
// 下面对测试图像进行预测,predictedLabel是预测标签结果
int predictedLabel = model->predict(testSample)
//
// 还有一种调用方式,可以获取结果同时得到阈值:
// int predictedLabel = -1
// double confidence = 0.0
// model->predict(testSample, predictedLabel, confidence)
//
string result_message = format("Predicted class = %d / Actual class = %d.", predictedLabel, testLabel)
cout <<result_message <<endl
// 这里是如何获取特征脸模型的特征值的例子,使用了getMat方法:
Mat eigenvalues = model->getMat("eigenvalues")
// 同样可以获取特征向量:
Mat W = model->getMat("eigenvectors")
// 得到训练图像的均值向量
Mat mean = model->getMat("mean")
// 现实还是保存:
if(argc==2) {
imshow("mean", norm_0_255(mean.reshape(1, images[0].rows)))
} else {
imwrite(format("%s/mean.png", output_folder.c_str()), norm_0_255(mean.reshape(1, images[0].rows)))
}
// 现实还是保存特征脸:
for (int i =0i <min(10, W.cols)i++) {
string msg = format("Eigenvalue #%d = %.5f", i, eigenvalues.at<double>(i))
cout <<msg <<endl
// 得到第 #i个特征
Mat ev = W.col(i).clone()
//把它变成原始大小,为了把数据显示归一化到0~255.
Mat grayscale = norm_0_255(ev.reshape(1, height))
// 使用伪彩色来显示结果,为了更好的感受.
Mat cgrayscale
applyColorMap(grayscale, cgrayscale, COLORMAP_JET)
// 显示或者保存:
if(argc==2) {
imshow(format("eigenface_%d", i), cgrayscale)
} else {
imwrite(format("%s/eigenface_%d.png", output_folder.c_str(), i), norm_0_255(cgrayscale))
}
}
// 在一些预测过程中,显示还是保存重建后的图像:
for(int num_components =10num_components <300num_components+=15) {
// 从模型中的特征向量截取一部分
Mat evs = Mat(W, Range::all(), Range(0, num_components))
Mat projection = subspaceProject(evs, mean, images[0].reshape(1,1))
Mat reconstruction = subspaceReconstruct(evs, mean, projection)
// 归一化结果,为了显示:
reconstruction = norm_0_255(reconstruction.reshape(1, images[0].rows))
// 显示或者保存:
if(argc==2) {
imshow(format("eigenface_reconstruction_%d", num_components), reconstruction)
} else {
imwrite(format("%s/eigenface_reconstruction_%d.png", output_folder.c_str(), num_components), reconstruction)
}
}
// 如果我们不是存放到文件中,就显示他,这里使用了暂定等待键盘输入:
if(argc==2) {
waitKey(0)
}
return0
}
我使用了伪彩色图像,所以你可以看到在特征脸中灰度值是如何分布的。你可以看到特征脸不但对人脸特征进行编码,还对这些图像中的光照进行编码。(看第四张图像是左侧的光照,而第五张是右侧的光照)[gm:PCA对光照变化图像识别效果很差,自然有一些改进方法,有后再谈]
人脸数据分析是什么
人脸数据分析是什么,人脸识别是基于人的脸部特征信息进行身份识别的一种生物识别技术,随着科技发展现在很多场所都用的到人脸分析,很多人还不清楚其中的原理是什么,那么就来了解一下人脸数据分析是什么吧。
人脸数据分析是什么1一、人脸识别技术
完整的人脸识别系统一般包括人脸检测跟踪、人脸关键点定位、人脸属性分析、人脸验证、人脸识别、人脸聚类等模块。
1、人脸检测跟踪:
人脸检测跟踪技术提供快速、高准确率的人像检测功能。对背景复杂低质量的图片或百人人群监控视频,可以在移动设备和个人电脑上实现毫秒级别的人脸检测跟踪。
2、人脸关键点定位:
人脸关键点定位可以精确定位面部的关键区域位置,微秒级别眼,口,鼻轮廓等人脸106个关键点定位。该技术可适应一定程度遮挡和大角度侧脸,表情变化,遮挡,模糊,明暗变化等各种实际环境。
3、人脸属性分析:
提供准备的面部分析技术,准确识别10多种人脸属性大类,例如性别,年龄、种族、表情、饰品、胡须、面部动作状态等。可以用于广告定向投放或顾客信息分析,让你秒懂顾客户心。
4、人脸验证、识别、聚类:
人脸验证技术可被用于登录验证、身份识别等应用场景。给定人脸样本,毫秒级别检索大规模人脸数据库或监控视频,给出身份认证,实现身份和人脸绑定。
人脸识别技术可以自动识别出照片、视频流中的人脸身份,可以实现安防检查、VIP识别、照片自动圈人、人脸登录等功能能,在认证出96%的人脸时,误检率低于十万分之一。数十万人的人脸快速聚类,可用于基于人脸的智能相册以及基于合影的社交网络分析。让照片管理更直观,让社交关系更清晰。
二、智能广告大数据分析特点
1、精确统计进出店铺的客流量:
启动应用,显示人脸识别检测界面,通过人脸识别技术检测头肩、检测人脸、对人脸进行跟踪识别,提取人脸特征值,进行精准的人体判断,准确的识别用户人脸,基于人体跟踪,有效避免因徘徊、逗留引起的重复计数,从而达到精确统计进出店铺的客流量的数据。在统计客流量的同时展示店铺的广告宣传信息、店铺简介、特色产品、售后服务等相关信息。
2、精准分析入店客户:
通过人脸识别技术,主动分析每一位停留观看广告的年龄、性别、并实时上传至服务器,管理者通过对消费群体的数据分析,精准挖掘出店铺和产品主要面向的销售者群体属于哪一类人,从而改善产品设计、运营模式、推广方案,极大有利于提升店铺的利润和广告的回报率。
3、精确认识和挖掘VIP客户:
精确、实时识别VIP客户并推送用户信息至店员手机,VIP客户历史入店信息及购买记录一目了然,店员重点接待VIP客户大大提升店铺营业额。通过大数据分析挖掘回头客,提升客户提袋率及VIP客户转化率,系统自动识别并排除店员,不再误统计为客流,真正做到准确的数据分析。
4、完备的报表:数据即事实 :
大数据分析并形成简洁、客观、精确的数据报表,直观的看到每日/月的客流量( 人数、人次)、客流人群分布(年龄、性别)、入店率、平均关注时间、提袋率(转化率),对店铺的客流量进行趋势分析(日、周、月),进行统一的广告效果分析,精准挖掘出每一个广告后面隐藏的客户数据,极大有利于广告制作和投放的精准营销,帮助商家精准定位有效客群,为投放商、制作方等相关企业提供可靠的数据参考,发现提高有效展示和回报率的关键。
5、大数据分析,驱动管理优化
通过大数据可以分析店铺什么产品最受关注、产品的目标客户群是哪些人、最受关注的产品是什么、单个产品为何有些销量高有些则低、VIP客户关注的是什么产品、什么区域受冷落、什么区域关注度比较高。
通过数据分析的结果优化店铺管理,找出最适合店铺的经营模式、消费者最关注的广告、转化率最高的产品、根据客户逛店路径分析热点区域,调整主打产品陈列引起客户关注度,改善店员服务过程中存在的不足,从宏观到细节进行优化,达到店铺的利益最大化。
6、 主动推送潜在客户,方便直接的提供业务帮助
将采集到的多用户信息进行聚类并分析得到统计数据,根据驻足观看的用户性别不同、年龄层次不同,1-2秒内切换广告内容,推送更针对性的产品广告信息。比如,为20-30岁的男性用户推送剃须刀、洗面奶等适合他们需求的广告,从而有效提高广告的关注效果,提高广告的传播和产品购买的`转化率。
人脸数据分析是什么2人脸数据分析的应用价值
人脸识别需要积累采集到的大量人脸图像相关的数据,用来验证算法,不断提高识别准确性,这些数据诸如A Neural Network Face Recognition Assignment(神经网络人脸识别数据)、orl人脸数据库、麻省理工学院生物和计算学习中心人脸识别数据库、埃塞克斯大学计算机与电子工程学院人脸识别数据等。
1、在人脸识别的设备上,除人脸识别区域外,设置固定的广告播放区域,使用多媒体信息发布系统,定时或不定时地轮播商家自定义的广告,比如商家简介、产品介绍、活动促销、联系方式等多媒体信息。
内容展现方式多种多样,可以是视频、图片、文字、流媒体等素材,让用户体验到现代化购物的感觉,智能化的液晶产品可以让店铺的整体美观度大大提升,顿刻显得高大上。
2、对于每一个广告投放商而言,广告效果的好坏直接关系到投入产出比,也决定着未来是否需继续投放。而对于广告制作方来说,什么样的广告最能吸引目标客户?提高有效传播率,他们需要足够的数据调研来为下一步广告制作提供依据。
为此,南翼基于人脸识别的智能广告大数据分析解决方案,为广告机提供广告效果分析解决方案,帮助商家精准定位有效客群,为投放商、制作方等相关企业提供可靠的数据参考,发现提高有效展示和回报率的关键,提升广告运营的价值。
3、除了人脸识别外,我们还提供手势识别技术,用户可以自由通过简单、通用的手势进行广告内容的切换,或者还可以在线玩一些有趣的游戏,从而提高用户的好感度,也可以通过完成商家指定的人脸表情赢得奖品等活动来增强商家与客户的互动性。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)