ひよこや日記

@hiroyky IT系エンジニアのまったりブログ

Alexaスキルアワード公式ハッカソンに参加した

Alexaスキルアワード公式ハッカソン

2018年7月29日開催のAlexaスキルアワード公式ハッカソン 東京に参加しました.参加した皆さんお疲れ様でした.

Alexaスキルアワード2018公式ハッカソン東京0729

台風の影響で土日二日間の開催が日曜のみの開催になりました. 1日のみで開発時間が5時間のハッカソンとなり,短時間で濃厚でした.

東急ハンズ賞いただきました.

つくったもの

ホテルの部屋でAmazo echoを使ってチェックアウトします.その時に一緒に宿泊者にアンケートをとるスキルを作りました. 今後,ホテルの一室に一台のAmazon echoなどのスマートスピーカが設置してあり,チェックアウトやルームサービスの窓口になってくれるといいですよね.

また,チェックアウトのときに,自然にアンケート内容を聞くことで,宿泊者は手を煩わせることなく回答できます.


【作ってみた】アレクサでホテルのチェックアウト,宿泊者にアンケートをとるスキル

構成

f:id:hiroyky:20180730233817p:plain

構成はいたってシンプルです.AlexaがLamdaをトリガすると,お礼とアンケートを話します.宿泊者の回答をバックエンドのDynamoDBに記録します. ホテルの従業員が今日の結果を聞いたときは,DynamoDBを参照して,統計データ(?)を話します.

ソースコード

当日チームで実装したGithubにアップロードしました.

github.com

まとめ

ハッカソンにてホテルのチェックアウト時にアンケートスキルを作りました.

Macbook Pro 2018 購入した.Windowsからまた戻ってきた

macbook pro 2018

新しいノートパソコンを新調しました.先日発表されたmacbook pro2018です. 15インチのmacbook proです.

f:id:hiroyky:20180721202109j:plain

CPU: 第8世代 Core i7 2.2Ghz 6コア
メモリ: DDR4 32GB
SSD: 512GB
GPU: Radeon Pro 555X 4096 MB
キーボード: 英字

macbookにした理由

自分,わりとWindows, macどちらでもいい人です.仕事ではずっとmacで開発を行っていますが,自宅はWindows(もしくはUbuntu)な人です.これまでノートパソコンはmacbookThinkpad行き来していました.

完全に,macUNIXとして利用しています.

1. WSLの微妙な動作の遅さが逐次気になる.(微妙に遅いんですよ.)

WSL使っている方,微妙な動作の遅さが気になりませんか? 演算が遅いというよりはコマンドを入力してから実行のレスポンスが体感的に遅く感じる.

2. WSLを利用しても,Windows側でもSDKのセットアップが必要になる(後述)

WSLでWindowsマシンをLinuxマシンのように利用できます. しかしながら,いざ開発するとなるとVisual Studio Codeプラグインを動かすためにはnodejsやらPHPの実行環境が Windows側にインストールされている必要があり,セットアップを2回しなければならない.当然,容量も2倍必要になる.

ちなみに,このあたりいい感じに解決する方法があったら教えていただきたいと思います.

3. Ubuntuなど通常にLinuxにすると不必要なところで苦労する(グラフィックドライバがおかしいとか)

じゃあ,素のLinuxを使えばいいじゃないか!となります.自分もUbuntuであったり,以前はGentooLinuxをセットアップしたこともあります.Linuxもとても使いやすいですよね. しかしながらコレ.苦労するんです.スリープからの復帰でマシンがクラッシュしたり,ノートPCをプロジェクタなど外部ディスプレイに接続したらグラフィックが落ちたりとか... あと,開発時だけならOKでも遊びに使うとなると厳しい部分あります.著作権保護のある動画を楽しんだりするなど..

4. emacs風なカーソル移動がしたい

一番の理由はコレかも.emacsは使います.そしてmacっていろんな箇所でemacs風のカーソル移動ができますよね. お仕事でmac使っているため,コレを多用しており,慣れすぎてしまったのです.これができないと厳しい;;

5. やっぱり安定稼働するUNIXがいい

Web系エンジニアがmac使い理由ですよね.サーバがLinuxだから手元のPCもUNIX/Linux系がいい. でも,たまにはAdobeのソフトウェアが使いたいし,ドライバ周りで苦労したくない. もちろんこのニーズを解決するためにWindowsではWSLを導入したりしてくれてるのですが,あともう人押しほしいです.

買った.

f:id:hiroyky:20180721202429j:plain f:id:hiroyky:20180721202109j:plain f:id:hiroyky:20180721202458j:plain f:id:hiroyky:20180721202734j:plain

現行macbook proへの懸念点と実際の感想

macbook自体は学生自体にmacbok airを使っていたし,職場でもmabook pro 2015を使っています. しかし,macbook proの2016年以降のモデルは懸念だらけだったので躊躇してました. あるあるですが,以下がその懸念点と実際に触った感想を挙げます.

1. USB TypeCだけ

イヤフォンジャックを除けばUSB Type-Cだけになりましたよね.その分,薄さを実現できたのでしょう. USB TypeCだけで不安かもしれませんが,自分はそんなに不安ではありませんでした. 少し調べるだけでも変換器はたくさんあります.薄さのメリットのほうが大きい. 自分は併せて下記も購入しました.便利そうです!

2. タッチバー

言わずとしれたタッチバーです.戸惑っているとも多いと思います. タッチバーなしのモデルもありますが,”つなぎ”で出しているだけであまりやる気ないようですよね. 今回の2018年モデルではアップグレードされなかったようです.

YoutubeでYoutuberの方々がタッチバーが便利ということ言っていらっしゃいました. そりゃ動画や画像編集などマルチメディア系だったら便利かなぁとは思います. 世の中の果たしてエンジニアはどう思っているのか..(周囲の人からはあまり歓迎する声は聞かず..)

といっても,積極的に利用することはないかもしれませんが,そこまで困ることはないかと思います. 設定で,fnキーの動作も変更できるし,fnキーを多用するアプリケーションではfnキーを常に表示するように設定できました.

f:id:hiroyky:20180721202803p:plain f:id:hiroyky:20180721202814p:plain

3. 大きすぎるトラックパッド

キーボードはいろいろあるようですが,自分が懸念した理由はコレです. トラックパッドが大きくなっていることです.

職場のmacbookThinkpadとの比較.なんでそんなに大きい必要があるの?? f:id:hiroyky:20180721202958j:plain f:id:hiroyky:20180721203045j:plain

なんでスペースキーの列とそんなに近いんですか?手の甲で触っちゃいそうです.

Thinkpadみたいに,スペースキー直下でちょうど親指の位置に左クリック右クリックのボタンがあるの最高です!!

実際使ってみると誤入力してしまうことはほぼ無さそうです.実際,この記事を書いていますが,手の甲でマウスポインタを移動させてしまうということはありません.トラックパッドの上に手のひらが乗っていることに対する違和感は多少ありますが,実利用では問題になら無さそうです.

まとめ

新しいノートパソコンを買ったという報告と懸念していた点とそれに対する感想でした. 現状,とても満足です!!

マークジェイコブスのタッチスクリーン スマートウォッチ購入レビュー!詳細スペックは?

スマートウォッチ買った 「RILEY TOUCHSCREEN WATCH

f:id:hiroyky:20180616165716j:plain

比較的ガジェット好きな自分ですが,今までスマートウォッチを持ってなかったです. 買おうかどうか迷っていたのですが,今回下記のスマートウォッチを購入しました.

stripe-department.com

マークジェイコブスっていうファッション系企業が販売しているスマートウォッチです. ファッションブランドということもあってか,デザインがめちゃくちゃいい感じです.

デザイン的にも男女双方に合いそうです.

スペック

詳細なスペックについては,価格.comやメーカサイトなどにも記載がなかったため, 各種記事を見たり,直接マークジェイコブス社に問い合わせたりして調べました.

OS: Wear OS by Google (旧名 Android wear)
CPU: Qualcomm®Snapdragon™Wear 2100
RAM: 512MB
ROM: 4GB
バッテリ: 300mAh (公称24時間持続) 充電時間は2時間程度
防水防塵: IP67, 1ATM
搭載センサ: ジャイロセンサ,加速度センサ,アンビエントライト
WiFi: IEEE802.11 b/g/n には少なくとも対応
Bluetooth: Bluetooth Smart Enabled/4.1 Low Energy
電子マネー: 非対応
メーカ保証: 購入から2年(バッテリ,事故による破損除く)
発売日: 2018年6月5日

スペック的にも十分って感じだと思いました. OSがWear OSなので,AndroidiOSのどちらとでも連携できますね. すべての項目でスマートウォッチとしては一般的な内容だと思います.

一方で,GPSや心拍センサなど豊富なセンサを搭載しているわけではないので, マラソンなど運動時に自身の状態を計測するには向いていないかもですね. とはいえ,スマートウォッチはスマートフォンと連動するため,スマートフォンGPSがあれば十分かなと思います.

また,防水防塵はIP67, 1ATMと,一般的な水の濡れ(手洗い,皿洗い,雨)などには耐えられそうですが, これを着けたままお風呂に入るとかプールで泳ぐとかはやめたほうが良さそうです.

あとはプリインストールされているフェイスのデザインとかが良い感じで!

開封

f:id:hiroyky:20180616172702j:plain

スマートウォッチの外箱と中の化粧箱

f:id:hiroyky:20180616172811j:plain f:id:hiroyky:20180616172938j:plain

同梱物

f:id:hiroyky:20180616173130j:plain

スマートウォッチ本体のほかに充電ケーブル,化粧箱,仕様書的な冊子が同梱されていました. ACアダプタは付属していないのでスマートフォンなど充電している物を利用します.

起動

念のためですが,日本語に対応しています. f:id:hiroyky:20180616173805j:plain

スマートフォンを用意してWear OSと連携をとるためのアプリをインストール. play.google.com

指示に従って進めなくいけば難なくペアリング. f:id:hiroyky:20180616174126j:plain

ペアリングして,いろいろ触ってみたりとか. f:id:hiroyky:20180616174301j:plainf:id:hiroyky:20180616174311j:plain

装着

今まで使ってた時計より軽い!

f:id:hiroyky:20180616175717j:plain

技適

当然ながら技適マークは付いていました.

f:id:hiroyky:20180616174430p:plain

まとめ

というわけでスマートウォッチを購入したので,購入したスマートウォッチと開封・起動をまとめました. またしばらくたったら使った感想書こうかなぁと思います.

色は全部で3種類あるみたいですね.

stripe-department.com stripe-department.com stripe-department.com

参考にしたサイト

HololensとWebSocketでピタゴラスイッチ

ハッカソンの報告

4月8,9日に日本マイクロソフト本社で開催されたHololens ハッカソン Vol.1に参加してきました. チームメンバをはじめ二日間ともに過ごした参加者の皆さん,ならびに主催者の方々,楽しい時間となり感謝しております.ありがとうございました.

そして,自分たちのチームが制作した作品がこちら. Hololensを利用したピタゴラスイッチです.


Hololens ピタゴラスイッチ

f:id:hiroyky:20170418223759j:plain

現実世界の物体と仮想世界のホログラムがスムーズにインタラクションする表現をやりたいとチームメンバでアイデアを出した結果,ピタゴラスイッチを思いつきました.実際の物理的なボールとホログラムのCGが交差しながら進んだらきっと面白いんじゃないか!というわけです.

Hololensのアプリケーション開発のハッカソンに,自分たちのチームだけハンドドリルやはんだごて,ニッパにカッター,段ボールなどを持ち込んで,小学生が夏休みの宿題で一作品つくっているような状態でした.

仕組み

動作の仕組みは次の通りです.

f:id:hiroyky:20170418225854p:plain

f:id:hiroyky:20170418225945p:plain

通常のピタゴラスイッチとは異なり,ステージ上には次の物が置かれています.

  • ボールや瓶といった現実の物を動きを制御するためのサーボモータや扇風機
  • 現実の物の状態を検知するためにタッチセンサ
  • 制御のためのArduino, Raspberry Pi

Raspberry Pi上でWebSocketサーバを動かし,Hololensがクライアントとして接続します. センサの値やサーボモータ,扇風機のトリガをWebSocket上でRaspberry PiとHololensが通信することで 現実の物とホログラムの同期をとりました.

WebSocketについて

自分がUnityでのHololensアプリの実装を担当したこともあり,HololensとUnity上でのWebSocketクライアントの実装について書こうと思います. Unity Editor上とHololens実機上では,フレームワークが.Net Framework3.5とUWPで違うため両方に対応した実装を行うとデバッグでも本番でも便利かと思います.

Unity Editor上でWebSocket

Unity上でWebSocketをするには次の記事に従いました.

qiita.com

C#のWebSocket用ライブラリを.Net Framework3.5向けにビルドしていますね.

インポートした際に,Unity Editor上のみでしか利用しないように設定します. f:id:hiroyky:20170418232743p:plain

UWP上でWebSocket

UWPではWebSocket用のAPIが用意されているようなので,それを使います. 公式のドキュメントに詳しく実装方法が書かれていますね.

docs.microsoft.com

ただし,このMessageWebSocketはasync/awaitを使った非同期処理での利用が前提になっており,Unityはこれに対応していません.

そこで次の記事で紹介されているような方法で回避します.

www.naturalsoftware.jp

↓こんな感じ

        var task = Task.Run(async () => {
            await websocket.ConnectAsync(new Uri(uri));
        });
        task.Wait();

切り替え

Unity Editor上とUWPのコードはプリプロセッサで切り替えればOKですね.

#if WINDOWS_UWP
// UWP
#else
// Unity
#endif

ソースコード

最終的なWebSocketクライアントを行う実装はこちらです.

github.com

なお,このリポジトリハッカソンで開発したソースコードをアップしてあります. ハードウェアと密接に絡む作品であるため,これだけではアプリとして完結しませんが,何かの参考になれば幸いです.

【永久保証付き】Arduino Uno

【永久保証付き】Arduino Uno

Hololensでワールド座標系とOpenCVの画像座標系の変換を確認

f:id:hiroyky:20170321014208p:plain

やったこと(概要)

Hololensでスクリーンショットを撮って,OpenCVで画像処理,その結果を空間に反映ということは,今後よくあるのではないかと思います. ここで重要なのが座標系の変換です.Hololensの空間であるUnityのワールド座標系とOpenCVの画像座標系を適切に変換する必要があります.

Unityはこうした座標系変換を行うAPIを提供しています.今回はそれらのAPIが適切に機能するかを検証・確認してみました.

OpenCVの画像座標としていますが,一般的な画像座標と等価です.

(何事もおそらくできるだろう という発想が危険です!)

さらに進化した画像処理ライブラリの定番 OpenCV 3基本プログラミング

さらに進化した画像処理ライブラリの定番 OpenCV 3基本プログラミング

詳解 OpenCV ―コンピュータビジョンライブラリを使った画像処理・認識

詳解 OpenCV ―コンピュータビジョンライブラリを使った画像処理・認識

OpenCVによる画像処理入門 (KS情報科学専門書)

OpenCVによる画像処理入門 (KS情報科学専門書)

方法

AirTapしたときに,次の動作を行うプログラムを作成します.

  1. スクリーンショット撮影.
  2. HololensのCursorのワールド座標を取得し,OpenCV画像座標に変換.
  3. OpenCVスクリーンショットに点を描画.
  4. その描画座標を再度,ワールド座標に変換し,空間にCubeを設置.

つまり,ワールド座標→画像座標→ワールド座標の変換を行い,スクリーンショットの点とワールド座標のCubeが同じ場所に設置されればOKです.

コード

今回作成したコードはこちらにあります.

github.com

なお,HololensToolkit for UnityOpenCVForUnity(有償)が必要です.

ポイント

変換API

ワールド座標系から画像座標系へ

画像座標系すなわちビューポート座標系の変換にはCamera.WorldToViewportPointを使います.この関数は正規化された値が返ってくること,Y軸の向きが逆(上方向)であることに注意しましょう. 従って正規化された値を画像サイズで乗算し,Y軸の向きを反転させる必要があります.

OpenCVForUnity.Point worldPointToMatPoint(Vector3 worldPosition, Mat image) {
    Vector3 viewportPoint = Camera.main.WorldToViewportPoint(worldPosition);
    OpenCVForUnity.Point drawPoint = new OpenCVForUnity.Point(viewportPoint.x * image.width(), (1.0 - viewportPoint.y) * image.height());
    return drawPoint;
}

画像座標系からワールド座標系へ

画像座標系からワールド座標系への変換には,まずビューポート座標系は正規化された値であるため,画像座標を正規化し,Camera.ViewportPointToRayでRayを取得し,ワールド座標系を取得します. また,ビューポート座標を求めるときはY軸の向きを反転させる必要があります.

bool matPointToWorldPoint(OpenCVForUnity.Point point, Mat image, out Vector3 worldPoint) {
// 画像座標を正規化,Y軸の向きを反転し,ビューポート座標を求める.
    float viewportPointX = (float)(point.x / (double)image.width());
    float viewportPointY = (float)(1.0 - point.y / (double)image.height());
    Vector3 viewportPoint = new Vector3(viewportPointX, viewportPointY);

    // Rayを使って,Z軸も含んだワールド座標を求める.
    Ray ray = Camera.main.ViewportPointToRay(viewportPoint);
    RaycastHit hitInfo;
    if (Physics.Raycast(ray, out hitInfo)) { 
        worldPoint = hitInfo.point;
        return true;
    }
    worldPoint = new Vector3();
    return false;
}

結果

う~ん,微妙にずれてるけど仕方ないのかぁ~.

f:id:hiroyky:20170321014346j:plain f:id:hiroyky:20170321014208p:plain

その他

※ 生活感ありありの画像で申し訳ありませんm_m

Hololensで初音ミクに踊ってもらった. MMDモデルとモーションの取り込み

f:id:hiroyky:20170307004236j:plain

作ったもの

Hololensでベッドの上で初音ミクに「Perfect Human」を踊ってもらいました. HololensアプリケーションにMMDのモデルとモーションを取り込んで動いています.


【Hololens】初音ミクにPerfectHumanをベッドの上で踊ってもらった

使用したもの

Hololens Tookkit for Unityに加え, 以下のものを活用させていただきました.

モデル

bowlroll.net

モーション

bowlroll.net

MMDファイルのUnityへの取り込み

MMD for Unity

github.com

開発キット

  • Unity 5.5 0p2

ポイント

MMD for Unityのインポートと修正

インポート

UnityでMMDモデルを利用するにはMMD4Mecanimを利用する方法もあるようですが,現行バージョンではUWPアプリケーションが非対応になっているようです. そこで,代わりにMikuMikuDance for Unityを利用します.公式サイトからzipファイルをダウンロードし,展開したディレクトリをそのままUnityのProjectにインポートします.

修正

インポートしたMMD for Unityに修正を加えます.2017年3月現在やや古い状態なので動くようにします・(ここではとりあえず動作することを目指して,機械的に修正を加えていきますが適切かどうかはまた別な話です.)

1 APIのアップデート

取り込んだMMD for Unityのディレクトリを右クリックしてRun API Updateをクリックします.

f:id:hiroyky:20170307002914p:plain

2 コードの修正

いくつかの行がエラーになるはずなので修正方法をピックアップします.

まず,以下のコードをコメントアウト

// AnimationUtility.SetAnimationType(clip, animation_type);

GameObject.collider, GameObject.rigidbodyのようにcolliderやrigidbodyをプロパティとして参照している箇所でエラーが出ています.そこをGetComponent<>()メソッドを使って取得するようにします.

// 変更前
parent.rigidbody
parent.collider
// 変更後
parent.GetComponent<Rigidbody>();
parent.GetComponent<Collider>();
// ・・・みたいに

MMDモデルとモーションの取り込み

MMD for Unityの公式サイトのドキュメントに従ってモデルとモーションを取り込みます.

MikuMikuDance for Unity - Howto

モデルの取り込み時にAnimationTypeをGeneric Mecanimを選択します.

f:id:hiroyky:20170307005144p:plain

アニメーションの設定

MMD for Unityでモーションのアニメーションまで作ったらあとは登録します. AnimationControllerを作ってprefabにanimationに設定していきます.

f:id:hiroyky:20170307010256p:plain

f:id:hiroyky:20170307010528p:plain

RigidbodyやSpatialMappingの設定

  • モデルにRigidbodyやColliderを設定.
  • 空間認識のためにSpatialMappingを設定.

ただ,起動直後に重力を有効にしてしまうと空間認識が完了しておらず,モデルが奈落の底に落ちてしまうため,空間認識が完了してから重力を有効にします.

まとめ

MMDのモデルとモーションを取り込んでダンスするHololensアプリケーションを作りました.

参考文献

HololensでPhotoCapture画像をワールド座標の照準オブジェをもとにトリミング

f:id:hiroyky:20170226213437j:plain

作ったもの

前回,突貫ながらHololensのQRコードリーダを開発しました.

hiroyky.hatenablog.com

今回は,QRコードリーダに正方形の照準を加えました.

f:id:hiroyky:20170226210028j:plain

前回作ったQRコードリーダはAirTapするとHololensの視野全体をキャプチャし, QRコードの検出と解析を行うものでした.

視野角全体をキャプチャするため,画像のほとんどの部分は不要です. 特に,視野角にQRコードが2つ入っていると対応できなくなっていました.

そこで,Hololensに正方形の照準を設けて,キャプチャ下画像のうち照準内のみを切り出して処理するようにしました.

仕組み

MainCamera直下に照準としてQuad(以下QrSight)を設置します. f:id:hiroyky:20170226213714p:plain

PhotoCaputureを行なったときに,QrSightの4頂点のワールド座標をキャプチャ画像の座標系に変換し,囲まれた範囲を切り出します.

ソースコード

ソースコードは前回同様このリポジトリにあります.

github.com

特に今回は Assets/Scripts/PhotoInput.csを実装しました.

ポイント

QrSightの設置

MainCameraの直下にQuadオブジェクトを設置します.枠線のみの透過pngの画像をテクスチャとして割り当てます. これを照準として利用します. f:id:hiroyky:20170226215437p:plain

  • popsition: (x, y, z = 0,0,0)
  • scale: (x, y, z = 0.2,0.2,0.2)

QrSightの4頂点の座標

AirTapで画像キャプチャされたときにQrSightの4頂点の座標を求め,座標変換を行います.

まずは,QrSightの座標(中央座標)からscaleを手掛かりに頂点をそれぞれ求めます. 今回はこのようにQuadの各頂点の位置を求めましたが,もっと良いやり方があればご教授願いです.

そして,Camera.main.WorldToScreenPointメソッドで ワールド座標系から投影座標系に変換を行います.なおこの時にRayCastした座標を使うべきか否かは悩みどころで悩んでます.

        var position = QrSight.transform.position;
        var direction = QrSight.transform.forward;
        var scale = QrSight.transform.localScale;

        // ワールド座標系でのQR照準の座標を求めます.
        var leftTop = new Vector3(
                position.x - scale.x / 2,
                position.y + scale.y / 2,
                position.z);
        var rightTop = new Vector3(
                position.x + scale.x / 2,
                position.y + scale.y / 2,
                position.z);
        var rightBottom = new Vector3(
                position.x + scale.x / 2,
                position.y - scale.y / 2,
                position.z);
        var leftBottom = new Vector3(
                position.x - scale.x / 2,
                position.y - scale.y / 2,
                position.z);

#if false
        /* Rayを使うかどうかが悩みどころ;;*/
        RaycastHit leftTopHit, rightTopHit, leftBottomHit, rightBottomHit;
        Physics.Raycast(leftTop, direction, out leftTopHit);
        Physics.Raycast(rightTop, direction, out rightTopHit);
        Physics.Raycast(leftBottom, direction, out leftBottomHit);
        Physics.Raycast(rightBottom, direction, out rightBottomHit);

        // ワールド座標系を投影座標系に変換
        var leftTopScreen = Camera.main.WorldToScreenPoint(leftTopHit.point);
        var rightTopScreen = Camera.main.WorldToScreenPoint(rightTopHit.point);
        var leftBottomScreen = Camera.main.WorldToScreenPoint(leftBottomHit.point);
        var rightBottomScreen = Camera.main.WorldToScreenPoint(rightBottomHit.point);
#else
        // ワールド座標系を投影座標系に変換
        var leftTopScreen = Camera.main.WorldToScreenPoint(leftTop);
        var rightTopScreen = Camera.main.WorldToScreenPoint(rightTop);
        var leftBottomScreen = Camera.main.WorldToScreenPoint(leftBottom);
        var rightBottomScreen = Camera.main.WorldToScreenPoint(rightBottom);
#endif

これで投影座標系に変換できたため画像上のピクセルが求まったかと思いきやそうではなくて,キャプチャ画像の座標に変換する必要がありそうでした. 次のように,各頂点の座標をいったん正規化してCameraParametersの解像度を使って変換します.

        // 投影座標系を,PhotoCaptureが撮影する画像上での座標に変換
        int leftSide = (int)(leftTopScreen.x / (float)Camera.main.pixelWidth * cameraParameters.cameraResolutionWidth);
        int rightSide = (int)(rightTopScreen.x / (float)Camera.main.pixelWidth * cameraParameters.cameraResolutionWidth);
        int bottomSide = (int)(leftBottomScreen.y / (float)Camera.main.pixelHeight * cameraParameters.cameraResolutionHeight);
        int topSide = (int)(leftTopScreen.y / (float)Camera.main.pixelHeight * cameraParameters.cameraResolutionHeight);

これで,キャプチャ画像座標系でのQrSightの頂点座標が求まりました.ただ,ズレも目立つので調整する必要ありそうです(;‘∀’)

画像の変換・トリミング

キャプチャ画像座標系でのQrSightの頂点座標をもとに,画像を抜き出します. ここはOpenCVを使えばよいと思いますが今回はゴリゴリ書いてみました.

        byte[] dst = new byte[src.Count];
        for (int y = 0; y < cameraParameters.cameraResolutionHeight; ++y) {
            for (int x = 0; x < cameraParameters.cameraResolutionWidth; ++x) {
                int px = (y * cameraParameters.cameraResolutionWidth + x) * stride;
                if (x >= leftSide && x <= rightSide && y >= bottomSide && y <= topSide) {
                    for (int i = 0; i < stride; ++i) {
                        dst[px + i] = src[px + i];
                    }
                } else {
                }
            }
        }
// *一部,ブログ記事用に本体コードに変更を加えています.

まとめ

  • 前回開発したHololens Qrコードリーダに照準を付けてみました.
  • ワールド座標系をHololensのPhotoCaptureによるキャプチャ画像の座標系に変換しました.(間違ってるかも)
  • 変換した座標をもとにキャプチャ画像をトリミングしました.