ここでは、PythonにおけるOpenCVを用いた顔認識してモザイク処理する方法について解説しています。
行ったこと
以下の写真において、顔を認識してモザイク処理を行いました。
プログラム
import cv2, re
#1---ファイル指定
image_file = "women.jpg"
#2---モザイクの割合設定
mosaic_rate = 60
#3---カスケードファイル
cascade_file = "haarcascade_frontalface_alt.xml"
#4---画像の読み込み
image = cv2.imread(image_file)
image_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
#5---顔認識を実行
cascade = cv2.CascadeClassifier(cascade_file)
face_list = cascade.detectMultiScale(image_gray,
scaleFactor=1.1,minNeighbors=1,minSize=(100,100))
#6---モザイク処理
color = (0, 0, 255)
for (x,y,w,h) in face_list:
#7---顔を切り抜く
face = image[y:y+h, x:x+w]
#8---指定倍率で縮小
face = cv2.resize(face, (w//mosaic_rate, h//mosaic_rate))
#9---元のサイズに戻す
face = cv2.resize(face, (w, h),interpolation=cv2.INTER_AREA)
#10---元画像に貼り付け
image[y:y+h, x:x+w] = face
#11---ファイルに書き込む
output_file = re.sub(r'\.jpg|jpeg|png$', '-モザイク処理.jpg', image_file)
cv2.imwrite(output_file, image)
上記がプログラムになります。
それでは解説していきます。
#1---ファイル指定
image_file = "women.jpg"
1の部分ではファイルを指定しています。
#2---モザイクの割合設定
mosaic_rate = 60
2の部分ではモザイク処理する際の粗さを指定しています。
#3---カスケードファイル
cascade_file = "haarcascade_frontalface_alt.xml"
3の部分ではカスケードファイルを指定しています。カスケードファイルの入手方法についてはこちらを参照して下さい。
#4---画像の読み込み
image = cv2.imread(image_file)
image_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
4の部分では画像を読み込んでいます。読み込んだ画像をグレースケールしています。
#5---顔認識を実行
cascade = cv2.CascadeClassifier(cascade_file)
face_list = cascade.detectMultiScale(image_gray,
scaleFactor=1.1,minNeighbors=1,minSize=(100,100))
5の部分では、カスケードファイルを基に顔を認識しています。
#6---モザイク処理
color = (0, 0, 255)
for (x,y,w,h) in face_list:
6の部分ではモザイク処理を行っています。具体的にはfor構文の中でモザイク処理を行っています。
#7---顔を切り抜く
face = image[y:y+h, x:x+w]
7の部分では顔と認識した部分のスケールを指定しています。
#8---指定倍率で縮小
face = cv2.resize(face, (w//mosaic_rate, h//mosaic_rate))
8の部分では指定した倍率で顔の範囲を縮小させています。
#9---元のサイズに戻す
face = cv2.resize(face, (w, h),interpolation=cv2.INTER_AREA)
9の部分では元のサイズに戻しています。ここでは、画像を縮小させてから元に戻すことでモザイク処理としています。「INTER_AREA」はピクセル領域の関係を利用したサンプリングを意味しています。他にも「INTER_NEAREST」という最近傍補間等などもあり、色々と試してみると面白いです。
#10---元画像に貼り付け
image[y:y+h, x:x+w] = face
10の部分では縮小させてから元に戻した画像を元画像に貼り付けています。imageは「image[y1:y2,x1:x2]」という意味になります。
#11---ファイルに書き込む
output_file = re.sub(r'\.jpg|jpeg|png$', '-モザイク処理.jpg', image_file)
cv2.imwrite(output_file, image)
11の部分ではファイルに保存しています。この時、ファイル名を元のファイル名にモザイク処理という言葉を追加しています。最後に「imwrite()」で書き込んで終了です。
結果
モザイク処理の値を30と60の場合で行った結果です。当然ですが、60の方がモザイクが粗くなっていることが分かります。
関数化したら複数の写真を一気にモザイク処理できるなど色々と応用できそうです。