コンテンツにスキップ

sample_face_ae

このガイドでは、K230 の sample_face_ae アプリケーションを CMake out-of-tree ビルドで構築する方法を説明します。このサンプルは顔検出モデル (MobileRetinaface) を使用して検出した顔領域を ISP の AE (Auto Exposure) ROI に反映し、顔に最適化された露出制御を実現するデモアプリケーションです。

前提条件

  • K230 SDK がビルド済みであること(ツールチェーン展開済み、MPP ライブラリコンパイル済み)
  • SDK がリポジトリルートの k230_sdk/ に配置されていること
  • 顔検出用の kmodel ファイル(mobile_retinaface.kmodel
  • ホスト OS: x86_64 Linux
  • CMake 3.16 以降

SDK のビルド

K230 SDK のビルド手順については SDK ビルド を参照してください。

概要

sample_face_ae は K230 SDK の顔検出サンプル (sample_face_ae) をベースにした、AI 推論と ISP AE ROI 制御を組み合わせたアプリケーションです。以下を実演します:

  • VICAP API によるカメラセンサーの設定(2チャネル: 表示用 YUV420 + AI推論用 RGB888P)
  • NNCASE ランタイムによる kmodel の読み込みと AI2D 前処理
  • MobileRetinaface モデルによる顔検出(バウンディングボックス + ランドマーク)
  • 検出した顔領域の ISP AE ROI への反映(面積比重み付け)
  • VO ディスプレイへのリアルタイムプレビューと顔枠描画

ソースファイル

ファイル 説明
main.cc メインアプリケーション — VB/VICAP/VO 初期化、AI 推論ループ、クリーンアップ
model.h / model.cc Model 抽象基底クラス — kmodel ロードと推論パイプライン
mobile_retinaface.h / mobile_retinaface.cc MobileRetinaface クラス — 顔検出モデル(AI2D 前処理、アンカーデコード、NMS)
face_ae_roi.h / face_ae_roi.cc FaceAeRoi クラス — 顔座標を ISP AE ROI に反映
util.h / util.cc ユーティリティ型(box_tface_coordinate)とヘルパー
anchors_320.cc 320x320 入力用の事前計算済みアンカーボックス
vo_test_case.h VO レイヤーヘルパー型(layer_info)の宣言

処理フロー

アプリケーションは以下のデータフローに沿って動作します:

センサー (OV5647)
  ├─ CHN0 (1920x1080 YUV420) ──→ VO レイヤー ──→ HDMI ディスプレイ
  │                                    ↑
  │                              顔枠描画 (kd_mpi_vo_draw_frame)
  └─ CHN1 (1280x720 RGB888P) ──→ AI 推論
                              ┌─────┴─────┐
                              │ AI2D 前処理 │
                              │ (リサイズ+パッド) │
                              └─────┬─────┘
                              ┌─────┴─────┐
                              │ KPU 推論    │
                              │ (MobileRetinaface) │
                              └─────┬─────┘
                              ┌─────┴─────┐
                              │ 後処理      │
                              │ (デコード+NMS) │
                              └─────┬─────┘
                              ┌─────┴─────┐
                              │ AE ROI 更新 │
                              │ (FaceAeRoi) │
                              └─────┬─────┘
                              ISP AE エンジン

クラスリファレンス

Model — 抽象基底クラス

Source: model.h L13–L39 / model.cc

kmodel のロードと推論パイプラインを管理する抽象基底クラス。サブクラスは Preprocess()Postprocess() を実装します。

メソッド 説明
Model(model_name, kmodel_file) kmodel ファイルを読み込み、入力テンソルを作成
Run(vaddr, paddr) PreprocessKpuRunPostprocess の推論パイプラインを実行
Preprocess(vaddr, paddr) 純粋仮想 — 入力データの前処理
KpuRun() kmodel を KPU で実行
Postprocess() 純粋仮想 — 推論結果の後処理
InputTensor(idx) / OutputTensor(idx) 入出力テンソルへのアクセス
InputShape(idx) / OutputShape(idx) 入出力形状の取得

メンバ変数:

変数 説明
ai2d_builder_ AI2D 前処理パイプラインビルダー
ai2d_in_tensor_ / ai2d_out_tensor_ AI2D 入出力テンソル
interp_ NNCASE ランタイムインタプリタ

MobileRetinaface — 顔検出モデル

Source: mobile_retinaface.h L13–L48 / mobile_retinaface.cc

Model を継承し、MobileRetinaface 顔検出モデルの前処理・後処理を実装します。

メソッド 説明
MobileRetinaface(kmodel_file, channel, height, width) AI2D 前処理パイプラインを構築(リサイズ + パディング)
GetResult() 検出結果(バウンディングボックス + ランドマーク)を返す
Preprocess(vaddr, paddr) VICAP フレームから AI2D テンソルを作成し、前処理を実行
Postprocess() 9 個の出力テンソルをデコードし、NMS でフィルタリング

後処理の流れ:

  1. Confidence デコード (DealConfOpt) — 3 スケールの信頼度を softmax で処理し、閾値 (obj_threshold_ = 0.6) 以上のオブジェクトを選択
  2. Location デコード (DealLocOpt) — 選択されたオブジェクトの位置情報をアンカーボックスを使ってデコード
  3. Landmark デコード (DealLandmsOpt) — 5 点の顔ランドマークをデコード
  4. NMS — IoU 閾値 (nms_threshold_ = 0.5) で重複ボックスを除去
  5. 座標変換 — モデル座標からカメラ入力座標に変換

FaceAeRoi — AE ROI 制御

Source: face_ae_roi.h L9–L21 / face_ae_roi.cc

検出された顔座標を ISP AE ROI ウィンドウに変換し、顔領域に最適化された自動露出制御を実現します。

メソッド 説明
FaceAeRoi(dev, model_w, model_h, sensor_w, sensor_h) ISP デバイスとモデル/センサー解像度を設定
SetEnable(enable) ISP AE ROI 機能の有効/無効を切り替え (kd_mpi_isp_ae_roi_set_enable)
Update(boxes) 顔バウンディングボックスを AE ROI ウィンドウに変換して設定

Update() の処理:

  1. 顔座標をモデル解像度からセンサー解像度にスケーリング
  2. 最大 8 個の ROI ウィンドウを設定
  3. 各 ROI の重みを面積比で算出(大きい顔 = 大きい重み)
  4. kd_mpi_isp_ae_set_roi() で ISP に反映

ビルド手順

1. 設定

cmake -B build/sample_face_ae -S apps/sample_face_ae \
  -DCMAKE_TOOLCHAIN_FILE="$(pwd)/cmake/toolchain-k230-rtsmart.cmake"

2. ビルド

cmake --build build/sample_face_ae

3. 確認

file build/sample_face_ae/sample_face_ae

期待される出力:

sample_face_ae: ELF 64-bit LSB executable, UCB RISC-V, RVC, double-float ABI, version 1 (SYSV), statically linked, ...

CMakeLists.txt の詳細

apps/sample_face_ae/CMakeLists.txt は以下を処理します:

  • MPP インクルードパス: mpp/include/mpp/include/comm/mpp/include/ioctl/mpp/userapps/api/ のヘッダ
  • NNCASE インクルードパス: nncase/include/nncase/include/nncase/runtime/rvvlib/include/ のヘッダ
  • MPP 静的ライブラリ: 全 MPP ライブラリを --start-group / --end-group で循環依存を解決してリンク
  • NNCASE ライブラリ: Nncase.Runtime.Nativenncase.rt_modules.k230functional_k230rvv
  • C++20: target_compile_features で C++20 を要求

コマンドライン引数

./sample_face_ae <kmodel> <roi_enable>
引数 説明
<kmodel> 顔検出用 kmodel ファイルのパス(例: /sharefs/mobile_retinaface.kmodel
<roi_enable> AE ROI の有効化: 1 = 有効、0 = 無効

K230 への転送・実行

CMake の deploy / run ターゲットで転送・実行をワンコマンドで行えます(詳細は CMake ターゲット を参照):

cmake --build build/sample_face_ae --target deploy   # ビルド + SCP 転送
cmake --build build/sample_face_ae --target run      # シリアル経由で実行 (Ctrl+C で終了)

手動で転送・実行する場合

SCP + minicom による手動操作

SCP で転送

scp build/sample_face_ae/sample_face_ae root@<K230_IP_ADDRESS>:/sharefs/sample_face_ae/
scp mobile_retinaface.kmodel root@<K230_IP_ADDRESS>:/sharefs/sample_face_ae/

K230 bigcore (msh) で実行

K230 のシリアルコンソール (ACM1) で実行します:

msh /> /sharefs/sample_face_ae/sample_face_ae /sharefs/sample_face_ae/mobile_retinaface.kmodel 1

AE ROI を無効にして実行する場合:

msh /> /sharefs/sample_face_ae/sample_face_ae /sharefs/sample_face_ae/mobile_retinaface.kmodel 0

シリアル接続

  • Bigcore (RT-Smart msh): /dev/ttyACM1、115200 bps
minicom -D /dev/ttyACM1 -b 115200

CMake ターゲット

設定

cmake -B build/sample_face_ae -S apps/sample_face_ae \
  -DCMAKE_TOOLCHAIN_FILE="$(pwd)/cmake/toolchain-k230-rtsmart.cmake"

ターゲット一覧

ターゲット コマンド 説明
(デフォルト) cmake --build build/sample_face_ae C++ バイナリのビルド
deploy cmake --build build/sample_face_ae --target deploy ビルド + K230 への SCP 転送
run cmake --build build/sample_face_ae --target run シリアル経由で K230 実行 (Ctrl+C で終了)

deploy

バイナリのビルドと K230 への SCP 転送を一括実行します:

cmake --build build/sample_face_ae --target deploy

転送されるファイル:

ローカル K230 上のパス
build/sample_face_ae/sample_face_ae /sharefs/sample_face_ae/sample_face_ae
apps/face_detect/scripts/output/dump/mobile_retinaface.kmodel /sharefs/sample_face_ae/mobile_retinaface.kmodel

run

シリアルポート経由で K230 bigcore (msh) にコマンドを送信し、出力をリアルタイム表示します:

cmake --build build/sample_face_ae --target run
  • キーボード入力はそのまま K230 に転送されます(q + Enter でアプリ終了)
  • Ctrl+C でシリアル接続を切断

K230 接続設定

CMake キャッシュ変数で接続先をカスタマイズできます:

変数 デフォルト 説明
K230_IP (空 = 自動検出) littlecore の IP アドレス
K230_USER root SSH ユーザー
K230_SERIAL /dev/ttyACM1 bigcore シリアルポート (run 用)
K230_SERIAL_LC /dev/ttyACM0 littlecore シリアル (IP 自動検出用)
K230_BAUD 115200 ボーレート