⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 facedetect.cpp

📁 人脸检测领域经典的Haar人脸检测。使用OpenCV.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*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 + -