つれづれなる備忘録

日々の発見をあるがままに綴る

OpenCVの使い方38 ~ 円検出

今回はOpenCVを用いた円検出について紹介する。

1. ハフ変換による円検出

 直線と同様に画像中の円を検出するためにハフ変換を用いて円検出する関数が実装されている。

以下のチュートリアルと同じOpenCVのロゴを使って円検出を実行する。

labs.eecs.tottori-u.ac.jp

"OpenCVのロゴ"
OpenCVのロゴ

以下はgoogle colabで画像を読み込む場合のコードを示す。

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

from google.colab import files
uploaded_file = files.upload()
uploaded_file_name = next(iter(uploaded_file))
print(uploaded_file_name)

orig = cv2.imread(uploaded_file_name)
src = cv2.cvtColor(orig, cv2.COLOR_BGR2RGB)
gray = cv2.cvtColor(orig, cv2.COLOR_BGR2GRAY)
plt.imshow(gray,cmap='gray')
plt.title('Original')
circles = cv2.HoughCircles(img,cv2.HOUGH_GRADIENT,1,20,
                            param1=50,param2=30,minRadius=0,maxRadius=0)
circles = np.uint16(np.around(circles))
for i in circles[0,:]:
    # draw the outer circle
    cv2.circle(src,(i[0],i[1]),i[2],(0,255,0),2)
    # draw the center of the circle
    cv2.circle(src,(i[0],i[1]),2,(0,0,255),3)
plt.figure(figsize=(3,3))
plt.imshow(src)

チュートリアルの通り、ロゴ中の円の要素を検出できていることがわかる。

"OpenCVロゴの円検出"
OpenCVロゴの円検出

2. 一般的な画像の円検出

 ロゴよりも複雑な一般的な画像でハフ変換による円検出を試してみる。例えば、以下の地球の画像をテスト画像とする。

"地球"
地球

チュートリアルと同じ設定で円を検出してみる。

circles = cv2.HoughCircles(img,cv2.HOUGH_GRADIENT,1,20,
                            param1=50,param2=30,minRadius=0,maxRadius=0)

以下のように無数に円が検出される。

地球の円検出

cv2.HoughCirclesの4番目の引数は、検出する円同士の最低距離であり、小さいと同じ円が重複して検出される。また、param1はエッジ検出の閾値、param2は円中心の検出の閾値であり、これらの閾値を大きくすることで、円の検出感度を下げる。

circles = cv2.HoughCircles(gray,cv2.HOUGH_GRADIENT,1,200,
                            param1=80,param2=100,minRadius=0,maxRadius=0)

地球の輪郭を含む数個の円まで検出される円を減らすことができた。人の目では地球の輪郭ぐらいしかわからないが、雲のつながり方で円として検出されているように思える。

"地球の円検出2"
地球の円検出2

3. まとめ

 今回はハフ変換を用いた円の検出と、円の検出感度の調整方法について紹介した。