상세 컨텐츠

본문 제목

#OpenCV 4로 배우는 컴퓨터 비전과 머신 러닝 - 13

Programing/OpenCV

by CouqueD'asse 2022. 7. 6. 15:46

본문

9.2 직선 검출과 원 검출

 

9.2.1 허프 변환 직선 검출

직선 : 영상에서 찾을 수 있는 많은 특징 중의 하나이며 영상을 분석함에 있어 중요한 정보를 제공

영상에서 직선 성분을 찾기 위해서는 우선 에지를 찾아내고, 에지 픽셀들이 일직선상에 배열되어 있는지를 확인

허프 변환 : 2차원 xy 좌표에서 직선의 방정식을 파라미터 공간으로 변환하여 직선을 찾는 알고리즘

2차원 평면 직선 방정식 : y = ax + b

축적 배열 : 0으로 초기화된 2차원 배열에서 직선이 지나가는 위치의 배열 원소 값을 1씩 증가시켜 생성

// 허브 변환 직선 검출
void hough_lines()
{
	Mat src = imread("building.jpg", IMREAD_GRAYSCALE);

	if (src.empty())
	{
		return;
	}

	Mat edge;
	Canny(src, edge, 50, 150); // 에지 영상

	vector<Vec2f>lines;
	HoughLines(edge, lines, 1, CV_PI / 180, 250);
    // 1 : 축적 배열에서 P값의 해상도 (픽셀 단위)
    // CV_PI /180 : 축적 배열에서 세타값의 해상도 (라디안 단위)

	Mat dst;
	cvtColor(edge, dst, COLOR_GRAY2BGR);

	for (size_t i = 0; i < lines.size(); i++)
	{
		float r = lines[i][0], t = lines[i][1];
		double cos_t = cos(t), sin_t = sin(t);
		double x0 = r * cos_t, y0 = r * sin_t;
		double alpha = 1000;

		Point pt1(cvRound(x0 + alpha * (-sin_t)), cvRound(y0 + alpha * cos_t));
		Point pt2(cvRound(x0 - alpha * (-sin_t)), cvRound(y0 - alpha * cos_t));
		line(dst, pt1, pt2, Scalar(0, 0, 255), 2, LINE_AA);
	}

	imshow("src", src);
	imshow("dst", dst);

	waitKey();
	destroyAllWindows();
}

확률적 허프 변환 : 직선의 방정식 파라미터 P와 세타를 반환하는 것이 아니라 직선의 시작점과 끝점 좌표를 반환 = 선분을 찾는 방법

// 확률적 허프 변환 선분 검출
void hough_lines_segments()
{
	Mat src = imread("building.jpg", IMREAD_GRAYSCALE);

	if (src.empty())
	{
		return;
	}

	Mat edge;
	Canny(src, edge, 50, 150);

	vector<Vec4i>lines;
	HoughLinesP(edge, lines, 1, CV_PI / 180, 160, 50, 5);
    // 50 : 검출할 선분의 최소 길이
    // 5 : 직선으로 간주할 최대 에지 점 간격
	
	Mat dst;
	cvtColor(edge, dst, COLOR_GRAY2BGR);

	for (Vec4i l : lines)
	{
		line(dst, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(0, 0, 255), 2, LINE_AA);
	}

	imshow("src", src);
	imshow("dst", dst);

	waitKey();
	destroyAllWindows();
}

 

9.2.2 허프 변환 원 검출

중심 좌표 ab에 반지름 r인 원의 방정식 : (x a)^2 + (y-b)^2 = r^2

허프 그래디언트 방법

1단계 : 영상에 존재하는 모든 원의 중심 좌표를 찾는다.

2단계 : 검출된 원의 중심으로부터 원에 적합한 반지름을 구한다.

축적 배열 : 입력 영상과 동일한 xy 좌표 공간에서 2차원 배열로 생성

원의 중심을 찾기 위해 허프 그래디언트 방법은 입력 영상의 모든 에지 픽셀에서 그래디언트를 구하고, 그래디언트 방향을 따르는 직선상의 축적 배열 값을 1씩 증가시킴

// 허프 원 검출
void hough_circles()
{
	Mat src = imread("coins.png", IMREAD_GRAYSCALE);

	if (src.empty())
	{
		return;
	}

	Mat blurred;
	blur(src, blurred, Size(3, 3));

	vector<Vec3f> circles;
	HoughCircles(blurred, circles, HOUGH_GRADIENT, 1, 50, 150, 30);
    // 1 : 축적 배열크기는 입력 영상과 같은 크기로 사용
    // 50 : 두 원의 중심점 거리가 50픽셀보다 작으면 검출하지 않는다.
    // 150 : 케니 에지 검출기의 높은 임계값
    // 30 : 축적 배열 원소 값이 30보다 크면 원의 중심점으로 선택
    // circles : 검출된 원의 중심 좌표와 반지름 정보는 circles 변수에 저장

	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();
	destroyAllWindows();
}

관련글 더보기