【python】webカメラの映像に目の周囲だけ自動でモザイク

はじめに

Pythonで自動モザイク等調べるとopencvで顔の検出をしているものが多いが、自分自身は顔の検出にdlibを使用することが多いです。

dlibは精度も高く、顔のランドマークが取得できるため、今回のような目だけモザイクを入れる処理も容易に可能となります。

Dlibの使い方は以下のサイトが参考になります。

https://qiita.com/mimitaro/items/bbc58051104eafc1eb38

結果

元動画

モザイク済み

コード

# -*- coding: utf-8 -*-
from face import Face
import cv2
from PIL import Image, ImageDraw
import numpy as np

def mosaic(img, ratio=0.1):
    small = cv2.resize(img, None, fx=ratio, fy=ratio, interpolation=cv2.INTER_NEAREST)
    return cv2.resize(small, img.shape[:2][::-1], interpolation=cv2.INTER_NEAREST)


# 左上の座標, 右下の座標
def mosaic_area(img, x1, y1, x2, y2, ratio=0.1):
    cp = img.copy()
    cp[y1:y2, x1:x2] = mosaic(cp[y1:y2, x1:x2], ratio)
    return cp


def main():
  face_detecter = Face()
  capture = cv2.VideoCapture(0)

  while(capture.isOpened()):
    ret, frame = capture.read()
    shape = face_detecter.get_face_point(frame)

    if not shape is None:
      frame = mosaic_area(frame, shape[17][0], shape[19][1], shape[26][0], shape[30][1], ratio=0.05)

    cv2.imshow('frame', frame)

    if cv2.waitKey(1) & 0xFF == ord('q'):
      break

  capture.release()
  cv2.destroyAllWindows()

if __name__ == "__main__":
  main()
# -*- coding: utf-8 -*-
import cv2
import dlib
from imutils import face_utils


class Face():
  def __init__(self):
    self.detector = dlib.get_frontal_face_detector() #顔検出器の呼び出し.ただ顔だけを検出する
    self.load_model()
  
  def load_model(self, path="./model/shape_predictor_68_face_landmarks.dat"):
    try:
      self.predictor = dlib.shape_predictor(path) #顔から目鼻などランドマークを出力する
    except Exception as e:
      raise ValueError('can not load predict model.')

  def get_face_point(self, frame):
    gray = cv2.cvtColor(frame, cv2.COLOR_RGB2GRAY) #gray scaleに変換する
    rects = self.detector(gray, 0) #grayから顔を検出

    if not rects:
      return 

    else:
      #顔が認識できればポイントを特定
      shape = self.predictor(gray, rects[0])
      shape = face_utils.shape_to_np(shape)
      return shape

モザイクのコードはこちらを使用しています。https://note.nkmk.me/python-opencv-mosaic/

おわりに

現在作成中の記事で顔を映さなきゃいけなそうな感じになってきたので、取り合えずモザイク貼れるようにしました。

今回のコードは1人用なので複数人に対応したい場合はFace内のrectsの扱いを変えてあげれば良いです。

おすすめの記事