Заранее поясню, что код в этой статье был обнаружен мною случайно. Здесь просто обмен. Справочные статьи будут даны в конце статьи. Не нравится - не распыляйтесь.
Полный исходный код и модель предварительного обучения можно получить в общедоступной учетной записи: «01 Binary», фоновый ответ: «AI face change».
предисловие
Как толстяк, который часто посещает станцию B, некоторое время назад я случайно увидел видео со сменой лица под названием «Face Changer», которое заставило Ян Ми «путешествовать» по версии 1994 года «Легенда о героях-кондорах», заменить» С Чжу Инь она «сыграла» роль Хуан Жун. Видео выглядит следующим образом (видео станции b удалено, можно перепечатать только видео Zhihu, исходный адрес«Изменение лица» Ян Ми, насколько ужасно изменение лица ИИ?):
После просмотра я был в шоке.Это слишком мощно.Как только эта технология станет популярной,аб может снимать не выходя в студию.Это реально зарабатывать деньги лежа. Если это применить к пленке H, не так ли ???
Ближе к дому, как кодер, увидев это видео, мне очень захотелось узнать, как это было сделано.Проверив некоторую информацию, я обнаружил, что самое печальное, что я наконец нашел исходный код, данные Набор скачан, но видеокарта не может его поднять...
Советы: Вот два репозитория о видеозаменах лиц, которые я нашел ранее, если вам интересно, вы можете узнать сами:
Поскольку условия не позволяют, мы можем только уменьшить стоимость.Поскольку лицо в видео не так просто изменить, то мы должны согласиться на следующую лучшую вещь и изменить лицо на картинке.Конечно же, после моего упорного поиском, я нашел совпадение низкого качества. Версия Дафа, изменяющая лицо Python:
«Переключение редакторов: замена лица с помощью Python, dlib и OpenCV»
Следующее содержание относится к отмеченным выше статьям, и я хотел бы поблагодарить здесь оригинального автора.
Далее я расскажу, как автоматически заменить черты лица на одном изображении чертами лица на другом изображении с помощью короткого скрипта Python (около 200 строк).
Конкретный процесс делится на четыре этапа:
- обнаружить ориентиры лица;
- Вращайте, масштабируйте и переводите рисунок 2, чтобы он соответствовал рисунку 1;
- Отрегулируйте баланс белого изображения 2, чтобы он соответствовал изображению 1;
- Интегрировать функции рисунка 2 в рисунок 1;
лабораторная среда
- MacOS 10.14.3
- Python 3.7
- PyCharm
- Используемые библиотеки:
- numpy
- dlib
- opencv-python
Описание инструмента
Все должны быть знакомы с numpy.Здесь я кратко представлю dlib и opencv.
dlib
Официальный веб-сайт представляет его как: Набор инструментов для создания реальных приложений для машинного обучения и анализа данных, Короче говоря, это библиотека машинного обучения с открытым исходным кодом, которая содержит множество алгоритмов машинного обучения. В то же время он предоставляет интерфейсы C++ и Python. Использование dlib может значительно упростить разработку, например, распознавание лиц, обнаружение характерных точек и другие задачи могут быть легко реализованы. В то же время существует множество приложений и библиотек с открытым исходным кодом, разработанных на основе dlib, таких как библиотека face_recogintion (говорят, что уровень распознавания достигает 93%, если вы заинтересованы, вы можете ознакомиться с соответствующей информацией ). Установка под python тоже очень простая, выполняемpip install dlib
Вот и все.
opencv
OpenCV — это библиотека компьютерного зрения Intel® с открытым исходным кодом. Он состоит из ряда функций C и нескольких классов C++, которые реализуют многие распространенные алгоритмы обработки изображений и компьютерного зрения. Это очень важная библиотека с открытым исходным кодом в области компьютерного зрения. Адрес официального сайта:opencv.org/
начать менять лицо
Извлечь черты лица
Так как мы хотим изменить лицо, мы должны сначала найти лицо на картинке, в dlib есть функцияget_frontal_face_detector()
Реализовано извлечение черт лица. Основной алгоритм взят из статьи Вахида Каземи и Жозефины Салливан «Выравнивание лица за одну миллисекунду с ансамблем дерева регрессии». Я не читал эту статью и не буду ее объяснять. Код для извлечения черт лица выглядит следующим образом:
# 面部检测器
detector = dlib.get_frontal_face_detector()
# 特征提取器
predictor = dlib.shape_predictor('shape_predictor_68_face_landmarks.dat')
def GetLandmarks(img_path):
img = cv2.imread(img_path, cv2.IMREAD_COLOR)
rects = detector(img, 1)
if len(rects) > 1:
print('[Warning]: More than one face in picture, only choose one randomly...')
rects = rects[0]
elif len(rects) == 0:
print('[Error]: No face detected...')
return None
return img, np.matrix([[p.x, p.y] for p in predictor(img, rects[0]).parts()])
Функция get_landmarks() берет изображение, обрабатывает его как пустой массив и возвращает матрицу элементов 68x2. Каждая строка матрицы соответствует координатам x,y конкретной характерной точки на входном изображении.
Средство извлечения признаков (предиктор) требует приблизительную ограничивающую рамку в качестве входных данных для алгоритма. Это обеспечит традиционный детектор лиц (детектор). Детектор лиц возвращает список прямоугольников, где каждый прямоугольник соответствует лицу на изображении.
Для создания предикторов требуется предварительно обученная модель. Модель можно получить, ответив «AI face change» в фоновом режиме публичной учетной записи WeChat «01 Binary».
выравнивание лица
С помощью описанного выше метода мы можем извлечь лицо на изображении, но направление лица на двух фотографиях должно быть несовместимым (в конце концов, вы не можете гарантировать, что каждая фотография является фотографией на удостоверение личности), как и следующие две Чжан картина:
Направления двух граней явно несовместимы, поэтому нам также нужно выровнять грани. Теперь, когда у нас есть координаты прямоугольника лица на каждом изображении, осталось выяснить, как вращать, перемещать и масштабировать все точки в первом векторе, чтобы максимально точно совпадать с точками во втором векторе. Для решения этой проблемы здесь используется метод под названием **Обычный анализ Прокруста**. Математические возможности ограничены. Математика основана на ссылке в справочном примечании. Давайте просто опубликуем код здесь:
# refer:
# https://en.wikipedia.org/wiki/Procrustes_analysis#Ordinary_Procrustes_analysis
def TransferPoints(points1, points2):
points1 = points1.astype(np.float64)
points2 = points2.astype(np.float64)
c1 = np.mean(points1, axis=0)
c2 = np.mean(points2, axis=0)
points1 -= c1
points2 -= c2
s1 = np.std(points1)
s2 = np.std(points2)
points1 /= s1
points2 /= s2
# 奇异值分解
U, S, Vt = np.linalg.svd(points1.T * points2)
R = (U * Vt).T
return np.vstack([np.hstack(((s2 / s1) * R, c2.T - (s2 / s1) * R * c1.T)), np.matrix([0., 0., 1.])])
Затем мы используем функцию OpenCV cv2.warpAffine для сопоставления второго изображения с первым изображением:
def WarpImg(img, M, dshape):
output_img = np.zeros(dshape, dtype=img.dtype)
cv2.warpAffine(img,
M[:2],
(dshape[1], dshape[0]),
dst=output_img,
borderMode=cv2.BORDER_TRANSPARENT,
flags=cv2.WARP_INVERSE_MAP)
return output_img
Правильный цвет изображения
Два изображения отличаются из-зацветисветлыйЭто создает разрыв на краю зоны покрытия. Итак, нам нужно исправить это:
def ModifyColor(img1, img2, landmarks1):
blur_amount = 0.6 * np.linalg.norm(
np.mean(landmarks1[LEFT_EYE_POINTS], axis=0) - np.mean(landmarks1[RIGHT_EYE_POINTS], axis=0))
blur_amount = int(blur_amount)
if blur_amount % 2 == 0:
blur_amount += 1
img1_blur = cv2.GaussianBlur(img1, (blur_amount, blur_amount), 0)
img2_blur = cv2.GaussianBlur(img2, (blur_amount, blur_amount), 0)
img2_blur += (128 * (img2_blur <= 1.0)).astype(img2_blur.dtype)
return (img2.astype(np.float64) * img1_blur.astype(np.float64) / img2_blur.astype(np.float64))
слияние изображений
Используйте маску, чтобы выбрать части рис. 2 и рис. 1, которые в конечном итоге должны отображаться:
Значение 1 (белый) — это область, в которой должен отображаться рисунок 2, а значение 0 (черный) — это область, в которой должен отображаться рисунок 1. Если значение находится между 0 и 1, это смешанная область рисунков 1 и рисунков 2.
Вот код, который генерирует вышеуказанное:
def GetFaceMask(img, landmarks):
img = np.zeros(img.shape[:2], dtype=np.float64)
groups = [
LEFT_EYE_POINTS + RIGHT_EYE_POINTS + LEFT_BROW_POINTS + RIGHT_BROW_POINTS,
NOSE_POINTS + MOUTH_POINTS,
]
for group in groups:
DrawConvexHull(img, landmarks[group], color=1)
img = np.array([img, img, img]).transpose((1, 2, 0))
img = (cv2.GaussianBlur(img, (11, 11), 0) > 0) * 1.0
img = cv2.GaussianBlur(img, (11, 11), 0)
return img
def DrawConvexHull(img, points, color):
points = cv2.convexHull(points)
cv2.fillConvexPoly(img, points, color=color)
def ModifyColor(img1, img2, landmarks1):
blur_amount = 0.6 * np.linalg.norm(
np.mean(landmarks1[LEFT_EYE_POINTS], axis=0) - np.mean(landmarks1[RIGHT_EYE_POINTS], axis=0))
blur_amount = int(blur_amount)
if blur_amount % 2 == 0:
blur_amount += 1
img1_blur = cv2.GaussianBlur(img1, (blur_amount, blur_amount), 0)
img2_blur = cv2.GaussianBlur(img2, (blur_amount, blur_amount), 0)
img2_blur += (128 * (img2_blur <= 1.0)).astype(img2_blur.dtype)
return (img2.astype(np.float64) * img1_blur.astype(np.float64) / img2_blur.astype(np.float64))
GetFaceMask()
Определение функции: создать маску для изображения и матрицу маркеров. Маска рисует два белых выпуклых многоугольника: один вокруг глаз и один вокруг носа и рта. После этого краевые области маски растушевываются на 11 пикселей, что может помочь удалить оставшиеся разрывы.
Ссылаться на
Эта статья относится к следующим статьям:
- «Переключение редакторов: замена лица с помощью Python, dlib и OpenCV»
- Как Mengxin реализует замену лица с помощью Python? 》
Полный исходный код и модель предварительного обучения можно получить в общедоступной учетной записи: «01 Binary», фоновый ответ: «AI face change».
Наконец
На этом низкопрофильная версия смены лица ИИ завершена, и результат такой же, как и в начале. Хоть в этом эксперименте и есть прототип смены лица, но точность далеко не достаточна, и если такой вид смены лица использовать в видео, то он точно будет некрасивым, ведь хорошо сделано вот так:
Методу обучают всех, фотоматериал можно найти самому, поиграть с ним, и будет лучше, если его можно будет переслать в круг друзей, чтобы его увидело больше людей!
Следующее обновление представляет собой txt-версию баскетбольного видео «Американская школьная команда Цай Сюкунь». Вот превью GIF-изображения:
Если вам это нравится, вы можете долго нажимать QR-код ниже, чтобы следовать. ?