学习随笔~opencv图像矫正2

主要参考https://blog.csdn.net/billbliss/article/details/52527182一文进行的学习

在1的基础上,将代码写成函数调用形式,利用.yml文件存储摄像头标定数据。

camera data.yml


%YAML:1.0
image_Width: 960
image_Height: 576
fx: 635.6616
fy: 493.5513
cx: 502.5203
cy: 272.9890
kc1: -0.3917
kc2: 0.1388
kc3: 0
kc4: 0


camera data中存储了相机标定数据(源自maltab工具箱),可以利用以下matlab程序生成上述yml文件


fp=fopen('D:\camera data.txt','a');
fprintf(fp,'%s\r\n','%YAML:1.0');
fprintf(fp,'%s','image_Width: ');
fprintf(fp,'%d\r\n',cameraParams.ImageSize(2));
fprintf(fp,'%s','image_Height: ');
fprintf(fp,'%d\r\n',cameraParams.ImageSize(1));
fprintf(fp,'%s','fx: ');
fprintf(fp,'%f\r\n',cameraParams.FocalLength(1));
fprintf(fp,'%s','fy: ');
fprintf(fp,'%f\r\n',cameraParams.FocalLength(2));
fprintf(fp,'%s','cx: ');
fprintf(fp,'%f\r\n',cameraParams.PrincipalPoint(1));
fprintf(fp,'%s','cy: ');
fprintf(fp,'%f\r\n',cameraParams.PrincipalPoint(2));
fprintf(fp,'%s','kc1: ');
fprintf(fp,'%f\r\n',cameraParams.RadialDistortion(1));
fprintf(fp,'%s','kc2: ');
fprintf(fp,'%f\r\n',cameraParams.RadialDistortion(2));
fprintf(fp,'%s','kc3: ');
fprintf(fp,'%f\r\n',cameraParams.TangentialDistortion(1));
fprintf(fp,'%s','kc4: ');
fprintf(fp,'%f\r\n',cameraParams.TangentialDistortion(2));
fclose(fp);%关闭文件。
movefile('D:\camera data.txt', 'D:\camera data.yml');


    模仿了前人的编写方法,将读取参数作为一个函数,将图片重映射参数获取作为一个参数,同时因为后续处理会用到处理后的图片,把remap放在main里面

#include <iostream>  
#include"opencv.hpp"
using namespace cv;
using namespace std;
void Get_Camera_Params(Mat &intrinsic_matrix, Mat &distortion_coeffs, Size &imageSize, char *image_path)
{
	FileStorage get_camera_inf;
	double fx, fy, cx, cy, kc1, kc2, kc3, kc4;
	int image_Width, image_Height;
	if (get_camera_inf.open(image_path, FileStorage::READ) != 0)
	{
		get_camera_inf["fx"] >> fx;
		get_camera_inf["fy"] >> fy;
		get_camera_inf["cx"] >> cx;
		get_camera_inf["cy"] >> cy;
		get_camera_inf["kc1"] >> kc1;
		get_camera_inf["kc2"] >> kc2;
		get_camera_inf["kc3"] >> kc3;
		get_camera_inf["kc4"] >> kc4;
		get_camera_inf["image_Width"] >> image_Width;
		get_camera_inf["image_Height"] >> image_Height;
	}
	else
		cout << "Cannot open this file" << endl;
	get_camera_inf.release();
	intrinsic_matrix = (Mat_<double>(3, 3) << fx, 0, cx, 0, fy, cy, 0, 0, 1);//内参矩阵
	distortion_coeffs = (Mat_<double>(1, 4) << kc1, kc2, kc3, kc4);//畸变系数
	imageSize = Size(image_Width, image_Height);
	cout << "intrinsic_matrix " << intrinsic_matrix << endl
		<< "distortion_coeffs " << distortion_coeffs << endl
		<< "imageSize " << imageSize << endl;
}
void Image_Correction(Mat &Img, char *image_path,Mat &map1, Mat &map2)
{
	Mat intrinsic_matrix, distortion_coeffs;//定义内参矩阵和畸变参数矩阵
	Size imageSize;//照片尺寸
	Get_Camera_Params(intrinsic_matrix, distortion_coeffs, imageSize, image_path);
	//undistort(Img, ImgRemap, intrinsic_matrix, distortion_coeffs); 	//矫正  300ms
	initUndistortRectifyMap(intrinsic_matrix, distortion_coeffs, Mat(),
	getOptimalNewCameraMatrix(intrinsic_matrix, distortion_coeffs,imageSize,1, imageSize, 0),
	imageSize,CV_16SC2,map1,map2);//获得map1,map2映射表,用以提升速度,多张图片只需要运行一次
}


void main()
{
	Mat Img1 = imread("C:\\Users\\sunmingzhe\\Desktop\\test\\1.jpg");//读取待处理图片
	char *image_path1 = "D:\\项目代码\\相机标定\\camera calibration\\camera calibration\\camera data.yml";
	string filePath = "Correction1.jpg";//处理后图像名
	Mat ImgRemap1= imread(filePath);
	Mat map1_x, map1_y;
	Image_Correction(Img1, image_path1, map1_x, map1_y);//获取映射矩阵map1_x, map1_y
	remap(Img1, ImgRemap1, map1_x, map1_y, INTER_LINEAR);//校准图像 70ms
	imshow("Correction Image", ImgRemap1);//显示图像
	imwrite(filePath, ImgRemap1);//保存图像
	waitKey(0);
}

Get_Camera_Params的作用是读取yaml文件中的参数(ps:yaml中":"一定是英文符号。。否则会报错。。中文英文很接近。。。mdzz)

map1,map2放在外面试因为处理多张图片时,这些图片的map1,map2是一样的,只需要执行一次Image_Correction函数

之前考虑把remap也放在Image_Correction函数中,然后把map1,map2定义为全局变量,考虑到remap就一行,就放弃了。。

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值