- 직선은 객체 인식과 영상 이해에 중요한 역할을 하기 때문에 영상 내의 특별한 특징을 감지하기 위해 사용.
- 허프 변환 알고리즘은 영상에서 선을 감지하기 위해 개발했고, 다른 간단한 영상 구조 감지로 확장할 수 있다.
- 허브 변환은 다음 방정식을 사용해 직선을 표현.
- p : 직선과 영상 원점(왼쪽 상단 모서리)간의 거리.
- Θ : 선에 대한 수직 각도.
- 식에서 영상 내에 보이는 선은 0과 π(파이) 라디안 사이의 각도인 Θ를 갖고,p 반지름은 영상 대각선의 길이와 같은 최대값을 갖는다.
- 다음 선 집합을 보았을 때
- OpenCV는 선을 감지하기 위한 두 가지 허프 변환을 제공.
- 기본 버전은 cv::HoughLines 이다.
- 입력은 점집합(넌제로 화소로 표현)을 포함하는 이진 맵이고, 일부는 선 형태로 정렬. (에지 맵에서 캐니 연산자로 얻는다.)
- cv::HoughLines 함수의 결과는 cv::Vec2f 요소의 벡터로, 부동소수점 값의 각 쌍은 감지된 선 (p, Θ)의 파라미터를 표현.
- 즉, 영상 외곽선을 얻기 위해 먼저 캐니 연산자를 적용한 곳에 허프 변환을 이용해 선을 감지.
// 선 감지 위한 허프 변환
std::vector<cv::Vec2f> lines;
cv::HoughLines(contours, lines,
1,PI/180, // 단계별 크기
80); // 투표(vote) 최대 개수
- 3, 4번째 파라미터는 선을 찾기 위한 단계별 크기에 해당.
- 예제에서 이 함수는 1과 π/180에서 단계별로 가능한 모든 각도로 반지름의 선을 찾음.
- 마지막 파라미터는 다음 절에서 설명.
- 특정 파라미터 값으로는 이전 절의 도로 영상에서 열다섯 개의 선을 감지.
- 이 알고리즘은 영상 내의 선을 감지할 뿐 각 선의 마지막 점이 부여되지 않은 상태에서 선을 분할할 수 없다. (따라서 영상 전체를 가로지르는 선을 그림)
- 대부분 수직선에 대해 영상의 수평 한계(처음과 마지막 행)와 교차하는 부분을 계산하고, 두 점 간의 선을 그린다. (처음과 마지막 열을 사용)
- cv::line 함수를 사용해 선을 그림.
- cv::line 함수는 영상 한계의 바깥에 있는 점 좌표로도 작동 (즉, 영상 내부에 계산된 교차점이 없는지 확인할 필요 없음)
- Example
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#define PI 3.1415926
int main()
{
cv::Mat image= cv::imread("road.jpg", 0);
cv::namedWindow("Original Image");
cv::imshow("Original Image",image);
// 캐니 알고리즘 적용
cv::Mat contours;
cv::Canny(image, contours, 125, 350);
// 선 감지 위한 허프 변환
std::vector<cv::Vec2f> lines;
cv::HoughLines(contours, lines,
1,PI/180, // 단계별 크기
80); // 투표(vote) 최대 개수
// 선 그리기
cv::Mat result(contours.rows, contours.cols, CV_8U, cv::Scalar(255));
std::cout << "Lines detected: " << lines.size() << std::endl;
// 선 벡터를 반복해 선 그리기
std::vector<cv::Vec2f>::const_iterator it= lines.begin();
while (it!=lines.end()) {
float rho = (*it)[0]; // 첫 번째 요소는 rho 거리
float theta = (*it)[1]; // 두 번째 요소는 델타 각도
if (theta < PI/4. || theta > 3.*PI/4.) { // 수직 행
cv::Point pt1(rho/cos(theta), 0); // 첫 행에서 해당 선의 교차점
cv::Point pt2((rho-result.rows*sin(theta))/cos(theta), result.rows);
// 마지막 행에서 해당 선의 교차점
cv::line(image, pt1, pt2, cv::Scalar(255), 1); // 하얀 선으로 그리기
} else { // 수평 행
cv::Point pt1(0,rho/sin(theta)); // 첫 번째 열에서 해당 선의 교차점
cv::Point pt2(result.cols,(rho-result.cols*cos(theta))/sin(theta));
// 마지막 열에서 해당 선의 교차점
cv::line(image, pt1, pt2, cv::Scalar(255), 1); // 하얀 선으로 그리기
}
std::cout << "line: (" << rho << "," << theta << ")n";
++it;
}
cv::namedWindow("Detected Lines with Hough");
cv::imshow("Detected Lines with Hough",image);
cv::waitKey(0);
return 0;
}
- Result
- Example
- Result
- 예제 분석
- 참고문헌 : OpenCV 2 Computer Vision Application Programming Cookbook
댓글 0
| 번호 | 제목 | 글쓴이 | 날짜 | 조회 수 |
|---|---|---|---|---|
| 51 | [아두이노] 장애물 감지 자율주행 자동차 | proin | 2018.05.14 | 1 |
| 50 | [아두이노] DC 모터의 제어(모터드라이버 L298N) 1편 | proin | 2018.05.14 | 3 |
| 49 | 아두이노 탱크 연결 사진 | proin | 2018.05.14 | 2 |
| 48 | 오픈소스 + 알고리즘 | proin | 2018.05.14 | 1 |
| » | OpenCV #7-2 Example (허프 변환으로 영상 내 선 감지) | proin | 2018.05.14 | 0 |
| 46 | 롤 모델 | proin | 2018.05.14 | 2 |
| 45 | 사진에서 엣지 따오는 소스 | proin | 2018.05.14 | 1 |
| 44 | 카메라 여는 소스 | proin | 2018.05.14 | 1 |
| 43 | Visual Studio 2017에서 OpenCV 3.4를 사용하는 방법 | proin | 2018.05.14 | 0 |
| 42 | 모터 돌리는 소스 | proin | 2018.05.14 | 2 |
| 41 | project | proin | 2018.05.14 | 1 |
| 40 | [25호]DIY 프로젝트 공모전- 차선 인식을 통한 차량의 능동적 안전시스템 개발 | proin | 2018.05.14 | 1 |
| 39 | [Web] PHP 로그인/로그아웃/회원가입 {원본} | proin | 2018.05.14 | 1 |
| 38 | html 출력 {원본} | proin | 2018.05.14 | 1 |
| 37 | 세션을 사용한 PHP 로그인/로그아웃 소스 {원본} | proin | 2018.05.14 | 1 |
| 36 | 세션을 사용한 PHP 로그인/로그아웃 소스 | proin | 2018.05.03 | 2 |
| 35 | html 출력 | proin | 2018.05.02 | 1 |
| 34 | 옥션 로그인 부분 소스 | proin | 2018.05.02 | 0 |
| 33 | XML과 DB | project2018 | 2018.05.02 | 3 |
| 32 | 컨버터 | proin | 2018.05.02 | 0 |










