对facedetection程序的理解 --转载

 //要经过训练的,它的cascade 已经训练好了
//OpnenCV 例子应用:facedetect.c
#include "cv.h"
#include "highgui.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <math.h>
#include <float.h>
#include <limits.h>
#include <time.h>
#include <ctype.h>

// 为计算开辟内存
static CvMemStorage* storage = 0;

//建立一个新的haar 分类器
static CvHaarClassifierCascade* cascade = 0;

//子函数声明从图像中检测出物体
void detect_and_draw( IplImage* image );

//建立一个字符串,包含cascade的名字,这个应该是训练的地方
const char* cascade_name =
  "haarcascade_frontalface_alt.xml";
//   "haarcascade_profileface.xml";

//主函数,函数的入口地址
int main( int argc, char** argv )
{

    //建立从video 或者avi中得到图像的结构
  CvCapture* capture = 0;

    //结构转换成的图像
  IplImage *frame, *frame_copy = 0;

    //定义整形的int用于计算
  int optlen = strlen("--cascade=");

    //从avi或者图像文件输入的文件名
  const char* input_name;

    //检查正确的命令行的使用
  if( argc > 1 && strncmp( argv[1], "--cascade=", optlen ) == 0 )
  {
    cascade_name = argv[1] + optlen;
    input_name = argc > 2 ? argv[2] : 0;
  }
  else
  {
    fprintf( stderr,
    "Usage: facedetect --cascade=/"<cascade_path>/" [filename|camera_index]/n" );
    return -1;
    //input_name = argc > 1 ? argv[1] : 0;
  }

    //装载haar分类器
  cascade = (CvHaarClassifierCascade*)cvLoad( cascade_name, 0, 0, 0 );
 
    //检测cascade加载是否成功
  if( !cascade )
  {
    fprintf( stderr, "ERROR: Could not load classifier cascade/n" );
    return -1;
  }
 
    //确定内存大小默认64k
  storage = cvCreateMemStorage(0);
 
    //确定是否目标来自文件或摄像头
  if( !input_name || (isdigit(input_name[0]) && input_name[1] == '/0') )
    capture = cvCaptureFromCAM( !input_name ? 0 : input_name[0] - '0' );
  else
    capture = cvCaptureFromAVI( input_name );

    //建立一个新的window窗口,以result命名
  cvNamedWindow( "result", 1 );

    //看看capture是否成功加载

  // If loaded succesfully, then:
    //如果成功加载,则:
  if( capture )
  {
    // Capture from the camera.
    for(;;)
    {
              //捕获一针,并存到图像中
        if( !cvGrabFrame( capture ))
          break;
        frame = cvRetrieveFrame( capture );
             
              //如果针不存在,退出循环
        if( !frame )
          break;
       
              //分配图像和frame一样大小 frame->nChannels
        if( !frame_copy )
          frame_copy = cvCreateImage( cvSize(frame->width,frame->height),
                            IPL_DEPTH_8U, frame->nChannels );

              //确定图像原点,如果是顶左结构,拷贝图像
        if( frame->origin == IPL_ORIGIN_TL )
          cvCopy( frame, frame_copy, 0 );
              //反转图像,沿x轴
        else
          cvFlip( frame, frame_copy, 0 );
       
              //调用函数确定脸的位置
        detect_and_draw( frame_copy );

              //在处理下一针前等待一会儿
        if( cvWaitKey( 10 ) >= 0 )
          break;
    }

        //释放图像和捕获针的内存
    cvReleaseImage( &frame_copy );
    cvReleaseCapture( &capture );
  }

    //如果捕获没有成功,则
  else
  {
        //假设图像是lena.jpg 或者特定的输入
    const char* filename = input_name ? input_name : (char*)"lena.jpg";

        //加载文件图像
    IplImage* image = cvLoadImage( filename, 1 );

        //如果图像成功加载,则调用处理函数
    if( image )
    {
        // Detect and draw the face
        detect_and_draw( image );

        // Wait for user input
              //等待。。。。
        cvWaitKey(0);

        // Release the image memory
              //释放内存
        cvReleaseImage( &image );
    }
    else
    {
              //假定它是一个文档类的文件包含要被处理图像名称,每行一个
        FILE* f = fopen( filename, "rt" ); //以读的形式打开
        if( f )
        {
          char buf[1000+1];

          while( fgets( buf, 1000, f ) )//从f中读取1000个数据
          {

                      //从中移去空格并且确定名字长度
            int len = (int)strlen(buf);
            while( len > 0 && isspace(buf[len-1]) ) //判断是否为空格
                len--;
            buf[len] = '/0';
                     
                      //加载确定名字的图像
            image = cvLoadImage( buf, 1 );

                      //如果文件加载成功,则
            if( image )
            {
                // Detect and draw the face from the image
                            //检测图像
                detect_and_draw( image );
               
                // Wait for the user input, and release the memory
                            //waiting....
                cvWaitKey(0);
                cvReleaseImage( &image );
            }
          }
          // Close the file
                  //既然打开文件,就要关闭它
          fclose(f);
        }
    }

  }
 
    //销毁窗口
  cvDestroyWindow("result");
    //返回一个成功的标志 yeah
  return 0;
}

// Function to detect and draw any faces that is present in an image
//检测的子函数——这种方法真的好
void detect_and_draw( IplImage* img )
{
  int scale = 1;

    //创建一个基于输入图像的新的图像
  IplImage* temp = cvCreateImage( cvSize(img->width/scale,img->height/scale), 8, 3 );

    //确定两个点来确定人脸位置,因为用cvRetangle嘛
  CvPoint pt1, pt2;
  int i;

    //在使用之前,清空内存
  cvClearMemStorage( storage );

    //看cascade是否被加载,如果加载,则
  if( cascade )
  {


    //也许图像中,有不止一个face,所以创建一增长的face序列
//检测并将其存储在序列中
    CvSeq* faces = cvHaarDetectObjects( img, cascade, storage,
                            1.1, 2, CV_HAAR_DO_CANNY_PRUNING,
                            cvSize(40, 40) );

    // Loop the number of faces found.
        //循环发现的face
    for( i = 0; i < (faces ? faces->total : 0); i++ )
    {
      // Create a new rectangle for drawing the face
              //在脸上画一个矩形
        CvRect* r = (CvRect*)cvGetSeqElem( faces, i );//返回索引所指定的元素指针
辛苦的工作,快乐的生活
              //找到画矩形的两个点
        pt1.x = r->x*scale;
        pt2.x = (r->x+r->width)*scale;
        pt1.y = r->y*scale;
        pt2.y = (r->y+r->height)*scale;

        // Draw the rectangle in the input image
              //画出矩形
        cvRectangle( img, pt1, pt2, CV_RGB(255,0,0), 3, 8, 0 );
    }
  }

  // Show the image in the window named "result"
  cvShowImage( "result", img );

  // Release the temp image created.
  cvReleaseImage( &temp );
}
 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值