'vision'에 해당되는 글 4건
- 2013.10.30 Xilinx ZYNQ 를 이용한 Vision Processing Board 1
- 2009.06.21 Rob Hess의 SIFT [8] 7
- 2009.02.23 Rob Hess의 SIFT [3] 2
- 2009.01.06 MAC에서 OpenCV를 컴파일 하기
Rob Hess의 SIFT 8번째
(주) 글을 읽기 전에
이 글은 저와 같은 초보자를 위해서 정리하는 것입니다.
전문가시라면 굳이 읽을 필요가 없습니다.
공부하면서 정리하는 글이라서 서툰 부분이 많이 보입니다. 이해하여 주시고
틈틈이 새로운 것을 알게 되면 그때 그때 업데이트 하겠습니다.
(주) 시작하기 전에
실제 코드를 한번 따라가기 전에 SIFT 알고리즘을 간략하게 정리하여둡니다.
코드를 기계적으로 따라가는것 보다는 알고리즘을 이해하고 따라가는 것이 유용하기 때문입니다.
물론 그렇다고 제가 알고리즘을 다 이해하는 것은 아닙니다.
그냥 초보 수준에서 아는 것들만 정리하였습니다.
PPT 발표 자료는 이 페이지를 참조 하세요 : SIFT 정리.PPT
발표자료를 기반으로 하여서 추가적으로 정리한 내용입니다.
1. Harris Corner Detector
특징으로는 다음과 같습니다.
Rotation 에 대해 검출이 가능하다.
부분 이미지로도 검출이 가능하다.
{
해석 :
이상의 말을 풀이하면
H.C.Detector는 영상이 회전된 것 그리고 밝기의 변화와 이미지 상에서 노이즈가 있어도
어느정도 이를 견디어 내며 원하는 포인트를 찾아낼 수 있다는 의미가 됩니다.
H.C.Detector는 Local Auto Correlation Function에 기반합니다.
기본적인 아이디어는 전체 이미지를 한방에 뒤지는 것이 아니고
주어진 이미지 영역에서 작은 이미지 영역 (부분 영역)을 설정하여 이 윈도우를 주변 영역과 비교하여
커다란 차이점이 있는 부분을 찾아내는 방식입니다.
설정된 이미지에 대해서 뒤지는 방향은 아무 방향이나 상관이 없습니다. 다만 주어진 부분 영역에 대해서
큰 변화가 생기는 방향으로 이동해야 하곘지요
아래 그림을 보면 쉽게 이해됩니다.
제일 왼쪽 그림은 뒤져서 변화가 없으므로 “Flat”으로 보게 됩니다.
가운데 그림은 상하로만 선분이 있다는 것을 알게 됩니다.
- 에지 방향으로 변화가 없다는 것은 에지가 존재한다는 의미가 됩니다.
오른쪽 그림은 모든 방향으로 변화가 존재하기 때문에
“Conor”라고 보는 것 입니다.
- 수학적인 의미는 다음에 하기로 하고 여기선 패스 합니다.
- SIFT가 우선이므로, H.C.Detector는 이정도에서 정리합니다.
매트랩에 대한 코드는 아래를 참고하시기 바랍니다.
http://ipl.cnu.ac.kr/mayadata/harris/harris_corner_detector.htm
}
상기 그림을 실제 H.C.Detector에 걸면 다음과 같은 영상을 얻을 수 있습니다.
그리고 이 그림의 임계치 이상만을 검출하면 다음과 같습니다.
임계치 이상 영역에서 최대값만을 표시하면 다음과 같습니다.
요것이 바로 코너 포인트가 되는 것입니다.
이 코너포인트를 원본 그림과 매핑하면 다음과 같습니다.
문제점 :
크기 변화에대해 대처하지 못한다.
위의 그림처럼 원래 EDGE로 인식되는 것이 스케일을 작에 줄이면, 코너로 바뀌는 경우가 발생합니다.
이처럼 크기가 변하는 것에 따러 검출되는 성분이 변하기 때문에 크기 변화에 대응하지 못하는 것이라고
합니다. - 당연한 이야기 인듯..
관련 자료는 이페이지에 있습니다.
매트랩등등의 코드를 함께 제공하기 때문에 공부하실 분들은 이 페이지를 참고하여 주세요
http://ipl.cnu.ac.kr/mayadata/harris/harris_corner_detector.htm
그리고 위에 설명에 사용된 그림은
을 참고하시기 바랍니다.
'Computer Vision' 카테고리의 다른 글
OpenCV 2.1 맥에서 빌드하기 (0) | 2010.09.04 |
---|---|
SURF Lib (3) | 2010.06.22 |
Rob Hess의 SIFT [7] (1) | 2009.04.30 |
OpenCV - Alpha Blending cvAddWeighted , cvFillPoly (2) | 2009.04.25 |
JPEG2AVI 를 맥에서 빌드하기 (0) | 2009.04.24 |
Rob Hess의 SIFT
앞서 두번에 걸쳐서 Rob의 코드를 컴파일해서 정상적으로 움직이는 것을 확인하였습니다.
이제 코드 내부가 어떻게 동작하는지 확인을 해보겠습니다.
SIFT자체는 나중에 따로 정리하기로 하고 전체 맥락을 한번 따라가는 형식으로 정리하였습니다.
이번에는 전체 코드를 한번 찬찬히 따라가면서 정리하였습니다.
그냥 코드를 읽는 수준이므로 큰 무리 없이 따라가면 됩니다.
OpenCV에 기반하므로, 그냥 이런 함수가 있다고 보고 읽어 가면 됩니다.
1. dspFeat의 분석
dspFeat를 먼저 코드를 보곘습니다.
이 프로그램은 그냥 SIFT를 대상 이미지에 올리는 그림입니다.
별다른 어려운 부분이 없읍니다.
시작 부분에서 두개의 파일을 먼저 설정하고 있습니다.
char* feat_file = "..\\beaver.sift";
char* img_file = "..\\beaver.png";
앞서의 것은 beaver.sift 의 결과물입니다. 텍스트 파일로 되어 있네요
두번째 것은 png format 으로 되어 있는 이미지 파일입니다.
int main( int argc, char** argv )
{
IplImage* img;
struct feature* feat;
char* name;
int n;
img = cvLoadImage( img_file, 1 ); // 먼저 이미지 파일을 로딩한다.
if( ! img )
fatal_error( "unable to load image from %s", img_file );
n = import_features( feat_file, feat_type, &feat ); // 피쳐 파일을 로딩한다.
if( n == -1 )
fatal_error( "unable to import features from %s", feat_file );
name = feat_file;
draw_features( img, feat, n ); // SIFT를 그린다.
cvNamedWindow( name, 1 ); // 창을 열고~~~
cvShowImage( name, img ); // 그림을 그린다. 이때 그림은 draw_feature로 그린것이다.
cvWaitKey( 0 ); // 글고 키 값을 기다린다.
return 0;
}
이다. 큰 문제점은... 은 없네요~
draw_feature()함수를 나중에 따로 정리하여야 하겠습니다.
이것은 SIFT를 정리하면서 하면 되므로 여기서는 SKIP...
2. match의 코드 따라가기
그럼 이제 두번째로 match를 한번 따라가 보겠습니다.
/******************************** Globals ************************************/
char img1_file[] = "..\\beaver.png"; // 찾고자 하는 이미지 파일이다.
char img2_file[] = "..\\beaver_xform.png"; // 비교 대상 파일이다.
/********************************** Main *************************************/
int main( int argc, char** argv )
{
IplImage* img1, * img2, * stacked;
struct feature* feat1, * feat2, * feat;
struct feature** nbrs;
struct kd_node* kd_root;
CvPoint pt1, pt2;
double d0, d1;
int n1, n2, k, i, m = 0;
img1 = cvLoadImage( img1_file, 1 ); // 찾는 이미지를 먼저 로딩한다.
if( ! img1 )
fatal_error( "unable to load image from %s", img1_file );
img2 = cvLoadImage( img2_file, 1 ); // 대상 이미지를 로딩한다.
if( ! img2 )
fatal_error( "unable to load image from %s", img2_file );
stacked = stack_imgs( img1, img2 ); // 두개의 이미지를 합쳐서 하나의 이미지로 만든다.
// 그렇다고 이미지를 겹치는 것이 아니라 상하로 포개는 것이다.
fprintf( stderr, "Finding features in %s...\n", img1_file );
n1 = sift_features( img1, &feat1 ); // 이제 FEATURE를 찾기...
fprintf( stderr, "Finding features in %s...\n", img2_file );
n2 = sift_features( img2, &feat2 ); // 피쳐를 더 찾기...
kd_root = kdtree_build( feat2, n2 ); // 키포인트 배열에서 원하는 kd tree로 구성한다.
for( i = 0; i < n1; i++ ) // 찾고자 하는 이미지 1의 특징점을 대상으로 반복한다.
{
feat = feat1 + i;
k = kdtree_bbf_knn( kd_root, feat, 2, &nbrs, KDTREE_BBF_MAX_NN_CHKS );
// 특징점에서 NN방식으로 하여 찾아낸다.
if( k == 2 ) // k가 2라면.. 찾아낸 것이므로..
{
d0 = descr_dist_sq( feat, nbrs[0] ); // nn과 두번째 nn사이의
// 유클리드 제곱 거리를 구한다.
d1 = descr_dist_sq( feat, nbrs[1] );
if( d0 < d1 * NN_SQ_DIST_RATIO_THR ) // 임계치보다 크다면..
{
// 두개의 포인트로 선을 그린다.
pt1 = cvPoint( cvRound( feat->x ), cvRound( feat->y ) );
pt2 = cvPoint( cvRound( nbrs[0]->x ), cvRound( nbrs[0]->y ) );
pt2.y += img1->height;
cvLine( stacked, pt1, pt2, CV_RGB(255,0,255), 1, 8, 0 );
m++;
feat1[i].fwd_match = nbrs[0];
}
}
free( nbrs );
}
// 다 찾았으면 이미지를 그린다.
fprintf( stderr, "Found %d total matches\n", m );
cvNamedWindow( "Matches", 1 );
cvShowImage( "Matches", stacked );
cvWaitKey( 0 );
/*
이 것은 RANSAC함수가 어떻게 움직이는지 보기 위해서 만든 것입니다.
아래 주석 처리가 된 블럭을 풀면 됩니다.
UNCOMMENT BELOW TO SEE HOW RANSAC FUNCTION WORKS
Note that this line above:
feat1[i].fwd_match = nbrs[0];
is important for the RANSAC function to work.
*/
/*
{
CvMat* H;
H = ransac_xform( feat1, n1, FEATURE_FWD_MATCH, lsq_homog, 4, 0.01,
homog_xfer_err, 3.0, NULL, NULL );
if( H )
{
IplImage* xformed;
xformed = cvCreateImage( cvGetSize( img2 ), IPL_DEPTH_8U, 3 );
cvWarpPerspective( img1, xformed, H,
CV_INTER_LINEAR + CV_WARP_FILL_OUTLIERS,
cvScalarAll( 0 ) );
cvNamedWindow( "Xformed", 1 );
cvShowImage( "Xformed", xformed );
cvWaitKey( 0 );
cvReleaseImage( &xformed );
cvReleaseMat( &H );
}
}
*/
//모두 해제합니다.
cvReleaseImage( &stacked );
cvReleaseImage( &img1 );
cvReleaseImage( &img2 );
kdtree_release( kd_root );
free( feat1 );
free( feat2 );
return 0;
}
여기서는 KDTree를 이용해서 공간상에서 dB를 구축하였음을 알수 있습니다.
다음에는 이것을 좀더 자세하게 따라가 보겠습니다.
'Computer Vision' 카테고리의 다른 글
Rob Hess의 SIFT [5] (2) | 2009.03.02 |
---|---|
Rob Hess의 SIFT [4] (0) | 2009.02.25 |
Rob Hess의 SIFT [2] (0) | 2009.02.18 |
Rob Hess의 SIFT [1] (1) | 2009.02.16 |
MAC에서 OpenCV를 컴파일 하기 (0) | 2009.01.06 |
MAC에서 OpenCV를 컴파일 하기
맥에서 OpenCV를 컴파일
http://opencv.willowgarage.com/wiki/Mac_OS_X_OpenCV_Port
이 페이지를 참조로 따라가면서 컴파일한다.
1. 시작은 OpenCV의 위키 페이지에서 시작한다.
http://opencv.willowgarage.com/wiki/
여기에서 올려져 있는 글을 찬찬이 읽어보면 많은 도움이 된다.
2. Learning OpenCV: Computer Vision with the OpenCV Library
- by Gary Bradski and Adrian Kaehler, O'Reilly Press, October, 2008.
- 책으로 잘 나온 것은 오라일리의 책입니다. 사실상 매뉴얼이라고 생각되고요, OpenCV사이트에서도
- 매뉴얼 대신으로 추천해주는 책입니다.
3. 다운로드는 SVN으로 한다.
http://sourceforge.net/svn/?group_id=22870
페이지에 가면 다운 받을 수 있는 커맨드가 있다. 이것을 이용하여 다운 받는다.
svn co https://opencvlibrary.svn.sourceforge.net/svnroot/opencvlibrary opencvlibrary
이 커맨드는 전체를 모두 다운 받는 것이다. 전체라 함은 브랜치라던가 프리베타 버전과 같은 불필요한 부분까지 모두 다운 받은 것을 말합니다.
처음에는 폴더 구조 가은 것을 잘 모르므로, 그냥 한번 정도는 다운 받아 폴더 구조를 보는 것도 도움이 된다.
위의 커맨드를 넣으면 OpenCV를 다운 받을 수 있다.
아래 사이트에서도 다운 받을 수 있다.
http://sourceforge.net/project/showfiles.php?group_id=22870
이 글을 쓰는 현재 시점에서 최신 버전은 1.1pre 버전이다.
여기서는 후자인 tar파일을 직접 다운받아서 진행한다.
4. compile
일단 다른 폴더에서 빌드를 한다.
mkdir build
cd build
../opencv-1.1.0/configure CPPFLAGS="-I/opt/local/include" LDFLAGS="-L/opt/local/lib"
make
한참을 컴파일 하고 끝난다.
sudo make install
끝나면 위와 같이 인스톨을 한다.
5. 테스트 해보기
인스톨이 끝나면 다음과 같이 확인을 해 볼 수 있다.
샘플용 소스 코드를 다운 받는다.
일일이 코딩하기 귀찮으므로 그냥 간단히 다운 받는다.
인터넷에서 OpenCV sample을 서치하면 아래 사이트를 발견할 수 있다.
http://www.netaro.info/techinfo/OpenCV/src/index.html
여기에 가면 적당한 예제가 있다. 다운 받은 폴더에 가면 ZIP파일로 되어 있고 이것을 압축을 푼다.
컴파일을 하면 다음과 같은 오류가 발생한다.
GUNDAMMACPRO:edgedetect kevinIm$ make
gcc -c -g -Wall sampleEdge.c
gcc -o simpleedge sampleEdge.o -lhighgui -lopencv
ld: library not found for -lopencv
Makefile 을 보면 몇가지 잘못된 옵션이 있다. 버전차이라고 생각된다.. 일단 Makefile을 아래와 같이 수정한다.
gcc -o simpleedge sampleEdge.o -L/usr/local/lib -lhighgui -lcv -lcvaux -lcxcore
== WAS ==
LDFLAGS = -lhighgui -lopencv -L/usr/local/lib
== IS ==
LDFLAGS = -lhighgui -lcv -lcvaux -lcxcore -L/usr/local/lib
그리고 컴파일하면 다음과 같이 나온다.
GUNDAMMACPRO:edgedetect kevinIm$ make
gcc -c -g -Wall InteractiveEdgeDetect.c
InteractiveEdgeDetect.c:18: warning: ‘ltval’ defined but not used
InteractiveEdgeDetect.c:19: warning: ‘htval’ defined but not used
gcc -o intedge InteractiveEdgeDetect.o -lhighgui -lcv -lcvaux -lcxcore -L/usr/local/lib
실행은 간단하게 해본다.
아래 그림은 실행한 결과이다.
윤곽선을 추출하는 예제이다.
'Computer Vision' 카테고리의 다른 글
Rob Hess의 SIFT [3] (2) | 2009.02.23 |
---|---|
Rob Hess의 SIFT [2] (0) | 2009.02.18 |
Rob Hess의 SIFT [1] (1) | 2009.02.16 |
XcodeでOpenCV開発 (0) | 2009.01.03 |
파노라마 구성하기 (0) | 2009.01.03 |