Log―STAND ALONE COMPLEX

情報技術の様々なことについて、日々調べたりしたことを書き記しています。

カメラで顔と眼を認識して、目線にモザイク加工(Python3 + OpenCV3 + PIL)

次のサイトを参考に顔全体のモザイクでなく、目線だけにモザイクを入れるものを作成してみました。

www.blog.umentu.work

  • 顔や眼が認識できなくなるとモザイクが外れてしまうので、まだ実用的ではないです。
# -*- coding: UTF-8 -*-

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: 顔判定する最小サイズの指定。
        """

        # イメージをpillowで扱うことのできる形式に変換しておく。
        img_edit = Image.fromarray(image)

        # 顔認識
        faces = self.get_faces(image, min_size)
        # 眼の認識
        eyes = self.get_eyes(image, min_size)
        # face,eyeには(四角の左上のx座標, 四角の左上のy座標, 四角の横の長さ, 四角の縦の長さ) が格納されている。

        # 顔があり かつ 眼もある 場合。
        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]))
                        # 切り抜いた画像を1/20に縮小する。
                        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]))

        # pillow用のデータをOpenCVデータに変換
        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)

        # qを押したら終了。
        k = cv2.waitKey(1)
        if k == ord('q'):
            break

    cap.release()
    cv2.destroyAllWindows()

pythonでText to Speach

py2.7環境でしか実現できなかったのでとりあえず。

>activate py2.7

pyttsxを入れます。

(py2.7)>anaconda search -t conda pyttsx

(py2.7)>anaconda show Primer/pyttsx

(py2.7)>conda install --channel https://conda.anaconda.org/Primer pyttsx

pythonを立ち上げて、、

(py2.7)>python
Python 2.7.13 |Anaconda 4.3.0 (64-bit)| 
||
 

次の4行だけで、話します。

>|python|
>>> import pyttsx
>>> engine = pyttsx.init()
>>> engine.say('Good morning.')
>>> engine.runAndWait()