📄 main.c
字号:
#ifdef _CH_
#define WIN32
#error "The file needs cvaux, which is not wrapped yet. Sorry"
#endif
#ifndef _EiC
#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>
#include <direct.h>
#endif
#ifdef _EiC
#define WIN32
#endif
#define MARGIN 15 // add margin to the detect face window
int imageCount=0; // image index for storing clipped faces
char strImageDir[255]; // directory for face images to be clipped
char strPersonName[255]; // person name, used for locating the directory
char strFilePrefix[255]; // image prefix for the stored images
int startFrame=0; //start frame number
int endFrame=50; //end frame number
int bSaveFaces; // toggle for saving faces
int bFirstFace = 1; // flag for first face
static CvMemStorage* storage = 0;
static CvHaarClassifierCascade* cascade = 0;
void FindFaces( IplImage* image );
void SaveFace(IplImage* src, int x, int y, int w, int h);
int bFindFromImageSeq = 0;
const char* cascade_name =
"--cascade=../../data/haarcascades/haarcascade_frontalface_alt.xml";
char *ReadConfigLine(FILE *fp){
char line[255];
char c;
int idx=0;
line[0]='\0';
while(!feof(fp)){
if(fgetc(fp)=='=')break;
}
while(!feof(fp)&&(c=fgetc(fp))!='\n'){
line[idx++]=c;
}
line[idx]='\0';
return line;
}
void loadconfig(char *configFilename){
FILE *fp;
char strStartFrame[255];
char strEndFrame[255];
if(!(fp=fopen(configFilename,"r"))){
printf("Cannot load config.ini!\nexiting.......\n");
exit(0);
}
strcpy(strImageDir, ReadConfigLine(fp));
printf("source dir:%s\n", strImageDir);
strcpy(strPersonName, ReadConfigLine(fp));
printf("source person:%s\n", strPersonName);
strcpy(strFilePrefix, ReadConfigLine(fp));
printf("source prefix:%s\n", strFilePrefix);
strcpy(strStartFrame, ReadConfigLine(fp));
startFrame=atoi(strStartFrame);
printf("start frame:%d\n", startFrame);
strcpy(strEndFrame, ReadConfigLine(fp));
endFrame=atoi(strEndFrame);
printf("end frame:%d\n", endFrame);
printf("config loaded....\n");
fclose(fp);
}
int main( int argc, char** argv )
{
CvCapture* capture = 0;
IplImage *frame, *frame_copy = 0;
const char *pName;
char input[255];
const char *input_name;
char filename[255];
char dirname[255];
int optlen = strlen("--cascade=");
int c, i;
pName = argc > 1 ? argv[1] : 0;
if(argc>1){
sprintf(input, "%s.avi", pName);
input_name = input;
}
else
input_name = 0;
cascade_name = cascade_name+optlen;
cascade = (CvHaarClassifierCascade*)cvLoad( cascade_name, 0, 0, 0 );
if( !cascade )
{
fprintf( stderr, "ERROR: Could not load classifier cascade\n" );
return -1;
}
loadconfig("config.ini");
if(argc>1){
sprintf(strPersonName, "%s", pName);
//create directory
sprintf(dirname, "%s\\%s", strImageDir, strPersonName);
_mkdir(dirname);
}
storage = cvCreateMemStorage(0);
cvNamedWindow( "Video", 1 );
//check if find faces from a sequnce of images
if(bFindFromImageSeq){
for(i=0; i<200; i++){
sprintf(filename, "%s\\%s\\%s%03d.jpg", strImageDir, strPersonName, strFilePrefix, i);
printf(filename);
printf("\n");
frame = cvLoadImage(filename, 1);
FindFaces( frame );
c = cvWaitKey(10);
switch( c )
{
case '\x1b':
printf("Exiting ...\n");
goto exit_main;
case 's':
bSaveFaces = !bSaveFaces;
printf("face clipping: %d\n", bSaveFaces);
break;
}
}
}
if( !input_name || (isdigit(input_name[0]) && input_name[1] == '\0') ){
capture = cvCaptureFromCAM( !input_name ? 0 : input_name[0] - '0' );
bSaveFaces = 0; //let user start the clipping face process
}
else{
capture = cvCaptureFromAVI( input_name );
bSaveFaces = 1; //auto start clipping face process
}
printf("press \'s\' to toggle the face clipping process...\n");
printf("face clipping: %d\n", bSaveFaces);
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 )
cvCopy( frame, frame_copy, 0 );
else
cvFlip( frame, frame_copy, 0 );
FindFaces( frame_copy );
c = cvWaitKey(10);
switch( c )
{
case '\x1b':
printf("Exiting ...\n");
goto exit_main;
case 's':
bSaveFaces = !bSaveFaces;
printf("face clipping: %d\n", bSaveFaces);
break;
}
}
cvReleaseImage( &frame_copy );
cvReleaseCapture( &capture );
}
else
{
printf("FindFaces: extracts faces from live cams or avi videos.\n");
printf(" syntax: FacesFaces [filename.avi]\n");
printf(" neither live cams nor avi videos are found.\n");
printf(" exiting.....\n");
}
exit_main:
cvDestroyWindow("Video");
return 0;
}
void SavePgm(IplImage *gray, char *filename){
FILE *fp;
int i, j;
if(!(fp=fopen(filename, "wb"))){
printf("Cannot write to file\n");
exit(0);
}
fprintf(fp, "P5\n%d %d\n255\n", gray->height, gray->width);
for(j=0;j<gray->height; j++){
for(i=0; i<gray->width; i++){
fputc((gray->imageData[j*gray->widthStep+i])&255,fp);
}
}
fclose(fp);
}
void SaveFace( IplImage* src, int x, int y, int w, int h){
IplImage *target, *gray;
char filename[255];
int i,j,x2,y2;
if(!w || !h) return;
//adjust window size to include more of the face
x2=x+w; y2=y+h;
if(x-MARGIN>=0)
x=x-MARGIN;
else
x=0;
if(y-MARGIN>=0)
y=y-MARGIN;
else
y=0;
if(x2+MARGIN<src->width)
x2=x2+MARGIN;
else
x2=src->width-1;
if(y2+MARGIN<src->height)
y2=y2+MARGIN;
else
y2=src->height-1;
w = x2-x;
h = y2-y;
// create target image
target = cvCreateImage( cvSize(w,h), 8, 3 );
gray = cvCreateImage(cvSize(w,h), 8, 1);
for (i=y; i<y+h; i++){
for (j=x; j<x+w; j++){
target->imageData[(i-y)*target->widthStep+(j-x)*3]=
src->imageData[i*src->widthStep+j*3];
target->imageData[(i-y)*target->widthStep+(j-x)*3+1]=
src->imageData[i*src->widthStep+j*3+1];
target->imageData[(i-y)*target->widthStep+(j-x)*3+2]=
src->imageData[i*src->widthStep+j*3+2];
}
}
sprintf(filename, "%s\\%s\\%s%03d.pgm", strImageDir, strPersonName, strPersonName, imageCount++);
cvCvtColor(target, gray, CV_BGR2GRAY);
/*
if(!(fp=fopen(filename, "wb"))){
printf("Cannot write to file\n");
exit(0);
}
fprintf(fp, "P5\n%d %d\n255\n", gray->height, gray->width);
//for(j=0;j<gray->widthStep*gray->height; j++){
fwrite(gray->imageData, gray->widthStep*gray->height, 1, fp);
fclose(fp);
*/
SavePgm(gray, filename);
if(bFirstFace){
sprintf(filename, "%s\\%s\\%s.jpg", strImageDir, strPersonName, strPersonName);
cvSaveImage(filename, target);
bFirstFace = 0;
}
}
void FindFaces( IplImage* img )
{
int scale = 1;
CvPoint pt1, pt2;
int i;
cvClearMemStorage( storage );
if( cascade )
{
CvSeq* faces = cvHaarDetectObjects( img, cascade, storage,
1.1, 2, CV_HAAR_DO_CANNY_PRUNING,
cvSize(40, 40) );
for( i = 0; i < (faces ? faces->total : 0); i++ )
{
CvRect* r = (CvRect*)cvGetSeqElem( faces, i );
if(r->width>85 && r->height>85){
pt1.x = r->x*scale;
pt2.x = (r->x+r->width)*scale;
pt1.y = r->y*scale;
pt2.y = (r->y+r->height)*scale;
if(bSaveFaces)
SaveFace(img, pt1.x, pt1.y, r->width, r->height);
cvRectangle( img, pt1, pt2, CV_RGB(255,0,0), 3, 8, 0 );
//just handle one face per frame,ignore the others
break;
}
}
}
cvShowImage( "Video", img);
}
#ifdef _EiC
main(1,"main.c");
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -