はじめに
Python と OpenCV を使って、画像に写っている図形を自動で判別する方法を紹介します。この記事では、実際にコードを動かしながら形を判別する方法をまとめています!
必要なもの
- Python 3.x
- OpenCV
- NumPy
インストール
pip install opencv-python numpy
1. 解析用の画像を用意する
自分で用意するか、githubに載せてある画像をお使いください
https://github.com/takoyakidath/image-analysis.git
Step 2: 前処理(グレースケール・二値化)
画像を読み込み、輪郭抽出のために前処理を行います。
img = cv2.imread("shapes.png")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (5, 5), 0)
_, thresh = cv2.threshold(blur, 127, 255, cv2.THRESH_BINARY_INV)
Step 3: 輪郭抽出
OpenCV の findContours を使って輪郭を取得します。
contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
Step 4: 図形の種類を判別する
頂点数や円形度を使って図形の種類を判定します。
import numpy as np
import cv2
def classify_shape(contour):
peri = cv2.arcLength(contour, True)
approx = cv2.approxPolyDP(contour, 0.04 * peri, True)
vertices = len(approx)
area = cv2.contourArea(contour)
if peri == 0:
return "unknown"
circularity = 4 * np.pi * area / (peri ** 2)
if vertices == 3:
return "triangle"
elif vertices == 4:
x, y, w, h = cv2.boundingRect(approx)
aspect_ratio = w / float(h)
return "square" if 0.9 < aspect_ratio < 1.1 else "rectangle"
else:
return "circle" if circularity > 0.8 else "polygon"
Step 5: 結果を画像に描画する
output = img.copy()
for cnt in contours:
shape = classify_shape(cnt)
M = cv2.moments(cnt)
if M["m00"] != 0:
cX = int(M["m10"] / M["m00"])
cY = int(M["m01"] / M["m00"])
else:
cX, cY = 0, 0
cv2.drawContours(output, [cnt], -1, (0, 0, 255), 2)
cv2.putText(output, shape, (cX - 40, cY), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (255, 0, 0), 2)
6.出力
cv2.imwrite("output_shapes.png", output)
調整ポイント
- ぼかしのサイズ(例:
(5,5)→(3,3)) - 二値化しきい値
-
approxPolyDPの係数(0.04 → 適宜調整)
おわりに
OpenCV を使うことで、形状判定は意外とシンプルに実装できます。
円形度、輪郭近似などの基本を押さえておくと、より高度な画像処理・物体検出の基礎にも役立ちます。
今回のコードは全てgithubに載ってるのでみてみてください!