Insight Face 教科書
【概要】InsightFaceは、オープンソースの2D&3D顔解析フレームワーク。顔検出(RetinaFace・SCRFD),顔認識(ArcFace)の機能を持つ。512次元の特徴ベクトルで顔を数値化してコサイン類似度により類似判定を行う。
目次
第1章 序論
1.1 顔解析技術の歴史的背景と社会的意義
顔解析技術は、1960年代の初期パターン認識研究から始まり、現代のディープラーニング技術によって大きな発展を遂げた。特に2010年代以降、畳み込みニューラルネットワーク(CNN)の発達により、高い精度を実現している。
現代社会において顔解析技術は、セキュリティシステム、個人認証、感情分析、人口統計分析など幅広い分野で活用されている。特に非接触型の生体認証として、COVID-19パンデミック以降、その活用が拡大している。
1.2 InsightFaceの概要
InsightFaceは、オープンソースの顔解析フレームワークである。学術的貢献として、顔検出のSCRFD(ICLR 2022採択)およびRetinaFace(CVPR 2020採択)と顔認識のArcFace(CVPR 2019採択)を開発している。
ライセンス情報:
- コード: MITライセンス(学術・商用利用可能)
- 事前学習済みモデル: 非商用研究目的のみ
必要な前提知識:
- Python プログラミングの基礎
- 機械学習の基本概念
- コンピュータビジョンの基礎知識
第2章 顔解析の技術基盤
2.1 特徴ベクトルと類似度計算
特徴ベクトルとは、顔画像の特徴を数値化した多次元ベクトルである。InsightFaceでは512次元のベクトルとして表現される。
コサイン類似度は、2つのベクトル間の類似性を測定する指標である:
cos(θ) = (A・B) / (|A| × |B|)
ここで、A・Bは内積、|A|、|B|はそれぞれのベクトルのノルムを表す。値域は[-1, 1]で、1に近いほど類似度が高くなる。
2.2 深層学習における顔認識の仕組み
顔認識では、CNNを用いて顔画像から特徴ベクトルを抽出する。学習過程では、同一人物の顔は近い特徴ベクトルに、異なる人物の顔は遠い特徴ベクトルになるように最適化される。
2.3 顔検出と顔認識の違い
必要な前提知識:
- 物体検出の基本概念:画像内の特定の物体(この場合は顔)の位置と境界ボックスを自動的に特定する技術。分類と位置推定を同時に行う
- アンカーベース検出手法:事前に定義された候補領域(アンカー)を基準として物体の位置を予測する検出方式。各アンカーに対して物体の有無と位置調整を学習する
2.4 損失関数と角度マージンの理論
必要な前提知識:
- 損失関数の概念:深層学習において、予測値と正解値の差を定量化する関数。モデルの学習は損失関数を最小化することで行われる
- 角度マージンの数学的意味:特徴ベクトル空間において、同一クラス内の角度を小さく、異なるクラス間の角度を大きくするマージン(余裕)を設ける手法。分離性能の向上に寄与する
2.5 モデル形式とONNXの基礎
必要な前提知識:
- ONNX(Open Neural Network Exchange)の基本概念:異なる深層学習フレームワーク間でモデルを交換するための標準形式。学習されたモデルを他の環境で推論実行するために使用される
- 深層学習モデルの推論処理:学習済みモデルに入力データを与えて予測結果を得る処理。学習とは異なり、重みの更新は行わない
第3章 InsightFaceの技術詳細
3.1 顔検出技術(RetinaFace・SCRFD)
InsightFaceでは、モデルパックに応じて2つの顔検出技術を使用している:
RetinaFace(buffalo系で使用)
- CVPR 2020採択の単段階顔検出手法
- buffalo_l/m/s/scシリーズで採用
- マルチスケールテスト評価に基づく設計
SCRFD(antelopev2で使用)
- ICLR 2022採択の顔検出手法
- Sample Redistribution + Computation Redistributionによる最適化
- VGA解像度(640×480)での処理に特化
計算量による性能階層
- 10GF系(buffalo_l, antelopev2):最高計算量
- 2.5GF系(buffalo_m):中程度計算量
- 500MF系(buffalo_s, buffalo_sc):軽量版
3.2 ArcFace顔認識技術
ArcFaceは、InsightFaceが開発した角度マージン損失による顔認識手法である(CVPR 2019採択)。
学習データセットによる性能差
- WebFace600K系(buffalo_l/m/s/sc):600万枚の顔画像で学習
- Glint360K系(antelopev2):1,700万枚・36万人の大規模データセットで学習により汎化性能が向上
アプリケーションの要求に応じてモデルを選択できる。リアルタイム処理が必要な場合はbuffalo_m、最高精度が必要な場合はantelopev2が適用される。
3.3 処理パイプライン
InsightFaceの顔解析処理は以下の順序で実行される:
[入力画像]
↓
[1. 顔検出(RetinaFace/SCRFD)] → 境界ボックス検出
↓
[2. 顔ランドマーク検出] → 特徴点位置特定
↓
[3. 顔認識(ArcFace)] → 特徴ベクトル抽出
↓
[4. 属性推定] → 年齢・性別推定
↓
[出力結果]
3.4 モデルパック構成
InsightFaceでは以下のモデルパックを提供している:
- buffalo_l:RetinaFace-10GF + ResNet50@WebFace600K
- buffalo_m:RetinaFace-2.5GF + ResNet50@WebFace600K
- buffalo_s:RetinaFace-500MF + MBF@WebFace600K
- buffalo_sc:RetinaFace-500MF + MBF@WebFace600K
- antelopev2:SCRFD-10GF + ResNet100@Glint360K
buffalo系(buffalo_l, buffalo_m, buffalo_s, buffalo_sc)に含まれる5つのONNXファイル:
- det_10g.onnx:顔検出モデル(RetinaFace-10GF)
- w600k_r50.onnx:顔認識モデル(ResNet50@WebFace600K)
- genderage.onnx:年齢・性別推定モデル
- 1k3d68.onnx:3D 68点ランドマークモデル
- 2d106det.onnx:2D 106点ランドマークモデル
antelopev2に含まれる5つのONNXファイル:
- scrfd_10g_bnkps.onnx:顔検出モデル(SCRFD-10GF)
- glintr100.onnx:顔認識モデル(ResNet100@Glint360K)
- genderage.onnx:年齢・性別推定モデル
- 1k3d68.onnx:3D 68点ランドマークモデル
- 2d106det.onnx:2D 106点ランドマークモデル
第4章 環境構築と基本実装
4.1 環境構築と基本設定
目的:InsightFaceの基本的なセットアップを行う
期待される結果:顔解析機能が使用可能な状態になる
import insightface
from insightface.app import FaceAnalysis
# 最高精度(antelopev2使用)
app = FaceAnalysis(name='antelopev2', providers=['CUDAExecutionProvider', 'CPUExecutionProvider'])
app.prepare(ctx_id=0, det_size=(640, 640))
4.1.1 ランドマークモデルの指定方法
InsightFaceではallowed_modules
パラメータを使用して、使用するモジュールを指定できる:
# 1. すべてのモジュールを使用(デフォルト)
app = FaceAnalysis()
# 2. 特定のモジュールのみを使用
app = FaceAnalysis(allowed_modules=['detection', 'recognition'])
# 3. 2D 106点ランドマークのみを使用
app = FaceAnalysis(allowed_modules=['detection', 'landmark_2d_106'])
# 4. 3D 68点ランドマークのみを使用
app = FaceAnalysis(allowed_modules=['detection', 'landmark_3d_68'])
# 5. 両方のランドマークを使用
app = FaceAnalysis(allowed_modules=['detection', 'landmark_2d_106', 'landmark_3d_68'])
# 6. 顔検出のみ
app = FaceAnalysis(allowed_modules=['detection'])
指定可能なモジュール:
'detection'
:顔検出'recognition'
:顔認識'genderage'
:年齢・性別推定'landmark_2d_106'
:2D 106点ランドマーク'landmark_3d_68'
:3D 68点ランドマーク
4.2 基本的な顔検出
目的:画像から顔を検出し、基本情報を取得する
期待される結果:検出された顔の数、位置、キーポイントが出力される
# InsightFace顔検出プログラム
# 静的画像からの顔検出とキーポイント抽出
# 論文: "RetinaFace: Single-Shot Multi-Level Face Localisation in the Wild" (CVPR 2020)
# GitHub: https://github.com/deepinsight/insightface
# 特徴: RetinaFaceアルゴリズムによる高精度顔検出、CNN基盤の深層学習手法
# マルチスケール検出対応、顔境界ボックスと5点キーポイント同時検出
# 学習済モデル: SCRFD(Sample and Computation Redistributed Face Detection)
# 軽量化と高精度を両立した顔検出モデル
# 前準備: pip install insightface opencv-python onnxruntime
import cv2
from insightface import FaceAnalysis
from insightface.data import get_image as ins_get_image
# 定数定義
CTX_ID = 0
DET_SIZE = (640, 640)
TEST_IMAGE = 't1'
# 顔検出用アプリケーション初期化
app = FaceAnalysis(allowed_modules=['detection'])
app.prepare(ctx_id=CTX_ID, det_size=DET_SIZE)
# テスト画像読み込み
img = ins_get_image(TEST_IMAGE)
# メイン処理
faces = app.get(img)
# 結果出力
print(f"検出された顔の数: {len(faces)}")
for i, face in enumerate(faces):
print(f"顔 {i+1}:")
print(f" 境界ボックス: {face.bbox}")
print(f" キーポイント: {face.kps}")
print(f" 検出信頼度: {face.det_score:.3f}")
4.3 顔認識と属性推定
目的:検出された顔から特徴ベクトルを抽出し、属性を推定する
期待される結果:512次元特徴ベクトル、年齢、性別、ランドマーク情報が出力される
# InsightFace顔解析プログラム
# 画像から顔検出・年齢・性別・特徴量抽出を行う包括的顔解析
# 論文: "ArcFace: Additive Angular Margin Loss for Deep Face Recognition" (CVPR 2019)
# GitHub: https://github.com/deepinsight/insightface
# 特徴: ArcFaceアルゴリズムによる高精度顔認識、512次元特徴ベクトル抽出
# 年齢・性別推定、顔ランドマーク検出機能を統合
# 学習済モデル: Buffalo_lモデル(高精度な顔検出・認識用事前学習モデル)
# 前準備: pip install insightface onnxruntime
from insightface.app import FaceAnalysis
from insightface.data import get_image as ins_get_image
# 顔解析アプリケーションを初期化
app = FaceAnalysis()
app.prepare(ctx_id=0, det_size=(640, 640))
# サンプル画像を読み込み
img = ins_get_image('t1')
# メイン処理
faces = app.get(img)
# 結果出力
for i, face in enumerate(faces):
print(f"顔 {i+1}:")
print(f" 特徴ベクトル次元: {len(face.embedding)}")
print(f" 年齢: {face.age:.1f}歳")
print(f" 性別: {'男性' if face.gender == 1 else '女性'}")
if hasattr(face, 'kps') and face.kps is not None:
print(f" 顔ランドマーク: 利用可能")
if hasattr(face, 'landmark_2d_106') and face.landmark_2d_106 is not None:
print(f" 2D 106点ランドマーク: 利用可能")
if hasattr(face, 'landmark_3d_68') and face.landmark_3d_68 is not None:
print(f" 3D 68点ランドマーク: 利用可能")
print(f"\n実行結果の解釈:")
print(f"- 特徴ベクトル: 顔の特徴を512次元の数値で表現")
print(f"- 年齢・性別: 深層学習モデルによる推定値")
print(f"- ランドマーク: 顔の特徴点座標(目、鼻、口など)")
第5章 応用実装とシステム構築
5.1 顔検出のみの実行
目的:認識機能を使わず、検出とランドマーク検出のみを実行する
期待される結果:顔位置とキーポイントのみが出力される
# InsightFace顔検出プログラム
# 静的画像からの顔検出と特徴点抽出
# 論文: "RetinaFace: Single-Shot Multi-Level Face Localisation in the Wild" (CVPR 2020)
# GitHub: https://github.com/deepinsight/insightface
# 特徴: InsightFaceは高精度な顔検出・認識ライブラリ、RetinaFaceベースの検出器搭載
# WIDER FACEデータセットで最高精度、リアルタイム処理対応
# 学習済モデル: buffalo_l(高精度汎用モデル)- 多様な顔向き・照明条件に対応
# 前準備: pip install insightface opencv-python onnxruntime
from insightface.app import FaceAnalysis
import cv2
# 顔検出器の初期化
app = FaceAnalysis(allowed_modules=['detection'])
app.prepare(ctx_id=0, det_size=(640, 640))
# 画像読み込み
img = cv2.imread('test.jpg')
# 顔検出実行
faces = app.get(img)
# 結果出力
for i, face in enumerate(faces):
bbox = face.bbox
kps = face.kps
print(f"顔 {i+1}:")
print(f" 顔の位置: {bbox}")
print(f" キーポイント: {kps}")
5.2 顔照合システム
目的:2つの顔画像が同一人物かを判定する
期待される結果:類似度スコアと同一人物判定結果が出力される
# InsightFace顔認識照合プログラム
# 2つの画像から顔の特徴ベクトルを抽出してコサイン類似度による同一人物判定
# 論文: "ArcFace: Additive Angular Margin Loss for Deep Face Recognition" (CVPR 2019)
# GitHub: https://github.com/deepinsight/insightface
# 特徴: ArcFaceは角度マージンを用いた損失関数により高精度な顔認識を実現
# LFWデータセットで99.83%の精度、Windows環境対応
# 学習済モデル: Buffalo_l(512次元特徴ベクトル、高精度汎用モデル)
# 前準備: pip install insightface opencv-python numpy
from insightface.app import FaceAnalysis
import numpy as np
import cv2
# 定数定義
THRESHOLD = 0.6
IMAGE1_PATH = 'person1.jpg'
IMAGE2_PATH = 'person2.jpg'
# 顔検出と認識の初期化
app = FaceAnalysis(allowed_modules=['detection', 'recognition'])
app.prepare(ctx_id=0, det_size=(640, 640))
# 画像読み込み
img1 = cv2.imread(IMAGE1_PATH)
img2 = cv2.imread(IMAGE2_PATH)
# 顔検出実行
faces1 = app.get(img1)
faces2 = app.get(img2)
# 特徴ベクトル抽出
face1_embedding = faces1[0].embedding
face2_embedding = faces2[0].embedding
# メイン処理
# コサイン類似度計算
similarity = np.dot(face1_embedding, face2_embedding) / (
np.linalg.norm(face1_embedding) * np.linalg.norm(face2_embedding)
)
# 同一人物判定
is_same = similarity > THRESHOLD
# 結果出力
print(f"類似度: {similarity:.3f}")
print(f"同一人物: {'はい' if is_same else 'いいえ'}")
print(f"判定基準: 類似度が{THRESHOLD}以上で同一人物と判定")
第6章 性能最適化と実践的応用
6.1 性能最適化のベストプラクティス
6.1.1 モデル選択による最適化
軽量化が必要な場合:
- buffalo_sまたはbuffalo_scを使用
- det_sizeを(320, 320)に縮小
精度を重視する場合:
- antelopev2を使用
- det_sizeを(640, 640)または(1024, 1024)に設定
6.1.2 処理速度の最適化
# GPU使用時の最適化設定
app = FaceAnalysis(
name='buffalo_l',
providers=['CUDAExecutionProvider'], # GPUのみ指定
)
app.prepare(ctx_id=0, det_size=(640, 640))
# バッチ処理による高速化
def process_multiple_images(images):
results = []
for img in images:
faces = app.get(img)
results.append(faces)
return results
大量の画像を処理する際は、メモリリークを防ぐため定期的にガベージコレクションを実行することが推奨される。また、不要な中間結果は速やかに削除することが推奨される。
6.1.3 精度向上のテクニック
# 高解像度入力による精度向上
app.prepare(ctx_id=0, det_size=(1024, 1024))
# 顔領域の前処理
def preprocess_face_region(img, bbox):
"""顔領域を切り出して正規化"""
x1, y1, x2, y2 = bbox.astype(int)
face_img = img[y1:y2, x1:x2]
# ヒストグラム平坦化による照明正規化
face_gray = cv2.cvtColor(face_img, cv2.COLOR_BGR2GRAY)
face_eq = cv2.equalizeHist(face_gray)
face_normalized = cv2.cvtColor(face_eq, cv2.COLOR_GRAY2BGR)
return face_normalized
6.2 基本的な顔照合
目的:2つの顔画像の類似度を計算する
期待される結果:コサイン類似度と同一人物判定結果が出力される
# InsightFace顔認識類似度計算プログラム
# 2枚の画像から顔の特徴を抽出し類似度を計算して同一人物判定を行う
# 論文: "ArcFace: Additive Angular Margin Loss for Deep Face Recognition" (CVPR 2019)
# GitHub: https://github.com/deepinsight/insightface
# 特徴: ArcFaceは角度マージンを用いた顔認識手法、高精度な顔認識を実現
# コサイン類似度による類似度計算、閾値による同一人物判定機能
# 学習済モデル: InsightFaceの事前学習済みモデル(RetinaFace検出+ArcFace認識)
# 前準備: pip install insightface opencv-python numpy
from insightface.app import FaceAnalysis
import numpy as np
import cv2
# 定数定義
DETECTION_SIZE = (640, 640)
SIMILARITY_THRESHOLD = 0.6
IMAGE1_PATH = 'person1.jpg'
IMAGE2_PATH = 'person2.jpg'
# InsightFace初期化
app = FaceAnalysis(allowed_modules=['detection', 'recognition'])
app.prepare(ctx_id=0, det_size=DETECTION_SIZE)
# 類似度計算関数
def calculate_similarity(embedding1, embedding2):
return np.dot(embedding1, embedding2) / (
np.linalg.norm(embedding1) * np.linalg.norm(embedding2)
)
# メイン処理
# 画像読み込み
img1 = cv2.imread(IMAGE1_PATH)
img2 = cv2.imread(IMAGE2_PATH)
# 顔検出・特徴抽出
faces1 = app.get(img1)
faces2 = app.get(img2)
# 類似度計算
face1_embedding = faces1[0].embedding
face2_embedding = faces2[0].embedding
similarity = calculate_similarity(face1_embedding, face2_embedding)
is_same_person = similarity > SIMILARITY_THRESHOLD
# 結果出力
print(f"類似度: {similarity:.3f}")
print(f"同一人物判定: {'はい' if is_same_person else 'いいえ'}")
print(f"判定基準: 類似度が{SIMILARITY_THRESHOLD}以上で同一人物と判定")
6.3 写真整理アプリケーション
目的:複数の写真を顔の類似度でグループ化する
期待される結果:同一人物の写真がグループにまとめられる
# InsightFace顔認識クラスタリングプログラム
# 複数画像から顔特徴量を抽出し類似度でグループ化
# 論文: "ArcFace: Additive Angular Margin Loss for Deep Face Recognition" (CVPR 2019)
# GitHub: https://github.com/deepinsight/insightface
# 特徴: InsightFaceは深層学習ベースの顔認識ライブラリ、高精度な顔検出・認識機能
# ArcFaceアルゴリズムによる512次元特徴量抽出、コサイン類似度による類似判定
# 学習済モデル: Buffalo_l(精度重視の大型モデル)、RetinaFace検出器とArcFace認識器
# 前準備: pip install insightface opencv-python numpy
from insightface.app import FaceAnalysis
import numpy as np
import cv2
from pathlib import Path
# 定数定義
SIMILARITY_THRESHOLD = 0.6
DETECTION_SIZE = (640, 640)
IMAGE_PATHS = ['photo1.jpg', 'photo2.jpg', 'photo3.jpg', 'photo4.jpg']
# 顔認識アプリケーション初期化
app = FaceAnalysis(allowed_modules=['detection', 'recognition'])
app.prepare(ctx_id=0, det_size=DETECTION_SIZE)
# 各写真から顔特徴を抽出
face_data = []
for img_path in IMAGE_PATHS:
if not Path(img_path).exists():
continue
img = cv2.imread(img_path)
if img is None:
continue
faces = app.get(img)
if len(faces) > 0:
face_data.append({
'path': img_path,
'embedding': faces[0].embedding
})
# 顔グループの作成
groups = []
for face in face_data:
placed = False
for group in groups:
# コサイン類似度計算
similarity = np.dot(face['embedding'], group[0]['embedding']) / (
np.linalg.norm(face['embedding']) * np.linalg.norm(group[0]['embedding'])
)
if similarity > SIMILARITY_THRESHOLD:
group.append(face)
placed = True
break
if not placed:
groups.append([face])
# 結果出力
if len(groups) == 0:
print("処理可能な顔データがありません")
else:
print("=== 顔認識クラスタリング結果 ===")
for i, group in enumerate(groups):
print(f"グループ {i+1} ({len(group)}枚):")
for face in group:
print(f" {face['path']}")
print(f"\n総グループ数: {len(groups)}個")
print(f"類似度閾値: {SIMILARITY_THRESHOLD}")
6.4 出欠確認アプリケーション
目的:教室写真から登録済み学生の出席を確認する
期待される結果:出席者リストと欠席者リストが出力される
# InsightFace顔認識出席確認システム
# 教室写真から学生の出席状況を自動判定
# 論文: "ArcFace: Additive Angular Margin Loss for Deep Face Recognition" (CVPR 2019)
# GitHub: https://github.com/deepinsight/insightface
# 特徴: ArcFaceは角度マージンを導入した高精度顔認識手法、単位球面上での特徴表現
# 顔認識精度LFW 99.83%、MegaFace 98.35%、Windows環境対応
# 学習済モデル: Buffalo_l(精度重視)、Buffalo_s(速度重視)から選択可能
# 前準備: pip install insightface opencv-python numpy
from insightface.app import FaceAnalysis
import numpy as np
import cv2
from pathlib import Path
# 定数定義
DETECTION_SIZE = (640, 640)
SIMILARITY_THRESHOLD = 0.6
CLASSROOM_IMAGE = 'classroom.jpg'
# InsightFace初期化
app = FaceAnalysis(allowed_modules=['detection', 'recognition'])
app.prepare(ctx_id=0, det_size=DETECTION_SIZE)
# 事前登録学生データ
registered_students = {
'student001': np.array([...]),
'student002': np.array([...]),
'student003': np.array([...])}
# 教室写真の読み込み
img_path = Path(CLASSROOM_IMAGE)
img = cv2.imread(str(img_path))
# メイン処理
faces = app.get(img)
present_students = []
for face in faces:
face_embedding = face.embedding
for student_id, registered_embedding in registered_students.items():
similarity = np.dot(face_embedding, registered_embedding) / (
np.linalg.norm(face_embedding) * np.linalg.norm(registered_embedding)
)
if similarity > SIMILARITY_THRESHOLD:
if student_id not in present_students:
present_students.append(student_id)
break
all_students = list(registered_students.keys())
absent_students = [s for s in all_students if s not in present_students]
# 結果出力
print(f"出席者: {present_students}")
print(f"欠席者: {absent_students}")
print(f"出席率: {len(present_students)}/{len(all_students)}")
第7章 用語集
- ArcFace:角度マージン損失を用いた顔認識手法。同一人物の特徴ベクトル間の角度を小さく、異なる人物間の角度を大きくするよう学習する。
- コサイン類似度:2つのベクトル間の角度から算出される類似度指標。値域は[-1, 1]で、1に近いほど類似している。
- Glint360K:1,700万枚・36万人の大規模顔認識データセット。より高い汎化性能を実現する。
- ONNX:Open Neural Network Exchangeの略。異なる深層学習フレームワーク間でモデルを交換するための標準形式。
- RetinaFace:CVPR 2020採択の実用的な単段階顔検出手法。buffalo系モデルパックで使用されている。
- SCRFD:Sample and Computation Redistribution for Face Detectionの略。ICLR 2022採択の効率的な顔検出手法。antelopev2で使用されている。
- WebFace600K:600万枚の顔画像からなる顔認識データセット。標準的な学習データとして使用される。
- 特徴ベクトル:顔画像の特徴を数値化した多次元ベクトル。InsightFaceでは512次元で表現される。
- 顔ランドマーク:顔の重要な特徴点(目、鼻、口など)の座標の座標情報。InsightFaceでは5点キーポイント、2D 106点、3D 68点のバリエーションがある。