kentsu.dat

何かその時の興味でいろいろする人。最近はScala使ってる。

OpenCV+Pythonで顔にモザイク処理をする

顔にモザイク

最近はずっと画像処理の理論的な部分ばかり勉強していて、これといった成果物を出してないから
簡単に作れるものをとりあえず作ってみようっていうことで
今回は、OpenCV+Pythonで顔にモザイクをかけてみた

顔認識とかはよくわからないしそういったことはまだ勉強してないけど
とりあえず色々調べながら作ってみたけど、なにせpythonは基礎文法レベルでしか書けないから
今回はいろいろと苦労するところがあった

ただリスト形式で画像をあれこれいじれたのでなかなか楽しかった

仕組み

まず顔認識をしようとしても、どういう仕組みかわからない
というわけで画像処理速報さんで調べた結果、やりたいことに近いものがあり
そこで仕組みを説明していたので、自分なりにまとめてみる

実際にこれから紹介する順番でコードを書いている
今回はカスケード型分類器なるものを使った

1,対象画像を読み込む(変数は2つ用意しそれぞれ同じ画像)
2,顔認識用のカスケード型分類器を取得
3,カスケード型分類器で顔認識を行う
4,検出した情報に基づいて顔部分を切り取る
5,切り取った顔の部分にモザイク処理をほどこす
6,モザイク部分を結果出力用画像の一部に貼り付ける
7,結果を表示する

といった具合で顔認識以外はOpenCVで行えるかなり初歩的な処理を組み合わせることで実現できる
(その初歩的な処理を実装できなくて苦戦した)

コード

#coding:utf-8

import numpy as np
import cv2

#顔探索用のカスケード型分類器を取得
face_cascade = cv2.CascadeClassifier(haarcascade_frontalface_default.xmlのパスを渡す)

img = cv2.imread("Lenna.png")
result = cv2.imread("Lenna.png")

#読み込んだ画像をグレースケールに変換
gray = cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)

#分類器で顔を認識する
face = face_cascade.detectMultiScale(gray,1.3,5)

if 0 < len(face):

	print "get face"

	for (x,y,w,h) in face:
		
		#顔の部分だけ切り抜いてモザイク処理をする
		cut_img = img[y:y+h,x:x+w]
		cut_face = cut_img.shape[:2][::-1]
		#10分の1にする
		cut_img = cv2.resize(cut_img,(cut_face[0]/10, cut_face[0]/10))
		#画像を元のサイズに拡大
		cut_img = cv2.resize(cut_img,cut_face,interpolation = cv2.cv.CV_INTER_NN)
		
		#モザイク処理した部分を重ねる
		result[y:y+h,x:x+w] = cut_img

else:

	print "no face"


cv2.imshow("face mosaic",result)
#cv2.imwrite("output file name",result)
cv2.waitKey(0)
cv2.destroyAllWindows()

こんな具合で割と短いコードになった
注意すべきは7行目のカスケード型分類器の取得を行う部分で、ここで渡すのはカスケード分類器のファイル名を含めたパスであること
他のサイトではファイル名のみを渡していたりするがそれだと顔認識が正常に行われない上にエラーとしてもでてこない
つまりバグになるので注意

結果

いつもの例にならって使った画像は以下のLenna.png

f:id:RabbitFoot141:20160219022220p:plain

そしてこれが上のコードで出力したface_mosaic_Lenna.png

f:id:RabbitFoot141:20160219022301p:plain