Computer Vision2009. 4. 30. 00:07


SIFT의 동작은


아래와 같이 호출됩니다.


int sift_features( IplImage* img, struct feature** feat )

{

  return _sift_features( img, feat,

SIFT_INTVLS,

SIFT_SIGMA,

SIFT_CONTR_THR,

                         SIFT_CURV_THR,

SIFT_IMG_DBL,

SIFT_DESCR_WIDTH,

                         SIFT_DESCR_HIST_BINS );

}


영상과 feature는 포인터로 전달되고 나머지는  매크로로 정의되어 있습니다. 이렇게 하면

최상위 함수는 매크로에 따라 파라미터를 줄 수 있고 이하 하위 함수들은 인자들을 기반으로 할 수 있으므로

프로그램 테스트 등이 편리해집니다.


정의된 매크로들은 나중에 코드를 읽어가면서 새로운 그리고 필요한 매크로가 나온다면, 그때마다

하나씩 확인해 가기로 하고 여기서는 건너 뜁니다.


실제 호출은 위의 코드에서 보는 바와 같이 _sift_features를 호출하여 구동합니다.

이 함수는 다음과 같은 순서로 동작합니다.


1. 인자를 검사해서 오류가 있는지 확인을 합니다.

2. 주어진 이미지로 이미지 피라미드를 구축합니다.

3. 구축한 이미지 피라미드에서 DoG를 구축합니다.

4. DoG에서 특징점들을 추출하고

5. 특징점 을 좌표에 매핑하고,

6. 특징점 기술자들을 논문대로 정리한다.


이를 위한 호툴된 함수는 다음과 같습니다.

기계적으로 따라갑니다.


int _sift_features( IplImage* img, struct feature** feat, int intvls,

                    double sigma, double contr_thr, int curv_thr,

                    int img_dbl, int descr_width, int descr_hist_bins )

{

  IplImage* init_img;

  IplImage*** gauss_pyr, *** dog_pyr;

  CvMemStorage* storage;

  CvSeq* features;

  int octvs, i, n = 0;


  /* check arguments  

인자를 검사한다. NULL Pointer이면 에러를 출력한다.*/


  if( ! img )

    fatal_error( "NULL pointer error, %s, line %d",  __FILE__, __LINE__ );

  if( ! feat )

    fatal_error( "NULL pointer error, %s, line %d",  __FILE__, __LINE__ );


  /* build scale space pyramid; smallest dimension of top level is ~4 pixels

      이미지 피라미드를 구축한다.

     최상위 피라미드는 그 크기가 4 픽셀 정도이다.

   */


/* 최초의 이미지를 만들어 냅니다.

   이 이미지는 그레이 스케일로 생성됩니다.. */

  init_img = create_init_img( img, img_dbl, sigma );


  octvs = log( MIN( init_img->width, init_img->height ) ) / log(2) - 2;


/* 이미지를  가지고 가우시안 스케일 피라미드를 구성합니다. */

  gauss_pyr = build_gauss_pyr( init_img, octvs, intvls, sigma );


/* DoG 이미지 피라미드를 구성합니다. */

  dog_pyr = build_dog_pyr( gauss_pyr, octvs, intvls );


  storage = cvCreateMemStorage( 0 );


DoG에서 특징점들을 열심히 추출합니다.

  features = scale_space_extrema(

dog_pyr,

octvs,

intvls,

contr_thr,

                            curv_thr,

storage );


/* 추출된 특징들의 특성들을 계산합니다. */

  calc_feature_scales( features, sigma, intvls );


/*  이미지가 2배로 키워서 특징점들을 추출하였을 경우 이를 다시 조절합니다. */

  if( img_dbl )

    adjust_for_img_dbl( features );


/* 정규 좌표를 계산합니다. */

  calc_feature_oris( features, gauss_pyr );


/* Lowe’s Paper 6절에 따라서 특징점 기술자를 만들어냅니다. */

  compute_descriptors( features, gauss_pyr, descr_width, descr_hist_bins );



  /* sort features by decreasing scale and move from CvSeq to array */


  cvSeqSort( features, (CvCmpFunc)feature_cmp, NULL );


  n = features->total;


  *feat = calloc( n, sizeof(struct feature) );


  *feat = cvCvtSeqToArray( features, *feat, CV_WHOLE_SEQ );


  for( i = 0; i < n; i++ )

    {

      free( (*feat)[i].feature_data );

      (*feat)[i].feature_data = NULL;

    }


  cvReleaseMemStorage( &storage );

  cvReleaseImage( &init_img );

  release_pyr( &gauss_pyr, octvs, intvls + 3 );

  release_pyr( &dog_pyr, octvs, intvls + 2 );

  return n;


}


'Computer Vision' 카테고리의 다른 글

SURF Lib  (3) 2010.06.22
Rob Hess의 SIFT [8]  (7) 2009.06.21
OpenCV - Alpha Blending cvAddWeighted , cvFillPoly  (2) 2009.04.25
JPEG2AVI 를 맥에서 빌드하기  (0) 2009.04.24
OpenCV - cvSmooth  (2) 2009.04.22
Posted by GUNDAM_IM
Computer Vision2009. 4. 25. 15:04

Alpha Blending


알파 블랜딩을 OpenCV에서 하는 것을 구현해 보았습니다.

코드를 읽어가면서 정리하였습니다.


1. 프로그램의 순서


순서는 다음과 같습니다.


(1) 이미지 화일을 읽어들이고

      ...

      cvLoadImage

  ...

(2) 알파블랜딩할 이미지를 만듭니다. - 이경우는 만들었지만 다른 이미지를 사용해도 됩니다.

...

cvFillPoly

...


(3) 원본 이미지와 알파블랜딩할 이미지의 크기가 틀리다면

      ROI로 서로의 크기를 맞추어 줍니다.

.....

cvSetImageROI

....

cvResetImageROI

...


(4) 적절한 비율로 블랜딩합니다.

....

cvAddWeighted

....


(5) 이후에 정리합니다.

  cvSaveImage(argv[2] , imgA );

  .....

      cvReleaseImage(&imgA);

      cvReleaseImage(&imgB);



2. 새로운 함수


2.1 cvFillPoly


여기에서 새로 나온 이미지 처리 함수는 다음과 같습니다.


cvFillPoly


2차원 폴리곤을 만들어서 그 폴리곤을 그리고 내부를 채웁니다.

폴리곤의 꼭지점 개수는 제한이 없습니다. 다만 시작하기 전에 해당 폴리곤의 꼭지점 개수를 알려주어야 합니다.



이 함수를 사용하기 위해서 다음과 같은 순서로 합니다.


(1)  폴리곤을 만듭니다. 이 프로그램에서 코드는 아래와 같습니다.

  ....

  CvPoint imgb_rectangle_pts[4] = { cvPoint( 0, 0) ,

    cvPoint(0,imgb_size.width),

    cvPoint(imgb_size.height,imgb_size.width),

    cvPoint(imgb_size.height,0)

  };

   ...

  CvPoint *PointArray[2] = { & imgb_rectangle_pts[0]  , 0 } ;

  ...


 (2) 폴리곤의 개수와 각 폴리곤의 꼭지점 개수를 정합니다.

       

  int PolyVertexNumber[2] = { 4 , 0 } ;

  int PolyNumber = 1 ;


  지금은 하나뿐이므로, 한개의 폴리곤만을 지정한다.

 

 (3) 그리고 함수를 호출합니다.


  cvFillPoly(imgB ,

    PointArray ,

    PolyVertexNumber ,

    PolyNumber,

    CV_RGB(5,5,5),8,0);



2.2 cvAddWeighted


알파블랜딩을 해주는 함수입니다.

사용은 쉽습니다.

각 이미지 별로 가중치를 곱해서 더하는 것입니다


호출은 아래와 같습니다.

  ......

  double alpha = 0.5 ;

  double beta  = 1.0 - alpha ;

  cvAddWeighted(imgA, alpha , imgB , beta , 0.0 , imgA );

  ......







3. 전체 코드


전체 코드는 아래와 같습니다.


--------------------------------------------------------------------------------------------------


#include <stdio.h>

#include <unistd.h>

#include <string.h>

#include <errno.h>


#include <opencv/cv.h>

#include <opencv/highgui.h>




int main(int argc , char * argv[] ){


  // 파라미터를 체크합니다.

  // 귀찮으니까 간단하게 개수만 체크합니다.

  if( argc < 2 )

   {

      printf("usage : alpha src dst\n");

      exit(0);

   }


  // 원본 이미지를 읽어들입니다.

  IplImage *imgA = cvLoadImage( argv[1] , 1);

  //알파 블랜딩할 이미지를 만듭니다. 사각형으로 만들기로 하겠습니다.

  //입력되는 이미지의 크기가 정해진 것이 아니므로,

  //입력 이미지의 크기를 갖고 와서 상대적으로 높이를 맞춥니다.

  //넓이는 150 픽셀 정도로 맞춥니다.

  CvSize imga_size = cvGetSize(imgA);

  CvSize imgb_size = cvSize(150,imga_size.height);

  IplImage *imgB = cvCreateImage( imgb_size  , IPL_DEPTH_8U, 3);


  // 이제 내부에 채워지는 4각형을 만듭니다.

  // 사용할 함수는 cvFillPoly 입니다.

  CvPoint imgb_rectangle_pts[4] = { cvPoint( 0, 0) ,

    cvPoint(0,imgb_size.width),

    cvPoint(imgb_size.height,imgb_size.width),

    cvPoint(imgb_size.height,0)

  };



  CvPoint *PointArray[2] = { & imgb_rectangle_pts[0]  , 0 } ;

  int PolyVertexNumber[2] = { 4 , 0 } ;

  int PolyNumber = 1 ;

  cvFillPoly(imgB ,

    PointArray ,

    PolyVertexNumber ,

    PolyNumber,

    CV_RGB(5,5,5),8,0);


  // 원본 이미지와, 채울 이미지의 크기가 틀리기 때문에 원본 이미지에서 관심 대상

  // 영역을 설정합니다.

  cvSetImageROI(imgA, cvRect(0,0,imgb_size.width,imgb_size.height));


  // 드디어 알파블랜딩을 합니다. 

  double alpha = 0.5 ;

  double beta  = 1.0 - alpha ;

  cvAddWeighted(imgA, alpha , imgB , beta , 0.0 , imgA );

 

  // 이제 관심 영역으로 설정된 것을 풉니다.

  cvResetImageROI(imgA);



  // 폰트를 정합니다.

  CvFont font1;

  double hscale = 0.5;

  double vscale = 0.5;

  double shear = 0.0;

  int thickness = 1;

  int line_type = CV_AA;


  cvInitFont(&font1,CV_FONT_HERSHEY_COMPLEX,hscale,vscale,shear,thickness,line_type);


  // 글을 집어 넣습니다.

  cvPutText(imgA,"GUNDAM",cvPoint( 0,100) ,&font1,CV_RGB(255,255,255));

  cvPutText(imgA,"Red Commet",cvPoint( 0,120) ,&font1,CV_RGB(255,255,255));


  // 화면에 출력하고

  cvNamedWindow( "ImageA-1", 1) ;

  cvShowImage( "ImageA-1", imgA );

 

  cvWaitKey(0);

  cvDestroyWindow("ImageA-1");


  // 파일은 따로 저장합니다.

  cvSaveImage(argv[2] , imgA );


  // 그리고 끝냅니다.

  cvReleaseImage(&imgA);

  cvReleaseImage(&imgB);


 

}//end of main


--------------------------------------------------------------------------------------------------


4. 처리 결과


다음 그림은 그 결과입니다.

사용자 삽입 이미지

'Computer Vision' 카테고리의 다른 글

Rob Hess의 SIFT [8]  (7) 2009.06.21
Rob Hess의 SIFT [7]  (1) 2009.04.30
JPEG2AVI 를 맥에서 빌드하기  (0) 2009.04.24
OpenCV - cvSmooth  (2) 2009.04.22
Rob Hess의 SIFT [6]  (0) 2009.04.18
Posted by GUNDAM_IM
Computer Vision2009. 4. 24. 19:19

JPEG2AVI 를 맥에서 빌드하기


소스 코드는 이곳에서 다운로드 하면 됩니다.


http://sourceforge.net/projects/jpegtoavi/



README를 읽어보면 큰 문제는 없습니다. 그냥  make all을 하면 된다고 합니다.


하지만


make all


을 하면 다음과 같은 에러가 발생합니다.


gcc  -O3 -Wall -ansi -g -DLINUX -D__UNIX__ -DVERSION_MIN=5 -DVERSION_MAJ=1 -DVERBOSE=0 -c jpegtoavi.c -o jpegtoavi.o

In file included from jpegtoavi.c:28:

byteswap.h:5:20: error: endian.h: No such file or directory

byteswap.h:10:3: error: #error "Aiee: __BYTE_ORDER not defined\n";

jpegtoavi.c: In function ‘main’:

jpegtoavi.c:204: error: ‘off64_t’ undeclared (first use in this function)

jpegtoavi.c:204: error: (Each undeclared identifier is reported only once

jpegtoavi.c:204: error: for each function it appears in.)

jpegtoavi.c:204: error: syntax error before ‘jpg_sz_64’

jpegtoavi.c:206: error: nested functions are disabled, use -fnested-functions to re-enable

jpegtoavi.c:206: error: syntax error before ‘MAX_RIFF_SZ’

jpegtoavi.c:344: error: ‘jpg_sz_64’ undeclared (first use in this function)

jpegtoavi.c:351: error: ‘riff_sz_64’ undeclared (first use in this function)

jpegtoavi.c:354: error: ‘MAX_RIFF_SZ’ undeclared (first use in this function)



(1) endian.h는 machine/endian.h에 있다.

이를 수정한다.


== WAS ==

#include <endian.h>

#include <sys/types.h>

== IS ==

#include <machine/endian.h>

#include <sys/types.h>


(2) 나머지 에러는 그냥 다음과 같이 하여서 코드에 추가합니다.


#ifndef _OFF64_T_DEFINED

#define _OFF64_T_DEFINED

        typedef long long  off64_t;

#endif


그 후에 컴파일 하면 빌드가 잘 됩니다.



사용법은 간단합니다. 헬프를 치면 금방 알 수 있습니다.


jpg2avi -f fps imagesize jpegfile list > dst.avi


     -f fps : frame per second입니다.

     imagesize : Width , Height를 구분하여 입력합니다.

    그리고 jpeg file 이름을 나열합니다.


좀 황당한것이 avi 파일로 받기 위해서는 파이프를 통하여 받습니다.

파일로 세이브 할 것이지 정말..


하여튼 동작은 잘 합니다.


 ./jpegtoavi -f 1 844 633  IMG_1.jpg IMG_2.jpg IMG_3.jpg IMG_3.jpg IMG_4.jpg IMG_5.jpg IMG_6.jpg IMG_7.jpg IMG_8.jpg IMG_9.jpg > img.avi


첨부 파일은 img.avi를 올렸습니다.




다 올리고 홈피에 올리니,

사파리에서는 동영상이 잘 안보이네요

익스플로어에서는 보이는데,


이러다가 사파리를 고쳐야 할런지도~



'Computer Vision' 카테고리의 다른 글

Rob Hess의 SIFT [7]  (1) 2009.04.30
OpenCV - Alpha Blending cvAddWeighted , cvFillPoly  (2) 2009.04.25
OpenCV - cvSmooth  (2) 2009.04.22
Rob Hess의 SIFT [6]  (0) 2009.04.18
OpenCV - Convert Image  (0) 2009.04.11
Posted by GUNDAM_IM
Computer Vision2009. 4. 22. 19:55

() 글을 읽기 전에 
 글은 저와 같은 OpenCV초보자를 위해서 정리하는 것입니다.
전문가이시라면 굳이 읽을 필요가 없습니다.
공부하면서 정리하는 글이라서 서툰 부분이 많이많이 보입니다.


SIFT의 내용을 따라가다 보면 Smooth함수를 호출합니다.

그래서 이번에 OpenCV Smooth함수를 아래와 같이 정리하고 테스트를 해보았습니다.

중요한 포인트는 번역을 했지만 억지로 번역하여 넣지 않았습니다.  

예제는 인터넷에서 다운 받은것을 조금 수정하였습니다.

( 인터넷에서 다운 받았는데, 나중에 페이지를 찾을려고 하니, 시간이 지난 뒤여서  찾지 못하였습니다.

   그때 그때 북마크를 걸어두어야 하는데, 나중에 보니 못찾겠더군요.. 쩝.. )

파라미터를 바꾸어가면서 테스트 할 수 있도록 수정하였기 때문에

필터 효과를 눈으로 확인을 할 수 있습니다.

덕분에 TrackBar의 사용법도 알게 되었습니다.

궁굼하신 분은 코드를 보시면 쉽게 이해가실 것입니다.

아래 그림은 실행시켰을때 나오는 그림입니다.

사용자 삽입 이미지
트랙바가 2개인데 위 트랙바는 필터의 종류를

두번째 트랙바는 필터의 인자를 뜻합니다.

프린트로 덤프하므로 하나씩 움직여가면서 테스트 해보시면 쉽게 결과를 보실 수 있습니다.


Smooth

OpenCV에서는 몇가지 방법으로 Smooth를 할 수 있게 하여 줍니다.

함수의 원형은 다음과 같습니다.

void cvSmooth( const CvArr* src, CvArr* dst,

               int smoothtype=CV_GAUSSIAN,

               int param1=3, int param2=0, double param3=0 );


smoothing 타입에 따라서 파라미터 인자의 역활이 바뀝니다.

요 부분만 알고 있으면 나머진 쉽습니다.

src

원본 이미지


dst

결과 이미지


smoothtype

smoothing 타입

  • CV_BLUR_NO_SCALE (simple blur with no scaling)
    • summation over a pixel param1×param2 neighborhood.
    • If the neighborhood size may vary, one may precompute integral image with cvIntegral function.
  • CV_BLUR (simple blur)
    • summation over a pixel param1×param2 neighborhood with subsequent scaling by 1/(param1param2).
  • CV_GAUSSIAN (gaussian blur)
    • convolving image with param1×param2 Gaussian kernel.
  • CV_MEDIAN (median blur)
    • finding median of param1×param1 neighborhood (i.e. the neighborhood is square).
  • CV_BILATERAL (bilateral filter)


param1

첫번째 인자

param2

두번째 인자

In case of simple scaled/non-scaled and Gaussian blur if param2 is zero, it is set to param1.

param3

         가우시안 방식일 경우 시그마를 넣어야 하지만,

이 파라미터가 0이면 커널 사이즈에서 자동으로 만들어진다.  수식은 아래와 같습니다.

              sigma = (n/2 - 1)*0.3 + 0.8,

                  where n=param1 for horizontal kernel,

                                                

                        n=param2 for vertical kernel.


  • Using standard sigma for small kernels (3×3 to 7×7) gives better speed.
  •       If param3 is not zero, while param1 and param2 are zeros, the kernel size is calculated from the sigma (to provide accurate enough operation).

보통의 시그마를 쓸 경우 그냥 좀 빨라진다. (차이는 ???)

         - 사실 차이라는게 크게 없는듯 합니다. 많이 하면 차이가 있겠지만 제 머쉰에서는 금방 결과가 나왔습니다.

         커널 사이즈를 안주고 (0으로 주고) 호출하면 역으로 시그마에서 커널 사이즈를 만듭니다.


The function cvSmooth smooths image using one of several methods. Every of the methods has some features and restrictions listed below

Blur with no scaling works with single-channel images only and supports accumulation of 8-bit to 16-bit format (similar to cvSobel and cvLaplace) and 32-bit floating point to 32-bit floating-point format.

Simple blur and Gaussian blur support 1- or 3-channel, 8-bit and 32-bit floating point images. These two methods can process images in-place.

Median and bilateral filters work with 1- or 3-channel 8-bit images and can not process images in-place.


아래는 소스 코드입니다.


#include <stdio.h>

#include <unistd.h>

#include <string.h>

#include <errno.h>


#include <opencv/cv.h>

#include <opencv/highgui.h>




int g_switch_value = 0;

int sigma_value  = 0;

int filterInt = 0;

int lastfilterInt = -1;

int lastsigma = -1;


void switch_callback( int position ){

filterInt = position;

}


void switch_sigma_callback( int position ){

  if(position < 3 )

    position = 4;


  sigma_value = position;

}



int main(int argc, char * argv[])

{

const char* name = "Filters Window";

float f_sigma ;

IplImage* img = cvLoadImage( "4390m.jpg",1 );

IplImage* out = cvCreateImage( cvGetSize(img), IPL_DEPTH_8U, 3 );


cvNamedWindow( name, 1 );

cvShowImage(name, out);

// Other Variables

CvPoint seed_point = cvPoint(305,195);

CvScalar color = CV_RGB(250,0,0);


// Create trackbar

cvCreateTrackbar( "FILTER", name, &g_switch_value, 5, switch_callback );

cvCreateTrackbar( "parameter", name, &sigma_value, 11, switch_sigma_callback );


while( 1 ) {


switch( filterInt ){

case 0:

 cvSmooth( img, out, CV_BLUR, 7, 7 , 0 ,0 );

break;

case 1:

 f_sigma = ( sigma_value / 2 - 1 ) * 0.3 + 0.8 ;

 cvSmooth( img, out, CV_GAUSSIAN, 7 , 7 , f_sigma , f_sigma);

 

break;

case 2:

 if( sigma_value < 3 )  sigma_value = 3 ;

 if( sigma_value % 2  == 0)  sigma_value +=1 ;

 cvSmooth( img, out, CV_MEDIAN,  sigma_value  ,  sigma_value , 0 , 0);

 break;

case 3:

cvErode( img, out, NULL, 1);

break;

case 4:

cvDilate( img, out, NULL, 1);

break;

case 5:

cvFloodFill( out, seed_point, color, cvScalarAll(5.0), cvScalarAll(5.0), NULL, 4, NULL );

break;

}


if(

  (filterInt != lastfilterInt)||

  (sigma_value != lastsigma)

 )

 {

cvShowImage(name, out);

lastfilterInt = filterInt;

lastsigma     = sigma_value;


switch( filterInt ){

   case 0:

     printf("Blur Smooth\n");

     break;

   case 1:

     printf("Gaussian Smooth\n");

       printf(" Sigma %d\n",  sigma_value );  

     break;

   case 2:

     printf("Median Smooth : Filter Size = %d x %d\n" , sigma_value , sigma_value);

     break;

   case 3:

     printf("Erode\n");

     break;

   case 4:

          printf("Dilate\n");

     break;

   case 5:

       printf("Flood Fill\n");

     break;

           }

 }


if( cvWaitKey( 15 ) == 27 )

break;

}


cvReleaseImage( &img );

cvReleaseImage( &out );

cvDestroyWindow( name );

return 0;

}





'Computer Vision' 카테고리의 다른 글

OpenCV - Alpha Blending cvAddWeighted , cvFillPoly  (2) 2009.04.25
JPEG2AVI 를 맥에서 빌드하기  (0) 2009.04.24
Rob Hess의 SIFT [6]  (0) 2009.04.18
OpenCV - Convert Image  (0) 2009.04.11
OpenCV - Image Mask  (0) 2009.03.16
Posted by GUNDAM_IM
Computer Vision2009. 4. 18. 15:08

() 글을 읽기 전에
글은 저와 같은  초보자를 위해서 정리하는 것입니다.
전문가시라면 굳이 읽을 필요가 없습니다.
공부하면서 정리하는 글이라서 서툰 부분이 많이 보입니다. 이해하여 주시고

틈틈이 새로운 것을 알게 되면 그때 그때 업데이트 하겠습니다.



(주) 시작하기 전에

실제 코드를 한번 따라가기 전에 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에 걸면 다음과 같은 영상을 얻을 수 있습니다.

사용자 삽입 이미지


그리고 이 그림의 임계치 이상만을 검출하면 다음과 같습니다.


사용자 삽입 이미지


임계치 이상 영역에서 최대값만을 표시하면 다음과 같습니다.

사용자 삽입 이미지

요것이 바로 코너 포인트가 되는 것입니다.


  이 코너포인트를 원본 그림과 매핑하면 다음과 같습니다.


사용자 삽입 이미지

문제점 :

크기 변화에대해 대처하지 못한다.

사용자 삽입 이미지
위의 그림처럼 원래 에지로 인식하는 것이 크기가 줄어들면서 Coner로 인식이 되는 경우가 발생합니다.

혹은 그 역으로도 발생합니다.


따라서 H.C.Detector는 크기의 변경에 따라서 검출되는 정보가 변하므로,

        크기 변화에 대처하지 못하는 것입니다.

   

       SIFT는 이러한 문제점을 개선하기 위해서 나온 것입니다.

       본격적인 이야긴 다음편에서~~      



    이번 내용에 대해서 추가적인 자료는 다음과 같습니다.


      매트랩등등의 코드를 함께 제공하기 때문에 공부하실 분들은 이 페이지를 참고하여 주세요


http://ipl.cnu.ac.kr/mayadata/harris/harris_corner_detector.htm

그리고 위에 설명에 사용된 그림과 수식등은


lect9-slides.pdf


      을 참고하시기 바랍니다.


      ----------

      자료 정리하던 프로그램이 Expire되어 버렸습니다.

      잘 정리(?) 된 줄 알았는데 근본적으로 Time Limit이 되어 있더군요

      좋은 프로그램인데 넘 고가여서.. .쩝..


      그래서 한단계 낮은 프로그램을 구입했습니다.

      그바람에 그동안 정리했던 것 옮기느라 많이 늦어졌네요

      

'Computer Vision' 카테고리의 다른 글

JPEG2AVI 를 맥에서 빌드하기  (0) 2009.04.24
OpenCV - cvSmooth  (2) 2009.04.22
OpenCV - Convert Image  (0) 2009.04.11
OpenCV - Image Mask  (0) 2009.03.16
OpenCV - Extract  (2) 2009.03.12
Posted by GUNDAM_IM