opencv チュートリアル チャレンジ14 ハフ変換による円検出

ハフ変換による円検出 — OpenCV-Python Tutorials 1 documentation

void HoughCircles(Mat& image, vector<Vec3f>& circles, int method, double dp, double minDist, double param1=100, double param2=100, int minRadius=0, int maxRadius=0)
ハフ変換を用いて,グレースケール画像から円を検出します.

パラメタ:   
image – 8ビット,シングルチャンネル,グレースケールの入力画像.
circles – 検出された円を出力するベクトル.各ベクトルは,3要素の浮動小数点型ベクトル  (x, y, radius) としてエンコードされます.
method – 現在のところ, CV_HOUGH_GRADIENT メソッドのみが実装されています.基本的には 2段階ハフ変換 で,これについては Yuen90 で述べられています.
dp – 画像分解能に対する投票分解能の比率の逆数.例えば, dp=1 の場合は,投票空間は入力画像と同じ分解能をもちます.また dp=2 の場合は,投票空間の幅と高さは半分になります.
minDist – 検出される円の中心同士の最小距離.このパラメータが小さすぎると,正しい円の周辺に別の円が複数誤って検出されることになります.逆に大きすぎると,検出できない円がでてくる可能性があります.
param1 – 手法依存の 1 番目のパラメータ. CV_HOUGH_GRADIENT の場合は, Canny() エッジ検出器に渡される2つの閾値の内,大きい方の閾値を表します(小さい閾値は,この値の半分になります).
param2 – 手法依存の 2 番目のパラメータ. CV_HOUGH_GRADIENT の場合は,円の中心を検出する際の投票数の閾値を表します.これが小さくなるほど,より多くの誤検出が起こる可能性があります.より多くの投票を獲得した円が,最初に出力されます.
minRadius – 円の半径の最小値.
maxRadius – 円の半径の最大値.

やってみよう

#!/usr/bin/env python
# -*- coding: utf-8 -*
import sys
import cv2
import numpy as np
from matplotlib import pyplot as plt

cimg = cv2.imread('170523-170301.jpg')
img = cv2.cvtColor(cimg,cv2.COLOR_BGR2GRAY)
img = cv2.medianBlur(img,15)

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(cimg,(i[0],i[1]),i[2],(0,255,0),2)
    # draw the center of the circle
    cv2.circle(cimg,(i[0],i[1]),2,(0,0,255),3)

cv2.imshow('HoughCircles',cimg)
cv2.imwrite('HoughCircles.png',cimg)

cv2.waitKey(0)
cv2.destroyAllWindows()

これが f:id:pongsuke:20170523172643j:plain

こう f:id:pongsuke:20170523172652p:plain

なんだろうか、この検出結果は。

よくみると、複数の光源によって、ゴルフボールに複数の影ができていて、その影を検出しているようだ。

また、テカリ?も検出しているようにみえる。