openCV不失真的理解

问题描述 投票:0回答:3

我通过

tof camera
接收
MATLAB
的深度图像。 tof 相机交付的用于计算深度图像中的 x、y、z 坐标的驱动程序使用
openCV
函数,该函数通过 mex 文件在
MATLAB
中实现。

但后来我不能再使用这些驱动程序,也不能使用

openCV
功能,因此我需要自己实现2d到3d映射,包括径向畸变的补偿。我已经掌握了相机参数,并且深度图像每个像素的 x、y、z 坐标的计算正在工作。到目前为止,我正在通过牛顿法求解不失真的隐式方程(这并不是很快......)。但我想实现
openCV
功能的不失真。

...这是我的问题:我不太明白,我希望你能帮助我。它实际上是如何运作的?我尝试在论坛中搜索,但没有找到有关此案例的任何有用的帖子。

问候!

matlab opencv camera-calibration
3个回答
14
投票

与相机校准相关的

文档页面提供了 3D 点 
[X; Y; Z]
 到 2D 图像点 
[u; v] 的投影方程 :


(来源:opencv.org

在镜头畸变的情况下,方程是非线性的,并且取决于 3 至 8 个参数(k1 至 k6、p1 和 p2)。因此,通常需要非线性求解算法(例如牛顿法、Levenberg-Marquardt算法等)来反转这样的模型并从失真坐标估计未失真坐标。这就是函数

undistortPoints
后面使用的内容,调整参数使优化速度很快,但有点不准确。

但是,在图像镜头校正的特定情况下(与点校正相反),有一种基于众所周知的图像重采样技巧的更有效的方法。这个技巧是,为了获得目标图像每个像素的有效强度,您必须将目标图像中的坐标转换为源图像中的坐标,而不是与人们直观期望的相反。在镜头畸变校正的情况下,这意味着您实际上不必反转非线性模型,而只需应用它即可。

基本上,函数

undistort
背后的算法如下。对于目标镜头校正图像的每个像素,执行以下操作:

  • 使用校准矩阵的逆矩阵
    (u_dst, v_dst)
    ,
     将像素坐标 
    (x', y')
     转换为归一化坐标 
    K
  • 应用镜头畸变模型,如上所示,以获得畸变归一化坐标
    (x'', y'')
  • 使用校准矩阵
    (x'', y'')
    ,
    (u_src, v_src)
     转换为扭曲像素坐标 
    K
  • 使用您选择的插值方法查找与源图像中像素坐标
    (u_src, v_src)
    关联的强度/深度,并将该强度/深度分配给当前目标像素。

请注意,如果您有兴趣使深度图图像不失真,则应使用最近邻插值,否则几乎肯定会在对象边界处插值深度值,从而导致不必要的伪影。


0
投票

上面的答案是正确的,但请注意 UV 坐标位于屏幕空间中并以 (0,0) 为中心,而不是“真实”UV 坐标。

来源:自己使用Python/OpenGL重新实现。代码:

def correct_pt(uv, K, Kinv, ds):
   uv_3=np.stack((uv[:,0],uv[:,1],np.ones(uv.shape[0]),),axis=-1)
   [email protected]
   r=np.linalg.norm(xy_,axis=-1)
   coeff=(1+ds[0]*(r**2)+ds[1]*(r**4)+ds[4]*(r**6));
   xy__=xy_*coeff[:,np.newaxis]
   return ([email protected])[:,0:2]

0
投票

请参阅这个很棒的教程,其中讨论了 OpenCV 和 Matlab 文档以及 python 中用于扭曲/不扭曲特征的相应实现。

© www.soinside.com 2019 - 2024. All rights reserved.