導入
二値画像から「白いかたまり」の輪郭を取り出すのが 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 になります。