opencv 星空_OPENCV CvHaar 使用

本文介绍了如何使用OpenCV的CvHaarClassifierCascade进行星空对象的检测。首先,通过opencv_createsamples和opencv_haartraining创建样本文件,然后详细讲解了训练过程。接着展示了如何加载XML文件并检测图像中的目标对象,提供了相关代码实例。
摘要由CSDN通过智能技术生成

1. 创建xml文件

创建xml文件需要两个命令,在新版的opencv,命令名字为:opencv_createsamples和opencv_haartraining

(1)创建样本

命令格式:

opencv_createsamples.exe -vec pic.vec -info zheng\zhenglist.txt -bg fu\fulist.txt -num 20 -w 100 -h 20

-vec 生成样本的名字,-info 正样本的图片列表,-bg 负样本的图片列表, -num 正样本的名字, -w 和 -h 正样本需要统一的高度和宽度。

zhenglist.txt正样本的文件的格式:

cv_1.jpg 1 0 0 100 20

图片的名字,1代表一个样本, 图片的有效范围为从(0,0)开始到(100,20)结束,所以,在之前就必须把图片转换成100*20的,而且还是8位的,不能使彩色的。

所以为了方便,我也提供的一个命令去转换图片。

picoperate.exe放在样本的所在目录下,直接执行,PicList.txt是需要处理的图片列表,必须为这个名字,处理完成后的图片名字会在原来名字之前添加一个“cv_”字符串,如原来为1.jpg转换后变为cv_1.jpg。

需要注意的是,负样本对大小没有要求,最好也是8位的,灰色图片。

zip.gif picoperate.zip

(2)训练样本

命令格式 :

opencv_haartraining.exe -data car -vec pic.vec -bg fu\fulist.txt -w 100 -h 20 -mem 800 -mode all -npos 20 -nneg 20

-data 输出名字,如果名字为car,最后结果为car.xml, -vec 样本的名字,就是上一步使用命令opencv_createsamples创建的文件,

-bg 负样本的文件列表,-w和-h也是正样本的大小。

-npos 是正样本的个数,-nneg 是负样本的个数。

如果样本很多的话这一步需要很多时间。

2. 样本的使用

1.load xml 文件

static CvHaarClassifierCascade *cascade = 0;

cascade = (CvHaarClassifierCascade*)cvLoad(cascade_name, 0, 0, 0 );

if( !cascade )

{

printf("load car.xml fail.\n");

return -1;

}

2. 开始检查

CvSeq* faces = cvHaarDetectObjects( img, cascade, storage,

1.1, 2, 0

//|CV_HAAR_FIND_BIGGEST_OBJECT

//|CV_HAAR_DO_ROUGH_SEARCH

|CV_HAAR_DO_CANNY_PRUNING

//|CV_HAAR_SCALE_IMAGE

,

cvSize(30, 30) );

3. 一个实例

#include "stdafx.h"

#include "cv.h"

#include "highgui.h"

#include #include #include #include #include #include #include #include #include

static CvMemStorage* storage = 0;

static CvHaarClassifierCascade *cascade = 0;

int use_nested_cascade = 0;

void detect_and_draw( IplImage* image );

const char* cascade_name = "car.xml";

double scale = 1;

int resizepic(IplImage *src, IplImage **img)

{

int time;

int widthabout = 300;

time = src->width / widthabout;

printf("width=%d,height=%d.\n", src->width, src->height);

if(time == 0)

{

if(src->width < (widthabout>>2))

{

time =  widthabout / src->width;

*img = cvCreateImage(cvSize(src->width*time, src->height*time), src->depth, src->nChannels);

}

else

{

*img = cvCreateImage(cvSize(src->width, src->height), src->depth, src->nChannels);

cvCopy(src, *img);

goto RESIZEEND;

}

}

else

{

*img = cvCreateImage(cvSize(src->width/time, src->height/time), src->depth, src->nChannels);

}

cvResize(src, *img, CV_INTER_LINEAR);

//IplImage *pyr = cvCreateImage(cvSize(src->width/2/time, src->height/2/time), src->depth, src->nChannels);

//cvPyrDown(*img, pyr, 7);

//cvPyrUp(pyr, *img, 7);

RESIZEEND:

//cvNamedWindow("ResizeSource");

//cvShowImage("ResizeSource", *img );

//cvMoveWindow("ResizeSource", 20, 100);

return 0;

}

int findcar(char *filename )

{

CvCapture* capture = 0;

IplImage *image, *src;

storage = cvCreateMemStorage(0);

cascade = (CvHaarClassifierCascade*)cvLoad(cascade_name, 0, 0, 0 );

if( !cascade )

{

printf("load car.xml fail.\n");

return -1;

}

image = cvLoadImage( filename, 0 );

resizepic(image, &src);

cvNamedWindow( "source", 1 );

//cvShowImage("source", src);

detect_and_draw(src);

cvDestroyWindow("source");

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}}

};

int i, j;

cvEqualizeHist(img, img);

//cvClearMemStorage( storage );

if(cascade)

{

double t = (double)cvGetTickCount();

CvSeq* faces = cvHaarDetectObjects( img, cascade, storage,

1.1, 2, 0

//|CV_HAAR_FIND_BIGGEST_OBJECT

//|CV_HAAR_DO_ROUGH_SEARCH

|CV_HAAR_DO_CANNY_PRUNING

//|CV_HAAR_SCALE_IMAGE

,

cvSize(30, 30) );

t = (double)cvGetTickCount() - t;

printf( "detection time = %gms\n", t/((double)cvGetTickFrequency()*1000.) );

for( i = 0; i < (faces ? faces->total : 0); i++ )

{

CvRect* r = (CvRect*)cvGetSeqElem( faces, i );

printf("rect is (%d,%d,%d,%d)\n", r->x, r->y, r->width, r->height);

cvRectangle (

img,

cvPoint(r->x,r->y),

cvPoint(r->x+r->width,r->y+r->height),

cvScalar(0x0,0x00,0x00)    /* red */

);

}

}

cvShowImage( "source", img );

cvWaitKey(0);

}

char *strip(char *str)

{

char *cp = str ;

char *p = str ;

int len = strlen(str);

int i;

if (cp == NULL || *cp == '\0')

{

return NULL;

}

cp = cp + len;

while(cp > str)

{

cp--;

if ((*cp == ' ') || (*cp == '\t') || (*cp == '\n'))

*cp = '\0';

else

break;

}

for (cp = str; (*cp == ' ') || (*cp == '\t') || (*cp == '\n'); cp++);

len = strlen(cp);

for(i=0;i{

*p = *cp;

p++;

cp++;

}

*p='\0';

return str;

}

int _tmain(int argc, _TCHAR* argv[])

{

FILE* fp = fopen( "PicList.txt", "r" );

char picname[256] = {0};

int ret;

if(!fp)

{

printf("Can not open PicList.txt.\n");

return -1;

}

while (!feof(fp))

{

memset(picname, 0, sizeof(picname));

fgets(picname, 128, fp);

strip(picname);

if (picname[0] == '#' || strlen(picname) <= 1)

continue;

printf("picName is %s.\n", picname);

ret = findcar(picname);

if(ret<0)

{

break;

}

}

fclose(fp);

return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值