JetsonNanoで顔認証(face_recognition)②
- 2019.10.09
- Jetson

前回(https://kocoffy.com/programmer_cat/jetson/post-110/)、顔認証を行うための準備で終わってしまいましたので今回はその続きからです。
face_recognitionライブラリのサンプルをまずは実際に動かしてみようと思います。
サンプルの作成
以下のコードをコピーしてテキストエディタに貼り付け.py形式で保存します。
→https://github.com/ageitgey/face_recognition/blob/master/examples/facerec_from_webcam_faster.py
コードは以下のようになっています(サンプルとして使用している画像も同ディレクトリ内にあります。)
コメント欄はGoogle翻訳済み
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
import face_recognition import cv2 import numpy as np # これは、Webカメラからのライブビデオで顔認識を実行するデモです。それは他の例よりも少し複雑ですが、 # 物事をはるかに速く実行するためのいくつかの基本的なパフォーマンスの調整が含まれています。 # 1. 1/4の解像度で各ビデオフレームを処理します(ただし、フル解像度で表示します) # 2. ビデオの他のすべてのフレームでのみ顔を検出します。 # 注意:この例では、OpenCV( `cv2`ライブラリ)をインストールして、Webカメラから読み取る必要があります。 # OpenCVは、face_recognitionライブラリを使用するために*必須*ではありません。この特定のデモを実行する場合に # のみ必要です。インストールに問題がある場合は、代わりにそれを必要としない他のデモを試してください。 # ウェブカメラ0(デフォルト)への参照を取得します video_capture = cv2.VideoCapture(0) # サンプル画像を読み込み、それを認識する方法を学びます。 obama_image = face_recognition.load_image_file("obama.jpg") obama_face_encoding = face_recognition.face_encodings(obama_image)[0] # 2番目のサンプル画像を読み込み、それを認識する方法を学びます。 biden_image = face_recognition.load_image_file("biden.jpg") biden_face_encoding = face_recognition.face_encodings(biden_image)[0] # 既知の顔エンコーディングとその名前の配列を作成します known_face_encodings = [ obama_face_encoding, biden_face_encoding ] known_face_names = [ "Barack Obama", "Joe Biden" ] # 変数を初期化する face_locations = [] face_encodings = [] face_names = [] process_this_frame = True while True: # Grab a single frame of video ret, frame = video_capture.read() # ビデオのフレームを1/4サイズにサイズ変更して、顔認識処理を高速化 small_frame = cv2.resize(frame, (0, 0), fx=0.25, fy=0.25) # 画像をBGRカラー(OpenCVが使用)からRGBカラー(face_recognitionが使用)に変換します rgb_small_frame = small_frame[:, :, ::-1] # 時間を節約するために、ビデオの他のすべてのフレームのみを処理します if process_this_frame: # ビデオの現在のフレームですべての顔と顔のエンコードを検索します face_locations = face_recognition.face_locations(rgb_small_frame) face_encodings = face_recognition.face_encodings(rgb_small_frame, face_locations) face_names = [] for face_encoding in face_encodings: # 顔が既知の顔と一致するかどうかを確認します matches = face_recognition.compare_faces(known_face_encodings, face_encoding) name = "Unknown" # # known_face_encodingsで一致が見つかった場合は、最初の一致を使用します。 # if True in matches: # first_match_index = matches.index(True) # name = known_face_names[first_match_index] # または、新しい顔までの距離が最小の既知の顔を使用します face_distances = face_recognition.face_distance(known_face_encodings, face_encoding) best_match_index = np.argmin(face_distances) if matches[best_match_index]: name = known_face_names[best_match_index] face_names.append(name) process_this_frame = not process_this_frame # 結果を表示する for (top, right, bottom, left), name in zip(face_locations, face_names): # 検出したフレームが1/4サイズに縮小されたため、顔の位置を縮小します top *= 4 right *= 4 bottom *= 4 left *= 4 # 顔の周りにボックスを描く cv2.rectangle(frame, (left, top), (right, bottom), (0, 0, 255), 2) # 顔の下に名前の付いたラベルを描く cv2.rectangle(frame, (left, bottom - 35), (right, bottom), (0, 0, 255), cv2.FILLED) font = cv2.FONT_HERSHEY_DUPLEX cv2.putText(frame, name, (left + 6, bottom - 6), font, 1.0, (255, 255, 255), 1) # 結果の画像を表示する cv2.imshow('Video', frame) # キーボードの「q」を押して終了します! if cv2.waitKey(1) & 0xFF == ord('q'): break # Webカメラへのハンドルを解放する video_capture.release() cv2.destroyAllWindows() |
実行するとこんな感じです。
スマホ越しでも一応認証できてます。(粗くてすみません)
ライブラリの関数について
最後に今回のサンプルで使用したface_recognitionライブラリの関数を簡単に説明します。
・load_image_file
→画像ファイル(jpeg,pngとか)をnumpy配列に変換します。
・face_encodings
→指定した画像を長さ128のfloat型配列に変換します。またあらかじめ顔の位置が分かって
・face_encodings
→指定した画像を長さ128のfloat型配列に変換します。またあらかじめ顔の位置が分かって
いる場合は続けてface_locationsを指定することができます。(複数人移っている時用?)
num_jittersはサンプリング回数です。n倍精度が上がりますがn倍遅くなります。
・face_locations
→指定した画像の顔の位置(上、右、下、左)を返します。
続けて引数にint方の値(デフォルトは1)を指定することで数値が大きいほど小さい顔でも
num_jittersはサンプリング回数です。n倍精度が上がりますがn倍遅くなります。
・face_locations
→指定した画像の顔の位置(上、右、下、左)を返します。
続けて引数にint方の値(デフォルトは1)を指定することで数値が大きいほど小さい顔でも
検出できるようになります。
・compare_faces
・compare_faces
→エンコーディング済みのリスト(複数人)、比較する人(エンコード済み)を引数にリスト
の中に同一人物が存在するか探します。True/Falseで返します。
また、引数に続けて数値(デフォルトは0.6)を指定することでたとえば0.5を指定するとより
また、引数に続けて数値(デフォルトは0.6)を指定することでたとえば0.5を指定するとより
厳密に比較を行います。
・face_distance
→エンコーディング済みのリスト(保存してある複数人)、比較する人間(エンコード済み)
・face_distance
→エンコーディング済みのリスト(保存してある複数人)、比較する人間(エンコード済み)
を引数に各比較対象の顔のユークリッド距離を計算します。リストと同じ順序、サイズで
それぞれユークリッド距離値に差し替えた配列を返します。
ユークリッド距離は顔がどれほど似ているか(特徴点値の距離の近さ)を示します。小さけ
ユークリッド距離は顔がどれほど似ているか(特徴点値の距離の近さ)を示します。小さけ
れば小さいほど似ているということです。(デフォルトの0.6以下だと一応同一人物と判断
できる)
-
前の記事
JetsonNanoをリモートデスクトップで操作する 2019.07.25
-
次の記事
Pycharmのインストール 2020.03.24