初めに
みなさんは一度はリア充を爆発させたいと思ったことがあると思います。
とはいえリア充判定はなかなか難しいものです。著者は人といる写真を見るだけでリア充判定してしまうのです。
そこで今回は画像からリア充かどうかを判定してもらい起爆の意思決定に役立てたいと思います。
※本当に起爆はしないでくださいね
実行環境&使用ライブラリ
- GoogleColaboratry
クラウド上で動かせることができるもの。 - MediaPipe
Googleが提供している画像処理ライブラリ。今回はface_detection
を使って顔認識を行う。他にも骨格検出であるpose
や手を検出するhand
がある。
- FER
FERはFace Emotion Recognizerの略のこと。顔から6つの感情をパラメータとして出力する。感情には「恐怖」、「中立」、「幸せ」、「悲しい」、「怒り」、「嫌悪」がある。
概要
リア充判定には画像を使って行います。画像から写っている人の顔をMediaPipe
で認識し、認識された顔をFERを用いていくつかの感情のパラメータを出力します。出力された感情のうちhappy
のパラメータをもとにリア充度合いを判定します。
リア充の定義
今回リア充判定を行う上でこちらでリア充の画像を定義をしていきます。
- 同性、異性に限らず二人以上一緒にいること
- 写っている人が全員が楽しそうであること
今回は以上の二つの条件を満たす画像をリア充画像と定義します。また顔から感情を分析する都合上マスクを着用されると正しく分析されないので定義には含まれませんがマスクが未着用という前提である必要があります。
判定の流れ
画像から判定する流れは以下の通りです。
- 画像を入力
- MediaPipeで画像から顔認証
- 顔認証した部分を抽出
- 抽出した画像をFERで感情分析
- 感情分析で得られたパラメータのうち
happy
のみを抽出 - 抽出した
happy
の平均値を求め閾値を基準に判定 - 起爆の意思決定を求める
コード
必要ライブラリをインストール
!pip install mediapipe
!pip install FER
必要モジュールのインポートとモデルのインスタンスの生成
import cv2
from fer import FER
import mediapipe as mp
emo_detector = FER(mtcnn=True)
mp_face_detection = mp.solutions.face_detection
mp_drawing = mp.solutions.drawing_utils
判定のコード
# 画像の選択
file = input('画像のパスを入力してください')
# 感情リストの定義
emotions = []
# モデルの設定
with mp_face_detection.FaceDetection(
model_selection=1, min_detection_confidence=0.5) as face_detection:
# 画像の読み込み
image = cv2.imread(file)
# 画像の大きさを取得
img_size = image.shape[:3]
original_y = img_size[0]
original_x = img_size[1]
# 画像をGBRからRGBに変更
results = face_detection.process(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
# 認識した顔に対して処理を行う
for idx, detection in enumerate(results.detections):
# 認識した顔の場所を表示
x = int(detection.location_data.relative_bounding_box.xmin*original_x)
y = int(detection.location_data.relative_bounding_box.ymin*original_y)
h = int(detection.location_data.relative_bounding_box.height*original_y*1.5)
w = int(detection.location_data.relative_bounding_box.width*original_x*1.5)
# 認識した顔を抽出
face_image = image[y:y+h,x:x+w,:3]
# 検出した顔の感情を予測
captured_emotion = emo_detector.detect_emotions(face_image)
# happyのパラメータのみ抽出
happy = captured_emotion[0]['emotions']['happy']
# 感情リストに追加
emotions.append(happy)
# リア充判定
if len(emotions)>1 and sum(emotions)/len(emotions)>=0.85:
print('この写真はリア充の写真です。')
explosion = input('爆破しますか?y/N')
else:
print('この写真はリア充の写真ではありません。')
ライブラリをメインに使っているので案外短いコードでしたね。
detection.location_data.relative_bounding_box
で取得できる値は画像の大きさに対して正規化されているので画像の大きさを掛けることで元の位置に戻す処理をしています。
今回は検出した顔が2つ以上かつ検出された顔の幸せ度合いの平均が0.85以上ならリア充判定としています。幸せ度合いを平均している理由は個人ではなく全体の雰囲気が煌めいているかどうかを表したいためです。
最後に
いかがだったでしょうか。色々試してみると、写っている全員の顔を検出できないことがたまにあるのでめちゃくちゃ幸せそうなカップルの画像なのにリア充ではないと判断されることがありました。とはいえ感情分析はかなり納得の精度ではあるのでまだ改善の余地はあるものの起爆の意思決定の一つにはなるのではないでしょうか。
まぁ、起爆する人がいなくなるくらい世界中が幸せで溢れるのが一番です。