OpenCV 2.4+ C++ 人脸识别

摘要:
人脸识别人脸识别通过级联分类器对特征进行分层过滤来确定它是否是人脸。每个节点的正确识别率很高,但正确拒绝率很低。如果所有节点都通过,它们将被声明为面。在工业中,人脸识别技术通常用于识别物体。识别图片#include“opencv2/core/core.hpp”#include”opencv2/objdetect/objdetect.hpp”#include“opencv2/highgui/highgui.hpp”#include”opencv2/imgproc/imgproc.hpp“#include<iostream>#include<studio。h> 使用namespacestd;使用namespacecv;stringface_cascade_name=“haarcascade_efrontalface_alt.xml”;级联分类器面_级联;stringwindow_ Name=“人脸识别”;空隙检测和显示;intmain{Matimage;image=imread;if(argc!\n“);return-1;}检测和显示;waitKey;}voiddetectAndDisplay{std::vector<Rect>face;Matframe_gray;cvtColor;equalizeHist;face_cscade.dedetectMultiScale;for{Pointcenter;ellipse;}imshow;}效果:级联分类器类级联分类器是用于检测对象的级联分类器类。

机器学习

  • 机器学习的目的是把数据转换成信息。
  • 机器学习通过从数据里提取规则或模式来把数据转成信息。

人脸识别

  • 人脸识别通过级联分类器对特征的分级筛选来确定是否是人脸。
  • 每个节点的正确识别率很高,但正确拒绝率很低。
  • 任一节点判断没有人脸特征则结束运算,宣布不是人脸。
  • 全部节点通过,则宣布是人脸。

工业上,常用人脸识别技术来识别物体。 

对图片进行识别

#include "opencv2/core/core.hpp"
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"

#include <iostream>
#include <stdio.h>

using namespace std;
using namespace cv;

string face_cascade_name = "haarcascade_frontalface_alt.xml";
CascadeClassifier face_cascade;
string window_name = "人脸识别";

void detectAndDisplay( Mat frame );

int main( int argc, char** argv ){
    Mat image;
    image = imread( argv[1]);

    if( argc != 2 || !image.data ){
        printf("[error] 没有图片\n");
        return -1;
    }

    if( !face_cascade.load( face_cascade_name ) ){ 
        printf("[error] 无法加载级联分类器文件!\n");
        return -1; 
    }

    detectAndDisplay(image);

    waitKey(0);    
}

void detectAndDisplay( Mat frame ){
    std::vector<Rect> faces;
    Mat frame_gray;

    cvtColor( frame, frame_gray, CV_BGR2GRAY );
    equalizeHist( frame_gray, frame_gray );

    face_cascade.detectMultiScale( frame_gray, faces, 1.1, 2, 0|CV_HAAR_SCALE_IMAGE, Size(30, 30) );

    for( int i = 0; i < faces.size(); i++ ){
        Point center( faces[i].x + faces[i].width*0.5, faces[i].y + faces[i].height*0.5 );
        ellipse( frame, center, Size( faces[i].width*0.5, faces[i].height*0.5), 0, 0, 360, Scalar( 255, 0, 255 ), 4, 8, 0 );
    }

    imshow( window_name, frame );
}

效果:

OpenCV 2.4+ C++ 人脸识别第1张

CascadeClassifier类

class CascadeClassifier

用于检测物体的级联分类器类。

CascadeClassifier::CascadeClassifier

从一个文件读取分类器。

C++:CascadeClassifier::CascadeClassifier(const string& filename)
参数filename – 所要读取分类器文件的文件名

CascadeClassifier::empty

检查分类器是否已经载入。

C++:bool CascadeClassifier::empty() const

CascadeClassifier::load

从一个文件读取分类器。

C++:bool CascadeClassifier::load(const string& filename)
参数filename – 所要读取分类器文件的文件名。文件可以是旧版的HAAR分类器模型也可以是新版的分类器模型。

CascadeClassifier::read

读取一个文件存储节点的分类器

C++:bool CascadeClassifier::read(const FileNode& node)

CascadeClassifier::detectMultiScale

对不同大小的输入图像进行物体识别,并返回一个识别到的物体的矩阵列表。

C++:void CascadeClassifier::detectMultiScale(const Mat& image, vector<Rect>& objects, double scaleFactor=1.1, int minNeighbors=3, int flags=0, Size minSize=Size(), Size maxSize=Size())
参数
  • image – 需要检测的 CV_8U 输入矩阵。
  • objects – 输出vector载体容器用于保存被识别的物体矩阵。
  • scaleFactor – 指定每张图片的缩小比例的参数。
  • minNeighbors – 指定每个候选矩阵至少包含的邻近元素个数。
  • flags与旧版级联分类器模型函数cvHaarDetectObjects的flags相同. 此参数不被用于新版模型。
  • minSize最小可能的对象的大小,小于的对象将被忽略
  • maxSize最大可能的对象的大小,大于对象将被忽略。

CascadeClassifier::setImage

设置被用于检测的图像

C++:bool CascadeClassifier::setImage(Ptr<FeatureEvaluator>& feval, const Mat& image)
参数
  • feval – 用于特征计算的特征求值程序的指针。
  • image – 需要进行特征检测的 CV_8U 输入矩阵。

这个函数将在每张图片中被 CascadeClassifier::detectMultiScale() 自动调用。 但如果你想在不同位置手动使用 CascadeClassifier::runAt(),你需要先调用该函数,使得图像被积分计算。

CascadeClassifier::runAt

在指定点运行检测。

C++:int CascadeClassifier::runAt(Ptr<FeatureEvaluator>& feval, Point pt, double& weight)
参数

feval – 用于特征计算的特征求值程序。

pt – 指定检测窗口左上角的点。窗口的大小和检测的图片大小一致。

如果级联分类器检测给定的位置中的一个对象该函数返回1否则,它会返回已被否决候选区域在哪个阶段的否定指数

使用CascadeClassifier::setImage()设置图像检测工作

代码注释:

//需要载入的级联分类器文件
string face_cascade_name = "haarcascade_frontalface_alt.xml";
//级联分类器类
CascadeClassifier face_cascade;

//……

    //载入级联分类器,并判断是否载入成功,如果不成功则打印提示
    if( !face_cascade.load( face_cascade_name ) ){ 
        printf("[error] 无法加载级联分类器文件!\n");
        return -1; 
    }

//……

    //对图片frame进行识别检测
    face_cascade.detectMultiScale( frame_gray, faces, 1.1, 2, 0|CV_HAAR_SCALE_IMAGE, Size(30, 30) );

转换成灰度图

由于CascadeClassifier类只支持CV_8U矩阵数据,所以我们需要将图片变成灰度图。

cvtColor API:

将图片从一个色彩空间转到另一个色彩空间。

C++:void cvtColor(InputArray src, OutputArray dst, int code, int dstCn=0 )
参数
  • src输入图像8位无符号16位无符号CV_16UC...)或单精度浮点数据类型
  • dst – 输出图像,与输入图像相同大小、深度。
  • code颜色空间转换代码
  • dstCn – 目标图像的通道数,当该参数为0时,则通道树由src和code自动得出。

该函数将输入图片从一个色彩空间转到另一个色彩空间。当从RGB颜色空间进行变换时,应明确指定的信道的顺序(RGB或BGR)。值得注意,在OpenCV的默认颜色格式中,通常被称为作为RGB,但实际上是BGR(字节是相反的)。因此,在一个标准的(24位)的彩色图像的第一个字节是一个8位的蓝色分量,第二个字节将是绿色的,第三个字节将是红色的。而第四,第五,和第六字节,则是第二像素(蓝,然后绿色,然后红色),依此类推。

R、G和B 通道通常信道值范围:

  • CV_8U:0 — 255
  • CV_16U:0 — 65535
  • CV_32F:0 — 1

线性变换的情况下,有没有范围是无所谓的。但是,在一个非线性变换的情况下,输入的RGB图像应被归为适当的值范围内,以得到正确的结果。例如,如果你有一个32位浮点图像直接转换成一个8位的图像而没有任何缩放,那么它将有0到255的数值范围,而这并不能准确0..1所有浮点数的值。所以,你需要之前调用cvtColor,进行图像缩放。

代码注释:

//将frame转换成灰度图,输出到frame_gray
cvtColor( frame, frame_gray, CV_BGR2GRAY );

直方图均衡化

  • 直方图是图像中像素强度分布的图形表达方式。
  • 它统计了每一个强度值所具有的像素个数。

  http://www.cnblogs.com/http://www.cnblogs.com/../_images/Histogram_Equalization_Theory_0.jpg

  • 直方图均衡化是通过拉伸像素强度分布范围来增强图像对比度的一种方法。
  • 说得更清楚一些, 以上面的直方图为例, 你可以看到像素主要集中在中间的一些强度值上. 直方图均衡化要做的就是 拉伸 这个范围. 见下面左图: 绿圈圈出了 少有像素分布其上的 强度值. 对其应用均衡化后, 得到了中间图所示的直方图. 均衡化的图像见下面右图.

  http://www.cnblogs.com/http://www.cnblogs.com/../_images/Histogram_Equalization_Theory_1.jpg

我们利用直方图均衡化对图片增强对比度,方便级联分类器分析。

equalizeHist API:

对灰度图像进行直方图均衡。

C++:void equalizeHist(InputArray src, OutputArray dst)
参数
  • src – 源为8位单通道图像。
  • dst – 输出图像,和源图片同样大小类型。

直方图均衡函数使用了下列的算法:

  1. 计算源文件的直方图 H 。

  2. 调整直方图,使得其方格总个数为255。

  3. 对直方图进行积分:

    H'_i = \sum _{0 \le j < i} H(j)

  4. 使用 H' 变换图片,其映射函数为:\texttt{dst}(x,y) = H'(\texttt{src}(x,y))

该算法归一化亮度并增加了图像的对比度。

被山寨的原文

Cascade Classifier . OpenCV.org

Cascade Classification API . OpenCV.org

Histogram Equalization . OpenCV.org

免责声明:文章转载自《OpenCV 2.4+ C++ 人脸识别》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇cell函数总结数据库概述及基本操作下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

机器学习与R语言

此书网上有英文电子版:Machine Learning with R - Second Edition [eBook].pdf(附带源码) 评价本书:入门级的好书,介绍了多种机器学习方法,全部用R相关的包实现,案例十分详实,理论与实例结合。 目录 第一章 机器学习简介 第二章 数据的管理和理解 第三章 懒惰学习--使用近邻分类 第四章 概率学习--朴素贝...

PythonOpencv-分类器—SVM,KNearest,RTrees,Boost,MLP

原文链接:http://blog.csdn.net/gjy095/article/details/9243153 上一篇文章,不是很详细,这一篇解释的清晰些,请访问原始链接。 Rtrees介绍!参考链接:http://docs.opencv.org/modules/ml/doc/random_trees.html Opencv提供了几种分类器,例程里通过字...

轻松学Pytorch-详解Conv2D卷积处理

轻松学Pytorch-详解Conv2D卷积处理 原创 gloomyfish OpenCV学堂 4月25日 收录于话题 #轻松学Pytorch系列 30个 图片 点击上方蓝字关注我们 微信公众号:OpenCV学堂 关注获取更多计算机视觉与深度学习知识 Conv2D基本原理与相关函数 常见的图像卷积是二维卷积,而深度学习中Conv2D卷积是三维卷积,图示...

卷积神经网络(CNN)

卷积神经网络介绍卷积神经网络是一种多层神经网络,擅长处理图像特别是大图像的相关机器学习问题。 最典型的卷积网络,由卷积层、池化层、全连接层组成。其中卷积层与池化层配合,组成多个卷积组,逐层提取特征,最终通过若干个全连接层完成分类。 卷积层完成的操作,可以认为是受局部感受野概念的启发,而池化层,主要是为了降低数据维度。 综合起来说,CNN通过卷积来模拟特征区...

解决多标签分类问题的技术

多标签分类基本上,有三种方法来解决一个多标签分类问题,即: 问题转换 改编算法 集成方法 4.1问题转换 在这个方法中,我们将尝试把多标签问题转换为单标签问题。这种方法可以用三种不同的方式进行: 二元关联(Binary Relevance) 分类器链(Classifier Chains) 标签Powerset(Label Powerset) 4.4...

图像检索(image retrieval)- 8

PARTICULAR OBJECT RETRIEVAL WITH INTEGRAL MAX-POOLING OF CNN ACTIVATIONS ABSTRACT 最近,建立在卷积神经网络(CNN)上的图像表征已经被证明可以为图像搜索提供有效的描述符,其性能优于作为短向量表征的前CNN特征。然而,这种模型与几何感知重排序方法并不兼容,在某些特定对象检索基...