차근차근/OpenCV

SURF에 의한 특징점 검출

예쁜꽃이피었으면 2014. 8. 6. 14:55

내가 찾고자 했던 것은 cvsurfpoint인데 ..

-시퀀스에 저장된 각 요소의 자료구조는 구조체 CvSURFPoint이다.  

-각 특징에 대해 특징의 좌표 위치, 크기, 방향, 묘사자를 계산할 수 있어, 크기 및 방향에 무관한 물체 주적 및 매칭에 사용될 수 있다.

-키포인트의 정보를 저장?(http://www.haenaki.com/141)


+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

http://blog.naver.com/hwanhee0920?Redirect=Log&logNo=130147029143


1. void cvExtractSURF(const CvArr* image, const CvArr* mask, CvSeq** keypoints, CvSeq** descriptors, CvMemStorage* storage, CvSURFParams params); 


 


  1) 8비트 그레이스케일 image 영상에서 Herbert Bay에 의해 제안된 SURF을 구현하여 특징점 및 묘사자를 계산한다.  마스크 영상 mask에서 0이 아닌 화소값이 


      50%이상인 곳에서만 특징을 검출한다.  keypoints는 검출된 특징점을 저장한 시퀀스의 이중 포인터이며, 시퀀스에 저장된 각 요소의 자료구조는 구조체 


      CvSURFPoint이다.  각 특징에 대해 특징의 좌표 위치, 크기, 방향, 묘사자를 계산할 수 있어, 크기 및 방향에 무관한 물체 주적 및 매칭에 사용될 수 있다.


 


  2) SURF는 Hessian을 사용한다.


 


  3) descriptors는 묘사자 시퀀스로의 이중 포인터로, 시퀀스의 각 요소는 params.extended = 0 이면 64개의 실수, params.extended = 1 이면 128개의 실수 묘사


      자를 저장한다.  storage는 특징점과 묘사자를 위한 메모리공간으로 사용한다.  params은 구조체 CvSURFParams로 알고리즘의 파라미터를 지정한다.


 


  4) SURF에서 묘사자는 Haar 웨이블릿을 사용하여 계산한다.  CvSURFPoint 구조체의 멤버 중에서 특징의 위치 pt, size, 방향 dir를 이용하여 사각영역을 설정하고,


      사각 영역을 4 X 4 영역으로 분할한 다음, 수평방향 Haar 웨이블릿 값 dx, 수직 Haar 웨이블릿 값 dy를 이용하여 각 영역에서 extened = 0 이면 4개의 특징을 생


      성하고 extended = 1 이면 8개의 특징을 생성한다.


 


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


 


#include "cv.h"

#include "highgui.h"

#include <stdio.h>


int main()

{

 IplImage *srcImage;

 if((srcImage = cvLoadImage("lena.jpg", CV_LOAD_IMAGE_GRAYSCALE)) == NULL)

 {

  return -1;

 }

 

 IplImage *dstImage = cvCreateImage(cvGetSize(srcImage), IPL_DEPTH_8U, 3);

 CvMemStorage *storage = cvCreateMemStorage(0);

 CvSeq *imageKeypoints = NULL, *imageDescriptors = NULL;

 CvSURFParams params = cvSURFParams(3000, 0);

 cvExtractSURF(srcImage, NULL, &imageKeypoints, &imageDescriptors, storage, params);

 printf("Image imageKeypoints : %d\n", imageKeypoints->total);

 printf("Image Descriptors : %d\n", imageDescriptors->total);

 cvCvtColor(srcImage, dstImage, CV_GRAY2BGR);

 

 int x, y, r, i;


 int x1, y1, x2, y2;

 CvPoint2D32f pt[4];

 CvBox2D box;

 CvScalar color;


 for(i=0; i<imageKeypoints->total; i++)

 {

  CvSURFPoint *surf = (CvSURFPoint*)cvGetSeqElem(imageKeypoints, i);

  x = cvRound(surf->pt.x);

  y = cvRound(surf->pt.y);

  r = cvRound(surf->size*1.2/9.*2);


  // Draw a box using surf-dir


  box.angle = surf->dir;

  box.center = cvPoint2D32f(x, y);

  box.size = cvSize2D32f(2*r, 2*r);

  cvBoxPoints(box, pt);

  

  if(surf->laplacian < 0)

  {

   color = CV_RGB(0, 0, 255);

  }

  else

  {

   color = CV_RGB(255, 0, 0);

  }

  

  for(int j=0; j<4; j++)

  {

   x1 = cvRound(pt[i].x);

   y1 = cvRound(pt[i].y);

   x2 = cvRound(pt[(j+1)%4].x);

   y2 = cvRound(pt[(j+1)%4].y);

   CvPoint r1 = cvPoint(x1, y1);

   CvPoint r2 = cvPoint(x2, y2);

   cvLine(dstImage, r1, r2, color, 2);

  }


  // Draw Circle


  cvCircle(dstImage, cvPoint(x, y), r, color, 2);

 }


 int descriptor_size = (params.extended) ? 128 : 64;


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

 {

  float *aD = (float*)cvGetSeqElem(imageDescriptors, i);

  printf("i = %d :\n", i);

  for(int j=0; j<descriptor_size; j++)

  {

   if(j%4 == 3)

   {

    printf("%.4f\n", aD[j]);

   }

   else

   {

    printf("%.4f,", aD[j]);

   }

  }

  printf("\n");

 }


 cvNamedWindow("dstImage", CV_WINDOW_AUTOSIZE);

 cvShowImage("dstImage", dstImage);

 cvWaitKey(0);

 cvDestroyAllWindows();


 cvReleaseMemStorage(&storage);


 cvReleaseImage(&srcImage);

 cvReleaseImage(&dstImage);


 return 0;

}


 


반응형