我有一个图像和两个带有旋转和平移分量的相机姿势。姿势之一对应于拍摄图像的姿势。另一个是目标姿势。我想将图像变形为目标姿势。我假设图像中的所有点都来自3D空间中的平面(它们在3D空间中具有相同的Z值)。当我与目标姿势下的groundtruth图像进行比较时,以下代码给出了正确的结果。
glm::mat4 H1 = glm::mat4_cast(targetQuat * glm::inverse(refQuat));
glm::mat4 H2 = glm::mat4_cast(targetQuat );
glm::vec4 T1 = glm::vec4(refLoc, 1.0f);
glm::vec4 T2 = glm::vec4(targetLoc, 1.0f);
glm::vec4 T = glm::transpose(H2) * (T1 - T2);
glm::mat4 rotationMatrix = glm::mat4(1.0f);
rotationMatrix[0] = { H1[0][0], H1[0][1], H1[0][2], T.x };
rotationMatrix[1] = { H1[1][0], H1[1][1], H1[1][2], T.y };
rotationMatrix[2] = { H1[2][0], H1[2][1], H1[2][2], T.z };
rotationMatrix[3] = { 0.0f, 0.0f, 0.0f, 1.0f };
glm::mat4 D = glm::mat4(1.0f);
D[0] = { -Z, 0.0f, 0.0f, 0.0f };
D[1] = { 0.0f, -Z, 0.0f, 0.0f };
D[2] = { 0.0f, 0.0f, -Z, 0.0f };
D[3] = { 0.0f, 0.0f, 0.0f, 1.0f };
glm::mat4 texWarpMatrix = D * rotationMatrix;
texWarpMatrix = glm::transpose(texWarpMatrix);
我正在使用以下代码扭曲纹理点:
glm::vec4 point = glm::vec4(uv, -1.0f, 1.0f);
glm::vec4 tmpTexCoords = *texWarpMatrix * point;
float projIZ = 1.0f / glm::max(tmpTexCoords.z, 0.00001f);
glm::vec2 projectedUV = glm::vec2(tmpTexCoords.x * -projIZ, tmpTexCoords.y * -projIZ);
glm::vec2 vTexcoordR = 0.5f * projectedUV + glm::vec2(0.5, 0.5);
return vTexcoordR;
我的问题是,如果要对此使用透视投影矩阵,在此代码中应在何处以及如何解释?单应性矩阵(rotationMatrix)是否应该更改?还是我们提供Z值的方式应该改变?我假设透视投影矩阵将是这样的:
glm::mat4 fmat = glm::mat4(1.0f);
fmat[0] = { focal / float(width/2), 0.0, 0.0, 0.0 };
fmat[1] = { 0.0, focal / float(height/2), 0.0, 0.0 };
fmat[2] = { 0.0, 0.0, -1.0*(far+near)/(far-near), -1.0 };
fmat[3] = { 0.0, 0.0, -2.0*(far*near)/(far-near), 0.0 };
请告诉我代码中是否还有其他错误。另外,请参阅任何解决此问题的文章或博客。因为我在Opengl世界中还比较陌生,所以它将非常有用。谢谢。