번 글에서는 허프 변환을 이용하여 원 검출 하는 방법에 대해 알아보겠습니다.
우선 원 검출 방법에 대해 알아보겠습니다. 중심 좌표가 (a, b)이고 반지름이 r인 원의 방정식은 아래와 같습니다.
(x - a)^2 + (y = b)^2 = r^2
위 방정식에서 파라미터는 3개이므로, 3차원 파라미터 공간에서 축적 배열을 정의 후 누적이 많은 위치를 찾아야 합니다.
하지만 이 방식은 메모리와 시간을 많이 필요하므로 허프 그래디언트를 사용합니다.
허프 그래디언트는 아래 두 단계로 이루어져있습니다.
- 영상에서 모든 원의 중심 좌표 찾기
- 찾은 원의 중심에서 적합한 반지름 구하기
OpenCV에서는 HoughCircles() 함수를 사용하여 원 검출이 가능합니다.
함수에 대한 설명은 아래와 같습니다.
/**
@param image 입력 영상. 8-bit, 싱글채널 그레이스케일 영상
@param circles 출력 원 정보.(벡터)
@param method HOUGH_GRADIENT, HOUGH_GRADIENT_ALT만 사용 가능
@param dp 입력 영상과 축적 배열의 크기 비율
@param minDist 원 중심의 최소 거리
@param param1 캐니 에지 검출 임계값
@param param2 축적 배열에서 원 검출 임계값
@param minRadius 원 검출의 최소 반지름
@param maxRadius 원 검출의 최대 반지름
*/
void HoughCircles(InputArray image,
OutputArray circles,
int method,
double dp,
double minDist,
double param1 = 100,
double param2 = 100,
int minRadius = 0,
int maxRadius = 0 );
샘플 소스는 아래와 같습니다.
Mat src = imread("coins.png");
if (src.empty())
{
cerr << "image load fail" << endl;
return;
}
// 그래이스케일로 변환
Mat srcGray;
cvtColor(src, srcGray, COLOR_BGR2GRAY);
// 블러 처리
Mat blurred;
blur(srcGray, blurred, Size(3, 3));
vector<Vec3f> circles;
HoughCircles(blurred, circles, HOUGH_GRADIENT,
1/*축적배열 크기 비율*/,
50/*인접한 원 중심과의 최소 거리*/,
150/*Caany 에지 검출기 높은 임계값*/,
30/*축적 배열에서 원 검출을 위한 임계값*/);
Mat dst;
cvtColor(srcGray, dst, COLOR_GRAY2BGR);
for (Vec3f vec : circles)
{
cout << "Center(" << vec[0] << ", " << vec[1] << ") Radius(" << vec[2] << ")" << endl;
Point center(cvRound(vec[0]), cvRound(vec[1]));
int radius = vec[2];
circle(dst, center, radius, Scalar(0,0,255), 2, LINE_AA);
}
imshow("src", src);
imshow("dst", dst);
waitKey();
destroyAllWindows();
출력 결과는 아래와 같습니다.