2013-08-02 20 views
5

は、私は次のことをやっている:のOpenGL/VTK:私はVTKで、3Dメッシュのビューをレンダリングしようとしている設定をカメラ内部パラメータ

vtkSmartPointer<vtkRenderWindow> render_win = vtkSmartPointer<vtkRenderWindow>::New(); 
vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New(); 

render_win->AddRenderer(renderer); 
render_win->SetSize(640, 480); 

vtkSmartPointer<vtkCamera> cam = vtkSmartPointer<vtkCamera>::New(); 

cam->SetPosition(50, 50, 50); 
cam->SetFocalPoint(0, 0, 0); 
cam->SetViewUp(0, 1, 0); 
cam->Modified(); 

vtkSmartPointer<vtkActor> actor_view = vtkSmartPointer<vtkActor>::New(); 

actor_view->SetMapper(mapper); 
renderer->SetActiveCamera(cam); 
renderer->AddActor(actor_view); 

render_win->Render(); 

私は、キャリブレーションのKinectからのレンダリングをシミュレートしようとしています私はそれが本質的なパラメータを知っている。どのようにしてvtkCameraに固有のパラメータ(焦点距離と主点)を設定できますか?

2次元ピクセルと3次元のカメラ座標が、キネクトからイメージを撮影した場合と同じになるようにしたいと思います。

答えて

3

私もkinectセンサーからのビューをシミュレートするためにVTKを使用しています。私はVTK 6.1.0を使用しています。私はこの質問は古いことを知っているが、うまくいけば私の答えは他の人を助けるかもしれない。

問題は、世界座標をクリップ座標にマップするために投影行列を設定する方法です。その詳細についてはこちらを参照してくださいOpenGL explanation.

私は、kinectセンサーをシミュレートするために透視投影行列を使用します。組み込みパラメータを制御するには、vtkCameraの以下のメンバ関数を使用できます。

double fov = 60.0, np = 0.5, fp = 10; // the values I use 
cam->SetViewAngle(fov);    // vertical field of view angle 
cam->SetClippingRange(np, fp);  // near and far clipping planes 

あなたにどのように見えるかを伝えるために、私はold projectをC++とOpenGLで完全に行いました。その中で私が記述した方法に似たPerspective Projection Matrixを設定し、zバッファをつかんで別のカメラから見たシーンにポイントを再投影しました。 (視覚化されたポイントクラウドはノイズをシミュレートしているのでノイズが多いように見えます)。

パースペクティブフレーバーではない独自のカスタムプロジェクションマトリックスが必要な場合は、私はそう信じています:

cam->SetUserTransform(transform); // transform is a pointer to type vtkHomogeneousTransform 

しかし、私はSetUserTransformメソッドを使用していません。

8

これは、ピンホールカメラの標準的なパラメータをvtkCameraに変換するのに役立ちます。完全な変換を行う方法を示す要点を作成しました。私は、世界がレンダリングされたイメージの正しい場所にプロジェクトをポイントしていることを確認しました。要点のキーコードは下に貼り付けられます。

要旨:https://gist.github.com/decrispell/fc4b69f6bedf07a3425b

// apply the transform to scene objects 
    camera->SetModelTransformMatrix(camera_RT); 

    // the camera can stay at the origin because we are transforming the scene objects 
    camera->SetPosition(0, 0, 0); 
    // look in the +Z direction of the camera coordinate system 
    camera->SetFocalPoint(0, 0, 1); 
    // the camera Y axis points down 
    camera->SetViewUp(0,-1,0); 

    // ensure the relevant range of depths are rendered 
    camera->SetClippingRange(depth_min, depth_max); 

    // convert the principal point to window center (normalized coordinate system) and set it 
    double wcx = -2*(principal_pt.x() - double(nx)/2)/nx; 
    double wcy = 2*(principal_pt.y() - double(ny)/2)/ny; 
    camera->SetWindowCenter(wcx, wcy); 

    // convert the focal length to view angle and set it 
    double view_angle = vnl_math::deg_per_rad * (2.0 * std::atan2(ny/2.0, focal_len)); 
    std::cout << "view_angle = " << view_angle << std::endl; 
    camera->SetViewAngle(view_angle); 
+0

この回答に感謝します!私はピンホールカメラで見ることが期待されるものを見るためにvtkカメラを作るために一週間を費やしました、そして、私はそれをほぼ正しいものにしましたが、いつもある違いがありました。カメラを静かにして、シーンを動かすとうまくいった! – martinako

+0

これは機能します!素晴らしい感謝! – alanwsx

0

このスレッドはVTK、特にdecrispellの答えにカメラの組み込み関数を設定するための私には超便利でした。しかし、xとy方向の焦点距離が等しくない場合、1つのケースが欠けている。これは、SetUserTransformメソッドを使用してコードに簡単に追加できます。以下のPythonのサンプルコードである:

FXおよびFyはX画素のY焦点距離、真性カメラ行列のすなわち二つの第一diagnoal素子で
cam = self.renderer.GetActiveCamera() 
m = np.eye(4) 
m[0,0] = 1.0*fx/fy 
t = vtk.vtkTransform() 
t.SetMatrix(m.flatten()) 
cam.SetUserTransform(t) 

。 npはnumpyのインポートのエイリアスです。

ここでは、pythonで完全な解決策を示している要点を示しています(簡単にするために外来語はありません)。与えられた3D位置に球を配置し、カメラの組み込み関数を設定した後にそのシーンを画像にレンダリングし、球面の投影をイメージプレーンに赤い円で表示します。https://gist.github.com/benoitrosa/ffdb96eae376503dba5ee56f28fa0943

関連する問題