#include <opencv/cv.hpp>
#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; //创建一个内存存储器,来统一管理各种动态对象的内存
static CvHaarClassifierCascade* cascade = 0; //分类器
void detect_and_draw( IplImage* image ); //检测人脸并标记
const char* cascade_name =
"haarcascade_frontalface_alt_tree.xml"; //分类器名称
int main( int argc, char** argv )
{
CvCapture* capture = 0; //视频的结构体
IplImage *frame, *frame_copy = 0; //读取每一帧的结构体
cascade = (CvHaarClassifierCascade*)cvLoad( cascade_name, 0, 0, 0 ); //载入分类器
if( !cascade )
{
fprintf( stderr, "ERROR: Could not load classifier cascade\n" );
fprintf( stderr,
"Usage: facedetect --cascade=\"<cascade_path>\" [filename|camera_index]\n" );
return -1;
}
storage = cvCreateMemStorage(0);
cvNamedWindow( "result", 1 ); //1表示autosize
//检测视频
capture = cvCaptureFromCAM(-1); //调用摄像头
if( capture )
{
for(;;)
{
if( !cvGrabFrame( capture )) //从摄像头或者视频文件中抓取帧
break;
frame = cvRetrieveFrame( capture ); //取回由函数cvGrabFrame抓取的图像
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 ) //图像顶点是否在顶-左
cvCopy( frame, frame_copy, 0 );
else
cvFlip( frame, frame_copy, 0 ); //翻转
IplImage *equ = cvCreateImage(cvGetSize(frame_copy),8, 1);
IplImage *gray = cvCreateImage(cvGetSize(frame_copy), 8, 1);
cvCvtColor(frame_copy, gray, CV_BGR2GRAY); //转灰度图
cvEqualizeHist(gray, equ); //直方图均衡化
//cvNamedWindow("yuantu");
//cvNamedWindow("equ");
//cvShowImage("yuantu",gray);
//cvShowImage("equ",equ);
detect_and_draw( frame_copy ); //人脸检测并标记
if( cvWaitKey(1) >= 0 )
break;
//cvReleaseImage(&gray);
//cvReleaseImage(&equ);
}
cvReleaseImage( &frame_copy );
cvReleaseCapture( &capture );
}
cvWaitKey(-1); //检测图片的时候,等待显示
cvDestroyWindow("result");
return 0;
}
void detect_and_draw( IplImage* img )
{
static CvScalar colors[] = //用8种颜色标记人脸
{
{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.2; //缩放因子
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 ); //调整大小
cvEqualizeHist( small_img, small_img ); //使灰度图象直方图均衡化
cvClearMemStorage( storage ); //重置
if( cascade )
{
double t = (double)cvGetTickCount(); //返回从操作系统启动所经过的毫秒数
CvSeq* faces = cvHaarDetectObjects( small_img, cascade, storage,
1.1, 2, 0/*CV_HAAR_DO_CANNY_PRUNING*/,
cvSize(30, 30) );
printf("face's total is %d\n",faces->total);
t = (double)cvGetTickCount() - t;
printf( "detection time = %gms\n", t/((double)cvGetTickFrequency()*1000.) ); //cvGetTickFrequency()返回每秒的计时周期数
for( i = 0; i < (faces ? faces->total : 0); i++ )
{
CvRect* r = (CvRect*)cvGetSeqElem( faces, i );
CvRect tr(r->x,r->y,r->width,r->height);
//用矩形框框出
cvRectangle(img, cvPoint(r->x * scale, r->y * scale), cvPoint( (r->x + r->width) * scale, (r->y + r->height) * scale), colors[i%8], 3, 8, 0);
//用原型框出
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 );
//用ROI截取人脸区域
cvSetImageROI(small_img, tr); //用缩放后的图,设置源图像ROI
CvSize size1 = cvSize(r->width, r->height);
IplImage* roi_img = cvCreateImage(size1,small_img->depth,small_img->nChannels);
cvCopy(small_img,roi_img); //复制图像
cvResetImageROI(small_img); //源图像用完后,清空ROI
cvNamedWindow("picture", CV_WINDOW_AUTOSIZE);
cvShowImage("picture", roi_img);
//cvReleaseImage( &roi_img );
//cvDestroyWindow("picture");
}
}
cvShowImage( "result", img );
cvReleaseImage( &gray );
cvReleaseImage( &small_img );
}
OpenCV人脸检测
最新推荐文章于 2024-08-13 14:17:45 发布