• 【OpenCV】【计算机图形学】DIBR: Depth Image Based Rendering/ 3D image warping 中的实现细节


    最近在学习DIBR并尝试实现。感觉网上相关资料比较少,大多还是爬虫,决定自己写一个。

    DIBR就是depth image based rendering问题。输入一个视角下的图像和深度图,要求你输出另外一个虚拟视角下的图像(当然两个视角的内外参矩阵都有办法通过已知信息求得)。

    总共分三步:内参提取 和 外参提取 ,以及DIBR的主过程。这里按照网上其他博客的顺序,先介绍内参提取。看的过程中注意坐标系的定义。由于是第一次接触,这里我采用的坐标系可能和常规的坐标系不太一样。

    开始之前先介绍一些定义(基于我自己实现算法的时候所使用的数据集):
    (u,v,1)T(u,v,1)T为一个点的像素坐标。
    (x,y,1)T(x,y,1)T为一个点在图像平面上以物理距离衡量的坐标。
    (X,Y,Z)(X,Y,Z)为一个点在相机坐标系下的坐标。
    (Xw,Yw,Zw)(Xw,Yw,Zw)为一个点在世界坐标系下的坐标。
    fxfy分别表示X轴的焦距和Y轴的焦距(非理想情况下横向和纵向的焦距是不一样的)。
    dxdy分别表示X轴(对应于图像的U轴)和Y轴(对应于图像的V轴)每个像素的物理尺寸(一个像素实际有多长)。
    pupv表示相机的主点(principal point,就是相机主轴与成像平面的交点)在图像中的位置(以像素为单位)。
    像素纵横比:pixel aspect ratio。表示像素的实际尺寸的高与宽之比。
    主点:principal point。是一个二维向量,表示相机主光轴与成像平面的交点。这里以像素为单位在图像上进行刻画。
    相机位置(positionx,positiony,positionz)
    焦距focal length
    相机姿态(朝向)camera orientation。为一个三维向量,通常可用欧拉角、轴角、四元数等方式表示。这里采用的是轴角表示法。

    后面的公式可以对照着这个表来看。

    内参提取

    内参提取就是求从相机坐标系到最终像素图像的变换。

    在看具体的矩阵之前,先看一下怎么推的。

    根据透视模型(这里就不赘述了)有:
    透视投影

    透视投影

    那么就用yf=YZy=fYZ。对于x同理。

    那么图像平面上的坐标(以物理长度衡量)就是(x,y,1)=(fXZ,fYZ,1)。这里采用齐次坐标。表示为(fX,fY,Z)

    再映射到以像素为单位的坐标系下:
    像素映射
    就是u=xdx+pu,v同理。那么就有(u,v)T=(xdx+pu,ydy+pv,1)。同样使用齐次坐标有:(Zu,Zv,Z)=(fXdx,fYdy,Z)。后面的推理都是在齐次坐标下进行的。

    接下来写出矩阵乘法的形式:

    定义K=[fx000fy0001]用于从相机坐标系转移到图像平面上的坐标系(以图片的物理尺度进行衡量,还不是像素尺度,不妨设为V坐标系)

    定义C=[1dx0pu01dypv001]为从V坐标系映射到图像坐标系(以像素为尺度)

    定义K=CK=[fxdx0pu0fydypv001]。 这就是我们的内参矩阵。即

    其中,fxdxfydy可由定义的par=pixel aspect ratio(像素纵横比)得到。我手上的数据集给出的焦距(focal length)是以像素为单位的,应该默认是给出focal length=fxdx。那么fydy=fxdx\xpar。也就不需要我们去计算dxdy了,毕竟jpg格式的解压不是人人都会的,opencv貌似也无法直接读出图像的分辨率信息(至少我没有查到)。

    外参提取

    外参提取就是求从世界坐标系到相机坐标系的变换。

    这里把变换拆分为旋转变换和平移向量。

    先来看看平移变换,这个很好写:

    相机位置是(px,py,pz)(变量名有点重复,见谅见谅),那么就有平移向量:
    C=(px,py,pz)T(Xw,Yw,Zw)T+C就能够实现平移了。
    (这里论文给的代码是正号,感觉不对,读者可以在评论区说服我为什么是正号)

    接下来看旋转变换
    这里的原理还没怎么搞懂,后面再来补上,先把做法说了。

    输入给的是轴角表示(axis-angle),文章给出的实现是,先转化为四元数,再用四元数进行旋转。(我的评价是,不如直接用欧拉角,这好复杂...)

    首先将axis和angle转化为四元数。设axis=(a,b,c)T。得到的四元数是q=(a,b,c,w)T。不妨设axis是单位向量。
    那么有q=(sin(angle2)axis,cos(angle2))T
    下面用四元数得到旋转矩阵。不妨设q已经经过了单位化。
    那么有:

    最后就有(X,Y,Z)T=R((Xw,Yw,Zw)T+C)

    DIBR的核心步骤

    有了两个视角下分别的内参和外参之后怎么做呢?这其实是最简单的一步。

    Z(u,v,1)T=KR((Xw,Yw,Zw)T+C)
    这对于两个视角下都是成立的:
    Z1p1=K1R1(P+C1)
    Z2p2=K2R2(P+C2)
    用第一个式子把P求出来:
    P=(K1R1)1Z1p1C1
    再带到第二个式子里,最后把Z2p2弄成p2=(u,v,1)的形式就可以了。最后一步就是把p1对应的像素直接赋给p2即可。
    注意:这里的Z_1,Z_2指的就是深度,所以才需要深度作为输入。这样看来,也能通过DIBR得到输出图像的深度信息。

    这里写的时间不长,写的比较粗糙,如果有问题敬请指出。有时间我会回来把四元数的推导补上的。

    最后把求内外参的代码奉上:

    void Calc_Intrinsic_Matrix()
    {
    	actual_height=1.0*height*len_per_pixel;
    	actual_width=1.0*width*len_per_pixel;
    
    	intr_K=Mat::zeros(3,3,CV_64FC1);
    	intr_K.at<double>(0,0)=focal_length;
    	intr_K.at<double>(1,1)=focal_length*pixel_aspect_ratio;
    	intr_K.at<double>(0,2)=1.0*width-principal_point[0]-1.0;
    	intr_K.at<double>(1,2)=1.0*height-principal_point[1]-1.0;
    	intr_K.at<double>(2,2)=1;
    
    	intr_K=intr_K;
    
    }
    
    void Calc_Extrinsic_Matrix()
    {
    	extr_R=Mat::eye(3,3,CV_64FC1);
    	//transform axis-angle to quaternion, and calculate transform matrix
    	Mat axis=Mat::zeros(3,1,CV_64FC1);
    	double angle=0;
    	for(int i=0;i<3;i++)
    	        angle+=orientation[i]*orientation[i];
    	angle=sqrt(angle);
    	for(int i=0;i<3;i++)
    		axis.at<double>(i,0)=orientation[i]/angle;
    	Mat qt=quaternion_about_axis(-angle,axis);
    	extr_R=quaternion_matrix(qt);
    
    	extr_C=Mat::zeros(3,1,CV_64FC1);
    	extr_C.at<double>(0,0)=position[0];
    	extr_C.at<double>(1,0)=position[1];
    	extr_C.at<double>(2,0)=position[2];
    
    }
    

    参考:https://blog.csdn.net/u010922186/article/details/40683129

  • 相关阅读:
    学习如何将Jenkins与UI测试报告完美整合,事半功倍,轻松获取高薪职位!
    Redis—听说你速度跟甲斗一样快?——哨兵
    自己用pip下载好模块啦,但是在pycharm里面不显示?
    [ubuntu][转载]ubuntu挂载nas并实现开机自动挂载
    微服务架构 | 消息队列 - [常见坑] TBC...
    Biotin-PEG-NH2 生物素PEG氨基
    Python数据类型 ——— 字典
    第三十五章 使用 CSP 进行基于标签的开发 - 使用服务器端方法的提示
    正则表达式的说明》
    数据结构复盘——第七章:查找和匹配
  • 原文地址:https://www.cnblogs.com/T-Y-P-E/p/16001154.html