【OpenCV】画像の顔検出&モザイク処理【Python】
こんにちは!こーたろーです。
OpenCVトレーニング第3回目は、モザイク処理です。
第2回目で顔を検出しましたので、その検出した顔に対してモザイク処理をしてみます。
今回もサンプル画像はフリー素材から持ってきて、やっていきます。
それでは早速ハンズオンやっていきましょう!
ライブラリのインポート
これまで通り、画像を制御するためのOpenCVと画像を表示するためのmatplotlib、画像をWebから取得するためのurllibをインポートします。
import cv2 import matplotlib.pyplot as plt import urllib.request as req
画像データの取得
フリー画像を検索して、画像のURLをコピーしてurlとして変数に格納しておきます。
Webリクエストした画像を変数に入れて保存(img)します。
その後、RGBの3チャネルの画像を、顔検出のためにグレースケールに変換して別変数(img_gray)へ格納します。
url = "https://pbs.twimg.com/media/DfQN7W8V4AECxVc?format=jpg&name=large" req.urlretrieve(url, "face_download.jpg") img = cv2.imread("face_download.jpg") img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
カスケードファイルの定義と検出器の作成・顔の検出
顔検出のためのカスケードファイルを準備します。
"haarcascade_frontalface_alt.xml"をGitHubからダウンロードし、ルートフォルダ内に配置しておきます。
cascade.detectMultiScale関数を使って、顔を検出します。複数検出した場合は、tupleの配列としてface_listに格納されます。
今回は2つの顔が検出されました。
cascade_file = "haarcascade_frontalface_alt.xml" cascade = cv2.CascadeClassifier(cascade_file) face_list = cascade.detectMultiScale(img_gray, minSize = (150, 150)) for x, y, w, h in face_list: print("顔の座標 =", x, y, w, h) cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), thickness = 5) plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)) plt.show()
モザイク処理の定義
モザイク処理をする関数を定義します。
モザイク処理の関数へは、face_listのtupleを渡します。
それから、モザイクの粒度をsizeとして定義し引数として渡します。
結果、「元の画像」「検出したface_list」「モザイクサイズ」を引数としています。
def mosaic(img, coordinate, size): (x, y, h, w) = coordinate x2 = x + w y2 = y + h img_coordinate = img[y:y2, x:x2] img_small = cv2.resize(img_coordinate, (size, size)) img_mosaic = cv2.resize(img_small, (w, h), interpolation = cv2.INTER_AREA) img2 = img.copy() img2[y:y2, x:x2] = img_mosaic return img2
モザイク処理では、検出した顔画像の部分を切り取って、リサイズにて一度小さくしたうえで、再度サイズを復元します。
この際に、「interpolation」として、画素の補間について定義しています。
今回は「INTER_AREA」を選択しています。これは、ピクセル領域の関係を利用したリサンプリング方法になります。
他にも、
- 「INTER_NEAREST : 最近傍補間」
- 「INTER_LINEAR : バイリニア補間」
- 「INTER_CUBIC : バイキュービック補間」
- 「INTER_LANCZOS4 : Lanczos 補間」などがあります。
最後に、モザイクをかけた部分について、原画像の顔部分のデータと差し替えてモザイク処理完了です。
モザイク処理後の結果の表示
モザイク処理を実際に実行し、その結果を表示させます。
for (x, y, w, h) in face_list: img = mosaic(img, (x, y, w, h), 10) plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)) plt.show()
無事に顔を検出した領域にモザイクを掛けることができました。
調べた結果、この方法での顔検出は、横向きや顔の軸が回転している場合には検出が難しいようです。
それを鑑みて、次回は別の手法での顔検出を行ってみたいと思います。
ではでは。
OpenCVではじめよう ディープラーニングによる画像認識