学习随笔~opencv图像矫正1

1、拍摄照片

      首先拍摄10~20张图片。将棋盘贴在墙上或者板子上,对摄像头进行调焦。拍摄时将摄像头视野分成2×2,4个象限,在每个象限中正对棋盘拍摄一张图片;拉近视距,将棋盘置于视野中心正对拍摄一张,倾斜摄像头,8个角度各拍摄一张。一共4+1+8=13张图片,这样可以减少被camera calibrator拒绝的概率。

2、利用matlab工具箱获得内参

    导入图片,calibrate,输出结果

    cameraParams.IntrinsicMatrix   查看内参矩阵(跟网上的理论推导出来的矩阵是转置关系)

    FocalLength: 焦距  fx,fy

    PrincipalPoint: 中心点偏移 cx,cy  

    RadialDistortion:径向失真参数 k1 k2

    TangentialDistortion: 切向失真参数 k3 k4

3、利用opencv进行图像矫正(vs 2015+opencv3)

     两种方式:undistort与initUndistortRectifyMap+getOptimalNewCameraMatrix+remap 

     代码如下:

//#include "opencv2/core/core.hpp"  
//#include "opencv2/calib3d/calib3d.hpp"  
//#include "opencv2/imgproc/imgproc.hpp" // undistort
//#include "opencv2/highgui/highgui.hpp"  
#include <iostream>  
#include"opencv.hpp"
using namespace cv;
using namespace std;
void main()
{
	double fc1, fc2, cc1, cc2, kc1, kc2, kc3, kc4; //用matlab事先获得
	fc1 = 635.6616;           fc2 = 493.5513;
	cc1 = 502.5203;           cc2 = 272.9890;
	kc1 = -0.3917;            kc2 = 0.1388;
	kc3 = 0;                  kc4 = 0;
	Mat Img = imread("C:\\Users\\sunmingzhe\\Desktop\\test\\1.jpg");
	Mat intrinsic_matrix = (Mat_<double>(3, 3) << fc1, 0, cc1, 0, fc2, cc2, 0, 0, 1);//内参矩阵
	Mat distortion_coeffs = (Mat_<double>(1, 4) << kc1, kc2, kc3, kc4);//畸变系数
	string filePath = "Correction1.jpg";//处理后图像名
	Mat ImgUndistort = imread(filePath),map1,map2;
	TickMeter tm; //计时
	//undistort(Img, ImgUndistort, intrinsic_matrix, distortion_coeffs); 	//矫正  300ms
	Size imageSize=Size(960,576);//相机尺寸
	initUndistortRectifyMap(intrinsic_matrix, distortion_coeffs, Mat(),
		getOptimalNewCameraMatrix(intrinsic_matrix, distortion_coeffs,imageSize,1, imageSize, 0),
		imageSize,CV_16SC2,map1,map2);//获得map1,map2映射表,用以提升速度,多张图片只需要运行一次
	tm.start();//计时开始
	remap(Img, ImgUndistort, map1, map2, INTER_LINEAR);//校准图像 70ms
	tm.stop();//计时结束
	cout << "count=" << tm.getCounter() << ",process time=" << tm.getTimeMilli() << endl;
	imshow("Correction Image", ImgUndistort);//显示图像
	waitKey(0);
}

    输入相机参数→读取图片(绝对路径)→生成内参与畸变矩阵→定义输出(ImgUndistort)→矫正图像

    矫正图像中首先利用了undistort函数,这个函数比较方便使用,但是运行时间长,不满足视频处理需求(300+ms)

    然后采用initUndistortRectifyMap函数与remap函数配合处理图像,时间较短(70ms)

CV_EXPORTS_W void initUndistortRectifyMap( InputArray cameraMatrix, InputArray distCoeffs,
                           InputArray R, InputArray newCameraMatrix,
                           Size size, int m1type, OutputArray map1, OutputArray map2 );

    initUndistortRectifyMap函数的作用是获得图像横纵方向映射关系表,供remap使用;其参数是(相机内参,畸变参数,映射矩阵(双目会用到,单目这里是单位阵,直接Mat()即可),输出的新的相机内参矩阵,图片尺寸,图像类型,图像x方向映射关系表,图像y方向映射关系表)

CV_EXPORTS_W Mat getOptimalNewCameraMatrix( InputArray cameraMatrix, InputArray distCoeffs,
                                            Size imageSize, double alpha, Size newImgSize = Size(),
                                            CV_OUT Rect* validPixROI = 0,
                                            bool centerPrincipalPoint = false);

    getOptimalNewCameraMatrix函数的作用是显示更大范围的图片(正常重映射之后会删掉一部分图像)(参考https://www.cnblogs.com/riddick/p/6711263.html)其用来显示所有图像;其参数是(内参矩阵,畸变参数,原图像大小,1,新生成图像大小,0);1代表源图像的像素都保留在未失真图像中,0代表未失真图像的所有像素都有效。

CV_EXPORTS_W void remap( InputArray src, OutputArray dst,
                         InputArray map1, InputArray map2,
                         int interpolation, int borderMode = BORDER_CONSTANT,
                         const Scalar& borderValue = Scalar());

    remap函数作用是生成矫正后未失真图像;其参数是(源图像, 矫正后图像, map1, map2, 插值方法),差值方法一般用 INTER_LINEAR双线性插值

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值