opencv的强大之处想必大家也是略知一二吧,本文章人脸识别研究的入门,算法都是直接调用opencv。
opencv3.0都已经发布了但是本代码还是写在2.4.9的环境中,不过其中的方法都是用的C++ API,也就是与3.0接轨了
//头文件:image.h
#include "opencv.hpp"
#include <iostream>
#include <iterator> //迭代器
using namespace std;
using namespace cv;
//主函数:mian.cpp
#include"image.h"
int main()
{
VideoCapture cap(0);
if(!cap.isOpened())
{
return -1;
}
Mat frame,gray, smallImg,imageROI;
vector<Rect> faces;
CascadeClassifier cascade ;
cascade.load("haarcascade_frontalface_alt.xml") ;
Ptr<FaceRecognizer> m_model = createLBPHFaceRecognizer(1,8,8,8,90);
m_model->load("MyFaceout.xml");
do{
cap>>frame;
cvtColor( frame, gray, CV_BGR2GRAY ); //灰度处理
resize( gray, smallImg, Size(), 0.2, 0.2, INTER_LINEAR );//设置图像尺寸
equalizeHist( smallImg, smallImg ); //直方均衡化
cascade.detectMultiScale( smallImg, faces,
1.1, 2, 0
//|CV_HAAR_FIND_BIGGEST_OBJECT
//|CV_HAAR_DO_ROUGH_SEARCH
|CV_HAAR_SCALE_IMAGE,
Size(30, 30) );
for( vector<Rect>::const_iterator r = faces.begin(); r != faces.end(); r++ )
{
Rect r(cvPoint(cvRound(5*(r->x)), cvRound(5*(r->y))),
cvPoint(cvRound(5*(r->x + r->width-1)), cvRound(5*(r->y + r->height-1))));
rectangle(frame, r,CV_RGB(0,0,255), 3, 8, 0);
imageROI = frame(r);
resize(imageROI,imageROI,Size(92,112));
cvtColor(imageROI , imageROI,CV_BGR2GRAY);
cout<<m_model->predict(imageROI)<<" 您好!\n";
}
cv::imshow("人脸检测",frame );
}while(waitKey(30)<=0);
return 0;
}
人脸识别的算法非常的多,在静态识别方面已经达到了不错的效果,但是在实时的监控方面还是存在很大的问题,本文是我写的第一篇Blog,所以还请谅解。
1,头文件:
#include "opencv.hpp"
这个是opencv最新推荐的头文件。opencv3.0使用的一个头文件。
2,函数实体
VideoCapture cap(0);
参数0打开默认的摄像头,-1表示打开前提醒选择摄像头
Mat frame,gray, smallImg,imageROI;
frme要接受来自摄像头的图像Mat,gray保存frame灰度化的图形,smallImg保存改变尺寸的gray,如果尺寸不变的话,对大图形进行人脸检测非常耗时的,imageROI设置图像的感兴趣区域,就是包含人脸的区域。
vector<Rect> faces;
保存检测出的人脸区域
CascadeClassifier cascade
人脸检测器
cascade.load("haarcascade_frontalface_alt.xml") ;
加载人脸检测需要的数据,在opencv文件的data文件夹内
Ptr<FaceRecognizer> m_model = createLBPHFaceRecognizer(1,8,8,8,90);
基于LBP的人脸识别方法,会详细讲解
m_model->load("MyFaceout.xml");
人脸库需要调用 model->train(images,labels);model->save("MyFaceout.xml");方法来进行训练得到,images表示包含人脸的容器,labells是标签容器,会详细讲解,在此先用着。
cap>>frame;
文件流将从cap的数据流向frame
cvtColor( frame, gray, CV_BGR2GRAY ); //灰度处理
resize( gray, smallImg, Size(), 0.2, 0.2, INTER_LINEAR );//归一化处理
equalizeHist( smallImg, smallImg ); //直方均衡化
进行人脸检测前对图像进行的必要的处理,灰度处理将图像变成一维的加快处理速度,resize的四个参数gray输入Mat,smallImg输出Mat,两个0.2分别是横向,和纵向的缩小比例,0.2就是把原来的长或宽乘0.2也就是缩小5倍
equalizedHist直方均衡化,突出图像的临界区域,提高识别率,但是对于本代码似乎无效
cascade.detectMultiScale( smallImg, faces,
1.1, 2, 0
//|CV_HAAR_FIND_BIGGEST_OBJECT
//|CV_HAAR_DO_ROUGH_SEARCH
|CV_HAAR_SCALE_IMAGE,
Size(30, 30) );
人脸检测的方法参数对于人脸识别来说没有那么的重要,具体的参数理解需要对检测的原理有个理解,所以现在也就先不说了。
for( vector<Rect>::const_iterator r = faces.begin(); r != faces.end(); r++ )
{
Rect r(cvPoint(cvRound(5*(r->x)), cvRound(5*(r->y))),
cvPoint(cvRound(5*(r->x + r->width-1)), cvRound(5*(r->y + r->height-1))));
imageROI = frame(r);
resize(imageROI,imageROI,Size(92,112));
cvtColor(imageROI , imageROI,CV_BGR2GRAY);
cout<<m_model->predict(imageROI)<<" 您好!\n";
}
利用上不检测得到的区域向量,在frame中设置该区域为感兴趣区域,并将该区域赋给iamgeROI,然后就是图像的大小设置,训练的时候图像大小就是92*112故该处也应如此,转换为灰度值,opencv的predict只能识别一维的图像。
cv::imshow("人脸检测",frame );
显示图像
至此代码完了详细的原理讲解将会在以后的文章中补充。