必要なパッケージのインストール
まず、このプロジェクトに必要なパッケージをインストールします。OpenCVは画像処理、dlibは顔検出と顔のランドマークの検出、numpyは数値計算のために必要です。
pip install opencv-python
pip install dlib
pip install numpy
学習済みモデルのダウンロード
次に、dlibの学習済みモデルを使います。このモデルは68個のランドマーク(顔の特徴的なポイント)を顔から検出するために使われます。
wget http://dlib.net/files/shape_predictor_68_face_landmarks.dat.bz2
bzip2 -d shape_predictor_68_face_landmarks.dat.bz2
顔の位置を置き換えるツールの作成
ここからは、Pythonでの実装を始めます。
import cv2
import numpy as np
import dlib
まず、必要なパッケージをインポートします。cv2はOpenCVのパッケージ名です。
predictor = dlib.shape_predictor('shape_predictor_68_face_landmarks.dat')
次に、ダウンロードした学習済みモデルをロードします。このモデルを使って顔のランドマークを予測することができます。
img1 = cv2.imread('image1.jpg')
img2 = cv2.imread('image2.jpg')
2つの画像をロードします。これらの画像の顔を入れ替えます。
detector = dlib.get_frontal_face_detector()
faces1 = detector(img1, 1)
faces2 = detector(img2, 1)
landmarks1 = predictor(img1, faces1[0])
dlibの顔検出器を使用して、画像から顔を検出します。その後、ランドマーク検出器で顔のランドマークを検出します。
mask = np.zeros_like(img1[:2], dtype=np.uint8)
for i in range(0, 68):
point = (landmarks1.part(i).x, landmarks1.part(i).y)
cv2.circle(mask, point, 1, (255, 255, 255), -1)
顔のランドマークに基づいてマスクを作成します。このマスクは、画像から顔を切り取るために使われます。
img1_face = cv2.bitwise_and(img1, img1, mask=mask)
マスクを適用して、画像1から
顔を切り出します。
img2 = cv2.seamlessClone(img1_face, img2, mask, (faces2[0].center().x, faces2[0].center().y), cv2.NORMAL_CLONE)
OpenCVのseamlessClone関数を使用して、画像2の顔の位置に画像1の顔を貼り付けます。seamlessClone関数は、画像の貼り付けを自然に行うために使われます。
cv2.imwrite('result.jpg', img2)
最後に、結果を保存します。これで、画像の顔の入れ替えが完了します。
注意点
このツールは、画像の顔が正面を向いており、ランドマークが正確に検出できることを前提としています。また、顔の形状や大きさが大きく異なる場合、完全には合わせられない場合があります。それらの場合には、さらなる手法(ランドマークベースの顔の変形や、ディープラーニングを用いたアプローチなど)が必要になることをご了承ください。
コメント