精华内容
下载资源
问答
  • 双目矫正
    千次阅读 热门讨论
    2020-06-01 20:56:36

    ![灰度图](https://img-blog.csdnimg.cn/20200601204821393.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0FzYWJjMTIzNDU=,size_16,color_FFFFFF,t_70视差图
    点云图
    因为只有一个视角的深度图,所以生成的点云图很粗糙只有个轮廓,顶多算是稀疏原始点云。还需要后期点云滤波、多点云拼接。至于为什么会有对称的两个轮廓,我觉得可能生成了左右两个视角的点云图,还有我的相机参数不完全匹配,导致两个分离了没有融合,有时间再研究研究。

    //2020.07.14更新
    之前视差图生成点云图显示有问题的原因找到了,大多数情况下大家都会遇到的问题是点云分层,呈放射状杂乱无章。不要慌,一般就两个原因:点云质量差和数据格式有问题。点云质量差意味着噪声多,生成的噪点点云杂乱分布

    更多相关内容
  • % 相机2畸变向量 Python双目矫正 新建一个python脚本,输入以下代码: import cv2 import numpy as np # 左目内参 left_camera_matrix = np.array([[443.305413261701, 0., 473.481578105186], [0., 445....

    一、双目标定

    双目标定需要获取到两个相机的内参以及变换矩阵。可参照链接:
    https://blog.csdn.net/qq_38236355/article/details/89280633
    https://blog.csdn.net/qingfengxiaosong/article/details/109897053
    或者自行百度
    建议使用Matlab工具箱做标定,其中建议勾选3 Coefficients。
    输出Matlab的数据之后,可用一下脚本提取数据:

    rowName = cell(1,10);
    rowName{1,1} = '平移矩阵';
    rowName{1,2} = '旋转矩阵';
    rowName{1,3} = '相机1内参矩阵';
    rowName{1,4} = '相机1径向畸变';
    rowName{1,5} = '相机1切向畸变';
    rowName{1,6} = '相机2内参矩阵';
    rowName{1,7} = '相机2径向畸变';
    rowName{1,8} = '相机2切向畸变';
    rowName{1,9} = '相机1畸变向量';
    rowName{1,10} = '相机2畸变向量';
    xlswrite('out.xlsx',rowName(1,1),1,'A1');
    xlswrite('out.xlsx',rowName(1,2),1,'A2');
    xlswrite('out.xlsx',rowName(1,3),1,'A5');
    xlswrite('out.xlsx',rowName(1,4),1,'A8');
    xlswrite('out.xlsx',rowName(1,5),1,'A9');
    xlswrite('out.xlsx',rowName(1,6),1,'A10');
    xlswrite('out.xlsx',rowName(1,7),1,'A13');
    xlswrite('out.xlsx',rowName(1,8),1,'A14');
    xlswrite('out.xlsx',rowName(1,9),1,'A15');
    xlswrite('out.xlsx',rowName(1,10),1,'A16');
    xlswrite('out.xlsx',stereoParams.TranslationOfCamera2,1,'B1');  % 平移矩阵
    xlswrite('out.xlsx',stereoParams.RotationOfCamera2.',1,'B2');  % 旋转矩阵
    xlswrite('out.xlsx',stereoParams.CameraParameters1.IntrinsicMatrix.',1,'B5');  % 相机1内参矩阵
    xlswrite('out.xlsx',stereoParams.CameraParameters1.RadialDistortion,1,'B8');  % 相机1径向畸变(1,2,5)
    xlswrite('out.xlsx',stereoParams.CameraParameters1.TangentialDistortion,1,'B9');  % 相机1切向畸变(3,4)
    xlswrite('out.xlsx',stereoParams.CameraParameters2.IntrinsicMatrix.',1,'B10');  % 相机2内参矩阵
    xlswrite('out.xlsx',stereoParams.CameraParameters2.RadialDistortion,1,'B13');  % 相机2径向畸变(1,2,5)
    xlswrite('out.xlsx',stereoParams.CameraParameters2.TangentialDistortion,1,'B14');  % 相机2切向畸变(3,4)
    xlswrite('out.xlsx',[stereoParams.CameraParameters1.RadialDistortion(1:2), stereoParams.CameraParameters1.TangentialDistortion,...
        stereoParams.CameraParameters1.RadialDistortion(3)],1,'B15');  % 相机1畸变向量
    xlswrite('out.xlsx',[stereoParams.CameraParameters2.RadialDistortion(1:2), stereoParams.CameraParameters2.TangentialDistortion,...
        stereoParams.CameraParameters2.RadialDistortion(3)],1,'B16');  % 相机2畸变向量
    

    Python双目矫正

    新建一个python脚本,输入以下代码:

    import cv2
    import numpy as np
    # 左目内参
    left_camera_matrix = np.array([[443.305413261701, 0., 473.481578105186],
                                   [0., 445.685585080218, 481.627083907456],
                                   [0., 0., 1.]])
    #左目畸变
    #k1 k2 p1 p2 k3
    left_distortion = np.array([[-0.261575534517449, 0.0622298171820726, 0., 0., -0.00638628534161724]])
    # 右目内参
    right_camera_matrix = np.array([[441.452616156177,0., 484.276702473006],
                                    [0., 444.350924943458, 465.054536507021],
                                    [0., 0., 1.]])
    # 右目畸变
    right_distortion = np.array([[-0.257761221642368, 0.0592089672793365, 0., 0., -0.00576090991058531]])
    # 旋转矩阵
    R = np.matrix([
        [0.999837210893742, -0.00477934325693493, 0.017398551383822],
        [0.00490062605211919, 0.999963944810228, -0.0069349076319899],
        [-0.0173647797717217, 0.00701904249875521, 0.999824583347439]
    ])
    # 平移矩阵
    T = np.array([-71.0439056359403, -0.474467959947789, -0.27989811881883]) # 平移关系向量
    
    size = (960, 960) # 图像尺寸
    
    # 进行立体更正
    R1, R2, P1, P2, Q, validPixROI1, validPixROI2 = cv2.stereoRectify(left_camera_matrix, left_distortion,
                                                                      right_camera_matrix, right_distortion, size, R,
                                                                      T)
    # 计算更正map
    left_map1, left_map2 = cv2.initUndistortRectifyMap(left_camera_matrix, left_distortion, R1, P1, size, cv2.CV_16SC2)
    right_map1, right_map2 = cv2.initUndistortRectifyMap(right_camera_matrix, right_distortion, R2, P2, size, cv2.CV_16SC2)
    

    参数需要换成自己实际的参数。
    接下来随便写一个脚本测试一下更正结果:

    import cv2
    import numpy as np
    import camera_config
    
    w = 1920
    h = 960
    cap = cv2.VideoCapture(0)
    cap.set(cv2.CAP_PROP_FRAME_WIDTH, w)
    cap.set(cv2.CAP_PROP_FRAME_HEIGHT, h)
    
    key = ""
    ww = int(w/2)
    
    jiange = int(h/10)
    
    while key!=27:
        ret, img = cap.read()
        if ret:
            imgLeft = img[:, :ww]
            imgRight = img[:, ww:w]
    
            left_remap = cv2.remap(imgLeft, camera_config.left_map1, camera_config.left_map2, cv2.INTER_LINEAR)
            right_remap = cv2.remap(imgRight, camera_config.right_map1, camera_config.right_map2, cv2.INTER_LINEAR)
    
            out = np.hstack([left_remap, right_remap])
            for i in range(10):
                cv2.line(out, (0, jiange*i), (w, jiange*i), (255, 0, 0), 2)
    
            cv2.imshow("frame", out)
            key = cv2.waitKey(10)
        
    cap.release()
    cv2.destroyAllWindows()
    

    即可看到效果:
    校正前(很差的相机,鱼眼效果,不适合用于实际使用):
    校正前
    校正后:
    校正后

    展开全文
  • C/CPP实现双目矫正(不使用OpenCV)及矫正源码解析 这篇文章是之前【要matlab标定数据做双目相机矫正OpenCV C++】的补充,再加上了双目矫正的原理及代码注释。 本文所需数据为matlab标定的双目摄像头外参及内参,具体...

    C/CPP实现双目矫正(不使用OpenCV)及矫正源码解析

    这篇文章是之前【要matlab标定数据做双目相机矫正OpenCV C++】的补充,再加上了双目矫正的原理及代码注释。更新中……

    本文所需数据为matlab标定的双目摄像头外参及内参,具体使用stereoCameraCalibrator 步骤可看之前那篇文章。后续将会实现CPP版本的双目标定,又挖了个坑😓。

    补充了,在最下面。
    再补充一个棋盘格标定板(可白嫖👍

    找paper搭配 Sci-Hub 食用更佳 (๑•̀ㅂ•́)و✧
    Sci-Hub 实时更新 : https://tool.yovisun.com/scihub/
    公益科研通文献求助:https://www.ablesci.com/
    立体匹配算法排行榜:KITTI 立体匹配算法排行榜,Middlebury 立体匹配算法排行榜
    在这里插入图片描述
    熟悉立体匹配的同学对这幅图一定不陌生,计算双目深度就是按照上图中的相似三角形进行求解。

    视 差     d i s p a r i t y = X R − X T , 视差~~~disparity = X_R - X_T,    disparity=XRXT,

    深 度     z / B a s e l i n e = ( z − f ) / ( B a s e l i n e − d i s p a r i t y ) , 深度~~~z / Baseline = (z - f) /( Baseline - disparity),    z/Baseline=(zf)/(Baselinedisparity)
    得 到 得到
                z = f ∗ B a s e l i n e / d i s p a r i t y ~~~~~~~~~~~z = f*Baseline/disparity            z=fBaseline/disparity, 也即视差与深度成反比。
    重投影矩阵Q
    1 / − Q [ 14 ]     b a s e l i n e ( m m )         根 据 标 定 的 相 机 外 参 计 算 。 如 果 只 需 要 相 对 深 度 取 1 即 可 1 / -Q[14] ~~~baseline (mm) ~~~~~~~ 根据标定的相机外参计算。如果只需要相对深度取1即可 1/Q[14]   baseline(mm)       1
    Q [ 11 ]             f o c a l   l e n g t h ( p x )     由 标 定 内 参 得 到 Q[11] ~~~~ ~~~~~~~ focal~length (px) ~~~ 由标定内参得到 Q[11]           focal length(px)   

    以上的计算建立在双目相机的光轴完全平行,但这是不可能的,为此需要进行标定和矫正。
    矫正主函数:

    void StereoRectify(double *left_intrinsic, double *left_distort, double *right_intrinsic, double *right_distort,
    	double *rotation_mat, double *translation_vector, double *left_rota, double *right_rota, double *left_proj, double *right_proj, double *Q)
    

    旋转矩阵求逆:

    void mat33Inverse(double *PR, double *PRI) {
    	/* 3*3 matrix inverse */
    	double temp;
    	temp = PR[0] * PR[4] * PR[8] + PR[1] * PR[5] * PR[6] + PR[2] * PR[3] * PR[7] -
    		PR[2] * PR[4] * PR[6] - PR[1] * PR[3] * PR[8] - PR[0] * PR[5] * PR[7];
    	PRI[0] = (PR[4] * PR[8] - PR[5] * PR[7]) / temp;
    	PRI[1] = -(PR[1] * PR[8] - PR[2] * PR[7]) / temp;
    	PRI[2] = (PR[1] * PR[5] - PR[2] * PR[4]) / temp;
    	PRI[3] = -(PR[3] * PR[8] - PR[5] * PR[6]) / temp;
    	PRI[4] = (PR[0] * PR[8] - PR[2] * PR[6]) / temp;
    	PRI[5] = -(PR[0] * PR[5] - PR[2] * PR[3]) / temp;
    	PRI[6] = (PR[3] * PR[7] - PR[4] * PR[6]) / temp;
    	PRI[7] = -(PR[0] * PR[7] - PR[1] * PR[6]) / temp;
    	PRI[8] = (PR[0] * PR[4] - PR[1] * PR[3]) / temp;
    }
    
    // 3*3 -> 3*1 rodrigues Transform
    rodriguesTransform(inv_rotation_mat, u, v, w);
    

    罗格里斯变换使用到奇异值分解,使用的《Numerical Recipes in C》一书中的代码 svdcmp.c
    在这里插入图片描述

    
    void rodriguesTransform(double *inv_rotation_mat, double **u, double **v, double w[])
    {	 /*
         * 使用 ** 来声明,然后用dmatrix来申请空间
         * 这样在函数引用矩阵时,就不用声明矩阵大小了
         */
    	//double **a;
    	int i, j, k;
    	double t;
    	double t1[MN+1], t2[MN+1];
    	/* 矩阵均以M,N中的最大值来申请空间,避免越界 */
    	//a = dmatrix(1, MN, 1, MN);  // inv_rotation_mat
    	for (i = 1; i <= M; i++) {
    		for (j = 1; j <= N; j++) {
    			//u[i][j] = a[i][j];
    			u[i][j] = inv_rotation_mat[i * 3 + j - 4];
    		}
    	}
    	svdcmp(u, MN, MN, w, v);
    	/* Sort the singular values in descending order */
    	for (i = 1; i <= N; i++) {
    		for (j = i + 1; j <= N; j++) {
    			if (w[i] < w[j]) { /* 对特异值排序 */
    				t = w[i];
    				w[i] = w[j];
    				w[j] = t;
    				/* 同时也要把矩阵U,V的列位置交换 */
    				/* 矩阵U */
    				for (k = 1; k <= M; k++) {
    					t1[k] = u[k][i];
    				}
    				for (k = 1; k <= M; k++) {
    					u[k][i] = u[k][j];
    				}
    				for (k = 1; k <= M; k++) {
    					u[k][j] = t1[k];
    				}
    
    				/* 矩阵V */
    				for (k = 1; k <= N; k++) {
    					t2[k] = v[k][i];
    				}
    				for (k = 1; k <= N; k++) {
    					v[k][i] = v[k][j];
    				}
    				for (k = 1; k <= N; k++) {
    					v[k][j] = t2[k];
    				}
    			}
    		}
    	}
    }
    
    	// u * v'
    	R[0] = u[1][1] * v[1][1] + u[1][2] * v[1][2] + u[1][3] * v[1][3];
    	R[1] = u[1][1] * v[2][1] + u[1][2] * v[2][2] + u[1][3] * v[2][3];
    	R[2] = u[1][1] * v[3][1] + u[1][2] * v[3][2] + u[1][3] * v[3][3];
    	R[3] = u[2][1] * v[1][1] + u[2][2] * v[1][2] + u[2][3] * v[1][3];
    	R[4] = u[2][1] * v[2][1] + u[2][2] * v[2][2] + u[2][3] * v[2][3];
    	R[5] = u[2][1] * v[3][1] + u[2][2] * v[3][2] + u[2][3] * v[3][3];
    	R[6] = u[3][1] * v[1][1] + u[3][2] * v[1][2] + u[3][3] * v[1][3];
    	R[7] = u[3][1] * v[2][1] + u[3][2] * v[2][2] + u[3][3] * v[2][3];
    	R[8] = u[3][1] * v[3][1] + u[3][2] * v[3][2] + u[3][3] * v[3][3];
    
    	double r[3];
    	r[0] = R[7] - R[5];
    	r[1] = R[2] - R[6];
    	r[2] = R[3] - R[1];
    
    	float s = sqrt((r[0] * r[0] + r[1] * r[1] + r[2] * r[2]) * 0.25);
    	float c = (R[0] + R[4] + R[8] - 1) * 0.5;
    	c = c > 1. ? 1. : c < -1. ? -1. : c;  // 1 <c> -1
    	float theta = acos(c);
    	
    	double rr[3]; // 1*3 一行三列
    	if (s < 1.0e-5)
    	{
    		float t;
    		if (c > 0)
    		{
    			double rr[3] = { 0, 0, 0 };
    		}
    		else
    		{
    			t = (R[0] + 1) * 0.5;
    			rr[0] = sqrt(MAX(t, float(0.)));
    			t = (R[4] + 1) * 0.5;
    			rr[1] = sqrt(MAX(t, float(0.))) * (R[1] < 0 ? -1. : 1.);
    			t = (R[8] + 1) * 0.5;
    			rr[2] = sqrt(MAX(t, float(0.))) * (R[2] < 0 ? -1. : 1.);
    			if (fabs(rr[0]) < fabs(rr[1]) && fabs(rr[0]) < fabs(rr[2]) && (R[5] > 0) != (rr[1] * rr[2] > 0))
    				rr[2] = -rr[2];
    			double rrsqrt = sqrt(rr[0] * rr[0] + rr[1] * rr[1] + rr[2] * rr[2]);
    			theta /= rrsqrt;
    			rr[0] = theta * rr[0];
    			rr[1] = theta * rr[1];
    			rr[2] = theta * rr[2];			
    		}
    	}
    	else
    	{
    		float vth = 1 / (2 * s);
    		vth *= theta;
    		rr[0] = vth * r[0];
    		rr[1] = vth * r[1];
    		rr[2] = vth * r[2];		
    	}
    
    	double eul[3];
    	eul[0] = rr[0] * (-0.5);
    	eul[1] = rr[1] * (-0.5);
    	eul[2] = rr[2] * (-0.5);
    
    std::string GetExePath()
    {
    	char szFilePath[MAX_PATH + 1] = { 0 };
    	GetModuleFileNameA(NULL, szFilePath, MAX_PATH);
    	/*
    	strrchr:函数功能:查找一个字符c在另一个字符串str中末次出现的位置(也就是从str的右侧开始查找字符c首次出现的位置),
    	并返回这个位置的地址。如果未能找到指定字符,那么函数将返回NULL。
    	使用这个地址返回从最后一个字符c到str末尾的字符串。
    	*/
    	(strrchr(szFilePath, '\\'))[0] = 0; // 删除文件名,只获得路径字串//
    	std::string path = szFilePath;
    
    	int pos = path.rfind("\\", path.length());//从后往前寻找第一个/出现的位置
    	path = path.substr(0, pos);//剪切[0,pos]
    	return path;
    }
    
    void getYamlParamters(std::string file_extrinsics, std::string file_intrisics)
    {
    	cv::FileStorage fs_read(file_intrisics, cv::FileStorage::READ);
    	if (fs_read.isOpened()) {
    		NDouble cameraMatrixL[3 * 3], cameraMatrixR[3 * 3], distCoeffL[5], distCoeffR[5];
    		fs_read["cameraMatrixL"] >> cameraMatrixL;
    		fs_read["cameraDistcoeffL"] >> distCoeffL;
    		fs_read["cameraMatrixR"] >> cameraMatrixR;
    		fs_read["cameraDistcoeffR"] >> distCoeffR;
    		fs_read.release();
    	}
    	fs_read.open(file_extrinsics, cv::FileStorage::READ);
    	if (fs_read.isOpened()) {
    		NDouble Rotation_mat[3 * 3], Translation_vector[3];
    		fs_read["R"] >> Rotation_mat;
    		fs_read["T"] >> Translation_vector;
    		fs_read.release();
    	}
    }
    
    	FileStorage fs("intrisics.yml", FileStorage::WRITE);
    	//time_t rawtime;
    	//time(&rawtime);
    	/*struct tm tm = *localtime(&(time_t) { time (NULL) });
    	char str[26];
    	asctime_s(str, sizeof str, &tm);
    	fs << "Time" << str;*/
    
    	if (fs.isOpened())
    	{
    		fs << "cameraMatrixL" << cameraMatrix << "cameraDistcoeffL" << distCoeffs << "cameraMatrixR" << cameraMatrixR << "cameraDistcoeffR" << distCoeffsR;
    		fs.release();
    		cout << "cameraMatrixL=:" << cameraMatrix << endl << "cameraDistcoeffL=:" << distCoeffs << endl << "cameraMatrixR=:" << cameraMatrixR << endl << "cameraDistcoeffR=:" << distCoeffsR << endl;
    	}
    	else
    	{
    		cout << "Error: can not save the intrinsics!!!!" << endl;
    	}
    
    	fs.open("extrinsics.yml", FileStorage::WRITE);
    	if (fs.isOpened())
    	{
    		fs << "R" << R << "T" << T << "E" << E << "F" << F << "Rl" << Rl << "Rr" << Rr << "Pl" << Pl << "Pr" << Pr << "Q" << Q;
    		cout << "R=" << R << endl << "T=" << T << endl << "E=" << E << endl << "F=" << F << endl << "Rl=" << Rl << endl << "Rr" << Rr << endl << "Pl" << Pl << endl << "Pr" << Pr << endl << "Q" << Q << endl;
    		fs.release();
    	}
    	else
    	{
    		cout << "Error: can not save the extrinsic parameters\n";
    	}
    
    #include <iostream>
    #include <sstream>
    #include <time.h>
    #include <stdio.h>
    #include <fstream>
    
    #include <opencv2/core/core.hpp>
    #include <opencv2/imgproc/imgproc.hpp>
    #include <opencv2/calib3d/calib3d.hpp>
    #include <opencv2/highgui/highgui.hpp>
    
    using namespace cv;
    using namespace std;
    //#define calibration
    
    int getImagePathList(std::string folder, std::vector<cv::String> &imagePathList);
    void calRealPoint(vector<vector<Point3f>>& obj, int boardWidth, int boardHeight, int imgNumber, int squareSize);
    void outputCameraParam(Mat cameraMatrix, Mat distCoeffs, Mat cameraMatrixR, Mat distCoeffsR, Mat R, Mat T, Mat E, Mat F, Mat Rl, Mat Rr, Mat Pl, Mat Pr, Mat Q);
    
    int getImagePathList(std::string folder, std::vector<cv::String> &imagePathList)
    {
    	//search all the image in a folder
    	cv::glob(folder, imagePathList);
    	return 0;
    }
    
    int main()
    {
    	//ifstream fin("left_img.txt");             /* 标定所用图像文件的路径 */
    	//ofstream fout("caliberation_result_left640.txt");  /* 保存标定结果的文件 */
    
    	// 读取每一幅图像,从中提取出角点,然后对角点进行亚像素精确化
    	int image_count = 0;  /* 图像数量 */
    	Size image_size;      /* 图像的尺寸 */
    	Size board_size = Size(8, 11);             /* 标定板上每行、列的角点数 */
    	vector<Point2f> image_points_buf;         /* 缓存每幅图像上检测到的角点 */
    	vector<vector<Point2f>> image_points_seq; /* 保存检测到的所有角点 */
    	string filenameL;      // 图片名
    	vector<string> filenamesL;
    
    	cout << "请输入左棋盘格目录路径: " << endl;
    	string checkboard_path;
    	cin >> checkboard_path;
    	cout << "Checkboard left path: " << checkboard_path << endl << endl;
    
    	cout << "接着输入右棋盘格目录路径: " << endl;
    	string checkboard_pathR;
    	cin >> checkboard_pathR;
    	cout << "Checkboard right path: " << checkboard_pathR << endl << endl;
    
    	String folder = "F:/code/imgs/left_biao1/"; // checkboard_path // "F:/kinect/multi_thread/chess/chess/left/";//"F:/kinect/multi_thread/chess/RGB/left640/";  "F:/kinect/multi_thread/chess/RGB/left1/";// "F:/code/imgs/left/0.png"
    	std::vector<String> imagePathList;
    	getImagePathList(folder, imagePathList);
    	// right folder
    	String folderight = "F:/code/imgs/right_biao1/"; // checkboard_pathR // "F:/kinect/multi_thread/chess/chess/right/";// "F:/kinect/multi_thread/chess/RGB/right640/";   "F:/kinect/multi_thread/chess/RGB/right1/";// "F:/code/imgs/right/0.png"
    	std::vector<String> imagePathListright;
    	getImagePathList(folderight, imagePathListright);
    
    	//while (getline(fin, filename))
    	for (int i = 0; i < imagePathList.size(); i++)
    	{
    		++image_count;
    		filenameL = imagePathList[i];
    		Mat imageInput = imread(filenameL);
    
    		std::cout << filenameL << endl;
    		
    
    		// 读入第一张图片时获取图片大小
    		if (image_count == 1)
    		{
    			image_size.width = imageInput.cols;
    			image_size.height = imageInput.rows;
    		}
    
    		/* 提取角点 */
    		if (0 == findChessboardCorners(imageInput, board_size, image_points_buf))
    		{
    			//cout << "can not find chessboard corners!\n";  // 找不到角点
    			cout << "**" << filenameL << "** can not find chessboard corners!\n";
    			//exit(1);
    			image_count--;
    		}
    		else
    		{
    			filenamesL.push_back(filenameL);
    			Mat view_gray;
    			cvtColor(imageInput, view_gray, COLOR_RGB2GRAY);  // 转灰度图IMREAD_GRAYSCALE
    
    			/* 亚像素精确化 */
    			// image_points_buf 初始的角点坐标向量,同时作为亚像素坐标位置的输出
    			// Size(5,5) 搜索窗口大小
    			// (-1,-1)表示没有死区
    			// TermCriteria 角点的迭代过程的终止条件, 可以为迭代次数和角点精度两者的组合
    			cornerSubPix(view_gray, image_points_buf, Size(5, 5), Size(-1, -1), TermCriteria(TermCriteria::EPS + TermCriteria::COUNT, 30, 0.1)); // CV_TERMCRIT_ITER、CV_TERMCRIT_EPS
    
    			image_points_seq.push_back(image_points_buf);  // 保存亚像素角点
    
    			/* 在图像上显示角点位置 */
    			drawChessboardCorners(view_gray, board_size, image_points_buf, false); // 用于在图片中标记角点
    
    			imshow("Camera Calibration", view_gray);       // 显示图片
    
    			waitKey(10); //暂停0.5S      
    		}
    	}
    	int CornerNum = board_size.width * board_size.height;  // 每张图片上总的角点数
    	cout << board_size.width << board_size.height << image_size.width << endl;
    	//-------------以下是摄像机标定------------------
    
    	/*棋盘三维信息*/
    	Size square_size = Size(25, 25); // Size(60, 60);         /* 实际测量得到的标定板上每个棋盘格的大小 */
    	vector<vector<Point3f>> object_points;   /* 保存标定板上角点的三维坐标 */
    
    	/*内外参数*/
    	Mat cameraMatrix = Mat(3, 3, CV_32FC1, Scalar::all(0));  /* 摄像机内参数矩阵 */
    	vector<int> point_counts;   // 每幅图像中角点的数量
    	Mat distCoeffs = Mat(1, 5, CV_32FC1, Scalar::all(0));       /* 摄像机的5个畸变系数:k1,k2,p1,p2,k3 */
    	vector<Mat> tvecsMat;      /* 每幅图像的旋转向量 */
    	vector<Mat> rvecsMat;      /* 每幅图像的平移向量 */
    
    	/* 初始化标定板上角点的三维坐标 */
    	int i, j, t;
    	for (t = 0; t < image_count; t++)
    	{
    		vector<Point3f> tempPointSet;
    		for (i = 0; i < board_size.height; i++)
    		{
    			for (j = 0; j < board_size.width; j++)
    			{
    				Point3f realPoint;
    
    				/* 假设标定板放在世界坐标系中z=0的平面上 */
    				realPoint.x = i * square_size.width;
    				realPoint.y = j * square_size.height;
    				realPoint.z = 0;
    				tempPointSet.push_back(realPoint);
    			}
    		}
    		object_points.push_back(tempPointSet);
    	}
    
    	/* 初始化每幅图像中的角点数量,假定每幅图像中都可以看到完整的标定板 */
    	for (i = 0; i < image_count; i++)
    	{
    		point_counts.push_back(board_size.width * board_size.height);
    	}
    	cout << "\n begin calibration \n" << endl;
    	/* 开始标定 */
    	// object_points 世界坐标系中的角点的三维坐标
    	// image_points_seq 每一个内角点对应的图像坐标点
    	// image_size 图像的像素尺寸大小
    	// cameraMatrix 输出,内参矩阵
    	// distCoeffs 输出,畸变系数
    	// rvecsMat 输出,旋转向量
    	// tvecsMat 输出,位移向量
    	// 0 标定时所采用的算法
    	calibrateCamera(object_points, image_points_seq, image_size, cameraMatrix, distCoeffs, rvecsMat, tvecsMat, 0);
    
    	//------------------------标定完成------------------------------------
    
    	// -------------------对标定结果进行评价------------------------------
    
    	double total_err = 0.0;         /* 所有图像的平均误差的总和 */
    	double err = 0.0;               /* 每幅图像的平均误差 */
    	vector<Point2f> image_points2;  /* 保存重新计算得到的投影点 */
    	cout << "每幅图像的标定误差:\n";
    
    	for (i = 0; i < image_count; i++)
    	{
    		vector<Point3f> tempPointSet = object_points[i];
    
    		/* 通过得到的摄像机内外参数,对空间的三维点进行重新投影计算,得到新的投影点 */
    		projectPoints(tempPointSet, rvecsMat[i], tvecsMat[i], cameraMatrix, distCoeffs, image_points2);
    
    		/* 计算新的投影点和旧的投影点之间的误差*/
    		vector<Point2f> tempImagePoint = image_points_seq[i];
    		Mat tempImagePointMat = Mat(1, tempImagePoint.size(), CV_32FC2);
    		Mat image_points2Mat = Mat(1, image_points2.size(), CV_32FC2);
    
    		for (int j = 0; j < tempImagePoint.size(); j++)
    		{
    			image_points2Mat.at<Vec2f>(0, j) = Vec2f(image_points2[j].x, image_points2[j].y);
    			tempImagePointMat.at<Vec2f>(0, j) = Vec2f(tempImagePoint[j].x, tempImagePoint[j].y);
    		}
    		err = norm(image_points2Mat, tempImagePointMat, NORM_L2);
    		total_err += err /= point_counts[i];
    		cout << "第" << i + 1 << "幅图像的平均误差:" << err << "像素" << endl;
    	}
    	cout << "总体平均误差:" << total_err / image_count << "像素" << endl << endl;
    
    	//-------------------------评价完成---------------------------------------------
    
    	//-----------------------保存定标结果------------------------------------------- 
    	Mat rotation_matrix = Mat(3, 3, CV_32FC1, Scalar::all(0));  /* 保存每幅图像的旋转矩阵 */
    	cout << "相机内参数矩阵:" << endl;
    	cout << cameraMatrix << endl << endl;
    	cout << "畸变系数:\n";
    	cout << distCoeffs << endl << endl << endl;
    	//for (int i = 0; i < image_count; i++)
    	//{
    	//	cout << "第" << i + 1 << "幅图像的旋转向量:" << endl;
    	//	cout << tvecsMat[i] << endl;
    
    	//	/* 将旋转向量转换为相对应的旋转矩阵 */
    	//	Rodrigues(tvecsMat[i], rotation_matrix);
    	//	cout << "第" << i + 1 << "幅图像的旋转矩阵:" << endl;
    	//	cout << rotation_matrix << endl;
    	//	cout << "第" << i + 1 << "幅图像的平移向量:" << endl;
    	//	cout << rvecsMat[i] << endl << endl;
    	//}
    	cout << "\n 左图标定完毕!\n" << endl;
    
    	// 右图
    	image_count = 0;
    	string filenameR;      // 图片名
    	vector<string> filenamesR;
    	vector<vector<Point2f>> image_points_seqR; /* 保存检测到的所有角点 */
    	for (int i = 0; i < imagePathListright.size(); i++)
    	{
    		++image_count;
    		filenameR = imagePathListright[i];
    		Mat imageInputR = imread(filenameR);
    
    		std::cout << filenameR << endl;
    		//
    
    		// 读入第一张图片时获取图片大小
    		if (image_count == 1)
    		{
    			image_size.width = imageInputR.cols;
    			image_size.height = imageInputR.rows;
    		}
    
    		/* 提取角点 */
    		if (0 == findChessboardCorners(imageInputR, board_size, image_points_buf))
    		{
    			//cout << "can not find chessboard corners!\n";  // 找不到角点
    			cout << "**" << filenameR << "** can not find chessboard corners!\n";
    			//exit(1);
    			image_count--;
    		}
    		else
    		{
    			filenamesR.push_back(filenameR);
    			Mat view_gray;
    			cvtColor(imageInputR, view_gray, COLOR_RGB2GRAY);  // 转灰度图IMREAD_GRAYSCALE
    
    			/* 亚像素精确化 */
    			// image_points_buf 初始的角点坐标向量,同时作为亚像素坐标位置的输出
    			// Size(5,5) 搜索窗口大小
    			// (-1,-1)表示没有死区
    			// TermCriteria 角点的迭代过程的终止条件, 可以为迭代次数和角点精度两者的组合
    			cornerSubPix(view_gray, image_points_buf, Size(5, 5), Size(-1, -1), TermCriteria(TermCriteria::EPS + TermCriteria::COUNT, 30, 0.1)); // CV_TERMCRIT_ITER、CV_TERMCRIT_EPS
    
    			image_points_seqR.push_back(image_points_buf);  // 保存亚像素角点
    
    			/* 在图像上显示角点位置 */
    			drawChessboardCorners(view_gray, board_size, image_points_buf, false); // 用于在图片中标记角点
    
    			imshow("Camera Calibration", view_gray);       // 显示图片
    
    			waitKey(10); //暂停0.5S      
    		}
    	}
    	CornerNum = board_size.width * board_size.height;  // 每张图片上总的角点数
    	cout << board_size.width << board_size.height << image_size.width << endl;
    	//-------------以下是摄像机标定------------------
    
    	/*棋盘三维信息*/
    	//Size square_size = Size(25, 25); // Size(60, 60);         /* 实际测量得到的标定板上每个棋盘格的大小 */
    	vector<vector<Point3f>> object_pointsR;   /* 保存标定板上角点的三维坐标 */
    
    	/*内外参数*/
    	Mat cameraMatrixR = Mat(3, 3, CV_32FC1, Scalar::all(0));  /* 摄像机内参数矩阵 */
    	vector<int> point_countsR;   // 每幅图像中角点的数量
    	Mat distCoeffsR = Mat(1, 5, CV_32FC1, Scalar::all(0));       /* 摄像机的5个畸变系数:k1,k2,p1,p2,k3 */
    	vector<Mat> tvecsMatR;      /* 每幅图像的旋转向量 */
    	vector<Mat> rvecsMatR;      /* 每幅图像的平移向量 */
    
    	/* 初始化标定板上角点的三维坐标 */
    	//int i, j, t;
    	for (t = 0; t < image_count; t++)
    	{
    		vector<Point3f> tempPointSet;
    		for (i = 0; i < board_size.height; i++)
    		{
    			for (j = 0; j < board_size.width; j++)
    			{
    				Point3f realPoint;
    
    				/* 假设标定板放在世界坐标系中z=0的平面上 */
    				realPoint.x = i * square_size.width;
    				realPoint.y = j * square_size.height;
    				realPoint.z = 0;
    				tempPointSet.push_back(realPoint);
    			}
    		}
    		object_pointsR.push_back(tempPointSet);
    	}
    
    	/* 初始化每幅图像中的角点数量,假定每幅图像中都可以看到完整的标定板 */
    	for (i = 0; i < image_count; i++)
    	{
    		point_countsR.push_back(board_size.width * board_size.height);
    	}
    	cout << "\n begin calibration \n" << endl;
    	/* 开始标定 */
    	// object_pointsR 世界坐标系中的角点的三维坐标
    	// image_points_seqR 每一个内角点对应的图像坐标点
    	// image_size 图像的像素尺寸大小
    	// cameraMatrix 输出,内参矩阵
    	// distCoeffs 输出,畸变系数
    	// rvecsMatR 输出,旋转向量
    	// tvecsMatR 输出,位移向量
    	// 0 标定时所采用的算法
    	calibrateCamera(object_pointsR, image_points_seqR, image_size, cameraMatrixR, distCoeffsR, rvecsMatR, tvecsMatR, 0);
    
    	//------------------------标定完成------------------------------------
    
    	// -------------------对标定结果进行评价------------------------------
    
    	total_err = 0.0;         /* 所有图像的平均误差的总和 */
    	err = 0.0;               /* 每幅图像的平均误差 */
    	vector<Point2f> image_points2R;  /* 保存重新计算得到的投影点 */
    	cout << "每幅图像的标定误差:\n";
    
    	for (i = 0; i < image_count; i++)
    	{
    		vector<Point3f> tempPointSet = object_pointsR[i];
    
    		/* 通过得到的摄像机内外参数,对空间的三维点进行重新投影计算,得到新的投影点 */
    		projectPoints(tempPointSet, rvecsMatR[i], tvecsMatR[i], cameraMatrixR, distCoeffsR, image_points2R);
    
    		/* 计算新的投影点和旧的投影点之间的误差*/
    		vector<Point2f> tempImagePoint = image_points_seqR[i];
    		Mat tempImagePointMat = Mat(1, tempImagePoint.size(), CV_32FC2);
    		Mat image_points2Mat = Mat(1, image_points2R.size(), CV_32FC2);
    
    		for (int j = 0; j < tempImagePoint.size(); j++)
    		{
    			image_points2Mat.at<Vec2f>(0, j) = Vec2f(image_points2R[j].x, image_points2R[j].y);
    			tempImagePointMat.at<Vec2f>(0, j) = Vec2f(tempImagePoint[j].x, tempImagePoint[j].y);
    		}
    		err = norm(image_points2Mat, tempImagePointMat, NORM_L2);
    		total_err += err /= point_countsR[i];
    		cout << "第" << i + 1 << "幅图像的平均误差:" << err << "像素" << endl;
    	}
    	cout << "总体平均误差:" << total_err / image_count << "像素" << endl << endl;
    
    	//-------------------------评价完成---------------------------------------------
    
    	//-----------------------保存定标结果------------------------------------------- 
    	Mat rotation_matrixR = Mat(3, 3, CV_32FC1, Scalar::all(0));  /* 保存每幅图像的旋转矩阵 */
    	cout << "相机内参数矩阵:" << endl;
    	cout << cameraMatrixR << endl << endl;
    	cout << "畸变系数:\n";
    	cout << distCoeffsR << endl << endl << endl;
    	//for (int i = 0; i < image_count; i++)
    	//{
    	//	cout << "第" << i + 1 << "幅图像的旋转向量:" << endl;
    	//	cout << tvecsMatR[i] << endl;
    
    	//	/* 将旋转向量转换为相对应的旋转矩阵 */
    	//	Rodrigues(tvecsMatR[i], rotation_matrixR);
    	//	cout << "第" << i + 1 << "幅图像的旋转矩阵:" << endl;
    	//	cout << rotation_matrixR << endl;
    	//	cout << "第" << i + 1 << "幅图像的平移向量:" << endl;
    	//	cout << rvecsMatR[i] << endl << endl;
    	//}
    	cout << "\n 右图标定完毕!\n" << endl;
    
    	//横向的角点数目
    	const int boardWidth = 8;
    	//纵向的角点数目
    	const int boardHeight = 11;
    	//总的角点数目
    	const int boardCorner = boardWidth * boardHeight;
    	//相机标定时需要采用的图像帧数
    	const int frameNumber = image_count;
    	//标定板黑白格子的大小 单位是mm
    	const int squareSize = 25;
    	//标定板的总内角点
    	const Size boardSize = Size(boardWidth, boardHeight);
    	Mat R, T, E, F;
    	//R旋转矢量 T平移矢量 E本征矩阵 F基础矩阵
    	vector<Mat> rvecs; //R
    	vector<Mat> tvecs; //T
    	//左边摄像机所有照片角点的坐标集合
    	vector<vector<Point2f>> imagePointL;
    	//右边摄像机所有照片角点的坐标集合
    	vector<vector<Point2f>> imagePointR;
    	//各图像的角点的实际的物理坐标集合
    	vector<vector<Point3f>> objRealPoint;
    	//左边摄像机某一照片角点坐标集合
    	vector<Point2f> cornerL;
    	//右边摄像机某一照片角点坐标集合
    	vector<Point2f> cornerR;
    
    	Mat rgbImageL, grayImageL;
    	Mat rgbImageR, grayImageR;
    
    	Mat intrinsic;
    	Mat distortion_coeff;
    	//校正旋转矩阵R,投影矩阵P,重投影矩阵Q
    	Mat Rl, Rr, Pl, Pr, Q;
    	//映射表
    	Mat mapLx, mapLy, mapRx, mapRy;
    	Rect validROIL, validROIR;
    
    	int goodFrameCount = 0;
    
    	for (i = 0; i < frameNumber; i++) {
    		rgbImageL = imread(filenamesL[i], 1);
    		cvtColor(rgbImageL, grayImageL, COLOR_RGB2GRAY);
    
    		rgbImageR = imread(filenamesR[i], 1);
    		cvtColor(rgbImageR, grayImageR, COLOR_RGB2GRAY);
    
    		bool isFindL, isFindR;
    		isFindL = findChessboardCorners(rgbImageL, boardSize, cornerL);
    		isFindR = findChessboardCorners(rgbImageR, boardSize, cornerR);
    		if (isFindL == true && isFindR == true)
    		{
    			cornerSubPix(grayImageL, cornerL, Size(5, 5), Size(-1, 1), TermCriteria(TermCriteria::EPS | TermCriteria::COUNT, 20, 0.1));
    			drawChessboardCorners(rgbImageL, boardSize, cornerL, isFindL);
    			imshow("chessboardL", rgbImageL);
    			imagePointL.push_back(cornerL);
    
    			cornerSubPix(grayImageR, cornerR, Size(5, 5), Size(-1, -1), TermCriteria(TermCriteria::EPS | TermCriteria::COUNT, 20, 0.1));
    			drawChessboardCorners(rgbImageR, boardSize, cornerR, isFindR);
    			imshow("chessboardR", rgbImageR);
    			imagePointR.push_back(cornerR);
    
    			goodFrameCount++;
    			cout << "the image" << goodFrameCount << " is good" << endl;
    		}
    		else
    		{
    			cout << "the image is bad please try again" << endl;
    		}
    		if (waitKey(10) == 'q')
    		{
    			break;
    		}
    	}
    	//计算实际的校正点的三维坐标,根据实际标定格子的大小来设置
    	calRealPoint(objRealPoint, boardWidth, boardHeight, frameNumber, squareSize);
    	cout << "cal real successful" << endl;
    
    	//标定摄像头
    	double rms = stereoCalibrate(objRealPoint, imagePointL, imagePointR,
    		cameraMatrix, distCoeffs,
    		cameraMatrixR, distCoeffsR,
    		image_size, R, T, E, F, CALIB_USE_INTRINSIC_GUESS,
    		TermCriteria(TermCriteria::COUNT + TermCriteria::EPS, 100, 1e-5));
    
    	cout << "Stereo Calibration done with RMS error = " << rms << endl;
    	stereoRectify(cameraMatrix, distCoeffs, cameraMatrixR, distCoeffsR, image_size, R, T, Rl,
    		Rr, Pl, Pr, Q, CALIB_ZERO_DISPARITY, -1, image_size, &validROIL, &validROIR);
    
    	//摄像机校正映射
    	initUndistortRectifyMap(cameraMatrix, distCoeffs, Rl, Pl, image_size, CV_32FC1, mapLx, mapLy);
    	initUndistortRectifyMap(cameraMatrixR, distCoeffsR, Rr, Pr, image_size, CV_32FC1, mapRx, mapRy);
    
    	Mat rectifyImageL, rectifyImageR;
    	cvtColor(grayImageL, rectifyImageL, COLOR_GRAY2BGR); //CV_GRAY2BGR
    	cvtColor(grayImageR, rectifyImageR, COLOR_GRAY2BGR);
    
    	imshow("Recitify Before", rectifyImageL);
    	cout << "按Q1退出..." << endl;
    	//经过remap之后,左右相机的图像已经共面并且行对准了
    	Mat rectifyImageL2, rectifyImageR2;
    	remap(rectifyImageL, rectifyImageL2, mapLx, mapLy, INTER_LINEAR);
    	remap(rectifyImageR, rectifyImageR2, mapRx, mapRy, INTER_LINEAR);
    	cout << "按Q2退出..." << endl;
    
    	imshow("rectifyImageL", rectifyImageL2);
    	imshow("rectifyImageR", rectifyImageR2);
    
    	outputCameraParam(cameraMatrix, distCoeffs, cameraMatrixR, distCoeffsR, R, T, E, F, Rl, Rr, Pl, Pr, Q);
    
    	//显示校正结果
    	Mat canvas;
    	double sf;
    	int w, h;
    	sf = 600. / MAX(image_size.width, image_size.height);
    	w = cvRound(image_size.width * sf);
    	h = cvRound(image_size.height * sf);
    	canvas.create(h, w * 2, CV_8UC3);
    
    	//左图像画到画布上
    	Mat canvasPart = canvas(Rect(0, 0, w, h));
    	resize(rectifyImageL2, canvasPart, canvasPart.size(), 0, 0, INTER_AREA);
    	Rect vroiL(cvRound(validROIL.x*sf), cvRound(validROIL.y*sf),
    		cvRound(validROIL.width*sf), cvRound(validROIL.height*sf));
    	rectangle(canvasPart, vroiL, Scalar(0, 0, 255), 3, 8);
    
    	cout << "Painted ImageL" << endl;
    
    	//右图像画到画布上
    	canvasPart = canvas(Rect(w, 0, w, h));
    	resize(rectifyImageR2, canvasPart, canvasPart.size(), 0, 0, INTER_LINEAR);
    	Rect vroiR(cvRound(validROIR.x*sf), cvRound(validROIR.y*sf),
    		cvRound(validROIR.width*sf), cvRound(validROIR.height*sf));
    	rectangle(canvasPart, vroiR, Scalar(0, 255, 0), 3, 8);
    
    	cout << "Painted ImageR" << endl;
    
    	//画上对应的线条
    	for (int i = 0; i < canvas.rows; i += 16)
    		line(canvas, Point(0, i), Point(canvas.cols, i), Scalar(0, 255, 0), 1, 8);
    
    	imshow("rectified", canvas);
    
    	cout << "wait key" << endl;
    	waitKey(0);
    	return 0;
    }
    
    /*计算标定板上模块的实际物理坐标*/
    void calRealPoint(vector<vector<Point3f>>& obj, int boardWidth, int boardHeight, int imgNumber, int squareSize)
    {
    	vector<Point3f> imgpoint;
    	for (int rowIndex = 0; rowIndex < boardHeight; rowIndex++)
    	{
    		for (int colIndex = 0; colIndex < boardWidth; colIndex++)
    		{
    			imgpoint.push_back(Point3f(rowIndex * squareSize, colIndex * squareSize, 0));
    		}
    	}
    	for (int imgIndex = 0; imgIndex < imgNumber; imgIndex++)
    	{
    		obj.push_back(imgpoint);
    	}
    }
    
    展开全文
  • 这个实现了双目立体视觉矫正,采用matlab编程。
  • 双目矫正及视差图的计算 立体匹配主要是通过找出每对图像间的对应关系,根据三角测量原理,得到视差图;在获得了视差信息后,根据投影模型很容易地可以得到原始图像的深度信息和三维信息。
  • 014-双目矫正

    2019-07-27 17:55:31
    基于双目视觉的三维重建与测量技术研究 ​ ​     ​ ​ 0.26 这个有转动棋盘 、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、 ​ ​ 没有转动情况下情况良好 、、、、...

    【1】以前的笔记,具体内容需要者自取吧。

     

    单目 opencv标定根据的是 https://blog.csdn.net/t247555529/article/details/47836233

    单目opencv标定根据的是 https://blog.csdn.net/qq_35971623/article/details/78297911?locationNum=1&fps=1

    MATLAB 单目和双目根据的是 https://blog.csdn.net/kaspar1992/article/details/54344965

    搜索关键词 视差图 深度图 孔洞 空洞

    空洞填充 https://wenku.baidu.com/view/c2c40c85fe4733687f21aaa3.html 【两次滤波】

    https://www.cnblogs.com/riddick/p/8486223.html 【给了一部分代码在底部】

    https://www.cnblogs.com/riddick/p/8486223.html 代码放到N盘了哈

    自带标定例子能达到下面的效果,所以。。 标定是否达标,就以这个为标准吧

    理论上的研究https://wenku.baidu.com/view/e47de0dbc9d376eeaeaad1f34693daef5ef7133f.html

    进行摄像头定标时,棋盘方格的实际大小 square_size (默认为 1.0f )的设置对定标参数是否有影响?

    @scyscyao :当然有。在标定时,需要指定一个棋盘方格的长度,这个长度(一般以毫米为单位,如果需要更精确可以设为0.1毫米量级)与实际长度相同,标 定得出的结果才能用于实际距离测量。一般如果尺寸设定准确的话,通过立体标定得出的Translation向量的第一个分量Tx的绝对值就是左右摄像头的中心距。一般可以用这个来验证立体标定的准确度。比如我设定的棋盘格大小为270 (27mm),最终得出的Tx大小就是602.8 (60.28mm),相当精确。”

     

    基于双目视觉的三维重建与测量技术研究

     

     

    0.26 这个有转动棋盘

    、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、

    没有转动情况下情况良好

    、、、、、、、、、、、、、、、、、、、、

     

     

    matlab标定:主要参考下面的程序

    https://blog.csdn.net/kaspar1992/article/details/54344965

     

     

    Aspect ratio optimized (est_aspect_ratio = 1) -> both components of fc are estimated (DEFAULT).

    Principal point optimized (center_optim=1) - (DEFAULT). To reject principal point, set center_optim=0

    Skew not optimized (est_alpha=0) - (DEFAULT)

    Distortion not fully estimated (defined by the variable est_dist):

    Sixth order distortion not estimated (est_dist(5)=0) - (DEFAULT) .

    Initialization of the principal point at the center of the image.

    Initialization of the intrinsic parameters using the vanishing points of planar patterns.

     

    Initialization of the intrinsic parameters - Number of images: 20

     

     

    Calibration parameters after initialization:

     

    Focal Length: fc = [ 939.72654 939.72654 ]

    Principal point: cc = [ 319.50000 239.50000 ]

    Skew: alpha_c = [ 0.00000 ] => angle of pixel = 90.00000 degrees

    Distortion: kc = [ 0.00000 0.00000 0.00000 0.00000 0.00000 ]

     

    Main calibration optimization procedure - Number of images: 20

    Gradient descent iterations: 1...2...3...4...5...6...7...8...9...10...11...12...13...14...15...16...17...18...19...20...21...22...done

    Estimation of uncertainties...done

     

     

    Calibration results after optimization (with uncertainties):

     

    Focal Length: fc = [ 922.20417 923.89379 ] +/- [ 6.35782 6.37689 ]

    Principal point: cc = [ 351.73299 262.49287 ] +/- [ 9.04650 10.18899 ]

    Skew: alpha_c = [ 0.00000 ] +/- [ 0.00000 ] => angle of pixel axes = 90.00000 +/- 0.00000 degrees

    Distortion: kc = [ -0.09798 -0.48136 0.00704 -0.00121 0.00000 ] +/- [ 0.04372 0.58554 0.00223 0.00245 0.00000 ]

    Pixel error: err = [ 0.39989 0.32289 ]

     

    Note: The numerical errors are approximately three times the standard deviations (for reference).

     

    ​​

     

    Note: The numerical errors are approximately three times the standard deviations (for reference).

     

     

    Number(s) of image(s) to show ([] = all images) =

    Pixel error: err = [0.39989 0.32289] (all active images)

     

    在面板中单击“Show Extrinsic”。外参(棋盘格相对于相机的相对位置)就以3D的形式显示出来了:

     

     

     

    Calibration results after optimization (with uncertainties):

     

    Focal Length: fc = [ 905.01767 906.38908 ] +/- [ 4.20204 4.22668 ]

    Principal point: cc = [ 354.96976 266.82158 ] +/- [ 5.97391 6.71897 ]

    Skew: alpha_c = [ 0.00000 ] +/- [ 0.00000 ] => angle of pixel axes = 90.00000 +/- 0.00000 degrees

    Distortion: kc = [ -0.15451 -0.38352 0.00664 -0.00141 0.00000 ] +/- [ 0.02869 0.37223 0.00122 0.00135 0.00000 ]

    Pixel error: err = [ 0.19065 0.29646 ]

     

    Note: The numerical errors are approximately three times the standard deviations (for reference).

     

    可以注意到只需要6次迭代就收敛了,并且没有进行初始化过程(因为优化是在前面标定的结果之上进行的)。上图

    中的两个值0.12668和0.12604分别是X和Y方向像素上投影的标准差。注意到标定参数的不确定性也进行了估算。

    数值大概是标准差的3倍。

    单击save ===》Saving calibration results under Calib_Results.mat

     

     

     

    去掉了三四这两张图片之后

    Calibration results after optimization (with uncertainties):

     

    Focal Length: fc = [ 895.24447 895.42671 ] +/- [ 3.75406 3.79119 ]

    Principal point: cc = [ 374.63834 242.42668 ] +/- [ 5.15280 5.72511 ]

    Skew: alpha_c = [ 0.00000 ] +/- [ 0.00000 ] => angle of pixel axes = 90.00000 +/- 0.00000 degrees

    Distortion: kc = [ -0.17715 -0.14770 0.00253 -0.00016 0.00000 ] +/- [ 0.02622 0.35614 0.00107 0.00101 0.00000 ]

    Pixel error: err = [ 0.17803 0.20835 ]

     

    Note: The numerical errors are approximately three times the standard deviations (for reference).

     

     

    Recommendation: Some distortion coefficients are found equal to zero (within their uncertainties).

    To reject them from the optimization set est_dist=[1;0;1;1;0] and run Calibration

    、、、、、、、、、、、、、、、、

    双目

    Main calibration optimization procedure - Number of images: 20 Gradient descent iterations: 1...2...3...4...5...6...7...8...9...10...11...12...13...14...15...16...17...18...19...20...21...22...23...done Estimation of uncertainties...done Calibration results after optimization (with uncertainties): Focal Length: fc = [ 903.36808 905.08398 ] +/- [ 4.35576 4.33065 ] Principal point: cc = [ 271.70839 203.90351 ] +/- [ 6.14347 6.96843 ] Skew: alpha_c = [ 0.00000 ] +/- [ 0.00000 ] => angle of pixel axes = 90.00000 +/- 0.00000 degrees Distortion: kc = [ -0.17976 -0.14665 0.00659 0.00245 0.00000 ] +/- [ 0.02416 0.17471 0.00119 0.00174 0.00000 ] Pixel error: err = [ 0.20973 0.29976 ] Note: The numerical errors are approximately three times the standard deviations (for reference).

    ​ right ​​ ​​ ​

     

     

     

     

     

     

    Calibration results after optimization (with uncertainties):

     

    Focal Length: fc = [ 890.07388 890.97664 ] +/- [ 4.05473 4.05219 ]

    Principal point: cc = [ 282.68313 188.02242 ] +/- [ 4.78063 5.94285 ]

    Skew: alpha_c = [ 0.00000 ] +/- [ 0.00000 ] => angle of pixel axes = 90.00000 +/- 0.00000 degrees

    Distortion: kc = [ -0.18932 -0.06016 0.00477 0.00296 0.00000 ] +/- [ 0.01927 0.16585 0.00101 0.00130 0.00000 ]

    Pixel error: err = [ 0.17969 0.18956 ]

     

    Note: The numerical errors are approximately three times the standard deviations (for reference).

     

     

    Recommendation: Some distortion coefficients are found equal to zero (within their uncertainties).

    To reject them from the optimization set est_dist=[1;0;1;1;0] and run Calibration

    http://blog.sina.com.cn/s/blog_5328beed0100lqtg.html

     

     

    Main stereo calibration optimization procedure - Number of pairs of images: 17

    Gradient descent iterations: 1...Disabling view 2 - Reason: the left and right images are found inconsistent (try help calib_stereo for more information)

    Disabling view 6 - Reason: the left and right images are found inconsistent (try help calib_stereo for more information)

    Disabling view 7 - Reason: the left and right images are found inconsistent (try help calib_stereo for more information)

    Disabling view 8 - Reason: the left and right images are found inconsistent (try help calib_stereo for more information)

    Disabling view 9 - Reason: the left and right images are found inconsistent (try help calib_stereo for more information)

    Disabling view 18 - Reason: the left and right images are found inconsistent (try help calib_stereo for more information)

    Disabling view 19 - Reason: the left and right images are found inconsistent (try help calib_stereo for more information)

    2...3...4...5...6...7...8...9...10...11...12...13...14...15...16...17...18...19...20...21...22...23...24...25...26...27...28...29...30...31...32...33...34...35...36...37...38...39...40...41...42...43...44...45...46...47...48...49...50...51...52...53...54...55...56...57...58...59...60...61...62...63...64...65...66...67...68...69...70...71...72...73...74...75...76...77...78...79...80...81...82...83...84...85...86...87...88...89...90...91...92...93...94...95...96...97...98...99...100...done

    Estimation of uncertainties...done

     

     

     

    Stereo calibration parameters after optimization:

     

     

    Intrinsic parameters of left camera:

     

    Focal Length: fc_left = [ 894.79814 896.53777 ] � [ 4.59451 4.58012 ]

    Principal point: cc_left = [ 275.85996 195.46365 ] � [ 4.91909 6.55289 ]

    Skew: alpha_c_left = [ 0.00000 ] � [ 0.00000 ] => angle of pixel axes = 90.00000 � 0.00000 degrees

    Distortion: kc_left = [ -0.20599 0.33673 0.00670 0.00225 0.00000 ] � [ 0.03529 0.56942 0.00128 0.00119 0.00000 ]

     

     

    Intrinsic parameters of right camera:

     

    Focal Length: fc_right = [ 894.79814 896.53777 ] � [ 4.59451 4.58012 ]

    Principal point: cc_right = [ 275.85996 195.46365 ] � [ 4.91909 6.55289 ]

    Skew: alpha_c_right = [ 0.00000 ] � [ 0.00000 ] => angle of pixel axes = 90.00000 � 0.00000 degrees

    Distortion: kc_right = [ -0.20599 0.33673 0.00670 0.00225 0.00000 ] � [ 0.03529 0.56942 0.00128 0.00119 0.00000 ]

     

     

    Extrinsic parameters (position of right camera wrt left camera):

     

    Rotation vector: om = [ -0.00000 -0.00000 -0.00000 ] � [ 0.00697 0.00641 0.00029 ]

    Translation vector: T = [ 0.00000 -0.00000 0.00000 ] � [ 0.25860 0.21652 2.22290 ]

     

     

    Note: The numerical errors are approximately three times the standard deviations (for reference).

     

    >>

    ​​​​

     

    一定要备份结果!!!!

    1。 Image names”按钮

    2. “Extract grid corners”按钮

    3. ​

    4.Calibration

    5.“Reproject on images” 输入一个空字符(直接按"Enter")作为“Number(s) of image(s) to show([]=all images)”来表示你想查看所有图像:

    6.在面板中单击“Show Extrinsic”

    7.单击面板中的“Recomp. corners ​

    8.然后通过单击“Calibration”进行一次标定优化:

    9.Save”保存标定结果(内参和外参)到matlab文件“Calib_Results.mat”

    10, Reproject on images”将网格点投影到原始图像中

    11 ,Analyse error”看

    12,单击“Show Extrinsic”看看棋盘格相对于相机的3D位置关系:

    13,角点的提取会调用三次“Recomp.corners”。第一次调用使用wintx=winty=9来处理图像1,2,

    3,4,6,9,10,11,12,13,14,15,16和17.然后选择自动模式:

    14,单击“Calibration”进行重新标定:

    15,通过单击“Analyse error”来检测误差:

    16,我们去除图像16,18,19,24和25然后重新进行标定:单击“Add/Suppress images

    17,重新“Calibration”进行标定:

    18,为了选择合理的畸变模型来使用,通常可视化对像素图像的畸变影响以及畸变的径向部分和切向部分

    的比对是非常有用的。为此,在matlab命令行运行visualize_distortions,就会有三张图出来:

    19,​

    第一幅图显示了整体的畸变模型对图像每个像素的影响。每个箭头表示由于镜头畸变而使一个像素发生的位移效果。

    可以看到图像角落处的像素移动了20个像素。

     

    畸变的切向部分。在这幅图中,最大的位移式1.4个

    像素,在图像的左上角。

     

     

    第三幅图显示了畸变的径向部分的影响。这幅图和第一幅图有点相似。说明畸变的切

    向部分相对于整体模型来说可以忽略不计。在第三幅图中,十字叉表示了图像的中心,而圆表示光心所在的位置。

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

    1. 单目标定

    这个教程将带你完整地利用20到25张平面棋盘格图像进行相机标定。

    这个教程将让你学会如何使用所有工具箱的特征:载入图像、提取图像角点、运行标定引擎、显示结果、控制精度

    添加和删减图像、图像矫正、导出标定不同格式的数据...这个教程对于刚开始使用工具箱的人来说非常重要。

     

    首先下载Matlab标定工具箱:

    [http://www.vision.caltech.edu/bouguetj/calib_doc/download/index.html]

     

    将其解压到Matlab的工作目录下,然后将其包含到matlab的工作路径下。

    运行calib_gui就可以打开matlab标定工具箱主界面:

    下载标定案例图片

    1、将标定用的图像单独存放于calib_example文件夹中。

    2、在matlab中,进入到calib_example文件夹中。

     

    3、读取图像:

     

    点击标定工具窗口中的“Image names”按钮。输入标定图像的基名和图像的格式(例如标定图像的名称分别是

    Img1.jpg,Img2.jpg,Img3.jpg...基名就是Img 图像格式就是jpg)

    然后所有的标定图像都将加载进来,其对应的变量名分别是I_1,I_2,...图像数量对应的变量是n_ima。

    载入完图像之后的图像如下:

    之后载入的图像将以缩略图的形式显示出来:

    一些图像内存不足的问题在此就不作详细的介绍了,现在一般的电脑RAM都是足够来做标定的。

    4、提取角点:

    点击标定工具箱上的“Extract grid corners”按钮。在matlab命令行会出现如下提示信息:

    直接按“Enter”(没有参数)选择所有的图像,否则就需要输入图像索引如[2 5 8 10 12]来提取这些图像中的

    角点。然后通过直接输入“Enter”来选择默认的角点寻找窗口尺寸:wintx=winty=5。这就产生了一个11X11个像素

    有效的窗口尺寸:

    角点提取引擎有一个对网格中的方格个数进行计数的自动机制。这个工具尤其对于图像数量大的时候非常便利,因为

    用户不需要手工地输入X和Y方向方格的数量。然而对于极少数场合,这个工具可能不能得到正确的方格数量,这种情况

    只有当镜头有很大的畸变。在这种情况下,角点提取这个过程,工具箱提供了一个可选项可供用户关闭自动计数方格。

    在这个特殊的模式下,使用者优先对每张图像使用方格自动计数功能,因此,直接按“Enter”键默认。(通常情况

    下都使用默认形式,然后如果确实有需要,再重新处理几张有问题的图像。)

    然后第一张标定图像就会显示出来:

    然后点击长方形棋盘格的四个边角点。选择的位置在下图中显示出来(注意:尽量精确地点击这四个角点,控制

    在实际角点的5个像素范围内,否则一些角点可能会被检测器丢失掉)

     

    点击的顺序规则:第一个点被用来作为棋盘格坐标系的原点。其他三个点可以以任何顺序点击。第一个点击的的点

    非常重要,尤其是对于多相机的情况(例如当计算几个相机在空间之间的相互关系的时候)。当处理多相机系统时

    对于不同的相机标定图像需要总是选择同一个棋盘格坐标系。三维标定可以运行stereo_gui.m(后文有介绍,双目标定部分)

    第一个点的选择非常重要,一定要注意

    经过上面的步骤之后,标定棋盘的边界就显示出来了:

    输入网格中每个方格在X和Y方向上的尺寸dX和dY(在这里,dX=dY=30mm=default values)(需要根据自己的棋盘做调整):

    注意:你可以直接输入“Enter”直接用默认参数,程序会自动对各个方向的方格数进行计数,然后在显示出没有

    畸变的预估角点。

    如果预估的角点很接近实际的图像角点,则下面的步骤就可以略过了(如果没有那么大的图像畸变)。在现在的

    图像中:预估的角点足够接近实际的图像角点。因此,没有必要通过输入一个猜测的径向畸变系数去帮助软件去

    检测图像角点。直接输入“Enter”,会使用这些初始的预估角点作为提取的角点:

    然后图像角点就被自动地提取出来了,然后显示出来,如下图所示:

    角点以大约0.1个像素的精度被提取出来。

    对第2、3、4...图像采用上述同样的步骤。如下图是将图像2、3、4..图像的角点提取出来:

    从上面观察到方格尺寸dX、dY总是被保持在它们的初始值(30mm).

     

    有时,预估的角点不是那么足够地接近实际图像角点,在这种情况下,就有必要通过输入一个镜头畸变系数来调整

    预估角点。第15张图像就是这种情况,在这张图像中,预估角点的图像如下图所示:

    可以看到一些预估角点和实际图像的角点的差距很大,这样就会导致错误的角点提取。而这产生的原因就是因为

    图像畸变。为了帮助系统更好地判断角点的位置,用户可以手动地输入一个镜头畸变系数Kc.为了输入镜头畸变

    系数,我们需要在那个问题“Need of an initial guess for distortion?”这里输入一个非空参数,这里

    我们输入畸变系数Kc=-0.3(一般这个系数在-1到1之间)。如下图所示:

    根据这个畸变系数,新的预估角点位置如下图所示:

    如果新的预估角点足够接近实际的图像角点(如上图所示),则输入任何不为空的字符(如1)作为问题“Satisfied

    with distortion?”的回答。然后亚像素角点的位置就会使用新的带有图像畸变的预估位置进行计算。

    如果我们还不满意,我们可以输入一个空的字符串作为问题"Satisfied with distortion?"(直接输入“Enter”)

    然后尝试一个新的畸变系数Kc。你可能会重复很多次这样的过程直到对结果满意为止。

    注意:上面用到的畸变的值仅仅是用来帮助提取角点,其不会影响下面主要的标定过程。换句话说,这里的畸变系数并不会作为最终的畸变结果,也不会用于优化畸变系数的初始值

    最后检测到的角点如下图所示:

    对剩下的几张图片重复上述过程(图片16-20).然而对这些图像,不要使用预先的畸变系数这个选项,尽管提取的

    角点不是很正确。在下面的步骤中,我们将纠正它们(在这个例子中,我们不会使用畸变系数这个选项用于图像15

    但是这样对于我们证明很有用)。

    在角点提取之后,就会自动产生一个calib_data.mat的matlab数据文件。这个文件包含了整个角点提取过程中

    的所有信息(图像坐标,对应的3D网格坐标,网格尺寸....)。这个文件是为了防止matlab突然崩溃而创立的。

    载入这个文件可以避免你又重复一遍上面的过程。

     

    在你自己标定的过程中,当图像中有大的畸变的时候,这个程序可能不能够在网格中自动对方格进行计数,在这种

    情况下,X和Y方向的方格数量必须手动输入。这在这个例子中没有出现这种情况。

     

    在你自己做标定的时候,还有一种情况会出现。如果镜头畸变非常严重(像鱼眼镜头),这个基于单个畸变系数的

    简化的指导工具对角点的初始预估可能就不够用。

    对于这几种麻烦的情况,在工具箱中的一个脚本程序支持完全手动的角点提取(例如每次点击一个角点)。脚本文

    件叫做“manual_corner_exteaction.m”(在内存优化模式下,你可以使用"manual_corner_

    extraction_no_read.m"),并且应该在传统的角点提取代码运行之后才能执行这个代码。(因为它基于传统的

    角点提取的一些数据)。

     

    显然,这种角点提取的方法当图像数量多的时候是非常耗时的。因为它作为当前面的尝试都失败的情况下的一种

    救命稻草。但完全可以不用太担心这个,在这个例子中不会出现这种情况。

    主要的标定步骤:

    在角点提取完之后,就可以单击标定工具箱面板上的“Calibration”来运行主要的相机标定程序。

     

    标定主要通过两个步骤来完成:初次初始化以及非线性优化。

    初始化步骤中对标定参数进行闭环计算,这个过程不包括任何镜头畸变(程序名:init_calib_param.m)

    非线性优化过程中将对所有的标定参数最小化总体映射误差(从最小二乘的角度出发)(9个内参以及6X20=129、

    个外参)。优化是对特定雅可比矩阵进行计算然后往梯度下降的方向进行的。

    标定参数存储在一系列变量中。注意切向畸变系数和第6个径向畸变系数没有没有被估算(这是默认的模式)。因此

    在像素坐标中X和Y之间是90°。在大多数实际情况中,这是一个很理想化的设想。然而,接下来,将会讲述一种介绍

    在优化中切向畸变alpha_c的方法。

     

    从上图中我们可以注意到:为了达到最小值,只用了11次梯度迭代。这就意味着只有11次对映射函数、雅可比计算

    以及求逆的评估。快速收敛的一个原因就是初始化程序所要计算的参数的有一个好的初始预估值。

    现在,忽略推荐的可以减少畸变的模型的系统。对一个模型的复杂性进行判断的映射误差仍然很大。这主要是因为

    对于一些图像一些网格角点并没有被精确地提取。

     

    单击面板上的“Reproject on images”来将网格角点映射到原始图像中。这些映射是基于当前的内参和外参计算

    出来的。输入一个空字符(直接按"Enter")作为“Number(s) of image(s) to show([]=all images)”来

    表示你想查看所有图像:

    下面的图像显示了最初的四张检测到的角点的图像(红色的叉)以及映射的网格角点(圆)。

    映射误差也以有颜色的叉叉显示在图中:

    为了退出误差分析工具,在图像上的任何位置右击(稍后你将会理解这个选项的使用)。

     

    在面板中单击“Show Extrinsic”。外参(棋盘格相对于相机的相对位置)就以3D的形式显示出来了:

    在上图中,坐标系(Oc,Xc,Yc,Zc)是相机的参考坐标系。红色的金字塔状的就是由图像平面定义的相机的有效

    视场。可以在相机坐标系视角或者世界坐标系视角之间切换:

    在这个视角里面,每个相机的位姿都用绿色的金字塔表示。

     

    现在我们回到前面的误差分析那一段,注意到在很多图像中的投影误差是非常大的。原因就是我们在一些高度畸变

    的图像的角点提取工作做得不到位。然而,我们现在可以通过对所有图像重新计算图像角点来进行矫正。接下来需要

    做的就是:单击面板中的“Recomp. corners”按钮,然后再次选择角点检测器的窗口尺寸(wintx=winty=5这个

    默认值)。

    对于最后问题“Number(s) of image(s) to process”亦然输入“Enter”选择默认值去重新计算所有图像中的

    角点。然后就是选择角点提取的方式:自动和手动,自动的就是使用重新投影的网格作为角点的初始预估位置。手

    动的方式就需要使用者手动的提取角点。在现在这样的条件下,因为重投影的网格点非常接近实际的图像角点,因此

    我们选择自动的方式:直接“Enter”输入默认值。所有图像的角点就会被重新计算。你的matlab命令行窗口就会出

    现下面这种形式:

    然后通过单击“Calibration”进行一次标定优化:

    可以注意到只需要6次迭代就收敛了,并且没有进行初始化过程(因为优化是在前面标定的结果之上进行的)。上图

    中的两个值0.12668和0.12604分别是X和Y方向像素上投影的标准差。注意到标定参数的不确定性也进行了估算。

    数值大概是标准差的3倍。

     

    优化之后,单击“Save”保存标定结果(内参和外参)到matlab文件“Calib_Results.mat”

    我们再次单击“Reproject on images”将网格点投影到原始图像中。前四张图像如下图所示:

    然后再“Analyse error”看看新的投影误差(可以看到误差比之前更小了):

    右击上面的误差图像(退出误差分析工具),单击“Show Extrinsic”看看棋盘格相对于相机的3D位置关系:

    工具“Analyse error”允许你去检查哪个点对应大的误差。单击“Analyse error”并且选择图像由上角的那个点

    单击选中之后,下面的信息就会出现在命令行窗口:

    这就意味着对应的点在第18张图像中,在标定板网格坐标的(0,0)的位置(标定板的原点)。下图是此点到原始

    图像的距离。

    误差检查工具对于在一张或多张图像中角点提取失败的情况下非常有用。在这种情况下,使用者可以使用不同的窗

    口尺寸去重新对于特定图像的角度进行重新计算。

     

    例如,我们使用窗口尺寸(wintx=winty=9)来对所有图像的角点进行计算,但对图像20我们使用(wintx=winty

    =5)的窗口尺寸,对图像5,7,8,19我们采用(wintx=winty=7),图像18采用(wintx=winty=8)的窗口

    尺寸进行计算。角点的提取会调用三次“Recomp.corners”。第一次调用使用wintx=winty=9来处理图像1,2,

    3,4,6,9,10,11,12,13,14,15,16和17.然后选择自动模式:

    第二次调用,使用wintx=winty=8来处理图像18,然后再次选择自动模式:

    第三次调用,使用wintx=winty=7来处理图像5,7,8和19:

    单击“Calibration”进行重新标定:

    观察上面的投影误差(0.11689,0.11500)比前面的更小了。另外注意到,标定参数的不确定性也更小了。通过单击“Analyse error”来检测误差:

    让我们来看看前面那个兴趣图像18中的点,在标定板的网格坐标(0,0)处。单击“Reproject on images”然后

    选择只显示图像18(当然在此之前你必须右击误差分析图像退出误差分析工具):

    放大图像我们可以看到更小的投影误差:

    单击“Save”保存标定结果到文件“Calib_Results.mat”中:

    可以看到前面的标定结果已经被拷贝到文件“Calib_Results_old0.mat”中。

    现在多加5张图像来重新进行相机标定。image21 image22 image23 image24 image25。然后“Read images”把所有的25张图像载入内存。然后以缩略图显示:

    单击“Extract grid corners”来对新的5张图像进行角点提取,窗口尺寸用wintx=winty=5:

    以传统的角度提取过程对这5张图像进行角点提取。然后单击“Calibration”运行又一次优化:

    接下来,使用不同的窗口尺寸对最后的四张图像进行重新计算。对图像22和24使wintx=winty=9,对图23使用

    wintx=winty=8,对图像25使用wintx=winty=6。然后按照前面介绍的过程重新进行一次(三次调用“Recomp.corners

    ”),重新计算之后,再次运行“Calibration”:

    然后“Save”保存标定结果。

    作为练习,我们去除图像16,18,19,24和25然后重新进行标定:

    单击“Add/Suppress images”

    输入要去掉的图像([16 18 19 24 25]):

    重新“Calibration”进行标定:

    “Add/Supress images”取决于使用者是否需要某些图像。实际上,这个函数只是简单地更新active_image这个

    向量,使对应的图像索引为0或1.

    接下来,载入之前标定的结果“Load”:

    现在又回到了没有去掉图像之前的状态了。现在我们实现一次含有用来描述X和Y像素之间角度的切向因素alpha_c

    进行的标定。为此,我们需要将est_alpha设置为1(在命令行中进行)。As an exercise, let us fit the

    radial distortion model up to the 6th order (up to now, it was up to the 4th order, with

    tangential distortion). For that, set the last entry of the vector est_dist to one:

    然后重新运行“Calibration”:

    优化之后可以看到,切向因素非常接近0(alpha_c=0.00042),这就意味着X和Y像素之间的角度非常接近90°

    (89.976°)。这调整了之前的90°的设想。另外,注意到第6个径向畸变系数非常大。在这种情况下,我们最好

    就是不使用它的估算值。在这里,我们直接将est_dist最后一个量设置为0:

    再次“Calibration”:

    如果标定结果满意的话就“Save”保存标定结果。

    为了选择合理的畸变模型来使用,通常可视化对像素图像的畸变影响以及畸变的径向部分和切向部分

    的比对是非常有用的。为此,在matlab命令行运行visualize_distortions,就会有三张图出来:

    第一幅图显示了整体的畸变模型对图像每个像素的影响。每个箭头表示由于镜头畸变而使一个像素发生的位移效果。

    可以看到图像角落处的像素移动了25个像素。第二幅图显示了畸变的切向部分。在这幅图中,最大的位移式0.14个

    像素,在图像的左上角。最后,第三幅图显示了畸变的径向部分的影响。这幅图和第一幅图有点相似。说明畸变的切

    向部分相对于整体模型来说可以忽略不计。在第三幅图中,十字叉表示了图像的中心,而圆表示光心所在的位置。

     

    现在我们来试验一下,当没有畸变的情况下标定会有什么结果。使Kc=[0;0;0;0;0],并且fc没有各向异性(使fc

    几个方向都相等):

    然后,运行一次优化“Calibration”:

    和预期一样,畸变系数向量Kc都是0,焦距各个方向都相当,fc1=fc2。在实际中,这种标定的模型是不推荐的:

    因为在没有各向异性的幸亏下去估算切向畸变是没有意义的。通常情况下,除非有特定的应用,一般推荐在模型中评

    估各向异性。对于畸变模型,一般经常只对其中一些系数进行优化。例如,将est_dist设置为【1;0;0;0】

    只对第一个畸变系数kc(1)进行估算而把其他三个畸变系数直接置0.这种模型也叫作第二对称性径向畸变模型。它

    是一个非常可行的模型,尤其是当使用比较低的畸变光学系统(昂贵的镜头),或者当用来标定的图像很少的时候。

    另一个比较常用的畸变模型是第4对称性径向畸变模型而没有切向部分畸变(est_dist=[1;1;0;0])。这个模

    型被zhang使用并被调整了,基于现在大多的镜头制造在聚焦方面都没有缺陷。这个模型可以很好地用于现在这个

    例子中,从前面三个图也可以看出,这个镜头的切向部分畸变远小于径向部分畸变。

     

    最后,让我们来做一次,没有各向异性fc(2)/fc(1),光心cc,畸变系数kc,切向系数alpha_c的优化。为此

    一般地,如果光心没有被估算,则最好的预估值就是图像的中心:

    然后运行“Calibration”:

    从上面可以看到,光心cc优化后还在图像的中心(因为center_optim=0)

     

    接下来,载入原来的标定结果:

    标定工具箱的其他功能

    仅仅计算外参:

    我们可以只计算图像的外参,而内参直接用之前标定好的结果,在前面标定好的基础上,输入一张图像,然后在面板

    上“Comp.Extrinsic”,就可以在matlab的命令行中出现下面的情况:

    外参在Rc_ext和Tc_ext两个变量中,另外一个变量omc_ext和Rc_ext一个效果,可以将omc_ext用罗得里格斯

    变换进行转换Rc_ext=rodrigues(omc_ext)。

    图像矫正

    这个函数帮助你利用之前标定的内参得到一些没有畸变的图像。

     

    作为一个练习,我们来对图像20进行矫正。

    在面板中单击“Undistort image”:

    输入1来选择一张要矫正的图像,注意不要输入图像的扩展名,只输入Image20就可以,然后是图像的类型。

    初始图像存储在矩阵I中,如下图所示:

    矫正过的图像存储在矩阵I2中,如下图所示:

    新产生的矫正的图像也存储成Image20_rect.tif。

     

    现在我们来矫正所有的图像。“Undistort image”,然后对第一个问题输入空参数。然后所有的标定图像都将被

    矫正,然后存储为Image_rect1.tif,Image_rect2.tif...

    也可以将标定数据导出为其他格式的数据:这样当你使用同样的数据来做标定,然后进行对比的时候是非常有用的

    这个可以在角点提取阶段使用,单击“Export calib data”:

    输入0选择使用Willson Heikkil格式,输入数据名(shot),然后每张图像的标定数据就会被保存为shot1,shot2,...

    也可以导出为zhang的格式。“Export calib data”,然后输入1.然后输入两个文件基名:一个是3D模型坐标(Model),

    另一个是图像坐标(data)。然后程序会创建一系列的text(Model1.txt,data1.txt,...),可以被zhang的

    代码直接使用:

    双目:

     

    1、下载双目示例图片,包括14对左右摄像头获取的图像,还有两个独立标定的结果。

     

    2、在窗口中输入stereo_gui ,出现工具窗口

    3、点击第一个按钮 Load left and right calibration files . 窗口提示输入左右标定文件名,分别输入对应文件名 Calib_Results_left.mat Calib_Results_right.mat

    4、内部参数的初始值在窗口中显示,并估算出外部参数 om 和 T ,右相机相对左相机的平移和旋转。3*3旋转矩阵是 om 通过 rodrigues 求出 。

    然后运行全局双目优化算法通过点击按钮Run

    stereo calibration 有以下所示结果

    可以发现内外参数都被重新计算,所有未确定的参数也确定保证误差最小的基础上。你会发现不确定的内参数都变小了,这是因为最优化算法的作用。默认情况下,优化算法

    会重新计算左右相机的内部参数,但是如果你不想让其优化,则在窗口运行 recompute_instrinsic_left 和或者recompute_instrinsic_right

    在窗口输入help go_calib_stereo 查看更多信息.

    5、点击 Save stereo calib results ,存储标定数据结果

    6、双目相机的空间位置和标定平面可以可视化,通过点击按键

    Show Extrinsics of the rig.​

    7、校正图像

    点击 Rectify the calibration images ,所有14对图片校正后图像存储在文件下。

     

     

     

     

    Stereo calibration parameters after optimization:

     

     

    Intrinsic parameters of left camera:

     

    (焦距)Focal Length: fc_left = [ 904.04147 905.15739 ] � [ 3.09344 3.06616 ]

     

    (相机主点)Principal point: cc_left = [ 355.30100 268.70908 ] � [ 5.26724 5.68795 ]

    Skew: alpha_c_left = [ 0.00000 ] � [ 0.00000 ] => angle of pixel axes = 90.00000 � 0.00000 degrees

    Distortion: kc_left = [ -0.16146 -0.28956 0.00673 -0.00145 0.00000 ] � [ 0.02699 0.33711 0.00108 0.00120 0.00000 ]

     

     

    Intrinsic parameters of right camera:

     

    Focal Length: fc_right = [ 903.75249 905.22217 ] � [ 3.16260 3.15348 ]

    Principal point: cc_right = [ 272.65718 200.97862 ] � [ 5.23068 5.57941 ]

    Skew: alpha_c_right = [ 0.00000 ] � [ 0.00000 ] => angle of pixel axes = 90.00000 � 0.00000 degrees

    Distortion: kc_right = [ -0.17423 -0.18553 0.00640 0.00189 0.00000 ] � [ 0.02212 0.16615 0.00098 0.00136 0.00000 ]

     

     

    Extrinsic parameters (position of right camera wrt left camera):

     

    Rotation vector: om = [ 0.01566 0.00315 -0.01171 ] � [ 0.00583 0.00636 0.00032 ]

    Translation vector: T = [ 40.38288 1.79900 0.33580 ] � [ 0.17438 0.14501 1.35436 ]

     

     

    Note: The numerical errors are approximately three times the standard deviations (for reference).

     

    >>

     

     

     

    Saving the stereo calibration results in Calib_Results_stereo.mat...

     

     

    上面是标定部分,标定完成

    、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、

    ​​

    stereoRectify ( //通过标定参数来得到校准参数,输出校准的矩阵P1,P2为下面的initUndistortRectifyMap提供参数 M1,//第一个相机矩阵 D1, //第一个相机畸变参数 M2,// 第二个相机矩阵 D2,//第二个相机畸变参数 img_size,// 用于校正的图像大小 R,// 第一和第二相机坐标系之间的旋转矩阵。 T,//第一和第二相机坐标系之间的平移矩阵. R1,//输出第一个相机的3x3矫正变换(旋转矩阵) R2, //输出第二个相机的3x3矫正变换(旋转矩阵) P1,//在第一台相机的新的坐标系统(矫正过的)输出 3x3 的投影矩阵 P2,//在第二台相机的新的坐标系统(矫正过的)输出 3x3 的投影矩阵 Q, //输出深度视差映射矩阵 CALIB_ZERO_DISPARITY,//CALIB_ZERO_DISPARITY,如果设置了CV_CALIB_ZERO_DISPARITY,函数的作用是使每个相机的主点在校正后的图像上有相同的像素坐标。如果未设置标志,功能还可以改变图像在水平或垂直方向 0,//alpha=0,校正后的图像进行缩放和偏移,只有有效像素是可见的(校正后没有黑色区域)alpha= 1意味着校正图像的抽取和转移,所有相机原始图像素像保留在校正后的图像(源图像像素没有丢失) img_size,//校正后新的图像分辨率 &roi1, &roi2 //校正后的图像可选的输出矩形,里面所有像素都是有效的。如果alpha= 0,ROIs覆盖整个图像。否则,他们可能会比较小。 );

    、也就是说R1 R2 P1 P2 这些参数是算在函数里算出来的后来哈哈哈哈哈、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、

    1

     

     

     

     

    2018年5月20日22:34:27 双目结果

    Stereo calibration parameters after optimization:

     

     

    Intrinsic parameters of left camera:

     

    Focal Length: fc_left = [ 896.37601 898.95766 ] � [ 4.03469 3.95967 ]

    Principal point: cc_left = [ 361.77261 245.26149 ] � [ 6.20599 8.25493 ]

    Skew: alpha_c_left = [ 0.00000 ] � [ 0.00000 ] => angle of pixel axes = 90.00000 � 0.00000 degrees

    Distortion: kc_left = [ -0.08909 -0.66204 -0.00321 -0.00425 0.00000 ] � [ 0.03527 0.36953 0.00209 0.00197 0.00000 ]

     

     

    Intrinsic parameters of right camera:

     

    Focal Length: fc_right = [ 898.13897 900.24565 ] � [ 4.07839 3.99084 ]

    Principal point: cc_right = [ 275.96707 170.10671 ] � [ 6.32297 8.67046 ]

    Skew: alpha_c_right = [ 0.00000 ] � [ 0.00000 ] => angle of pixel axes = 90.00000 � 0.00000 degrees

    Distortion: kc_right = [ -0.20690 0.49873 -0.00176 0.00013 0.00000 ] � [ 0.05076 0.88090 0.00185 0.00154 0.00000 ]

     

     

    Extrinsic parameters (position of right camera wrt left camera):

     

    Rotation vector: om = [ 0.01233 0.00471 -0.01134 ] � [ 0.01083 0.00921 0.00043 ]

    Translation vector: T = [ 39.82138 -0.02258 -0.19465 ] � [ 0.23969 0.21881 1.94060 ]

     

     

    Note: The numerical errors are approximately three times the standard deviations (for reference).

     

    Saving the stereo calibration results in Calib_Results_stereo.mat...

    Saving the stereo calibration results in Calib_Results_stereo.mat...

    Saving the stereo calibration results in Calib_Results_stereo.mat...

    错误使用 uiimport (line 69)

     

     

     

     

     

    、、、、、、、、、、、、、

    leftCalibration results after optimization (with uncertainties): Focal Length: fc = [ 892.54813 894.79744 ] +/- [ 8.61091 8.41579 ] Principal point: cc = [ 275.00160 171.81004 ] +/- [ 8.10321 11.05114 ] Skew: alpha_c = [ 0.00000 ] +/- [ 0.00000 ] => angle of pixel axes = 90.00000 +/- 0.00000 degrees Distortion: kc = [ -0.18891 0.31790 -0.00134 0.00123 0.00000 ] +/- [ 0.05952 0.97014 0.00238 0.00225 0.00000 ] Pixel error: err = [ 0.22786 0.16834 ] Note: The numerical errors are approximately three times the standard deviations (for reference). Recommendation: Some distortion coefficients are found equal to zero (within their uncertainties). To reject them from the optimization set est_dist=[1;0;1;1;0] and run Calibration

    、、、、、、、、、、、、、、

    right

     

     

     

     

     

    、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、2018年6月1日17:20:23

     

     

     

    Aspect ratio optimized (est_aspect_ratio = 1) -> both components of fc are estimated (DEFAULT).

    Principal point optimized (center_optim=1) - (DEFAULT). To reject principal point, set center_optim=0

    Skew not optimized (est_alpha=0) - (DEFAULT)

    Distortion not fully estimated (defined by the variable est_dist):

    Sixth order distortion not estimated (est_dist(5)=0) - (DEFAULT) .

    Initialization of the principal point at the center of the image.

    Initialization of the intrinsic parameters using the vanishing points of planar patterns.

     

    Initialization of the intrinsic parameters - Number of images: 20

     

     

    Calibration parameters after initialization:

     

    Focal Length: fc = [ 902.21426 902.21426 ]

    Principal point: cc = [ 319.50000 239.50000 ]

    Skew: alpha_c = [ 0.00000 ] => angle of pixel = 90.00000 degrees

    Distortion: kc = [ 0.00000 0.00000 0.00000 0.00000 0.00000 ]

     

    Main calibration optimization procedure - Number of images: 20

    Gradient descent iterations: 1...>>

     

     

    ​​

     

     

     

     

    Calibration results after optimization (with uncertainties):

     

    Focal Length: fc = [ 889.65926 892.22480 ] +/- [ 6.36924 6.70409 ]

    Principal point: cc = [ 265.83428 171.05333 ] +/- [ 7.14907 9.65841 ]

    Skew: alpha_c = [ 0.00000 ] +/- [ 0.00000 ] => angle of pixel axes = 90.00000 +/- 0.00000 degrees

    Distortion: kc = [ -0.34382 1.17602 0.00157 0.00781 0.00000 ] +/- [ 0.04709 0.53208 0.00220 0.00220 0.00000 ]

    Pixel error: err = [ 0.12907 0.12084 ]

     

    Note: The numerical errors are approximately three times the standard deviations (for reference).

     

    Saving calibration results under Calib_Results.mat

    Generating the matlab script file Calib_Results.m containing the intrinsic and extrinsic parameters...

    done

     

     

     

     

     

     

     

     

    、、、、、、、、、、、、、、、、、、右边

     

     

     

     

     

     

     

     

    Calibration results after optimization (with uncertainties):

     

    Focal Length: fc = [ 892.94254 895.08388 ] +/- [ 6.27844 6.60593 ]

    Principal point: cc = [ 356.03248 252.73026 ] +/- [ 6.98039 9.62436 ]

    Skew: alpha_c = [ 0.00000 ] +/- [ 0.00000 ] => angle of pixel axes = 90.00000 +/- 0.00000 degrees

    Distortion: kc = [ -0.26726 0.32322 0.00070 0.00062 0.00000 ] +/- [ 0.06141 0.70533 0.00312 0.00147 0.00000 ]

    Pixel error: err = [ 0.12518 0.11938 ]

     

    Note: The numerical errors are approximately three times the standard deviations (for reference).

     

     

    Recommendation: Some distortion coefficients are found equal to zero (within their uncertainties).

    To reject them from the optimization set est_dist=[1;0;0;0;0] and run Calibration

     

    >>

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

    Calibration results after optimization (with uncertainties):

     

    Focal Length: fc = [ 892.93595 895.07433 ] +/- [ 6.26832 6.59520 ]

    Principal point: cc = [ 356.03330 252.74978 ] +/- [ 6.96968 9.61067 ]

    Skew: alpha_c = [ 0.00000 ] +/- [ 0.00000 ] => angle of pixel axes = 90.00000 +/- 0.00000 degrees

    Distortion: kc = [ -0.26786 0.32877 0.00073 0.00062 0.00000 ] +/- [ 0.06131 0.70431 0.00312 0.00147 0.00000 ]

    Pixel error: err = [ 0.12497 0.11920 ]

     

    Note: The numerical errors are approximately three times the standard deviations (for reference).

     

     

    Recommendation: Some distortion coefficients are found equal to zero (within their uncertainties).

    To reject them from the optimization set est_dist=[1;0;0;0;0] and run Calibration

     

    >>

     

     

     

    、、、、、、、、、、、、、、、、、、、、、、双目

     

    2018年6月1日17:56:53

     

     

    Stereo calibration parameters after loading the individual calibration files:

     

     

    Intrinsic parameters of left camera:

     

    Focal Length: fc_left = [ 889.65926 892.22480 ] � [ 6.36924 6.70409 ]

    Principal point: cc_left = [ 265.83428 171.05333 ] � [ 7.14907 9.65841 ]

    Skew: alpha_c_left = [ 0.00000 ] � [ 0.00000 ] => angle of pixel axes = 90.00000 � 0.00000 degrees

    Distortion: kc_left = [ -0.34382 1.17602 0.00157 0.00781 0.00000 ] � [ 0.04709 0.53208 0.00220 0.00220 0.00000 ]

     

     

    Intrinsic parameters of right camera:

     

    Focal Length: fc_right = [ 892.93595 895.07433 ] � [ 6.26832 6.59520 ]

    Principal point: cc_right = [ 356.03330 252.74978 ] � [ 6.96968 9.61067 ]

    Skew: alpha_c_right = [ 0.00000 ] � [ 0.00000 ] => angle of pixel axes = 90.00000 � 0.00000 degrees

    Distortion: kc_right = [ -0.26786 0.32877 0.00073 0.00062 0.00000 ] � [ 0.06131 0.70431 0.00312 0.00147 0.00000 ]

     

     

    Extrinsic parameters (position of right camera wrt left camera):

     

    Rotation vector: om = [ -0.01590 -0.00642 0.01127 ]

    Translation vector: T = [ -40.20569 0.35539 2.56155 ]

     

    Intrinsic parameters of left camera:

     

     

     

     

    Focal Length: fc_left = [ 889.65926 892.22480 ] � [ 6.36924 6.70409 ]

    Principal point: cc_left = [ 265.83428 171.05333 ] � [ 7.14907 9.65841 ]

    Skew: alpha_c_left = [ 0.00000 ] � [ 0.00000 ] => angle of pixel axes = 90.00000 � 0.00000 degrees

    Distortion: kc_left = [ -0.34382 1.17602 0.00157 0.00781 0.00000 ] � [ 0.04709 0.53208 0.00220 0.00220 0.00000 ]

     

     

    Intrinsic parameters of right camera:

     

    Focal Length: fc_right = [ 892.93595 895.07433 ] � [ 6.26832 6.59520 ]

    Principal point: cc_right = [ 356.03330 252.74978 ] � [ 6.96968 9.61067 ]

    Skew: alpha_c_right = [ 0.00000 ] � [ 0.00000 ] => angle of pixel axes = 90.00000 � 0.00000 degrees

    Distortion: kc_right = [ -0.26786 0.32877 0.00073 0.00062 0.00000 ] � [ 0.06131 0.70431 0.00312 0.00147 0.00000 ]

     

     

    Extrinsic parameters (position of right camera wrt left camera):

     

    Rotation vector: om = [ -0.01590 -0.00642 0.01127 ]

    Translation vector: T = [ -40.20569 0.35539 2.56155 ]

     

     

     

     

     

    这个标定结果暂时就用matlab里的这,然后呢,那个用程序标定的那个,精度也在0.3 也挺好的,然后就接着做下一步吧,如果不行在回头重新标定一次。

    接下来做测距,就是把图片给模糊了。或者圈起来,测距离。

     

     

    、、、、、、、、、、、、、、、、、、、、、、、、2018年6月19日21:52:57

     

     

    Stereo calibration parameters after optimization:

     

     

    Intrinsic parameters of left camera:

     

    Focal Length: fc_left = [ 881.17671 881.99734 ] � [ 5.12032 5.57409 ]

    Principal point: cc_left = [ 278.90461 164.57156 ] � [ 6.62807 10.25004 ]

    Skew: alpha_c_left = [ 0.00000 ] � [ 0.00000 ] => angle of pixel axes = 90.00000 � 0.00000 degrees

    Distortion: kc_left = [ -0.19436 0.10991 -0.00424 0.00809 0.00000 ] � [ 0.03608 0.41745 0.00214 0.00193 0.00000 ]

     

     

    Intrinsic parameters of right camera:

     

    Focal Length: fc_right = [ 885.38048 885.63177 ] � [ 4.95810 5.54393 ]

    Principal point: cc_right = [ 356.48023 224.31055 ] � [ 6.21377 9.44063 ]

    Skew: alpha_c_right = [ 0.00000 ] � [ 0.00000 ] => angle of pixel axes = 90.00000 � 0.00000 degrees

    Distortion: kc_right = [ -0.11519 -0.31799 -0.00797 0.00174 0.00000 ] � [ 0.03560 0.35896 0.00271 0.00159 0.00000 ]

     

     

    Extrinsic parameters (position of right camera wrt left camera):

     

    Rotation vector: om = [ -0.03120 0.00402 0.01033 ] � [ 0.01164 0.00735 0.00061 ]

    Translation vector: T = [ -41.19179 -1.14778 2.61234 ] � [ 0.22041 0.18075 1.93149 ]

     

    、、、、、、、、、、、、、、、、、、、、、、、、2018年6月19日21:52:57

     

    K:\标定\双目标定 用这个标定程序吧啊

     

    O:\新建文件夹\新建文件夹\副本2 放这个文件夹了标定得结果

    2018年7月6日15:20:54 用6MM标定板标定的

    Intrinsic parameters of left camera:

     

    Focal Length: fc_left = [ 899.88011 899.51213 ] � [ 1.47074 1.48938 ]

    Principal point: cc_left = [ 283.38982 181.13032 ] � [ 2.65982 2.49405 ]

    Skew: alpha_c_left = [ 0.00000 ] � [ 0.00000 ] => angle of pixel axes = 90.00000 � 0.00000 degrees

    Distortion: kc_left = [ -0.19917 0.30091 0.00014 0.00025 0.00000 ] � [ 0.01066 0.10360 0.00053 0.00057 0.00000 ]

     

     

    Intrinsic parameters of right camera:

     

    Focal Length: fc_right = [ 905.75915 905.53299 ] � [ 1.53607 1.54158 ]

    Principal point: cc_right = [ 382.26445 272.63482 ] � [ 2.80930 2.59566 ]

    Skew: alpha_c_right = [ 0.00000 ] � [ 0.00000 ] => angle of pixel axes = 90.00000 � 0.00000 degrees

    Distortion: kc_right = [ -0.16802 -0.02121 -0.00206 0.00082 0.00000 ] � [ 0.01095 0.05612 0.00042 0.00083 0.00000 ]

     

     

    Extrinsic parameters (position of right camera wrt left camera):

     

    Rotation vector: om = [ -0.00532 -0.01617 0.01132 ] � [ 0.00285 0.00357 0.00023 ]

    Translation vector: T = [ -39.79172 -0.47970 -0.06547 ] � [ 0.02902 0.02727 0.24626 ]

     

     

    Note: The numerical errors are approximately three times the standard deviations (for reference).

     

    Saving the stereo calibration results in Calib_Results_stereo.mat...

    Calib_Results_stereo.mat

     

    、、、、、、、、、、、、、、、、、、、、、、、、2018年6月19日21:52:57

     

     

     

     

     

     

     

     

     

     

    展开全文
  • 双目图像矫正

    2021-04-17 10:31:45
    一、畸变矫正: 1.径向畸变:透镜本身工艺问题。 2.切向畸变:安装带来的问题。...但是,在现实的双目立体视觉系统中,是不存在完全的共面行对准的两个摄像机图像平面的,所以我们要进行立体校正。 ...
  • 双目标定及矫正系列文章更新,C/CPP实现双目矫正(不使用OpenCV)及矫正源码解析。 matlab标定较为准确,命令行中输入stereoCameraCalibrator enter 添加左图 右图 确定 选择畸变参数,calibratior 拖拉红线,删除误差...
  • 1.双目测距原理 图源 OL和OR分别是左右两个相机镜头位置,b是两个镜头之间的距离,左右两个相机成像平面长度是L,并且平行于baseline(OL与OR连线)。视角内一点P(X,Y,Z)P(X,Y,Z)P(X,Y,Z)在左右两个图像平面的PL,...
  • 双目矫正学习

    2021-01-11 22:44:20
    OpenCV undistort 与 stereoRectify ...Opencv中的双目标定和校正 https://blog.csdn.net/laobai1015/article/details/55211036 ORB_SLAM2非ROS版本rgbd_tum、stereo_euroc、mono_tum三者算法原理异对比与解析 ...
  • 双目摄像头的标定、矫正和世界坐标的计算(opencv),实践
  • 对立体视觉的双目图像进行极线校正,以实现双目致密匹配 (Of three-dimensional visual image of the binocular epipolar rectification to realize dense binocular matching)
  • 我们用相机拍完照之后就要进行相机标定了,双目测距只有在相机标定之后可以发挥比较好的效果。 我们要做一些准备工作,首先就是下载matlab并且去下载棋盘照片打印出来进行标定 棋盘图片下载网址:...
  • 基于LINUX系统的双目测距系统的开发文档、双目摄像头的测距算法及相关注释
  • 双目摄像头矫正

    2015-11-17 17:02:58
    根据摄像头定标后获得的单目内参数据(焦距、成像原点、畸变系数)和双目相对位置关系(旋转矩阵和平移向量),基于opencv开发环境分别对左右视图进行消除畸变和行对准,使得左右视图的成像原点坐标一致、两摄像头...
  • 双目立体视觉Bouguet矫正算法详解

    千次阅读 2019-07-30 17:15:56
    ... ,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);... 人类可以看到3维立体的世界,是因为人的两只...双摄像头立体成像(三)-畸变矫正与立体校正
  • 双目相机的畸变矫正及平行矫正

    千次阅读 2017-09-07 19:24:05
    通过相机标定的程序获取了两个相机各自的内参...Opencv和Matlab都给了我们现成的函数,可以利用这些数据进行去畸变或者双目平行校正,因为有需求要将去畸变和平行校正移植到硬件上,那么自己如何利用这些参数和
  • MATLAB实现双目校准

    2017-10-22 20:52:54
    完全利用MATLAB实现双目校准。其中分为公式法和直接法。内有详细文档介绍
  • 1.用OPENCV生成内参数 intrinsics.yml和外参数 extrinsics.yml 参考博客1:https://blog.csdn.net/xiaoxiaowenqiang/article/details/79687144 2.关于euroc.yaml中Camera.bf 参数的设定 参考博客2:...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,782
精华内容 712
关键字:

双目矫正