2013-08-02 32 views
5

我試圖渲染視圖VTK三維網格的,我做了以下內容:的OpenGL/VTK:設置攝像機內參數

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。

我希望這樣做,以便2d像素-3d相機座標將與圖像是從kinect拍攝一樣。

回答

3

我也使用VTK來模擬來自kinect傳感器的視圖。我正在使用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中完成,其中我設置了類似於我所描述的透視投影矩陣,抓取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方向的焦距不相等。這可以通過使用SetUserTransform方法輕鬆添加到代碼中。下面是在python一個示例代碼:

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) 

其中fx和fy是x和以像素爲單位ÿ焦距,固有照相機矩陣即兩個第一diagnoal元件。 np是numpy導入的別名。

這是一個顯示python完整解決方案的要點(爲簡單起見,沒有外部因素)。它在給定的3D位置放置一個球體,在設置相機內部函數之後將場景渲染爲圖像,然後在圖像平面的球體中心投影處顯示一個紅色圓圈:https://gist.github.com/benoitrosa/ffdb96eae376503dba5ee56f28fa0943