'ComputerVision'에 해당되는 글 2건

  1. 2011.09.06 OpenCV 2.3 Computer vision (3)
  2. 2009.04.30 Rob Hess의 SIFT [7] 1
Computer Vision2011. 9. 6. 10:22
Creating a GUI application using QT

앞절에서는 Qt의 기본적인 내용만 정리한 것이고 , 이번에는 Qt와 OpenCV를 연결하여 좀더 Qt의  GUI를 사용하는 것을 테스트 합니다.   Graphic 관련 데이터를 처리하는데 O/S마다 종속성도 존재하고 귀찮은 GUI를 일일이 만들기도 그렇고 할때 딱 좋은 것이 이 Qt + OpenCV 조합입니다. 필요한 함수는 다 있으므로 이것을 이용해서 알고리듬을 만들어서 테스트 해보고 필요한 부분만 들어 내에서 H/W로 변경하면 됩니다.

이 OpenCV조합을 SystemC로 연결시켜서 테스트 할 수 있고 또 SystemC 조합을 다시 SDL로 연결시켜서 해볼 수 있기 때문에 이런것을 한번 알아 두면 두고두고 조합하면서 써먹을 수 있습니다. - 쉽게 말하면 아주 편하다는 의미입니다. 


이번에는 Create Project에서 QT GUI를 선택합니다.

 
프로젝트 이름은 원하는것으로 정하고 만들면 아래와 같이 만들어집니다.

 
위에서 중요한 것이  GUI 어플을 위한 Form입니다.
Visual base의 Form과 비슷한데 하여튼  GUI Template로 생각하면 됩니다.
GUI Template를 아래와 같이 만듭니다.

 
Push Button을 두개 넣어 두고 이름을 위와 같이 합니다.
버튼의 정식 이름은 오른쪽에 조그마한 창에 나오는데 이 버튼의 이름을
PB_OpenImage와 PB_Process로 정합니다.

 
이제 이벤트를 추가하면 됩니다.
이벤트는 버튼이 Push되었을때 즉  Click되었을때를 추가하면 됩니다.

 QT에서는  Event를 처리하는 개념을  Slot 을 추가한다고 합니다.
Slot을 추가하기 위해서는 마우스의 버튼 혹은 콘트롤 버튼과 함께 클릭하면 아래와 같은 Pop Up 매뉴가 나옵니다.
여기서  Slot 추가 매뉴 Go to Slot을 선택합니다.


 그럼 아래 창이 나타나는데 여기서 clicked를 추가합니다.

 
그럼 코드에 아래와 같이 나옵니다.

void MainWindow::on_PB_OpenImage_clicked()
{
    
}

같은 방법으로 Process도 만듭니다.

시작시에 말했듯이 이 프로그램은 Image를 읽어들여서 작업하는 프로그램입니다. 이미지를 읽어들여서 저장하기 위해서는 별도의 변수가 필요합니다. 엄밀하게는 이미지를 저장할 공간을 필요로 합니다.

다음과 같이 이미지를 저장할 변수를 추가합니다.


private 공간에 cv::Mat image를 추가합니다.
각각의 버튼이 눌려졌을때의 함수는 아래와 같이 추가를 합니다.

#include <QFileDialog>
...
 
void
MainWindow::on_PB_OpenImage_clicked()
{
    QString filename = QFileDialog::getOpenFileName( this, tr("Open Image") , "." , tr("Image Files (*.png *.jpg * jpeg *.bmp)")) ;
    image = cv::imread(filename.toAscii().data());
    cv::namedWindow("Original Image");
    cv::imshow("Original Image", image);
}

 
그리고 컴파일을 하면 아래와 같이 실행됩니다.
- project 파일에 옵션 추가하는 것은 2번째 글을 참고하시기 바랍니다.

 
  OpenImage를 눌러서 파일 다이얼로그를 띄우고 잘 처리하면 됩니다.

  Process에 대한 함수는 아래와 같이 추가합니다.

void MainWindow::on_PB_Process_clicked()
{
 cv::flip(image , image , 1);
 cv::namedWindow("Output Image");
 cv::imshow("Output Image", image);
}
 

위의 코드는 읽어들인  image를 flip시키는 것입니다.

컴파일과 실행하면 아래와 같이 나옵니다.



주) 항상 함수 하나 추가해보고 테스트 해보는 식으로 하는 것이 나중에 디버깅이 쉬워집니다.

이제 좀더 다음 단계로  다이얼로그 박스에 결과를 내보내는 것을 해보겠습니다.

먼저 Qt에서는 그래픽 데이터를 Label로 출력할 수 있으므로 Dialog에 label을 추가 합니다.



그리고 코드를 다음과 같이 수정합니다.


void MainWindow::on_PB_Process_clicked()
{
 cv::flip(image , image , 1);
 // cv::namedWindow("Output Image");
 // cv::imshow("Output Image", image);

 // Qt Image
 QImage img = QImage (( const unsigned char *) (image.data) , image.cols , image.rows, QImage::Format_RGB888);

// display on label
 ui->label->setPixmap( QPixmap::fromImage(img));
 ui->label->resize(ui->label->pixmap()->size());

}

  이제 실행하면 됩니다.

  

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

3D Noise Reduction algorithm test  (0) 2011.10.05
OpenCV 2.3 Computer vision (4)  (4) 2011.09.14
OpenCV 2.3 Computer vision (2)  (0) 2011.09.05
OpenCV 2.3 Computer vision (1)  (2) 2011.09.05
OpenCV 2.1 맥에서 빌드하기  (0) 2010.09.04
Posted by GUNDAM_IM
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