Описание проблемы

В настоящее время существуют программы,позволяющие анимировать статические фотографии. Прежде всего, речь идёт об анимации лица и создании определённой мимики. Теоретически задача решается достаточно просто. Берём 3Д модель черепа и добавляем к ней основные лицевые мускулы. Фотография рассматривается как текстура, помещаем текстуру на 3Д модель и и проводим эксперименты с сокращениями определённых групп мышц. При реализации данной схемы возникает большое количество проблем. Одна из основных -- изменение текстуры при сокращении заданных мышц. Известны и удачные решения этой задачи, реализованные, в приложениях, ссылки на которые можно найти в Интернете. При этом существенно используются нейронные сети либо анимация осуществляется по определенным шаблонам. В данной статье рассматривается простейший случай, когда надо открыть рот на фотографии, сделанной анфас. Оказывается, что в этой ситуации достаточно обычной квадратичной интерполяции. Ссылка на ролик, где реализована данная схема помещена в конец статьи.

Открывание рта тигром

Всю используемую технику проиллюстрируем с помощью фотографии головы тигра, который должен открыть рот. Оригинал представлен на Fig.1.

 Fig.1 Голова тигра с отмеченными точками
Fig.1 Голова тигра с отмеченными точками

Преобразования основаны на выборе 6 точек: три точки, определяющие положение верхней челюсти (точки r0,r1,r2) и три точки, задающие положение нижней челюсти (u0,u1,u2). Все точки отмечены крестиками на рисунке. Следует сразу отметить, что мы работаем с растровым изображением, представленным матрицей, и все рассматриваемые точки имеют целочисленные координаты,совпадающие с номерами строк и столбцов матрицы. Точки r0, r2 расположены в уголках рта. Схема точек представлена на Fig.2.

 Fig.2 Взаимное расположение точек в задаче моделирования раскрытия рта
Fig.2 Взаимное расположение точек в задаче моделирования раскрытия рта

Кривые на Fig.2 строятся с помощью квадратичной аппроксимации. Каждая точка r имеет координаты Y,X в форме r[0] и r[1]. Например кривая, построенная по точкам r0,r1,r2, задается с помощью фрагмента кода

from scipy.interpolate import interp1d
List = [r0,r1,r2]
Args = [Pr[0] for Pr in List]
Values = [Pr[1] for Pr in List]
F1 = interp1d(Args,Values,kind='quadratic')

Функция F1(Y) вычисляет по номеру Y столбца матрицы значение координаты X (номер строки), в которой расположена точка кривой. Аналогично строится строится функция F2 для второй кривой, но теперь List=[r0,u0,u1,u2,r2]. С помощью этих двух функций строится новый список, состоящий из всех интервалов вида A,B матрицы расположенных между верхней и нижней челюстями (см. Fig.2. )

 Fig.3 Построение  раскрытого рта
Fig.3 Построение раскрытого рта

С помощью указанных построений процедура раскрытия рта теперь выглядит следующим образом:

  • Верхняя губа, заданная списком [r0,r1,r2], остаётся неподвижной

  • Нижняя губа определяется списком [r0,r1',r2] путём смещения точки r1 вниз на величину Shift в положение r1'

  • По списку [r0,r1',r2] строится функция F3(Y)

  • Каждый интервал A,B в столбце матрицы изображения с номером Y смещается вниз на величину F3(Y)-F1(Y) и занимает положение A',B' (см.Fig.3)

Дополнив полученное изображение зубами и языком, получим результат:

 Fig.4 Голова тигра с раскрытым ртом
Fig.4 Голова тигра с раскрытым ртом

Очевидно, каким образом данная процедура распространяется на анимацию раскрытия рта другими объектами.

Посмотреть на работу алгоритма можно здесь Пример анимации .

Комментарии (1)


  1. ferosod
    03.02.2022 11:13
    +13

    Крутой результат получился, сложноотличимый от реального фото!