OpenCV|Huff変換器の検出


円心座標は(a,b)、半径rの方程式は以下の通りである.
(x - a)^2 + (y - b)^2 = r^2
円の方程式には3つのパラメータがあり、Huff変換を適用するには、3 Dパラメータ空間で蓄積アレイを定義し、蓄積量が最大の位置を見つける必要があります.しかし,これは複雑すぎるので,従来のhuffs変換ではなくhuffgradient法を用いて円を検出した.
huffgradient法は2つの段階から構成される.第1の再試行フェーズは、画像内のすべての円の中心座標を検索し、第2の再試行フェーズは、検出された円の中心から円に適した半径を求める.円心座標を探す過程で,蓄積配列を用いた.この蓄積アレイでは、入力画像と同じxy座標空間に2次元アレイを形成し、入力六角のすべてのエッジ画素からグラデーションを求め、グラデーション方向の直線上の蓄積アレイ値を1増加させる.

上図はhuffgradient法を用いて円心を検出する過程である.
OpenCVはHoughCircles()関数を使用して円を検出できます.

HoughCircles()

void HoughCircles(InputArray image, OutputArray circles,
int method, double dp, double minDist, 
double param1 = 100, double param2 = 100,
int minRadius = 100, int maxRadius = 0);
画像:入力画像(グレースケール画像)ニュウリョク画像
circle:検出された円情報を格納する出力ベクトル
メソッド:Hough GRADIENTのみを指定できます
dp:入力画像と蓄積アレイの割合
minDist:隣接する円心の最小距離
param 1:Cannyエッジ検出器の高閾値
param 2:蓄積アレイ内の円を検出するためのしきい値
minRadius:検出する円の最小半径
maxRadius:検出された円の最大半径
void hough_circles()
{
    Mat src = imread("coins.png", IMREAD_GRAYSCALE);
     if (src.empty()) {
         cerr << "Image load failed!" << endl;
         return;
    }

    Mat blurred;
    blur(src, blurred, Size(3, 3));
    vector<Vec3f> circles;
    HoughCircles(blurred, circles, HOUGH_GRADIENT, 1, 50, 150, 30);
    Mat dst;
    cvtColor(src, dst, COLOR_GRAY2BGR);
    for (Vec3f c : circles) {
        Point center(cvRound(c[0]), cvRound(c[1]));
        int radius = cvRound(c[2]);
        circle(dst, center, radius, Scalar(0, 0, 255), 2, LINE_AA);
    }
    
    imshow("src", src);
    imshow("dst", dst);
    
    waitKey(0);
    destroyAllWindows();  
}