タイトルのテキスト
タイトルのテキスト
タイトルのテキスト
タイトルのテキスト

PythonとOpenCVを用いた画像中の細長い物体検出と寸法推定の実装解説

Python

t f B! P L

 

タイトル画像

本記事では、PythonOpenCVを使って、画像内に存在する細長い物体を検出し、その厚さと長さを推定する方法について詳しく解説します。対象物体には一定の細長さ(長さと厚さに大きな比率)を持つことを前提とし、輪郭検出、最小外接矩形、そして画像上への可視化の処理までを一貫して実施します。

 実際に使用されたコードを読み解きながら、その意味と処理内容を段階的に解説します。

 〇必要なライブラリのインポート

import cv2

import matplotlib.pyplot as plt

このコードでは、画像処理のライブラリであるOpenCVcv2)と、可視化のためのmatplotlib.pyplotを使用しています。OpenCVは画像処理において非常に強力なツールセットであり、matplotlibPythonでのグラフ描画や画像表示に適しています。

 〇画像の読み込みと前処理

aimg = cv2.imread("/content/画像3.png")

img = cv2.cvtColor(aimg,cv2.COLOR_BGR2GRAY)

img = cv2.GaussianBlur(img,(5,5),0)

img = cv2.Canny(img,50,150)

cv2.imread: 対象の画像(ここでは「画像3.png」)をカラー画像として読み込みます。

 cv2.cvtColor: BGROpenCVのデフォルト)からグレースケールに変換。エッジ検出などの処理では色情報が不要なため、この変換を行います。

 cv2.GaussianBlur: 5×5のカーネルを使って画像をガウシアンブラーで平滑化します。これによりノイズが減り、次のエッジ検出が安定します。

 cv2.Canny: Cannyアルゴリズムを用いてエッジ検出を実行します。50を下限、150を上限とする2つのしきい値で、エッジを抽出します。

 〇輪郭検出

img,_ = cv2.findContours(img,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)

cv2.findContours: Cannyで得られたエッジ画像から輪郭(Contour)を検出します。

 cv2.RETR_EXTERNAL: 最外輪郭のみを抽出。

 cv2.CHAIN_APPROX_SIMPLE: 輪郭の点を簡略化して保存。

 imgにはすべての検出された輪郭情報が格納されます。

 寸法判定とフィルタリング

pp = 3

rr = []

qq = []

for ii in img:

  aa = cv2.minAreaRect(ii)

  (x,y),(w,h),ag = aa

  if max(w,h)/min(w,h) >1.5 :

    rr.append((int(x),int(y)))

    print(f"厚さ{round(min(w,h)/pp,2)}  長さ{round(max(w,h)/pp,2)}")

cv2.minAreaRect(ii): 各輪郭に最小外接矩形(最小面積で回転も許す長方形)をあてはめます。返り値は中心座標(x, y)、幅と高さ(w, h)、および回転角(ag)です。

 max(w,h)/min(w,h) > 1.5: 幅と高さの比が1.5を超えるもの=細長い物体を条件にフィルタリングします。

 pp = 3: 画像上のピクセル単位をmmに換算するスケール係数。例えば「3ピクセル = 1mm」という前提。

 print: 条件を満たした物体に対して、厚さと長さをmm単位で表示。

 これにより、画像中の細長い物体を自動的に選別し、その物理的なサイズを推定して出力できます。

 〇可視化:対象物に赤い枠を描画

for dd in rr:

    x, y = dd

    w, h = 60,20  # 四角の大きさ

    top_left = (x - w // 2, y - h // 2)

    bottom_right = (x + w // 2, y + h // 2)

     cv2.rectangle(aimg, top_left, bottom_right, (0, 0, 255), thickness=2)

このブロックでは、検出された細長い物体の中心座標(x, y)を基準に、60×20ピクセルの赤い長方形を描画しています。

 (0, 0, 255): BGR形式の赤色。

 thickness=2: 線の太さは2ピクセル。

 これは厳密な物体の輪郭とは異なりますが、視覚的にどこを検出したのかを確認する目的で、目立つ枠を描画しています。

 〇結果の表示

plt.imshow(cv2.cvtColor(aimg, cv2.COLOR_BGR2RGB))

plt.axis("off")

plt.show()

OpenCVの画像(BGR形式)をmatplotlibで正しく表示するために、cv2.COLOR_BGR2RGBで色空間を変換し、軸を非表示にして画像のみを表示しています。

 〇出力例と応用

このコードを実行すると、以下のような結果が得られます:

 コンソールには、各細長い物体の「厚さ」と「長さ」がmm単位で出力されます。

 画像上では、対象物の中心を赤い枠で強調表示し、検出結果を視覚的に確認可能です。

 この処理は、例えば次のような用途に応用できます:

 製造ラインでの部品寸法チェック

 図面やスキャン画像からの寸法抽出

 簡易的な非接触測定システムのプロトタイピング

 改良のアイデア

このコードはシンプルで効果的ですが、いくつかの改良も考えられます:

 スケールの自動取得

現在はpp = 3でスケーリングしていますが、画像内にスケールバーがある場合は自動的に測定することが理想です。

 正確な矩形描画

現在は単純な長方形を描いていますが、cv2.boxPoints()を使えば回転を考慮した矩形が描画できます。

 検出物体へのラベリング

cv2.putText()で物体のサイズを枠の横に描画することで、さらに直感的な表示が可能です。

 複数画像処理の自動化

フォルダ内の全画像にこの処理を適用することで、バッチ処理も実現可能です。

 〇まとめ

本記事では、OpenCVを使って画像内の細長い物体を検出し、寸法を推定・可視化するPythonスクリプトを詳しく解説しました。

 本コードのポイントは以下の通りです:

 前処理(グレースケール・ぼかし・エッジ検出)

 輪郭検出と最小外接矩形の利用

 アスペクト比による物体フィルタリング

 寸法換算と可視化による検出結果の明確化

 画像処理や機械視覚の基礎を学ぶ上でも非常に有用な実例となっています。今後の応用として、リアルタイム検出や機械学習との組み合わせも視野に入れると、さらに高度なシステム構築も可能となるでしょう。

koneka1208

koneka1208

自己紹介

自分の写真
エクセル好きの窓際会社員です。 エクセルの操作法や日々の会社で得た知見などを発信していきます。 よろしくお願いします。

ブログ アーカイブ

連絡フォーム

名前

メール *

メッセージ *

QooQ