本文へスキップ
BecomeCoder

Python画像認識コース · 第4章 特徴と領域の検出 · レッスン15

輪郭を見つける ― findContours

ブラウザで完結

導入

二値画像から「白いかたまり」の輪郭を取り出すのが findContours です。文字1つ1つや、文字ブロックを「領域」として捉える第一歩になります。

説明

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

# 文字が白い二値画像を作る
base = np.full((120, 300), 255, dtype=np.uint8)
cv2.putText(base, "A B C", (20, 85), cv2.FONT_HERSHEY_SIMPLEX, 2.2, 0, 4)
_, binary = cv2.threshold(base, 128, 255, cv2.THRESH_BINARY_INV)

# 輪郭を検出
contours, _ = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
print("見つかった輪郭の数:", len(contours))

# 輪郭を緑で描いて可視化
canvas = cv2.cvtColor(base, cv2.COLOR_GRAY2RGB)
cv2.drawContours(canvas, contours, -1, (0, 180, 0), 2)

plt.imshow(canvas)
plt.title("contours")
plt.axis("off")
  • cv2.findContours(二値画像, 取得モード, 近似方法) … 白い領域の輪郭を返します。戻り値は (輪郭のリスト, 階層情報)
  • cv2.RETR_EXTERNAL … 一番外側の輪郭だけを取ります(文字の内側の穴は無視)。
  • cv2.drawContours(描画先, 輪郭, -1, 色, 太さ) … 見つけた輪郭を描きます。-1 は「すべての輪郭」の意味。
  • 「A B C」の3文字なら、輪郭の数は概ね3つになります(文字がつながっていなければ)。

やってみよう

cv2.putText の文字を "1 2 3 4" に変えると、輪郭の数も増えます。二値化とモルフォロジー(前レッスン)で文字がくっつくと、数が減ることも確かめてみましょう。

演習

上のコードで、"A B C""X Y" に変えて、見つかる輪郭の数print で確認してください。

ヒント1を見る

cv2.putText(..., "X Y", ...) に変え、print("輪郭数:", len(contours)) を実行します。

ヒント2を見る

離れた2文字なら概ね 2 になります。

実際に動かしてみよう

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

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

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