2

私は約1週間カメラのキャリブレーションに取り組んできました。オンラインの記事やブログで見た例では、Web カメラを使用して画像をキャプチャしています。

しかし、私のシナリオでは、Casio Exilim EX-Z77 というデジタル カメラを使用しています。セット プログラムの引数に画像を追加し、for ループを使用して個別にアクセスします。このようにして、Web カメラの動作を模倣することができました。

正しい歪みと固有値を取得することは可能ですか?? 間違っていたり、誤解がある場合は訂正してください。

これが私のコードに基づいた記事です。以下のコードは、私が作成できたものです。

     int n_boards = 0;
     int board_w;
     int board_h;
     using namespace std;
    int main( int argc, char *argv[] )
    {
 board_w = 5; // Board width in squares
 board_h = 8; // Board height
 n_boards = 16; // Number of boards
 int board_n = board_w * board_h;
 CvSize board_sz = cvSize( board_w, board_h );

 CvMat* image_points        = cvCreateMat( n_boards*board_n, 2, CV_32FC1 );
 CvMat* object_points       = cvCreateMat( n_boards*board_n, 3, CV_32FC1 );
 CvMat* point_counts            = cvCreateMat( n_boards, 1, CV_32SC1 );
 CvMat* intrinsic_matrix        = cvCreateMat( 3, 3, CV_32FC1 );
 CvMat* distortion_coeffs   = cvCreateMat( 5, 1, CV_32FC1 );

 CvPoint2D32f* corners = new CvPoint2D32f[ board_n ];
 int corner_count;
 int successes = 0;
 int step;

      int a;
      for(a =1; a<=n_boards; a++){

   while( successes < n_boards ){

        IplImage *image = cvLoadImage(argv[a]);
        IplImage *gray_image = cvCreateImage( cvGetSize( image ), 8, 1 );

        int found = cvFindChessboardCorners( image, board_sz, corners,
            &corner_count, CV_CALIB_CB_ADAPTIVE_THRESH |         CV_CALIB_CB_FILTER_QUADS );

        // Get subpixel accuracy on those corners
        cvCvtColor( image, gray_image, CV_BGR2GRAY );
        cvFindCornerSubPix( gray_image, corners, corner_count, cvSize( 11, 11 ),
            cvSize( -1, -1 ), cvTermCriteria( CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 30, 0.1 ));

        // Draw it
        cvDrawChessboardCorners( image, board_sz, corners, corner_count, found );
        //cvShowImage( "Calibration", image );

        // If we got a good board, add it to our data
        if( corner_count == board_n ){
            step = successes*board_n;
            for( int i=step, j=0; j < board_n; ++i, ++j ){
                CV_MAT_ELEM( *image_points, float, i, 0 ) = corners[j].x;
                CV_MAT_ELEM( *image_points, float, i, 1 ) = corners[j].y;
                CV_MAT_ELEM( *object_points, float, i, 0 ) = j/board_w;
                CV_MAT_ELEM( *object_points, float, i, 1 ) = j%board_w;
                CV_MAT_ELEM( *object_points, float, i, 2 ) = 0.0f;
            }
            CV_MAT_ELEM( *point_counts, int, successes, 0 ) = board_n;
            successes++;
        }

}
  IplImage *image1 = cvLoadImage(argv[1]);
CvMat* object_points2 = cvCreateMat( successes*board_n, 3, CV_32FC1 );
CvMat* image_points2 = cvCreateMat( successes*board_n, 2, CV_32FC1 );
CvMat* point_counts2 = cvCreateMat( successes, 1, CV_32SC1 );


// Transfer the points into the correct size matrices
for( int i = 0; i < successes*board_n; ++i ){
    CV_MAT_ELEM( *image_points2, float, i, 0) = CV_MAT_ELEM( *image_points, float, i, 0 );
    CV_MAT_ELEM( *image_points2, float, i, 1) = CV_MAT_ELEM( *image_points, float, i, 1 );
    CV_MAT_ELEM( *object_points2, float, i, 0) = CV_MAT_ELEM( *object_points, float, i, 0 );
    CV_MAT_ELEM( *object_points2, float, i, 1) = CV_MAT_ELEM( *object_points, float, i, 1 );
    CV_MAT_ELEM( *object_points2, float, i, 2) = CV_MAT_ELEM( *object_points, float, i, 2 );
}

for( int i=0; i < successes; ++i ){
    CV_MAT_ELEM( *point_counts2, int, i, 0 ) = CV_MAT_ELEM( *point_counts, int, i, 0 );
}
cvReleaseMat( &object_points );
cvReleaseMat( &image_points );
cvReleaseMat( &point_counts );

CV_MAT_ELEM( *intrinsic_matrix, float, 0, 0 ) = 1.0;
CV_MAT_ELEM( *intrinsic_matrix, float, 1, 1 ) = 1.0;

cvCalibrateCamera2( object_points2, image_points2, point_counts2, cvGetSize( image1 ),
    intrinsic_matrix, distortion_coeffs, NULL, NULL, CV_CALIB_FIX_ASPECT_RATIO );

cvSave( "Intrinsics.xml", intrinsic_matrix );
cvSave( "Distortion.xml", distortion_coeffs );

// Example of loading these matrices back in
CvMat *intrinsic = (CvMat*)cvLoad( "Intrinsics.xml" );
CvMat *distortion = (CvMat*)cvLoad( "Distortion.xml" );

IplImage* mapx = cvCreateImage( cvGetSize( image1 ), IPL_DEPTH_32F, 1 );
IplImage* mapy = cvCreateImage( cvGetSize( image1 ), IPL_DEPTH_32F, 1 );
cvInitUndistortMap( intrinsic, distortion, mapx, mapy );

cvNamedWindow( "Undistort" );

while( image1 ){
    IplImage *t = cvCloneImage( image1 );
    cvShowImage( "Calibration", image ); // Show raw image
    cvRemap( t, image1, mapx, mapy ); // undistort image
    cvReleaseImage( &t );
    cvShowImage( "Undistort", image1 ); // Show corrected image

    }
}

return 0;
}

コード ブロック 10.05 と Opencv 2.3.0、Mingw GNU GCC コンパイラを使用しています。

4

1 に答える 1

2

Casio Exilim EX-Z77 などのデジタル カメラは、通常、カメラ内である程度の画像補正を実行します。

このカメラから得られる画像は (レンズの歪みに関して) 既に補正されていると思いますが、この主張を裏付ける参照を見つけることができませんでした.

使用している複数の画像に関しては、実際には、歪みを見つけるために必要なのは1 つだけです。OpenCV を使用したこの手順の詳細については、この回答を確認してください。

編集

画像のステッチについて言及したので、OpenCV はバージョン 2.2 でこの機能のサポートを開始しました

OpenCV 2.2 がリリースされました! このリリースの後、ティーザーはすでにかなり進んでいます:パノラマ スティッチング

この件に関して、この興味深い投稿では、いくつかのソース コードを共有しています。

于 2011-12-22T15:39:17.247 に答える