人脸识别-再识
来源:互联网 发布:传奇app源码 编辑:程序博客网 时间:2024/06/09 16:00
这里是识别,而不是人脸检测,检测部分前面我已经说过,是一种基于adaboost的级联决策算法,能够高精度的检测出人脸所在的区域。
前面我们转载了几篇人脸识别网上的资源,大家可能知道如何在OpenCV中使用人脸识别这个库,但是对于其中算法的深层含义还远没有彻底弄懂。所以我通过一篇论文的阅读《基于LBP和Fisher face的人脸算法研究》讲解现在人脸识别算法的具体含义。
CV_EXPORTS_W Ptr<FaceRecognizer> **createEigenFaceRecognizer**(int num_components = 0, double threshold = DBL_MAX); CV_EXPORTS_W Ptr<FaceRecognizer> **createFisherFaceRecognizer**(int num_components = 0, double threshold = DBL_MAX); CV_EXPORTS_W Ptr<FaceRecognizer> **createLBPHFaceRecognizer**(int radius=1, int neighbors=8, int grid_x=8, int grid_y=8, double threshold = DBL_MAX);
OpenCV中比较好认识的就是 基于LBP算子的人脸识别算法。我们首先讲解这个算子的过程。
还是先看下OpenCV下的结果,我们使用的是ORL人脸数据库,每个人有10张,包含了40个人。
vector<Mat> images; vector<int> labels; // images for first person images.push_back(imread("ORL\\s1\\1.bmp", CV_LOAD_IMAGE_GRAYSCALE)); labels.push_back(1); images.push_back(imread("ORL\\s1\\2.bmp", CV_LOAD_IMAGE_GRAYSCALE)); labels.push_back(1); images.push_back(imread("ORL\\s1\\3.bmp", CV_LOAD_IMAGE_GRAYSCALE)); labels.push_back(1); images.push_back(imread("ORL\\s1\\4.bmp", CV_LOAD_IMAGE_GRAYSCALE)); labels.push_back(1); images.push_back(imread("ORL\\s1\\5.bmp", CV_LOAD_IMAGE_GRAYSCALE)); labels.push_back(1); images.push_back(imread("ORL\\s1\\6.bmp", CV_LOAD_IMAGE_GRAYSCALE)); labels.push_back(1); images.push_back(imread("ORL\\s1\\7.bmp", CV_LOAD_IMAGE_GRAYSCALE)); labels.push_back(1); images.push_back(imread("ORL\\s1\\8.bmp", CV_LOAD_IMAGE_GRAYSCALE)); labels.push_back(1);
这是第一个人的信息,大家可以按照这个规律进行人脸的扩展。
Ptr<FaceRecognizer> model = createEigenFaceRecognizer(); model->train(images, labels); Mat img = imread("ORL\\s1\\8.bmp", CV_LOAD_IMAGE_GRAYSCALE); double confidence; int predicted; model->predict(img,predicted,confidence);
confidence是预测的置信度。可以在构造createEigenFaceRecognizer的时候设置阈值参数,如果超过了这个参数,那么得到的结果就是-1,表示没有合适的分类。
基于LBP的人脸识别
LBP是local binary pattern的简写,局部二值模式。
原始LBP算子最初是在3*3的矩形窗口上定义的,以矩形窗口心中点的灰度值作为阈值,将邻域内各像素点像素值与阈值进行比较,将比较结果进行二值化处理,然后各邻域像素点根据位置的不同进行加权求和和到该窗口中心的LBP值(为了满足旋转性,将该二值串进行循环移动,然后使用权值加权–如下)。
对所有情况中选择值最小的作为这个点的LBP值。
当然后面提出了基于圆形的任意半径只是一个扩展,也很好理解。
接着,在圆形LBP的基础上,发现局部二值模式在提取局部纹理特征过程中,二进制模式种类数是对着采样像素点的个数增加而增加的。比如3*3的矩形框中的二进制模式就有
注意:对于3×3邻域内8个采样点来说,二进制模式由原始的256种减少为58种,即:它把值分为59类,58个uniform pattern为一类,其它的所有值为第59类。
当我们知道某一个点属于哪个模式后,接下来我们基于这些LBP值进行人脸识别。
LBP被运用于计算机人脸识别领域时,提取出来的人脸特征通常是以LBP直方图向量进行表达的。
1. 对预处理后的人脸图像进行分块
2. 对分块后的各小块图像区域进行LBP特征提取变换
3. 使用LBP直返图向量作为人脸特征的描述。
一般分块数越多,人脸表达的效果就会越好,但是分块数越多,会直接导致特征向量维数的增加,会增加计算的复杂度。对每个分块计算LBP值的直方图,然后将所有分块直方图进行连接得到最终的直方图特征向量,这个特征向量代表原来的人脸图像,可以用来描述整体图像。
对于这个融合的直方图,我们进行特征分类。
如果训练样本数量越大,分类的效果也会越好,在基于LBP的人脸识别中,通常采用基于直方图的相似性度量的最近邻分类方法来分类。
我们可以在 OpenCV源码中找到他的实现“sources
\modules\contrib\src\facerec.cpp”函数
void LBPH::predict(InputArray _src, int &minClass, double &minDist) const
部分源码如下:
// find 1-nearest neighbor minDist = DBL_MAX; minClass = -1; for(size_t sampleIdx = 0; sampleIdx < _histograms.size(); sampleIdx++) { double dist = compareHist(_histograms[sampleIdx], query, CV_COMP_CHISQR); if((dist < minDist) && (dist < _threshold)) { minDist = dist; minClass = _labels.at<int>((int) sampleIdx); } }
可以看出是在所有图像的直方图中找出距离最近的作为返回值。
- 人脸识别-再识
- 语音识别&人脸识别
- 【人脸识别】初识人脸识别
- 【人脸识别】初识人脸识别
- OpenCV的行人识别&人脸识别
- 图片识别之人脸识别API
- OpenCV的行人识别&人脸识别
- IOS人脸识别和二维码识别
- 人脸识别之颜色识别
- Face++ 人脸识别,身份识别集成
- 人脸识别:(抓拍+识别)
- 人脸识别的发展方向:蒙面识别
- 人脸识别-再识(二)
- 人脸识别
- 人脸识别
- 人脸识别算法
- 简单人脸识别
- 人脸识别代码
- 我的成长—优化类(new数组)--2016.8.13
- LearnOpenGL学习笔记4:纹理
- 【数据结构】——树状数组的几种模型
- YYModel 简介与使用
- myBatis关于不允许空值属性的查询
- 人脸识别-再识
- Sring 字符串判断是否相同
- map写入文件及从文件读出
- c# 经验谈:巧用Expression表达式 解决类似于sql中 select in 的查询
- 傅立叶分析导论-5 傅里叶变换
- IE6IE7Firefox浏览器不兼容原因及解决办法
- git difftool 第三方工具配置
- java中方法为什么需要返回值?
- JSP的3个指令