day33:单目视觉

day33:单目视觉,第1张

day33:单目视觉

1.单目相机模型

 

 齐次坐标与非齐次坐标转换:

void visionagin:: Myhomogeneous()
{
	vector  point3;
	point3.push_back(Point3f(18, 14, 2));
	point3.push_back(Point3f(25, 45, 5));
	Mat point4;
	convertPointsToHomogeneous(point3, point4);
	Mat point2;
	convertPointsFromHomogeneous(point3, point2);
	for (int i = 0; i < point3.size(); i++)
	{
		cout << "非齐次:" << point3[i] << endl;
		cout << "齐次: " << point4.at(i, 0) << endl;
	}
	for (int j = 0; j < point3.size(); ++j)
	{
		cout << "非齐次: " << point2.at(j, 0) << endl;
		cout << "齐次:" << point3[j] << endl;
	}
}

2.标定板角点提取

 

 

 

 

void visionagin::Mychessboard()
{
	Mat imgboard = imread("C:\Users\86176\Downloads\visionimage\left01.jpg");
	if (imgboard.empty())
	{
		cout << "读取失败!" << endl;
	}
	Mat gry;
	cvtColor(imgboard, gry, COLOR_BGR2GRAY);
	vector conners;
	Size boardsize(6, 9);
	findChessboardCorners(gry, boardsize, conners);
	find4QuadCornerSubpix(gry, conners, Size(5, 5));

	drawChessboardCorners(imgboard, boardsize, conners, true);
	imshow("out", imgboard);
}

 3.单目相机标定

 

 

 

 

void visionagin:: Mycailbratecamera()
{
	ifstream ft("C:\Users\86176\Downloads\visionimage\totalphotos.txt");
	vector images;
	string imgname;//图像名称
	string source = "C:\Users\86176\Downloads\visionimage\";
	while (getline(ft, imgname))
	{
		cout << imgname << endl;
		Mat img = imread(source+imgname);//注意路径
		images.push_back(img);
	}
	Size bordsize(9, 6);
	vector> points2;//多幅图像的角点组的集合
	vector> points3;//多幅图像的角点组的三维世界坐标
	//计算每副图像角点,
	for (int i = 0; i < images.size(); ++i)
	{
		vector point2;
		Mat tempimg = images[i];
		Mat gry;
		cvtColor(images[i], gry, COLOR_BGR2GRAY);
		findChessboardCorners(gry, bordsize,point2);//图像用灰度图
		find4QuadCornerSubpix(gry, point2, Size(5, 5));//棋盘角点细化
		points2.push_back(point2);
	}
	Size squaresize(10, 10);//棋盘每个方格尺寸
	//计算每副图像的角点组的三维坐标
	for (int i = 0; i < images.size(); ++i)
	{
		vector temppoints3;//单幅图像的角点的三维坐标
		for (int j = 0; j < bordsize.height; ++j)
		{
			for (int k = 0; k < bordsize.width; ++k)
			{
				Point3f temppoint3;//单个角点
				temppoint3.y = j * 10;
				temppoint3.x = k * 10;
				temppoint3.z = 0;
				temppoints3.push_back(temppoint3);
			}
		}
		points3.push_back(temppoints3);
	}
	Size imgsize;
	imgsize.width = images[0].cols;
	imgsize.height = images[0].rows;
	//相机的内参矩阵   3*3 cv_32fc1
	Mat cameraM = Mat(3, 3, CV_32FC1, Scalar::all(0));
	//畸变系数 k1 k2 p1 p2 k3
	Mat distcoeff = Mat(1,5 , CV_32FC1, Scalar::all(0));
	vectorrvecs;//每幅图像的旋转矩阵
	vectortvecs;//每幅图像的平移矩阵
	calibrateCamera(points3, points2, imgsize, cameraM, distcoeff, rvecs, tvecs);
	cout << "内参矩阵:" << cameraM << endl;
	cout << "畸变系数" << distcoeff << endl;
}

 

 4.单目相机校正

 

 

 实现1:

void visionagin:: Myundisort1()
{
	ifstream ift("C:\Users\86176\Downloads\visionimage\totalphotos.txt");
	string imagename;
	string temp("C:\Users\86176\Downloads\visionimage\");
	vectorimgs;
	while (getline(ift, imagename))
	{
		Mat img = imread(temp + imagename);
		imgs.push_back(img);
	}
	//导入上次标定得到内参和畸变系数
	Mat cameraM = (Mat_(3, 3) << 532.0162975827582, 0, 332.1725192389595,
		0, 531.5651587897565, 233.3880748229786,
		0, 0, 1);
	Mat distcoeff=(Mat_(1, 5) << -0.2851884066280067, 0.0800972142572013, 0.001274031468563325, -0.002415106464876228, 0.1065791099058786);
	for (int i = 0; i < imgs.size(); ++i)
	{
		imshow("原图像" + to_string(i), imgs[i]);
		Mat temp;
		undistort(imgs[i], temp, cameraM, distcoeff);
		imshow("矫正后图像" + to_string(i), temp);
	}
}

 实现2:

void visionagin::Myundisortremap()
{
	ifstream ift("C:\Users\86176\Downloads\visionimage\totalphotos.txt");
	string imagename;
	string temp("C:\Users\86176\Downloads\visionimage\");
	vectorimgs;
	while (getline(ift, imagename))
	{
		Mat img = imread(temp + imagename);
		imgs.push_back(img);
	}
	//导入上次标定得到内参和畸变系数
	Mat cameraM = (Mat_(3, 3) << 532.0162975827582, 0, 332.1725192389595,
		0, 531.5651587897565, 233.3880748229786,
		0, 0, 1);
	Mat distcoeff = (Mat_(1, 5) << -0.2851884066280067, 0.0800972142572013, 0.001274031468563325, -0.002415106464876228, 0.1065791099058786);
	Size imgsize;
	imgsize.width = imgs[0].cols;
	imgsize.height = imgs[0].rows;
	Mat r = Mat::eye(3, 3, CV_32FC1);
	Mat remapx = Mat(imgsize, CV_32FC1);
	Mat remapy = Mat(imgsize, CV_32FC1);
	initUndistortRectifyMap(cameraM, distcoeff, r, cameraM, imgsize, CV_32FC1, remapx, remapy);
	for (int i = 0; i < imgs.size(); ++i)
	{
		imshow("原图像" + to_string(i), imgs[i]);
		Mat temp;
		remap(imgs[i], temp, remapx, remapy, INTER_LINEAR);
		imshow("矫正后图像" + to_string(i), temp);
	}
}

5.单目投影

void visionagin:: Myprojectpoints()
{
	Mat imgboard = imread("C:\Users\86176\Downloads\visionimage\left01.jpg");
	Mat cameraM = (Mat_(3, 3) << 532.0162975827582, 0, 332.1725192389595,
										0, 531.5651587897565, 233.3880748229786,
										0, 0, 1);
	Mat distcoeff = (Mat_(1, 5) << -0.2851884066280067, 0.0800972142572013, 0.001274031468563325, -0.002415106464876228, 0.1065791099058786);
	Mat rvec = (Mat_(1, 3) <<-1.977853, -2.002220, 0.130029);
	Mat tvec = (Mat_(1, 3) << -26.88155, -42.79936, 159.19703);
	vector points3;
	Size bordsize(9, 6);
	Size square(10, 10);
	for (int i = 0; i < bordsize.height; ++i)
	{
		for (int j = 0; j < bordsize.width; ++j)
		{
			Point3f temp;
			temp.x = i * 10;
			temp.y = 10 * j;
			temp.z = 0;
			points3.push_back(temp);
		}
	}
	vector propoints2;//投影到二维的结果
	projectPoints(points3, rvec, tvec, cameraM, distcoeff, propoints2);
	vectorpoints2;
	Mat gray;
	cvtColor(imgboard, gray, COLOR_BGR2GRAY);
	findChessboardCorners(gray, bordsize, points2);
	find4QuadCornerSubpix(gray, points2, Size(5, 5));
	//计算投影到二维的点与计算出的角点的误差
	double e = 0;
	for (int k = 0; k < points2.size(); ++k)
	{
		double ex = pow(points2[k].x-propoints2[k].x, 2);
		double ey = pow(points2[k].y- propoints2[k].y, 2);
		e += sqrt(ex+ey);
	}
	e /= points2.size();
	cout << "误差:" << e << endl;
}

 6.单目位姿估计

 

 

 

 

 

void visionagin:: Mysolvepnpandransac()
{
	Mat imgboard = imread("C:\Users\86176\Downloads\visionimage\left01.jpg");
	Mat boardgry;
	cvtColor(imgboard, boardgry, COLOR_BGR2GRAY);
	Size boardsize(9, 6);
	Size squaresize(10, 10);
	vector points2;
	findChessboardCorners(boardgry, boardsize, points2);
	find4QuadCornerSubpix(boardgry, points2, Size(5,5));
	vector points3;
	for (int i = 0; i < boardsize.height; i++)
	{
		for (int j = 0; j < boardsize.width; ++j)
		{
			Point3f temp;
			temp.x = squaresize.width * i;
			temp.y = squaresize.height * j;
			temp.z = 0;
			points3.push_back(temp);
		}
	}
	//使用之前标定得到的内参,畸变系数;
	Mat cameraM = (Mat_(3, 3) << 532.0162975827582, 0, 332.1725192389595,
										0, 531.5651587897565, 233.3880748229786,
										0, 0, 1);
	Mat distcoeff=(Mat_(1,5)<< -0.2851884066280067, 0.0800972142572013, 0.001274031468563325, -0.002415106464876228, 0.1065791099058786);
	Mat rvec, tvec;//旋转,平移向量
	solvePnP(points3, points2, cameraM, distcoeff, rvec, tvec);
	cout << "世界坐标系转化到相机坐标系的旋转向量:" << rvec << endl;
	cout << "世界坐标系转化到相机坐标系的平移向量:" << tvec << endl;
	//向量转化成矩阵
	Mat R, T;
	Rodrigues(rvec, R);
	Rodrigues(tvec, T);
	cout << "世界坐标系转化到相机坐标系的旋转矩阵:" << R << endl;
	cout << "世界坐标系转化到相机坐标系的平移矩阵:" << T << endl;
	Mat ransacrvec, ransactvec;
	//用solvepnpransac计算 r,t
	solvePnPRansac(points3, points2, cameraM, distcoeff, ransacrvec, ransactvec );
	Mat ransacR, ransacT;
	Rodrigues(ransacrvec, ransacR);
	Rodrigues(ransactvec, ransacT);
	cout << "ransac方法,世界坐标系转化到相机坐标系的旋转矩阵:" << ransacR << endl;
	cout << "ransac方法,世界坐标系转化到相机坐标系的平移矩阵:" << ransacT << endl;
}

 

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5659601.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存