catalinaの備忘録

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

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

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のおかげで手順の自動化ができるので、もっといろいろ試してみたいところです。 では今回はこれくらいで。

ChainerのモデルデータをOpenCVで使うための準備

できれば一通りの目論見が達成してから投稿したかったのですが、まとまった時間をとれそうにないのでいったん投稿です。かたりぃなです。

何をしたいの?

ChainerなどのDeep-Learningフレームワークを使えば色々な学習モデルを構築できそうです。 次のステップとして、その学習したモデルを使ってアプリだったりサービスだったりに組み込むことを考えています。 このとき、サーバがあればPythonをインストールしてChainer走らせて完成になるわけですが、できればクライアント側で処理したいところです。 クライアント環境にPythonを導入してもいい(そういうアプリの配布方法もある)のですが、私自身Pythonはあんまり得意ではないので、妙なところで転びそうです。 できれば慣れたC++でやりたい。C++でchainerの学習済みモデルを取り込みたい

というわけで、今回のゴールは「C++でchainerの学習済みモデルを取り込む」です。 まずは「実現はできそう」というところは見えてきたので、ゴール手前までやります。

どうやるの?

方法ですが、まずOpenCVのdnnで学習済みモデルを取り込めないか考えました。 結論としては「CaffeとTorchはOpencv.dnnの関数を使えば済むけどchainerはインポータを書く必要がある」です。 インポータを書くためにはChainerの出力フォーマットを知る必要があります。chainerは現バージョンでは2種類提供されていて

でした。 numpyを使ってしまうとまたPythonの環境に戻されてしまうので、c++からOpenCVのhdfモジュールを使ってchainerが出力したhdf5を読み込む実験をしてみます。

使うライブラリ一覧

  • OpenCV3.1 dev
    • contrib
      • hdf5モジュール
      • dnnモジュール
  • libhdf

ビルドツール

ライブラリの簡単な説明

OpenCVは有名な画像処理ライブラリです。少し前まではltseezという会社がメンテナンスしていたのですが、Intelに買収されたらしい。 政治的な話はおいといて、構成です。 一般的な機能(枯れた技術)を含むものはopencv本家のリポジトリにあります。 これに対して最新技術であったり、特許なんかの理由で本家に含められないものはopencv-contribリポジトリに含められています。 というわけで、両方それぞれダウンロードしてきます。

libhdfは階層型のデータ構造を扱うためのフォーマットらしく、データサイエンスの分野でよく使われるらしいです。 このあたりにライブラリやツールがあるのでダウンロードしておきます。 The HDF Group - Information, Support, and Software

OpenCVはNuGetでインストールじゃだめなの?

NuGetだとうまくいきませんでした。 NuGetで提供されているものをためそうとしましたが、少し古いVisualStudioでビルドされているようで2015ではそのまま使うことはできなさそうです。(ディレクトリを覗いてみると2012,13用っぽいディレクトリができているのがわかります) このあたりのパッケージ定義をいじってツールセットもそれにあったものを選択してあげればいけそうな気はしますが、そうしてまで使うのは本末転倒(バージョン管理でラクできない)ので手元で全部バージョン管理します。 またNuGetでもOpenCV3.1まではリリースされているのですが、contribがどうなってるのかちょっと不安です。

cmakeの注意点

今回はver3.7を使います。 起動後にopencvやhdfのディレクトリを指定してconfigureしたときにコンパイラのバージョン問い合わせダイアログが表示されます。 ここでターゲット(x86/x64, visualstudioのバージョン)が固定されてしまいます。変更方法はわかりませんでした。 x86/64の切り替えだけなら以前はのcmakeで生成されたソリューションをvisual studioで開いてから切り替えられるようになっていた気がしたのですが。 まあ実験用としてはどちらかに固定しておけば問題ないです。 名前がわかりにくく表示されているので間違えないようにしましょう。visual studio 2015の64bitなら「VisualStudio 14 2015 Win64」です。

hdfライブラリのビルド

hdf5はさきほどのライブラリをビルドします。 ビルドツールはCmakeで。 cmakeの基本的な使い方はほかの親切なサイトに譲るとして、ここではトラブった内容と解決方法を書き留めます。

hdfライブラリのビルド後のイベントが失敗する

setlocalうんたらとかいうスクリプトがビルド後のイベントに設定されているのですが、インストールプロジェクトでインストールを試みるとここで失敗します。 原因としてはデフォルト設定ではインストール先が"c:\programfiles\HDF~"になっているためで、ここにアクセスするには管理者権限が必要です。

解決策をスマートな順に列挙します。

  1. cmakeのinstallprefix変数に適当なディレクトリを設定する
  2. visual studioを管理者モードで起動する

最後のはやっつけ仕事的ですね。 installprefix指定したところにincludeとlib,binと一通り吐き出してくれるので、これが正攻法だと思います。 configureしたらgenerateを忘れずに。

OpenCV

最後にOpenCVのビルドです。

  • opencv-contribを取りんでconfigure
  • hdfのパスを指定する
  • with-msmfをenable
  • with-python(2,3ともに外す)

msmfはMicrosoft Media Foundationの略です。レガシーになりつつあるDirect Showではなく今後はこちらが推奨とのこと。

with-pythonを外した理由は、chainerをインストールしたときにhdfライブラリがくっついていたらしく、有効にしたままだとこっちを参照してしまいました。 依存ライブラリのパスを変えてあげればいいのかもしれませんが、依存関係で面倒ごとにならないように最初から切っておきます。

OpenCVPythonから叩くことは当面は無いので。2.7系3.5系それぞれ外すのを忘れずに。

OpenCV-contrib

windows環境だとopencvのビルドで多数の警告が出ることがあります。 警告はW4819(文字コードunicode形式で保存してください)ですが、とりあえずvisual studioの警告抑制で4819を指定しておきます。

opencv,hdfを使うプロジェクトを作る

visual studioを起動して適当なプロジェクトを作ります。 win32コンソールでいいんじゃないでしょうか。

ライブラリの参照パスの設定

参照プロジェクトとしてopencvを指定すればいいんですが、もういい加減面倒になってきました。dllをコピーして済ませます。 ライブラリディレクトリとインクルードディレクトリの指定をして、インポートライブラリもすぐ使うものだけ指定します。 libhdfとopencv_coreがあればいいかと。

hdfを読む実験(途中)

libhdfは私が欲しい機能と違う気がしてきたので、コードの途中までです。(投げやり) ちなみにこのコードのままではcv::Matの型やサイズを指定していないので実行時エラーになります。

 const std::string  hdf5_file_path("testmodel.hdf");
    auto hdf5_inst = cv::hdf::open(hdf5_file_path);

    const std::string layer_name = "predictor/conv1";
    if (hdf5_inst->hlexists(layer_name) ) {
        auto mat = cv::Mat();
        hdf5_inst->dsread(mat, "predictor/conv1");
    }

何が違う?

このhdfライブラリはhlexistsで目的のノードが存在していることを確認してからdsreadすれば、目的のデータは読めそうです。 しかしこういったインターフェースは私が欲しいものではありません。

私が欲しい機能は 「データ構造が変わってもプログラムを変更せずに動作確認したい」 です。

対するhdfの機能は「データの階層構造は固定されたものである」という大前提があります。 これは「chainerで層を増やして学習したものをOpenCVで試したい」といったときにプログラムを書き換える手間が発生します。

hdfそのままだと扱いづらい。どうしよう?

hdfの構造なんてそういうものと言われればそれまでかもしれませんが、ちょっと納得いきません。 私が欲しいのはboost::ptreeみたいなパーサです。 libhdfのツールにdumphdfというのがあってxml出力できるようなので試してみましたが、xmlにするとファイルサイズが大変なことになってしまったのでちょっと工夫が必要そうです。 (以前作った3層のCNNで10MByte超)

感想と今後の展望

xmlとhdfのハイブリッド構成ができればいいのかもしれません。 xml側にネットの構造だけ記述されていて、実際のwとbはhdfから読んでくるとか。 色々工夫する余地はありそうです。 では今回はこれくらいで。

Chainerでcifar-10画像分類を試してみる

やっとchainerでCNNを動作させるところまで辿り着きました。かたりぃなです。

何がやりたいのか?

ARというかHololensのMRで現実世界のオブジェクトを識別して追加の情報をユーザーに提示できれば楽しいだろうなと思っています。 HololensのAPIを軽く見たところ、深度マップなどの面倒は見てくれるようですが、画像からの物体検出などは見当たりませんでした。 画像処理といえばOpenCVなんかが有名で、最近はdnnモジュールが追加されているのでこいつを使って公開されている学習済みモデルを取り込めば一般物体認識はできそうですが、学習済みモデルを持ってくるだけでは私のやりたいことに届かなさそうです。 手作業で前処理や特徴抽出を記述していくのもアリかもしれませんが、そういう試行錯誤に時間を費やすのは勿体ないと思います。 なら自前でモデルを作ってDeepLearningのフレームワークを使って学習させよう、そしてAR/MRでなんか面白いことやりたいなといったところです。 過去にChainer動かしてみたりもしてますし、ゲーム目的とはいえGPUもよさげなのが手に入りました。 さっそくやってみます。 今回のゴールはcifarデータセットをCNNで処理して一般物体認識を行うことです。

cifarデータセットとは

10種類のラベル付けされた画像のデータセットです。一般物体認識における分類問題と呼ばれるものです。 画像の情報として

  • RGBの3チャンネル
  • 32x32 pixel です。 これができれば私がやりたいことの実現に向けた足掛かりになりそうです。

データセットの中身を確認する

cifarデータセットpython-typeでダウンロードしてそこからデータを取り出します。 pythonはあまり慣れていないので調べることが多いです。 ネットの情報ではcPickleを使おうという情報が散見されますが、どうやらインストールしたpythonのバージョンにはcPickleが無いらしく、仕方ないのでpickleを使います。 シリアライズとデシリアライズを面倒見てくれるモジュールらしいです。 手元の環境ではエンコードタイプの問題でややこしいことになってしまいました。

# python3ではcPickleがなくなったらしいので、pickleを使う
import pickle;

# metadataがラベルデータ
# それ以外がデータセット
# データは32x32,3ch(RGB)の形式

# ただのバイト列としてエンコーディングされたものとして扱う
f = open('data_batch_1', 'rb')
train_data = pickle.load(f, encoding="bytes")

len(train_data)
# result : 4
train_data.keys()
# result : dict_keys([b'filenames', b'data', b'labels', b'batch_label'])
type(train_data[b'data'])
# result : <class 'numpy.ndarray'>
train_data[b'data'].shape
# result : (10000, 3072)
type(train_data[b'labels'])
# result : <class 'list'>
train_data[b'labels'][:10]
# result : [6, 9, 9, 4, 1, 1, 2, 7, 8, 3]
sample_image = train_data[b'data'][:100].reshape((10, 10, 3, 32, 32)).transpose((0, 3, 1, 4, 2)).reshape((320, 320, 3)) # 先頭100個をタイル状に並べ替える
Image.fromarray(sample_image).save('sample.png')
# result : outputfile "sample.png"

これでデータ構造はわかりました。何か目に見えるものがあると達成感ありますね。

CNNとは

畳み込み(2次元カーネル)を使ったニューラルネットワークです。 今回は動かすことが目的なので、細かいパラメータ調整はしていません。

こちらのページを参考にさせていただきました。

Chainerのtrainerを使ってCIFAR-10の分類に挑戦したかった - Qiita

詰まったポイント

ネットで調べてみましたが、少し前のバージョンのchainerのコードが多く見受けられました。 functionsetとforwardで順方向の計算グラフを定義されていたりしましたが、functionsetは非推奨となったようで、NN全体をchainとして定義するのが今の主流のようです。 手作業で書こうとしましたが、ゼロから書くのはまだ無理でした。 上記ページのコードを引用して動作確認しました。 pickleのところとか、学習結果の出力を少し試してみた程度の変更です。

全体のコード。

giste82cb557c1939de2f1bb45089637ea59

cpuのみで動かすと重くて全然進みませんが、GPUなら数十分で終わりました。これなら色々と試行錯誤できそうです。

今後の展望

以前に試したARの原理の延長で、物体ごとに異なるオブジェクトを表示してみたいですね。

ARの原理実験 - catalinaの備忘録

ただ、カードゲームなんかで全ての種類のカードを分類するのはちょっときつそうなので、適当な分類ラベルを選択して限定的に実装してみたいと思います。 またDeepLearningを使えば検出精度の向上も期待できるかもしれません。 DeepLearningで何ができるか、色々と試行錯誤してみましょう。 週末のまとまった時間でキリのいいところまでできたのでひと段落です。

では今回はこれくらいで。

UWPで音声認識APIを試してみる

画像の分類問題に少し飽きてきました。かたりぃなです。
機械学習を使った画像の分類方法を色々と試していますが、どれも私のやりたいことと少しずれている感じがしていて少し煮詰まった感があります。

音声認識に挑戦(ライブラリを叩くだけ)

画像や映像よりも先行しているイメージのある音声の識別ってどういう理論なのだろうと思いつつPRMLの後ろのほうの章をじっくり読んでいますが、まだまだ修行が足りないらしくよくわかりません。
時系列のデータ扱うのって色々面倒だなーと思い始めています。
そういえばWindowsの左下で「何でも聞いてください」と言ってる人がいますね。マイクアイコン付いてますし、試してみましょう。
Hololensでこれが使えれば遊びの幅が広がりそうなので購入するための言い訳に使えます。

Microsoft音声認識APIを試す

まずは自分のプログラムで試す前にCortanaさんに話しかけてみます。
思った以上にお利口さんで、動画サイト見ながらマイクに音声を入れてもしっかり識別してくれます。
ユーザー見えのふるまいとしてCortanaさんがやってくれることは次のようなことでした。

  • 音声を認識して文字列にする
  • 文字列をもとにアプリやブラウザを起動する

試した単語は次の4つです。最後のは意地悪テストの域に入るので、まあ充分実用的な精度で識別できています。
発音の識別だけでなく形態素解析までやってくれてるんでしょうか。なんかすごい。

  • 「ぺいんと」

  候補「ペイント」のアプリを表示後にペイントを起動

  • 「はいぱーぶいまねーじゃー」

  候補「Hyper v マネージャ」を表示後にブラウザで検索結果を表示

  • 「とらんぷし」

  候補「トランプ氏」を表示後にブラウザで「トランプ氏」の検索結果を表示

  • 「じぇんきんすし」

  候補「jenkinsし」を表示後にアプリ候補「天気」を表示

HyperVマネージャを起動してくれなかったのはちょっと残念です。Cortanaさんのすぐ隣にいるのに。
ジェンキン寿司は古いネタなのかCortanaさんには通じませんでした。

公式ドキュメントはこちら
https://msdn.microsoft.com/en-us/library/windows/apps/windows.media.speechrecognition.aspx

簡単に試せそうなものを先人が示してくれているのでコピペして動かします。
UWPで音声認識 - かずきのBlog@hatena

まとめ

10行未満のコードで簡単に音声認識ができました。
これなら気軽にアプリに組み込むことができそうです。
Hololensのような端末で何か作ることを考えたときに、こういったユーザーインターフェイスは従来のそれと比較して重要度が相対的に高くなると思います。
どこまで細かいことができるのかはまた別途試してみたいところです。
では今回はこれくらいで。

HoloLensの開発環境を試してみた

やっとうちのメインマシンがWindows10Proになったので試してみました。かたりぃなです。

とはいっても実機は無いのでエミュレータです。

 

実験環境

実験環境はこんな感じです。HyperVを有効化しておくことを忘れずに。

HyperVとは?

いわゆるMicrosoftの仮想化技術です。私自身使うのは初めてです。

今回使うHyperVはクライアントHyperVと呼ばれているもので、VMWareとかVirtualBoxと同系列になります。Windows上で他OSを動かすのに使います。

 

必要なツールをインストールする

公式サイトみながらやればいいんですが、英語読むの面倒な人はこのあたりを参考にすればいけると思います。

HoloLens Emulatorアプリ開発入門(1):HoloLensのAR世界を疑似体験できる、エミュレーターの基礎知識とインストール、基本的な使い方 (3/3) - @IT

 

おおまかな手順としては

  1. HyperV仮想化の有効化
  2. VisualStudioのインストール
  3. Hololensエミュレータのインストール

です。

VisualStudioのインストール時にUWP関係のものにチェックを付けるのをお忘れなく。

 

自作プログラムを準備

プログラムはXAMLのhelloworldでもいいのですが、私がやりたいことを試すためにDirectX11のテンプレートから始めることにします。

言語はC++cxでやってみます。とはいってもまだコードは書きません。サンプル動かしてみてエミュレータ上で動くアプリがどんなものかを見るだけ。

公式発表ではDirectX11 laterとのことですが、DirectX12はマニュアル見た限りすごく低レベルなAPIに思えたので、11でいってみます。

https://developer.microsoft.com/en-us/windows/holographic/install_the_tools

プロジェクト作成から実行までの手順はVisualStudioに慣れている人ならいつもの手順ですね

  1. 新規プロジェクトを選択
  2. DirectX11のテンプレートをダウンロード(立方体が回ってるやつ)
  3. ビルド
  4. 実行

まあ普通にWindows上でアプリが起動するかと思います。

HoloLens上で実行してみる

以前にMicrosoft SurfaceRT向けに何か作ろうかなと試したことがありました。手順はその時と同じです。ツールバーから実行環境を指定するだけです。

f:id:Catalina1344:20161106204757p:plain

なんか未来ちっくな名前の人がいますね。これです。

f:id:Catalina1344:20161106204807p:plain

 

これでHololensEmulator上へのアプリのデプロイとデバッグが開始されます。

 

エミュレータの設定は?

どうやらこれで自動的にHoloLensの仮想マシンがHyperV上に生成されるらしく、HyperVマネージャを起動して確認するとそれっぽい名前の仮想マシンが作られていることがわかります。

手元の環境ではデフォルト設定でも軽快にエミュレータは動作したので、しばらくはこれで色々やってみることにします。

 

トラブルシューティング

今回詰まったポイントは2つでした。

VisualStudioのHoloLensデバッグセッションが開始できない

HoloLensエミュレータは起動しているのにデバッグセッションが開始できないとVisualStudioに言われることがあります。

どうやらエミュレータ上にアプリをデプロイするにはアカウント設定を終える必要があるっぽいので、手持ちのMicrosoftアカウントを設定します。

英語キーボード設定になっているので記号入力で詰まってしまいますが、試しにタイプしながらやればすんなりいきました。

HoloLensエミュレータの操作に慣れる

慣れてきたので思い出しましたが、FPSゲームっぽい操作感覚です。

  • 左クリックとドラッグ=頭の向きを変える
  • 右クリック=視点カーソル?地点の選択
  • WSAD=移動

です。

スペースキーを押すと空間マップが表示されます。手元のカメラではこんなの作れない(kinnectがあればもうちょっと色々できるのかな?)ので、サンプルとして準備されている空間マップを切り替えてみると楽しめると思います。

 

まとめ

HoloLensエミュレータを動かしてみただけでもそれなりに楽しめました。

次回はもう一歩進んで何か面白いことができればなと思います。

Microsoft hololensへの期待

久しぶりのブログ記事です。かたりぃなです。

MicrosoftHMD(ヘッドマウントディスプレイ)のデベロッパー向けエディションが日本で発売されるという話を耳にして歓喜しています。

Microsoft HoloLens の日本での提供について | News Center Japan

APIリファレンスも一通り流し読みしたので、私自身の見解を簡単に整理したいと思います。読み間違い・勘違いも含まれている可能性がありますので、詳細は公式サイトをあたってください。

hololensとは?

公式サイト:Microsoft HoloLens | Official Site

 AR(拡張現実)とVR(仮想現実)のさらに進んだ概念としてのMR(複合現実)を実現するためのデバイスです。

利用側からみた特徴としては

  • Windows10搭載
  • 透過型ディスプレイ
  • スピーカ、マイク、カメラなどの現実世界と情報をやり取りするためのデバイスを内蔵

といったところでしょうか。

アプリ開発側からみた特徴としては

  • Intel32bitCPUと、それに付随するDSPか何のでリアルタイム演算
  • Windows10のストアアプリとして配信可能(UWPアプリ)
  • 3DグラフィックのレンダリングはDirectX11世代
  • Unity対応
  • 開発用エミュレータを動作させるにはHyperVが必要

さっそくエミュレータを試そうとしみましたが、残念ながらうちのOSはWindows10-Homeのため、HyperVを動かせないので環境作るためにしばらく保留状態です。

またWindows8以降から標準搭載されているWindowsストアでのアプリを配布ですが、Windows8発売当初は開発者向けには「ストアアプリ」と銘打ってVisualStudio用のテンプレートの配布などが行われていましたが、今は複数のデバイスにパッケージを共通化して配布するための仕組みとして「UWP(ユニバーサルウインドウズプラットフォーム)」が標準となっています。開発言語としてはC#,C++/cxなどが利用できるようです。

C++/cxって何ぞ?と思って今色々試している最中ですが、利用目的から解釈すると「ストアアプリで配布するアプリを作るためにMicrosoftがマネージド拡張を施したc++」です。

開発環境はこれくらいにして、ハードウェア的な課題も既に見えていて次のようなものがあります

  • 視野角が狭い
  • バッテリー駆動時間(2~3h)

特に視野角についてはMicrosoftも認識しているようで、今後改善していくようです。

 

VRとAR

hololensの仕組みの詳細に入る前に、世間一般を賑わせているVRとの違いについて。Oculusとか最近だとPSVRなんかが有名で、視界全体を覆うHMDを使うことで仮想空間への没入感を高めてユーザー体験を向上させようというアプローチです。

VRは仮想世界を主とし、そこに対していかにしてユーザー体験を向上させるかといったアプローチですが、ARは現実世界ありきで、そこに対して付加価値を提供していくかといったアプローチになります。

MRはさらに進んだ概念で現実世界と仮想世界の融合を目指すもので、どちらかといえばARの延長上(ARを包含するといったほうが正しいのかな)にある概念です。

 

hololensの原理を考える

原理はあちこちの記事で述べられているので関連しそうな技術要素だけ簡単に整理します。

現実世界に立体像を表示するという研究や成果は既にあって、例えば日本では

空中ディスプレイ エアリアルイメージングパネル

なんかがあります。

ここで案内されている展示場所に行けば実体験できるので、直接行けるなら実体験したほうが早いと思います。実際に触ると感動とともに課題なんかも見えやすいので。

実際に試させてもらいましたが、空中に結像されたメニューをそのまま選択する方式はユーザーにフィードバックが無いためちょっと難しいと感じました。

こういった技術を応用すれば現実世界で目的の場所に結像はできるわけですが、次はその位置を確定する必要があります。このあたりはおそらく

  • kinectと同様の深度センサを使って奥行を検出
  • 空間マッピングのためのアルゴリズム(ptam?dtam?slam?)
  • hololens自身の位置推定に加速度センサとジャイロセンサを使う

あたりかなと思っています。ptamとかよくわかってませんが。

機能を個別にみていくとhololensは基本的な機能は揃っているわけで、あとは拡張現実感を出すためのノウハウが必要になると思います。

加速度と角速度を使った姿勢推定ではカルマンフィルタや相補フィルタが有名です。

拡張現実感を出すためには現実と仮想の世界の間での誤差が小さいほど良い結果になりますが、この誤差を小さくする(外れ値とかノイズ対策?)機能としてアンカー(詳細は開発者マニュアルを参照)を置いてオブジェクトを固定するという解決ができそうです。

 

何ができるの?

応用分野の話になるので少しそれますが、こういうのとか楽しそう。海外のほうが先行してますね。

「遊戯王」のデュエルシーンが現実に!マイクロソフト製ARメガネ「HoloLens」でリアル再現した動画が話題に - Character JAPAN

 

以前PCのUSBカメラでやってみたもの

ARの原理実験 - catalinaの備忘録

 

カードゲーム好きなのでよく遊んでいますが、これをそのまま実現することはやっぱり困難があると思います。

既に分かっている課題は

  • カード種別の認識をどうやるの?
  • モデルデータをだれが作るの?

あたりです。

データが無いのは諦める(え?)として、カード種別は非常に膨大で、発売元が存続する限りは増えるので、画像分類問題のラベル(種類)が増えても有限時間内で種別を判断できるアルゴリズムがほしいなと思っています。(それが今まさに読んでるPRMLだったりするわけですが。)

 

まとめ

horolensは夢を現実にしてくれる気がします。そんな夢を買うために$3000という金額が必要になるわけですが。

本職は技術屋なので、自分への投資と思って買うのもアリかなと思いつつも悩みます。

まだ正式な発売まで時間はありますし、開発者向けのあとの一般向け販売ではもうちょっと手を出しやすいお値段になるとは思うので、情報を集めて整理しつつ考えましょう。

では今回はこのあたりで。

windows10でchainer+CUDA+cuDNNをGPUで動かしてみた

ディープラーニング用のフレームワークを何か動かしてみました。かたりぃなです。 以前にCPU版のみのchainerを動かしてみたことはあるのですが、今回はGPU版に挑戦です。 今回の記事は動かすことよりもトラブルシューティングが主な内容になります。

作業前の自分の作業環境でchainerに関連しそうなものはこんなものでした。 最初はVMWareやDockerを使おうかとも考えていましたが、仮想環境からGPUがどう見えるのかとか調べるのが面倒になってきたので、Windows上で直接動かします。

  • ソフトウェア

  • ハードウェア

    • GeForce GTX670
    • IntelCore-i7 3.4G
    • RAM 8GB

以下のサイトを参考にして必要なものをインストールしていきました。

参考にさせていただいたサイト

Windows上にChainer v1.5+CUDA+cuDNNを一番簡単に入れれる方法 - Qiita

WindowsでChainerをGPUを使って動かす - TadaoYamaokaの日記

Windows環境でChainerのGPUを使えるようにするまで - Qiita

chainerの準備

基本的なインストール手順は先人が示してくれているのでそれに従います。

  1. anaconda(python3.5)を入れる
  2. cuda-toolkit(7.5)を入れる
  3. chainerを入れる

というわけで試しに動かしてみます。 chainerのexamplesにmnistがあるのでこれを走らせます。 コマンドは

python train_mnist.py -g 0

です。

とりあえず動かすことはできました。 動かすまでにいろいろと問題があったので、問題が起きたポイントごとに原因と解決策を整理します。 その前にトラブルシューティングの基本的なことを一つ。 上記pythonコマンドを打ってエラーが出た場合、以下の情報が表示されます。

  • コマンドが戻り値0以外で終了した(異常終了した)
  • 異常終了したコマンドラインとパラメータ

エラーになったコマンドを実際に打ってみてエラー情報を確認しつつ進めます。

cuda-toolkit7.5はvisualstudio2013までしかサポートしていない。

nvcc(cudaコンパイラ)が出すエラーなのですが、visual studio2013付属のコンパイラまでしかサポートしないというエラーメッセージを出してきます。 おとなしくvisual studio community 2013をインストールします。 昔のvisual studioは最新版(手元の環境では2015)がインストール済みの場合は古いバージョンはインストールさせてくれなかった気がしますが、今回はすんなりインストールできました。

Windowsのユーザー名が日本語

何をいまさら的なところで足元をすくわれました。 windows10にアップグレードしたときにmicrosoftアカウントを作ったのですが、そのとき適当に作ったアカウントが日本語名でした。 日本語ユーザー名で作業しているとpythonがパス文字列をUTF8デコードするところでエラーになります。 今までwindowsで作業するときはVM上か、VisualStudioで作業する場合でもD:\myproject\とかで作業していたのであまり問題にはなりませんでした。 どうしてpythonだけエラーになるのだろうと調べてみましたが、アプリケーション固有の設定情報(ここではanaconda/python)が置かれる場所がここでした。 C:\Users\日本語ユーザー名\AppData\

python側の文字コードの設定を変更するだけでもいけるのかもしれませんが、また同じ轍を踏みそうなのでアルファベットのみのユーザー名を作り直します。 Microsoftアカウントはクラウド連携するので次のような手順で作り直します。 一旦クラウドから切り離してローカルで作業するのがポイントですね。

  • ユーザーアカウント作り直し&データ移行の手順
    • 作業中のユーザーアカウント(microsoftアカウント)をクラウドから切り離してローカルアカウントでログインしなおす
    • ローカルアカウントで新規にユーザーアカウントを作成
    • 新しく作成したユーザーアカウントに必要なデータ(AppDataとかDeskTopとか)をコピー
    • 新しく作成したローカルユーザーアカウントでログインしなおした後、microsoftアカウントに紐づける

コンパイラのパスが通っていない

nvcc(cudaコンパイラ)がvisual studio 2013のコンパイラのパスを認識できない状態だとこんなエラーになります。

nvcc fatal   : Cannot find compiler 'cl.exe' in PATH

環境変数PATHの設定しましょう。 visualstudio2013のcl.exeは私の環境ではこの場所に置かれていました。 C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin

感想と今後の予定

とりあえずchainerのサンプルをGPUで動かすことまでできたのでひと段落です。 実行速度はGPUを使ったほうが圧倒的に早くなっています(以前試したCPUのみの場合は30分以上かかっていたものが5分前後になった)。 これくらいの速度ならトライ&エラーしやすそうですね。 速度計測は今回は面倒&興味がないのでやりません。体感できたから良しとします。 今回利用したPCは何年も前に買ったもので、当時出たばかりのDiablo3、バージョンアップごとに重くなっていくA列車で行こう9などの3Dゲームを快適に遊ぶために買ったものだったのですが、意外なところで役に立ってよかったです。

とりあえず最初の一歩は踏み出せました。 今後はchainerの詳しい使い方を調べていこうと思います。

その他参考にした資料など

基礎からがっつりやるならPRMLもよいのですが、難しい内容かつ大判なので通勤電車で軽く読むといったことがしづらい本です。 私は紙のノートに数式ごりごり書いていかないと覚えられないオールドタイプですので。 通勤中はこのあたりの本を読み進めていくのが最近の私のスタイルです。PRMLと比べて小さめサイズというのもありがたいところ。 帰りの電車の中で読んでいると、疲れている時などは丁度いい感じに眠くなれるので、疲労度チェックにも使えます。

イラストで学ぶ ディープラーニング (KS情報科学専門書)

イラストで学ぶ ディープラーニング (KS情報科学専門書)

この本は実践的な内容でした。どんなフレームワークがあるのか、どんなことができるのかといった内容が多いと感じました。 もちろん数学的な説明もしっかりと丁寧になされているので「ディープラーニングってよくわかんないけど、動かして試してみたい」って人向けかと思います。

深層学習 Deep Learning

深層学習 Deep Learning

こちらは機械学習人工知能の歴史的な内容を踏まえての学術的なしっかりとした解説が主な内容でした。 体系的にしっかりと学ぶならこちらのほうがよさそうです。