fullseye

手の 21 キーポイントと指屈曲角 — 使い方ガイド

呼び出しモデル: この族は apply(img, "<op名>", a, b) の 2 つまみ規約ではなく、 ファサード関数(import fullseye; fullseye.hand_landmarks(...))です。 検出結果が dict のリストという構造化データで、a/b の連続つまみに馴染まないため。 検証済みテスト: tests/test_handpose.py (幾何 = 伸びきり 0° / 直角 90° / 描画非破壊 / fail-closed を機械検証)。

この族は何をする道具箱か

写真・動画から手の 21 キーポイント(手首 1 + 各指 4×5)を取り、そこから 指 5 本の屈曲角を計算するための入口です。位置づけは Physical AI ブリッジ —— 「人の動きを見て、ロボットに写す」パイプラインの手版の第一歩です。

依存と fail-closed(重要)

検出だけ optional extra です。mediapipe(Apache-2.0)と手モデル hand_landmarker.task(~8MB、Apache-2.0)が要り、どちらか欠けると 導入手順つきの明示エラーを送出します(黙って空リストは返しません)。 幾何側(finger_flexions / hand_skeleton_edges / draw_hand_landmarks)は numpy のみで動きます。

py -3.11 -m pip install mediapipe
curl -L -o %USERPROFILE%/.cache/fullseye/hand_landmarker.task ^
    https://storage.googleapis.com/mediapipe-models/hand_landmarker/hand_landmarker/float16/1/hand_landmarker.task

代表的なパイプライン(op の繋がり)

flowchart LR
  img["写真 / 動画フレーム<br/>image(HxW / HxWx3)"] --> det["hand_landmarks<br/>21 点 x 手"]
  det --> flex["finger_flexions<br/>指 5 本の屈曲角[deg]"]
  det --> draw["draw_hand_landmarks<br/>注釈画像"]
  flex --> ret["正規化 [0,1]<br/>→ ロボットハンド指令(構想)"]
  det -.->|骨格語彙| skel["hand_skeleton_edges<br/>(junctions/branches と同じ発想)"]

使い方

import numpy as np
import handpose as H

# --- 検出(mediapipe + モデルが要る。無ければ導入手順つきエラー)---
# dets = H.hand_landmarks(rgb_image)          # list[dict]

# --- 幾何は numpy だけで動く: 合成 world 座標で屈曲角を確かめる ---
w = np.zeros((21, 3))
for f, chain in enumerate(H.FINGERS.values()):
    d = np.array([1.0, 0.15 * f, 0.0]); d /= np.linalg.norm(d)
    for j, idx in enumerate(chain):
        w[idx] = 0.03 * (j + 1) * d                 # 全指伸びきり(手首から放射直線)
flex = H.finger_flexions({"world_landmarks": w})
assert all(abs(v) < 0.1 for v in flex.values())     # 伸びきり = 0°

mcp, pip, dip, tip = H.FINGERS["index"]
w[dip] = w[pip] + (0.0, 0.0, 0.03)                  # 人差し指を PIP で直角に折る
w[tip] = w[dip] + (0.0, 0.0, 0.03)
flex = H.finger_flexions({"world_landmarks": w})
assert abs(flex["index"] - 90.0) < 0.1              # 直角 = 90°
print({k: round(v, 1) for k, v in flex.items()})

デモ(画像 1 枚 / Web カメラ 1 フレーム): examples/hand_tracking_demo.py

正直な現状と落とし穴

関連