cv 畸变图像校正(使用openCV)

获取镜头的畸变参数

  • 1 基于平面标定版的畸变参数计算。使用既定的标定版,从多个角度进行拍照,如下

  • 2 使用openCV中的标定板角点检测函数,检测出角点

    int cvFindChessboardCorners(const void* image, CvSize patternSize, CvPoint2D32f* corners, int* cornerCount=NULL, int flags=CV_CALIB_CB_ADAPTIVE_THRESHParameters:

    • image – Source chessboard view; it must be an 8-bit grayscale or color image
    • patternSize – The number of inner corners per chessboard row and column ( patternSize = cvSize(points_per_row,points_per_colum) = cvSize(columns,rows) )
    • corners – The output array of corners detected
    • cornerCount – The output corner counter. If it is not NULL, it stores the number of corners found
    • flags – Various operation flags, can be 0 or a combination of the following values:
      • CV_CALIB_CB_ADAPTIVE_THRESH - use adaptive thresholding to convert the image to black and white, rather than a fixed threshold level (computed from the average image brightness).
      • CV_CALIB_CB_NORMALIZE_IMAGE - normalize the image gamma with EqualizeHist before applying fixed or adaptive thresholding.
      • CV_CALIB_CB_FILTER_QUADS - use additional criteria (like contour area, perimeter, square-like shape) to filter out false quads that are extracted at the contour retrieval stage.
  • 3 找到亚像素角度位置,函数:cvFindCornerSubPix
  • 4 赋值给像点坐标和对应地面点坐标
    size.height = img_->height;
    size.width = img_->width;float dImage[CornerNumbers*2];
    float dObject[CornerNumbers*3];
    int dCount[NumberImages];
    float dIntrin[9];// 
    float dDistor[4];//
    float dRot[NumberImages*3];
    float dTrans[NumberImages*3];

    CvMat object_points, image_points, point_counts;
    CvMat intrinsic, distortion, rot, trans;
    cvInitMatHeader(&object_points,CornerNumbers ,3, CV_32FC1, dObject);
    cvInitMatHeader(&image_points, CornerNumbers, 2, CV_32FC1, dImage);
    cvInitMatHeader(&point_counts, NumberImages, 1, CV_32SC1, dCount);
    cvInitMatHeader(&intrinsic, 3, 3, CV_32FC1, dIntrin);
    cvInitMatHeader(&distortion, 1, 4, CV_32FC1, dDistor);
    cvInitMatHeader(&rot, NumberImages, 3, CV_32FC1, dRot);
    cvInitMatHeader(&trans, NumberImages, 3, CV_32FC1, dTrans);


    for (int i = 0; i < NumberImages; i++)
        {
        
        dCount[i] = ROWS*COLS;// *****每一行角点数(ROWS),每一列角点数(COLS)
        for (int j = 0; j < COLS; j++)
            for (int k = 0; k < ROWS; k++)
            {
                dImage[i*COLS*ROWS*2 + 2*ROWS*j + 2*k + 0] = p[i*COLS*ROWS+j*ROWS+k].x;
                dImage[i*COLS*ROWS*2 + 2*ROWS*j + 2*k + 1] = p[i*COLS*ROWS+j*ROWS+k].y;
                dObject[i*COLS*ROWS*3 + 3*ROWS*j + 3*k + 0] = k*10;
                dObject[i*COLS*ROWS*3 + 3*ROWS*j + 3*k + 1] = j*10;
                dObject[i*COLS*ROWS*3 + 3*ROWS*j + 3*k + 2] = 0;
            }
        }
  • 5 计算内外方位元素
cvCalibrateCamera2(&object_points, &image_points, &point_counts, size, &intrinsic, &distortion, &rot, &trans, CV_CALIB_FIX_PRINCIPAL_POINT);

 根据畸变参数纠正影像

    int width=image->width;
    int high=image->height;
    CvSize sz= buildSize(width,high);
    IplImage* dst = cvCreateImage( sz, IPL_DEPTH_8U, 1);

    //转换为灰度图
    cvCvtColor( image, ImageGry, CV_RGB2GRAY);
    //cvFlip( ImageGry, NULL, 0);// 有时候需要翻转

    double *mi= new double[3*3];
    double *md = new double[4];

    CvMat intrinsic_matrix,distortion_coeffs;

    //摄像机内参数
    cvInitMatHeader(&intrinsic_matrix,3,3,CV_64FC1,mi);

    //镜头畸变参数
    cvInitMatHeader(&distortion_coeffs,1,4,CV_64FC1,md);

    //****** 畸变参数 赋值 *******
    double fc1,fc2,cc1,cc2,kc1,kc2,kc3,kc4;
    fc1 = 533.817749;
    fc2 = 534.484619 ;
    cc1 = 319.5;
    cc2 = 239.5;
    kc1 =  -0.302179;
    kc2 =   0.148561;
    kc3 =  0.001140 ;
    kc4 =  -0.000979;

    cvmSet(&intrinsic_matrix, 0, 0, fc1);
    cvmSet(&intrinsic_matrix, 0, 1, 0);
    cvmSet(&intrinsic_matrix, 0, 2, cc1);
    cvmSet(&intrinsic_matrix, 1, 0, 0);
    cvmSet(&intrinsic_matrix, 1, 1, fc2);
    cvmSet(&intrinsic_matrix, 1, 2, cc2);
    cvmSet(&intrinsic_matrix, 2, 0, 0);
    cvmSet(&intrinsic_matrix, 2, 1, 0);
    cvmSet(&intrinsic_matrix, 2, 2, 1);

    cvmSet(&distortion_coeffs, 0, 0, kc1);
    cvmSet(&distortion_coeffs, 0, 1, kc2);
    cvmSet(&distortion_coeffs, 0, 2, kc3);
    cvmSet(&distortion_coeffs, 0, 3, kc4);

//******** 矫正畸变(opencv)***********
    cvUndistort2( ImageGry, dst, &intrinsic_matrix, &distortion_coeffs);
//******** 显示结果 (opencv)***********
cvNamedWindow( "矫正", 1 );//创建窗口
cvShowImage("矫正", dst);

  cvWaitKey(1);
  cvReleaseImage( &dst );

原图和纠正的图

  

 

posted @ 2013-08-26 17:17  Lemon_Hi  阅读(22204)  评论(2编辑  收藏  举报