本文へスキップ
BecomeCoder

Python画像認識コース · 第2章 画像をコードで扱う · レッスン7

カラーをグレースケールにする ― なぜOCRで白黒にするのか

ブラウザで完結

導入

OCR の前処理の第一歩は、たいてい グレースケール化(色を捨てて明るさだけにする)です。文字を読むのに色は不要で、むしろ計算量を1/3に減らし、後の二値化をやりやすくするからです。

説明

from PIL import Image, ImageDraw, ImageFont
import numpy as np
import matplotlib.pyplot as plt

# カラーの文字画像を用意
img = Image.new("RGB", (280, 100), "white")
draw = ImageDraw.Draw(img)
draw.text((15, 25), "Gray", fill=(0, 120, 220), font=ImageFont.load_default(size=52))

gray = img.convert("L")      # "L" = 明るさ(luminance)だけの1チャンネル画像
arr = np.array(gray)
print("カラーの形:", np.array(img).shape)   # (100, 280, 3)
print("グレーの形:", arr.shape)             # (100, 280) ← チャンネルが消えた

fig, ax = plt.subplots(1, 2, figsize=(8, 3))
ax[0].imshow(np.array(img));            ax[0].set_title("color");  ax[0].axis("off")
ax[1].imshow(arr, cmap="gray");         ax[1].set_title("gray");   ax[1].axis("off")
  • img.convert("L") … 画像をグレースケールに変換します。"L" は「明るさ」を意味するモードです。
  • グレー画像の配列(高さ, 幅) の2次元。チャンネルが1つになり、1ピクセル=1つの明るさ値(0〜255)になります。
  • plt.subplots(1, 2) で、カラーとグレーを左右に並べて比べています。

色の情報を捨てても、文字の形(明暗の差)は残ります。OCR にとって大事なのは「背景と文字の明るさの差」なので、これで十分なのです。

やってみよう

fill=(0, 120, 220)(青)を別の色に変えても、グレースケールにすると似た明るさになることを確かめましょう。色より「濃さ」が効いていると分かります。

演習

上のコードのグレー画像 arr について、一番暗いピクセルの値(最小値)を print してください。

ヒント1を見る

NumPy 配列の最小値は arr.min() で取れます。print("最小:", arr.min())

ヒント2を見る

文字(濃い青)の部分が暗いので、0 に近い値が返るはずです。

実際に動かしてみよう

下のエディタにPythonを書いて「実行」を押すと、本物の Pillow・OpenCV(Pyodide)で画像処理をその場で試せます。処理した画像は図として下に表示されます。初回や OpenCV を使う回は読み込みに時間がかかります(数十秒かかることがあります)。しきい値やフィルタの数値を書き換えて、画像の変化を確かめましょう(画像に描く文字は表示が崩れるため英字で書きます。Tesseract などOCRエンジン本体は第5章の読み物で解説します)。

Python — ライブラリ付きで実行(Pyodide)

numpy / pandas / matplotlib が使える本物のPython(Pyodide)を読み込みます。初回のみ読み込みに少し時間がかかります(以降はブラウザにキャッシュされます)。
スクロールして表示された時点でも自動で読み込まれます。