Оценка позы головы с помощью OpenCV, C ++ и Image 2D — Геометрический метод — крен, рыскание и тангаж

Я пытаюсь найти три угла лица человека на основе 2D-изображения 2D изображение.

Я использую OpenCV с HaarCascade, чтобы найти лицо, глаза, нос и рот.
Но я не нашел геометрического метода, который мог бы помочь мне найти углы X, Y и Z (Roll, Pitch и Yaw).

Может ли кто-нибудь помочь мне показать какой-то метод в C ++ или Java, который работает?

7

Решение

Учитывая одно изображение и никакой другой информации, не существует единого решения для углов. Рассмотрим случай просто Йоу. Проецируемая на плоскость 2d, это видно как небольшое изменение проецируемого расстояния между глазами и расположением глаз относительно носа / рта. Однако это расстояние не является постоянным от человека к человеку.

Один из типичных способов обойти это — потребовать, чтобы пользователь «откалибровал» свое лицо, глядя прямо в камеру на номинальные углы «0». Теперь у вас есть эталонные длины, с которыми вы можете сравнивать последующие изображения.

Однако длины по-прежнему являются не совсем достаточной информацией, поскольку величина изменения видимых проецируемых расстояний зависит от оптики и расстояния лица от камеры. Оптика, которую вы обычно настраиваете вручную; расстояние, которое вы можете оценить, приняв «средние» размеры лица и предположив, что «номинальное» изображение идеально соответствует этим размерам. Вы можете сделать это регулируемым, если обнаружите, что это переоценка или недооценка поворотов для конкретной грани.

Когда у вас есть все эти предположения, это довольно простая геометрия. Вы можете оценить крен от линии от глаз через нос к рту. Вы можете измерить расстояние между глазами, чтобы оценить рыскание. Наконец, вы можете оценить высоту тона, используя расстояние между глазами / ртом или глазами / носом. Имейте в виду, что эти предположения работают лучше всего, когда лицо все еще довольно близко к номинальному.

5

Другие решения

Итак, вы хотите найти ориентацию (в углах RPY) лица на основе положения носа, глаз и рта. Предполагая, что все три (четыре — два глаза) видимы, я бы использовал симметричные особенности лица для определения ориентации головы, такие как:

Линия между глазами может использоваться как ориентир для одной из осей (например, тангажа). Тогда мы можем предположить, что ось крена указывает в направлении носа — что можно измерить по позиционному смещению носа к средней точке между глазами. И, наконец, рыскание может быть измерено через отношение расстояний между средней точкой между глазами, положением носа и положением рта.

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

Кстати, интересное приложение!

0

Если вы используете каскадный классификатор для определения правого глаза, левого глаза и носа, вычислите центр тяжести каждой функции (функция x / 2, функция y / 2), это даст вам три точки x-y на вашем изображении.

Вы можете обнаружить крен, посмотрев на значения Y каждого глаза, если одно выше другого, это означает, что головка наклонена в направлении наименьшего значения Y (когда один глаз движется вверх, другой движется вниз)

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

Вы можете определить высоту тона, посмотрев на значение Y носа, если пользователь смотрит вверх, значение Y будет ближе к обоим значениям Y глаз, а если они смотрят вниз, значение Y будет дальше от значения глаз.

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

Единственное, что я могу увидеть, когда вы вычисляете все три в одном изображении, может быть, если крен довольно резкий, вычисление рыскания может быть проблематичным, поскольку ось X больше не является плоской.

Вы можете решить эту проблему, исправляя изображение с помощью 2D поворота.
Вам нужно будет найти, на сколько нужно повернуть изображение

Value = (right eye Y / 2) - (left eye Y / 2)

С помощью этой информации вы можете исправить изображение и продолжить обработку (для поворота изображения посмотрите вверх, создав 2D-матрицу вращения и используя деформацию деформации)

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

0
По вопросам рекламы [email protected]