我试图将360视频像素坐标映射到球体表面坐标,但我无法得到正确的结果......它只是映射到错误的位置我已经知道360个视频像素的XY数据点。 / p>
how map 2d grid points (x,y) onto sphere as 3d points (x,y,z)
我检查了这个链接,我从这里复制了方法,但是我得到的并没有映射到所需的位置。
我不确定我是否正在为imageRadius传递正确的半径,但我认为它将是圆周/ PI以获得半径,视频比率为4096x2048。我也尝试传递数字1因为UV是0-1但是它不对......
也许方法是错误的。我将随机数传递给imageRadius,但无法获得正确的位置...如果我将X设为负数,那么看起来有点接近结果......?
https://youtu.be/t0I7Hlb-tbk 它使用我在网上找到的方法映射到正确的位置......
https://drive.google.com/a/swordfish-sf.com/file/d/0B45RYzVs0t0_VVdaaHdmNHRWTk0/view?usp=sharing 如果有人可以检查Unity项目文件那将是伟大的......
public class mapScript : MonoBehaviour {
public int input = 4098;
float imageRadius = 4098f / Mathf.PI; //2098? 3072? 4098?
float radius;
public GameObject testSphere;
void Start () {
radius = this.transform.localScale.x;
}
void Update () {
imageRadius = input / Mathf.PI;
int currentFrame = (int)this.GetComponent<VideoPlayer>().frame;
testSphere.transform.position = MercatorProjection(mapVals[currentFrame,0],mapVals[currentFrame,1]);
}
Vector3 MercatorProjection(float xVal, float yVal)
{
float lon = (xVal / imageRadius);
float lat = (2 * Mathf.Atan(Mathf.Exp(yVal / imageRadius)) - Mathf.PI / 2);
float calcX = radius * Mathf.Cos(lat) * Mathf.Cos(lon);
float calcY = radius * Mathf.Cos(lat) * Mathf.Sin(lon);
float calcZ = radius * Mathf.Sin(lat);
Vector3 result = new Vector3(calcX,calcY,calcZ);
Debug.Log(result);
return result;
}
float[,] mapVals = new float[,] {
{1969.21f, 928.625f},
{1969.6f, 928.533f},
{1968.92f, 928.825f},
{1968.68f, 929f},
{1968.47f, 929.067f},
{1968.41f, 929.025f},
{1968.48f, 928.992f},
....
};
}
谢谢。
答案 0 :(得分:1)
作为旁注,半径是任意的。像素坐标仅映射到方向坐标(极[θ
]和方位角[ϕ
]角度)。
我们可以通过将每个像素映射到相等的θ
和ϕ
间隔来实现此目的。下图说明了低分辨率设置:
让我们采用以下惯例:对于W
的图片,ϕ = 0
对应于:
W
:在X = floor((W - 1) / 2)
和X = ceil((W - 1) / 2)
W
:位于X = floor((W - 1) / 2)
Y
处的像素行映射到θ = (Y + 0.5) / H * π
处的等角线。
要映射完整中的所有像素,请X
从-0.5
开始,而不是0
,并以W - 0.5
结束;同样适用于Y
。由于整数坐标映射到上面所示像素区域的中心,因此可以对任何特定像素的整个区域进行寻址。如果您计划对例如多采样过滤进行多次采样过滤,则稍后可能需要此操作。抗混叠
代码:
Vector3 Mercator(float x, float y, int w, int h)
{
// outside of valid pixel region
if (x < -0.5f || x >= w - 0.5f || y < -0.5f || y >= h - 0.5f)
return new Vector3();
float theta = (y + 0.5f) / h * Math.PI;
float phi = ((x + 0.5f) / w - 0.5f) * 2.0 * Math.PI;
float c_t = Math.Cos(theta);
return new Vector3(c_t * Math.Cos(phi), c_t * Math.Sin(phi), Math.Sin(theta));
}
...并将得到的方向向量乘以你喜欢的任何“半径”,因为它(基本上)与映射无关。