OpenCVの新しい顔検出をWebNNでも試してみる(失敗編)
この記事は 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=1
は emscripten-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