从观测到的点坐标计算理想点坐标。
该函数类似于 undistort 和 initUndistortRectifyMap,但它操作的是稀疏点集而不是光栅图像。此外,该函数执行与 projectPoints 相反的变换。对于3D对象,它不会重建其3D坐标;但对于平面对象,如果指定了适当的旋转矩阵 R,它可以重建坐标,直到一个平移向量为止。
对于每个观测到的点坐标 (u,v),该函数计算:
x " ← ( u − c x ) / f x y " ← ( v − c y ) / f y ( x ′ , y ′ ) = u n d i s t o r t ( x " , y " , distCoeffs ) [ X Y W ] T ← R ∗ [ x ′ y ′ 1 ] T x ← X / W y ← Y / W only performed if P is specified: u ′ ← x f ′ x + c ′ x v ′ ← y f ′ y + c ′ y \begin{array}{l} x^{"} \leftarrow (u - c_x)/f_x \\ y^{"} \leftarrow (v - c_y)/f_y \\ (x',y') = undistort(x^{"},y^{"}, \texttt{distCoeffs}) \\ {[X\,Y\,W]} ^T \leftarrow R*[x' \, y' \, 1]^T \\ x \leftarrow X/W \\ y \leftarrow Y/W \\ \text{only performed if P is specified:} \\ u' \leftarrow x {f'}_x + {c'}_x \\ v' \leftarrow y {f'}_y + {c'}_y \end{array} x"←(u−cx)/fxy"←(v−cy)/fy(x′,y′)=undistort(x",y",distCoeffs)[XYW]T←R∗[x′y′1]Tx←X/Wy←Y/Wonly performed if P is specified:u′←xf′x+c′xv′←yf′y+c′y
其中 undistort 是一个近似的迭代算法,它根据归一化的畸变点坐标估计归一化的原始点坐标(“归一化”意味着这些坐标不依赖于相机矩阵)。
该函数可以用于立体相机或单目相机(当旋转矩阵R为空时)。
void cv::undistortPoints
(
InputArray src,
OutputArray dst,
InputArray cameraMatrix,
InputArray distCoeffs,
InputArray R = noArray(),
InputArray P = noArray()
)
#include
#include
#include
using namespace cv;
using namespace std;
int main()
{
// 假设我们有一组畸变的图像点
vector< Point2f > distortedPoints = { Point2f( 320, 240 ), Point2f( 330, 250 ) };
// 相机内参矩阵和畸变系数(假设已经通过标定获得)
Mat cameraMatrix = ( Mat_< double >( 3, 3 ) << 520.9, 0, 325.1, 0, 521.0, 249.7, 0, 0, 1 );
Mat distCoeffs = ( Mat_< double >( 5, 1 ) << -0.28340811, 0.07395907, 0.00019359, 1.76187114e-05, 0.0 );
// 创建输出点容器
vector< Point2f > undistortedPoints;
// 可选参数:旋转矩阵 R 和新投影矩阵 P
// 对于单目相机,R 和 P 可以为空
// 注意:这里直接使用 noArray() 作为参数传递,而不是赋值给 Mat 类型变量
// Mat R = noArray(); // 错误的做法
// Mat P = noArray(); // 错误的做法
// 执行去畸变操作
undistortPoints( distortedPoints, undistortedPoints, cameraMatrix, distCoeffs, noArray(), noArray() );
// 输出结果
for ( size_t i = 0; i < undistortedPoints.size(); ++i )
{
cout << "Point " << i + 1 << ": (" << undistortedPoints[ i ].x << ", " << undistortedPoints[ i ].y << ")" << endl;
}
return 0;
}
Point 1: (-0.00979206, -0.0186206)
Point 2: (0.00940703, 0.000575813)