次のサイトを参考に顔全体のモザイクでなく、目線だけにモザイクを入れるものを作成してみました。
www.blog.umentu.work
- 顔や眼が認識できなくなるとモザイクが外れてしまうので、まだ実用的ではないです。
import cv2
import math
import numpy as np
import os
from PIL import Image
class Eye(object):
"""
顔認識して色々遊ぶ関数
"""
def get_faces(self, image, min_size=(20, 20)):
"""
顔を取得するメソッド。
image: cv2.imreadで読み取った変数
min_size: 顔判定する最小サイズの指定。
"""
cascade_path = os.path.dirname(os.path.abspath(__file__)) + "/haarcascade_frontalface_alt.xml"
cascade = cv2.CascadeClassifier(cascade_path)
enclosed_faces = image
frame_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
"""
minSize で顔判定する際の最小の四角の大きさを指定できる。
(小さい値を指定し過ぎると顔っぽい小さなシミのような部分も判定されてしまう。)
"""
faces = cascade.detectMultiScale(frame_gray, scaleFactor=1.1, minNeighbors=1, minSize=min_size)
return faces
def get_eyes(self, image, min_size=(5, 5)):
"""
眼を取得するメソッド。
image: cv2.imreadで読み取った変数
min_size: 顔判定する最小サイズの指定。
"""
cascade_path = os.path.dirname(os.path.abspath(__file__)) + "/haarcascade_eye.xml"
cascade = cv2.CascadeClassifier(cascade_path)
enclosed_eyes = image
frame_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
"""
minSize で顔判定する際の最小の四角の大きさを指定できる。
(小さい値を指定し過ぎると顔っぽい小さなシミのような部分も判定されてしまう。)
"""
eyes = cascade.detectMultiScale(frame_gray, scaleFactor=1.1, minNeighbors=1, minSize=min_size)
return eyes
def get_mosaic_eyes(self, image, min_size=(30, 30), ratio=20):
"""
目線をモザイクで覆うメソッド。
image: cv2.imreadで読み取った変数
min_size: 顔判定する最小サイズの指定。
"""
img_edit = Image.fromarray(image)
faces = self.get_faces(image, min_size)
eyes = self.get_eyes(image, min_size)
if len(faces) and len(eyes) > 0:
for face in faces:
for eye in eyes:
if face[0] < eye[0] and face[0]+face[2] > eye[0] + eye[2] and\
face[1] < eye[1] and face[1] + face[3] > eye[1] + eye[3]:
cut_eye_line = img_edit.crop((face[0],
eye[1],
face[0] + face[2],
eye[1] + eye[3]))
cut_eye_line = cut_eye_line.resize((int(face[2] / ratio), int(eye[3] / ratio)), Image.LINEAR)
cut_eye_line = cut_eye_line.resize((face[2], eye[3]), Image.LINEAR)
img_edit.paste(cut_eye_line, (face[0], eye[1]))
img_opencv = np.asarray(img_edit)
return img_opencv
if __name__ == '__main__':
eye = Eye()
cap = cv2.VideoCapture(0)
i = 0
while (True):
ret, frame = cap.read()
cv2.imshow('Origin', frame)
frame = eye.get_mosaic_eyes(frame, ratio=20)
cv2.imshow('MOSAIC eye', frame)
k = cv2.waitKey(1)
if k == ord('q'):
break
cap.release()
cv2.destroyAllWindows()