Skip to the content
soy-software

ソイソフトウェアではゲームやアプリを作ってます!

CYwLTP6VAAAUc4e

こんにちは、海行です。
Doge CameraというAndroidアプリを作りました。

端末のカメラで見えている映像に対して、リアルタイムにDogeがDoge風にコメントしてくれるという物です。
わかりやすいように実際にコメントをボイスで読み上げる機能も付けました。
スクリーンショットを撮影、保存する事もできます。

Dogeとは? → 参考リンク:2013年に大流行のミーム Doge とは

Unity3DとGoogle Cloud Vision APIを使用して制作しました。
Cloud Vision APIが限定プレビュー版なので利用制限があるため、残念ながらアプリ配布はまだ行えません。

一か月ほど前にGoogleがCloud Vision APIを発表した時に真っ先にこれが思いつきました。
これの何が面白いかというと、今見えている風景に対してコンピュータがそこに何が映っているのかを認識してくれます。
これまでも人間の顔を認識する事くらいは出来ましたが、自転車を見たら自転車、アニメを見たらアニメだという風に多様な物を識別できるというのは画期的ではないでしょうか。

↓このDoge Cameraを公園に持って行った様子のプレイ動画です。

[フレーム]

アプリに表示されてるDogeの線画はWulcanis さんからお借りしました。

リンク:Shibe Lineart ( Free to use) REUPLOADED: MORE DOGE

技術的な話


このアプリはGoogle Cloud Vision APIを試しに使って何か作ってみようという趣旨で制作しました。
Google Cloud Vision APIを使うと何が出来るのかというのはこちら(Node.jsとGoogle Cloud Vision API使って色々な画像認識試してみた。)の記事に詳しいです。こちら(Cloud vision apiを使ってみた。)でも各機能を試されてます。

すでに色々情報が上がってますが、Unity3Dを使ってAndroidからCloud Vision APIを使用という点は史上初っぽいので、その辺をざっくり解説します。

やってる事は非常に簡単です。
1リクエスト用のJSONを作る
2HTTPリクエストでAPIを叩く
3レスポンスJSONからデータをゲット

1リクエスト用のJSONを作る

Cloud Vision APIはJSONでリクエストを出してJSONでレスポンスを受け取るので、リクエスト用のJSONを作りましょう。

UnityでJSONを扱う時は私は以前はLitJsonを使ってましたが、Unity5.3でUnity公式でJSONがサポートされたのでそっちを使ってみます。
UnityのJsonUtilityはDictionary(というかインスペクタに出てこないもの)はシリアライズしてくれないようです。
LitJsonは確か入れ子のDictionaryとかも何なくシリアライズしてくれて簡単だったのですが、JsonUtilityは不便な分高速だという話なので、我慢して使ってみます。

参考リンク:Unity 5.3で実装されたJsonUtilityの注意点まとめ

JSONをシリアライズするためのクラスを設計します。
ドキュメントにクラス設計が書いてるのでそれ通りにクラスを書いていくべきなのですが、今回は動けばそれでいいのでリクエストJSONの例を見てパパッと作っちゃいます。

↓これがドキュメントのGETTING STARTEDに載ってたリクエストJSONの例です

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"requests":[
{
"image":{
"content":"base64-encoded file data"
},
"features":[
{
"type":"LABEL_DETECTION",
"maxResults":1
}
]
}
],
}

これ通りに設計すればOKですが、気を付けるポイントは、[]は配列になってる事と、””に囲まれてたら文字列ですが囲まれてなかったら数値だという所です。

設計したクラスはこんな感じです。

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
//-----------REQUEST--------------
[System.Serializable]
publicclassRequestClass
{
publicList<Requests>requests;
}
[System.Serializable]
publicclassRequests
{
publicImages image;
publicList<Features>features;
}
[System.Serializable]
publicclassImages
{
publicstringcontent;
}
[System.Serializable]
publicclassFeatures
{
publicstringtype;
publicintmaxResults;
}

2HTTPリクエストでAPIを叩く

以前のUnityだとHTTP通信するにはWWWクラスを使ってましたが、新しくUnityWebRequestクラスができてます。
WWWがGETとREST通信にしか対応してないのに対してUnityWebRequestはPUTやDELETEにも対応してて上位互換なので新しい方を使いたいですね。

参考リンク:UnityWebRequestについてちょっと調べてみた

ところがどっこい、実際に使ってみたところ何故か400番の不正なJSONエラーが出てしまいました。
WWWだと普通に通信が通るので、しょうがないので今回はWWWで通信します。

叩くURLは

https://vision.googleapis.com/v1alpha1/images:annotate?key=

↑Cloud Vision用APIキーをGoogleデベロッパーコンソールから入手して上の末尾に足した物を叩きます。

3レスポンスJSONからデータをゲット

レスポンスで返ってきたJSONをデータにします。
リクエストJSON用のクラスを設計したのと同じ要領です。

↓ドキュメントのGETTING STARTEDに載ってたレスポンスJSONの例です

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
{
"responses":[
{
"labelAnnotations":[
{
"mid":"/m/0bt9lr",
"description":"dog",
"score":0.89208293
}
]
}
]
}

↓JSONから設計したクラスは以下のような感じです。

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//----------RESPONSE--------------
[System.Serializable]
publicclassResponseClass
{
publicList<Response>responses;
}
[System.Serializable]
publicclassResponse
{
publicList<LabelAnnotation>labelAnnotations;
}
[System.Serializable]
publicclassLabelAnnotation
{
publicstringmid;
publicstringdescription;
publicfloatscore;
}

最後に、1〜3の部分の処理を行っているソースコードを抜粋して掲載します。

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
IEnumerator coroutineSendHttpRequest()
{
while(true)
{
yield returnnewWaitForSeconds(3f);
//リクエスト作成
RequestClass requestClass=newRequestClass();
Requests requests=newRequests();
requestClass.requests=newList<Requests>();
requestClass.requests.Add(requests);
//webcamtextureをbase64エンコードテキストに変換
_snapTexture.SetPixels(_webCamTexture.GetPixels());
_snapTexture.Apply();
byte[]bytesJpg=_snapTexture.EncodeToJPG();//クオリティ下げたら送信サイズ下がる
requests.image=newImages();
requests.image.content=System.Convert.ToBase64String(bytesJpg);
requests.features=newList<Features>();
Features feature=newFeatures();
feature.type="LABEL_DETECTION";
feature.maxResults=10;
requests.features.Add(feature);
stringjsonData=JsonUtility.ToJson(requestClass,false);
//Debug.Log(jsonData);
stringurl="https://vision.googleapis.com/v1alpha1/images:annotate?key=";
url+=windowsApiKey;
Dictionary<string,string>header=newDictionary<string,string>();
header.Add("Content-Type","application/json; charset=UTF-8");
byte[]postData=System.Text.Encoding.Default.GetBytes(jsonData);
WWW www=newWWW(url,postData,header);
yield returnwww;
// 成功
if(www.error==null)
{
//Debug.Log("Post Success\n" + www.text);
//レスポンスを解析
ResponseClass responseClass=JsonUtility.FromJson<ResponseClass>(www.text);
//信頼度0.7以上のラベルをリストに突っ込む
if(responseClass!=null)
{
for(inti=0;i<responseClass.responses.Count;i++)
{
Response response=responseClass.responses[i];
for(intj=0;j<response.labelAnnotations.Count;j++)
{
if(response.labelAnnotations[j].score>=0.7f)
{
LabelToken labelToken=newLabelToken();
labelToken._lifeTime=10f;
labelToken._label=response.labelAnnotations[j].description;
labelToken._score=response.labelAnnotations[j].score;
_labelTokenList.Add(labelToken);
}
}
}
}
}
// 失敗
else
{
Debug.Log("Post Failure");
}
/*var request = UnityWebRequest.Post(url, jsonData);
request.SetRequestHeader("Content-type", "application/json; charset=UTF-8");
Debug.Log(request.GetRequestHeader("Content-type"));
yield return request.Send();
Debug.Log(request.responseCode.ToString() + ":" + request.downloadHandler.text);*/
}
}

こんな感じになります。

下の方のコメントアウトしてる箇所は動かなかったUnityWebRequestで書いてた部分です。
誰か動かない謎がもしわかれば教えてください。

今後の展望


実際に試してみてGoogle Cloud Vision APIがどんなものか大体わかりました。
Cloud Vision APIはディープラーニングの技術が使われているので、ディープラーニングによる画像認識もこういう感じかなと掴めたのでディープラーニング初心者が取っ付いてみるという意味でも面白かったです。

Cloud Vision APIはまだ限定プレビュー版なので正式リリースまではこれを使って製品を出したりは出来ませんが、リリースされたら有料になるんだろうなあ。

今回使ったのはラベルディテクションという画像に何が写ってるか識別する機能ですが、画像を投稿するサービスだとセーフサーチ機能を利用したり、レシート手動入力サービスだと画像OCRの機能を利用していきそうですね。

フォルダの中にある大量の画像を自動で仕分けするみたいな使い方もできそうです。

これからはコンピュータがどんどん世界を認識していくんだなあという予感を抱きました。
今はまだ人を見てもpersonという事までしかわからないみたいですが、いずれ顔を見たらそれが誰かまでわかるようになるでしょう。
コンピュータが"まなざし"を持つようになるという事ですね。
突き詰めていくと何が起こるのか...それはまだわかりません。

何か面白い使い道のアイデアがあれば、みなさんも是非Google Cloud Vision APIを試してみてください。
無料で使えるのは限定プレビューの今だけかも!?

Comments are closed.

Text widget

These widgets are displayed because you haven't added any widgets of your own yet. You can do so at Appearance> Widgets in the WordPress settings.

アーカイブ

© 2025 soy-software — Powered by WordPress

Theme by Anders NorenUp ↑

AltStyle によって変換されたページ (->オリジナル) /