【初心者】Azure Cognitive Services - Computer Vision を一通り使ってみる

# 1. 目的
- Azure Cognitive Services の勉強をしている。Cognitive Servicesのジャンルの1つである Computer Vision だけでもかなりたくさんの機能があるため、一通り実行してどんなものかをざっくり理解する。

# 2. Azure Cognitive Services - Computer Vision とは
- 画像や動画に対して、物体の検出などの処理を行うことができるサービス。

# 3. やったこと

|ジャンル  |概要  | 実施 |
|---|---|---|
|画像分析  |画像内に何が含まれるのか、などを認識  |チュートリアル(クイックスタート)に載っている機能を一通り実施
|光学式文字認識(OCR)  |画像内の文字を認識  |チュートリアル(クイックスタート)に従い、英語の手書き文字の認識を実施
|空間分析  |動画の分析(人物検出など)  |プレビューのため今回は未実施

# 4. 作業内容

## 4.1 事前準備
- Azure サブスクリプションの作成
- Computer Vision サービスの作成(エンドポイントとキーが必要)
- 作業用のAWS EC2インスタンスの作成(Python3のインストール、ライブラリ追加など)

## 4.2 画像分析

- MS社公式ドキュメント「[クイックスタート: 画像分析のクライアント ライブラリまたは REST API を使用する](https://docs.microsoft.com/ja-jp/azure/cognitive-services/computer-vision/quickstarts-sdk/image-analysis-client-library?tabs=visual-studio&pivots=programming-language-python)」に従って動作確認する。
- 基本的に上記サイトのPythonコードを完全にコピペして実行するため、本記事でのコードの記載は省略する。なおPythonコード内で以下2点のみ個別設定する。
    - subscription_key、endpoint について自分のものを設定する。
    - remote_image_url_objects (処理したい画像のURL)について、分析対象の画像のURLを設定する。
    
- 以下の3つの画像(MS社によりチュートリアル用に一般公開されている画像)に対し、Computer Vision による分析処理を実行し、結果を確認する。
    - 画像1: [コロッセウム](https://raw.githubusercontent.com/Azure-Samples/cognitive-services-sample-data-files/master/ComputerVision/Images/landmark.jpg)
    - 画像2: [MSロゴ入りTシャツ](https://docs.microsoft.com/en-us/azure/cognitive-services/computer-vision/images/gray-shirt-logo.jpg)
    - 画像3: [6人の顔](https://raw.githubusercontent.com/Azure-Samples/cognitive-services-sample-data-files/master/ComputerVision/Images/faces.jpg)

|画像1|画像2|画像3
|---|---|---|
|![1](https://raw.githubusercontent.com/Azure-Samples/cognitive-services-sample-data-files/master/ComputerVision/Images/landmark.jpg)|![2](https://docs.microsoft.com/en-us/azure/cognitive-services/computer-vision/images/gray-shirt-logo.jpg)|![3](https://raw.githubusercontent.com/Azure-Samples/cognitive-services-sample-data-files/master/ComputerVision/Images/faces.jpg)


- 使いたい機能と、対象の画像のURLを指定して分析を実行する。以下がその実行結果となる。

|機能  |内容  |分析対象画像  |結果 |
|---|---|---|---|
|画像の説明の取得  |どういう画像かを文章で説明  |画像1  | 'an ancient city with many ruins with Colosseum in the background' with confidence 33.80% |
|画像カテゴリの取得  |画像のカテゴリを列挙  |画像1  |'building_' with confidence 31.64% <br> 'others_' with confidence 0.39% <br> 'outdoor_' with confidence 3.91% |
|画像タグの取得|画像のタグ(画像に含まれる要素)を列挙|画像1|'outdoor' with confidence 99.00% <br> 'building' with confidence 98.81% <br> 'sky' with confidence 98.21% <br> 'stadium' with confidence 98.17% <br> 'ancient rome' with confidence 96.16% <br> 以下省略
|物体を検出する|画像に含まれる物体を列挙(座標の提示)|画像1|Detecting objects in remote image: <br> object at location 213, 365, 85, 208 <br> object at location 218, 402, 179, 384 <br> object at location 238, 417, 298, 416 <br> object at location 116, 419, 60, 386|
|ブランドを検出する|ブランド名と座標の提示|画像2|'Microsoft' brand detected with confidence 62.5% at location 58, 113, 106, 152 <br> 'Microsoft' brand detected with confidence 69.8% at location 58, 260, 86, 149 |
|顔を検出する|画像に含まれる顔を列挙(座標の表示)|画像3|Faces in the remote image: <br> 'Male' of age 39 at location 118, 159, 212, 253 <br> 'Male' of age 54 at location 492, 111, 582, 201 <br> 'Female' of age 55 at location 18, 153, 102, 237 <br> 'Female' of age 33 at location 386, 166, 467, 247 <br> 'Female' of age 18 at location 235, 158, 311, 234 <br> 'Female' of age 8 at location 323, 163, 391, 231 <br> |
|成人向け、わいせつ、または不快なコンテンツを検出する|成人向け/わいせつ(ヌードなど)、不快(血など)の提示|画像3|Is adult content: False with confidence 0.14 <br> Has racy content: False with confidence 0.30　|
|画像の配色の取得|画像の配色(白黒orカラー)、支配的な色は何かなどの提示|画像1 | Getting color scheme of the remote image:<br> Is black and white: False <br> Accent color: 486A83 <br> Dominant background color: White <br> Dominant foreground color: Grey <br> Dominant colors: ['Grey', 'White'] |

- 「顔を検出する」の機能では、検出された顔の男女の区別、年齢、及び座標が表示される。得られた座標を元にベタ打ちで四角形を描画したら、きちんと検出されていた。

![3-faces-edited.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/9b6df7c7-1334-db49-0860-c9beea840660.jpeg)

- 画像に対して、座標を指定して四角形を書くスクリプトは以下の通り。

``` mypillow.py
from PIL import Image, ImageDraw

im = Image.open('3-faces.jpg')
draw = ImageDraw.Draw(im)

draw.rectangle([(118, 159), (212, 253)], outline='lime', width=2)
draw.rectangle([(492, 111), (582, 201)], outline='lime', width=2)
draw.rectangle([(18, 153), (102, 237 )], outline='lime', width=2)
draw.rectangle([(386, 166), (467, 247)], outline='lime', width=2)
draw.rectangle([(235, 158), (311, 234)], outline='lime', width=2)
draw.rectangle([(323, 163), (391, 231)], outline='lime', width=2)
im.save('3-faces-edited.jpg', quality=95)
```


- 「成人向け、わいせつ、または不快なコンテンツを検出する」の機能では、それっぽい画像を指定すると 0.99 のようにきちんと検出された。

## 4.3 光学式文字認識(OCR) 

- MS社公式ドキュメント「[クイックスタート: Read クライアント ライブラリまたは REST API を使用する](https://docs.microsoft.com/ja-jp/azure/cognitive-services/computer-vision/quickstarts-sdk/client-library?tabs=visual-studio&pivots=programming-language-python)」に従って動作確認する。
- 基本的に上記サイトのPythonコードを完全にコピペして実行するため、本記事でのコードの記載は省略する。なおPythonコード内で以下2点のみ個別設定する。
    - subscription_key、endpoint について自分のものを設定する。
    - remote_image_url_objects (処理したい画像のURL)について、分析対象の画像のURLを設定する。

- 以下の画像(MS社によりチュートリアル用に一般公開されている画像)に対し、READ API(文字認識用のAPI)を用いた文字認識処理を実行する。
![手書き.jpg](https://raw.githubusercontent.com/MicrosoftDocs/azure-docs/master/articles/cognitive-services/Computer-vision/Images/readsample.jpg)

- Pythonのサンプルコードの実行結果は以下になった。認識した文字列と位置(上下左右の4点)が出力される。

```
[ec2-user@ip-10-0-1-153 ~]$ python3 ocr.py
===== Read File - remote =====
The quick brown fox jumps
[38.0, 650.0, 2572.0, 699.0, 2570.0, 854.0, 37.0, 815.0]
Over
[184.0, 1053.0, 508.0, 1044.0, 510.0, 1123.0, 184.0, 1128.0]
the lazy dog!
[639.0, 1011.0, 1976.0, 1026.0, 1974.0, 1158.0, 637.0, 1141.0]
```

- 座標をベタ打ちで描画したところ、位置も正しく認識されていた。

![readsample-edited.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/a2a0625f-aa5c-ab7b-53d2-a6be7f432dd1.jpeg)

- 画像に対して、座標を指定して四角形を書くスクリプトは以下の通り。（先の顔検出と異なり、今回は正方形/長方形ではないためpolygonを使用）

``` mypillow2.py
from PIL import Image, ImageDraw

im = Image.open('readsample.jpg')
draw = ImageDraw.Draw(im)

draw.polygon(((38, 650), (2572, 699), (2570,854), (37,815)), outline='lime')
draw.polygon(((184, 1053), (508, 1044), (510, 1123), (184, 1128)), outline='lime')
draw.polygon(((639, 1011), (1976, 1026), (1974, 1158), (637, 1141)), outline='lime')
im.save('readsample-edited.jpg', quality=95)
```


# 5.所感
- とりあえず超基本が分かったので、そのうち「空間分析」にもチャレンジしたい。


# 6.参考URL
- [Pythonの画像処理ライブラリPillow(PIL)の使い方](https://note.nkmk.me/python-pillow-basic/)