现在我可以将3D世界坐标转换为2D屏幕坐标。 我可以用这个来实现:
D3DXMATRIX viewMatrix = renderer->viewMatrix;
D3DXMATRIX projectionMatrix = renderer->projectionMatrix;
D3DXMATRIX viewProjectionMatrix = D3DXMATRIX();
D3DXMatrixMultiply(&viewProjectionMatrix, &viewMatrix, &projectionMatrix);
D3DXVECTOR3 pScreen = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
D3DXVECTOR3 pWorld(world->getX(), world->getY(), world->getZ());
D3DXVec3TransformCoordImpl(&pScreen, &pWorld, &viewProjectionMatrix);
现在pScreen
包含2D屏幕坐标
我怎样才能将其反转以从2D屏幕坐标中获取3D世界坐标?我正在使用D3DXVec3TransformCoord
函数的这种实现:
D3DXVECTOR3* WINAPI D3DXVec3TransformCoordImpl(D3DXVECTOR3* pout, CONST D3DXVECTOR3* pv, CONST D3DXMATRIX* pm)
{
FLOAT norm = pm->m[0][3] * pv->x + pm->m[1][3] * pv->y + pm->m[2][3] * pv->z + pm->m[3][3];
if (norm)
{
pout->x = (pm->m[0][0] * pv->x + pm->m[1][0] * pv->y + pm->m[2][0] * pv->z + pm->m[3][0]) / norm;
pout->y = (pm->m[0][1] * pv->x + pm->m[1][1] * pv->y + pm->m[2][1] * pv->z + pm->m[3][1]) / norm;
pout->z = (pm->m[0][2] * pv->x + pm->m[1][2] * pv->y + pm->m[2][2] * pv->z + pm->m[3][2]) / norm;
}
else
{
pout->x = 0.0f;
pout->y = 0.0f;
pout->z = 0.0f;
}
return pout;
}
答案 0 :(得分:0)
您可以像这样使用SolvePnP库:
int max = std::max(img.rows,img.cols);
Mat camMatrix = (Mat_<double>(3,3) <<
max_d, 0, img.cols/2.0,
0, max_d, img.rows/2.0,
0, 0, 1.0);
// 2d -> 3d correspondence
vector<Point2d> pts2d = ...
vector<Point3d> pts3d = ...
Mat rvec,tvec;
solvePnP(pts3d, pts2d, camMatrix, Mat(1,4,CV_64F,0.0), rvec, tvec, false, SOLVEPNP_EPNP);
// get 3d rot mat
Mat rotM(3, 3, CV_64F);
Rodrigues(rvec, rotM);
// push tvec to transposed Mat
Mat rotMT = rotM.t();
rotMT.push_back(tvec.reshape(1, 1));
// transpose back, and multiply
camMatrix * rotMT.t();