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

bad*_*nts 17 python opencv image-processing computer-vision eye-detection

对于那些发现它太长的人,只需阅读粗线.

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

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

这些是我到目前为止对图像的角落检测的一些结果.

使用GFTT:

良好的照明,使用GFTT

使用哈里斯:

使用cv.CornerHarris

视频中会发生什么:

使用GFTT的视频中的角落 绿色的cirlces是角落,其他(粉红色,较小的圆圈)是其他角落

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

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

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

我使用cv.CornerHarris进行眼角检测的代码

使用GFTT的眼角

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

来自GFTT的这些参数适用于平均照明条件

cornerCount = 100
qualityLevel = 0.1
minDistance = 5
Run Code Online (Sandbox Code Playgroud)

而这些:

    cornerCount = 500
    qualityLevel = 0.005
    minDistance = 30
Run Code Online (Sandbox Code Playgroud)

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

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

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

cv.CreateImage((colorImage.width, colorImage.height), 8,1)
Run Code Online (Sandbox Code Playgroud)

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

cv.CreateImage(cv.GetSize(grayImage), cv.IPL_DEPTH_32F, 1)
Run Code Online (Sandbox Code Playgroud)

注意深度.

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

我通过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
Run Code Online (Sandbox Code Playgroud)

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

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

此外,max_dist存储了迄今为止看到的X坐标之间的最大距离,因此可以测量左右角的哪一对角 - 最大距离= max_dist的角

另外,我从我的快照中看到,眼角的Y坐标在40-70之间,所以我也用它来最小化候选池

fra*_*xel 6

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

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

在此输入图像描述

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

我们知道瞳孔之间的距离a,并且我们知道这个距离与一只眼睛(角落到角落)的距离之间的比率b对于个体是固定的,并且在成年人群中不会有太大变化(可能不同)两性之间).

ie. a / b = constant.

因此,我们可以推断b,独立于拍摄对象与相机的距离,仅知道a.

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

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

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

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

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

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


bad*_*nts 5

我换了这个

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

对此:

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

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

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

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

在此输入图像描述

在此输入图像描述

在此输入图像描述 希望这对从这个领域开始的其他人有用.