zoukankan      html  css  js  c++  java
  • 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 );

    原图和纠正的图

      

  • 相关阅读:
    控件显示和隐藏
    删除标题和边框
    界面图片
    VC界面最前端显示
    在VC++6.0开发中实现全屏显示
    VC比例放大缩小
    plsql dev
    通过OCCI连接oracle(C++)
    VC++使用Pro*CC++
    文件对话框
  • 原文地址:https://www.cnblogs.com/Lemon-Li/p/3283059.html
Copyright © 2011-2022 走看看