actfw

カメラを用いたアプリケーションでは、カメラの撮像とクラス分類の推論を高スループットで行うために 3 つの仕事をタスク並列で実行する必要があります。

  • Capture: カメラの撮像をする
  • Predicator: 分類タスクを行う
  • Presenter: 画面描画を行う

この中に含まれるカメラの撮像や Actcast への Heartbeat などの機能は定形であることが多いです。 これらの機能を Python ライブラリ化したものがactfwです。

actfw の使い方

ライブラリ構成

actfw として次の 2 つが提供されています。

actfwのインストール

actfw-*は pip によりインストールすることが出来ます。 actdk initにより生成されたdependencies.jsonではactfw-raspberrypiがデフォルトでインストールされるようになっています。

actfwの計算モデル

actfwは非同期計算を記述するための Idein 提供ライブラリです。 このライブラリ上のタスクは「このタスクが行われたとき実行する次のタスク」を登録するモデルになっており、データの流れをconnectメソッドで定義します。

actfwのモデル

Applicationクラスが全体をコントロールします。

app = actfw_core.Application()
app.run()

非同期に実行するタスクは以下の 3 つに分けられます。

  • Producer : リソースを生成し続ける処理
  • Pipe : リソースを変形して次のタスクに渡す処理
  • Consumer : リソースを最終的に消費し続ける処理

例えば、次に示す 3 つのタスクがあるとします。

  • カメラから画像を取得(Producer)
    • RGB 画像を撮影し続ける処理
  • 取得画像を白黒にコンバート(Pipe)
    • RGB 画像をグレイスケール画像に変換する処理
  • 画面に描画(Consumer)

これらは以下のように記述できます。

import actfw_core
from actfw_core.task import Pipe, Consumer
from actfw_core.system import find_csi_camera_device
from actfw_core.unicam_isp_capture import UnicamIspCapture
import actfw_raspberrypi
from actfw_raspberrypi.vc4 import Display

class Converter(Pipe):
  ...

class Presenter(Consumer):
  ...

app = actfw_core.Application()

# Capture task
capture_size = (CAPTURE_WIDTH, CAPTURE_HEIGHT)
framerate = 30
device = find_csi_camera_device()
cap = UnicamIspCapture(unicam=device, size=capture_size, framerate=framerate)
app.register_task(cap)

# Converter task
conv = Converter()
app.register_task(conv)

# Presentation task
pres = Presenter(settings, camera, cmd)
app.register_task(pres)

# Make task connection
cap.connect(conv)  # from `cap` to `conv`
conv.connect(pres) # from `conv` to `pres`

app.run()

この例はGetting Started の grayscale exampleを簡略化したものです。

カメラの設定

Raspberry Pi で利用可能なカメラは 2 種類に分けられ、利用可能なインターフェイスが異なります。

Official Raspberry Pi Camera Module

Raspberry Pi が公式に提供しているカメラモジュールです。 actfw_core.unicam_isp_capture.UnicamIspCapture を利用する必要があります。

  • Pi Camera Module 1
  • Pi Camera Module 2
  • Pi Camera Module 3
    • Pi Camera Module 3 は ActcastOS 1,2 ではサポートされていません

一般的な USB カメラ

actfw-core.capture.V4LCameraCapture を利用する必要があります。

TakePhoto 機能の実装

カメラを用いるアプリケーションは設置確認のため、TakePhoto コマンド要求に対応することを推奨します。

actfw では以下のようにCommandServerクラスを用いることで簡単に実装することが出来ます。 CommandServerは内部的に画像を保持し、画像送信要求を受け取ると内部的に保持していた画像を返します。 そのためupdate_imageメソッドで要求を受け取ったときに返す画像をアップデートする必要があります。

class Presenter(Consumer):
    def __init__(self, ..., cmd):
      self.cmd = cmd

    def proc(self, ...):
      ...
      self.cmd.update_image(rgb_image) # update `Take Photo` image
      ...

# Actcast application
app = actfw_core.Application()

# CommandServer (for `Take Photo` command)
cmd = actfw_core.CommandServer()
app.register_task(cmd)

# Presentation task
pres = Presenter(..., cmd)
app.register_task(cmd)

アプリケーションの死活監視

アプリケーションが連続的に画像を処理できていないなど何らかの不健全な状態にあると判断されたとき、Actcast デバイスエージェントはアプリケーションを再起動します。 アプリケーションの健全性の判定にはhealthcheckerが利用されます。

以下は、healthcheckerの実装例です。 /root/heartbeatファイルの更新が 1 分以内に起きていることを確認するスクリプトとなっています。

app/healthchecker
#!/bin/bash

HEARTBEAT_FILE='/root/heartbeat'

[ "$(find "${HEARTBEAT_FILE}" -mmin -1)" == "${HEARTBEAT_FILE}" ]

healthcheckerに対応するように、main側ではactfw_core.heartbeat()によって/root/heartbeatファイルを一定間隔で更新します。

class Presenter(Consumer):
  def __init__(self):
    ...

  def proc(self, image):
    # update image here
    actfw_core.heartbeat()

もし、以前のタスクが止まったりすると、この箇所で短い間隔で行われている筈の更新が行われなくなり、healthcheckerに検知されることになります。

画面の描画

一般的に Actcast アプリケーションは高度なセンシングのためのアプリケーションであることがほとんどであるため、画面の描画も必要無いことが多いです。 しかし、デモや動作確認のために画面に計算結果を描画できると便利な場合があります。 actfw-raspberrypiDisplayオブジェクトを用いると HDMI で接続されたディスプレイに RGB 画像を表示することが出来ます。

以下の例は画面に RGB 画像を表示するだけのPresenterタスクの例です。 画面描画を行うだけのPresenterタスクの例です。Presenterは、データを消費だけして次のタスクに渡さないConsumerとして作成しているので,procメソッドに返り値は不要です.

この例では、HDMI ディスプレイを640x480の領域として扱い、 320x240の RGB 画像を(0, 0, 640, 480)の矩形領域に拡大描画しています。

class Presenter(Consumer):
  def __init__(self, camera):
    self.display = Display(camera, (640, 480))

  def proc(self, image):
    self.display.update((0, 0, 640, 480), image.tobytes(), (320, 240), 'rgb')

LocalVideoServer 機能の実装

LocalVideoServer 機能を実装することで、デバイスと同一のネットワーク内からブラウザでライブ映像を確認することができます。 デバイスの設置作業や、設置後の動作確認時に有用なため、実装を推奨します。

詳細は Local Video Server 機能 を参照してください。

最終更新日