使用OpenCV创建分类器XML并测试效果

    经过三天奋斗,终于自己创建了想要的分类器,并测试了分类器。感觉很兴奋,然而想到遇到的一系列问题,而求助无果,遂写本文以飨读者。
    本人使用OpenCV 2.1.0版本,使用VS2008平台,VS2008的安装同志们自己找吧,一搜一大堆,这个好解决。我先前在训练XML时,使用的是OpenCV2.4以上的版本,里面没有OpenCV_createsamples.exe文件,所以,后来安装了OpenCV 2.1.0-win32-VS2008这个版本(经测试,这个可以http://ishare.iask.sina.com.cn/f/14399905.html)。下载后,自己安装并设置系统路径等参数(不会的可以参考http://www.docin.com/p-405551652.html)。
    现在要准备正负样本了,正样本可以自己收集,也可以从网上下载。对于人脸这东西,现在很多研究机构都有自己的测试库,而且公开了。我建议做人脸识别这一块的,可以上这个网站下载http://tutorial-haartraining.googlecode.com/svn/trunk/data/,其中正负样本大概有几万个(负样本就6000+,够用了)。关于正负样本,强调一下,正样本需要一样大,即需要归一化,而负样本不需要,负样本要比正样本大,本人第一次测试时,负样本也归一化为正样本大小,分类器训练中貌似陷入死循环,半天没结果。所以,负样本大小一定要比正样本大。还有,本人针对自己的项目,设了自己的负样本并用此训练了一个分类器,另外使用网上的负样本又训练了一个分类器,最后监测结果表明,第一个分类器测试精度比较高,我觉的是不同问题需要不同的负样本,所以,负样本尽量自己收集。关于如何创建正负样本集生成分类器,注意以上几点后,就可以参考本人上一篇转载的博客了《OpenCV训练分类器制作XML文档》(我参考了很多博文,这个写的最好,说明了很多问题是怎么产生的),如果你鄙视国人写的,你可以看看老外写的,那个详细啊……自己看http://note.sonots.com/SciSoftware/haartraining.html。
    当你的XML文档生成后,你就可以出一口气了。呵呵使用OpenCV创建分类器XML并测试效果
     不过,这个XML分类器究竟如何,需要进一步测试。由于以前接触过一本书中(《Visual C++数字图像处理技术详解》机械工业出版社)的一个人脸检测项目(12章,P478),所以,测试中自然而然的使用了它的代码。该代码比较简单,但比较实用。在你要粘贴下面代码之前,你需要建一个控制台应用程序项目,然后,对项目进行全局选项配置(如果你没配置的话),即在工具-》选项-》项目和解决方案-》VC++目录-》库文件中添加lib文档-》包含文件中添加include相关文件。
     然后是对项目属性进行配置(只要新建项目都得配置),项目-》xxx属性-》配置属性-》连接器-》输入-》附加依赖项中加入
cv210.lib
cvaux210.lib
cxcore210.lib
cxts210.lib
highgui210.lib
ml210.lib
opencv_ffmpeg210.lib
cv210d.lib
cvaux210d.lib
cxcore210d.lib
highgui210d.lib
ml210d.lib
opencv_ffmpeg210d.lib
     以上前期工作做完后,就可以粘贴我下面的代码测试了。
#include "stdafx.h"
#include "highgui.h"
#include "cv.h"
#include <stdio.h>

static CvHaarClassifierCascade* cascade=0;
static CvMemStorage* storage=0;
void detect_and_draw(IplImage* img);
const char* cascade_name="xml.xml";  //此xml文件是刚才你产生的,拷贝到项目文件中,把名字改了

int main(int argc,char* argv[])
{
    cascade=(CvHaarClassifierCascade*)cvLoad(cascade_name,0,0,0);
    if (!cascade)
    {
        fprintf(stderr,"ERROR!\n");
        return -1;
    }

    storage=cvCreateMemStorage(0);
    const char* filename="1.bmp";      //你要测试的图片名字
    IplImage* image=cvLoadImage(filename,1);

    if (!image)
    {
        fprintf(stderr,"Load image error!\n");
        return -1;
    }

    cvNamedWindow("result",1);
    detect_and_draw(image);
    cvWaitKey();
    cvReleaseImage(&image);
    cvDestroyWindow("result");
    return 0;
}

void detect_and_draw(IplImage* img)
{
    static CvScalar colors[]=
    {
        {{0,0,255}},
        {{0,128,255}},
        {{0,255,255}},
        {{0,255,0}},
        {{255,128,0}},
        {{255,255,0}},
        {{255,0,0}},
        {{255,0,255}}
    };

    double scale=1.3;
    IplImage* gray=cvCreateImage(cvSize(img->width,img->height),8,1);
    IplImage* small_img=cvCreateImage(cvSize(cvRound(img->width/scale),cvRound(img->height/scale)),8,1);
    cvCvtColor(img,gray,CV_BGR2GRAY);
    cvResize(gray,small_img,CV_INTER_LINEAR);
    cvEqualizeHist(small_img,small_img);
    cvClearMemStorage(storage);

    if (cascade)
    {
        CvSeq* faces=cvHaarDetectObjects(small_img,cascade,storage,1.1,2,0,cvSize(30,30));
        for (int i=0;i<(faces?faces->total:0);i++)
        {
            CvRect* r=(CvRect*)cvGetSeqElem(faces,i);
            CvPoint center;
            int radius;
            center.x=cvRound((r->x+r->width*0.5)*scale);
            center.y=cvRound((r->y+r->height*0.5)*scale);
            radius=cvRound((r->width+r->height)*0.25*scale);

            cvCircle(img,center,radius,colors[i%8],3,8,0);
        }
    }

    cvShowImage("Result",img);
    cvReleaseImage(&gray);
    cvReleaseImage(&small_img);
}
    该代码功能就是识别图像中分类器中的东西,并且使用圆圈标记出来。你可以根据标记的位置来判断你的分类器精确度如何。完事儿喽,嘎嘎使用OpenCV创建分类器XML并测试效果

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值