導入
スキャン画像は「白黒が反転している」「少し傾いている」ことがよくあります。OCR にかける前に、向きと明暗を整えておくと認識が安定します。
説明
from PIL import Image, ImageDraw, ImageFont, ImageOps
import numpy as np
import matplotlib.pyplot as plt
img = Image.new("L", (240, 90), "white") # グレースケールで作成
draw = ImageDraw.Draw(img)
draw.text((15, 20), "TILT", fill=0, font=ImageFont.load_default(size=48))
inverted = ImageOps.invert(img) # 白黒を反転(白↔黒)
rotated = img.rotate(-8, expand=True, fillcolor=255) # 8度回転(傾き補正のイメージ)
fig, ax = plt.subplots(1, 3, figsize=(10, 3))
ax[0].imshow(np.array(img), cmap="gray"); ax[0].set_title("original"); ax[0].axis("off")
ax[1].imshow(np.array(inverted), cmap="gray"); ax[1].set_title("inverted"); ax[1].axis("off")
ax[2].imshow(np.array(rotated), cmap="gray"); ax[2].set_title("rotated"); ax[2].axis("off")
ImageOps.invert(img)… 明暗を反転します(255 - 値)。黒地に白文字のスキャンを、黒文字に直すときに使います。img.rotate(角度, expand=True, fillcolor=255)… 画像を回します。expand=Trueで切れないように枠を広げ、fillcolor=255で余白を白で埋めます。プラスが反時計回りです。- 実務では、文字の並びから傾き角度を自動推定して
rotateで水平に直す「傾き補正(deskew)」を行います。
やってみよう
img.rotate(-8, ...) の角度を 10 や -20 に変えて、回転の向きと余白の埋まり方を確かめましょう。fillcolor を 0 にすると余白が黒になります。
演習
元画像 img を 90度回転 させて表示してください。
ヒント1を見る
out = img.rotate(90, expand=True, fillcolor=255) として plt.imshow(np.array(out), cmap="gray")。
ヒント2を見る
expand=True を付けないと、正方形でない画像は角が切れてしまいます。