MediaPipeの動作テスト
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

73 lines
2.9 KiB

import cv2
import numpy as np
import mediapipe as mp
from mediapipe.tasks import python
from mediapipe.tasks.python import vision
# 1. クラスのセットアップ (FaceLandmarkerに変更)
BaseOptions = python.BaseOptions
FaceLandmarker = vision.FaceLandmarker
FaceLandmarkerOptions = vision.FaceLandmarkerOptions
VisionRunningMode = vision.RunningMode
# 2. 顔ランドマーカーの設定
# 変換行列(顔の向きデータ)を出力するようにフラグを立てます
options = FaceLandmarkerOptions(
base_options=BaseOptions(model_asset_path='face_landmarker.task'),
running_mode=VisionRunningMode.VIDEO,
output_facial_transformation_matrixes=True, # 顔の向き取得に必須
num_faces=1 # 検出する顔の最大数
)
cap = cv2.VideoCapture(0)
# FaceLandmarkerのインスタンスを生成
with FaceLandmarker.create_from_options(options) as landmarker:
while cap.isOpened():
success, frame = cap.read()
if not success:
break
rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
frame_timestamp_ms = int(cap.get(cv2.CAP_PROP_POS_MSEC))
# 稀にタイムスタンプが0や重複になるのを防ぐ安全策
if frame_timestamp_ms == 0:
frame_timestamp_ms = 1
mp_image = mp.Image(image_format=mp.ImageFormat.SRGB, data=rgb_frame)
# 3. 検出の実行
result = landmarker.detect_for_video(mp_image, frame_timestamp_ms)
# 4. 変換行列から顔の向き(オイラー角)を計算
if result.facial_transformation_matrixes:
for matrix in result.facial_transformation_matrixes:
# 4x4の変換行列から、左上の3x3の回転行列のみを抽出
rot_mat = matrix[:3, :3]
# OpenCVを使って回転行列をオイラー角(度数法)に分解
angles, _, _, _, _, _ = cv2.RQDecomp3x3(rot_mat)
# ピッチ(上下), ヨー(左右), ロール(傾き)の取得
# ※カメラや座標系によって軸の順番は変わる場合があります
pitch = angles[0]
yaw = angles[1]
roll = angles[2]
# 画面上に角度を描画
text_pitch = f"Pitch (Up/Down): {pitch:.1f}"
text_yaw = f"Yaw (Left/Right): {yaw:.1f}"
text_roll = f"Roll (Tilt): {roll:.1f}"
cv2.putText(frame, text_pitch, (20, 40), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 255), 2)
cv2.putText(frame, text_yaw, (20, 70), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 255), 2)
cv2.putText(frame, text_roll, (20, 100), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 255), 2)
cv2.imshow('MediaPipe Face Orientation', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()