OpenCV中文网站

 找回密码
 立即注册
搜索
热搜: 安装 配置
查看: 57169|回复: 40

视觉测量与三维重建(二):OpenCV的源代码

[复制链接]
发表于 2011-8-13 14:26:39 | 显示全部楼层 |阅读模式
OpenCV
samples目录下有一些源代码,包括标定,立体标定,立体匹配等等。最近弄了弄,放在这,希望能对新手有所帮助。
之前那篇帖子有人讨论到底用什么硬件,我暂时用的USB摄像头。
我的条件相当艰苦,现在刚开始学,标定用的棋盘格也是自己用纸打印了贴在木板上的,精度低点,但凑合着可以弄弄,相信最开始学这个的童鞋也都是用自己打印的棋盘格。

第一段代码是生成棋盘格的
  1. #include"cv.h"
  2. #include"highgui.h"
  3. #define numx 9
  4. #define numy 9
  5. #define size 200
  6. #define filename "chessboard.jpg"
  7. void main()
  8. {
  9.         IplImage* image=cvCreateImage(cvSize(numx*size,numy*size),8,1);
  10.         ///生成黑白条
  11.         for(int i=0;i<image->height;i++)
  12.         {
  13.                 uchar* data=(uchar*)image->imageData+image->widthStep*i;
  14.                 for(int j=0;j<image->width;j++)
  15.                 {
  16.                         if((j/size)%2==1)
  17.                                 *data=255;
  18.                         else
  19.                                 *data=0;
  20.                         data++;
  21.                 }
  22.         }
  23.         //生成棋盘格
  24.         for(int i=0;i<image->height;i++)
  25.         {
  26.                 if((i/size)%2==1)
  27.                 {       
  28.                         uchar* data=(uchar*)image->imageData+image->widthStep*i;
  29.                         for(int j=0;j<image->width;j++)
  30.                         {
  31.                                 *data=255-*data;
  32.                                 data++;
  33.                         }
  34.                 }
  35.         }
  36.         cvSaveImage(filename,image);
  37. }
复制代码

第二段代码是单目摄像头的标定
  1. #include &quot;cv.h&quot;
  2. #include &quot;highgui.h&quot;
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <time.h>
  6. // example command line (for copy-n-paste):
  7. // calibration -w 6 -h 8 -s 2 -n 10 -o camera.yml -op -oe &#91;<list_of_views.txt>&#93;
  8. /* The list of views may look as following (discard the starting and ending ------ separators):
  9. -------------------
  10. view000.png
  11. view001.png
  12. #view002.png
  13. view003.png
  14. view010.png
  15. one_extra_view.jpg
  16. -------------------
  17. that is, the file will contain 6 lines, view002.png will not be used for calibration,
  18. other ones will be (those, in which the chessboard pattern will be found)
  19. */
  20. enum { DETECTION = 0, CAPTURING = 1, CALIBRATED = 2 };
  21. double compute_reprojection_error( const CvMat* object_points,
  22.         const CvMat* rot_vects, const CvMat* trans_vects,
  23.         const CvMat* camera_matrix, const CvMat* dist_coeffs,
  24.         const CvMat* image_points, const CvMat* point_counts,
  25.         CvMat* per_view_errors )
  26. {
  27.     CvMat* image_points2 = cvCreateMat( image_points->rows,
  28.         image_points->cols, image_points->type );
  29.     int i, image_count = rot_vects->rows, points_so_far = 0;
  30.     double total_err = 0, err;
  31.    
  32.     for( i = 0; i < image_count; i++ )
  33.     {
  34.         CvMat object_points_i, image_points_i, image_points2_i;
  35.         int point_count = point_counts->data.i&#91;i&#93;;
  36.         CvMat rot_vect, trans_vect;
  37.         cvGetCols( object_points, &object_points_i,
  38.             points_so_far, points_so_far + point_count );
  39.         cvGetCols( image_points, &image_points_i,
  40.             points_so_far, points_so_far + point_count );
  41.         cvGetCols( image_points2, &image_points2_i,
  42.             points_so_far, points_so_far + point_count );
  43.         points_so_far += point_count;
  44.         cvGetRow( rot_vects, &rot_vect, i );
  45.         cvGetRow( trans_vects, &trans_vect, i );
  46.         cvProjectPoints2( &object_points_i, &rot_vect, &trans_vect,
  47.                           camera_matrix, dist_coeffs, &image_points2_i,
  48.                           0, 0, 0, 0, 0 );
  49.         err = cvNorm( &image_points_i, &image_points2_i, CV_L1 );
  50.         if( per_view_errors )
  51.             per_view_errors->data.db&#91;i&#93; = err/point_count;
  52.         total_err += err;
  53.     }
  54.    
  55.     cvReleaseMat( &image_points2 );
  56.     return total_err/points_so_far;
  57. }
  58. int run_calibration( CvSeq* image_points_seq, CvSize img_size, CvSize board_size,
  59.                      float square_size, float aspect_ratio, int flags,
  60.                      CvMat* camera_matrix, CvMat* dist_coeffs, CvMat** extr_params,
  61.                      CvMat** reproj_errs, double* avg_reproj_err )
  62. {
  63.     int code;
  64.     int image_count = image_points_seq->total;
  65.     int point_count = board_size.width*board_size.height;
  66.     CvMat* image_points = cvCreateMat( 1, image_count*point_count, CV_32FC2 );
  67.     CvMat* object_points = cvCreateMat( 1, image_count*point_count, CV_32FC3 );
  68.     CvMat* point_counts = cvCreateMat( 1, image_count, CV_32SC1 );
  69.     CvMat rot_vects, trans_vects;
  70.     int i, j, k;
  71.     CvSeqReader reader;
  72.     cvStartReadSeq( image_points_seq, &reader );
  73.     // initialize arrays of points
  74.     for( i = 0; i < image_count; i++ )
  75.     {
  76.         CvPoint2D32f* src_img_pt = (CvPoint2D32f*)reader.ptr;
  77.         CvPoint2D32f* dst_img_pt = ((CvPoint2D32f*)image_points->data.fl) + i*point_count;
  78.         CvPoint3D32f* obj_pt = ((CvPoint3D32f*)object_points->data.fl) + i*point_count;
  79.         for( j = 0; j < board_size.height; j++ )
  80.             for( k = 0; k < board_size.width; k++ )
  81.             {
  82.                 *obj_pt++ = cvPoint3D32f(j*square_size, k*square_size, 0);
  83.                 *dst_img_pt++ = *src_img_pt++;
  84.             }
  85.         CV_NEXT_SEQ_ELEM( image_points_seq->elem_size, reader );
  86.     }
  87.     cvSet( point_counts, cvScalar(point_count) );
  88.     *extr_params = cvCreateMat( image_count, 6, CV_32FC1 );
  89.     cvGetCols( *extr_params, &rot_vects, 0, 3 );
  90.     cvGetCols( *extr_params, &trans_vects, 3, 6 );
  91.     cvZero( camera_matrix );
  92.     cvZero( dist_coeffs );
  93.     if( flags & CV_CALIB_FIX_ASPECT_RATIO )
  94.     {
  95.         camera_matrix->data.db&#91;0&#93; = aspect_ratio;
  96.         camera_matrix->data.db&#91;4&#93; = 1.;
  97.     }
  98.     cvCalibrateCamera2( object_points, image_points, point_counts,
  99.                         img_size, camera_matrix, dist_coeffs,
  100.                         &rot_vects, &trans_vects, flags );
  101.     code = cvCheckArr( camera_matrix, CV_CHECK_QUIET ) &&
  102.         cvCheckArr( dist_coeffs, CV_CHECK_QUIET ) &&
  103.         cvCheckArr( *extr_params, CV_CHECK_QUIET );
  104.     *reproj_errs = cvCreateMat( 1, image_count, CV_64FC1 );
  105.     *avg_reproj_err =
  106.         compute_reprojection_error( object_points, &rot_vects, &trans_vects,
  107.             camera_matrix, dist_coeffs, image_points, point_counts, *reproj_errs );
  108.     cvReleaseMat( &object_points );
  109.     cvReleaseMat( &image_points );
  110.     cvReleaseMat( &point_counts );
  111.     return code;
  112. }
  113. void save_camera_params( const char* out_filename, int image_count, CvSize img_size,
  114.                          CvSize board_size, float square_size,
  115.                          float aspect_ratio, int flags,
  116.                          const CvMat* camera_matrix, CvMat* dist_coeffs,
  117.                          const CvMat* extr_params, const CvSeq* image_points_seq,
  118.                          const CvMat* reproj_errs, double avg_reproj_err )
  119. {
  120.     CvFileStorage* fs = cvOpenFileStorage( out_filename, 0, CV_STORAGE_WRITE );
  121.    
  122.     time_t t;
  123.     time( &t );
  124.     struct tm *t2 = localtime( &t );
  125.     char buf&#91;1024&#93;;
  126.     strftime( buf, sizeof(buf)-1, &quot;%c&quot;, t2 );
  127.     cvWriteString( fs, &quot;calibration_time&quot;, buf );
  128.    
  129.     cvWriteInt( fs, &quot;image_count&quot;, image_count );
  130.     cvWriteInt( fs, &quot;image_width&quot;, img_size.width );
  131.     cvWriteInt( fs, &quot;image_height&quot;, img_size.height );
  132.     cvWriteInt( fs, &quot;board_width&quot;, board_size.width );
  133.     cvWriteInt( fs, &quot;board_height&quot;, board_size.height );
  134.     cvWriteReal( fs, &quot;square_size&quot;, square_size );
  135.    
  136.     if( flags & CV_CALIB_FIX_ASPECT_RATIO )
  137.         cvWriteReal( fs, &quot;aspect_ratio&quot;, aspect_ratio );
  138.     if( flags != 0 )
  139.     {
  140.         sprintf( buf, &quot;flags: %s%s%s%s&quot;,
  141.             flags & CV_CALIB_USE_INTRINSIC_GUESS ? &quot;+use_intrinsic_guess&quot; : &quot;&quot;,
  142.             flags & CV_CALIB_FIX_ASPECT_RATIO ? &quot;+fix_aspect_ratio&quot; : &quot;&quot;,
  143.             flags & CV_CALIB_FIX_PRINCIPAL_POINT ? &quot;+fix_principal_point&quot; : &quot;&quot;,
  144.             flags & CV_CALIB_ZERO_TANGENT_DIST ? &quot;+zero_tangent_dist&quot; : &quot;&quot; );
  145.         cvWriteComment( fs, buf, 0 );
  146.     }
  147.    
  148.     cvWriteInt( fs, &quot;flags&quot;, flags );
  149.     cvWrite( fs, &quot;camera_matrix&quot;, camera_matrix );
  150.     cvWrite( fs, &quot;distortion_coefficients&quot;, dist_coeffs );
  151.     cvWriteReal( fs, &quot;avg_reprojection_error&quot;, avg_reproj_err );
  152.     if( reproj_errs )
  153.         cvWrite( fs, &quot;per_view_reprojection_errors&quot;, reproj_errs );
  154.     if( extr_params )
  155.     {
  156.         cvWriteComment( fs, &quot;a set of 6-tuples (rotation vector + translation vector) for each view&quot;, 0 );
  157.         cvWrite( fs, &quot;extrinsic_parameters&quot;, extr_params );
  158.     }
  159.     if( image_points_seq )
  160.     {
  161.         cvWriteComment( fs, &quot;the array of board corners projections used for calibration&quot;, 0 );
  162.         assert( image_points_seq->total == image_count );
  163.         CvMat* image_points = cvCreateMat( 1, image_count*board_size.width*board_size.height, CV_32FC2 );
  164.         cvCvtSeqToArray( image_points_seq, image_points->data.fl );
  165.         cvWrite( fs, &quot;image_points&quot;, image_points );
  166.         cvReleaseMat( &image_points );
  167.     }
  168.     cvReleaseFileStorage( &fs );
  169. }
  170. int main( int argc, char** argv )
  171. {
  172.     CvSize board_size = {0,0};
  173.     float square_size = 1.f, aspect_ratio = 1.f;
  174.     const char* out_filename = &quot;out_camera_data.yml&quot;;
  175.     const char* input_filename = 0;
  176.     int i, image_count = 10;
  177.     int write_extrinsics = 0, write_points = 0;
  178.     int flags = 0;
  179.     CvCapture* capture = 0;
  180.     FILE* f = 0;
  181.     char imagename&#91;1024&#93;;
  182.     CvMemStorage* storage;
  183.     CvSeq* image_points_seq = 0;
  184.     int elem_size, flip_vertical = 0;
  185.     int delay = 1000;
  186.     clock_t prev_timestamp = 0;
  187.     CvPoint2D32f* image_points_buf = 0;
  188.     CvFont font = cvFont( 1, 1 );
  189.     double _camera&#91;9&#93;, _dist_coeffs&#91;4&#93;;
  190.     CvMat camera = cvMat( 3, 3, CV_64F, _camera );
  191.     CvMat dist_coeffs = cvMat( 1, 4, CV_64F, _dist_coeffs );
  192.     CvMat *extr_params = 0, *reproj_errs = 0;
  193.     double avg_reproj_err = 0;
  194.     int mode = DETECTION;
  195.     int undistort_image = 0;
  196.     CvSize img_size = {0,0};
  197.     const char* live_capture_help =
  198.         &quot;When the live video from camera is used as input, the following hot-keys may be used:\n&quot;
  199.             &quot;  <ESC>, 'q' - quit the program\n&quot;
  200.             &quot;  'g' - start capturing images\n&quot;
  201.             &quot;  'u' - switch undistortion on/off\n&quot;;
  202.     if( argc < 2 )
  203.     {
  204.         printf( &quot;This is a camera calibration sample.\n&quot;
  205.             &quot;Usage: calibration\n&quot;
  206.             &quot;     -w <board_width>         # the number of inner corners per one of board dimension\n&quot;
  207.             &quot;     -h <board_height>        # the number of inner corners per another board dimension\n&quot;
  208.             &quot;     &#91;-n <number_of_frames>&#93;  # the number of frames to use for calibration\n&quot;
  209.             &quot;                              # (if not specified, it will be set to the number\n&quot;
  210.             &quot;                              #  of board views actually available)\n&quot;
  211.             &quot;     &#91;-d <delay>&#93;             # a minimum delay in ms between subsequent attempts to capture a next view\n&quot;
  212.             &quot;                              # (used only for video capturing)\n&quot;
  213.             &quot;     &#91;-s <square_size>&#93;       # square size in some user-defined units (1 by default)\n&quot;
  214.             &quot;     &#91;-o <out_camera_params>&#93; # the output filename for intrinsic &#91;and extrinsic&#93; parameters\n&quot;
  215.             &quot;     &#91;-op&#93;                    # write detected feature points\n&quot;
  216.             &quot;     &#91;-oe&#93;                    # write extrinsic parameters\n&quot;
  217.             &quot;     &#91;-zt&#93;                    # assume zero tangential distortion\n&quot;
  218.             &quot;     &#91;-a <aspect_ratio>&#93;      # fix aspect ratio (fx/fy)\n&quot;
  219.             &quot;     &#91;-p&#93;                     # fix the principal point at the center\n&quot;
  220.             &quot;     &#91;-v&#93;                     # flip the captured images around the horizontal axis\n&quot;
  221.             &quot;     &#91;input_data&#93;             # input data, one of the following:\n&quot;
  222.             &quot;                              #  - text file with a list of the images of the board\n&quot;
  223.             &quot;                              #  - name of video file with a video of the board\n&quot;
  224.             &quot;                              # if input_data not specified, a live view from the camera is used\n&quot;
  225.             &quot;\n&quot; );
  226.         printf( &quot;%s&quot;, live_capture_help );
  227.         return 0;
  228.     }
  229.     for( i = 1; i < argc; i++ )
  230.     {
  231.         const char* s = argv&#91;i&#93;;
  232.         if( strcmp( s, &quot;-w&quot; ) == 0 )
  233.         {
  234.             if( sscanf( argv&#91;++i&#93;, &quot;%u&quot;, &board_size.width ) != 1 || board_size.width <= 0 )
  235.                 return fprintf( stderr, &quot;Invalid board width\n&quot; ), -1;
  236.         }
  237.         else if( strcmp( s, &quot;-h&quot; ) == 0 )
  238.         {
  239.             if( sscanf( argv&#91;++i&#93;, &quot;%u&quot;, &board_size.height ) != 1 || board_size.height <= 0 )
  240.                 return fprintf( stderr, &quot;Invalid board height\n&quot; ), -1;
  241.         }
  242.         else if( strcmp( s, &quot;-s&quot; ) == 0 )
  243.         {
  244.             if( sscanf( argv&#91;++i&#93;, &quot;%f&quot;, &square_size ) != 1 || square_size <= 0 )
  245.                 return fprintf( stderr, &quot;Invalid board square width\n&quot; ), -1;
  246.         }
  247.         else if( strcmp( s, &quot;-n&quot; ) == 0 )
  248.         {
  249.             if( sscanf( argv&#91;++i&#93;, &quot;%u&quot;, &image_count ) != 1 || image_count <= 3 )
  250.                 return printf(&quot;Invalid number of images\n&quot; ), -1;
  251.         }
  252.         else if( strcmp( s, &quot;-a&quot; ) == 0 )
  253.         {
  254.             if( sscanf( argv&#91;++i&#93;, &quot;%f&quot;, &aspect_ratio ) != 1 || aspect_ratio <= 0 )
  255.                 return printf(&quot;Invalid aspect ratio\n&quot; ), -1;
  256.         }
  257.         else if( strcmp( s, &quot;-d&quot; ) == 0 )
  258.         {
  259.             if( sscanf( argv&#91;++i&#93;, &quot;%u&quot;, &delay ) != 1 || delay <= 0 )
  260.                 return printf(&quot;Invalid delay\n&quot; ), -1;
  261.         }
  262.         else if( strcmp( s, &quot;-op&quot; ) == 0 )
  263.         {
  264.             write_points = 1;
  265.         }
  266.         else if( strcmp( s, &quot;-oe&quot; ) == 0 )
  267.         {
  268.             write_extrinsics = 1;
  269.         }
  270.         else if( strcmp( s, &quot;-zt&quot; ) == 0 )
  271.         {
  272.             flags |= CV_CALIB_ZERO_TANGENT_DIST;
  273.         }
  274.         else if( strcmp( s, &quot;-p&quot; ) == 0 )
  275.         {
  276.             flags |= CV_CALIB_FIX_PRINCIPAL_POINT;
  277.         }
  278.         else if( strcmp( s, &quot;-v&quot; ) == 0 )
  279.         {
  280.             flip_vertical = 1;
  281.         }
  282.         else if( strcmp( s, &quot;-o&quot; ) == 0 )
  283.         {
  284.             out_filename = argv&#91;++i&#93;;
  285.         }
  286.         else if( s&#91;0&#93; != '-' )
  287.             input_filename = s;
  288.         else
  289.             return fprintf( stderr, &quot;Unknown option %s&quot;, s ), -1;
  290.     }
  291.     if( input_filename )
  292.     {
  293.         capture = cvCreateFileCapture( input_filename );
  294.         if( !capture )
  295.         {
  296.             f = fopen( input_filename, &quot;rt&quot; );
  297.             if( !f )
  298.                 return fprintf( stderr, &quot;The input file could not be opened\n&quot; ), -1;
  299.             image_count = -1;
  300.         }
  301.         mode = CAPTURING;
  302.     }
  303.     else
  304.         capture = cvCreateCameraCapture(0);
  305.     if( !capture && !f )
  306.         return fprintf( stderr, &quot;Could not initialize video capture\n&quot; ), -2;
  307.     if( capture )
  308.         printf( &quot;%s&quot;, live_capture_help );
  309.     elem_size = board_size.width*board_size.height*sizeof(image_points_buf&#91;0&#93;);
  310.     storage = cvCreateMemStorage( MAX( elem_size*4, 1 << 16 ));
  311.     image_points_buf = (CvPoint2D32f*)cvAlloc( elem_size );
  312.     image_points_seq = cvCreateSeq( 0, sizeof(CvSeq), elem_size, storage );
  313.     cvNamedWindow( &quot;Image View&quot;, 1 );
  314.     for(;;)
  315.     {
  316.         IplImage *view = 0, *view_gray = 0;
  317.         int count = 0, found, blink = 0;
  318.         CvPoint text_origin;
  319.         CvSize text_size = {0,0};
  320.         int base_line = 0;
  321.         char s&#91;100&#93;;
  322.         int key;
  323.         
  324.         if( f && fgets( imagename, sizeof(imagename)-2, f ))
  325.         {
  326.             int l = strlen(imagename);
  327.             if( l > 0 && imagename&#91;l-1&#93; == '\n' )
  328.                 imagename&#91;--l&#93; = '\0';
  329.             if( l > 0 )
  330.             {
  331.                 if( imagename&#91;0&#93; == '#' )
  332.                     continue;
  333.                 view = cvLoadImage( imagename, 1 );
  334.             }
  335.         }
  336.         else if( capture )
  337.         {
  338.             IplImage* view0 = cvQueryFrame( capture );
  339.             if( view0 )
  340.             {
  341.                 view = cvCreateImage( cvGetSize(view0), IPL_DEPTH_8U, view0->nChannels );
  342.                 if( view0->origin == IPL_ORIGIN_BL )
  343.                     cvFlip( view0, view, 0 );
  344.                 else
  345.                     cvCopy( view0, view );
  346.             }
  347.         }
  348.         if( !view )
  349.         {
  350.             if( image_points_seq->total > 0 )
  351.             {
  352.                 image_count = image_points_seq->total;
  353.                 goto calibrate;
  354.             }
  355.             break;
  356.         }
  357.         if( flip_vertical )
  358.             cvFlip( view, view, 0 );
  359.         img_size = cvGetSize(view);
  360.         found = cvFindChessboardCorners( view, board_size,
  361.             image_points_buf, &count, CV_CALIB_CB_ADAPTIVE_THRESH );
  362. #if 1
  363.         // improve the found corners' coordinate accuracy
  364.         view_gray = cvCreateImage( cvGetSize(view), 8, 1 );
  365.         cvCvtColor( view, view_gray, CV_BGR2GRAY );
  366.         cvFindCornerSubPix( view_gray, image_points_buf, count, cvSize(11,11),
  367.             cvSize(-1,-1), cvTermCriteria( CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 30, 0.1 ));
  368.         cvReleaseImage( &view_gray );
  369. #endif
  370.         if( mode == CAPTURING && found && (f || clock() - prev_timestamp > delay*1e-3*CLOCKS_PER_SEC) )
  371.         {
  372.             cvSeqPush( image_points_seq, image_points_buf );
  373.             prev_timestamp = clock();
  374.             blink = !f;
  375. #if 1
  376.             if( capture )
  377.             {
  378.                 sprintf( imagename, &quot;view%03d.png&quot;, image_points_seq->total - 1 );
  379.                 cvSaveImage( imagename, view );
  380.             }
  381. #endif
  382.         }
  383.         cvDrawChessboardCorners( view, board_size, image_points_buf, count, found );
  384.         cvGetTextSize( &quot;100/100&quot;, &font, &text_size, &base_line );
  385.         text_origin.x = view->width - text_size.width - 10;
  386.         text_origin.y = view->height - base_line - 10;
  387.         if( mode == CAPTURING )
  388.         {
  389.             if( image_count > 0 )
  390.                 sprintf( s, &quot;%d/%d&quot;, image_points_seq ? image_points_seq->total : 0, image_count );
  391.             else
  392.                 sprintf( s, &quot;%d/?&quot;, image_points_seq ? image_points_seq->total : 0 );
  393.         }
  394.         else if( mode == CALIBRATED )
  395.             sprintf( s, &quot;Calibrated&quot; );
  396.         else
  397.             sprintf( s, &quot;Press 'g' to start&quot; );
  398.         cvPutText( view, s, text_origin, &font, mode != CALIBRATED ?
  399.                                    CV_RGB(255,0,0) : CV_RGB(0,255,0));
  400.         if( blink )
  401.             cvNot( view, view );
  402.         if( mode == CALIBRATED && undistort_image )
  403.         {
  404.             IplImage* t = cvCloneImage( view );
  405.             cvUndistort2( t, view, &camera, &dist_coeffs );
  406.             cvReleaseImage( &t );
  407.         }
  408.         cvShowImage( &quot;Image View&quot;, view );
  409.         key = cvWaitKey(capture ? 50 : 500);
  410.         if( key == 27 )
  411.             break;
  412.         
  413.         if( key == 'u' && mode == CALIBRATED )
  414.             undistort_image = !undistort_image;
  415.         if( capture && key == 'g' )
  416.         {
  417.             mode = CAPTURING;
  418.             cvClearMemStorage( storage );
  419.             image_points_seq = cvCreateSeq( 0, sizeof(CvSeq), elem_size, storage );
  420.         }
  421.         if( mode == CAPTURING && (unsigned)image_points_seq->total >= (unsigned)image_count )
  422.         {
  423. calibrate:
  424.             cvReleaseMat( &extr_params );
  425.             cvReleaseMat( &reproj_errs );
  426.             int code = run_calibration( image_points_seq, img_size, board_size,
  427.                 square_size, aspect_ratio, flags, &camera, &dist_coeffs, &extr_params,
  428.                 &reproj_errs, &avg_reproj_err );
  429.             // save camera parameters in any case, to catch Inf's/NaN's
  430.             save_camera_params( out_filename, image_count, img_size,
  431.                 board_size, square_size, aspect_ratio, flags,
  432.                 &camera, &dist_coeffs, write_extrinsics ? extr_params : 0,
  433.                 write_points ? image_points_seq : 0, reproj_errs, avg_reproj_err );
  434.             if( code )
  435.                 mode = CALIBRATED;
  436.             else
  437.                 mode = DETECTION;
  438.         }
  439.         if( !view )
  440.             break;
  441.         cvReleaseImage( &view );
  442.     }
  443.     if( capture )
  444.         cvReleaseCapture( &capture );
  445.     if( storage )
  446.         cvReleaseMemStorage( &storage );
  447.     return 0;
  448. }
复制代码
如果使用上面一段代码生成的棋盘格,这里可以用这样的调用方式  calibration -w 8 -h 8 -s 2 -n 10 -o camera.yml -op -oe -p
调试时在Property->Configuration Properties->Debugging->Command Arguments 添加-w 8 -h 8 -s 2 -n 10 -o camera.yml -op -oe -p


第三段代码是立体标定的,我稍微改了一下,让它直接从两个摄像头中读取图像来处理
  1. //!  邮箱:yang3kui@gmail.com       
  2. #include &quot;cv.h&quot;
  3. #include &quot;highgui.h&quot;
  4. #include<iostream>
  5. using namespace std;
  6. /* This is sample from the OpenCV book. The copyright notice is below */
  7. /* *************** License:**************************
  8. Oct. 3, 2008
  9. Right to use this code in any way you want without warrenty, support or any guarentee of it working.
  10. BOOK: It would be nice if you cited it:
  11. Learning OpenCV: Computer Vision with the OpenCV Library
  12. by Gary Bradski and Adrian Kaehler
  13. Published by O'Reilly Media, October 3, 2008
  14. AVAILABLE AT:
  15. http://www.amazon.com/Learning-OpenCV-Computer-Vision-Library/dp/0596516134
  16. Or: http://oreilly.com/catalog/9780596516130/
  17. ISBN-10: 0596516134 or: ISBN-13: 978-0596516130   
  18. OTHER OPENCV SITES:
  19. * The source code is on sourceforge at:
  20. http://sourceforge.net/projects/opencvlibrary/
  21. * The OpenCV wiki page (As of Oct 1, 2008 this is down for changing over servers, but should come back):
  22. http://opencvlibrary.sourceforge.net/
  23. * An active user group is at:
  24. http://tech.groups.yahoo.com/group/OpenCV/
  25. * The minutes of weekly OpenCV development meetings are at:
  26. http://pr.willowgarage.com/wiki/OpenCV
  27. ************************************************** */
  28. #undef _GLIBCXX_DEBUG
  29. #include &quot;cv.h&quot;
  30. #include &quot;cxmisc.h&quot;
  31. #include &quot;highgui.h&quot;
  32. #include <vector>
  33. #include <string>
  34. #include <algorithm>
  35. #include <stdio.h>
  36. #include <ctype.h>
  37. using namespace std;
  38. //
  39. // Given a list of chessboard images, the number of corners (nx, ny)
  40. // on the chessboards, and a flag: useCalibrated for calibrated (0) or
  41. // uncalibrated (1: use cvStereoCalibrate(), 2: compute fundamental
  42. // matrix separately) stereo. Calibrate the cameras and display the
  43. // rectified results along with the computed disparity images.
  44. //
  45. static void
  46. StereoCalib(const char* imageList, int useUncalibrated)
  47. {
  48.         CvRect roi1, roi2;
  49.         int nx = 0, ny = 0;
  50.         int displayCorners = 1;
  51.         int showUndistorted = 1;
  52.         bool isVerticalStereo = false;//OpenCV can handle left-right
  53.         //or up-down camera arrangements
  54.         const int maxScale = 1;
  55.         const float squareSize = 1.f; //Set this to your actual square size
  56.         FILE* f = fopen(imageList, &quot;rt&quot;);
  57.         int i, j, lr, nframes = 0, n, N = 0;
  58.         vector<string> imageNames&#91;2&#93;;
  59.         vector<CvPoint3D32f> objectPoints;
  60.         vector<CvPoint2D32f> points&#91;2&#93;;
  61.         vector<CvPoint2D32f> temp_points&#91;2&#93;;
  62.         vector<int> npoints;
  63.         //    vector<uchar> active&#91;2&#93;;
  64.         int is_found&#91;2&#93; = {0, 0};
  65.         vector<CvPoint2D32f> temp;
  66.         CvSize imageSize = {0,0};
  67.         // ARRAY AND VECTOR STORAGE:
  68.         double M1&#91;3&#93;&#91;3&#93;, M2&#91;3&#93;&#91;3&#93;, D1&#91;5&#93;, D2&#91;5&#93;;
  69.         double R&#91;3&#93;&#91;3&#93;, T&#91;3&#93;, E&#91;3&#93;&#91;3&#93;, F&#91;3&#93;&#91;3&#93;;
  70.         double Q&#91;4&#93;&#91;4&#93;;
  71.         CvMat _M1 = cvMat(3, 3, CV_64F, M1 );
  72.         CvMat _M2 = cvMat(3, 3, CV_64F, M2 );
  73.         CvMat _D1 = cvMat(1, 5, CV_64F, D1 );
  74.         CvMat _D2 = cvMat(1, 5, CV_64F, D2 );
  75.         CvMat matR = cvMat(3, 3, CV_64F, R );
  76.         CvMat matT = cvMat(3, 1, CV_64F, T );
  77.         CvMat matE = cvMat(3, 3, CV_64F, E );
  78.         CvMat matF = cvMat(3, 3, CV_64F, F );
  79.         CvMat matQ = cvMat(4, 4, CV_64FC1, Q);
  80.         char buf&#91;1024&#93;;
  81.         if( displayCorners )
  82.                 cvNamedWindow( &quot;corners&quot;, 1 );
  83.         // READ IN THE LIST OF CHESSBOARDS:
  84.         if( !f )
  85.         {
  86.                 fprintf(stderr, &quot;can not open file %s\n&quot;, imageList );
  87.                 return;
  88.         }
  89.         if( !fgets(buf, sizeof(buf)-3, f) || sscanf(buf, &quot;%d%d&quot;, &nx, &ny) != 2 )
  90.                 return;
  91.         n = nx*ny;
  92.         temp.resize(n);
  93.         temp_points&#91;0&#93;.resize(n);
  94.         temp_points&#91;1&#93;.resize(n);
  95.         for(i=0;;i++)
  96.         {
  97.                 int count = 0, result=0;
  98.                 lr = i % 2;
  99.                 vector<CvPoint2D32f>& pts = temp_points&#91;lr&#93;;//points&#91;lr&#93;;
  100.                 if( !fgets( buf, sizeof(buf)-3, f ))
  101.                         break;
  102.                 size_t len = strlen(buf);
  103.                 while( len > 0 && isspace(buf&#91;len-1&#93;))
  104.                         buf&#91;--len&#93; = '\0';
  105.                 if( buf&#91;0&#93; == '#')
  106.                         continue;
  107.                 IplImage* img = cvLoadImage( buf, 0 );
  108.                 if( !img )
  109.                         break;
  110.                 imageSize = cvGetSize(img);
  111.                 imageNames&#91;lr&#93;.push_back(buf);
  112.                 //FIND CHESSBOARDS AND CORNERS THEREIN:
  113.                 for( int s = 1; s <= maxScale; s++ )
  114.                 {
  115.                         IplImage* timg = img;
  116.                         if( s > 1 )
  117.                         {
  118.                                 timg = cvCreateImage(cvSize(img->width*s,img->height*s),
  119.                                         img->depth, img->nChannels );
  120.                                 cvResize( img, timg, CV_INTER_CUBIC );
  121.                         }
  122.                         result = cvFindChessboardCorners( timg, cvSize(nx, ny),
  123.                                 &temp&#91;0&#93;, &count,
  124.                                 CV_CALIB_CB_ADAPTIVE_THRESH |
  125.                                 CV_CALIB_CB_NORMALIZE_IMAGE);
  126.                         if( timg != img )
  127.                                 cvReleaseImage( &timg );
  128.                         if( result || s == maxScale )
  129.                                 for( j = 0; j < count; j++ )
  130.                                 {
  131.                                         temp&#91;j&#93;.x /= s;
  132.                                         temp&#91;j&#93;.y /= s;
  133.                                 }
  134.                                 if( result )
  135.                                         break;
  136.                 }
  137.                 if( displayCorners )
  138.                 {
  139.                         printf(&quot;%s\n&quot;, buf);
  140.                         IplImage* cimg = cvCreateImage( imageSize, 8, 3 );
  141.                         cvCvtColor( img, cimg, CV_GRAY2BGR );
  142.                         cvDrawChessboardCorners( cimg, cvSize(nx, ny), &temp&#91;0&#93;,
  143.                                 count, result );
  144.                         IplImage* cimg1 = cvCreateImage(cvSize(640, 480), IPL_DEPTH_8U, 3);
  145.                         cvResize(cimg, cimg1);
  146.                         cvShowImage( &quot;corners&quot;, cimg1 );
  147.                         cvReleaseImage( &cimg );
  148.                         cvReleaseImage( &cimg1 );
  149.                         int c = cvWaitKey(1000);
  150.                         if( c == 27 || c == 'q' || c == 'Q' ) //Allow ESC to quit
  151.                                 exit(-1);
  152.                 }
  153.                 else
  154.                         putchar('.');
  155.                 //N = pts.size();
  156.                 //pts.resize(N + n, cvPoint2D32f(0,0));
  157.                 //active&#91;lr&#93;.push_back((uchar)result);
  158.                 is_found&#91;lr&#93; = result > 0 ? 1 : 0;
  159.                 //assert( result != 0 );
  160.                 if( result )
  161.                 {
  162.                         //Calibration will suffer without subpixel interpolation
  163.                         cvFindCornerSubPix( img, &temp&#91;0&#93;, count,
  164.                                 cvSize(11, 11), cvSize(-1,-1),
  165.                                 cvTermCriteria(CV_TERMCRIT_ITER+CV_TERMCRIT_EPS,
  166.                                 30, 0.01) );
  167.                         copy( temp.begin(), temp.end(), pts.begin() );
  168.                 }
  169.                 cvReleaseImage( &img );
  170.                 if(lr)
  171.                 {
  172.                         if(is_found&#91;0&#93; == 1 && is_found&#91;1&#93; == 1)
  173.                         {
  174.                                 assert(temp_points&#91;0&#93;.size() == temp_points&#91;1&#93;.size());
  175.                                 int current_size = points&#91;0&#93;.size();
  176.                                 points&#91;0&#93;.resize(current_size + temp_points&#91;0&#93;.size(), cvPoint2D32f(0.0, 0.0));
  177.                                 points&#91;1&#93;.resize(current_size + temp_points&#91;1&#93;.size(), cvPoint2D32f(0.0, 0.0));
  178.                                 copy(temp_points&#91;0&#93;.begin(), temp_points&#91;0&#93;.end(), points&#91;0&#93;.begin() + current_size);
  179.                                 copy(temp_points&#91;1&#93;.begin(), temp_points&#91;1&#93;.end(), points&#91;1&#93;.begin() + current_size);
  180.                                 nframes++;
  181.                                 printf(&quot;Pair successfully detected...\n&quot;);
  182.                         }
  183.                         is_found&#91;0&#93; = 0;
  184.                         is_found&#91;1&#93; = 0;
  185.                 }
  186.         }
  187.         fclose(f);
  188.         printf(&quot;\n&quot;);
  189.         // HARVEST CHESSBOARD 3D OBJECT POINT LIST:
  190.         objectPoints.resize(nframes*n);
  191.         for( i = 0; i < ny; i++ )
  192.                 for( j = 0; j < nx; j++ )
  193.                         objectPoints&#91;i*nx + j&#93; =
  194.                         cvPoint3D32f(i*squareSize, j*squareSize, 0);
  195.         for( i = 1; i < nframes; i++ )
  196.                 copy( objectPoints.begin(), objectPoints.begin() + n,
  197.                 objectPoints.begin() + i*n );
  198.         npoints.resize(nframes,n);
  199.         N = nframes*n;
  200.         CvMat _objectPoints = cvMat(1, N, CV_32FC3, &objectPoints&#91;0&#93; );
  201.         CvMat _imagePoints1 = cvMat(1, N, CV_32FC2, &points&#91;0&#93;&#91;0&#93; );
  202.         CvMat _imagePoints2 = cvMat(1, N, CV_32FC2, &points&#91;1&#93;&#91;0&#93; );
  203.         CvMat _npoints = cvMat(1, npoints.size(), CV_32S, &npoints&#91;0&#93; );
  204.         cvSetIdentity(&_M1);
  205.         cvSetIdentity(&_M2);
  206.         cvZero(&_D1);
  207.         cvZero(&_D2);
  208.         // CALIBRATE THE STEREO CAMERAS
  209.         printf(&quot;Running stereo calibration ...&quot;);
  210.         fflush(stdout);
  211.         cvStereoCalibrate( &_objectPoints, &_imagePoints1,
  212.                 &_imagePoints2, &_npoints,
  213.                 &_M1, &_D1, &_M2, &_D2,
  214.                 imageSize, &matR, &matT, &matE, &matF,
  215.                 cvTermCriteria(CV_TERMCRIT_ITER+
  216.                 CV_TERMCRIT_EPS, 100, 1e-5),
  217.                 CV_CALIB_FIX_ASPECT_RATIO +
  218.                 CV_CALIB_ZERO_TANGENT_DIST +
  219.                 CV_CALIB_SAME_FOCAL_LENGTH +
  220.                 CV_CALIB_FIX_K3);
  221.         printf(&quot; done\n&quot;);
  222.         // CALIBRATION QUALITY CHECK
  223.         // because the output fundamental matrix implicitly
  224.         // includes all the output information,
  225.         // we can check the quality of calibration using the
  226.         // epipolar geometry constraint: m2^t*F*m1=0
  227.         vector<CvPoint3D32f> lines&#91;2&#93;;
  228.         points&#91;0&#93;.resize(N);
  229.         points&#91;1&#93;.resize(N);
  230.         _imagePoints1 = cvMat(1, N, CV_32FC2, &points&#91;0&#93;&#91;0&#93; );
  231.         _imagePoints2 = cvMat(1, N, CV_32FC2, &points&#91;1&#93;&#91;0&#93; );
  232.         lines&#91;0&#93;.resize(N);
  233.         lines&#91;1&#93;.resize(N);
  234.         CvMat _L1 = cvMat(1, N, CV_32FC3, &lines&#91;0&#93;&#91;0&#93;);
  235.         CvMat _L2 = cvMat(1, N, CV_32FC3, &lines&#91;1&#93;&#91;0&#93;);
  236.         //Always work in undistorted space
  237.         cvUndistortPoints( &_imagePoints1, &_imagePoints1,
  238.                 &_M1, &_D1, 0, &_M1 );
  239.         cvUndistortPoints( &_imagePoints2, &_imagePoints2,
  240.                 &_M2, &_D2, 0, &_M2 );
  241.         cvComputeCorrespondEpilines( &_imagePoints1, 1, &matF, &_L1 );
  242.         cvComputeCorrespondEpilines( &_imagePoints2, 2, &matF, &_L2 );
  243.         double avgErr = 0;
  244.         for( i = 0; i < N; i++ )
  245.         {
  246.                 double err = fabs(points&#91;0&#93;&#91;i&#93;.x*lines&#91;1&#93;&#91;i&#93;.x +
  247.                         points&#91;0&#93;&#91;i&#93;.y*lines&#91;1&#93;&#91;i&#93;.y + lines&#91;1&#93;&#91;i&#93;.z)
  248.                         + fabs(points&#91;1&#93;&#91;i&#93;.x*lines&#91;0&#93;&#91;i&#93;.x +
  249.                         points&#91;1&#93;&#91;i&#93;.y*lines&#91;0&#93;&#91;i&#93;.y + lines&#91;0&#93;&#91;i&#93;.z);
  250.                 avgErr += err;
  251.         }
  252.         printf( &quot;avg err = %g\n&quot;, avgErr/(nframes*n) );
  253.         // save intrinsic parameters
  254.         CvFileStorage* fstorage = cvOpenFileStorage(&quot;intrinsics.yml&quot;, NULL, CV_STORAGE_WRITE);
  255.         cvWrite(fstorage, &quot;M1&quot;, &_M1);
  256.         cvWrite(fstorage, &quot;D1&quot;, &_D1);
  257.         cvWrite(fstorage, &quot;M2&quot;, &_M2);
  258.         cvWrite(fstorage, &quot;D2&quot;, &_D2);
  259.         cvReleaseFileStorage(&fstorage);
  260.         //COMPUTE AND DISPLAY RECTIFICATION
  261.         if( showUndistorted )
  262.         {
  263.                 CvMat* mx1 = cvCreateMat( imageSize.height,
  264.                         imageSize.width, CV_32F );
  265.                 CvMat* my1 = cvCreateMat( imageSize.height,
  266.                         imageSize.width, CV_32F );
  267.                 CvMat* mx2 = cvCreateMat( imageSize.height,
  268.                         imageSize.width, CV_32F );
  269.                 CvMat* my2 = cvCreateMat( imageSize.height,
  270.                         imageSize.width, CV_32F );
  271.                 CvMat* img1r = cvCreateMat( imageSize.height,
  272.                         imageSize.width, CV_8U );
  273.                 CvMat* img2r = cvCreateMat( imageSize.height,
  274.                         imageSize.width, CV_8U );
  275.                 CvMat* disp = cvCreateMat( imageSize.height,
  276.                         imageSize.width, CV_16S );
  277.                 double R1&#91;3&#93;&#91;3&#93;, R2&#91;3&#93;&#91;3&#93;, P1&#91;3&#93;&#91;4&#93;, P2&#91;3&#93;&#91;4&#93;;
  278.                 CvMat _R1 = cvMat(3, 3, CV_64F, R1);
  279.                 CvMat _R2 = cvMat(3, 3, CV_64F, R2);
  280.                 // IF BY CALIBRATED (BOUGUET'S METHOD)
  281.                 if( useUncalibrated == 0 )
  282.                 {
  283.                         CvMat _P1 = cvMat(3, 4, CV_64F, P1);
  284.                         CvMat _P2 = cvMat(3, 4, CV_64F, P2);
  285.                         cvStereoRectify( &_M1, &_M2, &_D1, &_D2, imageSize,
  286.                                 &matR, &matT,
  287.                                 &_R1, &_R2, &_P1, &_P2, &matQ,
  288.                                 CV_CALIB_ZERO_DISPARITY,
  289.                                 1, imageSize, &roi1, &roi2);
  290.                         CvFileStorage* file = cvOpenFileStorage(&quot;extrinsics.yml&quot;, NULL, CV_STORAGE_WRITE);
  291.                         cvWrite(file, &quot;R&quot;, &matR);
  292.                         cvWrite(file, &quot;T&quot;, &matT);   
  293.                         cvWrite(file, &quot;R1&quot;, &_R1);
  294.                         cvWrite(file, &quot;R2&quot;, &_R2);
  295.                         cvWrite(file, &quot;P1&quot;, &_P1);   
  296.                         cvWrite(file, &quot;P2&quot;, &_P2);   
  297.                         cvWrite(file, &quot;Q&quot;, &matQ);
  298.                         cvReleaseFileStorage(&file);
  299.                         isVerticalStereo = fabs(P2&#91;1&#93;&#91;3&#93;) > fabs(P2&#91;0&#93;&#91;3&#93;);
  300.                         if(!isVerticalStereo)
  301.                                 roi2.x += imageSize.width;
  302.                         else
  303.                                 roi2.y += imageSize.height;
  304.                         //Precompute maps for cvRemap()
  305.                         cvInitUndistortRectifyMap(&_M1,&_D1,&_R1,&_P1,mx1,my1);
  306.                         cvInitUndistortRectifyMap(&_M2,&_D2,&_R2,&_P2,mx2,my2);
  307.                 }
  308.                 //OR ELSE HARTLEY'S METHOD
  309.                 else if( useUncalibrated == 1 || useUncalibrated == 2 )
  310.                         // use intrinsic parameters of each camera, but
  311.                         // compute the rectification transformation directly
  312.                         // from the fundamental matrix
  313.                 {
  314.                         double H1&#91;3&#93;&#91;3&#93;, H2&#91;3&#93;&#91;3&#93;, iM&#91;3&#93;&#91;3&#93;;
  315.                         CvMat _H1 = cvMat(3, 3, CV_64F, H1);
  316.                         CvMat _H2 = cvMat(3, 3, CV_64F, H2);
  317.                         CvMat _iM = cvMat(3, 3, CV_64F, iM);
  318.                         //Just to show you could have independently used F
  319.                         if( useUncalibrated == 2 )
  320.                                 cvFindFundamentalMat( &_imagePoints1,
  321.                                 &_imagePoints2, &matF);
  322.                         cvStereoRectifyUncalibrated( &_imagePoints1,
  323.                                 &_imagePoints2, &matF,
  324.                                 imageSize,
  325.                                 &_H1, &_H2, 3);
  326.                         cvInvert(&_M1, &_iM);
  327.                         cvMatMul(&_H1, &_M1, &_R1);
  328.                         cvMatMul(&_iM, &_R1, &_R1);
  329.                         cvInvert(&_M2, &_iM);
  330.                         cvMatMul(&_H2, &_M2, &_R2);
  331.                         cvMatMul(&_iM, &_R2, &_R2);
  332.                         //Precompute map for cvRemap()
  333.                         cvInitUndistortRectifyMap(&_M1,&_D1,&_R1,&_M1,mx1,my1);
  334.                         cvInitUndistortRectifyMap(&_M2,&_D1,&_R2,&_M2,mx2,my2);
  335.                 }
  336.                 else
  337.                         assert(0);
  338.                 cvReleaseMat( &mx1 );
  339.                 cvReleaseMat( &my1 );
  340.                 cvReleaseMat( &mx2 );
  341.                 cvReleaseMat( &my2 );
  342.                 cvReleaseMat( &img1r );
  343.                 cvReleaseMat( &img2r );
  344.                 cvReleaseMat( &disp );
  345.         }
  346. }
  347. void error(int level,char * msg)
  348. {
  349.         switch(level)
  350.         {
  351.                 case 1:
  352.                         ///严重错误
  353.                         cout<<msg<<endl;
  354.                         cout<<&quot;这是一个严重错误,程序将终止运行\n&quot;
  355.                                 <<&quot;按任意键退出&quot;
  356.                                 <<endl;
  357.                         cin.get();
  358.                         break;
  359.                 case 2:
  360.                         //警告
  361.                         cout<<&quot;警告:&quot;<<msg<<endl;
  362.                         break;
  363.                 case 3:
  364.                         ///信息
  365.                         cout<<msg<<endl;
  366.                         break;
  367.                 default:
  368.                         cout<<msg<<endl;
  369.                         cout<<&quot;这是一个级别未知的警告信息&quot;<<endl;
  370.                         break;
  371.         }
  372. }
  373. void main()
  374. {
  375.         cout<<&quot;这是摄像机双目标定程序&quot;<<endl;
  376.         IplImage * leftimg,* rightimg,*image;
  377.         CvCapture *leftcap=NULL;
  378.         CvCapture *rightcap=NULL;
  379.         leftcap=cvCreateCameraCapture(1);
  380.         rightcap=cvCreateCameraCapture(0);
  381.         image=cvQueryFrame(leftcap);\
  382.                 ///左右两个照片空间的申请
  383.         leftimg=cvCloneImage(image);
  384.         rightimg=cvCloneImage(image);
  385.         if(leftcap==NULL||rightcap==NULL)
  386.         {
  387.                 error(1,&quot;有一个摄像头无法打开&quot;);
  388.                 return;
  389.         }
  390.         cvNamedWindow(&quot;left&quot;,1);
  391.         cvNamedWindow(&quot;right&quot;,1);
  392.         int index=0;///当前是第几张
  393.         int total=10;///总的照片的数量
  394.         char* basename1=&quot;jpgleft&quot;;
  395.         char* basename2=&quot;jpgright&quot;;
  396.         char  filename&#91;100&#93;;
  397.         FILE* file=fopen(&quot;filename.txt&quot;,&quot;wt&quot;);
  398.         char* buf=&quot;8 8\n&quot;;
  399.         fwrite(buf,1,strlen(buf),file);
  400.        
  401.         while(1)
  402.         {
  403.                 image=cvQueryFrame(leftcap);
  404.                 cvCopy(image,leftimg);
  405.                 image=cvQueryFrame(rightcap);
  406.                 cvCopy(image,rightimg);
  407.                 cvShowImage(&quot;left&quot;,leftimg);
  408.                 cvShowImage(&quot;right&quot;,rightimg);
  409.                 char ch=cvWaitKey(27);
  410.                 if(ch=='e')
  411.                 {
  412.                         //正常退出
  413.                         break;
  414.                 }
  415.                 else if(ch==' ')
  416.                 {
  417.                         //拍取照片,并处理之
  418.                         cout<<&quot;正在采集第&quot;<<index+1<<&quot;对图片,一共需要采集&quot;<<total<<&quot;对图片。&quot;<<endl;
  419.                         char *temp=&quot;\n&quot;;
  420.                         sprintf_s(filename,100,&quot;%s%d.jpg&quot;,basename1,index);
  421.                        
  422.                        
  423.                         cvSaveImage(filename,leftimg);
  424.                         fwrite(filename,1,strlen(filename),file);
  425.                         fwrite(temp,1,strlen(temp),file);
  426.                         sprintf_s(filename,100,&quot;%s%d.jpg&quot;,basename2,index);
  427.                        
  428.                         cvSaveImage(filename,rightimg);
  429.                         fwrite(filename,1,strlen(filename),file);
  430.                         fwrite(temp,1,strlen(temp),file);
  431.                         index++;
  432.                 }
  433.                 if(index==total)
  434.                         break;
  435.         }
  436.         fclose(file);
  437.         cout<<&quot;开始双目标定&quot;<<endl;
  438.         StereoCalib(&quot;filename.txt&quot;,0);
  439.         cout<<&quot;标定已经完成,内参数保存在intrinsic.yml文件中,外参数保存在extrinsic.yml文件中!\n按任意键结束程序。&quot;<<endl;
  440.         return;
  441. }
复制代码


第四段代码是立体匹配
  1. /*
  2. *  stereo_match.cpp
  3. *  calibration
  4. *
  5. *  Created by Victor  Eruhimov on 1/18/10.
  6. *  Copyright 2010 Argus Corp. All rights reserved.
  7. *
  8. */
  9. #include <cv.h>
  10. #include <highgui.h>
  11. #include <stdio.h>
  12. using namespace cv;
  13. void saveXYZ(const char* filename, const Mat& mat)
  14. {
  15.         const double max_z = 1.0e4;
  16.         FILE* fp = fopen(filename, &quot;wt&quot;);
  17.         fprintf(fp, &quot;\&quot;X\&quot;        \&quot;Y\&quot;        \&quot;Z\&quot;\n&quot;);
  18.         for(int y = 0; y < mat.rows; y++)
  19.         {
  20.                 for(int x = 0; x < mat.cols; x++)
  21.                 {
  22.                         Vec3f point = mat.at<Vec3f>(y, x);
  23.                         if(fabs(point&#91;2&#93; - max_z) < FLT_EPSILON || fabs(point&#91;2&#93;) > max_z) continue;
  24.                         fprintf(fp, &quot;%f\t%f\t%f\n&quot;, point&#91;0&#93;*1000, point&#91;1&#93;*1000, point&#91;2&#93;*1000);
  25.                 }
  26.         }
  27.         fclose(fp);
  28. }
  29. void print_help()
  30. {
  31.         printf(&quot;Usage: stereo_match <left_image> <right_image> &#91;--algorithm=bm|sgbm|hh&#93; &#91;--blocksize=<block_size>&#93;\n&quot;
  32.                 &quot;&#91;--max-disparity=<max_disparity>&#93; &#91;-i <intrinsic_filename>&#93; &#91;-e <extrinsic_filename>&#93;\n&quot;
  33.                 &quot;&#91;--no-display&#93; &#91;-o <disparity_image>&#93; &#91;-p <point_cloud_file>&#93;\n&quot;);
  34. }
  35. int main(int argc, char** argv)
  36. {
  37.         const char* algorithm_opt = &quot;--algorithm=&quot;;
  38.         const char* maxdisp_opt = &quot;--max-disparity=&quot;;
  39.         const char* blocksize_opt = &quot;--blocksize=&quot;;
  40.         const char* nodisplay_opt = &quot;--no-display=&quot;;
  41.         //print_help();
  42.         if(argc < 3)
  43.         {
  44.                 print_help();
  45.                 return 0;
  46.         }
  47.         const char* img1_filename = 0;
  48.         const char* img2_filename = 0;
  49.         const char* intrinsic_filename = 0;
  50.         const char* extrinsic_filename = 0;
  51.         const char* disparity_filename = 0;
  52.         const char* point_cloud_filename = 0;
  53.         enum { STEREO_BM=0, STEREO_SGBM=1, STEREO_HH=2 };
  54.         int alg = STEREO_SGBM;
  55.         int SADWindowSize = 0, numberOfDisparities = 0;
  56.         bool no_display = false;
  57.         StereoBM bm;
  58.         StereoSGBM sgbm;
  59.         for( int i = 1; i < argc; i++ )
  60.         {
  61.                 if( argv&#91;i&#93;&#91;0&#93; != '-' )
  62.                 {
  63.                         if( !img1_filename )
  64.                                 img1_filename = argv&#91;i&#93;;
  65.                         else
  66.                                 img2_filename = argv&#91;i&#93;;
  67.                 }
  68.                 else if( strncmp(argv&#91;i&#93;, algorithm_opt, strlen(algorithm_opt)) == 0 )
  69.                 {
  70.                         char* _alg = argv&#91;i&#93; + strlen(algorithm_opt);
  71.                         alg = strcmp(_alg, &quot;bm&quot;) == 0 ? STEREO_BM :
  72.                                 strcmp(_alg, &quot;sgbm&quot;) == 0 ? STEREO_SGBM :
  73.                                 strcmp(_alg, &quot;hh&quot;) == 0 ? STEREO_HH : -1;
  74.                         if( alg < 0 )
  75.                         {
  76.                                 printf(&quot;Command-line parameter error: Unknown stereo algorithm\n\n&quot;);
  77.                                 print_help();
  78.                                 return -1;
  79.                         }
  80.                 }
  81.                 else if( strncmp(argv&#91;i&#93;, maxdisp_opt, strlen(maxdisp_opt)) == 0 )
  82.                 {
  83.                         if( sscanf( argv&#91;i&#93; + strlen(maxdisp_opt), &quot;%d&quot;, &numberOfDisparities ) != 1 ||
  84.                                 numberOfDisparities < 1 || numberOfDisparities % 16 != 0 )
  85.                         {
  86.                                 printf(&quot;Command-line parameter error: The max disparity (--maxdisparity=<...>) must be a positive integer divisible by 16\n&quot;);
  87.                                 print_help();
  88.                                 return -1;
  89.                         }
  90.                 }
  91.                 else if( strncmp(argv&#91;i&#93;, blocksize_opt, strlen(blocksize_opt)) == 0 )
  92.                 {
  93.                         if( sscanf( argv&#91;i&#93; + strlen(blocksize_opt), &quot;%d&quot;, &SADWindowSize ) != 1 ||
  94.                                 SADWindowSize < 1 || SADWindowSize % 2 != 1 )
  95.                         {
  96.                                 printf(&quot;Command-line parameter error: The block size (--blocksize=<...>) must be a positive odd number\n&quot;);
  97.                                 return -1;
  98.                         }
  99.                 }
  100.                 else if( strcmp(argv&#91;i&#93;, nodisplay_opt) == 0 )
  101.                         no_display = true;
  102.                 else if( strcmp(argv&#91;i&#93;, &quot;-i&quot; ) == 0 )
  103.                         intrinsic_filename = argv&#91;++i&#93;;
  104.                 else if( strcmp(argv&#91;i&#93;, &quot;-e&quot; ) == 0 )
  105.                         extrinsic_filename = argv&#91;++i&#93;;
  106.                 else if( strcmp(argv&#91;i&#93;, &quot;-o&quot; ) == 0 )
  107.                         disparity_filename = argv&#91;++i&#93;;
  108.                 else if( strcmp(argv&#91;i&#93;, &quot;-p&quot; ) == 0 )
  109.                         point_cloud_filename = argv&#91;++i&#93;;
  110.                 else
  111.                 {
  112.                         printf(&quot;Command-line parameter error: unknown option %s\n&quot;, argv&#91;i&#93;);
  113.                         return -1;
  114.                 }
  115.         }
  116.         if( !img1_filename || !img2_filename )
  117.         {
  118.                 printf(&quot;Command-line parameter error: both left and right images must be specified\n&quot;);
  119.                 return -1;
  120.         }
  121.         if( (intrinsic_filename != 0) ^ (extrinsic_filename != 0) )
  122.         {
  123.                 printf(&quot;Command-line parameter error: either both intrinsic and extrinsic parameters must be specified, or none of them (when the stereo pair is already rectified)\n&quot;);
  124.                 return -1;
  125.         }
  126.         if( extrinsic_filename == 0 && point_cloud_filename )
  127.         {
  128.                 printf(&quot;Command-line parameter error: extrinsic and intrinsic parameters must be specified to compute the point cloud\n&quot;);
  129.                 return -1;
  130.         }
  131.         int color_mode = alg == STEREO_BM ? 0 : -1;
  132.         Mat img1 = imread(img1_filename, color_mode);
  133.         Mat img2 = imread(img2_filename, color_mode);
  134.         Size img_size = img1.size();
  135.         Rect roi1, roi2;
  136.         Mat Q;
  137. //        +                intrinsic_filename,        0x001f4e9e &quot;intrinsics.yml&quot;        const char *
  138.         if( intrinsic_filename )
  139.         {
  140.                 // reading intrinsic parameters
  141.                 FileStorage fs(intrinsic_filename,CV_STORAGE_READ);
  142.                 if(!fs.isOpened())
  143.                 {
  144.                         printf(&quot;Failed to open file %s\n&quot;, intrinsic_filename);
  145.                         return -1;
  146.                 }
  147.                 Mat M1, D1, M2, D2;
  148.                 fs&#91;&quot;M1&quot;&#93; >> M1;
  149.                 fs&#91;&quot;D1&quot;&#93; >> D1;
  150.                 fs&#91;&quot;M2&quot;&#93; >> M2;
  151.                 fs&#91;&quot;D2&quot;&#93; >> D2;
  152.                 fs.open(extrinsic_filename, CV_STORAGE_READ);
  153.                 if(!fs.isOpened())
  154.                 {
  155.                         printf(&quot;Failed to open file %s\n&quot;, extrinsic_filename);
  156.                         return -1;
  157.                 }
  158.                 Mat R, T, R1, P1, R2, P2;
  159.                 fs&#91;&quot;R&quot;&#93; >> R;
  160.                 fs&#91;&quot;T&quot;&#93; >> T;
  161.                 stereoRectify( M1, D1, M2, D2, img_size, R, T, R1, R2, P1, P2, Q, -1, img_size, &roi1, &roi2 );
  162.                 Mat map11, map12, map21, map22;
  163.                 initUndistortRectifyMap(M1, D1, R1, P1, img_size, CV_16SC2, map11, map12);
  164.                 initUndistortRectifyMap(M2, D2, R2, P2, img_size, CV_16SC2, map21, map22);
  165.                 Mat img1r, img2r;
  166.                 remap(img1, img1r, map11, map12, INTER_LINEAR);
  167.                 remap(img2, img2r, map21, map22, INTER_LINEAR);
  168.                 img1 = img1r;
  169.                 img2 = img2r;
  170.         }
  171.         numberOfDisparities = numberOfDisparities > 0 ? numberOfDisparities : img_size.width/8;
  172.         bm.state->roi1 = roi1;
  173.         bm.state->roi2 = roi2;
  174.         bm.state->preFilterCap = 31;
  175.         bm.state->SADWindowSize = SADWindowSize > 0 ? SADWindowSize : 9;
  176.         bm.state->minDisparity = 0;
  177.         bm.state->numberOfDisparities = numberOfDisparities;
  178.         bm.state->textureThreshold = 10;
  179.         bm.state->uniquenessRatio = 15;
  180.         bm.state->speckleWindowSize = 100;
  181.         bm.state->speckleRange = 32;
  182.         bm.state->disp12MaxDiff = 1;
  183.         sgbm.preFilterCap = 63;
  184.         sgbm.SADWindowSize = SADWindowSize > 0 ? SADWindowSize : 3;
  185.         int cn = img1.channels();
  186.         sgbm.P1 = 8*cn*sgbm.SADWindowSize*sgbm.SADWindowSize;
  187.         sgbm.P2 = 32*cn*sgbm.SADWindowSize*sgbm.SADWindowSize;
  188.         sgbm.minDisparity = 0;
  189.         sgbm.numberOfDisparities = numberOfDisparities;
  190.         sgbm.uniquenessRatio = 10;
  191.         sgbm.speckleWindowSize = bm.state->speckleWindowSize;
  192.         sgbm.speckleRange = bm.state->speckleRange;
  193.         sgbm.disp12MaxDiff = 1;
  194.         sgbm.fullDP = alg == STEREO_HH;
  195.         Mat disp, disp8;
  196.         //Mat img1p, img2p, dispp;
  197.         //copyMakeBorder(img1, img1p, 0, 0, numberOfDisparities, 0, IPL_BORDER_REPLICATE);
  198.         //copyMakeBorder(img2, img2p, 0, 0, numberOfDisparities, 0, IPL_BORDER_REPLICATE);
  199. ;
  200.         int64 t = getTickCount();
  201.         if( alg == STEREO_BM)
  202.                 bm(img1, img2, disp);
  203.         else
  204.                 sgbm(img1, img2, disp);
  205.         t = getTickCount() - t;
  206.         printf(&quot;Time elapsed: %fms\n&quot;, t*1000/getTickFrequency());
  207.         //disp = dispp.colRange(numberOfDisparities, img1p.cols);
  208.         disp.convertTo(disp8, CV_8U, 255/(numberOfDisparities*16.));
  209.         if( !no_display )
  210.         {
  211.                 namedWindow(&quot;left&quot;, 1);
  212.                 imshow(&quot;left&quot;, img1);
  213.                 namedWindow(&quot;right&quot;, 1);
  214.                 imshow(&quot;right&quot;, img2);
  215.                 namedWindow(&quot;disparity&quot;, 0);
  216.                 imshow(&quot;disparity&quot;, disp8);
  217.                 printf(&quot;press any key to continue...&quot;);
  218.                 fflush(stdout);
  219.                 waitKey();
  220.                 printf(&quot;\n&quot;);
  221.         }
  222.         if(disparity_filename)
  223.                 imwrite(disparity_filename, disp8);
  224.         if(point_cloud_filename)
  225.         {
  226.                 printf(&quot;storing the point cloud...&quot;);
  227.                 fflush(stdout);
  228.                 Mat xyz;
  229.                 reprojectImageTo3D(disp, xyz, Q, true);
  230.                 saveXYZ(point_cloud_filename, xyz);
  231.                 printf(&quot;\n&quot;);
  232.         }
  233.         return 0;
  234. }
  235. ////注意此处要连接 ---d.lib,不然filestorage打不开文件。不知道哪儿的问题
复制代码
如果要输出视差图和点云,需要在调试时设置Property->Configuration Properties->Debugging->Command Arguments
我是这样设置的jpgleft0.jpg jpgright0.jpg --algorithm=bm --blocksize=7 --max-disparity=96 -i intrinsics.yml -e extrinsics.yml  -o depth.jpg -p point.xyz

立体标定和立体匹配事实上是学习opencv这本书上的一段代码。在例子中被强行拆为了两个部分。

这一段时间除了折腾这些代码,还好好的学习了一下立体视觉的相关理论知识,如果有时间,再整理一篇发出来。个人感觉要用立体视觉来做测量,就软件而言最影响精度的部分,其实是匹配。
建了一个QQ群,欢迎计算机视觉这一个行业的从业者加入。无论你是在学校还是已经工作,无论你是新手还是大牛,无论你是做技术还是已经转型,我都真诚欢迎你的加入,我们都交流,才能共同进步。
群号:130541036(此群已满 请加194369242)

另外,我想买一组好一点的摄像头,平行的那种,大家有没有什么推荐的啊?
回复

使用道具 举报

发表于 2011-8-13 14:44:06 | 显示全部楼层

视觉测量与三维重建(二):OpenCV的源代码

看起来不错,good luck。
给你建议几个我写的关于stereo vision的帖子,希望有帮助哦。

[HQ]如何研究双目视觉STEREO VISION: <!-- l --><a class=\"postlink-local\" href=\"http://www.opencv.org.cn/forum/viewtopic.php?f=1&t=14542\">viewtopic.php?f=1&t=14542</a><!-- l -->
[HQ]OpenCV双目视觉Stereo算法实现源码分享 VS2008和Xcode: <!-- l --><a class=\"postlink-local\" href=\"http://www.opencv.org.cn/forum/viewtopic.php?f=1&t=8305\">viewtopic.php?f=1&t=8305</a><!-- l -->
[HQ]双目视觉Stereo Vision中的cvFindStereoCorrespondenceBM使用范例: <!-- l --><a class=\"postlink-local\" href=\"http://www.opencv.org.cn/forum/viewtopic.php?f=1&t=14239\">viewtopic.php?f=1&t=14239</a><!-- l -->
[HQ]相机标定camera calibration中的cvFindChessboardCorners使用范例:http://www.opencv.org.cn/forum/viewtopic.php?f=1&t=14214
回复 支持 反对

使用道具 举报

 楼主| 发表于 2011-8-13 14:45:00 | 显示全部楼层

视觉测量与三维重建(二):OpenCV的源代码

看起来不错,good luck。
给你建议几个我写的关于stereo vision的帖子,希望有帮助哦。

[HQ]如何研究双目视觉STEREO VISION: <!-- l --><a class=\"postlink-local\" href=\"http://www.opencv.org.cn/forum/viewtopic.php?f=1&t=14542\">viewtopic.php?f=1&t=14542</a><!-- l -->
[HQ]OpenCV双目视觉Stereo算法实现源码分享 VS2008和Xcode: <!-- l --><a class=\"postlink-local\" href=\"http://www.opencv.org.cn/forum/viewtopic.php?f=1&t=8305\">viewtopic.php?f=1&t=8305</a><!-- l -->
[HQ]双目视觉Stereo Vision中的cvFindStereoCorrespondenceBM使用范例: <!-- l --><a class=\"postlink-local\" href=\"http://www.opencv.org.cn/forum/viewtopic.php?f=1&t=14239\">viewtopic.php?f=1&t=14239</a><!-- l -->
[HQ]相机标定camera calibration中的cvFindChessboardCorners使用范例:http://www.opencv.org.cn/forum/viewtopic.php?f=1&t=14214
正在学习,谢了!
回复 支持 反对

使用道具 举报

发表于 2011-8-20 16:27:50 | 显示全部楼层

视觉测量与三维重建(二):OpenCV的源代码

上个学期,刚把基于结构光的三维表面重建整个过程用matlab仿真了一遍。这学期应该要opencv把整个软件写完,有机会想和lz多交流。
回复 支持 反对

使用道具 举报

发表于 2011-8-21 15:12:54 | 显示全部楼层

视觉测量与三维重建(二):OpenCV的源代码

我想问下具体的每一点的视差值是如何求出的,我实在很菜,看了很多文章也没提及,我也不太熟悉,谢谢 也可回复邮箱304672302@qq.com
回复 支持 反对

使用道具 举报

发表于 2011-9-19 23:10:55 | 显示全部楼层

视觉测量与三维重建(二):OpenCV的源代码

您好,当我运行stereo matching这部分代码的时候,出现了一个问题,就是debug error对话框。这个对话框上有三个按钮,停止,重试,忽略。然后我点击停止后,在MS-Dos中出现了:OpenCV Error: Assertion failed <dst.data != src.data>in unknown function,file ......\\OpenCV-2.1.0\\src\\cv\\cvimgwarp.cpp,Line 2375。这个调试错误困扰了我很久了,请您指点下,多谢!
回复 支持 反对

使用道具 举报

发表于 2011-10-14 15:35:17 | 显示全部楼层

视觉测量与三维重建(二):OpenCV的源代码

我正在学习这方面的知识,但是就连最简单的结构光都不能编出来,您能否给我一些指导?
回复 支持 反对

使用道具 举报

发表于 2011-10-15 15:39:21 | 显示全部楼层

视觉测量与三维重建(二):OpenCV的源代码

我正在学习这方面的知识,但是就连最简单的结构光都不能编出来,您能否给我一些指导?
你要什么结构光,也许我能帮忙
回复 支持 反对

使用道具 举报

发表于 2011-10-15 16:29:28 | 显示全部楼层

视觉测量与三维重建(二):OpenCV的源代码

[quote=&quot;zcqfh&quot;:qg3i72o9]我正在学习这方面的知识,但是就连最简单的结构光都不能编出来,您能否给我一些指导?
你要什么结构光,也许我能帮忙[/quote:qg3i72o9]
格雷码的,我想用这个开始,等以后深入了,想用格雷码结合相移的结构光来进行我的课题,谢谢你了,希望能给我一些帮助,因为我编程的基础太差了
回复 支持 反对

使用道具 举报

发表于 2011-10-28 13:45:52 | 显示全部楼层

视觉测量与三维重建(二):OpenCV的源代码

回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|OpenCV中文网站

GMT+8, 2024-7-14 19:37 , Processed in 0.014313 second(s), 16 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表