本文へスキップ
BecomeCoder

Python画像認識コース · 第3章 OCRのための前処理 · レッスン10

ノイズを消す ― ぼかしフィルタ

ブラウザで完結

導入

写真には細かなザラつき(ノイズ)が乗っています。そのまま二値化すると、ノイズが黒い点として残り、OCR が「ゴミ」を文字と誤認します。ノイズは軽くぼかすことで抑えられます。

説明

import numpy as np
import cv2
import matplotlib.pyplot as plt

# ノイズを載せたグレー画像を用意する
rng = np.random.default_rng(0)
base = np.full((120, 240), 200, dtype=np.uint8)      # 明るい灰色の背景
cv2.putText(base, "NOISE", (20, 80), cv2.FONT_HERSHEY_SIMPLEX, 2, 0, 5)
noise = rng.integers(-60, 60, base.shape)
noisy = np.clip(base.astype(int) + noise, 0, 255).astype(np.uint8)

# ぼかしでノイズを平滑化
blur = cv2.GaussianBlur(noisy, (5, 5), 0)   # ガウシアンぼかし
median = cv2.medianBlur(noisy, 5)           # メディアンフィルタ(粒ノイズに強い)

fig, ax = plt.subplots(1, 3, figsize=(10, 3))
ax[0].imshow(noisy, cmap="gray");  ax[0].set_title("noisy");    ax[0].axis("off")
ax[1].imshow(blur, cmap="gray");   ax[1].set_title("gaussian"); ax[1].axis("off")
ax[2].imshow(median, cmap="gray"); ax[2].set_title("median");   ax[2].axis("off")
  • cv2.putText … OpenCV でも文字を描けます(ここではノイズを載せる素材作り)。
  • cv2.GaussianBlur(画像, (5,5), 0) … 5×5 の範囲で周囲と平均を取り、なめらかにします。数字を大きくするほど強くぼけます。
  • cv2.medianBlur(画像, 5) … 範囲内の中央値を取るフィルタ。ぽつぽつした粒ノイズ(ごま塩ノイズ)に特に強いのが特徴です。

ぼかしは「ノイズを消す」一方で「文字も少しぼやける」トレードオフがあります。消しすぎないのがコツです。

やってみよう

cv2.GaussianBlur(noisy, (5, 5), 0)(5, 5)(11, 11) にすると、強くぼけてノイズは減りますが文字も甘くなります。ちょうど良い強さを探してみましょう(フィルタサイズは奇数にします)。

演習

ノイズ画像 noisycv2.medianBlurカーネルサイズ 3 でかけた結果を表示してください。

ヒント1を見る

out = cv2.medianBlur(noisy, 3) として plt.imshow(out, cmap="gray")

ヒント2を見る

サイズは奇数(3, 5, 7…)。小さいほど効果は弱く、文字は保たれます。

実際に動かしてみよう

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

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

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