360视频:CMP和ACP投影
Posted Dillon2015
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了360视频:CMP和ACP投影相关的知识,希望对你有一定的参考价值。
CMP投影
立方体投影格式(Cubemap projection format,CMP)是通过将球面内容投影在立方体模型上后将各个面展开,然后拼接为矩形的一种投影方式。
和ERP不同,CMP采用正方体进行投影,内容会投影到6个面上,如图1所示。
图1 CMP投影
6个面编号PX、PY、PZ、NX、NY、NZ,P表示沿坐标轴正方形,N表示沿坐标轴负方向。
表1 CMP face index
Face index | Face label | 说明 |
0 | PX | 正面,沿x轴正方向 |
1 | NX | 背面,沿x轴负方向 |
2 | PY | 上面,沿Y轴正方向 |
3 | NY | 下面,沿Y轴负方向 |
4 | PZ | 右面,沿Z轴正方向 |
5 | NZ | 左面,沿Z轴负方向 |
>5 | null |
每个面都对应一个uv平面,uv平面是2x2的正方向平面(等于单位球体的直径),u和v的取值[-1,1]。
假定每个面都是AxA的正方形,则对于某个面f上的坐标(m,n),其对应(u,v)计算方式为:
由(u,v)可按表2求3D坐标(X,Y,Z),
表2 由(f,u,v)计算(X,Y,Z)
f | X | Y | Z |
0 | 1.0 | -v | -u |
1 | -1.0 | -v | u |
2 | u | 1.0 | v |
3 | u | -1.0 | -v |
4 | u | -v | 1.0 |
5 | -u | -v | -1.0 |
对于3D到2D的投影变换,给定(X,Y,Z)可以按表3求得(f,u,v),
表3 由(X,Y,Z)计算(f,u,v)
条件 | f | u | v |
|X|≥ |Y| and |X| ≥ |Z| and X >0 | 0 | −Z/|X| | −Y/|X| |
|X|≥ |Y| and |X| ≥ |Z| and X <0 | 1 | Z/|X| | −Y/|X| |
|Y|≥ |X| and |Y| ≥ |Z| and Y >0 | 2 | X/|Y| | Z/|Y| |
|Y|≥ |X| and |Y| ≥ |Z| and Y <0 | 3 | X/|Y| | -Z/|Y| |
|Z|≥ |X| and |Z| ≥ |X| and Z >0 | 4 | X/|Z| | −Y/|Z| |
|Z|≥ |X| and |Z| ≥ |Y| and Z <0 | 5 | -X/|Z| | −Y/|Z| |
Frame Packing
CMP投影到6个面上,但是这6个面要拼成一个矩形2D平面才能编码。360Lib对CMP提供了2种面的拼接方式,分别为3x4和2x3形式,
图2 CMP frame packing
图2.1是原始360图像ERP投影的结果,红色虚线是经度。图2.2是图像按照CMP投影后6个面按3x4拼接的结果,其中有6个灰色的面是无效的,即表1中索引大于5的面,红色虚线是面的边界。图2.2是图像按照CMP投影后6个面按2x3拼接的结果,红色虚线是面的边界。
6个面拼接的时候还可以按照90、180、270度旋转,如图3中面1,2,3均逆时针旋转了270度。
图3 frame packing旋转
CMP是直接透视投影,均匀性仍然较差,由于透视投影过程不改变立体角的大小,这表现在对应于球面上等立体角的两点,投影到立方体上后会出现中心区域密度高而边缘区域密度低的现象。
/********************
face order:
PX: 0
NX: 1
PY: 2
NY: 3
PZ: 4
NZ: 5
********************/
Void TCubeMap::map2DTo3D(SPos& IPosIn, SPos *pSPosOut)
pSPosOut->faceIdx = IPosIn.faceIdx;
POSType u, v;
POSType pu, pv; //positin in the plane of unit sphere;
u = IPosIn.x + (POSType)(0.5);
v = IPosIn.y + (POSType)(0.5);
pu = (POSType)((2.0*u)/m_sVideoInfo.iFaceWidth-1.0);
pv = (POSType)((2.0*v)/m_sVideoInfo.iFaceHeight-1.0);
//map 2D plane ((convergent direction) to 3D ;
switch(IPosIn.faceIdx)
case 0:
pSPosOut->x = 1.0;
pSPosOut->y = -pv;
pSPosOut->z = -pu;
break;
case 1:
pSPosOut->x = -1.0;
pSPosOut->y = -pv;
pSPosOut->z = pu;
break;
case 2:
pSPosOut->x = pu;
pSPosOut->y = 1.0;
pSPosOut->z = pv;
break;
case 3:
pSPosOut->x = pu;
pSPosOut->y = -1.0;
pSPosOut->z = -pv;
break;
case 4:
pSPosOut->x = pu;
pSPosOut->y = -pv;
pSPosOut->z = 1.0;
break;
case 5:
pSPosOut->x = -pu;
pSPosOut->y = -pv;
pSPosOut->z = -1.0;
break;
default:
assert(!"Error TCubeMap::map2DTo3D()");
break;
Void TCubeMap::map3DTo2D(SPos *pSPosIn, SPos *pSPosOut)
POSType aX = sfabs(pSPosIn->x);
POSType aY = sfabs(pSPosIn->y);
POSType aZ = sfabs(pSPosIn->z);
POSType pu, pv;
if(aX >= aY && aX >= aZ)
if(pSPosIn->x > 0)
pSPosOut->faceIdx = 0;
pu = -pSPosIn->z/aX;
pv = -pSPosIn->y/aX;
else
pSPosOut->faceIdx = 1;
pu = pSPosIn->z/aX;
pv = -pSPosIn->y/aX;
else if(aY >= aX && aY >= aZ)
if(pSPosIn->y > 0)
pSPosOut->faceIdx = 2;
pu = pSPosIn->x/aY;
pv = pSPosIn->z/aY;
else
pSPosOut->faceIdx = 3;
pu = pSPosIn->x/aY;
pv = -pSPosIn->z/aY;
else
if(pSPosIn->z > 0)
pSPosOut->faceIdx = 4;
pu = pSPosIn->x/aZ;
pv = -pSPosIn->y/aZ;
else
pSPosOut->faceIdx = 5;
pu = -pSPosIn->x/aZ;
pv = -pSPosIn->y/aZ;
//convert pu, pv to [0, width], [0, height];
pSPosOut->z = 0;
pSPosOut->x = (POSType)((pu+1.0)*(m_sVideoInfo.iFaceWidth>>1) + (-0.5));
pSPosOut->y = (POSType)((pv+1.0)*(m_sVideoInfo.iFaceHeight>>1)+ (-0.5));
ACP投影
ACP(Adjustedcubemap projection format)投影是CMP的改进。
在2D转3D的计算过程中,对公式(1)(2)计算的(u,v)进行改进,
在3D转2D的计算过程中,计算得到的(u,v)再进一步处理,
将公式(3)(4)的变换用f(x)表示,公式(5)(6)的变换用g(x)表示(其中x为u或v),则f(x)和g(x)变换如下:
EAC和HEC投影
EAC(Equi-angular cubemap projection)和HEC(Hybrid equi-angular cubemap projection)和ACP类似,就是(u,v)的转换函数不同,
EAC的(u,v)计算为:
HEC和EAC类似,对于所有面的u的计算使用公式(7)(8),对于顶面和底面的v的计算使用公式(7)(8),不过对于其他4个面的v的正向和逆向变换如下:
感兴趣的请关注微信公众号Video Coding
以上是关于360视频:CMP和ACP投影的主要内容,如果未能解决你的问题,请参考以下文章