AzureでOCRができる?Azure Computer Visonでテキスト抽出をやってみた!

はじめに

この記事では Azure の機械学習サービス【Azure Computer Vision】 を使って画像からテキストを抽出を試していきます。

Azure Computer Vison ではテキスト抽出の自動化・リアルタイムのビデオ分析などが行えます。機械学習に関する専門知識は不要です。

詳細なサービス内容については以下をご参照ください

Computer Vision APIを解説 【シリーズ Azureサービスいちから紹介】

本記事の概要

  • 前提として Azure のアカウント登録はしている状態から始めます。
  • 手書きの文字を取った画像を Azure Computer Vison でテキスト抽出するまでを解説します。言語は Python を使用しています。
  • Azure Computer Vison を試してみたい・導入を検討している方に向けて執筆しています。

開発環境

Windows 10

Anaconda

Python 3.6

OpenCV 4.4.0

Azure Computer Vision API

Computer Vision クライアント ライブラリ(必要なら)

導入

1.Azure ポータルにログインします

2.Computer Vision API のリソースを作成します

https___qiita-image-store.s3.ap-northeast-1.amazonaws.com_0_63863_db52fef2-972e-fe1b-d430-d2914d5cdc75.png

3.キーとエンドポイントをメモします

https___qiita-image-store.s3.ap-northeast-1.amazonaws.com_0_63863_f5c0b265-c718-98d6-893a-e11adabf078d.png
4.必要なライブラリをインストールしてください。
pip install matplotlib
pip install pillow
pip install opencv-python
pip install --upgrade azure-cognitiveservices-vision-computervision

5.メモしたキーとエンドポイントを入力し、次のコードを実行してみましょう!

subscription_key = "<your subscription key>"
endpoint = "<your API endpoint>"

エンドポイントはリージョン(場所)指定でも動くようです。

endpoint = "https://<your region>.api.cognitive.microsoft.com/"

画像 URL からテキスト抽出する

クイック スタート: Computer Vision の REST API と Python を使用して印刷されたテキストと手書きテキストを抽出する

import json
import os
import os.path
import sys
import requests
import time
import matplotlib.pyplot as plt
from matplotlib.patches import Polygon
from PIL import Image
from io import BytesIO
# import cv2

subscription_key = ""
endpoint = ""
# endpoint = "https://japanwest.api.cognitive.microsoft.com/"
text_recognition_url = endpoint + "vision/v3.1/read/analyze"

image_url = "https://raw.githubusercontent.com/MicrosoftDocs/azure-docs/master/articles/cognitive-services/Computer-vision/Images/readsample.jpg"
headers = {'Ocp-Apim-Subscription-Key': subscription_key}
data = {'url': image_url}
response = requests.post(text_recognition_url, headers=headers, json=data)
response.raise_for_status()

operation_url = response.headers["Operation-Location"]
analysis = {}
poll = True
while (poll):
    response_final = requests.get(response.headers["Operation-Location"], headers=headers)
    analysis = response_final.json()

    print(json.dumps(analysis, indent=4))

    time.sleep(1)
    if ("analyzeResult" in analysis):
        poll = False
    if ("status" in analysis and analysis['status'] == 'failed'):
        poll = False

polygons = []
if ("analyzeResult" in analysis):
    polygons = [(line["boundingBox"], line["text"])
                for line in analysis["analyzeResult"]["readResults"][0]["lines"]]

image = Image.open(BytesIO(requests.get(image_url).content))
ax = plt.imshow(image)
for polygon in polygons:
    vertices = [(polygon[0][i], polygon[0][i+1])
                for i in range(0, len(polygon[0]), 2)]
    text = polygon[1]
    patch = Polygon(vertices, closed=True, fill=False, linewidth=2, color='y')
    ax.axes.add_patch(patch)
    plt.text(vertices[0][0], vertices[0][1], text, fontsize=20, va="top")
plt.show()
input output
https___raw.githubusercontent.com_MicrosoftDocs_azure-docs_master_articles_cognitive-services_Computer-vision_Images_readsample.jpg https___qiita-image-store.s3.ap-northeast-1.amazonaws.com_0_63863_e3e84db0-bca3-d504-4974-bfa1da58cd75.png

ローカル画像からテキスト抽出する

import json
import os
import os.path
import sys
import requests
import time
import matplotlib.pyplot as plt
from matplotlib.patches import Polygon
from PIL import Image
from io import BytesIO
import cv2

subscription_key = ""
endpoint = ""
# endpoint = "https://japanwest.api.cognitive.microsoft.com/"
text_recognition_url = endpoint + "vision/v3.1/read/analyze"

headers = {'Ocp-Apim-Subscription-Key': subscription_key, 'Content-Type': 'application/octet-stream'}
filename = "readsample.jpg"
root, ext = os.path.splitext(filename)
# image_data = open(filename, "rb").read()
color = cv2.imread(filename, cv2.IMREAD_COLOR)
cv2.namedWindow("color", cv2.WINDOW_NORMAL)
cv2.imshow("color", color)
cv2.waitKey(1)
image_data = cv2.imencode(ext, color)[1].tostring()
response = requests.post(text_recognition_url, headers=headers, data=image_data)
response.raise_for_status()

operation_url = response.headers["Operation-Location"]
analysis = {}
poll = True
while (poll):
    response_final = requests.get(
        response.headers["Operation-Location"], headers=headers)
    analysis = response_final.json()

    print(json.dumps(analysis, indent=4))

    time.sleep(1)
    if ("analyzeResult" in analysis):
        poll = False
    if ("status" in analysis and analysis['status'] == 'failed'):
        poll = False

polygons = []
if ("analyzeResult" in analysis):
    polygons = [(line["boundingBox"], line["text"])
                for line in analysis["analyzeResult"]["readResults"][0]["lines"]]

# image = Image.open(BytesIO(image_data))
image = Image.fromarray(color)
ax = plt.imshow(image)
for polygon in polygons:
    vertices = [(polygon[0][i], polygon[0][i+1])
                for i in range(0, len(polygon[0]), 2)]
    text = polygon[1]
    patch = Polygon(vertices, closed=True, fill=False, linewidth=2, color='y')
    ax.axes.add_patch(patch)
    plt.text(vertices[0][0], vertices[0][1], text, fontsize=20, va="top")
plt.show()
input  output
https___raw.githubusercontent.com_MicrosoftDocs_azure-docs_master_articles_cognitive-services_Computer-vision_Images_readsample (1).jpg https___qiita-image-store.s3.ap-northeast-1.amazonaws.com_0_63863_ff1597be-1b59-b5ab-28c9-dd64fbb08d33.png

Computer Vision クライアント ライブラリを使用する

クイック スタート: Computer Vision クライアント ライブラリを使用する

from azure.cognitiveservices.vision.computervision import ComputerVisionClient
from azure.cognitiveservices.vision.computervision.models import OperationStatusCodes
from azure.cognitiveservices.vision.computervision.models import VisualFeatureTypes
from msrest.authentication import CognitiveServicesCredentials

from array import array
import os
from PIL import Image
import sys
import time
import cv2 
from io import BytesIO

subscription_key = ""
endpoint = ""
# endpoint = "https://japanwest.api.cognitive.microsoft.com/"

computervision_client = ComputerVisionClient(endpoint, CognitiveServicesCredentials(subscription_key))

print("===== Batch Read File - remote =====")
remote_image_handw_text_url = "https://raw.githubusercontent.com/MicrosoftDocs/azure-docs/master/articles/cognitive-services/Computer-vision/Images/readsample.jpg"

recognize_handw_results = computervision_client.read(remote_image_handw_text_url, raw=True)
operation_location_remote = recognize_handw_results.headers["Operation-Location"]
operation_id = operation_location_remote.split("/")[-1]

while True:
    get_handw_text_results = computervision_client.get_read_result(operation_id)
    if get_handw_text_results.status not in ['notStarted', 'running']:
        break
    time.sleep(1)

if get_handw_text_results.status == OperationStatusCodes.succeeded:
    for text_result in get_handw_text_results.analyze_result.read_results:
        for line in text_result.lines:
            print(line.text)
            print(line.bounding_box)
print()
===== Batch 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]

お疲れ様でした。

最後に

Azure Computer Vison で テキスト抽出を行うところまでを解説していきました。

手書きの文字が認識できると手書き帳簿の読み取りを Azure Computer Vison を使って可能になるかもしれないですね。

今回は英語での検証でしたが、パブリックプレビュー版で日本語対応機能が追加されているのでそちらも検証していきたいと思います。

この記事を書いた人

azure-recipe-user