如何进行稳定的眼角检测?

时间:2012-03-10 10:59:42

标签: python image-processing opencv computer-vision eye-detection

对于那些发现时间过长的人,请阅读粗体字。

我基于视线估计的屏幕光标移动HCI的项目现在依赖于最后一件事 - 凝视估计,我使用眼角作为参考稳定点,相对于该参考稳定点,我将检测瞳孔的运动并计算凝视。

但是我无法从现场网络摄像头视频中稳定地检测到眼角。我一直在使用cv.CornerHarris()和GFTT - cv.GoodFeaturesToTrack()函数进行角点检测。我在我的眼睛图像上直接尝试了FAST演示(来自他们网站的可执行文件),但这并不好。

这些是我迄今为止的角落检测的一些结果。

使用GFTT:

good lighting, using GFTT

使用Harris:

using cv.CornerHarris

视频中会发生什么:

corners in video using GFTT 绿色的cirlces是角落,其他(粉红色,小圆圈)是其他角落

我使用了某种启发式方法 - 如果垂直思考,角落将位于左侧或右侧极端,并且位于中间位置。 我之所以这样做是因为在很多条件下拍摄了许多快照后,除了不到5%的图像外,休息就像这些,对于他们来说,上面的启发式算法就可以了。

但是这些眼角检测用于快照 - 而不是来自网络摄像头。

当我使用方法论(哈里斯和GFTT)进行网络摄像头输入时,我只是没有得到它们。

My code for eye corner detection using cv.CornerHarris

Eye corners using GFTT

现在我在两种方法中使用的参数 - 它们不会显示不同光照条件下的结果。但是在与拍摄这些快照的照明条件相同的情况下,我仍然没有得到我从网络摄像头视频查询的帧的结果

GFTT的这些参数适用于平均光照条件

cornerCount = 100
qualityLevel = 0.1
minDistance = 5

而这些:

    cornerCount = 500
    qualityLevel = 0.005
    minDistance = 30

适用于上面显示的静态图片

minDistance = 30因为很明显,角落至少会有这么远的距离,再一次,从我的快照中看到的是一种趋势。但是我把它降级为GFTT的网络摄像头饲料版本,因为那时我根本没有任何角落。

此外,对于GFTT的实时馈送版本,我必须进行一些小改动:

cv.CreateImage((colorImage.width, colorImage.height), 8,1)

而对于静止图像版本(pastebin上的代码),我使用了:

cv.CreateImage(cv.GetSize(grayImage), cv.IPL_DEPTH_32F, 1)

注意深度。

这会改变任何检测质量吗?

我通过GFTT方法的眼睛图像没有32F的深度所以我不得不改变它并根据其余的临时图像(eignenimg,tempimg等)

底线:我要完成凝视估计,但没有稳定的眼角检测我无法进展..而且我要继续眨眼检测和模板匹配基于瞳孔跟踪(或者你知道更好吗?) 。简单地说,我想知道我是否犯了任何新手的错误,或者没有做任何阻止我在我的网络摄像头视频流中进行接近完美的眼角检测的事情,我在这里发布了我的快照。

无论如何,谢谢你提供一个观点。 任何想法如何在各种照明条件下进行眼角检测都会非常有帮助

好的,如果你没有得到我在我的代码中做的事情(我如何得到左右角),我会解释:

max_dist = 0
maxL = 20
maxR = 0

lc =0
rc =0

maxLP =(0,0)
maxRP =(0,0)

for point in cornerMem:
    center = int(point[0]), int(point[1])

    x = point[0]
    y = point[1]


    if ( x<colorImage.width/5 or x>((colorImage.width/4)*3) ) and (y>40 and y<70):
                      #cv.Circle(image,(x,y),2,cv.RGB(155, 0, 25))

                      if maxL > x:
                               maxL = x
                               maxLP = center


                      if maxR < x:
                               maxR = x
                               maxRP = center

                      dist = maxR-maxL

                      if max_dist<dist:
                           max_dist = maxR-maxL
                           lc = maxLP
                           rc = maxRP





    cv.Circle(colorImage, (center), 1, (200,100,255)) #for every corner

cv.Circle(colorImage,maxLP,3,cv.RGB(0, 255, 0)) # for left eye corner
cv.Circle(colorImage,maxRP,3,cv.RGB(0,255,0))   # for right eye corner

maxLP和maxRP将分别存储眼睛左右角的(x,y)。 我在这里做的是,分别为左右角检测变量maxL和maxR,将进行比较 到检测到的角的x值。现在简单地说,对于maxL,它必须超过0;我分配了20因为如果 左边角是(x,y),其中x <20,然后maxL将是= x,或者如果说,也就是说,这样找到了最左边的X坐标。同样是最正确的角落。

我也试过maxL = 50(但这意味着左角几乎位于眼睛区域的中间)以获得更多网络摄像头饲料的候选者 - 我根本没有任何角落< / p>

此外, max_dist存储到目前为止看到的X坐标之间的最大距离,从而给出了哪一对角的度量 将是左眼和右眼 - 最大距离= max_dist

另外,我从我的快照中看到眼角的Y坐标在40-70之间,所以我也用它来尽量减少 候选人池

3 个答案:

答案 0 :(得分:6)

我认为有一种简单的方法可以提供帮助!

看起来你正在孤立地考虑每只眼睛。我建议你做的是组合你的双眼数据,并使用面部几何。我将用一张有些人可能认出的照片来说明我的建议(这不是最好的例子,因为它是一幅画,她的脸有点偏离中心,但它肯定是最有趣的......)

enter image description here

看起来你对两只眼睛的瞳孔位置都有可靠的估计,并且提供的脸在相机上看起来相当直接(垂直于屏幕的面部旋转可以使用这种方法),我们知道角落眼睛(从现在开始只是'角落')将躺在(或接近)穿过双眼瞳孔的线上(红色虚线)。

我们知道瞳孔之间的距离a,我们知道这个距离与一只眼睛(角落到角落)的距离b之间的比例对于个人而言是固定的,并且在成年人口中不会发生太大变化(性别可能不同)。

ie. a / b = constant.

因此,我们可以推导b,与受试者距离相机的距离无关,仅知道a

使用此信息,我们可以为每个眼角构建阈值框(虚线框,详细标记为1, 2, 3, 4)。每个方框bc(眼高,同样可通过相同的固定比率原理确定)并且平行于瞳孔轴。每个盒子的中心边缘固定在瞳孔的中心,随之移动。我们知道每个角落都会在它自己的门槛框中!

现在,当然麻烦就是学生走动,我们的门槛盒也是如此......但是我们以这种方式大幅缩小了场地,因为我们可以放心地丢弃所有估计的眼睛位置(来自Harris或GFTT)或者任何东西)掉在这些盒子外面(假如我们对我们的瞳孔检测有信心)。

  • 如果我们对一个角落位置有很高的信心,我们可以从几何中推断和推断出所有其他角落位置! (对于双眼!)。

  • 如果在多个角落位置之间存在疑问,我们可以使用其他角落(来自任何一只眼睛)的知识来解决它在概率上连接它们的位置,做出最佳猜测。即。做任何一对估计(当然在他们的方框内)与{瞳孔轴>分开并平行b

  • 如果您可以获得在瞳孔四处移动时不移动的一般“眼睛”位置(或实际上在同一平面上的任何面部特征),这非常有用,并允许您在几何上确定角位置。

我希望这可以帮助你找到难以捉摸的d(从眼睛中心移位瞳孔)。

答案 1 :(得分:5)

我改变了这个

if ( x<colorImage.width/5 or x>((colorImage.width/4)*3) ) and (y>40 and y<70):

到此:

if ( x<(w/5) or x>((w/4)*3) ) and (y>int(h*0.45) and y<int(h*0.65)):

因为早些时候我只是手动查看像素值,超出这个像素值我的窗口可以找到最高概率的角落。但后来我意识到,让我们把它做成一般,所以我制作了一个45到65个Y范围的水平窗口,以及X范围的1/5到3/4,因为这是角落所在的通常区域。

我很抱歉回复很晚,我忙于项目的后期部分 - 凝视估计。而且我要发一个关于它的问题,我被困在里面。

顺便说一句,这里有几张眼角和瞳孔在我眼中检测到: (放大到100x100)

enter image description here

enter image description here

enter image description here 希望这对从这个领域开始的其他人有用。

答案 2 :(得分:1)

您是否尝试过巩膜分割?

您也可以使用巩膜的两个角,这可能更容易,因为您已经有一个像样的瞳孔检测工作,巩膜是瞳孔周围较亮的区域。