结构光深度检测的原理,本质就是双目视觉。用projector替代一个camera,投影的pattern就是双目视觉所需的其中一张图片。需要对camera和projector进行calibration。
以camera为例说一下自己对calibration的理解。
先将practical camera看做一个pin hole camera model,像平面与pin hole的距离为d。首先是要明确两个坐标系,一个是camera coordinate system(下边计为{C}),或者说是world coordinate system,以(calibrate出来的camera的)光心,也就是pin hole为{C}的origin,垂直于像平面指向外为z正半轴;第二个是image coordinate system(下边计为{I}),像平面的某个角为{I}的origin。原则上{I}是一个2D coordinate system,不过也可以看成3D的。
如上图所示,从左往右看过去,场景左上方的物体会通过光心O投射到像平面右下方,将像平面关于原点对称重新构造后,物体像就会在左上方,也就是我们通常见到保存好的图像,因此通常图像处理所涉及的坐标系原点在左上角。有一点要注意的是,这个像平面并不是实际的camera的像平面,并且可以看到这个像平面的一些特别之处,如{C}与{I}的坐标轴分别平行。但是光心O在像平面的投影并不一定在像平面的中心点。假设scene中有一个点在{C}下为(Xmm,Ymm,Zmm)',现在要解答的问题是这个点投射到这个虚拟的像平面上坐标是多少呢?不妨将结果记为{I}下坐标(x pixel, y pixel, z pixel)。
首先(Xmm,Ymm,Zmm)和(X/Z mm,Y/Z mm,1 mm)会投影到同一个点上。不妨将图中的像平面按原点对称原则转换到光线右侧,这样{C}与{I}的三轴分别平行同向,并且假定像平面到O的距离就是1mm。这样一来{C}中所有点(X/Z mm,Y/Z mm,1 mm) * k构成一条通过O的直线,并且与像平面相交于一点,这点在{C}下坐标为(X/Z mm,Y/Z mm,1 mm)。接下来就是简单的坐标变换。(同一个点,在{C}下坐标已知,求在{I}new下的坐标。)先假定{I}的坐标轴的单位长度和{C}是一样的,也就是说先用mm做单位。因为{C}和{I}new三轴平行同向,所以R是单位矩阵,T是{C}和{I}new的origin的translation(以mm为单位)。接着做一个小小的修改,将{I}的X-Y平面沿着Z轴移动到{C}的X-Y平面作为最后的{I}。{C}下一点(X/Z mm,Y/Z mm,1 mm),在{I}new下,以mm为单位,其Z坐标为0,在最后的{I}下,其Z坐标为1。用homogeneous的写法如左下图。因为我们选定了特定的{I}和特定的像平面,所以{C}下一点(X/Z mm,Y/Z mm,1 mm)在{I}下Z坐标应该为1mm,因而Cz’=0.现在再将X坐标和Y坐标转为以pixel为单位,也就是说考虑1个mm有多少个pixel的问题,同时要注意的是X方向上和Y方向上这个比例可以是不一样的。(Z轴也有做缩放,固定选用1pixel/mm作为坐标轴缩放比例。)如右下图所示:
右上图里上方的{R|T}就构成了同一个点从{C}下描述到{I}下描述的转换,也就是{C}和{I}之间的变换关系。只不过R并不表示传统{R|T}中坐标轴旋转,而是缩放。注意这个像平面的选取是特定的,其三轴与{C}的三轴分别平行同向,并且X-Y平面重合,并且像平面距离光心1mm,Z轴缩放比例为1pixel/mm,这样才会有这个简洁的结果,并且化简为由右上图下方的形式,而这个简化了的{R|T}就是calibration中的A,处理的是{C}中一条射线与如前所述的一个特定的像平面相交的过程,本质上是求同一个点({C}下(X/Z mm,Y/Z mm,1 mm))在不同坐标系下的坐标变换。
再次强调一次,这个像平面不是实际光学仪器上的像平面。原则上{C}下(X/Z mm,Y/Z mm,1 mm)在{I}下的Z坐标不一定非要是1pixel,我们只是选取了一个特定的像平面以及特定的{C}Z轴到{I}Z轴的缩放比例,才是1pixel的结果。
总的而言,A描述的是一个pinhole camera model下,一条射线和一个虚拟像平面的交点在{C}和{I}下的坐标转换关系。选取虚拟像平面的时候有两个本质上可以任意设定的量,一个是虚拟像平面到光心的距离在{C}下的描述(即多少mm,假定{C}下以mm为单位),另一个是虚拟像平面到光心的距离在{I}下的描述(即多少pixel)。通常我们选择距离光心1mm,交点在{I}下Z坐标为1pixel,Z轴缩放比例则固定为1pixel/mm。
同时,哪怕真的是理想的pin hole camera,fx与fy都可以是不一样的,这取决于当我们把真实的像平面放到这个特定的像平面时,在这个像平面上,X方向和Y方向上1mm所包含的像素点的个数。举个例子,假设一个camera是pin hole camera,真实像平面与光轴垂直,和光心的距离为10mm,X方向上有1000个pixel,真实长度为1000mm,Y方向上有500个pixel,真实长度为100mm,并且光心在真实像平面上的投影恰好是像平面的中心。那么,在特定像平面上(和光心距离1mm),X方向长度为100mm,包含1000个pixel,Y方向长度为10mm,包含500个pixel。因此fx=10pixel/mm,fy=50pixel/mm,cx=500pixel,cy=250pixel。也就是说,我们获得了一个virtual pinhole camera去描述真实的camera,而这个virtual camera的像平面正是上边所说的特定的像平面。
当然,我们也可以假定virtual camera的像平面和光心的距离不是1mm,而是10mm,注意这时候{C}下(X/Z mm,Y/Z mm,1 mm) * k这条通过光心的直线和虚拟像平面的交点变为(10*X/Z mm,10*Y/Z mm,10 mm),{I}和之前的{I}一样(X-Y平面和{C}的X-Y平面重合),保持交点在{I}下坐标不变,需要令坐标轴的缩放比例变为原来的0.1倍。具体地看,因为交点在{C}下的Z坐标由原来的1mm变为10mm,为使得交点在{I}下的Z坐标保持为1pixel,Z轴的缩放比例从原来的1pixel/mm变为0.1pixel/mm。类似地,fx,fy,cx,cy也要变为原来的0.1倍。这个就是虚拟像平面与光心的距离对intrinsic matrix的影响。
从另一个角度看,如果虚拟的像平面和光心距离1mm,{I}也和之前的一样,但是{C}下(X/Z mm,Y/Z mm,1 mm)这个交点在{I}下的Z坐标不再是1pixel,而是0.1pixel。如果我们规定,进行处理的交点在{I}下的Z坐标必须保持1pixel,那么现在这个虚拟的像平面并不是我们想要进行处理的像平面,需要将它放到和光心距离10mm处,接下来就按照上一段讨论的一样,fx,fy,cx,cy变为原来的0.1倍。
Intrinsic矩阵A描述的是pin hole model的线性变换关系,而Distortion系数D描述的则是实际镜头对光线的偏折关系。如下图所示:
Scene中一条射线,在没有发生偏折的时候(也就是按上边所说的pinhole model,没有distortion)将会沿路径
1和特定像平面相交,发生偏折的情况下,会沿路径2与特定像平面相交。因此前者的交点我们会称为undistorted
point,后者的交点称为distorted point。undistorted point和distorted point之间的转换关系就是Distortion
Coefficients。在考虑成像时,指定{C}中一点,先通过A转换成{I}中一点,也就是undistorted point,再通过
D转为distorted point,就是最后的成像位置。反过来,如果要{I}上一点是由{C}中哪一条射线得到的(或者
说考虑projector),需要先将该点(distorted point)通过D转为undistorted point,再通过A转为射线。所谓
转为射线,就是用该射线和虚拟像平面上的交点来表示射线本身,而这个虚拟的像平面就是上面讨论A时候的那个特定
的像平面。
下面说一下自己对OpenCV进行camera calibration的理解。
转载于:https://www.cnblogs.com/cyrus-ho/p/4229253.html