Hough Transform 이란 영상에 있는 점들이 이루는 직선들 중 가장 많이 겹치는 부분을 추출하는 변환규칙입니다.
수학이 힘을 발휘하는 부분으로서 간단하게 (x, y) 를 (a, b) 라 하고 새로운 좌표계에 y' = ax' + b 를 그리면 여러개의 직선들이 존재하게되는데 이중 가장 많은 직선이 지나는 점 (x', y') 를 다시 (x, y) 좌표계로 변환하면 점들이 지나는 직선을 구해낼 수 있는 규칙입니다.
정말로 간단하면서도 신기하지요. OpenCV 에는 간단하게 cvHoughLines2() 함수를 제공하고 있고요.
코딩에는 Media Systam Lab. 의 서종훈 연구원(flamme4u) 님이 수고해 주셨습니다.
제가 연구실 세미나 때 제가 발표했던 자료 중 핵심 입니다.
핵심을 정리하면,
Hough Transform 은 픽셀기반의 raster image 에서 기하학적 성분 geometric primitives 추출하는 방법이다.
Hough 변환은 직선 뿐만 아니라 원, 타원 등 도형을 위한 특징 추출법으로 “점<->직선” 변환을 하는 방법
xy 평면상에 직선이 있으면 y=ax+b 로 표현이 되고 이를 ab 평면상으로 옮기면 (a,b) 좌표계가 된다.
- 소스코드
//
// Hough Lines
//
// Jong-Hoon Seo, Dong-Chul Kim
// Media System Lab., Yonsei University
// http://msl.yonsei.ac.kr
// http://opencv.co.kr
//
#include "stdafx.h"
int main()
{
IplImage* src0;
CvCapture* captue = cvCaptureFromCAM(0);
while(1){
cvGrabFrame(captue);
if( (src0=cvRetrieveFrame(captue)) != 0)
{
IplImage* dst = cvCreateImage( cvGetSize(src0), 8, 1 );
IplImage* color_dst = cvCreateImage( cvGetSize(src0), 8, 3 );
IplImage* src = cvCreateImage( cvGetSize(src0), IPL_DEPTH_8U, 1);
cvCvtColor(src0, src, CV_RGB2GRAY);
CvMemStorage* storage = cvCreateMemStorage(0);
CvSeq* lines = 0;
cvCanny( src, dst, 50, 200, 3 );
cvCvtColor( dst, color_dst, CV_GRAY2BGR );
lines = cvHoughLines2( dst, storage, CV_HOUGH_STANDARD, 1, CV_PI/180, 100, 0, 0 );
for( int i = 0; i < MIN(lines->total,100); i++ )
{
float* line = (float*)cvGetSeqElem(lines,i);
float rho = line[0];
float theta = line[1];
CvPoint pt1, pt2;
double a = cos(theta), b = sin(theta);
double x0 = a*rho, y0 = b*rho;
pt1.x = cvRound(x0 + 1000*(-b));
pt1.y = cvRound(y0 + 1000*(a));
pt2.x = cvRound(x0 - 1000*(-b));
pt2.y = cvRound(y0 - 1000*(a));
cvLine( color_dst, pt1, pt2, CV_RGB(255,0,0), 3, 8 );
}
lines = cvHoughLines2( dst, storage, CV_HOUGH_PROBABILISTIC, 1, CV_PI/180, 80, 30, 10 );
for( i = 0; i < lines->total; i++ )
{
CvPoint* line = (CvPoint*)cvGetSeqElem(lines,i);
cvLine( color_dst, line[0], line[1], CV_RGB(255,0,0), 3, 8 );
}
cvNamedWindow( "Source", 0 );
cvShowImage( "Source", src );
cvNamedWindow( "Hough", 0 );
cvShowImage( "Hough", color_dst );
cvReleaseMemStorage(&storage);
}
if(cvWaitKey(10) >= 0) break;
}
cvDestroyAllWindows();
cvReleaseCapture(&captue);
return 0;
}
Copyrights (c) 2006 OpenCV.co.kr. All rights reserved.
Media System Lab., Yonsei University. http://msl.yonsei.ac.kr
by Dong-Chul Kim, e-mail: opencv at opencv.co.kr
- T9T9.com
'CLASS' 카테고리의 다른 글
[OpenCV] 키보드로 OpenCV 를 제어하는 인터페이스 강좌 (소스포함) (0) | 2006.07.26 |
---|---|
[OpenCV] OpenCV 카메라 화면 크기 제어하기 강좌 (소스포함) (1) | 2006.07.26 |
[OpenCV] 윤곽(contour) 추출, 에지(edge) 추출 중급강좌 (0) | 2006.01.03 |
[OpenCV] OpenCV 를 이용한 영상 이진화(Binarization) 초급강좌 (8) | 2005.11.11 |
[OpenCV] OpenCV 기초강좌 - 2편 : 카메라 입력받기 (7) | 2005.11.06 |