2011-11-16 51 views
12

我正在致力于一个项目旨在轨道眼睛瞳孔。为此,我制作了一个捕捉眼睛图像的头戴式系统。硬件部分完成我在软件部分。我正在使用opencv。请让我知道什么是追踪学生最有效的方法。 Houghcircles表现不佳。轨道眼睛瞳孔在视频

之后,我也试着用HSV过滤器和这里是代码和 链接到原始图像和处理的截图。请帮我解决这个问题。该链接还包含我在此代码中使用的眼睛瞳孔的视频。

https://picasaweb.google.com/118169326982637604860/16November2011?authuser=0&authkey=Gv1sRgCPKwwrGTyvX1Aw&feat=directlink

代码:瞳孔

include "cv.h" 

include"highgui.h" 

IplImage* GetThresholdedImage(IplImage* img) 
{ 

    IplImage *imgHSV=cvCreateImage(cvGetSize(img),8,3); 
    cvCvtColor(img,imgHSV,CV_BGR2HSV); 
    IplImage *imgThresh=cvCreateImage(cvGetSize(img),8,1); 
    cvInRangeS(imgHSV,cvScalar(0, 84, 0, 0),cvScalar(179, 256, 11, 0),imgThresh); 
    cvReleaseImage(&imgHSV); 
    return imgThresh; 
} 

void main(int *argv,char **argc) 
{ 

    IplImage *imgScribble= NULL; 
    char c=0; 
    CvCapture *capture; 
    capture=cvCreateFileCapture("main.avi"); 

    if(!capture) 
    { 
     printf("Camera could not be initialized"); 
     exit(0); 
    } 
    cvNamedWindow("Simple"); 
    cvNamedWindow("Thresholded"); 

    while(c!=32) 
    { 
     IplImage *img=0; 
     img=cvQueryFrame(capture); 
     if(!img) 
      break; 
     if(imgScribble==NULL) 
      imgScribble=cvCreateImage(cvGetSize(img),8,3); 

     IplImage *timg=GetThresholdedImage(img); 
     CvMoments *moments=(CvMoments*)malloc(sizeof(CvMoments)); 
     cvMoments(timg,moments,1); 

     double moment10 = cvGetSpatialMoment(moments, 1, 0); 
     double moment01 = cvGetSpatialMoment(moments, 0, 1); 
     double area = cvGetCentralMoment(moments, 0, 0); 

     static int posX = 0; 
     static int posY = 0; 

     int lastX = posX; 
     int lastY = posY; 

     posX = moment10/area; 
     posY = moment01/area; 
     // Print it out for debugging purposes 
     printf("position (%d,%d)\n", posX, posY); 
     // We want to draw a line only if its a valid position 
     if(lastX>0 && lastY>0 && posX>0 && posY>0) 
     { 
      // Draw a yellow line from the previous point to the current point 
      cvLine(imgScribble, cvPoint(posX, posY), cvPoint(lastX, lastY), cvScalar(0,255,255), 5); 
     } 
     // Add the scribbling image and the frame... 

     cvAdd(img, imgScribble, img); 

     cvShowImage("Simple",img); 
     cvShowImage("Thresholded",timg); 
     c=cvWaitKey(3); 
     cvReleaseImage(&timg); 
     delete moments; 

    } 
    //cvReleaseImage(&img); 
    cvDestroyWindow("Simple"); 
    cvDestroyWindow("Thresholded"); 

} 

我能够追踪的眼睛,找到中心坐标精确。

首先我对头戴式摄像头拍摄的图像进行阈值处理。之后,我使用轮廓查找算法,然后找到所有轮廓的质心。这给我眼睛瞳孔的中心坐标,这种方法实时工作正常,还能以非常高的准确度检测眨眼。

现在,我的目标是将此功能嵌入到游戏中(赛车游戏)。其中,如果我向左/右看,则汽车向左/向右移动,如果我眨眼,汽车就会慢下来。我现在该怎么办?我需要一个游戏引擎来做到这一点吗?

我听说过一些与visual studio 2010兼容的开源游戏引擎(unity等)。这是可行吗?如果是,我应该如何继续?

回答

10

我是SimpleCV的开发人员之一。我们为计算机视觉维护一个开放源代码的python库。您可以在SimpleCV.org下载它。 SimpleCV非常适合通过在命令行上黑客来解决这些类型的问题。我只能用几行代码就可以提取学生。在这里你去:

img = Image("eye4.jpg") # load the image 
bm = BlobMaker() # create the blob extractor 
# invert the image so the pupil is white, threshold the image, and invert again 
# and then extract the information from the image 
blobs = bm.extractFromBinary(img.invert().binarize(thresh=240).invert(),img) 

if(len(blobs)>0): # if we got a blob 
    blobs[0].draw() # the zeroth blob is the largest blob - draw it 
    locationStr = "("+str(blobs[0].x)+","+str(blobs[0].y)+")" 
    # write the blob's centroid to the image 
    img.dl().text(locationStr,(0,0),color=Color.RED) 
    # save the image 
    img.save("eye4pupil.png") 
    # and show us the result. 
    img.show() 

Here are the results.

所以你的下一个步骤是使用某种跟踪器,像一个Kalmann滤波器,能够稳健地追踪瞳孔。您可能需要将眼睛建模为球体,并在球体坐标(即theta和phi)中跟踪瞳孔的质心。您还需要编写一些代码来检测眨眼事件,以便在用户眨眼时系统不会全部失效。我建议使用canny边缘检测器来查找图像中最大的水平线,并假设这些是眼睑。我希望这可以帮助,请让我们知道你的工作进展。

2

这一切都取决于你的系统必须有多好。如果这是一个为期两个月的大学项目,那么可以像Kscottz推荐的那样找到并跟踪一些斑点或使用现成的解决方案。

但是,如果你的目标是要有一个更严重的系统,你必须更深入。

我建议你的方法是检测脸部兴趣点。一个很好的例子是主动外观模型,这似乎是最好的跟踪面临

http://www2.imm.dtu.dk/~aam/

http://www.youtube.com/watch?v=M1iu__viJN8

它需要你的计算机视觉算法有深刻的理解,良好的编程技巧,还有一些工作。但结果是值得的。

不要被演示显示全脸跟踪的事实所迷惑。你可以训练它来跟踪什么:手,眼,花或叶,等

(AAM与开始之前,你可能想了解更多关于其它脸部追踪算法,他们可能对你更好。)

1

这是我的解决方案,我能够跟踪眼睛并精确地找到瞳孔的中心坐标。

首先我对头戴式摄像头拍摄的图像进行阈值处理。之后,我使用轮廓查找算法,然后找到所有轮廓的质心。这给我眼睛瞳孔的中心坐标,这种方法实时工作正常,还能以非常高的准确度检测眨眼。

+0

这真的应该是一个新问题。 –

+0

好的,这里是http://stackoverflow.com/questions/8200031/transfer-output-of-opencv-to-input-for-a-game-engine – siso