initUndistortRectifyMap 源码
时间: 2023-07-05 16:08:33 浏览: 66
initUndistortRectifyMap 是OpenCV中的一个函数,用于计算相机的畸变矫正映射。以下是该函数的源代码实现(版本为OpenCV 4.5.2):
```c++
void cv::initUndistortRectifyMap(
InputArray cameraMatrix, InputArray distCoeffs,
InputArray R, InputArray newCameraMatrix,
Size size, int m1type, OutputArray map1, OutputArray map2)
{
Mat cameraMatrixMat = cameraMatrix.getMat(), RMat = R.getMat(), newCameraMatrixMat = newCameraMatrix.getMat();
CV_Assert( cameraMatrixMat.type() == CV_64FC1 || cameraMatrixMat.type() == CV_32FC1 );
CV_Assert( distCoeffs.empty() || distCoeffs.type() == CV_64FC1 || distCoeffs.type() == CV_32FC1 );
CV_Assert( RMat.empty() || RMat.type() == CV_64FC1 || RMat.type() == CV_32FC1 );
CV_Assert( newCameraMatrixMat.type() == CV_64FC1 || newCameraMatrixMat.type() == CV_32FC1 );
CV_Assert( m1type == CV_16SC2 || m1type == CV_32FC1 || m1type < 0 );
if( !map1.needed() && !map2.needed() )
return;
map1.create(size, m1type);
Mat map1Mat = map1.getMat();
map2.create(size, m1type == CV_16SC2 ? CV_16UC1 : m1type);
Mat map2Mat = map2.getMat();
Mat_<double> A, Ar, I = Mat_<double>::eye(3,3);
cameraMatrixMat.convertTo(A, CV_64F);
newCameraMatrixMat.convertTo(Ar, CV_64F);
Mat_<double> Rmat;
R.convertTo(Rmat, CV_64F);
if( distCoeffs.empty() )
distCoeffs = Mat_<double>::zeros(1, 5);
Mat distCoeffsMat = distCoeffs.getMat();
if (CV_MAT_DEPTH(m1type) == CV_32F)
{
float* map1f = map1Mat.ptr<float>();
float* map2f = map2Mat.ptr<float>();
double v0 = A(1, 2), inv_f = 1./A(0, 0);
double _a = Ar(0, 0), _b = Ar(0, 1), _c = Ar(0, 2),
_d = Ar(1, 0), _e = Ar(1, 1), _f = Ar(1, 2),
_g = Ar(2, 0), _h = Ar(2, 1), _i = Ar(2, 2);
double k1 = distCoeffsMat.at<double>(0, 0);
double k2 = distCoeffsMat.at<double>(0, 1);
double k3 = distCoeffsMat.at<double>(0, 4);
double k4 = distCoeffsMat.rows + distCoeffsMat.cols - 1 >= 7 ? distCoeffsMat.at<double>(0, 2) : 0.;
double k5 = distCoeffsMat.rows + distCoeffsMat.cols - 1 >= 8 ? distCoeffsMat.at<double>(0, 3) : 0.;
for( int i = 0; i < size.height; ++i)
{
float* map1fi = map1f + i*size.width;
float* map2fi = map2f + i*size.width;
double y = (i + 0.5 - v0)*inv_f;
for( int j = 0; j < size.width; ++j)
{
double x = (j + 0.5 - A(0, 2))*inv_f;
double x0 = x, y0 = y, x02, y02;
if( k1 != 0 || k2 != 0 || k3 != 0 || k4 != 0 || k5 != 0 )
{
double r2 = x*x + y*y, _2xy = 2*x*y;
double radial = 1 + r2*(k1 + r2*(k2 + r2*k3));
x0 = x*radial + k4*_2xy + k5*(r2 + 2*x*x);
y0 = y*radial + k4*(r2 + 2*y*y) + k5*_2xy;
}
x02 = x0*_a + y0*_b + _c;
y02 = x0*_d + y0*_e + _f;
map1fi[j] = (float)x02;
map2fi[j] = (float)y02;
}
}
}
else
{
short* map1s = map1Mat.ptr<short>();
ushort* map2s = map2Mat.ptr<ushort>();
double v0 = A(1, 2), inv_f = 1./A(0, 0);
double _a = Ar(0, 0), _b = Ar(0, 1), _c = Ar(0, 2),
_d = Ar(1, 0), _e = Ar(1, 1), _f = Ar(1, 2),
_g = Ar(2, 0), _h = Ar(2, 1), _i = Ar(2, 2);
double k1 = distCoeffsMat.at<double>(0, 0);
double k2 = distCoeffsMat.at<double>(0, 1);
double k3 = distCoeffsMat.at<double>(0, 4);
double k4 = distCoeffsMat.rows + distCoeffsMat.cols - 1 >= 7 ? distCoeffsMat.at<double>(0, 2) : 0.;
double k5 = distCoeffsMat.rows + distCoeffsMat.cols - 1 >= 8 ? distCoeffsMat.at<double>(0, 3) : 0.;
for( int i = 0; i < size.height; ++i)
{
short* map1si = map1s + i*size.width*2;
ushort* map2si = map2s + i*size.width;
double y = (i + 0.5 - v0)*inv_f;
for( int j = 0; j < size.width; ++j)
{
double x = (j + 0.5 - A(0, 2))*inv_f;
double x0 = x, y0 = y, x02, y02;
if( k1 != 0 || k2 != 0 || k3 != 0 || k4 != 0 || k5 != 0 )
{
double r2 = x*x + y*y, _2xy = 2*x*y;
double radial = 1 + r2*(k1 + r2*(k2 + r2*k3));
x0 = x*radial + k4*_2xy + k5*(r2 + 2*x*x);
y0 = y*radial + k4*(r2 + 2*y*y) + k5*_2xy;
}
x02 = x0*_a + y0*_b + _c;
y02 = x0*_d + y0*_e + _f;
map1si[j*2] = (short)(x02*map1Mat.cols);
map1si[j*2+1] = (short)(y02*map1Mat.rows);
map2si[j] = saturate_cast<ushort>(sqrt(x*x + y*y)*newCameraMatrixMat.at<double>(0, 0) + 0.5);
}
}
}
}
```
该函数的输入参数包括:相机内参矩阵,畸变系数,旋转矩阵,新的相机内参矩阵,输出映射尺寸和映射类型。其中,相机内参矩阵和畸变系数是必须的输入参数,而旋转矩阵和新的相机内参矩阵可以为空。映射类型可以选择CV_16SC2或CV_32FC1,分别表示输出映射为16位有符号整型或32位浮点型。
函数的主要实现过程是根据输入参数计算畸变矫正映射,最后将结果输出到map1和map2中。具体实现过程可参考上述代码。
相关推荐
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)