织梦CMS - 轻松建站从此开始!

罗索

OpenCV Eye Tracking

jackyhwei 发布于 2010-04-14 17:12 点击:次 
This is a simple program that displays live video from a webcam and tracks user's eye. The system tracks user's eye with a given template, which was manually selected using mouse.
TAG:

When the user initially clicks the eye feature, a box is drawn around the square and the subimage within this square is cropped out of the image frame. The cropped image is used as a template to find the position of the feature in subsequent frames. The system determines the position of the feature using Sum of Square Differences (SQD) method. To reduce extensive computation, the system tracks the feature in a "search window", a small area around the position of the feature in previous frame.

Listing 1: OpenCV Eye Tracking

  1. /** 
  2.  * Display video from webcam and track user's eye with 
  3.  * manually selected template. 
  4.  * 
  5.  * Author    Nash <me [at] nashruddin.com> 
  6.  * License   GPL 
  7.  * Website   http://nashruddin.com 
  8.  */ 
  9.   
  10. #include <stdio.h> 
  11. #include "cv.h" 
  12. #include "highgui.h" 
  13.   
  14. #define  TPL_WIDTH       12      /* template width       */ 
  15. #define  TPL_HEIGHT      12      /* template height      */ 
  16. #define  WINDOW_WIDTH    24      /* search window width  */ 
  17. #define  WINDOW_HEIGHT   24      /* search window height */ 
  18. #define  THRESHOLD       0.3 
  19.   
  20. IplImage *frame, *tpl, *tm
  21. int      object_x0, object_y0, is_tracking = 0; 
  22.   
  23. void mouseHandler( int event, int x, int y, int flags, void *param ); 
  24. void trackObject(); 
  25.   
  26. /* main code */ 
  27. int main( int argc, char** argv ) 
  28.     CvCapture   *capture; 
  29.     int         key; 
  30.   
  31.     /* initialize camera */ 
  32.     capture = cvCaptureFromCAM( 0 ); 
  33.   
  34.     /* always check */ 
  35.     if( !capture ) return 1; 
  36.   
  37.     /* get video properties, needed by template image */ 
  38.     frame = cvQueryFrame( capture ); 
  39.     if ( !frame ) return 1; 
  40.     
  41.     /* create template image */ 
  42.     tpl = cvCreateImage( cvSize( TPL_WIDTH, TPL_HEIGHT ), 
  43.                          frame->depth, frame->nChannels ); 
  44.     
  45.     /* create image for template matching result */ 
  46.     tm = cvCreateImage( cvSize( WINDOW_WIDTH  - TPL_WIDTH  + 1, 
  47.                                 WINDOW_HEIGHT - TPL_HEIGHT + 1 ), 
  48.                         IPL_DEPTH_32F, 1 ); 
  49.     
  50.     /* create a window and install mouse handler */ 
  51.     cvNamedWindow( "video", CV_WINDOW_AUTOSIZE ); 
  52.     cvSetMouseCallback( "video", mouseHandler, NULL ); 
  53.     
  54.     while( key != 'q' ) { 
  55.         /* get a frame */ 
  56.         frame = cvQueryFrame( capture ); 
  57.   
  58.         /* always check */ 
  59.         if( !frame ) break
  60.   
  61.         /* 'fix' frame */ 
  62.         cvFlip( frame, frame, -1 ); 
  63.         frame->origin = 0; 
  64.         
  65.         /* perform tracking if template is available */ 
  66.         if( is_tracking ) trackObject(); 
  67.         
  68.         /* display frame */ 
  69.         cvShowImage( "video", frame ); 
  70.   
  71.         /* exit if user press 'q' */ 
  72.         key = cvWaitKey( 1 ); 
  73.     } 
  74.   
  75.     /* free memory */ 
  76.     cvDestroyWindow( "video" ); 
  77.     cvReleaseCapture( &capture ); 
  78.     cvReleaseImage( &tpl ); 
  79.     cvReleaseImage( &tm ); 
  80.     
  81.     return 0; 
  82.   
  83. /* mouse handler */ 
  84. void mouseHandler( int event, int x, int y, int flags, void *param ) 
  85.     /* user clicked the image, save subimage as template */ 
  86.     if( event == CV_EVENT_LBUTTONUP ) { 
  87.         object_x0 = x - ( TPL_WIDTH  / 2 ); 
  88.         object_y0 = y - ( TPL_HEIGHT / 2 ); 
  89.         
  90.         cvSetImageROI( frame, 
  91.                        cvRect( object_x0, 
  92.                                object_y0, 
  93.                                TPL_WIDTH, 
  94.                                TPL_HEIGHT ) ); 
  95.         cvCopy( frame, tpl, NULL ); 
  96.         cvResetImageROI( frame ); 
  97.   
  98.         /* template is available, start tracking! */ 
  99.         fprintf( stdout, "Template selected. Start tracking... \n" ); 
  100.         is_tracking = 1; 
  101.     } 
  102.   
  103. /* track object */ 
  104. void trackObject() 
  105.     CvPoint minloc, maxloc; 
  106.     double  minval, maxval; 
  107.   
  108.     /* setup position of search window */ 
  109.     int win_x0 = object_x0 - ( ( WINDOW_WIDTH  - TPL_WIDTH  ) / 2 ); 
  110.     int win_y0 = object_y0 - ( ( WINDOW_HEIGHT - TPL_HEIGHT ) / 2 ); 
  111.     
  112.     /* 
  113.      * Ooops, some bugs here. 
  114.      * If the search window exceed the frame boundaries, 
  115.      * it will trigger errors. 
  116.      * 
  117.      * Add some code to make sure that the search window 
  118.      * is still within the frame. 
  119.      */ 
  120.     
  121.     /* search object in search window */ 
  122.     cvSetImageROI( frame, 
  123.                    cvRect( win_x0, 
  124.                            win_y0, 
  125.                            WINDOW_WIDTH, 
  126.                            WINDOW_HEIGHT ) ); 
  127.     cvMatchTemplate( frame, tpl, tm, CV_TM_SQDIFF_NORMED ); 
  128.     cvMinMaxLoc( tm, &minval, &maxval, &minloc, &maxloc, 0 ); 
  129.     cvResetImageROI( frame ); 
  130.     
  131.     /* if object found... */ 
  132.     if( minval <= THRESHOLD ) { 
  133.         /* save object's current location */ 
  134.         object_x0 = win_x0 + minloc.x; 
  135.         object_y0 = win_y0 + minloc.y; 
  136.   
  137.         /* and draw a box there */ 
  138.         cvRectangle( frame, 
  139.                      cvPoint( object_x0, object_y0 ), 
  140.                      cvPoint( object_x0 + TPL_WIDTH, 
  141.                               object_y0 + TPL_HEIGHT ), 
  142.                      cvScalar( 0, 0, 255, 0 ), 1, 0, 0 ); 
  143.     } else { 
  144.         /* if not found... */ 
  145.         fprintf( stdout, "Lost object.\n" ); 
  146.         is_tracking = 0; 
  147.     } 

Notice line 117-124, you should add some code to make sure that the search window is still within the frame. If the search window exceed the frame boundaries, it will trigger errors. I will leave this as an exercise for you, dear reader.

Some features to add for the next version:

  • Automatic eye detection
  • Save the video to file
  • Head movement for User Interface

原文:http://nashruddin.com/eyetracking-track-user-eye.html

(Nash )
本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www.rosoo.net/a/201004/9122.html]
本文出处:nashruddin.com 作者:Nash
顶一下
(2)
100%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容