• opencv 角点检测+相机标定+去畸变+重投影误差计算


    https://blog.csdn.net/u010128736/article/details/52875137

    https://blog.csdn.net/h532600610/article/details/51800488

    python 角点检测+相机标定+去畸变+重投影误差计算:

    #coding:utf-8
    import cv2
    import numpy as np
    import glob
    
    # 找棋盘格角点
    # 阈值
    criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
    #棋盘格模板规格
    w = 9
    h = 6
    # 世界坐标系中的棋盘格点,例如(0,0,0), (1,0,0), (2,0,0) ....,(8,5,0),去掉Z坐标,记为二维矩阵
    objp = np.zeros((w*h,3), np.float32)
    objp[:,:2] = np.mgrid[0:w,0:h].T.reshape(-1,2)
    # 储存棋盘格角点的世界坐标和图像坐标对
    objpoints = [] # 在世界坐标系中的三维点
    imgpoints = [] # 在图像平面的二维点
    
    images = glob.glob('calib/*.png')
    for fname in images:
        img = cv2.imread(fname)
        gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
        # 找到棋盘格角点
        ret, corners = cv2.findChessboardCorners(gray, (w,h),None)
        # 如果找到足够点对,将其存储起来
        if ret == True:
            cv2.cornerSubPix(gray,corners,(11,11),(-1,-1),criteria)
            objpoints.append(objp)
            imgpoints.append(corners)
            # 将角点在图像上显示
            cv2.drawChessboardCorners(img, (w,h), corners, ret)
            cv2.imshow('findCorners',img)
            cv2.waitKey(1)
    cv2.destroyAllWindows()
    
    # 标定
    ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None)
    
    # 去畸变
    img2 = cv2.imread('calib/00169.png')
    h,  w = img2.shape[:2]
    newcameramtx, roi=cv2.getOptimalNewCameraMatrix(mtx,dist,(w,h),0,(w,h)) # 自由比例参数
    dst = cv2.undistort(img2, mtx, dist, None, newcameramtx)
    # 根据前面ROI区域裁剪图片
    #x,y,w,h = roi
    #dst = dst[y:y+h, x:x+w]
    cv2.imwrite('calibresult.png',dst)
    
    # 反投影误差
    total_error = 0
    for i in xrange(len(objpoints)):
        imgpoints2, _ = cv2.projectPoints(objpoints[i], rvecs[i], tvecs[i], mtx, dist)
        error = cv2.norm(imgpoints[i],imgpoints2, cv2.NORM_L2)/len(imgpoints2)
        total_error += error
    print "total error: ", total_error/len(objpoints)
    
    

     标定 cv2.calibrateCamera函数文档:https://docs.opencv.org/2.4.1/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html

    c++ 角点检测+角点绘制:

    #include <iostream>
    #include <cv.h>
    #include <cxcore.h>
    #include <highgui.h>
    using namespace std;
     
    int main( )
    {
        cout<<"Draw Chess OpenCV!"<<endl;  
        char* filename="..//image5.jpg";
        char* filename2="..//5.jpg";
        IplImage* imgRGB = cvLoadImage(filename); 
        IplImage* imgGrey = cvLoadImage(filename,CV_LOAD_IMAGE_GRAYSCALE); 
     
        if (imgGrey==NULL){//image validation
            cout<< "No valid image input."<<endl; 
            char c=getchar();
            return 1;
        } 
     
        //-------find chessboard corners--------------
        int corner_row=7;//interior number of row corners.(this can be countered by fingers.)
        int corner_col=7;//interior number of column corners.
        int corner_n=corner_row*corner_col;
        CvSize pattern_size=cvSize(corner_row,corner_col);
       // CvPoint2D32f* corners=new CvPoint2D32f[corner_n];
        CvPoint2D32f corners[49];
        int corner_count;
     
        int found=cvFindChessboardCorners(//returning non-zero means sucess.
            imgGrey,// 8-bit single channel greyscale image.
            pattern_size,//how many INTERIOR corners in each row and column of the chessboard.
            corners,//an array where the corner locations can be recorded.
            &corner_count,// optional, if non-NULL, its a point to an integer where the nuber of corners found can be recorded.
           // CV_CALIB_CB_ADAPTIVE_THRESH|CV_CALIB_CB_FILTER_QUADS// check page 382-383.
            0
            );
         cout<<"corner_count = "<<corner_count;
        //-------Draw the corner pattern-------
        cvDrawChessboardCorners(
            imgRGB,
            pattern_size,
            corners,
            corner_count,
            found
            );
        cvSaveImage(filename2,imgRGB);
        //to summary a bit of findings.
        cout<<"found="<<found<<endl;
        cout<<"x="<<corners[1].x;
        cout<<",y="<<corners[1].y<<endl;
        
        cvNamedWindow("Find and Draw ChessBoard", 0 );
        cvShowImage( "Find and Draw ChessBoard", imgRGB );
     
        cvWaitKey(0); 
     
        cvReleaseImage(&imgGrey);
        cvReleaseImage(&imgRGB);
        cvDestroyWindow("Find and Draw ChessBoard"); 
     
        return 0;
    }
    
    

    注意事项:

    • pattern_size参数传递内点数,8*8的棋盘只有7*7内点。
    • 图像选取应注意减少干扰,例如光照与背景等。
    • Corners中的角点坐标顺序排列规律不一定是以行从左上到右下。使用坐标计算映射关系时应提高警惕,对坐标进行重新排列。

    关键函数参数说明:

    int cvFindChessboardCorners( const void* image, CvSize pattern_size, CvPoint2D32f* corners, int* corner_count=NULL, int flags=CV_CALIB_CB_ADAPTIVE_THRESH );

    Image:

    输入的棋盘图,必须是8位的灰度或者彩色图像。

    pattern_size:

    棋盘图中每行和每列角点的个数。

    Corners:

    检测到的角点

    corner_count:

    输出,角点的个数。如果不是NULL,函数将检测到的角点的个数存储于此变量。

    Flags:

    各种操作标志,可以是0或者下面值的组合:

    CV_CALIB_CB_ADAPTIVE_THRESH -使用自适应阈值(通过平均图像亮度计算得到)将图像转换为黑白图,而不是一个固定的阈值。

    CV_CALIB_CB_NORMALIZE_IMAGE -在利用固定阈值或者自适应的阈值进行二值化之前,先使用cvNormalizeHist来均衡化图像亮度。

    CV_CALIB_CB_FILTER_QUADS -使用其他的准则(如轮廓面积,周长,方形形状)来去除在轮廓检测阶段检测到的错误方块。

  • 相关阅读:
    MyEclipse的配置--博客园老牛大讲堂
    Hbuilder连接夜神模拟器---博客园老牛大讲堂
    APICloud连接夜神模拟器--博客园老牛大讲堂
    H5混合开发APP配置以及第一个工程--博客园老牛大讲堂
    实现标签页(菜单栏)--博客园老牛大讲堂
    H5动态添加数据-博客园老牛大讲堂
    bootstrap实现网页手风琴--博客园老牛大讲堂
    返回零长度的数组或集合,而不是null
    用EnumMap代替序数索引
    用EnumSet代替位域
  • 原文地址:https://www.cnblogs.com/zealousness/p/9759375.html
Copyright © 2020-2023  润新知