📄 facedetect.cpp
字号:
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "cvfltk.h"
#include "highgui.h"
#include "cv.h"
#include "cvaux.h"
#include <string.h>
#include <stdio.h>
#include <math.h>
#include <limits.h>
class VideoWindow;
char outputFileName[5000];
bool interactiveRun;
FILE* outf;
Fl_Window *root_window=(Fl_Window *)0;
VideoWindow* video_window = 0;
CvCapture* capture = 0;
CvAVIWriter* writer = 0;
static int started = 0;
int numScales = 1;
double timeout = 0.005;
IplImage* video_image = 0;
double old_pos = 0;
Fl_Value_Slider* video_pos = 0;
int guard = 0;
int is_avi = 0;
int is_recorded = 0;
double fps = -1;
double fps_alpha = 0.1;
char fps_buffer[100];
double cpu_freq = 0;
double prev_frame_stamp = 0;
int start_pos = 0;
int total_frames0 = 0;
int total_frames = 0;
int is_loopy = 0;
Fl_Button* stop_button = 0;
Fl_Button* play_button = 0;
Fl_Button* video_button = 0;
Fl_Button* cam_button = 0;
Fl_Button* record_button = 0;
Fl_Box* fps_box = 0;
#define ORIG_WIN_SIZE 24
#define MIN_NEIGHBORS 2
static CvHidHaarClassifierCascade* hid_cascade = 0;
int InitFaceDetect( const char* classifier_cascade_path )
{
CvHaarClassifierCascade* cascade = cvLoadHaarClassifierCascade(
classifier_cascade_path && strlen(classifier_cascade_path) > 0 ?
classifier_cascade_path : "<default_face_cascade>",
cvSize( ORIG_WIN_SIZE, ORIG_WIN_SIZE ));
if( !cascade )
return 0;
hid_cascade = cvCreateHidHaarClassifierCascade( cascade );
cvReleaseHaarClassifierCascade( &cascade );
return 1;
}
void DetectAndDrawFaces( IplImage* img )
{
//scale shifts from 2 to 1 to .5
double scales[3];
static int frameNumber = 0;
scales[0] = 2;
scales[1] = 1;
scales[2] = .5;
double scale;
bool foundFace = false;
frameNumber++;
if( hid_cascade && img )
{
for (int scaleIndex = 0; scaleIndex < numScales; scaleIndex++) {
//if a face was not found last frame then look at different scales for faces
scale = scales[scaleIndex];
CvSize img_size = cvGetSize( img );
IplImage* temp = cvCreateImage( cvSize(img_size.width/scale,img_size.height/scale), 8, 3 );
IplImage* canvas = cvCreateImage( cvSize(temp->width,temp->height*3/2), 8, 3 );
CvPoint offset = cvPoint( 0, temp->height/3 );
int i;
if ( scale > 1 ) {
cvPyrDown( img, temp );
}
else if ( scale < 1 ) {
cvPyrUp( img, temp );
}
else if ( fabs(scale-1.0) < ZERO_VALUE ) {
//do not pyramid either way leave it alone
//temp = cvCloneImage(img);
cvCopy(img,temp,0);
}
cvZero( canvas );
CvMemStorage* storage = cvCreateMemStorage(0);
//cvClearMemStorage( storage );
//offset.x = 0;
//offset.y = 0;
cvSetImageROI( canvas, cvRect( offset.x, offset.y, temp->width, temp->height ));
cvCopy( temp, canvas );
cvResetImageROI( canvas );
if( hid_cascade )
{
//these are "tuned" yet slower though i don't see much better results;
//1.1 3 0 were given in the open cv manual i am playing with them more
CvSeq* faces = cvHaarDetectObjects( canvas, hid_cascade, storage, 1.1, 3, 0 );
for( i = 0; i < (faces ? faces->total : 0); i++ )
{
CvRect r = *(CvRect*)cvGetSeqElem( faces, i );
r.x -= offset.x;
r.y -= offset.y;
cvRectangle( img,
cvPoint(r.x*scale,/*img->height - */r.y*scale),
cvPoint((r.x+r.width)*scale,/*img->height - */(r.y+r.height)*scale),
CV_RGB(0,255,0), 2 );
if ( outf != NULL ) {
fprintf(outf,"x1= %lf y1= %lf x2= %lf y2= %lf frameNumber= %d ",
r.x*scale, r.y*scale,(r.x+r.width)*scale,(r.y+r.height)*scale,
frameNumber);
}
printf("x1= %lf y1= %lf x2= %lf y2= %lf frameNumber= %d ",
r.x*scale, r.y*scale,(r.x+r.width)*scale,(r.y+r.height)*scale,
frameNumber);
}
if ( faces->total > 0 ) {
if ( scaleIndex == 0 ) {
printf("leave early in %d\n",frameNumber);
}
foundFace = true;
}
}
cvReleaseMemStorage(&storage);
cvReleaseImage( &temp );
cvReleaseImage( &canvas );
if ( foundFace ) {
break;
}
}
if ( !foundFace && outf != NULL) {
fprintf(outf,"**** frameNumber= %d DATA NOT AVAILABLE",frameNumber);
}
if ( outf != NULL ) {
fprintf(outf,"\n");
}
printf("\n");
}
}
class VideoWindow : public Fl_Box
{
public:
VideoWindow( int x, int y, int w, int h, const char* t = 0 );
~VideoWindow();
void draw();
};
VideoWindow::VideoWindow( int x, int y, int w, int h, const char* t ):
Fl_Box( x, y, w, h, t )
{
}
VideoWindow::~VideoWindow()
{
}
void VideoWindow::draw()
{
}
static void end_capture()
{
started = 0;
cvReleaseCapture( &capture );
}
static void cb_Stop( Fl_Widget*, void* );
static void cb_StartStopRecord( Fl_Widget*, void* );
static void cb_Exit( Fl_Widget*, void* );
static double get_time_accurate(void)
{
return (double)cvGetTickCount()*1e-3/(cpu_freq+1e-10);
}
static void get_next_frame(void*)
{
static int repositioning = 0;
IplImage* frame = 0;
double new_pos = video_pos->value();
if( (new_pos-old_pos >= 1e-10 || new_pos-old_pos <= -1e-10) && !repositioning)
{
video_window->redraw();
cvSetCaptureProperty( capture, CV_CAP_PROP_POS_AVI_RATIO, new_pos );
new_pos = cvGetCaptureProperty( capture, CV_CAP_PROP_POS_AVI_RATIO );
printf("Repositioning\n");
repositioning = 1;
}
else
{
new_pos = cvGetCaptureProperty( capture, CV_CAP_PROP_POS_AVI_RATIO );
video_pos->value(new_pos);
repositioning = 0;
}
old_pos = new_pos;
frame = cvQueryFrame( capture );
if( frame == 0 && is_avi )
{
cb_Stop(0,0);
return;
}
if( video_window && frame )
{
if( video_window->w() < frame->width || video_window->h() < frame->height )
root_window->size( (short)(frame->width + 40), (short)(frame->height + 150));
CvRect rect = { video_window->x(), video_window->y(),
frame->width, frame->height };
if( !video_image || video_image->width < rect.width ||
video_image->height < rect.height )
{
cvReleaseImage( &video_image );
video_image = cvCreateImage( cvSize( rect.width, rect.height ), 8, 3 );
}
cvSetImageROI( video_image, cvRect(0,0,rect.width, rect.height));
//video_image= cvCloneImage(frame);
if( frame->origin == 1 )
cvFlip( frame, video_image, 0 );
else
cvCopy( frame, video_image, 0 );
DetectAndDrawFaces( video_image );
if( writer && is_recorded )
{
cvWriteToAVI( writer, video_image );
}
cvCvtColor( video_image, video_image, CV_RGB2BGR );
uchar* data = 0;
int step = 0;
CvSize size;
cvGetRawData( video_image, &data, &step, &size );
video_window->redraw();
fl_draw_image( (uchar*)data, video_window->x(), video_window->y(),
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -