Как выполнить стабильное определение угла глаза?

Для тех, кто считает это слишком длинным, просто прочитайте жирные строки.

Мой проект HCI, основанный на оценке взгляда и перемещении экранного курсора, теперь зависит от одной последней вещи - оценки взгляда, для которой я использую углы глаза в качестве контрольной устойчивой точки, относительно которой я буду обнаруживать движение зрачка и вычислять взгляд.

Но я не смог стабильно обнаружить уголки глаз в прямом эфире с веб-камеры. Я использовал функции cv.CornerHarris() и GFTT - cv.GoodFeaturesToTrack() для определения угла. Я попробовал FAST demo (исполняемый файл с их сайта) прямо на моих изображениях глаз, но это было не очень хорошо.

Вот некоторые результаты моих пока что обнаруженных угловых изображений.

Используя GFTT:

хорошее освещение, используя GFTT

Используя Харриса:

используя cv.CornerHarris

что происходит в видео:

углы в видео с использованием GFTT Зеленые кружки - это углы, остальные (в розовых, меньших кругах) - другие углы.

Я использовал определенную эвристику - что углы будут в левом или правом крайнем положении и вокруг середины, если мыслить вертикально. Я сделал это, потому что после того, как я сделал много снимков во многих условиях, за исключением менее 5% изображений, остальные были такими, и для них верна вышеупомянутая эвристика.

Но эти определения углов глаз предназначены для снимков, а не из веб-камеры.

Когда я использую методологии (Харрис и GFTT) для веб-камеры, я просто не понимаю их.

Мой код для определения угла глаза с помощью cv.CornerHarris

Углы зрения с использованием 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 (но это означало бы, что левый угол находится почти посередине области глаза), чтобы получить больше кандидатов на канал веб-камеры - в котором я вообще не получаю никаких углов.

Кроме того, max_dist хранит максимальное расстояние между до сих пор видимыми X-ординатами и, таким образом, дает меру того, какая пара углов будет левым и правым углами глаза - та, которая имеет максимальное расстояние = max_dist

Кроме того, из моих снимков я видел, что Y-ординаты углов глаза лежат между 40-70, поэтому я использовал это тоже, чтобы минимизировать пул кандидатов

3 ответа

Решение

Я изменил это

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 и от 1/5 до 3/4 для диапазона X, потому что это обычная область, в которой находятся углы.

Извините, ребята, что ответили поздно, я был занят более поздней частью проекта - оценкой взгляда. И я собираюсь отправить вопрос об этом, я застрял в этом.

Кстати, вот несколько снимков углов глаза и зрачка, обнаруженных в моем глазу: (увеличено до 100x100)

Надеюсь, что это будет полезно для других, начинающих в этой области.

Я думаю, что есть простой способ помочь!

Похоже, вы рассматриваете каждый глаз изолированно. Я предлагаю вам объединить данные для обоих глаз, а также использовать геометрию лица. Я проиллюстрирую свои предложения картиной, которую некоторые люди могут узнать (это на самом деле не лучший пример, так как это картина, а ее лицо немного смещено от центра, но это, безусловно, самое смешное..)

Кажется, у вас есть надежные оценки положения зрачка для обоих глаз, и если лицо смотрит прямо в камеру (при этом методе повороты лица перпендикулярно экрану будут в порядке), мы знаем, что уголки глаз (отныне только "углы") будут лежать на (или вблизи) линии, проходящей через зрачки обоих глаз (красная пунктирная линия).

Мы знаем расстояние между учениками, aи мы знаем, что отношение между этим расстоянием и расстоянием через один глаз (от угла к углу), b, является фиксированным для человека, и не будет сильно меняться среди взрослого населения (может отличаться для разных полов).

ie. a / b = constant.

Поэтому мы можем вывести b независимо от расстояния до объекта, зная только a,

Используя эту информацию, мы можем построить пороговые блоки для каждого угла глаза (пунктирные блоки, подробно обозначенные 1, 2, 3, 4). Каждая коробка b от c (высота глаза, опять же определяемая по тому же принципу фиксированного отношения) и лежит параллельно оси зрачка. Центральный край каждой коробки прикреплен к центру зрачка и движется вместе с ним. Мы знаем, что каждый угол всегда будет в своем собственном пороге!

Теперь, конечно, проблема в том, что зрачки двигаются, как и наши пороговые блоки... но мы таким образом значительно сузили поле, потому что мы можем уверенно отбрасывать ВСЕ оценочные положения глаз (от Харриса или GFTT или чего-либо еще) выпадать из этих рамок (при условии, что мы уверены в том, что наш ученик обнаружен).

  • Если у нас есть высокая достоверность только в одной угловой позиции, мы можем экстраполировать и вывести все остальные угловые позиции только из геометрии! (для обоих глаз!).

  • Если между несколькими угловыми позициями есть сомнение, мы можем использовать знания о других углах (из любого глаза), чтобы разрешить их вероятностным связыванием их позиций, делая правильное предположение. то есть. лежат ли какие-либо пары оценок (в пределах их рамок, конечно) b отдельно и параллельно оси зрачка.

  • Если вы можете получить общие "глазные" позиции, которые не двигаются, когда зрачок движется (или фактически любые черты лица в той же плоскости), это очень полезно и позволяет вам определять геометрические положения углов.

Я надеюсь, что это может помочь вам найти неуловимого d (смещение зрачка от центра глаза).

Вы пробовали сегментацию склеры?

Вы могли бы также справиться с двумя углами склеры, и это может быть проще, потому что у вас уже есть приличное обнаружение зрачка, склера - более яркая область, окружающая зрачок.

Другие вопросы по тегам