利用OpenCV的Haar特征目标检测方法进行人脸识别的尝试(一)

一、前言

由于还处于学习阶段,大多数内容都是从网上学习借鉴的,重复的内容就不多赘述,只是将自己的经验和想法分享出来。感觉不错的学习资源如下

http://www.cnblogs.com/tornadomeet/archive/2012/03/28/2420936.html

http://www.cnblogs.com/wengzilin/p/3849118.html

http://blog.csdn.net/liulina603/article/details/8197889


二、目标检测概念

在实践前我先阅读了OpenCV中文网用户手册的相关内容,对目标检测有了一个大体的概念。

链接:http://wiki.opencv.org.cn/index.php/Cv模式识别


三、前期准备

1.准备用于人脸识别的正负样本

样本的选取上面链接的博客中说的都很清楚,按要求选好样本的大小,比例

需要注意的是。负样本的选取很有讲究,并不是图片越复杂,图片之间越不相干越好。如果识别有特定的应用场景,则负样本中应尽量挑选具有这类特定场景的图片。当然,我们的人脸识别并没有特定的场景,尽量选中照相时经常出现的背景即可。另外可以考虑添加一些干扰项,比如动物的脸。

下面是我使用的正负样本的下载地址,正样本均标准化为24*24像素,方便大家使用

http://download.csdn.net/detail/u011583927/8534763


2.生成正负样本的描述文件

按照上面链接中的教程一步一步来即可

以正样本为例,先打开cmd

使用cd 命令将命令行的作用位置调到存放样本图像的文件夹下

输入dir /b >pos_image.txt

正样本需要将生产的txt文件中数据格式化成固定格式,负样本不需要


3.创建vec文件

命令:opencv_createsamples.exe -vec pos.vec -info pos_image.txt -bg neg_image.txt -w 24 -h 24 -num 400


四、训练xml文件

命令:opencv_haartraining.exe -data xml -vec pos.vec -bg neg_image.txt -nstages 20 -nsplits 2 -minhitrate 0.999 -maxfalsealarm 0.5 -npos 800 -nneg 2500 -w 24 -h 24  -mem 1024 -mode ALL

训练的参数进行了多次调整,上面所示是我多次修改后最后选用的。训练过程可能出现多种多样的问题,需要耐心的尝试修改自己的样本集。如果并没有达到设置的阶段数就停止迭代,并没有发生错误,只是负样本太少或者不够丰富。我的就是这种情况,设置的20层,只运行到了14层。这种情况不会自动生成想要的xml文件,需要手动运行

文件夹转换为xml文件命令:convert.exe --size="24x24" xml haarcascade.xml

convert.exe是opencv自带的转换文件,名字应该是convert_cascade。exe

xml是训练时生成的文件夹的名字

haarcascade.xml是想要生成的xml文件的名字

由于对于算法的理解还不深刻,参数的选择只是在实践性的尝试。

获得的经验是影响训练的效果的最重要环节是样本的选择好坏!

首先,在你的精力和时间允许的情况下,收集的样本越多越好。正样本好坏会决定人脸的漏识率,负样本的好坏决定了误识率。

仔细分析我的样本可以看出,正样本800个,是直接下载的人脸包,貌似外国人的人脸居多,可能会影响我们的识别。负样本2500个,数量较大。

根据我最后的测试结果,和我们的分析是符合的。人脸的漏识率还是不太满意的,但是误识率比较低。

训练了几个小时,在第13层时停止迭代了,应该是负样本


五、识别

识别代码如下,只是简单调用了openCV提供的函数

#include "cv.h"
#include "highgui.h"

CvHaarClassifierCascade* load_object_detector( const char* cascade_path )
{
    return (CvHaarClassifierCascade*)cvLoad( cascade_path );
}

void detect_and_draw_objects( IplImage* image,
                              CvHaarClassifierCascade* cascade,
                              int do_pyramids )
{
    IplImage* small_image = image;
    CvMemStorage* storage = cvCreateMemStorage(0);
    CvSeq* faces;
    int i, scale = 1;

    /* if the flag is specified, down-scale the 输入图像 to get a performance boost w/o loosing quality (perhaps) 
	    如果标识(do_puramids)是指定的,把输入图像缩小比例来获得一个性能的提升 without 不稳定的质量*/
    if( do_pyramids )
    {
        small_image = cvCreateImage( cvSize(image->width/2,image->height/2), IPL_DEPTH_8U, 3 );
        cvPyrDown( image, small_image, CV_GAUSSIAN_5x5 );
		/*功能:函数cvPyrDown使用Gaussian金字塔分解对输入图像向下采样。
		格式:void cvPyrDown(const CvArr*src,CvArr*dst,int filter=CV_GAUSSIAN_5x5);
		参数:src 输入图像。
			  dst 输出图像,其宽度和高度应是输入图像的一半。
			  filter 卷积滤波器类型,目前仅支持CV_GAUSSIAN_5x5。*/
        scale = 2;
    }

    /* use the fastest variant */
	/*使用了最快速的检测方式*/
    faces = cvHaarDetectObjects( small_image, cascade, storage, 1.1, 2, CV_HAAR_DO_CANNY_PRUNING );

    /* draw all the rectangles */
    for( i = 0; i < faces->total; i++ )
    {
        /* extract the rectanlges only */
        //CvRect face_rect = *(CvRect*)cvGetSeqElem( faces, i, 0 );
		CvRect face_rect = *(CvRect*)cvGetSeqElem( faces, i );
        cvRectangle( image, cvPoint(face_rect.x*scale,face_rect.y*scale),
                     cvPoint((face_rect.x+face_rect.width)*scale,
                             (face_rect.y+face_rect.height)*scale),
                     CV_RGB(255,0,0), 3 );
    }

    if( small_image != image )
        cvReleaseImage( &small_image );
    cvReleaseMemStorage( &storage );
}
//  .exe testImageAddress 分类器地址(xml)
/* takes image filename and cascade path from the command line */
int main( int argc, char** argv )
{
    IplImage* image;
    if( argc==3 && (image = cvLoadImage( argv[1], 1 )) != 0 )
    {
		CvHaarClassifierCascade* cascade=(CvHaarClassifierCascade*)cvLoad(argv[2]);
        //CvHaarClassifierCascade* cascade = load_object_detector(argv[2]);
        detect_and_draw_objects( image, cascade, 1 );
        cvNamedWindow( "test", 0 );
        cvShowImage( "test", image );
        cvWaitKey(0);
        cvReleaseHaarClassifierCascade( &cascade );
        cvReleaseImage( &image );
    }

    return 0;
}

运行测试文件命令:  可执行文件地址 图片地址 xml文件地址
C:\Users\Administrator\Desktop\lena\x64\Debug\lena.exe D:\数字图像处理\图像处理图片\标准测试图片\dollar.bmp C:\Users\Administrator\Desktop\haarcascade.xml

上传了几张程序运行结果




对于比较明显的人脸,尤其是外国人。。。识别结果还是不错的

还用了一些生活中的照片,识别效果一般,这里就不上传了,有一部分脸会漏识,还会偶尔有误识别。下一步打算把具体的算法深入研究一下,应该会有所突破

  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值