[Vision API] Javaで画像内のオブジェクトを検出する

Googleが提供しているVision APIをJavaで使ってみました。

APIを使用し、画像内に含まれているオブジェクトを検出します。
画像にどのようなものが写っているのかをAIで検出し、
画像内の位置とオブジェクト名前を返します。

本記事の[3.結果の検証](#3-結果の検証)でどのようなものが検出されるか試していますが、
大きめに映り込んでいるものしか検出されないようです。
ラベルを検出するの方がより細かい情報を取得できそうです。

:::note info
APIを利用する環境の準備から始める場合や、コードを実行する際は、
[⧉[Vision API] Javaで画像内のいろいろなものを検出する](https://qiita.com/doran/items/444cb6231b7dffb9ddac)
を参照ください。
:::

|No||目次|
|---|---|---|
|1||[Feature.Typeの指定](#1-featuretypeの指定)|
|2||[実行結果の取得](#2-実行結果の取得)|
||1|[レスポンスの出力](#21-レスポンスの出力)|
||2|[レスポンスの内容](#22-レスポンスの内容)|
|3||[結果の検証](#3-結果の検証)|
||1|[駐車場](#31-駐車場)|
||2|[ボーリング中](#32-ボーリング中)|
||3|[人物](#33-人物)|
||4|[街](#34-街)|
||5|[野菜](#35-野菜)|
||6|[猫](#36-猫)|
||7|[風景](#37-風景)|
||8|[デスク](#38-デスク)|

# 1. Feature.Typeの指定
オブジェクトを検出する場合は、
**Feature.Type.OBJECT_LOCALIZATION**
を指定します。

以下の記事でexecApi()にタイプを指定します。
[⧉[Vision API] Javaで画像内のいろいろなものを検出する](https://qiita.com/doran/items/444cb6231b7dffb9ddac#25-apiを呼び出す)

# 2. 実行結果の取得
### 2.1. レスポンスの出力
取得した結果をコンソールに出力します。
```
private static void output(BatchAnnotateImagesResponse response){
    List<AnnotateImageResponse> responses = response.getResponsesList();
    
    for (AnnotateImageResponse res : responses) {
        for (LocalizedObjectAnnotation entity : res.getLocalizedObjectAnnotationsList()) {
            System.out.format("Object name: %s%n", entity.getName());
            System.out.format("Confidence: %s%n", entity.getScore());
            System.out.format("Normalized Vertices:%n");
            entity.getBoundingPoly()
                .getNormalizedVerticesList()
                .forEach(vertex -> System.out.format("- (%s, %s)%n", vertex.getX(), vertex.getY()));
        }
    }
}
```
### 2.2. レスポンスの内容
BatchAnnotateImagesResponseの
getResponsesListでAnnotateImageResponseリストが取得できます。
検出されなった場合は、空のリストが返ってきます。
#### AnnotateImageResponse
|メソッド|戻り値|内容|
|---|---|---|
|getLocalizedObjectAnnotationsList|List\<[LocalizedObjectAnnotation](#localizedobjectannotation)\>|検出されたラベル|
#### LocalizedObjectAnnotation
|メソッド|戻り値|内容|
|---|---|---|
|getMid|string|OpaqueエンティティID|
|getName|string|検出されたオブジェクトの名前|
|getScore|float|検出結果の信頼度。範囲は0〜1|
|getBoundingPoly|[BoundingPoly](#boundingpoly)|オブジェクトが属する画像領域|
#### BoundingPoly
正規化された頂点座標は元のイメージを基準としています。
座標を取得したい場合は、
X座標 = 画像の高さ x getX
Y座標 = 画像の幅() x getY()
で取得します。
|メソッド|戻り値|内容|
|---|---|---|
|getNormalizedVerticesList|List\<[NormalizedVertex](#normalizedvertex)\>|正規化された頂点。<br>左上、右上、左下、右下の順|
#### NormalizedVertex
|メソッド|戻り値|内容|
|---|---|---|
|getX|float|X座標|
|getY|float|Y座標|

## 3. 結果の検証
いろいろな画像でオブジェクトを検出してみました。
### 3.1. 駐車場
**検出させる元画像**
<img width="480" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/0264fdc6-b4a0-da82-400a-5d1491626ab5.jpeg">

**実行結果**
大きめに写っている車のみ検出されていますね。
人もいるのですが検出されていません。小さすぎたのでしょうか。
<img width="480" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/867461f7-8a83-71ab-bcf4-78f8604a682a.jpeg">

### 3.2. ボーリング中
**検出させる元画像**
<img width="480" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/9968a8cf-2ad7-d8c2-e184-47d252f558bd.jpeg">

**実行結果**
屈んでいる女性がパンツと判定されている。
<img width="480" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/d9318c36-fc16-38c2-0db2-e1b811573441.jpeg">

### 3.3. 人物
**検出させる元画像**
<img width="480" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/1ff8b1fe-0e61-566e-0033-e969becae158.jpeg">

**実行結果**
持っているのは鏡だと思いますが、帽子と判定されていますね。
<img width="480" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/280f95b0-7932-8eef-fecb-c3d896258c0b.jpeg">

### 3.4. 街
**検出させる元画像**
<img width="480" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/64e4322d-7ebb-b6a8-af42-fc7509af992e.jpeg">

**実行結果**
大きめに写っているビルが検出されています。
<img width="480" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/9c59bfef-86ce-beaf-19fc-4ae713434dd2.jpeg">

### 3.5. 野菜
**検出させる元画像**
<img width="480" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/93152065-0186-b69d-90b1-95308f1c3878.jpeg">

**実行結果**
全部の野菜は認識されないようです。
<img width="480" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/dd60f09b-83fc-2e7b-a1a6-e07e1c554d06.jpeg">

### 3.6. 猫
**検出させる元画像**
<img width="480" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/0f57a993-09b5-121e-91dd-4819a6f9c7e8.jpeg">

**実行結果**
一匹だけ猫と判定されなかった子がいる。
動物と判定されているので間違いではないですが。
<img width="480" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/a563bbf9-af16-a03d-76dc-6632c844b2ce.jpeg">

### 3.7. 風景
**検出させる元画像**
<img width="480" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/2af9a89e-c2e9-fb0a-6e37-d0e8f0285390.jpeg">

**実行結果**
遠くのビル群は、まとめてビルと判定されていますね。
<img width="480" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/45a22a0d-9bf6-0a08-d35a-1681fa318aad.jpeg">

### 3.8.　デスク
**検出させる元画像**
<img width="480" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/f5a89469-96e1-31b5-4532-222a42a6b346.jpeg">

**実行結果**
眼鏡(Glasses)の判定は正しいですが、サングラスには見えないですね。
<img width="480" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/a963b59e-4efa-3862-b751-d6b94bf8043c.jpeg">


<BR>
<BR>
おしまい。。。