はじめに
今回は顔の一部、目や口、輪郭にだけ処理を加えたいといった場合を想定しています。
pythonの顔認識ライブラリであるdlibを使用しています。顔の一部ということで目に対して処理を加えました。必要に応じて部位は変更してください。
Dlibで取得できるランドマークは以下の通りです。今回は右目を使用しているので36~41までの座標を使用しています。
生成結果
コード
Faceライブラリはこちらに記載あります。
import cv2
import numpy as np
from face import Face
# 画像の処理内容
def draw(im):
im = cv2.bitwise_not(im)
return im
# どの部位にマスクをかけるか
def masked(shape, frame,):
if not shape is None:
eye_points = shape[36:42]
mask = np.zeros((frame.shape[0], frame.shape[1], 3), dtype=np.float32)
cv2.fillConvexPoly(mask, np.int32(eye_points), (1.0, 1.0, 1.0))
mask = 255*np.uint8(mask)
# Apply close operation to improve mask
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (40,40))
mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel, 1)
# Blur the mask to obtain natural result
mask = cv2.GaussianBlur(mask,(15,15),cv2.BORDER_DEFAULT)
# Calculate inverse mask
inverseMask = cv2.bitwise_not(mask)
# Convert masks to float to perform blending
mask = mask.astype(float)/255
inverseMask = inverseMask.astype(float)/255
eye = draw(frame)
eye = eye.astype(float)/255
ladyFace = frame.astype(float)/255
justLips = cv2.multiply(mask, eye)
justFace = cv2.multiply(inverseMask, ladyFace)
# cat
frame = justFace + justLips
return frame
def main():
video_flag = False
face_detecter = Face()
if video_flag:
capture = cv2.VideoCapture(0)
while(capture.isOpened()):
ret, frame = capture.read()
shape = face_detecter.get_face_point(frame)
frame = masked(shape, frame)
cv2.imshow('frame', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
capture.release()
cv2.destroyAllWindows()
else:
im = cv2.imread('demo.png')
shape = face_detecter.get_face_point(im)
im = masked(shape, im)
cv2.imshow('image', im)
cv2.waitKey(0)
cv2.destroyAllWindows()
if __name__ == "__main__":
main()
おわりに
今回顔の輪郭を切り取って処理を加えたくなり、そのためのコードを書いたので記事にまとめました。これを使えば東京喰種の目の再現なんかもできそうですね。