📄 main.c
字号:
/*
* EyeTracking 1.0 - Display video from webcam and track user's eye with
* manually selected template.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @author Nashruddin Amin <me@nashruddin.com>
* @copyright Nashruddin Amin 2008
* @license GNU General Public License 3.0
* @version 1.0
* @website http://www.nashruddin.com
*/
#include "main.h"
int main( int argc, char** argv )
{
CvCapture *capture;
int key;
display_info();
/* initialize webcam */
capture = cvCaptureFromCAM( 0 );
/* always check */
if( !capture ) {
fprintf( stderr, "Cannot initialize webcam!\n" );
return 1;
}
/* test camera */
if( !cvGrabFrame( capture ) ) {
fprintf( stderr, "Could not grab a frame!\n" );
return 1;
}
/* get a frame to get video properties, needed by template image */
frame = cvRetrieveFrame( capture );
/* create template image */
tpl = cvCreateImage( cvSize( TPL_WIDTH, TPL_HEIGHT ),
frame->depth, frame->nChannels );
/* image for template matching result */
match_res = cvCreateImage( cvSize( 2 * SEARCH_RANGE_X + 1,
2 * SEARCH_RANGE_Y + 1 ),
IPL_DEPTH_32F, 1 );
/* create GUI */
cvNamedWindow( "video", CV_WINDOW_AUTOSIZE );
cvShowImage( "video", frame );
/* install mouse hander */
cvSetMouseCallback( "video", mouse_handler, NULL );
while( TRUE ) { /* display forever */
if( !cvGrabFrame( capture ) ) {
fprintf( stderr, "Could not grab a frame!\n" );
return 1;
}
/* get a frame */
frame = cvRetrieveFrame( capture );
/* 'fix' frame */
cvFlip( frame, frame, -1 );
frame->origin = 0;
/* track object if template has been selected */
if( state == STATE_TRACKING ) {
track_object();
}
/* display video */
cvShowImage( "video", frame );
/* exit if user press a key */
if( ( key = cvWaitKey( 1 ) ) >= 0 ) {
goto done;
}
}
done:
/* free memory */
cvDestroyWindow( "video" );
cvReleaseCapture( &capture );
return 0;
}
/**
* mouse handler
*/
void mouse_handler( int event, int x, int y, int flags, void *param )
{
if( event == CV_EVENT_LBUTTONUP ) {
object_x0 = x - ( TPL_WIDTH / 2 );
object_y0 = y - ( TPL_HEIGHT / 2 );
object_x0_ini = object_x0;
object_y0_ini = object_y0;
/* extract template from frame */
cvSetImageROI( frame, cvRect( object_x0,
object_y0,
TPL_WIDTH,
TPL_HEIGHT ) );
cvCopy( frame, tpl, NULL );
cvResetImageROI( frame );
/* template has been extracted, start tracking! */
state = STATE_TRACKING;
}
}
/**
* function to track object
*/
void track_object()
{
int win_x0, win_y0, win_x1, win_y1;
CvPoint minloc, maxloc;
double minval, maxval;
/* setup search window */
win_x0 = object_x0 - SEARCH_RANGE_X;
win_y0 = object_y0 - SEARCH_RANGE_Y;
win_x1 = win_x0 + TPL_WIDTH + ( 2 * SEARCH_RANGE_X );
win_y1 = win_y0 + TPL_HEIGHT + ( 2 * SEARCH_RANGE_Y );
/* make sure the window still inside the frame */
if( win_x0 < 0 ) {
win_x0 = 0;
win_x1 = TPL_WIDTH + ( 2 * SEARCH_RANGE_X );
}
if( win_y0 < 0 ) {
win_y0 = 0;
win_y1 = TPL_HEIGHT + ( 2 * SEARCH_RANGE_Y );
}
if( win_x1 > frame->width ) {
win_x1 = frame->width;
win_x0 = frame->width - TPL_WIDTH - ( 2 * SEARCH_RANGE_X );
}
if( win_y1 > frame->height ) {
win_y1 = frame->height;
win_y0 = frame->height - TPL_HEIGHT - ( 2 * SEARCH_RANGE_Y );
}
/* draw window */
/*
cvRectangle( frame,
cvPoint( win_x0, win_y0 ),
cvPoint( win_x1, win_y1 ),
cvScalar( 0, 255, 0, 0 ),
1, 0, 0 );
*/
/* apply window to frame */
cvSetImageROI( frame, cvRect( win_x0,
win_y0,
win_x1 - win_x0,
win_y1 - win_y0 ) );
/* search for matching object */
cvMatchTemplate( frame, tpl, match_res, CV_TM_SQDIFF_NORMED );
cvMinMaxLoc( match_res, &minval, &maxval, &minloc, &maxloc, 0 );
/* clear window */
cvResetImageROI( frame );
/* if object found... */
if( minval <= THRESHOLD ) {
/* save object's current location */
object_x0 = object_x0 - SEARCH_RANGE_X + minloc.x;
object_y0 = object_y0 - SEARCH_RANGE_Y + minloc.y;
/* and draw a box there */
cvRectangle( frame,
cvPoint( object_x0, object_y0 ),
cvPoint( object_x0 + TPL_WIDTH, object_y0 + TPL_HEIGHT ),
cvScalar( 0, 0, 255, 0 ), 1, 0, 0 );
}
/* if not found... */
else {
/* search around initialization area */
object_x0 = object_x0_ini;
object_y0 = object_y0_ini;
}
}
void display_info()
{
fprintf( stdout, "EyeTracking 1.0 - Track user's eye with manually selected template\n" );
fprintf( stdout, "Author: Nashruddin Amin (me@nashruddin.com)\n" );
fprintf( stdout, "Website: http://www.nashruddin.com\n\n" );
fprintf( stdout, "Enjoy!\n" );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -