この記事はOpenCV Advent Calendar 2017の23日目の記事です。他の記事は目次にまとめられています。
この話のオチ
Web上でアプリケーションを開発するツール・ライブラリもいろいろありますが、JavaScriptで動作する画像解析ライブラリとしてOpenCVが活用できるようになりました!
単純な色変換のみならず、Webカメラからの入力・表示をはじめとして、様々な機能が使えるようになっています。
2018年は、もっと身近に、コンピュータビジョンが使える時代になりそうですね!
はじめに
OpenCVアプリケーションを作るときの課題の1つに、ポータビリティがあります。GUIとして共通化できるhighguiモジュールがあってもWindows, MacOS, Android, iOS それぞれのプラットフォームで動かすためには、それなりの苦労が必要。多様なクライアントに対応するには、コンパイルとデプロイは各環境に必要になるので、なかなか面倒。これはどうにかしたい。
しかし、画像処理部をサーバーに集約させると、画像データ処理するためだけに大量のアップロードが必要になってしまう。これも良くない。クラウドの使用料も膨大になり、セキュリティ的にも・・・・。ローカルに画像処理が実行できる必要がありますね!
こういう事を踏まえると、前処理なら、JavaScriptで組んで全プラットフォーム共通にしたくなりますよね! むしろ、なってください!ということで、OpenCV 3.3.1で導入された、OpenCV.jsのお話です。
実現方法は?
[本家のドキュメント] ( https://docs.opencv.org/3.3.1/df/d0a/tutorial_js_intro.html )にも詳しく書いていますが、図にするとこういうイメージです。
従来は、OpenCVのソースコードは、コンパイラ(例えばGCC)でライブラリにコンパイル・リンクされていました。これに対して、LLVMフロントエンドであるclangによってLLVM bitcode(中間コード)に変換し、これをEmscriptenでJavaScriptコードにコンパイルしたのが、OpenCV.jsとなります。なお、実際に動かす場合には、asm.js/WebAssemblyなどを使って高速処理できるようになっている、とのことです。
OpenCV.jsの入手元は?
公式に配布されていないので、探せば見つかりますが…頑張りましょう!(Releases に欲しいなあ)
OpenCV.jsの作り方
本家マニュアル の手順に従って、Ubuntuで作業したらできます。コンフィギュレーションはこんな感じで、core/imgproc/objdetect/video/jsしか対象にならない…。
core i7 の4770 8コアでぶん回しで、これくらい。
OpenCV.jsの使い方
OpenCVを使ったことがある人ならば、非常に簡単に始められます!例えば、画像を2値化する例はこうなります。
let src = cv.imread('canvasInput');
let dst = new cv.Mat();
// You can try more different parameters
cv.threshold(src, dst, 177, 200, cv.THRESH_BINARY);
cv.imshow('canvasOutput', dst);
src.delete();
dst.delete();
ポイント
src.delete() ってあるけど、勝手に消してくれないの?と感じた方がいるかもしれません。これを補足しますとECMA-262 Edition 5.1では、finalizers/weak references with callbacksがサポートされていないので、EmscriptenはC++オブジェクトのdestructorを自動的に呼び出せない、とのことですね。そのため、利用したMatオブジェクトは手動で削除する必要があります。
どんな機能が使えるの?
GUI Feature
- HTML5 Canvasからの画像読み込み・書き込み
- カメラからの動画フレームの読み込み(表示はCanvasで)
- トラックバーの追加
Core Operations
- 基本的なMatオブジェクト操作(構築、複製、フォーマット変換、etc...)
- 算術処理(加法、減法、ビット操作などなど)
Image Processing
- 色空間変換
- 形状変換
- 2値化
- スムージング
- モーフィング
- エッジ抽出 etc...
Video Analysis
- Meanshift/Camshift
- Optical Flow
- Background Subtraction
Object Detection
- Face Detection
そして、JavaScript bindings for dnn moduleと、夢は広がりまくりですね!
現状の問題点
OpenCV.jsが配布されていない。
これが一番大きい問題ですね……。node.jsやらVue.jsやらであれば公式リリースがあるのですが、OpenCV.jsはまだ配布されていないのか、配布場所が分かりにくいのか、見つからないです。
「使いたい」と思ったときに、すぐ使えないことは機会損失にもつながります。やはりここは、OpenCV.jsの公式配布を希望したいですね!
OpenCV.jsが巨大すぎる
私の手元で作成したものでも6MBあります。初回ダウンロード時のみ必要になるとはいえ、やはりこれでは…。
アプリケーション側が参照していない関数を削除するなどして、OpenCV.jsをシュリンクする機能が必要になるかもしれません。あるいは、OpenCV.jsがメインルーチンをロードした後、機能が呼ばれるたびに必要なサブjsを読みだす仕組み、などなど。
重たい処理の進捗不明
重たい処理をしているときに、OpenCV側ががっつりCPU/メモリをもっていってしまうので、やはりこの部分については何かしらシステムにフィードバックできる仕組みが必要になる気がします。
例えば、100ms以上OpenCV側が処理から応答がない場合には、イベントが発行するような仕組み、などなど。
特徴量抽出あたりが早くほしい
ほしいです!というのは、画像特徴量だけをやりとりするようにできれば、例えば個人情報なども除去した状態でのやり取りになるので、非常に扱いやすくなります!
明日は、tomoaki_teshima さんの投稿で、執筆時点でのタイトルは 「去年書いた浮動小数点数の精度問題のネタ」 です!組込大好き人間としては気になります(IAとARMで泣かされた……)よろしくお願いいたします。