opencv 人脸检测

请注意您首先要已配置好opencv环境,代码中视频路径换位自己的视频路径。

// oc22.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#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>  
  
  char filename[128];//存放截取人脸的文件名
  char num[128];//存放要在人脸图片中显示的数字
  int count = 1;//计截取的图片的数

static CvMemStorage* storage = 0;  
static CvHaarClassifierCascade* cascade = 0;  
  
void detect_and_draw( IplImage* image );  
  
const char* cascade_name =  
//"haarcascade_frontalface_alt.xml"; //opencv自带的特征分类器
"D:\\opencv\\sources\\data\\haarcascades\\haarcascade_upperbody.xml";
int _tmain(int argc, _TCHAR* argv[])
{
	 CvCapture* capture = 0;  
    IplImage *frame, *frame_copy = 0;  
  
    cascade = (CvHaarClassifierCascade*)cvLoad( cascade_name, 0, 0, 0 );  
  
     if( !cascade )  
    {  
       printf("No cascade!!!!\n");  
        return -1;  
    }  
    storage = cvCreateMemStorage(0);  
   // capture =  cvCaptureFromCAM( -1);//摄像头视频
   // capture = cvCaptureFromAVI("F:\\OPENCV实验室\\test.avi");//存好的视频文件   
  capture = cvCaptureFromFile("E:\\00012.avi" );
    cvNamedWindow( "result", 1 );  
  
    if( capture )  
    {  
        for(;;)  
        {  
            if( !cvGrabFrame( capture ))  
                break;  
            frame = cvRetrieveFrame( capture );  
            if( !frame )  
                break;  
            if( !frame_copy )  
				frame_copy = cvCreateImage( cvSize(frame->width,frame->height),  
                IPL_DEPTH_8U, frame->nChannels );  
            if( frame->origin == IPL_ORIGIN_TL )  
                  
				cvResize( frame, frame_copy, 1 );
            else  
                cvFlip( frame, frame_copy, 0 );  
  
            detect_and_draw( frame_copy );  
  
            if( cvWaitKey( 10 ) >= 0 )  
                break;  
        }  
  
        cvReleaseImage( &frame_copy );  
        cvReleaseCapture( &capture );  
    }  
	
	
    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}}  
    };  
    int addwid;//截取人头像时宽度增加 20141106
    int addhei;//截取人头像时高度增加 20141106
   double scale =1; 
    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 ); 
    int i;  


	//对图片的预处理,这里要慎重,不然可能影响人脸检测的效果,可根据实际情况决定
   cvCvtColor( img, gray, CV_BGR2GRAY );  //颜色空间转换,彩色转灰
	cvResize( gray, small_img, CV_INTER_LINEAR );//重新调整图像,CV_INTER_LINEAR是双线性插值(默认方法)  
   cvEqualizeHist( small_img, small_img );  //使灰度图象直方图均衡化
	//cvDilate(small_img,small_img,NULL,1);//膨胀
	//cvErode(small_img,small_img,NULL,1);//腐蚀
     //cvSmooth(small_img,small_img,CV_MEDIAN,3,0,0,0);//中值滤波

    cvClearMemStorage( storage );  
  
    if( cascade )  
    {  
        double t = (double)cvGetTickCount(); //从操作系统启动所经过的毫秒数 
        CvSeq* faces = cvHaarDetectObjects( small_img, cascade, storage,  
        1.2,2, CV_HAAR_DO_CANNY_PRUNING,cvSize(50,50) );  //找出人脸的矩形区域
        
        t = ((double)cvGetTickCount()-t); //人脸检测的用时 
        printf( "detection time = %gms\n", t/((double)cvGetTickFrequency()*1000.) );  
          //截图用
			IplImage * frame1 = cvCreateImage( cvSize(img->width,img->height), 
                IPL_DEPTH_8U, img->nChannels );
			 cvCopy( img, frame1, 0 );

        for( i = 0; i < (faces ? faces->total : 0); i++ )  
        {  
            CvRect* r = (CvRect*)cvGetSeqElem( faces, i );  

		     //截图
			if(r->x*scale-10<0||r->y*scale-10<0||frame1->width<r->x*scale+r->width*scale+10
				||frame1->height<r->y*scale+r->height+10)//判断截图是否越界 20141106
			 {
				 cvSetImageROI(frame1, cvRect(r->x* scale,r->y* scale,r->width* scale,r->height* scale));//越界时设置源图像ROI 20141106
			     addwid=0;
				 addhei=0;//越界时以获取的矩形区域截图 20141106
			 }
			else
			 {
				 cvSetImageROI(frame1, cvRect(r->x* scale-10,r->y* scale-10,r->width* scale+20,r->height* scale+20));//设置源图像ROI
			 //frame1指向ROI
			     addwid=20;
				 addhei=20;//非越界时在获取的矩形宽和高的基础上扩大一些 20141106
			 }
			
			IplImage* pDest = cvCreateImage(cvSize(r->width*scale+addwid,r->height* scale+addhei),8,3);//创建目标图像
			cvCopy(frame1,pDest,0); //复制图像
			 

             //在图片上书写数字
			 sprintf(num, "%d", count);
			CvFont font;
           cvInitFont( &font, CV_FONT_VECTOR0,0.5, 1, 0,2, 8);
		    CvSize text_size;
            int baseline;
           cvGetTextSize(num, &font, &text_size, &baseline);
          cvPutText(pDest, num , cvPoint(4,text_size.height+baseline), &font, CV_RGB(255,0,0));



            sprintf(filename, "img_%d.jpg", count++);
			 cvSaveImage(filename,pDest);//保存目标图像
             cvReleaseImage( &pDest );
			  cvResetImageROI(frame1);//使frame1指向源图像20141106
			
			  //用圆圈出人脸
            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.3*scale);  
            cvCircle( img, center, radius, colors[i%8], 2, 8, 0 ); 

			

        }  
		cvReleaseImage( &frame1 );//释放截图用
    }  
  
    cvShowImage( "result", img );  
    cvReleaseImage( &gray );  
    cvReleaseImage( &small_img );  
	
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值