PythonとOpenCVを使って2つの画像の顔を入れ替える

必要なパッケージのインストール

まず、このプロジェクトに必要なパッケージをインストールします。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)

最後に、結果を保存します。これで、画像の顔の入れ替えが完了します。

注意点

このツールは、画像の顔が正面を向いており、ランドマークが正確に検出できることを前提としています。また、顔の形状や大きさが大きく異なる場合、完全には合わせられない場合があります。それらの場合には、さらなる手法(ランドマークベースの顔の変形や、ディープラーニングを用いたアプローチなど)が必要になることをご了承ください。

コメント

タイトルとURLをコピーしました