0

概要:

次のような 3D アプリケーションを作成しようとしています。

www.youtube.com/watch?v=h9kPI7_vhAU. 

OpenCV2.2、Python2.7、pyOpenGL を使用しています。これは、このバックグラウンドの数学とコード スニペットによって実現できます。ここで、x、y、z は視聴者の目の位置です (ウェブカメラから取得したときのように!)。

問題:

これを行うと、レンダリングしたオブジェクト (立方体) が z 軸に沿って (画面に向かって) 引き伸ばされますが、その理由はよくわかりません。これは、(立方体ではなく) 非常に高い超高層ビルを上から見下ろすことに例えられます。キューブの位置は、目の z 位置が変化すると、z 方向に急速に変化します。これは結果のフレームです。引き延ばされています。

コード (bigD の編集による):

def DrawGLScene():
    #get some parameters for calculating the FRUSTUM
    NEAR_CLIPPING_PLANE = 0.01
    FAR_CLIPPING_PLANE  = 2
    window = glGetIntegerv(GL_VIEWPORT)
    WINDOW_WIDTH = window[2]
    WINDOW_HEIGHT= window[3]

    #do facial detection and get eye co-ordinates
    eye = getEye()

    #clear window
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

    #before any projection transformation command comes these 2 lines:
    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()

    #transform projection to that of our eye
    glFrustum(NEAR_CLIPPING_PLANE*(-WINDOW_WIDTH /2 - eye[0])/eye[2],
              NEAR_CLIPPING_PLANE*( WINDOW_WIDTH /2 - eye[0])/eye[2],
              NEAR_CLIPPING_PLANE*(-WINDOW_HEIGHT/2 - eye[1])/eye[2],
              NEAR_CLIPPING_PLANE*( WINDOW_HEIGHT/2 - eye[1])/eye[2],
              NEAR_CLIPPING_PLANE, FAR_CLIPPING_PLANE)

    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity()
    glTranslatef(-eye[0],-eye[1],-eye[2])

    drawCube()

    glutSwapBuffers()

getEye() が返すデータの例は次のとおりです。

[0.25,0.37,1] 視聴者の顔が画面の左下近くにあり、1m 離れている場合

[-0.5,-0.1,0.5] 視聴者の顔が画面の右上近くにあり、0.5m 離れている場合

描画時の立方体の高さ、幅、深さは 2 で、中心は (0,0,0) です。

誰かが同様のプロジェクトをやりたいと思っていて、キックスタートが必要な場合、または問題が提供されたコード以外の場所にあると考えている場合は、完全なコードを提供します.

4

1 に答える 1

1

奇妙な結果が得られる理由は次のとおりです。

glTranslatef(-eye[0],-eye[1],-eye[2])

この呼び出しは後に行う必要があります

glMatrixMode(GL_MODELVIEW)
glLoadIdentity()

射影行列は glFrustum 呼び出しでそのまま準備ができているため、それを平行移動行列で乗算すると、透視射影行列にはなりません。モデルビュー マトリックスは、すべてのワールドとカメラの変換を記述する必要があります。

また、modelview マトリックスで行う変換が平行移動だけの場合は、常に負の Z 軸を見下ろしていることにも注意してください。

于 2013-05-08T09:58:22.660 に答える