Table of Contents
허프변환
허프변환
Hough Circle Transform
원을 다음 식으로 나타낼 수 있다.
\((x - cx)^2 + (y - cy)^2 = r^2\)
- (cx, cy): 원의 중심 좌표
- r: 원의 반지름
- 원을 나타내는 식에 3개의 파라미터가 있기 때문에
hough transfor
m를 사용하려면 3차원 배열이 필요 -> 비효율적
[solve] 에지의 그레디언트 정보를 사용하는Hough Gradient Method
를 사용
OpenCV에서는 원 검출을 위해HoughCircles ()
함수를 제공 - 내부에 에지 검출 알고리즘이 포함
- 캐니 에지 등을 사용하여 에지를 검출한 결과를 입력으로 사용할 필요 없음
함수 원본
HoughCircles ( InputArray image, OutputArray circles, int method, double dp, double minDist, double param1 = 100, double param2 = 100, int minRadius = 0, int maxRadius = 0 )
Python:
circles =cv.HoughCircles( image, method, dp, minDist[, circles[, param1[, param2[, minRadius[, maxRadius]]]]] )
- Image: 입력 이미지는 그레이 스케일 이미지여야 함
- Method: 원을 검출하는 방법, HOUGH_GRADIENT만 사용 가능
- dp
- 이미지 해상도에 대한 accumulator 해상도의 비율의 역수
- ex) dp=1 이면 배열 accumulator는 입력 이미지와 같은 해상도를 가짐.
- dp=2이면 배열 accumulator는 절반의 너비와 높이를 가짐
- minDist: 검출된 원 사이의 최소 거리입니다. 이 값이 너무 크면 검출되지 못한 원들이 생기며, 너무 작으면 인접한 원들이 잘못 검출될 수 있음
- Circles: 발견한 원에 대한 벡터입니다. 각 벡터는 3개 (x,y,radius) 또는 4개 (x,y,radius,votes)의 원소를 가짐
- param1: 지정한 원 검출 방법을 위한 파라미터. HOUGH_GRADIENT의 경우 캐니 에지 디텍터의 높은 스레솔드 값입니다. 낮은 스레솔드 값은 0.5배해서 사용하게 됨
- param2: 지정한 원 검출 방법을 위한 파라미터. HOUGH_GRADIENT의 경우 accumulator 스레솔드 값. 이 값이 너무 작으면 거짓 원이 검출됩니다. 가장 큰 accumulator 값을 가지는 원이 먼저 리턴
- minRadius: 검출하려는 원의 최소 반지름. 크기를 알 수 없는 경우 0으로 지정.
- maxRadius: 검출하려는 원의 최대 반지름. 크기를 알 수 없는 경우 0으로 지정. 음수를 지정하면 원의 중심만 리턴.
코드
[C++]
# include < opencv2/opencv.hpp>
# include < iostream>
using namespace cv;
using namespace std;
int main()
{
// 그레이 스케일로 입력 이미지를 불러옵니다.
Mat img_gray;
img_gray = imread("test.jpg", IMREAD_GRAYSCALE);
medianBlur(img_gray, img_gray, 5);
// 결과 이미지에 컬러 도형을 사용하기 위해 컬러로 변환합니다.
Mat img_color;
cvtColor(img_gray, img_color, COLOR_GRAY2BGR);
// 원을 검출합니다.
vector<Vec3f> circles;
HoughCircles(img_gray, circles, HOUGH_GRADIENT, 1,20,50,35,0,0);
// 검출된 원에 빨간색/초록색 원을 그려줍니다.
for( size_t i = 0; i < circles.size(); i++ )
{
Vec3i c = circles[i];
Point center(c[0], c[1]);
int radius = c[2];
// 바깥 원
circle( img_color, center, radius, Scalar(0,255,0), 2);
// 중심 원
circle( img_color, center, 2, Scalar(0,0,255), 3);
}
// 검출 결과를 화면에 보여줍니다.
imshow("detected circles", img_color);
waitKey(0);
destroyAllWindows();
return 0;
}
[Python]
import numpy as np
import cv2 as cv
# 그레이 스케일로 입력 이미지를 불러옵니다.
img_gray = cv.imread('test.jpg', cv.IMREAD_GRAYSCALE)
img_gray = cv.medianBlur(img_gray,5)
# 결과 이미지에 컬러 도형을 사용하기 위해 컬러로 변환합니다.
img_color = cv.cvtColor(img_gray,cv.COLOR_GRAY2BGR)
# 원을 검출합니다.
circles = cv.HoughCircles(img_gray,cv.HOUGH_GRADIENT,1,20, param1=50,param2=35,minRadius=0,maxRadius=0)
circles = np.uint16(np.around(circles))
# 검출된 원에 빨간색/초록색 원을 그려줍니다.
for c in circles[0,:]:
center = (c[0],c[1])
radius = c[2]
# 바깥 원
cv.circle(img_color,center,radius,(0,255,0),2)
# 중심 원
cv.circle(img_color,center,2,(0,0,255),3)
# 검출 결과를 화면에 보여줍니다.
cv.imshow('detected circles',img_color)
cv.waitKey(0)
cv.destroyAllWindows()