🤳

WASMでOCR使ってみた

2024/12/17に公開

これは SMat Advent Calendar 2024 の12/17分の記事です。

弊社では「SmartMat Cloud」というIoT重量計 x SaaSでモノの流れを可視化するサービスを提供しております。最近お客様がスムーズにオンボーディングできるように、スマホのweb appのプロトタイプを作っております。当時のスプリントのゴールは商品の初回登録の時はスマートマットのシリアル番号や製品バーコードを読み取って検索するプロトタイプを狙いました。

バーコードリーダーはnpmのzxing-wasmがデファクトスタンダードでしたがスマートマットのシリアル番号はOptical Character Recognition(OCR)が必要でした。

OCR in the browser

OCRはtesseract.jsでしょう?と思いましたが、ocrsというプロジェクトが気になりました。

ocrsは、機械学習モデルを使用し、wasmにコンパイル可能であり、前処理ステップの代わりにより多くのML機能を使用することでtesseract.jsよりも速く動作するとされる。rustで書かれた新たなcli/ライブラリです。内部では、ocrsは異なるONNXモデルが必要な場合に使用できるように、ONNXモデルから変換されたrtenモデルを推論に使用しています。

Getting started: compile some wasm

https://github.com/robertknight/ocrsgit clone した後、以下のようなコマンドでwasmビルドを行うことができました:

cargo install wasm-bindgen-cli --version 0.2.89
rustup target add wasm32-unknown-unknown                 
sh ./ocrs/examples/download-models.sh
make wasm

ディレクトリは以下のようになりました:

.
├── index.js
├── package-lock.json
├── package.json
├── serialsample.jpg # テスト画像
├── text-detection.rten
└── text-recognition.rten

その後、サンプルのnodeアプリケーションが動作しました!

Integration: working with workers

パフォーマンスは重要であり、OCRロジックは可能な限りメインスレッドではないところで多くの作業を行うことになります。

これはワーカーを使用する絶好のケースです!このブログからワーカーを使ってパフォーマンスを向上させる方法について読んだ後、以下を実現できると確信しました:

  1. ワーカーとメインスレッド間のシグナルとしてSharedArrayBufferを使用する
  2. 処理する画像を送信するためにpostMessageを使用する
  3. メインスレッドから離れたワーカー内でWASMを使用する
  4. ワーカーのpostMessageからキャンバスに結果を更新する

これは以下のようになります:

そして、個人のiPhone SES 3で約1秒の処理時間で動作しました。プロトタイプにとって十分に速く、改善の余地もあります。

まとめ

このスプリントはエンゲージングであり、WASMを使用してweb appが現在のパフォーマントに動作できるかを示すプロトタイプを作成する機会でした。

株式会社エスマット

Discussion