3

レンジスキャナーから取得した一連のポイント(3D)があります。サンプルデータはここにあります:http://pastebin.com/RBfQLm56

スキャナーには次のパラメーターもあります。

camera matrix
[3871.88184, 0, 950.736938;
  0, 3871.88184, 976.1383059999999;
  0, 0, 1]



distortion coeffs
[0.020208003; -1.41251862; -0.00355229038; -0.00438868301; 6.55825615]



camera to reference point (transform)

[0.0225656671, 0.0194614234, 0.9995559233, 1.2656986283;

  -0.9994773883, -0.0227084301, 0.0230060289, 0.5798922567;

  0.0231460759, -0.99955269, 0.0189388219, -0.2110195758;

  0, 0, 0, 1]

openglを使用してこれらのポイントを適切にレンダリングしようとしていますが、レンダリングが正しく表示されません。openGLプロジェクションとmodelviewマトリックスを設定する正しい方法は何ですか?これは私が現在していることです-

znear = 0.00001
zfar =  100
K = array([[3871.88184, 0, 950.736938],[0, 3871.88184, 976.1383059999999],[0, 0, 1]])
Rt =array([[0.0225656671, 0.0194614234, 0.9995559233, 1.2656986283],[-0.9994773883, -0.0227084301, 0.0230060289, 0.5798922567],[0.0231460759, -0.99955269, 0.0189388219, -0.2110195758]])
ren.set_projection(K,zfar,znear)
ren.set_projection_from_camera(Rt)

使用されている関数は次のとおりです。

def set_projection(self,K,zfar,znear):
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    f_x = K[0,0]
    f_y = K[1,1]
    c_x = K[0,2]
    c_y = K[1,2]
    fovY = 1/(float(f_x)/height * 2);
    aspectRatio = (float(width)/height) * (float(f_y)/f_x);
    near = zfar
    far = znear
    frustum_height = near * fovY;
    frustum_width = frustum_height * aspectRatio;
    offset_x = (width/2 - c_x)/width * frustum_width * 2;
    offset_y = (height/2 - c_y)/height * frustum_height * 2;
    glFrustum(-frustum_width - offset_x, frustum_width - offset_x, -frustum_height - offset_y, frustum_height - offset_y, near, far);


def set_modelview_from_camera(self,Rt):
    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity()
    Rx = array([[1,0,0],[0,0,-1],[0,1,0]])
    R = Rt[:,:3]
    U,S,V = linalg.svd(R)
    R = dot(U,V)
    R[0,:]=-R[0,:]
    t=Rt[:,3]
    M=eye(4)
    M[:3,:3]=dot(R,Rx)
    M[:3,3]=t
    M=M.T
    m=M.flatten()
    glLoadMatrixf(m)

次に、ポイントをレンダリングします(スニペットの貼り付け):

def renderLIDAR(self,filename):
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
    glPushMatrix();

    glEnable(GL_DEPTH_TEST)
    glClear(GL_DEPTH_BUFFER_BIT)
    glPointSize(1.0)
    f = open(filename,'r')
    f.readline() #Contains number of particles
    for line in f:
        line = line.split(' ')
        glBegin(GL_POINTS)
        glColor3f (0.0,1.0,0.0); 
        x = float(line[0])
        y = float(line[1])
        z = float(line[2])
        glVertex3f(x,y,z)
        #print x,y,z
        glEnd()

    glPopMatrix();
4

1 に答える 1

3

返される行列、特に質問の最後の行列は、OpenGL では投影とモデルビューの構成であり、Modelviewprojection とも呼ばれます。

MVP=P・M

イルミネーション計算の実行に関心がない限り、頂点シェーダーでそれを使用できます。つまり、

#version 330

uniform mat4 MVP;
in vec3 position;

void main()
{
    gl_Position = MVP * vec4(position, 1);
}

ところで、OpenGL、そしておそらくあなたが使用しているライブラリも、列優先順を使用しています。つまり、メモリ内の要素の順序は

0 4 8 c
1 5 9 d
2 6 a e
3 7 b f

したがって、ソースコードに書かれていることは「転置された」と考えなければなりません (もちろんそうではありません)。あなたが書いたマトリックスは同じスキームに従っているので、そのままユニフォームに入れることができます. 残っている唯一の問題は、レンジ スキャナーが使用する NDC 空間の境界です。しかし、これは追加のマトリックスを適用することで対処できます。OpenGL は範囲 [-1, 1]^3 を使用するため、発生する可能性のある最悪の事態は、それが他の一般的な NDC 範囲 [0, 1]^3 にある場合、ジオメトリが左上に押し込まれてしまうことです。 Z 軸が反対方向に入ると、おそらく「裏返し」になります。試してみてください。すでに OpenGL と一致していると思います。

とにかく、イルミネーションで使用したい場合は、投影とモデルビューの部分に分解する必要があります。言うは易く行うは難しですが、良い出発点は、左上の 3×3 部分行列を直交正規化することです。これにより、モデルビュー 'M' の回転部分が得られます。次に、左に M を掛けると元の行列が得られる行列 P を見つける必要があります。これは過剰決定された線形方程式のセットなので、Gauss-Jordan スキームで実行できます。そして、私が完全に間違っていなければ、そのカメラ マトリックスの形で既に得られているのは、分解された M または P (私なら M を選びます) です。

取得したら、並進部分 (4 番目の列) もモデルビュー マトリックスに取得することができます。

于 2013-02-11T18:38:43.923 に答える