//要经过训练的,它的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 );
}
//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 );
}