Chinaunix首页 | 论坛 | 博客
  • 博客访问: 665031
  • 博文数量: 121
  • 博客积分: 4034
  • 博客等级: 上校
  • 技术积分: 1439
  • 用 户 组: 普通用户
  • 注册时间: 2010-04-28 12:42
文章分类

全部博文(121)

文章存档

2017年(8)

2016年(10)

2013年(2)

2012年(3)

2011年(18)

2010年(80)

分类: C/C++

2012-08-06 22:57:50

 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位的,灰色图片。
 
 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;
}
 

 
阅读(6236) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~