😃

OpenCVの新しい顔検出をWebNNでも試してみる(失敗編)

2021/12/26に公開

この記事は OpenCV Advent Calendar 2021 カレンダー 2 の 23 日目の記事として後付けで投稿しました。

はじめに

25 日目の記事では OpenCV.js の WebNN バックエンドのことに触れられています。これは非常に気になるので試してみよう、という記事ですが、結局失敗します。新しい顔検出のモデルは WebNN バックエンドで対応していないレイヤーを使っているようです。

OpenCV の DNN WebNN バックエンド

OpenCV の WebNN バックエンドというのは、GSoC の成果のようです。このプルリクエストに色々と書いてあります。逆に言うとプルリクエストをしっかり読むまでセットアップ方法などが全然わからなかったです。良く読むとどうやらネイティブライブラリとして webnn-native を使うものと、フロントエンドで Emscripten 経由で使うものの 2 種類があるようです。この記事では後者を試してみます。

WebNN 有効の OpenCV のビルド

まずは WebNN を有効にした OpenCV をビルドしないとなりません。先のプルリクエストを良く読んで更にエスパーする必要がありました。

Emscripten の準備

Wasm にビルドするので Emscripten が必要なのですが、ここでちょっと特殊なインストールをします。まず、通常通りに emsdk を用意して、emsdk install 2.0.26 と実行してバージョン 2.0.26 をインストール、emsdk activate 2.0.26 と実行してアクティベートします。プルリクエストではバージョン 2.0.15 と書いてありますが、OpenCV 4.5.5 リリース時のものをビルドするには 2.0.26 が必要なようです。そして更にインストールした ${EMSDK}/upstream/emscripten ディレクトリの内容を、emscripten のフォークの emscripten-webnn リポジトリの webnn_2.0.26 ブランチに置き換えます。ここもプルリクエストの記載と異なりバージョンは 2.0.26 です。その後、置き換えた ${EMSDK}/upstream/emscripten ディレクトリに cd して、npm install or npm ci コマンドを実行します(私は後者を実行しました)。

OpenVINO とか webnn-native とかのインストールは無視します。

OpenCV のビルド

Emscripten の準備が整ったら OpenCV を Wasm ビルドしていきます。.js にしたい場合も手順は大差ありません。

OpenCV のソースディレクトリで python platform/js/build_js.py --webnn --emscripten_dir=${EMSDK}/upstream/emscripten と、後は必要なオプションを適宜付けて実行します。--webnn オプションで CMake には -DWITH_WEBNN が付けて渡され、emcc には -s USE_WEBNN=1 が渡されるようになります。この -s USE_WEBNN=1emscripten-webnn フォーク特有のオプションです。

また、ビルドするモジュールに dnn, objdetect, ml が含まれるようにします。

webnn-polyfill の用意

プルリクエストの記載に従い、webnn-polyfill を準備します。このリポジトリをクローン、npm install して npm run build します。ここで npm run build失敗 しますが、必要な dist/webnn-polyfill.js は生成されているので気にせず進めます。

利用アプリケーションの作成

さて、必要なものはそろったのでアプリケーションを作っていきます。今回は OpenCV Advent Calendar 23 日目の記事 で作成した新しい顔検出のデモを WebNN バックエンドで実行できるようにしていきます。

ポイントは

  • webnn-polyfill.js を先にロードさせておく
  • cv::FaceDetectorYN::create の引数にバックエンドの指定があるので、cv::dnn::Backend::DNN_BACKEND_WEBNN (=6) を指定する。

以上です。

実行、そして失敗

yarn dev で開発サーバを起動して表示すると・・・顔が検出されません。開発者コンソールを見てみると、以下のように警告がいくつか出ています。読んで見ると「WebNN バックエンドではこのレイヤーはサポートされてないよ」みたいなことが書いてあります。

つまり、今回使った FaceDetectYN のモデルが使っているレイヤー全てをサポートしていないということですね。残念!

Discussion