Files
SignageSystem/README.md
T

458 lines
35 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Phase 1〜8 人物検知・声掛け研究/統計解析システム
デジタルサイネージ付近の通行人に対する声掛け研究の基盤です。Webカメラまたは動画を入力し、Ultralytics YOLOで現在フレームの人物をリアルタイム検出します。
## Phase 8の概要
Phase 8は複数セッションの `*_person_analysis_table.csv` を読み込み、Prompt条件とControl条件の反応率、reaction time、最大Yaw変化、Turn level、除外理由を比較するオフライン解析です。解析時にカメラ、YOLO、MediaPipeは初期化しません。
```powershell
python main.py analyze --input data/logs/unified --output data/analysis
python main.py analyze --input data/logs/unified --output data/analysis --no-analysis-plots
```
主解析の反応率は次の定義です。
```text
response_rate = response_detected_count / valid_for_voice_analysis=True の人数
```
`valid_for_voice_analysis=False`はno responseではなく分析対象外です。顔向き評価不能者を分母や非反応へ混ぜません。
反応率は期待度数が小さい場合にFisherの正確確率検定、十分な場合にカイ二乗検定を自動選択します。数値指標は既定でMann–Whitney U検定を使い、rank-biserial correlationを効果量として保存します。反応率では率差、オッズ比、カイ二乗時のφ係数を保存します。
出力CSV:
- `condition_summary.csv`
- `response_rate_test.csv`
- `numeric_comparisons.csv`
- `turn_level_distribution.csv`
- `exclusion_summary.csv`
- `analysis_run_summary.csv`
出力グラフ:
- `response_rate_by_condition.png`
- `reaction_time_by_condition.png`
- `max_yaw_delta_by_condition.png`
- `turn_level_distribution.png`
- `exclusion_reason_counts.png`
p値は「条件間に差がない」という仮説のもとで、観測差以上が得られる確率です。小さいp値は差の可能性を示しますが、音声が原因で振り向いたことを直接証明しません。サンプル数が少ないと検出力が低いため、p値だけでなく効果量と各条件の分母を確認してください。
PromptとControlは同一trigger、response window、カメラ配置で比較し、session IDと `camera_position_note`を確認してください。評価不能が多い場合はカメラ配置、Face ROI、照明を見直します。Phase 9ではログ選択・条件切替・結果閲覧GUIを追加予定です。
## Phase 7の概要
Phase 7はtracking、turn、voice、person stateの重要イベントを同一のsession ID・時刻軸・track IDへ統合します。既存ログを置き換えず、`data/logs/unified/`へ次の解析用CSVを追加します。
- `*_unified_events.csv`: source付き時系列イベント
- `*_person_analysis_table.csv`: prompt/control共通列を持つ人物単位解析表
- `*_session_summary.csv`: セッション集計
- `*_log_consistency_issues.csv`: 非致命的な整合性警告
sourceはtracking、face、turn、voice、person_state、session、systemです。既定では巨大化を避けるためface frameは統合イベントに含めず、人物summary側へ反映します。全ファイルへ実行ごとのsession IDとexperiment IDを保存します。
`person_analysis_table.csv`はprompt condition、prompt/pseudo、response、reaction time、Turn、顔・Pose成功率、分析可否、除外理由、カメラ位置メモを同じ列構造で保持します。`valid_for_turn_analysis=false`は「振り向かなかった」ではなく評価不能です。
セッションのresponse rateは次の定義です。
```text
response_detected_count / valid_voice_analysis_tracks
```
全trackを分母にせず、顔向き評価不能者をno responseへ混ぜません。これは観測結果の集計であり、声掛けとの因果関係を断定するものではありません。
カメラ位置は結果に大きく影響するため、実行ごとに記録してください。
```powershell
python main.py --config config/experiment.yaml --voice-mode prompt --camera-position-note "サイネージ正面寄り。顔が見える位置。"
python main.py --config config/experiment.yaml --voice-mode control --camera-position-note "サイネージ正面寄り。顔が見える位置。"
python main.py --config config/experiment.yaml --disable-unified-logging
```
整合性チェックは、promptなしresponse、負のreaction time、turnなしresponse、windowなしprompt、control以外のpseudo、unknown条件、除外理由欠落、summary重複をwarningとして記録し、アプリを停止しません。
## Phase 6の概要
`PersonStateManager`はTrack、Face、Turn、Voiceの既存モジュールを置き換えず、track IDをキーに結果を統合します。track IDは実行中だけ有効な一時IDであり、顔認証や個人識別ではありません。
状態は `new / tracked / inside_region / eligible / prompted / pseudo_prompted / observing_response / responded / no_response / completed / excluded / not_evaluable / lost` です。promptとcontrolは同じ遷移を使い、音声提示だけを`prompted`、無音の観測開始を`pseudo_prompted`として区別します。
顔未検出は「見ていない」ではなく評価不能です。no face、no pose、baseline不足、短いtrack、prompt失敗、prompt前/観測中lostなどを統一除外理由へ変換します。既定ではnot evaluableを即座にexcludedへ統合せず、標本構成を確認できるよう別状態で保存します。
追加ログは `data/logs/person_state/` に保存されます。
- `*_person_state_frames.csv`: 更新ごとの統合状態
- `*_person_state_events.csv`: 状態遷移
- `*_person_state_summary.csv`: 人物単位のTrack/Face/Turn/Voice統合結果
Phase 5相当へ戻す場合:
```powershell
python main.py --config config/experiment.yaml --disable-person-state
```
prompt/controlの実機確認では、tracked→inside→eligible→promptedまたはpseudo→observing→responded/no_response→completedの遷移とCSVを確認してください。tracker無効時はtrack IDがないためPerson Stateも自動無効になります。face/turn無効時は関連値をNoneまたはnot evaluable、voice無効時はvoice disabledとして統合します。
## Phase 5の概要
Phase 5は、track ID付きのライン通過などを契機に短い音声を再生し、その後のPhase 4 `turn_confirmed` を反応観測として関連付けます。記録される `reaction_time_sec` は「音声またはpseudo prompt後に振り向きが観測された時間」であり、声掛けとの因果関係を断定する値ではありません。track IDも実行中だけ有効な一時IDで、個人識別ではありません。
モードは次の3種類です。
- `prompt`: 条件成立時にpygameで音声を非同期再生
- `control`: 音声を鳴らさず、同じ条件成立時刻をpseudo promptとして保存
- `disabled`: Phase 4相当として声掛け制御とvoice CSVを無効化
既定の `trigger_line_crossing` は人物との距離・位置を揃えやすく、再現性が高いため推奨します。ほかに `region_entry`、`fixed_x_position`、デバッグ用の `first_confirmed_track` を選択できます。同一trackへの声掛けは原則1回で、連続通過時は `global_cooldown_sec` により過剰再生を抑えます。
音声ファイルはユーザーが `assets/audio/prompt.wav` へ配置してください。MP3/WAVに対応するpygameを使用します。ファイルが存在しない、pygame初期化に失敗する、再生デバイスがない場合は警告と `prompt_failed` を記録して映像処理を継続します。実験時は1〜2秒程度の固定音声を使い、PC・スピーカー音量と設置位置を一定にしてください。
```powershell
python main.py --config config/experiment.yaml --voice-mode prompt
python main.py --config config/experiment.yaml --voice-mode control
python main.py --config config/experiment.yaml --disable-voice
python main.py --audio-file assets/audio/prompt.wav --voice-volume 0.8
```
`response_window_sec`(既定3秒)以内にweak以上の確定振り向きが発生すると `response_detected=true` とし、prompt/pseudo promptからの経過を `reaction_time_sec` に保存します。subtleとface appearedは補助情報であり、単独ではresponse確定にしません。Turnが無効または評価不能なら `valid_for_voice_analysis=false` として除外理由を残します。
出力は `data/logs/voice/` の3種類です。
- `*_voice_decisions.csv`: eligibility、skip理由、再生成否
- `*_voice_events.csv`: prompt/pseudo prompt、観測開始、response、期限切れ、最終化
- `*_voice_summary.csv`: 人物ごとのprompt時刻、反応時間、最大Yaw変化、分析可否
音声が鳴らない場合は、ファイルパス、Windowsの出力デバイス、音量、`audio.enabled`、`voice_prompt.mode`、pygame導入を確認してください。tracker無効時はVoiceも自動無効になります。Turn無効時もprompt/controlは実行できますが、反応分析は無効です。
## Phase 4の概要
`HeadPoseResult.yaw` のtrack ID別時系列から基準Yawとの差を計算し、サイネージ方向への顔向き変化を検出します。顔が検出できないことは「見ていない」ではなく「評価不能」です。全追跡人物を、評価可能な振り向きあり/なしと、評価不能へ明確に分離します。
`turn_detection.signage_yaw_direction` が `positive` ならYaw増加、`negative` ならYaw減少をサイネージ方向とします。サイネージ方向の変化が必ず正になるよう正規化します。カメラ配置、左右反転、Head Poseの符号によって設定が変わるため、実機で左右を向いて必ず確認してください。
基準Yaw方式:
- `first_valid`: 最初の有効Yaw群の中央値。Phase 4の既定値
- `before_trigger`: トリガー通過前のYaw中央値
- `region_entry_window`: 評価領域進入直後のYaw中央値
`first_valid` は評価しやすい一方、最初からサイネージを向いている人物の変化を過小評価します。Phase 5でも既存baselineを利用し、音声直前baselineへの再取得は今後の実験状態管理で拡張する制約があります。
振り向きレベルはサイネージ方向のYaw変化量で分類します。
| 変化量 | レベル | 扱い |
|---:|---|---|
| 10°未満 | none | 評価可能・閾値未満 |
| 10°以上 | subtle | 補助的な微弱反応 |
| 20°以上 | weak | 主判定の振り向き |
| 35°以上 | medium | 中程度 |
| 50°以上 | strong | 強い振り向き |
weak以上が既定0.30秒継続すると `turn_confirmed` になります。subtleは0.20秒以上を補助反応として保持します。0.30秒以内の短いpose欠落は同じ継続として扱います。顔未検出から検出可能へ変わった場合は `face_appeared` を補助イベントとして保存しますが、それだけでは振り向き確定にしません。
## Phase 3の概要
確定した `TrackedPerson` の人物Box上部からFaceROIを作り、ROIごとにMediaPipe Face Meshを実行します。MediaPipeは軽量で468点(refine有効時は追加点を含む)の顔ランドマークを取得でき、人物track IDと安定して結び付けやすいため採用しました。MediaPipe固有型は `FaceProcessor` 内で独自の `FaceLandmark` と `HeadPoseResult` へ変換します。
処理の流れは次のとおりです。
```text
TrackedPerson -> FaceROI -> MediaPipe Face Mesh -> 6 landmark points
-> OpenCV solvePnP -> pitch / yaw / roll -> track_id別EMA・統計
```
FaceROIは人物Boxの上部25%を初期値とし、幅・高さを10%拡張して画像内へクリップします。小さすぎるROI、未確定track、設定により領域外trackを除外します。
Head Poseではnose、chin、左右目尻、左右口角と簡易3D顔モデルを `cv2.solvePnP` へ渡します。Pitchは上下回転、Yawは左右回転、Rollは首の傾きに相当し、単位はdegreeです。ただし焦点距離を画像幅、主点を画像中心、歪みゼロとした未校正近似なので、角度は絶対的な測定値ではありません。同一環境での時間変化を主目的とします。
3D顔モデルのY軸はOpenCV画像と同じ下向きを正としており、正面が約180°回転として解かれる座標系不一致を避けます。真横付近の近似誤差を考慮して `head_pose.max_abs_angle` の既定値は120°です。範囲外になった場合もraw Pitch/Yaw/Rollを画面とface CSVへ残すため、実機で原因を確認できます。
solvePnPの顔平面軸が反転し、直立した正面顔のRollが±180°付近になる場合があります。本システムは通常の直立姿勢を対象とするため、Rollを等価な `[-90°, 90°)` へ正規化します(例: -170°は10°)。上下逆さの顔姿勢を識別する用途には対応しません。
顔未検出、ランドマーク不足、solvePnP失敗、角度範囲外、MediaPipe例外はfailure reasonとして区別し、人物検出・追跡は継続します。顔処理を間引いたフレームはface CSVへ書かず、画面では直近の結果を表示します。
顔向きはtrack ID単位で管理するためtracker有効が必須です。`--disable-tracker` と同時にfaceが設定されている場合、face処理を自動的に無効化して警告を1回出します。track IDは顔認証を意味しません。
## Phase 2の概要
Phase 2ではYOLOの `list[Detection]` を独立した `PersonTracker` に渡し、Ultralyticsに同梱されたByteTrackでフレーム間を対応付けます。ByteTrackは検出信頼度の高低を二段階で関連付け、一時的な低信頼検出や遮蔽でもIDを維持しやすく、既存のUltralytics依存だけで利用できるため採用しました。Ultralytics固有型は `src/tracker.py` 内だけで扱い、以降は `TrackedPerson`、`TrackState`、`TrackEvent` を使用します。
追跡IDは1回の実行内だけで同一人物候補を結び付ける一時IDです。顔認証でも個人識別情報でもなく、再起動後や複数日にわたって継続しません。遮蔽、退出後の再入場、交差、検出漏れによって別IDになることや、人物間でID switchが起きることがあります。
### 人数の定義
- `Raw Detections`: 現在フレームのYOLO検出数(Phase 1)
- `Active Tracks`: 現在表示中の確定トラック数
- `Unique Tracks`: 実行中に確定した一時IDの累計
- `Region Visitors`: 評価領域へ進入した確定トラック数
- `Trigger Crossings`: トリガーラインを通過した確定トラック数
- `Completed Passers`: 最終化時に設定された表示時間・領域進入・ライン通過条件を満たした数
これらは意味が異なります。特にRaw Detectionsを通過人数として扱わないでください。
### 進入・退出、交差、方向
位置判定にはBounding Boxの足元点を使います。初回検出が領域内なら即座に進入とし、通常の進入・退出には連続フレーム確認を使用して境界揺れを抑えます。トリガーラインは縦・横に対応し、確定トラック、最低軌跡点数、デッドバンド、最小移動量を満たした場合に方向付きイベントを生成します。既定では同一IDにつき1回です。
移動方向は直近の複数軌跡点の変位から、`left_to_right`、`right_to_left`、`top_to_bottom`、`bottom_to_top`、`stationary`、`unknown` のいずれかへ分類します。
## Phase 1の機能
- `person` クラスのBounding Box・信頼度表示
- 現在フレームの検出人数と評価領域内人数の表示
- FPS、フレーム番号、時刻、推論デバイスの表示
- normalized/pixel指定の評価領域と仮想トリガーライン
- UTF-8 BOM付きCSV検出ログ、ローテーション実行ログ
- 描画済み動画(任意)とスクリーンショットの保存
- YAMLの再帰マージ(default → experiment → CLI)
Phase 1由来のRaw Detectionsはフレーム単位であり、通過人数ではありません。Phase 2ではByteTrackによる一時ID、イベント、集計を追加しています。顔向き推定、振り向き判定、音声再生、統計解析はまだ実装しません。
## 構成
```text
main.py CLIエントリーポイント
config/ 既定・実験・logging設定
src/ カメラ、検出、描画、ログ、アプリ制御
models/ ローカルモデル配置先
data/input/ 入力動画
data/output/ 動画・スクリーンショット
data/logs/ CSV・実行ログ・実行時設定
tests/ モデル不要の単体テスト
docs/ 仕様概要・実験環境テンプレート
```
## セットアップ
Python 3.11を推奨します。PowerShell:
```powershell
py -3.11 -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install --upgrade pip
python -m pip install -r requirements.txt
```
### Phase 3のOpenCV・MediaPipe互換環境
Phase 3ではMediaPipeとの互換性を保つため、次の組み合わせを使用します。
- `mediapipe==0.10.21`
- `numpy==1.26.4`
- `opencv-contrib-python==4.11.0.86`
`opencv-contrib-python` は通常のOpenCV APIを含むため、`opencv-python` と併用しないでください。両方を同じ環境へ入れると、共有する `cv2` パッケージやNumPy要件が衝突する可能性があります。
既存環境に `opencv-python` や異なる版が残っている場合は、一度関連パッケージを削除してから再構築します。
```powershell
pip uninstall -y opencv-python opencv-contrib-python mediapipe numpy
pip install -r requirements.txt
```
一般的なシェルでも同じコマンドを使用できます。
一般的なsh:
```sh
python3.11 -m venv .venv
. .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install -r requirements.txt
```
## 起動
Webカメラ(`--config` 省略時も `config/experiment.yaml`):
```powershell
python main.py --config config/experiment.yaml
python main.py --camera-id 0
```
動画:
```powershell
python main.py --input-type video --video data/input/test.mp4
```
主なCLI上書きは `--model`、`--device`、`--confidence`、`--iou`、`--image-size`、`--save-video`、`--no-display`、`--debug` です。全項目は `python main.py --help` で確認できます。
追跡用CLIには `--tracker bytetrack`、`--disable-tracker`、`--track-buffer`、`--match-threshold`、`--show-trajectories`、`--no-trajectories` があります。`--disable-tracker` ではPhase 1相当の検出処理を継続します。
顔処理用CLIには `--disable-face`、`--face-every N`、`--max-face-persons N`、`--no-head-pose`、`--show-face-landmarks`、`--no-face-roi` があります。CPUではYOLO、ByteTrack、MediaPipeの同時実行でFPSが低下し得るため、まず `face.process_every_n_frames` と `max_persons_per_frame` を調整してください。
振り向き用CLIには `--disable-turn`、`--signage-yaw-direction`、`--turn-weak-threshold`、`--turn-medium-threshold`、`--turn-strong-threshold`、`--turn-min-duration`、`--no-turn-frame-log` があります。tracker、face、head poseのいずれかが無効ならturnも自動無効になり、警告を1回出します。
## YAML設定
`config/default.yaml` の全項目を基礎とし、実験ファイル、明示されたCLI引数の順に上書きします。ネストされた項目は再帰マージされるため、実験ファイルに一項目だけ記載しても同セクションの既定値は残ります。評価領域内の判定にはBounding Box中心ではなく、下辺中央(足元)を使用します。
`performance.skip_frames=1` は1フレームおきに推論します。Phase 1では推論しないフレームに前回結果を流用せず、空検出としてCSVへ記録します。
追跡有効時はID安定性を優先し、`performance.skip_frames` は必ず `0` とします。正の値は設定エラーです。追跡無効時だけPhase 1のスキップ動作を利用できます。
主なPhase 2調整項目は、`tracker.track_high_thresh`、`new_track_thresh`、`match_thresh`、`track_buffer_frames`、`min_confirmed_frames`、進入・退出確認フレーム数、交差デッドバンド、最小移動量です。カメラ角度、人数密度、遮蔽時間に合わせて実映像で調整してください。
## キー操作
| キー | 動作 |
|---|---|
| `q` / Esc | 終了 |
| `s` | 描画後フレームを保存 |
| `p` | 一時停止・再開 |
| `d` | デバッグ表示切替 |
| `r` | FPS計測リセット |
一時停止中は同じフレームを再推論・再記録しません。
## ログと成果物
CSVは `data/logs/detections/YYYYMMDD_HHMMSS_<experiment_id>_detections.csv` に保存されます。フレーム情報、検出番号、クラス、信頼度、Box座標・寸法、中心・足元座標、評価領域内フラグを含みます。人物ゼロ時は設定により検出列が空の行を記録します。
- 実行ログ・マージ済み設定: `data/logs/runtime/`
- 追跡ログ: `data/logs/tracking/`
- 顔向きログ: `data/logs/face/`
- 振り向きログ: `data/logs/turn/`
- 動画: `data/output/videos/`
- スクリーンショット: `data/output/screenshots/`
プライバシー保護のため、映像保存は既定で無効です。研究倫理・所属機関の規則に従って有効化してください。
追跡ログは次の3種類です。
- `*_tracking_frames.csv`: 1人物・1フレームの位置、ID、確定状態、方向
- `*_events.csv`: 作成、進入、通過、退出、消失、最終化イベント(metadataはJSON)
- `*_track_summary.csv`: 人物単位の時刻、滞在、軌跡、集計妥当性
いずれもExcelで扱いやすいUTF-8 BOM付きです。Phase 1の検出CSVも維持されます。
Phase 3では `*_face_frames.csv` にtrack ID付きの検出成否、Pitch/Yaw/Roll、ROI、失敗理由を保存し、`*_face_summary.csv` に人物ごとの検出率、推定率、Yawの最小・最大・平均、最終角度を保存します。
Phase 4では `*_turn_frames.csv` にbaseline、current Yaw、raw/サイネージ方向delta、candidate、confirmed、levelを保存します。`*_turn_events.csv` はbaseline取得、face appeared、candidate開始、確定、level変更、lost、最終化を記録し、`*_turn_summary.csv` は人物ごとの最大変化、時刻、継続時間、評価可否、除外理由を保存します。
## GPUとカメラ
`detector.device: auto` はCUDAが利用可能ならCUDA、それ以外はCPUを選択します。明示する場合は `python main.py --device cuda` を使用します。`half_precision` はCUDAかつ明示的に有効化した場合だけ使用します。CPUでは使用せず、`true` が指定されても警告を1回出して無効化します。通常のPyTorch推論では `quantize` を自動的に有効化しません。実際のCUDA利用には、環境に合うPyTorch/CUDA構成が必要です。
Windowsでカメラが開けない場合は `config/experiment.yaml` の `input.backend` を `dshow` または `msmf` に変更してください。カメラID、他アプリによる占有、OSのカメラ権限も確認します。Linuxでは `v4l2` を選択できます。
よくあるエラー:
- モデル読込失敗: ネットワーク、モデル名、ローカルパスを確認(`yolo11n.pt` は初回に自動取得)
- 動画が開けない: パスとコーデックを確認
- VideoWriterが開けない: `mp4v` 対応と保存先権限を確認
- 低FPS: `image_size` を下げる、CUDAを使う。`skip_frames` は追跡無効時のみ増やせる
## テスト
```powershell
python -m pytest
python -m compileall -q main.py src tests
```
標準テストはカメラやYOLOモデルを必要としません。実機では、解像度/FPS、評価領域、照明・逆光、検出漏れ・誤検出、CSV、動画、各キーを確認してください。
Phase 2の手動試験では、左→右、右→左、2人並行、2人交差、一時遮蔽、ライン付近停止・往復、領域へ少し入って戻る、画面端進入、退出後再入場、30分連続動作、CSVと画面カウンタの整合を確認します。ID switch数、track fragmentation数、誤トラック数、見逃し人数、実人数とシステム人数、交差判定誤り、平均・最低FPSを記録してください。
Phase 3では `TrackedPerson.track_id` とBBoxを使い、顔領域、MediaPipeランドマーク、Head Pose結果を人物トラックへ対応付けます。顔向き推定を無効化すればPhase 1・2の処理を維持できます。
Phase 3の実機確認では、正面、右、左、上、下、首の傾きの順に動かし、それぞれのYaw/Pitch/Rollを記録してください。カメラ配置や座標変換により符号が直感と逆になる場合があります。通行中のID付き角度、顔が映らない人物、複数人の上限処理、face CSV、CPUの平均・最低FPSも確認します。Phase 4でサイネージ方向へのYaw変化を使うため、左右の符号確認は必須です。
Phase 4では `HeadPoseResult` を使い、track IDごとの基準Yaw、Yaw変化、振り向きレベル、開始時刻、最大変化、継続時間、顔検出率による除外判定を実装しています。音声再生と声掛け後の反応時間計測はPhase 5の対象です。
Phase 4の手動確認では、正面、サイネージ方向、反対方向でYaw符号と `signage_yaw_direction` を確定します。通過試験では、見ずに通過、軽く見る、明確に見る、一瞬だけ見る、最初から見る、左右両方向、複数人、顔未検出から検出への変化を試します。baseline/current/delta/level/confirmed、顔・pose成功率、除外理由を記録してください。
Phase 5では音声提示時刻、声掛け条件、提示後反応時間、一定時間内Yaw変化への接続を実装しています。Phase 4は `baseline_yaw`、`yaw_delta_toward_signage`、level、confirmed、開始・確定時刻、最大変化、face appeared、評価可否を提供します。
## Phase 5の実機確認と実験上の注意
`prompt`モードでライン通過時の再生、音量、同一track一回制限、複数人通過時のcooldownを確認します。`control`モードでは音が鳴らず、`pseudo_prompt_triggered`と観測windowが記録されることを確認します。声掛け後に見る/見ない試験でresponseと期限切れを確認し、存在しない音声パスでもアプリが継続することを確認してください。
音声内容は初期実験では固定し、周囲への配慮、プライバシー説明、設置場所と音量を事前確認してください。例として「こんにちは」「こちらをご覧ください」「お知らせがあります」のような短い音声を使用できます。controlは声掛けなし条件でも観測開始タイミングを揃えるためのモードです。Phase 5だけで因果関係は断定しません。
Phase 6の統合人物状態を、Phase 7では `unified_events.csv`、人物解析表、セッションsummaryへ接続しています。Phase 8ではprompt/controlの反応率、reaction time、最大Yaw変化、除外数を統計解析する予定です。
## ライセンス
本実装は研究用プロトタイプとしてUltralytics YOLOと `yolo11n.pt` を使用します。研究成果、ソース、モデル、生成物を配布・公開する前に、使用時点のUltralyticsおよびモデルのライセンスと利用条件を必ず確認してください。
# Phase 9 GUI
Phase 9では、Phase 1〜8の実験実行と統計解析を操作するPySide6デスクトップGUIを追加しました。既存CLIは引き続き利用できます。
```powershell
python -m pip install -r requirements.txt
python main.py gui
python main.py gui --help
```
GUIではcamera/video入力、Prompt/Control/Disabled条件、音声ファイルと音量、顔処理頻度、サイネージ方向Yaw、統合ログを設定できます。Start/Stop/Pause/Resume、処理済み映像プレビュー、FPS・追跡・prompt・response等の状態表示、Phase 8解析、生成CSV・グラフの保存場所表示に対応します。起動しただけではカメラやYOLOを初期化しません。
GUI設定はYAMLを直接変更せず、その実行だけの最優先上書きとして反映されます。Prompt実験では音声ファイルを選択してください。Controlでは音声を再生せずpseudo promptを記録します。実験条件、音量、カメラ位置は研究記録にも残してください。
PySide6がない場合は `pip install -r requirements.txt` を実行してください。CPU環境ではプレビューによりFPSが低下する可能性があります。Stop後はログとsummaryのfinalizeに数秒かかる場合があります。GUIは研究用プロトタイプであり、実験前にはCLIでも実機動作を確認してください。顔認証・個人識別は行わず、ID switchも解消しません。統計結果は因果関係を直接証明しません。
Phase 10では実験プロトコル、条件ローテーション、チェックリスト、閾値・カメラ位置調整、ログ品質確認を追加予定です。詳細は `docs/phase9_specification.md` を参照してください。
# Phase 10 実験運用・品質確認
Phase 10では、本実験前に条件を固定し、ログ品質を確認し、パイロット結果と中間発表用要約を作る機能を追加しました。新しい認識アルゴリズムではありません。
```powershell
python main.py protocol --output docs/experiment_protocol.md
python main.py quality-check --logs data/logs/unified --analysis data/analysis --output data/analysis
python main.py pilot-report --analysis data/analysis --output data/analysis/pilot_report.md
python main.py presentation-summary --analysis data/analysis --output data/analysis/midterm_summary.md
```
GUIでは「Quality & Reports」タブから同じ処理を実行できます。これらの操作はカメラ、YOLO、MediaPipe、音声を初期化しません。
実験前には[実験プロトコル](C:/Users/koooo/Documents/NITGC/KawamotoLab/SignageSystem/docs/experiment_protocol.md)、[チェックリスト](C:/Users/koooo/Documents/NITGC/KawamotoLab/SignageSystem/docs/experiment_checklist.md)、[パイロット計画](C:/Users/koooo/Documents/NITGC/KawamotoLab/SignageSystem/docs/pilot_experiment_plan.md)を確認してください。PromptとControlでは、音声提示以外のカメラ位置、サイネージ位置、トリガー、通行方向、時間帯、照明、response window、turn閾値、顔処理頻度を可能な限り同一にします。Controlは音声を鳴らさずpseudo prompt時刻を記録します。
カメラ位置は主要な実験条件です。位置、高さ、角度、サイネージとの関係、通行方向、照明を`camera_position_note`とセッションメモへ記録してください。顔未検出や`valid_for_voice_analysis=false`は「見ていない」ではなく評価不能です。
Quality Checkは`quality_issues.csv`と`quality_report.md`を生成し、必要ファイル、Prompt/Control記録、有効解析率、not_evaluable率、Pose未推定率、カメラ位置メモ、反応時間、plotsを確認します。これはログ品質の目安であり、研究上の妥当性を保証しません。少数サンプルの有意差や因果関係を断定しないでください。
`pilot_report.md`と`midterm_summary.md`は予備的な記述要約です。Phase 11では実データ収集、除外理由の確認、有効解析人数の確保、カメラ位置・閾値の改善を行います。
# Phase 11 パイロット実験診断
Phase 11では、実際に収集したPrompt/Controlログを診断し、本実験へ進める状態か、設定調整や追加収集が必要かを判定します。
```powershell
python main.py pilot-diagnostics --analysis data/analysis --logs data/logs/unified --output data/analysis
python main.py calibration-add --category camera_position --before "通路横" --after "サイネージ正面寄り" --reason "no_pose_estimated_rateが高かったため"
python main.py calibration-list
```
診断結果は`ready`、`needs_minor_adjustment`、`needs_major_adjustment`、`insufficient_data`で出力します。Prompt/Controlの有効解析人数、有効音声解析率、not_evaluable率、no_pose_estimated率、条件人数比、カメラ位置メモを確認します。
生成ファイル:
- `pilot_diagnostic_report.md`
- `pilot_diagnostic_metrics.csv`
- `improvement_recommendations.csv`
- `session_quality_summary.csv`
- `data/calibration_history/calibration_history.csv`
改善提案にはカメラ位置、顔処理、条件バランス、サンプル数、プロトコル確認などが含まれます。提案は設定を自動変更しません。変更した場合は`calibration-add`で変更前後と理由を記録してください。
`valid_for_voice_analysis=false`は「振り向きなし」ではなく評価不能です。カメラ位置は主要な実験条件であり、PromptとControlで音声以外の位置、照明、通行方向、トリガー、閾値を可能な限り揃えてください。
診断がreadyでも研究デザインの妥当性や因果関係を保証しません。少数サンプルの統計判断、高い反応率からの因果推論、ID switchの無視を避けてください。詳細は`docs/phase11_specification.md`を参照してください。
# Phase 12 本実験・最終結果整理
```powershell
python main.py main-progress --logs data/logs/unified --analysis data/analysis --output data/final_results
python main.py snapshot --config config/experiment.yaml --output data/experiment_snapshots
python main.py final-analysis --logs data/logs/unified --analysis data/analysis --output data/final_results
python main.py final-report --analysis data/analysis --output data/final_results
python main.py presentation-assets --analysis data/analysis --output data/final_results
```
本実験前にPilot Diagnostics、カメラ位置記録、Prompt/Control運用ルール、音声、response window、turn閾値を確認し、設定snapshotを保存してください。目標人数は初期運用値であり正式なサンプルサイズ設計ではありません。
最終レポートでも`valid_for_voice_analysis=false`を反応なしへ混ぜません。カメラ位置は主要な実験条件です。p値や効果量が得られても、観察研究上の制約から音声との因果関係を直接断定しません。
GUIにはFinal Resultsタブを追加しました。Phase 12操作はカメラ、YOLO、MediaPipe、音声を初期化しません。詳細は`docs/phase12_specification.md`を参照してください。