• 投稿日
  • 【Ask SA!】Python開発者向け S+ Camera Basic アルゴリズム開発をJupyter Notebookで対話的に行う方法

    こんにちは、ソリューションアーキテクトの今井(factory)です。ここ最近、非常に嬉しいことにS+ Camera Basic(ご存じない方もご安心ください。このあと詳しくご説明します!)をご検討頂いたり、実際にご購入頂く機会が増えてきました。今日は、このカメラ上でのアプリケーション開発のひとつの手法について書きたいと思います。

    S+ Camera Basicとは?

    S+ Camera Basic(サープラスカメラ、と読みます。以下、S+ Cameraと略します。)はソラコムが開発、販売するプログラマブルなネットワークカメラデバイスです(コネクティビティはもちろんSORACOM Airです!)。S+ CameraはSORACOM Mosaicという「エッジデバイス統合管理サービス」によって管理され、通信回線を通じてアプリケーションデプロイやシステムメンテナンスが行えるため、一度現場に配備したあとでも簡単にアプリケーションの更新が可能です。(S+ Camera、SORACOM Mosaicではユーザーが開発してデプロイするアプリケーションのことを「アルゴリズム」と呼んでおり、以降、本記事内でアルゴリズムという表記は特段のことわりがない限り、このユーザーがデプロイするアプリケーションであるアルゴリズムを指すものとします)

    実際のユースケースとしては、カメラから取得した画像を利用した交通量の調査や特定の場所における混雑具合の確認などで多く利用されています。公開事例もありますのでご興味ある方はぜひ御覧ください:

    SORACOM 導入事例:Intelligence Design株式会社 -交通量調査が AIxカメラで進化精緻かつ継続的なデータ取得で見えてきたデータ活用の可能性-

    このカメラの特徴としては、電源を挿すだけでオンラインになり、書き込まれたプログラムが動作し始める、プログラムはPythonで開発できる、デプロイはSORACOM Mosaic経由でオンラインで行えることが上げられます。つまり、アプリケーション開発者はPythonでの画像処理の部分、言い換えればビジネスロジックの開発にリソースを集中することができます。

    S+ Cameraで動作するアルゴリズムの開発方法は?

    では、実際にS+ Cameraで動作するアルゴリズムを開発するにはどうすればいいでしょうか?詳細はSORACOM Mosaic を用いたアルゴリズムの更新にありますが、ざっくり書くと以下のような手順になります。

    1. ローカル環境(カメラ画像はリモートの実機から取得できます)でアルゴリズムの開発
    2. 動作確認が取れたら実機へデプロイ
    3. ログをSORACOM Mosaic経由で回収して動作状況を確認
    4. 必要に応じて1から繰り返し

    SORACOM Mosaicはアルゴリズムのデプロイからログの回収までの一連の操作をGUIで一貫して行うことができ、開発やデプロイ済みのアルゴリズムの動作確認やデバッグがスムーズに行えます。

    一方アルゴリズム開発の中には、画像処理や機械学習のパラメータチューニングなどをインタラクティブかつ探索的に試していきたいようなフェーズもあり、チューニングのたびにデプロイとログ回収を繰り返すのが必ずしも最適でない場合もあります。

    今回のブログでは、そういった場面での開発手法のひとつとして、S+ Camera上にJupyter Notebookを起動して、ブラウザ上で直接コードを動かしたりログ出力を受け取りながら開発をする方法をご紹介します。

    Jupyter NotebookをS+ Camera上で動かす

    目指すべき構成は以下のイメージです。Jupyter Notebookをご存知ない方に補足しますと、ブラウザ上で対話的にPythonを実行できる環境で、画像やチャートを描画するライブラリやノウハウも非常に多く公開されており、データ処理の分野で広く活用されているソフトウェアです。

    今回はJupyter Notebookを「アルゴリズム」としてS+ Cameraにデプロイし、その上でコード開発を行う、という形です。

    まずは動かしてみましょう。今回、上記の構成を構築するアルゴリズムを用意していますので、これをSORACOM Mosaicを通してS+ CameraにデプロイするだけでJupyter Notebookが動き始めます。(このパッケージの作り方自体はブログ後半のHow it works?で解説しています。)

    ※以下の手順(Juptyer Notebook上での作業を含む)を進めることにより、SORACOM Airを利用して約30〜40MBのダウンロード通信が発生しますのでご注意ください。

    起動までの手順は以下のとおりです。

    1. SORACOM Mosaicコンソールから対象のデバイスを開く
    2. 、APP(CAMERAAPP0)タブ内の「Install」ボタンを押します。ポップアップメニューが開きますので、ここに予め用意されたJupyter Notebookを動かすアルゴリズムのURL( https://raw.githubusercontent.com/soracom-labs/splus-camera-jupyternotebook-boilerplate/master/build/CameraApp0.tgz )をコピーして入力し、インストールを実行

    SORACOM Mosaicコンソール上で、特にエラー等が表示されずにインストールのポップアップが消えたら成功です。数分でS+ Camera上にJupyter Notebookがインストールされ起動してきますので、SORACOM Napter経由でブラウザからアクセスできるようになります。スクリーンショット付きの詳細な手順は下記のレポジトリのREADMEを参考にしてください。

    Jupyter Notebook Boilerplate Project for S+ Camera Basic

    手順を追っていくと、下記のようにブラウザからS+ Cameraにアクセスしてコードを動かすことができます!本手順では、ハンズオン的なサンプルとしてcamera_demo.ipynbというノートブックが用意されており、このなかでS+ Cameraからの画像の取得、Caffeを使ったオブジェクト検出、結果(検出結果と解析対象の画像)をそれぞれHarvest DataとHarvest Filesに送信するというところまでがひととおり体験いただけます。

    いかがでしたか?この仕組をご利用頂くことによって、インタラクティブなアルゴリズム開発やパラメータ調整を短いサイクルで行うことができるようになります!

    改めてアルゴリズムの開発ワークフローを考えてみる

    今回のJupyter Notebookを使った開発環境と、プロダクションであるべき構成を絵にしてみると以下のようなイメージです。Jupyter Notebookを「アルゴリズム」としてSORACOM Mosaicでデプロイして、その上で実際のユーザーアルゴリズムの開発や体験が可能になっている、というイメージが伝わったら幸いです。

    なぜわざわざ「今回の構成」と「プロダクション構成」を分けて絵にしているのでしょうか?

    Jupyter Notebookはあくまでインタラクティブな作業をすることを目的としたプラットフォームですので、残念ながらここで作り上げたコードをそのままロングラン/プロダクション用にデプロイすることにはいくつかの難しさがあります(例えばJupyter Notebookのコード実行はターミナルであるブラウザのウィンドウが閉じられると止まってしまいます)。

    したがって、実際には以下のような開発フローがよいでしょう。Jupyter Notebook上での開発はあくまで「インタラクティブな開発」に利用する、というイメージです。

    1. Jupyter Notebookを使ってアルゴリズムの中身の開発
    2. 固まってきたらSORACOM Mosaicでデプロイできるpythonスクリプトとしてアルゴリズムを実装しなおしていく
    3. 2を実際にデプロイし動作確認。問題がなくなるまで2と3を繰り返す。
    4. 固まったパッケージを他の端末にもデプロイしていく。

    個人的にはJupyter Notebookの大ファンなので、Notebookがそのまま(もしくはほぼそのまま)ロングランできるといいなと思っているので、この辺りは引き続き調査をしていきます。

    まとめ

    ここまでお読みいただいてありがとうございました。この記事では、S+ CameraとSORACOM Mosaicについての概要と、それを使ったアプリケーション開発の手法のひとつのアイデアをご紹介させて頂きました。S+ Camera Basicはカメラからセルラー回線までパッケージになっていて、更にプログラマブルなのでカメラ画像を使ったアプリケーション開発やPoCを簡単に始めていただくのに非常に適した製品です。ぜひお試しください!

    より詳細な「どうやって使えるの?どうやって動くの?」が気になる方は、ぜひこの後の追記までお読みください!

    追記: How it works?

    今回のJupyter Notebookはどのようにインストールされて起動されているのでしょうか?ぜひ皆さまにS+ Cameraの仕組みをよく知っていただきたいので、ご紹介させてください。(なお、詳細は前述の本家ドキュメント(SORACOM Mosaic を用いたアルゴリズムの更新)をご確認頂ければと思います)

    今回インストールしたリリースパッケージはレポジトリ内のCameraApp0というディレクトリをそのままTARボールにしたものです。ディレクトリに含まれるファイルは以下のような構成になっています。

    この中にはいくつか特別な意味を持つファイルがあります。

    まずinfo.json これはパッケージのメタ情報を表すファイルで中身は以下のように非常なシンプルがものです。現在のプラットフォームの仕様上、ご利用頂く皆様が変更すべき項目はPkgNamePkgVersionのみです。これかが、デプロイされているアルゴリズムの名前とバージョンとしてSORACOM Mosaicコンソールで表示されるようになっています。

    {
    "PkgApp": "CameraApp0",
    "PkgName": "Jupyter Notebook boilerplate project for S+ Camera Basic.",
    "PkgVersion": "1.0.9",
    "PkgIdentifier": "io.soracom.CameraApp0"
    }

    次にPreSetup これは、アルゴリズムが実行される前のフックで、任意のコマンドが実行可能なシェルスクリプトです。このプロジェクトでは下記のような感じで、Jupyter Notebookとmatplotlibのインストールを行っています。つまり、任意のパッケージやライブラリのインストールはこのフックを使って実施していくことになります。(現状、S+ Cameraではプラットフォームの制約上、 !pip install ...!wget ...といったシステムコマンドの発行ができません。必要なPythonモジュールはこちらを使ってインストールしてください。全ての外部リソースアクセスはセルラー通信で行われますので、速度面と料金面にご注意ください。)

    #!/bin/bash
    
    pip install notebook
    pip install matplotlib
    pip freeze

    最後にCameraApp0 これが起動されるプログラムのエントリポイント(つまり一番最初にインタプリタから実行されるPythonスクリプト)です。長くなるので全てはここに貼りませんが、こういうやつです。普通のPythonスクリプトですね。

    import sys
    
    from IPython.terminal.ipapp import launch_new_instance
    from IPython.lib import security
    
    def main():
      sys.argv.append("notebook")
      sys.argv.append("--IPKernelApp.pylab='inline'")
      sys.argv.append("--NotebookApp.ip=" + get_my_ip())
      sys.argv.append("--NotebookApp.open_browser=False")
      sys.argv.append("--NotebookApp.port=" + "49152")
      sys.argv.append("--NotebookApp.allow_root=" + "True")
      sys.argv.append("--NotebookApp.password=" + security.passwd(password))
      launch_new_instance()
    
    if __name__ == "__main__":
       main()

    CameraApp0の処理内容、このプロジェクトではJupyter Notebookを起動するのがその役目となっていますが、ロングランなプログラムを実装する場合、ここにカメラからの画像取得とその処理、そして出力のループを書いていって頂くことになります。それに近いコードのサンプルは、camera_demo.ipynbの末尾に実装がありますので参考にしてみてください。

    これら以外のファイルは上記のエントリポイントからimoprtされたり、Jupyter Notebookから呼び出されるノートブックファイルなどです。

    また、肝心のカメラ画像はどこから取得してくればいいのでしょうか?S+ Camera上には、8080番ポートで画像の撮影と出力を行ってくれるdeviceInterfaceというデーモンが存在しており、アルゴリズムはここから画像をHTTP API経由で取得することになります。このサンプルプロジェクトではsurplus_camera_client.pyというファイル内にクライアントの実装がありますので参考にしてみてください。

    いかがでしょうか?若干手数が多いようにも見えますが、Pythonを知っている方であれば実はあまり違和感なく開発ができることが伝われば幸いです・・・!