The quick brown fox jumps over the lazy dog. 這句話涵蓋了 a 到 z ,共 26 個字母,這句話原本是用來檢測鍵盤有沒有故障。
光學字元辨識是透過影像處理,擷取並辨別影像上的文字,稍微介紹一下簡單作法的流程:
原始影像 | 二值化 | 濾雜訊 |
原始影像 | 前處理 | 文字切分 |
以上這些流程,除了後處理以外,其他都可以靠 Azure OCR 來幫忙搞定,下面開始利用 Azure 來處理 OCR。
Python
套件
azure-cognitiveservices-vision-computervision
Pillow
requests
from azure.cognitiveservices.vision.computervision \
import ComputerVisionClient
from msrest.authentication import (
CognitiveServicesCredentials
)
from azure.cognitiveservices.vision.computervision.models \
import OperationStatusCodes
from io import BytesIO
import requests
from PIL import Image, ImageDraw, ImageFont
# 利用金鑰SUBSCRIPTION_KEY和端點ENDPOINT,取得使用電腦視覺服務的權限。
SUBSCRIPTION_KEY = "YOUR SUBSCRIPTION_KEY"
ENDPOINT = "YOUR ENDPOINT"
CV_CLIENT = ComputerVisionClient(
ENDPOINT, CognitiveServicesCredentials(SUBSCRIPTION_KEY)
)
# 讀取 URL 得到圖片
url = "https://i.imgur.com/qyWiqQv.jpg"
response = requests.get(url)
img = Image.open(BytesIO(response.content))
draw = ImageDraw.Draw(img)
font_size = int(5e-2 * img.size[1])
fnt = ImageFont.truetype(
"../static/TaipeiSansTCBeta-Regular.ttf",
size=font_size)
# 開始利用 Azure 電腦視覺執行 OCR
ocr_results = CV_CLIENT.read(url, raw=True)
operation_location_remote = \
ocr_results.headers["Operation-Location"]
operation_id = operation_location_remote.split("/")[-1]
# 因為讀取文字有多有少,所以時間會不一,透過 operation_id 可以確認目前進度
status = ["notStarted", "running"]
while True:
get_handw_text_results = \
CV_CLIENT.get_read_result(operation_id)
if get_handw_text_results.status not in status:
break
time.sleep(1)
# 當執行狀態 status 為 succeeded ,就可以把結果標示在原本的照片上了
succeeded = OperationStatusCodes.succeeded
if get_handw_text_results.status == succeeded:
res = get_handw_text_results.analyze_result.read_results
for text_result in res:
for line in text_result.lines:
bounding_box = line.bounding_box
bounding_box += bounding_box[:2]
draw.line(
line.bounding_box,
fill=(255, 0, 0),
width=int(font_size / 10)
)
left = line.bounding_box[0]
top = line.bounding_box[1]
draw.text(
[left, top - font_size],
line.text,
fill=(0, 255, 255),
font=fnt,
)
# bounding_box是四邊形的頂點 [x1, y1, x2, y2, x3, y3, x4, y4],這邊的四邊形並非長方形,要使用 draw.line 畫出封閉四邊形。
# draw.line 需要知道起點位置,才能畫出封閉形狀。
img.save("output.png")
辨識完文字之後,看不懂的文字,還是看不懂,只好想辦法翻譯一下了。下一篇,使用 Azure 來翻譯。