🦀

Rust製の動画像可視化ツールRerunの紹介

2023/12/10に公開

この記事はRust Advent Calendar 2023 シリーズ2画像処理・画像解析 Advent Calendar 2023の10日目の記事です。

rerunの紹介

rerunとは、rerun.ioという会社が開発している、動画像の可視化を強みとした

  • 可視化UI
  • 専用のロギングライブラリ

が一体となったOSSの可視化ツールになります。

こちらは、公式のexampleからの引用になりますが

のような画面を比較的簡単に作成することができます。

Rustで記述されている事による強みや特徴があり、恩恵に強くあやかれている言語だと思います。

rerunの特徴

rerunは開発中の可視化やデモとしての可視化に重きをおいているように見えます。(実運用中のデータを可視化する用途ではない)
rerunのツールとしての特徴は以下だと思っています。

  • 可視化ツールとしての独立性が高い
  • プログラムとの分離性が高い
  • Rust製のツールなので可搬性が高い

各々について書いて行きたいと思います。

可視化ツールとしての独立性が高い

これは可視化UIの独立性になります。

可視化で有名なツールと言えば私の知るところだと、kibanaやgrafanaだと思っています。

kibanaを例にすると、kibanaではElasticSearchをストアとしてそれの可視化を行います。

図にすると以下のようになるかと思います。

実際はプログラム => ElasticSearch には fluentd的な何かが必要かもしれないですが一旦割愛しておきます。

つまり、可視化ツールとデータストアが分離しているということになります。

これに対してrerunは

のように、可視化UIとデータストアが一体になっている構成になります。

この特徴により、

  • 気軽に利用を始めることが出来る
  • 他人が利用する場合でも立ち上げ手順が簡単

というメリットがあります。
また、デメリットとしては

  • 取り扱うことが出来る系列の長さが、可視化UIが実行しているディスクに律速してしまう

というものがありますが、

rerunは開発中の可視化やデモとしての可視化に重きをおいている

というところでの割り切りかと思っています。

プログラムとの分離性が高い

次にrerunはプログラムとの分離性が高いという解説をします。

これも比較対象を置くと、少し乱暴な対象だとは思いますが。
Opencv drawing & imshow可視化略してODIとしましょう

ODIの概略

Opencv drawing & imshow可視化というのは、
動画像の可視化に対して「Opencvのdraw*関数とimshow」で対応するという方針になります。

例として顔検出をして、検出した顔に対して赤い四角を書くというコードは以下のようになります。

import cv2

if __name__ == '__main__':
    # 顔検出用のカスケード分類器を読み込む
    face_cascade = cv2.CascadeClassifier('./data/haarcascade_frontalface_default.xml')

    # 動画を読み込む
    cap = cv2.VideoCapture('./data/face.mp4')

    while cap.isOpened():
        ret, frame = cap.read()
        if not ret:
            break

        # グレースケールに変換
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

        # 顔検出
        faces = face_cascade.detectMultiScale(gray, 1.1, 4)

        # 顔の周りに赤い矩形を描画
        for (x, y, w, h) in faces:
            cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 0, 255), 2)

        # 結果を表示
        cv2.imshow('Face Detection', frame)

        # 'q'を押すとループから抜ける
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

    # リソースを解放
    cap.release()
    cv2.destroyAllWindows()

ODIは上記の独立性を満たすため、動画像の処理を行う際のファーストチョイスに選ばれることが多いです。場合によってはデモとかだとそのまま、ODIで押し切る場合も多いです。

rerunの場合の可視化

import cv2
import rerun
from rerun.components import DrawOrder

if __name__ == '__main__':
    # 顔検出用のカスケード分類器を読み込む
    face_cascade = cv2.CascadeClassifier('./data/haarcascade_frontalface_default.xml')

    # 動画を読み込む
    cap = cv2.VideoCapture('./data/face.mp4')

    rerun.init("face_detection", spawn=True)

    while cap.isOpened():
        ret, frame = cap.read()
        if not ret:
            break

        rerun.log("rgb", rerun.Image(frame[:, :, ::-1], draw_order=[]))

        # グレースケールに変換
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

        rerun.log("gray", rerun.Image(gray))

        # 顔検出
        faces = face_cascade.detectMultiScale(gray, 1.1, 4)

        # 顔の周りに赤い矩形を描画
        for (x, y, w, h) in faces:
            rerun.log("rgb/faces", rerun.Boxes2D(mins=[x, y], sizes=[w, h]))
            rerun.log("gray/faces", rerun.Boxes2D(mins=[x, y], sizes=[w, h]))

    # リソースを解放
    cap.release()
    cv2.destroyAllWindows()

コードはあんまり変わっていないですがコレを実行するとrerunの可視化UIが起動して以下のような感じになります。(環境によって違うかも)

rerunの可視化画面はあとから表示要素を変えることが出来るので

を押すことで。

グレイスケール画像の可視化を一旦消すことなどができます。

また、このようにタイムバーを動かすと可視化するフレームを変えることも出来ます。

ODI vs rerun

rerunの可視化はODIに比べると以下のような優位性があります。

時系列を遡りながら可視化結果を確認できる。

言わずもがな、

これが出来るということです。
コレをODIでやろうと思うと不可能ではないですが、かなり苦労するかと思います。

3D系の描画が豊富

今回のサンプルには入れていないですが、

https://www.rerun.io/docs/reference/types/archetypes/pinhole
などの3D向けの可視化も大量に用意されています。
SLAMの結果の可視化などにいかがでしょうか?

プログラムを実行しているコンピュータ以外でも可視化出来る

rerunのロガーと可視化UIの間はTCPベースの通信で行われているため、実行しているコンピュータ上にWindowシステムが無くても(imshowは何かしらのWindowシステムか魔改造が必要になる)可視化することができます。

これにより、

  • スマートフォンアプリ
  • VRデバイス
  • テレビ

などの(全部スマホでごめんなさい)環境で動作させるときに、その環境にTCPのAPIさえあれば別のPCにログを送って可視化することなどができます。

他にも色々あるとは思いますが一旦コレくらいにしておきます。

今回のサンプルコードを実行できる環境は以下においておきます。

https://github.com/higumachan/rerun-opencv-facedetection-python

Rust製のツールなので可搬性が高い

Rust製のツールおなじみの可搬性が高いというのがあります。

可視化UIに関してもWasmでビルド出来たりと可搬性が高いですが、今回はロガーAPIの可搬性について説明します。

まず、rerunはcrateが細かく別れているためロガーのみを切り出して利用することが容易です。

> ls crates
re_analytics                re_build_tools       re_data_ui        re_log_encoding  re_sdk                   re_space_view_spatial        re_string_interner  re_types_builder   re_viewport           rerun_c
re_arrow_store              re_build_web_viewer  re_error          re_log_types     re_sdk_comms             re_space_view_tensor         re_time_panel       re_types_core      re_web_viewer_server
re_build_examples           re_crash_handler     re_format         re_memory        re_smart_channel         re_space_view_text_document  re_tracing          re_ui              re_ws_comms
re_build_examples_manifest  re_data_source       re_int_histogram  re_query         re_space_view            re_space_view_text_log       re_tuid             re_viewer          rerun
re_build_info               re_data_store        re_log            re_renderer      re_space_view_bar_chart  re_space_view_time_series    re_types            re_viewer_context  rerun-cli

ロガーの実装に当たる、re_logに関してはほぼrustのtoolchainのみでコンパイルできるためクロスビルドも容易です。

このロガーのクロスビルドの容易さが先程も上げた

  • スマートフォンアプリ
  • VRデバイス
  • テレビ

などの環境で利用するときに、とても助けになります。

私の場合は、過去にiOS向けにビルドして利用したりをしていましたが、feature flagを少しいじる程度の調整でiOS向けにビルドすることが出来ました。

rerunのおすすめ出来ないポイント

基本的にはないのですが、敷いてあげると以下のような点になります。

安定していないものが嫌いな人

凄まじい速度で発展しているアプリケーションなので、UI・ロガーAPI共に安定していないです。

私はロガーAPIのメインの利用がRustからのため、変わってもコンパイル時にすぐに気付くことが出来ていたためそこまで大きいストレスはありませんでした。
ただ、Python APIを利用していたり、可視化UI側をガッツリ使ったりするとバージョンを上げるのに躊躇してしまうケースは出てくるかもしれません。

可視化UIは手動でしかさわれない

AとBの可視化結果を横に並べて~~
みたいな作業は現時点では、コード化出来ず、手動で行う必要があります。
また、可視化UIの状態はUIアプリケーションを落としても維持されますがなにかの拍子にその状態が消えてしまうとやり直しになってしまいます。

blueprintという機能で2024の1Qに対応予定らしいです。

まとめ

rerunは画像処理アプリケーション開発時の可視化において

  • 手軽に利用開始可能
  • タイムシーケンス対応
  • 2D・3Dともに強力なドローイング機能

なツールになっているのでRustでもRustじゃなくても画像処理を行っている人は使ってみてください。

rerunに興味が出てきた人は、

ここに色々な例があるので試してみてください

また、ここでは可視化UIをブラウザ上で試すことが出来ます。


落ち穂拾い

rerunのUIの構成要素について

rerunはeguiというRust製のGUIライブラリの上に構成されています。eguiの記事
このeguiはimmediate modeという特徴を持っていて、よく利用されるUIライブラリがイベントベースナノに対してイベントが有ってもなくても60fps(画面の垂直同期でかわる)で再描画し続けるというものになっています。

これは個人的な推察ですが、eguiの作者はrerun.ioのCTOだったりするので、eguiのマネタイズ先としてrerunを開発しているっていうのもあるかもしれません。

Discussion