【问题标题】:3D Projection Mapping3D 投影映射
【发布时间】:2011-08-24 19:57:45
【问题描述】:

我正在尝试使用普通的 LCD 投影仪将图像投射到简单的 3D 形状上,但要以可重复的方式进行。

我需要什么: 我最简单的例子是,我将一个立方体放在桌子上,将投影仪连接到三脚架上一段距离,测量两者之间的距离/方向(使用 GOM photogammetry 产品,http://www.capture3d.com/products-TRITOP.html),打开现有的 obj(多边形)形状与立方体完全相同的模型(尺寸非常准确),但带有一些“花哨”的颜色,然后将多边形模型投影到 LCD 投影仪上。

我做了什么: 花了一个月的时间试图确定我的投影仪的内在/外在常数 - 相机对,焦距,主点,失真常数......我想我有它们。 (http://code.google.com/p/procamcalib/)

我找到/修改了代码来打开我的 obj 文件。

我不知道如何处理投影仪的这些内在/外在常量。

我正在使用 opengl / opencv...

【问题讨论】:

  • 为什么?如果您的眼睛/相机与投影仪具有完全相同的位置和方向,结果似乎只会看起来正确。一旦您的眼睛/相机离轴,投影版本看起来就会越来越差。

标签: opengl opencv mapping projection projector


【解决方案1】:

一些有用的链接: http://urbanar.blogspot.it/2011/04/from-homography-to-opengl-modelview.html

http://cvrr.ucsd.edu/publications/2008/MurphyChutorian_Trivedi_CVGPU08.pdf

首先在 k,R,t 中分解 P 矩阵,其中 k 是内在矩阵,R,t 是相对于姿势旋转和平移,然后您可以生成相应的 OpenGL 矩阵,如下所示(我的解决方案是在 C++ 中,但是你可以理解它背后的逻辑):

Eigen::Matrix4d convertIntrinsicToOpenGLProjection(const Eigen::Matrix3d &K,double x0,double y0,double width,double height,double znear,double zfar)
{
    double depth = zfar - znear;
    double q =  -(zfar + znear) / depth;
    double qn = -2.0 * (zfar * znear) / depth;
    Eigen::Matrix4d proj;
    proj << 2*K(0,0)/width, -2*K(0,1)/width, (-2*K(0,2)+width+2*x0)/width, 0 ,
                           0,             -2*K(1,1)/height,(-2*K(1,2)+height+2*y0)/height, 0,
                         0,0,q,qn,
                         0,0,-1,0;
    return proj;
}

Affine3d convertExtrinsicToOpenGLModelView(const Matrix3d &R, const Vector3d &t)
{
    Affine3d MV;
    MV.linear().matrix() << R;
    MV.translation() << t;
    AngleAxis<double> adapter(M_PI,Eigen::Vector3d(1,0,0));
    MV = MV*adapter;
    return MV.inverse();
}
// Decompose P in k,R,t with any DLT direct linear transform procedure or Zhang method
Eigen::Matrix3d K; //intrinsic calibration matrix
    K <<     49.30423  ,   0.00000 ,  387.13187,
        0.00000  ,  26.81592 ,  295.07170,
        0.00000 ,    0.00000   , 1.00000 ;

    int projAreaWidth = 684; //related to the size of your screen
    int projAreaHeight = 608;
    double x0=0,y0=0;
    double zfar=0.1;
    double znear=2000;

Matrix4d P = convertIntrinsicToOpenGLProjection( K,  x0, y0,  width,  height, znear, zfar);
Affine3d MV = convertExtrinsicToOpenGLModelView(R, t);

glPushMatrix();
glLoadMatrixd(P.data());
glMultMatrixd(MV.data());

//draw your object

glPopMatrix();

如果这对你有意义,请告诉我。

【讨论】:

    【解决方案2】:

    您可以按照here 的描述从焦距计算相机的视野。一旦有了视野,就可以使用 gluPerspective() (或do the calculation yourself - 请参阅第 9.085 节)来设置透视矩阵。您显然还需要根据投影仪和对象的位置来更改模型视图矩阵。我不知道你有什么失真数据,但你大概也需要考虑到这一点。

    【讨论】:

      猜你喜欢
      • 2011-07-29
      • 2021-05-05
      • 1970-01-01
      • 2017-05-08
      • 1970-01-01
      • 1970-01-01
      • 2014-12-19
      • 2017-12-21
      • 1970-01-01
      相关资源
      最近更新 更多