day34:双目视觉

1.双目相机模型

 2.双目相机标定

 

 

void visionagin:: Mystersocalibrate()
{
	//读取左右相机拍摄的照片文件名
	ifstream iftL("C:\\Users\\86176\\Downloads\\visionimage\\totalphotosL.txt"),
			iftR("C:\\Users\\86176\\Downloads\\visionimage\\totalphotosR.txt");
	string temp("C:\\Users\\86176\\Downloads\\visionimage\\");
	string imagenameL, imagenameR;//每幅图像的路径
	vector<Mat>imagesL, imagesR;
	while (getline(iftL, imagenameL)&&getline(iftR,imagenameR))
	{
		Mat imageL, imageR;
		//读取左右图像集
		imageL = imread(temp + imagenameL);
		imageR = imread(temp + imagenameR);
		if (imageL.empty() || imageR.empty())
		{
			cout << "读取失败!" << endl;
		}
		imagesL.push_back(imageL);
		imagesR.push_back(imageR);
	}
	vector<vector<Point2f>>points2L, points2R;//左右相机多幅图像的角点坐标
	Size bothboardsize(9, 6);
	Size squaresize(10, 10);
	//求取左右图像中棋盘的角点坐标
	for (int i = 0; i < imagesL.size(); ++i)
	{
		Mat gryL, gryR;
		cvtColor(imagesL[i], gryL, COLOR_BGR2GRAY);
		cvtColor(imagesR[i], gryR, COLOR_BGR2GRAY);
		vector<Point2f> tempL;
		vector<Point2f> tempR;
		findChessboardCorners(gryL, bothboardsize, tempL);
		findChessboardCorners(gryR, bothboardsize, tempR);
		//细化棋盘角点坐标
		find4QuadCornerSubpix(gryL, tempL, Size(5, 5));
		find4QuadCornerSubpix(gryR, tempR, Size(5, 5));
		points2L.push_back(tempL);
		points2R.push_back(tempR);
	}
	//生成左右棋盘角点的空间三维坐标集
	vector<vector<Point3f>>points3;
	for (int i = 0; i < imagesL.size(); ++i)
	{
		vector<Point3f> TEMP;
		for (int j = 0; j < bothboardsize.height; ++j)
		{
			for (int k = 0; k < bothboardsize.width; ++k)
			{
				Point3f temp;
				temp.x = j * squaresize.width;
				temp.y = k * squaresize.height;
				temp.z = 0;
				TEMP.push_back(temp);
			}
		}
		points3.push_back(TEMP);
	}
	Mat cameraML = Mat(3, 3, CV_32FC1,Scalar::all(0));
	Mat cameraMR = Mat(3, 3, CV_32FC1, Scalar::all(0));
	Mat distcoeffL= Mat(1, 5, CV_32FC1, Scalar::all(0));
	Mat distcoeffR = Mat(1, 5, CV_32FC1, Scalar::all(0));
	Mat rvecs, tvecs;
	//先单独标定左右相机参数
	calibrateCamera(points3, points2L, imagesL[0].size(), cameraML, distcoeffL, rvecs, tvecs);
	calibrateCamera(points3, points2R, imagesR[0].size(), cameraMR, distcoeffR, rvecs, tvecs);
	Mat R, T, E, F;//旋转短阵、平移向量、 本征矩阵、基本矩阵
	stereoCalibrate(points3, points2L, points2R, cameraML, distcoeffL, cameraMR, distcoeffR, imagesL[0].size(), R, T, E, F,CALIB_USE_INTRINSIC_GUESS);
	cout << "两个相机坐标系的旋转矩阵:" << R << endl;
	cout << "两个相机坐标系的平移向量" << T<< endl;
}

 3.双目相机校正

 

void visionagin:: Mysterorectofy()
{
	//使用之前双目相机标定得到的内参 畸变系数 旋转矩阵和平移向量
	Mat R= (Mat_<double >(3, 3) << 0.9999912307195959, 0.003090276899205375, 0.002826423994037764,
								-0.003077528700595732, 0.9999851228861411, -0.004503645577366223,
								-0.002840299456896107, 0.004494907682673629, 0.9999858641520486);
	//平移向量三行一列
	Mat T=(Mat_<double >(3,1)<< -33.22516725994758,
							0.4373643000560988,
							0.523302125269594);

	Mat cameraML = (Mat_<float >(3, 3) << 532.0162975827582, 0, 332.1725192389595,
										0, 531.5651587897565, 233.3880748229786,
										0, 0, 1);
	Mat distcoeffL = (Mat_<float >(1, 5) << -0.2851884066280067, 0.0800972142572013, 0.001274031468563325, -0.002415106464876228, 0.1065791099058786);
	Mat cameraMR = (Mat_<float >(3, 3) << 535.3824650855895, 0, 321.0856312892987,
										0, 535.4791599963741, 248.6968617265358,
										0, 0, 1);
	Mat distcoeffR = (Mat_<float>(1, 5) << -0.3191637777394278, 0.2726553907347779, -0.001018543210768334, -0.001877630188078218, -0.2524120140824795);
	//读取图片
	ifstream iftL("C:\\Users\\86176\\Downloads\\visionimage\\totalphotosL.txt"),
		iftR("C:\\Users\\86176\\Downloads\\visionimage\\totalphotosR.txt");
	string temp("C:\\Users\\86176\\Downloads\\visionimage\\");
	string imagenameL, imagenameR;//每幅图像的路径
	vector<Mat>imagesL, imagesR;
	while (getline(iftL, imagenameL) && getline(iftR, imagenameR))
	{
		Mat imageL, imageR;
		//读取左右图像集
		imageL = imread(temp + imagenameL);
		imageR = imread(temp + imagenameR);
		if (imageL.empty() || imageR.empty())
		{
			cout << "读取失败!" << endl;
		}
		imagesL.push_back(imageL);
		imagesR.push_back(imageR);
	}
	//计算校正变换矩阵
	Mat R1, R2, P1, P2, Q;//把第一个相机校正前点的坐标转换到校正后点的坐标所需的旋转矩阵:R1;   第一个相机校正后坐标系的投影矩阵P1;  深度差异映射矩阵	Q	
	stereoRectify(cameraML, distcoeffL, cameraMR, distcoeffR, imagesL[0].size(), R, T, R1, R2, P1, P2, Q);
	//计算校正映射矩阵
	Mat remapx1, remapx2, remapy1, remapy2;
	initUndistortRectifyMap(cameraML, distcoeffL, R1, P1, imagesL[0].size(), CV_32FC1, remapx1, remapy1);
	initUndistortRectifyMap(cameraMR, distcoeffR, R2, P2, imagesL[0].size(), CV_32FC1, remapx2, remapy2);
	for (int i = 0; i < imagesL.size(); ++i)
	{
		imshow("原图L" + to_string(i + 1), imagesL[i]);
		imshow("原图R" + to_string(i + 1), imagesR[i]);
		//进行校正
		Mat tempL, tempR;
		remap(imagesL[i], tempL, remapx1, remapy1, INTER_LINEAR);
		remap(imagesR[i], tempR, remapx2, remapy2, INTER_LINEAR);
		//图像拼接
		Mat result;
		hconcat(tempL, tempR, result);
		imshow("校正后结果"+to_string(i+1), result);
	}
}

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值