Как выполнить стабильное определение угла глаза?
Для тех, кто считает это слишком длинным, просто прочитайте жирные строки.
Мой проект HCI, основанный на оценке взгляда и перемещении экранного курсора, теперь зависит от одной последней вещи - оценки взгляда, для которой я использую углы глаза в качестве контрольной устойчивой точки, относительно которой я буду обнаруживать движение зрачка и вычислять взгляд.
Но я не смог стабильно обнаружить уголки глаз в прямом эфире с веб-камеры. Я использовал функции cv.CornerHarris() и GFTT - cv.GoodFeaturesToTrack() для определения угла. Я попробовал FAST demo (исполняемый файл с их сайта) прямо на моих изображениях глаз, но это было не очень хорошо.
Вот некоторые результаты моих пока что обнаруженных угловых изображений.
Используя 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
(смещение зрачка от центра глаза).
Вы пробовали сегментацию склеры?
Вы могли бы также справиться с двумя углами склеры, и это может быть проще, потому что у вас уже есть приличное обнаружение зрачка, склера - более яркая область, окружающая зрачок.