読者です 読者をやめる 読者になる 読者になる

catalinaの備忘録

ソフトウェアやハードウェアの備忘録。後で逆引きできるように。

WindowsストアアプリでOpenCVを使う

C++ プログラム VisualStudio2015 Windows10

Hololensが楽しそうなのでアプリ作れないか試行錯誤しています。かたりぃなです。 開発者向けの販売とはいえ購入には踏ん切りがつかないので、何かつくれるようになったら購入したいと思っています。 というわけでWindowsストアアプリ向けに画像処理のアプリを作る基盤づくりです。 今回はOpenCVWindowsストアアプリ向け(UWP)にポーティングしてみます。

とりあえず動かしたい

手っ取り早くHololensエミュレータOpenCV動かすにはこちらがお勧め。 HololensのCPU向けにビルドされたパッケージ一式がすでにNuGetにありました。 OpenCV for Hololens (UWP/C++) - NuGet Must Haves

c++/cxのUWPプロジェクトを作って適当なopencvAPIを叩いてみたところ動作はしました。 ストアアプリ認定キットも通るので問題なく使えそうです。 このNuGetパッケージのcv::getBuildInformation()を参考にすればOpenCVソースコードからビルドするのに使えるかもしれませんね。 ただ配布されているパッケージはRelease版のライブラリのみなので、デバッグに難ありです。

公式で何かやってるんじゃない?

MSもOpenCVをforkしていました。 Easily build OpenCV-powered apps for Windows Store! - MS Open Tech ブラウザからパっと見た限り特別何か手を入れてる様子は見えません。 git cloneして中身を調べてみた内容をメモします。

既に試した人がいるので、参考にさせてもらいました。

Windows 10ユニバーサルアプリ(Universal Windows Application)でOpenCVを使う(その2) - embeddedなブログ

とりあえず中身みてみる

windowsでもpowershellが入ってコマンドライン操作も昔より楽になりました。 コマンド体系が独特ですが、まあ慣れの問題でしょう。 とりあえず中身を見てみます。

git clone https://github.com/Microsoft/opencv
git branch -a
  master
  remotes/origin/HEAD -> origin/master
  remotes/origin/contrib-enable
  remotes/origin/highgui
  remotes/origin/master
  remotes/origin/test
  remotes/origin/test-attach
  remotes/origin/test-vs2015
  remotes/origin/test_gtest_upd
  remotes/origin/update_py_script
  remotes/origin/videoio-old-sample
  remotes/origin/vs2015-samples
  remotes/origin/vs2015-samples-ARM
  remotes/origin/winrt

vs-2015-samplesってのが気になりますね。

git checkout -b vs2015-samples remotes/origin/vs2015-samples

このブランチのREADME.mdを見ると、OpenCVをUWP向けにビルドする手順が記載されています。 Short wayとLong wayがありますが、まずはShort wayを試してみます。 準備済みのソリューションファイルを開いてビルドするだけです。 何が違うのかちょっと気になったので、簡単にですがOpenCV本家と比較してみました。

  1. UWP環境でビルドするコンパイルオプションの追加(/ZWなど)
  2. vcxprojファイルにWindowsストアアプリ用の設定を追記

まず1ですが、OpenCVをデフォルト設定でビルドすると、従来のWindowsアプリ向けのDLLとインポートライブラリが生成されます。 これはWindowsストアアプリで配布できないらしく、Windowsストアアプリ用にはUWPとしてDLLを生成する必要があります。 このためのコンパイルオプションが/ZWらしいです。 方法: ユニバーサル Windows アプリで既存の C++ コードを使用する

次に2ですが、単純にOpenCV本家のビルドオプションに/ZWを付けるだけではダメでした。 UWPのvcxprojファイルをテキストエディタで開いてみるとに次の内容が記載されています。

  • ApplicationType
  • WindowsTargetPlatformVersion
  • WindowsTargetPlatformMinVersion

など。 アプリ配布のターゲットを示すもののようで、単純にOpenCVのビルドプロジェクトを/ZWを付けてcmakeした場合、このあたりの記述が行われません。 このためコンパイルエラーになってしまいます。 MS曰く適切に記述しなさいとのこと。 ユニバーサル Windows プラットフォームへの移植 (C++)

OpenCVをUWP(Windowsストアアプリ向け)にビルドする

ソリューションファイルのパスはMicrosoft/OpenCVのルートディレクトリから見て

  • vs2015\WS\10.0\ARM
  • vs2015\WS\10.0\x64
  • vs2015\WS\10.0\x86

の3つが各CPUアーキテクチャ向けのものです。 いずれのディレクトリにもOpenCV.slnがあるのでこれをビルドすればOKです。 READMEに書いてあるように環境変数OCV2015_ROOTにopencvのルートディレクトリを設定してからビルドです。 この環境変数がないとOpenCVが参照しているライブラリ(zlibとか)を探せないのでエラーになります。 Windowsストアアプリとして組み込むにはRelease版が必要ですが、開発中はデバッグ版も欲しいので、Debug,Release両方をビルドするのを忘れずに。

ビルドで生成されるもの

ビルドが終わるとソリューションファイルの配置されているディレクトリに次のものが生成されます。

  • /include
  • /lib/Debug
  • /lib/Release
  • /bin/Debug
  • /bin/Release

それぞれの役割は名前から想像できるとおり、 includeはインクルードファイル群の置き場です。 libはDLLをアプリケーションが利用するためのインポートライブラリ一式です。 binはDLL本体です。

生成されたOpenCVWindowsストアアプリで使う

ここからはストアアプリのVisualStudioプロジェクトで設定をしていきます。 ソリューションエクスプローラからプロジェクトのプロパティを開き、「C/C++ -> 追加のインクルードディレクトリ」で設定します。 libは同様に「リンカー -> 追加のライブラリディレクトリ」で設定します。 リンクするライブラリファイルはリンカの入力で指定しても良いのですが、一個一個記載していくとミスの元になるのでスクリプト化しました。 プロジェクト作るたびに設定するのも面倒ですし。 PowerShell書くのは初めてですがなかなか楽しめました。

gist.github.com

こいつを実行すると、生成されたインポートライブラリを取り込むためのC++ソースコードが生成できます。 各アーキテクチャ(x86/x64/ARM)と各ビルド(Debug/Release)libディレクトリにあるライブラリを全てリンクするようなC++ソースコードが生成できます。 こんな感じ。

// genereted powershell script from gen_opencl_linkheader.ps1
#include "pch.h"
#ifdef _DEBUG
#ifdef _M_X64
#pragma comment(lib, "C:\\myproject\\ms-opencv\\opencv\\vs2015\\WS\\10.0\\x64\\lib\\Debug\\opencv_calib3d300d.lib" )
#pragma comment(lib, "C:\\myproject\\ms-opencv\\opencv\\vs2015\\WS\\10.0\\x64\\lib\\Debug\\opencv_core300d.lib" )
#pragma comment(lib, "C:\\myproject\\ms-opencv\\opencv\\vs2015\\WS\\10.0\\x64\\lib\\Debug\\opencv_features2d300d.lib" )
// 略

これでdebug版/release版の切り替え、ターゲットCPUごとにリンクライブラリを設定しなおさずに済みます。

最後にOpenCVのDLLをVisualStudioプロジェクトに組み込んで、コンテンツとしてファイルを含めるよう設定します。 (ソリューションエクスプローラにDLLを追加してからそのDLLを右クリック、プロパティ->全般->コンテンツ->YES)

Windowsアプリ認定キットを通す

VisualStudioのプロジェクトを右クリックして、「ストア -> アプリパッケージの作成」でパッケージを作成します。 配布者名・予約済みアプリ名をプロジェクトに関連付けて、アプリパッケージのターゲットアーキテクチャを指定してパッケージ化すれば完了です。 アプリ認定キットで少しトラブったので忘れないようにメモします。

OpenCVのDLLがストアアプリとして利用不可のAPIを呼び出している

Debugビルドではストアアプリの要件を満たせないのが原因です。パッケージに含めたDLLがリリース版ビルドされているか確認しましょう。

OpenCV3.1のデフォルト設定では、生成されたDLLのファイル名でdebug/releaseどちらかを確認できます。 名前付けのルールは"モジュール名"+"バージョン番号(310とか300とか)"+"d"+".dll"になっています。 デバッグ版の場合はdが付加されて、リリース版では付加されません。 つまりバージョン番号と拡張子の間に"d"が付いているDLLを含めたパッケージをアプリ認定キットに通すとこのエラーで引っかかります。

イメージが既定です

ちょっと日本語が不自由なエラーメッセージですが、アプリ提出するならアイコンとかをデフォルト(=既定)のままじゃダメだということです。 内容をよく読むと、アプリのリソース(画像とかアイコンとか)がデフォルト設定のままだからダメだと言っているようです。 試しにアイコンを差し替えるとエラーメッセージが減ったので一通り設定してあげればよさそうです。

感想

色々と詰まりましたが、これでアプリ開発の環境は整いました。 次からは色々と試してみたいと思います。 Windows上でもPowerShellのおかげで手順の自動化ができるので、もっといろいろ試してみたいところです。 では今回はこれくらいで。