opencv2 摄像机标定代码简化版 (ubuntu 16)

来源:互联网 发布:淘宝750图片怎么设置 编辑:程序博客网 时间:2024/06/09 10:56
//用法://摄像头取像,找到棋盘的时候会显示,按空格捕获图像,esc退出//捕获够10幅才能按回车开始标定//本次试验用的是8*8方格棋盘,每个方格边长为20mm//过程://函数findChessboardCorners()寻找棋盘角点粗略位置保存在corners//函数cornerSubPix()精确化角点坐标//把每一幅捕获的图像的corners保存在image_point,并生成对应size的object_point//函数calibrateCamera()利用上面的image_point和object_point进行标定//得到的intrinsic_matrix矩阵就是摄像头的内参,具体自行查阅资料#include <opencv2/opencv.hpp>#include <opencv2/core/core.hpp>#include <opencv2/highgui/highgui.hpp>#include <opencv2/imgproc/imgproc.hpp>#include <string>#include <vector>#include <sstream>#include <iostream>using namespace cv;using namespace std;void Tool::calibrate_camera(){    VideoCapture vc;    vc.open(1);    if(!vc.isOpened()){        cout << "Could not open camera\n";        return;    }    Mat frame;    Mat gray_frame;  //用于精确角点坐标    namedWindow("摄像头");    Size board_size = Size(7, 7); //棋盘行列角点数, 不是行列数!    float square_size = 20;   //方格边长 单位:mm    vector<Point2f> corners; //一幅图像的角点坐标    vector<vector<Point2f>> image_point;  //所有图像的角点坐标    vector<vector<Point3f>> object_point;  //所有图像的世界坐标的相对值    Mat intrinsic_matrix;  //内参矩阵    Mat distortion_coeffs;  //失真系数矩阵    vector<Mat> rvecs;  //旋转矩阵    vector<Mat> tvecs;  //平移矩阵    bool pattern_found;  //是否找到棋盘    stringstream ss;   //用于生成字符串    //循环播放视频, 按键捕获图像和标定    for (int key = waitKey(33); ; key = waitKey(33)) {        vc >> frame;        corners.clear();        pattern_found = findChessboardCorners(                    frame, board_size, corners,                    CALIB_CB_FAST_CHECK +                    CALIB_CB_ADAPTIVE_THRESH +                    CALIB_CB_NORMALIZE_IMAGE);        if(pattern_found){            cvtColor(frame, gray_frame, CV_BGR2GRAY);            //criteria:角点精准化迭代过程的终止条件。            //也就是当迭代次数超过criteria.maxCount,            //或者角点位置变化小于criteria.epsilon时,停止迭代过程。            TermCriteria criteria = TermCriteria(                        CV_TERMCRIT_EPS + CV_TERMCRIT_ITER,                        40,                        0.001 );            // 亚像素级精确角点位置            cornerSubPix(gray_frame, corners, Size(11,11), Size(-1, -1), criteria);            // 画出角点            drawChessboardCorners(frame, board_size, corners, pattern_found);            if(key == 0x100020){ //space 取得一帧的角点                image_point.push_back(corners);            }        }        if(key == 0x10001b){ //esc 退出            break;        }        else if(key == 0x10000a && image_point.size() >= 10){ //enter 进行标定            //计算单幅图像对应的世界坐标的相对值,每个方块的单位取为1            vector<Point3f> object_point_1;            for(int h = 0; h < board_size.height; h++){                for(int w = 0; w < board_size.width; w++){                    object_point_1.push_back(                           Point3f(w * square_size, h * square_size, 0.0f)                           );                }            }            object_point.resize(image_point.size(), object_point_1);            //初始化内参数矩阵  和  失真系数矩阵            intrinsic_matrix = Mat::eye(Size(3, 3), CV_32F);            distortion_coeffs = Mat::zeros(5, 1, CV_32F);            //开始标定            calibrateCamera(object_point, image_point, frame.size(),                            intrinsic_matrix, distortion_coeffs, rvecs, tvecs);            cout << "内参矩阵" << intrinsic_matrix << endl                 << "失真系数矩阵" << distortion_coeffs;            break;        }        ss.str("");        ss << image_point.size();        //显示已捕获图片数量        putText(frame, ss.str(), Point(20,50),                FONT_HERSHEY_SIMPLEX, 1, Scalar(255,255,255), 3);        imshow("摄像头", frame);    }}int main(){    calibrate_camera();    return 0;}
0 0
原创粉丝点击