※ replitで「You've used up all your Development time」というメッセージが出た人は
こちらを参考にして新しくreplitのアカウントを作ってください。
※ 本題に入る前に、必ず動画の
連絡
を見てください。
- リサイズ
- パラメータによる顔検出精度の調整
- 顔検出
- 顔にぼかしを入れる
- 顔にモザイクを入れる
元画像の選定
今回の課題では顔検出を行うため、人物が写っている写真を元画像として使用する。
TEMPLATE PARTY では、AIで生成された人物の写真が多く見つけられる。写真は以下の条件を満たすものにする
- 実写, もしくはAI生成の実写風のもの。
- 正面を向いた複数の人物が写っている。
例 (これは解説で使用しているものなのでこれを元画像として使ってはいけない)
顔検出
OpenCVで顔検出を行うには、まず「顔検出器」を用意する必要がある。
XML形式で記述されたファイルから顔検出器を作ることもできるが、OpenCVのデフォルトの顔検出器を使う場合は以下のようにすれば顔検出器 face_cascade が使える。
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
画像 image で顔検出を行う命令は例えば以下のようになる。
faces = face_cascade.detectMultiScale(image, scaleFactor=1.05, minNeighbors=5, minSize=(30, 30))
この場合、画像を1/1.05のサイズに縮小して検出、さらに1/1.05のサイズに…のように連続して処理を行い、5回以上顔として認識されたところを顔として検出する。
このとき、元画像で30x30ピクセル未満のサイズの部分は顔とは判定しない。
また、左辺のfacesは顔と判定された領域配列で、配列の要素にはその顔のエリアの情報、具体的には「左上のx座標, 左上のy座標, 横幅, 高さ」が含まれる。
顔にぼかしを入れる
顔検出を行うと faces は顔のエリアの配列になるので、その要素すべてについて
- 元画像からそのエリアを切り出す
- 切り出した画像に平滑化処理を行う
- 平滑化した (小さい) 画像を元画像に上書き
という処理を行えば、顔の部分だけをぼかすことができる。
for (x, y, w, h) in faces:
face = image[y:y+h, x:x+w]
blurred_face = cv2.GaussianBlur(face, (99, 99), 30)
image[y:y+h, x:x+w] = blurred_face
顔にモザイクを入れる
平滑化するかわりに
- 切り出した画像を1/10に縮小する
- 縮小した画像を (切り出し時点と) 同じサイズに拡大する
という処理を行えば、顔の部分にモザイクがかかる。
for (x, y, w, h) in faces:
face = image[y:y+h, x:x+w]
face = cv2.resize(face, (w//10, h//10))
face = cv2.resize(face, (w, h), interpolation=cv2.INTER_NEAREST)
image[y:y+h, x:x+w] = face