织梦CMS - 轻松建站从此开始!

罗索

Camera calibration 摄像头标定 代码整理(2007-2-6 修正)

落鹤生 发布于 2010-04-25 16:35 点击:次 
这里介绍了一个使用directshow标定与Matlab的示例,写的很详细。 http://w3.impa.br/~pcezar/3dp/original/CVL_html/appPage/doc_calib.html#Tutorial OPENCV没有提供完整的示例,自己整理了一下,贴出来记录。
TAG:

这里介绍了一个使用directshow标定与Matlab的示例,写的很详细。

 http://w3.impa.br/~pcezar/3dp/original/CVL_html/appPage/doc_calib.html#Tutorial

OPENCV没有提供完整的示例,自己整理了一下,贴出来记录。

步骤如下:

首先自制一张标定图片,用A4纸打印出来,设定距离,再设定标定棋盘的格子数目,如8×6,以下是我做的图片8×8


然后利用cvFindChessboardCorners找到棋盘在摄像头中的2D位置,这里cvFindChessboardCorners不太稳定,有时不能工作。

计算实际的距离,应该是3D的距离。我设定为21.6毫米,既在A4纸上为两厘米。

再用cvCalibrateCamera2计算内参,

最后用cvUndistort2纠正图像的变形。

结果如下:

源代码如下:

  1. #include "stdafx.h" 
  2. #include <stdio.h> 
  3. #include <stdlib.h> 
  4. #include <string.h> 
  5. // OpenCV 
  6. #include <cxcore.h> 
  7. #include <cv.h> 
  8. #include <highgui.h> 
  9. #include <cvaux.h> 
  10.  
  11.  
  12. void InitCorners3D(CvMat *Corners3D, CvSize ChessBoardSize, 
  13.  int Nimages, float SquareSize); 
  14. void makeChessBoard(); 
  15. int myFindChessboardCorners( const void* image, CvSize pattern_size, 
  16.    CvPoint2D32f* corners, int* corner_count=NULL, 
  17.    int flags=CV_CALIB_CB_ADAPTIVE_THRESH ); 
  18.  
  19.  
  20. inline int drawCorssMark(IplImage *dst,CvPoint pt) 
  21. /**//************************************************* 
  22.   Function:        main_loop 
  23.   Description:     绘制一个十字标记                     
  24.   Calls:           
  25.   Called By:       
  26.   Input:           RGB image,  pt                
  27.   Output:          
  28.   Return:          
  29.   Others:          需要检查坐标是否越界 to do list 
  30. *************************************************/ 
  31.      
  32.     const int cross_len = 4; 
  33.     CvPoint pt1,pt2,pt3,pt4; 
  34.     pt1.x = pt.x; 
  35.     pt1.y = pt.y - cross_len; 
  36.     pt2.x = pt.x; 
  37.     pt2.y = pt.y + cross_len; 
  38.     pt3.x = pt.x - cross_len; 
  39.     pt3.y = pt.y; 
  40.     pt4.x = pt.x + cross_len; 
  41.     pt4.y = pt.y; 
  42.  
  43.     cvLine(dst,pt1,pt2,CV_RGB(0,255,0),2,CV_AA, 0 );     
  44.     cvLine(dst,pt3,pt4,CV_RGB(0,255,0),2,CV_AA, 0 ); 
  45.      
  46.     return 0; 
  47.  
  48. /**//* declarations for OpenCV */ 
  49. IplImage *current_frame_rgb,grid; 
  50. IplImage *current_frame_gray; 
  51. IplImage *chessBoard_Img; 
  52.  
  53. int Thresholdness = 120; 
  54.  
  55. int image_width = 320; 
  56. int image_height = 240; 
  57.  
  58. bool verbose = false
  59.  
  60. const int ChessBoardSize_w = 7; 
  61. const int ChessBoardSize_h = 7; 
  62. // Calibration stuff 
  63. bool         calibration_done = false
  64. const CvSize ChessBoardSize = cvSize(ChessBoardSize_w,ChessBoardSize_h); 
  65. //float      SquareWidth = 21.6f; //实际距离 毫米单位 在A4纸上为两厘米 
  66. float        SquareWidth = 17; //投影实际距离 毫米单位  200 
  67.  
  68. const   int NPoints = ChessBoardSize_w*ChessBoardSize_h; 
  69. const   int NImages = 20; //Number of images to collect  
  70.  
  71. CvPoint2D32f corners[NPoints*NImages]; 
  72. int corner_count[NImages] = {0}; 
  73. int captured_frames = 0; 
  74.  
  75. CvMat *intrinsics; 
  76. CvMat *distortion_coeff; 
  77. CvMat *rotation_vectors; 
  78. CvMat *translation_vectors; 
  79. CvMat *object_points; 
  80. CvMat *point_counts; 
  81. CvMat *image_points; 
  82. int find_corners_result =0 ; 
  83.  
  84.  
  85. void on_mouse( int event, int x, int y, int flags, void* param ) 
  86.  
  87.     if( event == CV_EVENT_LBUTTONDOWN ) 
  88.     { 
  89.         //calibration_done = true;  
  90.     } 
  91.  
  92.  
  93. int main(int argc, char *argv[]) 
  94.  
  95.  
  96.   CvFont font; 
  97.   cvInitFont( &font, CV_FONT_VECTOR0,5, 5, 0, 7, 8); 
  98.    
  99.   intrinsics         = cvCreateMat(3,3,CV_32FC1); 
  100.   distortion_coeff     = cvCreateMat(1,4,CV_32FC1); 
  101.   rotation_vectors     = cvCreateMat(NImages,3,CV_32FC1); 
  102.   translation_vectors     = cvCreateMat(NImages,3,CV_32FC1); 
  103.  
  104.   point_counts         = cvCreateMat(NImages,1,CV_32SC1); 
  105.  
  106.   object_points     = cvCreateMat(NImages*NPoints,3,CV_32FC1); 
  107.   image_points         = cvCreateMat(NImages*NPoints,2,CV_32FC1); 
  108.  
  109.  
  110.   // Function to fill in the real-world points of the checkerboard 
  111.   InitCorners3D(object_points, ChessBoardSize, NImages, SquareWidth); 
  112.  
  113.  
  114.   CvCapture* capture = 0; 
  115.  
  116.    
  117.   if( argc == 1 || (argc==2 && strlen(argv[1])==1 && isdigit(argv[1][0]))) 
  118.       capture = cvCaptureFromCAM( argc == 2 ? argv[1][0] - '0' : 0 ); 
  119.   else if( argc == 2 ) 
  120.       capture = cvCaptureFromAVI( argv[1] ); 
  121.  
  122.   if( !capture ) 
  123.   { 
  124.       fprintf(stderr,"Could not initialize capturing "); 
  125.       return -1; 
  126.   } 
  127.    
  128.    
  129.   // Initialize all of the IplImage structures 
  130.   current_frame_rgb = 
  131.  cvCreateImage(cvSize(image_width, image_height), IPL_DEPTH_8U, 3); 
  132.    
  133.   IplImage *current_frame_rgb2 = 
  134.  cvCreateImage(cvSize(image_width, image_height), IPL_DEPTH_8U, 3); 
  135.   current_frame_gray = 
  136.  cvCreateImage(cvSize(image_width, image_height), IPL_DEPTH_8U, 1); 
  137.  
  138.   chessBoard_Img   = 
  139.  cvCreateImage(cvSize(image_width, image_height), IPL_DEPTH_8U, 3);   
  140.   current_frame_rgb2->origin = chessBoard_Img->origin = 
  141.  current_frame_gray->origin = current_frame_rgb->origin = 1; 
  142.    
  143.   makeChessBoard(); 
  144.  
  145.   cvNamedWindow( "result", 0); 
  146.   cvNamedWindow( "Window 0", 0); 
  147.   cvNamedWindow( "grid", 0); 
  148.   cvMoveWindow( "grid", 100,100); 
  149.   cvSetMouseCallback( "Window 0", on_mouse, 0 );   
  150.   cvCreateTrackbar("Thresholdness","Window 0",&Thresholdness, 255,0); 
  151.    
  152.   while (!calibration_done) 
  153.   { 
  154.  
  155.     while (captured_frames < NImages) 
  156.     { 
  157.       current_frame_rgb = cvQueryFrame( capture ); 
  158.       //current_frame_rgb = cvLoadImage( "c:\BoardStereoL3.jpg" ); 
  159.       //cvCopy(chessBoard_Img,current_frame_rgb); 
  160.  
  161.       if( !current_frame_rgb ) 
  162.           break
  163.  
  164.       cvCopy(current_frame_rgb,current_frame_rgb2); 
  165.       cvCvtColor(current_frame_rgb, current_frame_gray, CV_BGR2GRAY); 
  166.       //cvThreshold(current_frame_gray,current_frame_gray, 
  167. Thresholdness,255,CV_THRESH_BINARY); 
  168.       //cvThreshold(current_frame_gray,current_frame_gray, 
  169. 150,255,CV_THRESH_BINARY_INV); 
  170.  
  171. /**//* 
  172.     int pos = 1; 
  173.     IplConvKernel* element = 0; 
  174.     const int element_shape = CV_SHAPE_ELLIPSE; 
  175.     element = cvCreateStructuringElementEx( pos*2+1, pos*2+1, 
  176.  pos, pos, element_shape, 0 ); 
  177.     cvDilate(current_frame_gray,current_frame_gray,element,1); 
  178.     cvErode(current_frame_gray,current_frame_gray,element,1); 
  179.     cvReleaseStructuringElement(&element); 
  180. */ 
  181.      
  182.     find_corners_result = cvFindChessboardCorners(current_frame_gray, 
  183.                                           ChessBoardSize, 
  184.                                           &corners[captured_frames*NPoints], 
  185.                                           &corner_count[captured_frames], 
  186.                                           0); 
  187.  
  188.  
  189.  
  190.     cvDrawChessboardCorners(current_frame_rgb2, ChessBoardSize, 
  191.  &corners[captured_frames*NPoints], NPoints, find_corners_result); 
  192.  
  193.  
  194.     cvShowImage("Window 0",current_frame_rgb2); 
  195.     cvShowImage("grid",chessBoard_Img); 
  196.  
  197.     if(find_corners_result==1) 
  198.     { 
  199.         cvWaitKey(2000); 
  200.         cvSaveImage("c:\hardyinCV.jpg",current_frame_rgb2); 
  201.         captured_frames++; 
  202.     } 
  203.     //cvShowImage("result",current_frame_gray); 
  204.  
  205.     intrinsics->data.fl[0] = 256.8093262;   //fx         
  206.     intrinsics->data.fl[2] = 160.2826538;   //cx 
  207.     intrinsics->data.fl[4] = 254.7511139;   //fy 
  208.     intrinsics->data.fl[5] = 127.6264572;   //cy 
  209.  
  210.     intrinsics->data.fl[1] = 0;    
  211.     intrinsics->data.fl[3] = 0;    
  212.     intrinsics->data.fl[6] = 0;    
  213.     intrinsics->data.fl[7] = 0;    
  214.     intrinsics->data.fl[8] = 1;        
  215.  
  216.     distortion_coeff->data.fl[0] = -0.193740;  //k1 
  217.     distortion_coeff->data.fl[1] = -0.378588;  //k2 
  218.     distortion_coeff->data.fl[2] = 0.028980;   //p1 
  219.     distortion_coeff->data.fl[3] = 0.008136;   //p2 
  220.  
  221.     cvWaitKey(40); 
  222.     find_corners_result = 0; 
  223.     }    
  224.     //if (find_corners_result !=0) 
  225.     { 
  226.  
  227.         printf(" "); 
  228.  
  229.         cvSetData( image_points, corners, sizeof(CvPoint2D32f)); 
  230.         cvSetData( point_counts, &corner_count, sizeof(int)); 
  231.  
  232.          
  233.         cvCalibrateCamera2( object_points, 
  234.             image_points, 
  235.             point_counts, 
  236.             cvSize(image_width,image_height), 
  237.             intrinsics, 
  238.             distortion_coeff, 
  239.             rotation_vectors, 
  240.             translation_vectors, 
  241.             0); 
  242.          
  243.  
  244.         // [fx 0 cx; 0 fy cy; 0 0 1]. 
  245.     cvUndistort2(current_frame_rgb,current_frame_rgb,intrinsics,distortion_coeff); 
  246.     cvShowImage("result",current_frame_rgb); 
  247.  
  248.  
  249.         float intr[3][3] = {0.0}; 
  250.         float dist[4] = {0.0}; 
  251.         float tranv[3] = {0.0}; 
  252.         float rotv[3] = {0.0}; 
  253.  
  254.         for ( int i = 0; i < 3; i++) 
  255.         { 
  256.             for ( int j = 0; j < 3; j++) 
  257.             { 
  258.             intr[i][j] = ((float*)(intrinsics->data.ptr + intrinsics->step*i))[j]; 
  259.             } 
  260.             dist[i] = ((float*)(distortion_coeff->data.ptr))[i]; 
  261.             tranv[i] = ((float*)(translation_vectors->data.ptr))[i]; 
  262.             rotv[i] = ((float*)(rotation_vectors->data.ptr))[i]; 
  263.         } 
  264.         dist[3] = ((float*)(distortion_coeff->data.ptr))[3]; 
  265.  
  266.     printf("----------------------------------------- "); 
  267.     printf("INTRINSIC MATRIX:  "); 
  268.     printf("[ %6.4f %6.4f %6.4f ]  ", intr[0][0], intr[0][1], intr[0][2]); 
  269.     printf("[ %6.4f %6.4f %6.4f ]  ", intr[1][0], intr[1][1], intr[1][2]); 
  270.     printf("[ %6.4f %6.4f %6.4f ]  ", intr[2][0], intr[2][1], intr[2][2]); 
  271.     printf("----------------------------------------- "); 
  272.     printf("DISTORTION VECTOR:  "); 
  273.     printf("[ %6.4f %6.4f %6.4f %6.4f ]  ", dist[0], dist[1], dist[2], dist[3]); 
  274.     printf("----------------------------------------- "); 
  275.     printf("ROTATION VECTOR:  "); 
  276.     printf("[ %6.4f %6.4f %6.4f ]  ", rotv[0], rotv[1], rotv[2]); 
  277.     printf("TRANSLATION VECTOR:  "); 
  278.     printf("[ %6.4f %6.4f %6.4f ]  ", tranv[0], tranv[1], tranv[2]); 
  279.     printf("----------------------------------------- "); 
  280.  
  281.     cvWaitKey(0); 
  282.  
  283.     calibration_done = true;       
  284.     } 
  285.                 
  286.   } 
  287.  
  288.   exit(0); 
  289.   cvDestroyAllWindows(); 
  290.  
  291. void InitCorners3D(CvMat *Corners3D,CvSize ChessBoardSize,int NImages,float SquareSize) 
  292.   int CurrentImage = 0; 
  293.   int CurrentRow = 0; 
  294.   int CurrentColumn = 0; 
  295.   int NPoints = ChessBoardSize.height*ChessBoardSize.width; 
  296.   float * temppoints = new float[NImages*NPoints*3]; 
  297.  
  298.   // for now, assuming we're row-scanning 
  299.   for (CurrentImage = 0 ; CurrentImage < NImages ; CurrentImage++) 
  300.   { 
  301.     for (CurrentRow = 0; CurrentRow < ChessBoardSize.height; CurrentRow++) 
  302.     { 
  303.       for (CurrentColumn=0;CurrentColumn<ChessBoardSize.width;CurrentColumn++) 
  304.       { 
  305.           temppoints[(CurrentImage*NPoints*3)+(CurrentRow*ChessBoardSize.width + 
  306.  CurrentColumn)*3]=(float)CurrentRow*SquareSize; 
  307.           temppoints[(CurrentImage*NPoints*3)+(CurrentRow*ChessBoardSize.width + 
  308.  CurrentColumn)*3+1]=(float)CurrentColumn*SquareSize; 
  309.           temppoints[(CurrentImage*NPoints*3)+(CurrentRow*ChessBoardSize.width + 
  310.  CurrentColumn)*3+2]=0.f; 
  311.       } 
  312.     } 
  313.   } 
  314.   (*Corners3D) = cvMat(NImages*NPoints,3,CV_32FC1, temppoints); 
  315.  
  316. int myFindChessboardCorners( const void* image, CvSize pattern_size, 
  317.                              CvPoint2D32f* corners, int* corner_count, 
  318.                              int flags ) 
  319.  
  320.  
  321.  
  322.     IplImage* eig = cvCreateImage( cvGetSize(image), 32, 1 ); 
  323.     IplImage* temp = cvCreateImage( cvGetSize(image), 32, 1 ); 
  324.     double quality = 0.01; 
  325.     double min_distance = 5; 
  326.     int win_size =10; 
  327.  
  328.     int count = pattern_size.width * pattern_size.height; 
  329.     cvGoodFeaturesToTrack( image, eig, temp, corners, &count, 
  330.         quality, min_distance, 0, 3, 0, 0.04 ); 
  331.     cvFindCornerSubPix( image, corners, count, 
  332.         cvSize(win_size,win_size), cvSize(-1,-1), 
  333.         cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,20,0.03)); 
  334.      
  335.     cvReleaseImage( &eig ); 
  336.     cvReleaseImage( &temp ); 
  337.  
  338.     return 1; 
  339.  
  340. void makeChessBoard() 
  341.  
  342.   CvScalar e;  
  343.   e.val[0] =255; 
  344.   e.val[1] =255; 
  345.   e.val[2] =255; 
  346.   cvSet(chessBoard_Img,e,0); 
  347.   for(int i = 0;i<ChessBoardSize.width+1;i++) 
  348.       for(int j = 0;j<ChessBoardSize.height+1;j++) 
  349.       { 
  350.           int w =(image_width)/2/(ChessBoardSize.width); 
  351.           int h = w; //(image_height)/2/(ChessBoardSize.height); 
  352.  
  353.           int ii = i+1; 
  354.           int iii = ii+1; 
  355.           int jj =j+1; 
  356.           int jjj =jj+1; 
  357.           int s_x = image_width/6;           
  358.  
  359.         if((i+j)%2==1) 
  360.            cvRectangle( chessBoard_Img, cvPoint(w*i+s_x,h*j+s_x), 
  361. cvPoint(w*ii-1+s_x,h*jj-1+s_x), CV_RGB(0,0,0),CV_FILLED, 8, 0 ); 
  362.       } 

 

(pcezar)
本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www.rosoo.net/a/201004/9257.html]
本文出处:w3.impa.br 作者:pcezar
顶一下
(3)
100%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容