principal point is always set even though the intrinsic parameters are not given...
authorozantonkal <ozantonkal@gmail.com>
Fri, 9 Aug 2013 08:39:30 +0000 (10:39 +0200)
committerozantonkal <ozantonkal@gmail.com>
Fri, 9 Aug 2013 08:39:30 +0000 (10:39 +0200)
modules/viz/src/types.cpp
modules/viz/src/viz3d_impl.cpp

index ad9eb27..104fc5a 100644 (file)
@@ -155,10 +155,11 @@ cv::viz::Camera::Camera(const Vec2f &fov, const Size &window_size)
 {
     CV_Assert(window_size.width > 0 && window_size.height > 0);
     setClip(Vec2d(0.01, 1000.01)); // Default clipping
-    principal_point_ = Vec2f(-1.0f, -1.0f); // Default symmetric lens
-    focal_ = Vec2f(-1.0f, -1.0f);
     setFov(fov);
-    setWindowSize(window_size);
+    window_size_ = window_size;
+    // Principal point at the center
+    principal_point_ = Vec2f(static_cast<float>(window_size.width)*0.5f, static_cast<float>(window_size.height)*0.5f);
+    focal_ = Vec2f(principal_point_[0] / tan(fov_[0]*0.5f), principal_point_[1] / tan(fov_[1]*0.5f));
 }
 
 cv::viz::Camera::Camera(const cv::Matx33f & K, const Size &window_size)
@@ -172,6 +173,8 @@ cv::viz::Camera::Camera(const cv::Matx33f & K, const Size &window_size)
 
 cv::viz::Camera::Camera(const Matx44f &proj, const Size &window_size)
 {   
+    CV_Assert(window_size.width > 0 && window_size.height > 0);
+    
     double near = proj(2,3) / (proj(2,2) - 1.0);
     double far = near * (proj(2,2) - 1.0) / (proj(2,2) + 1.0);
     double left = near * (proj(0,2)-1) / proj(0,0);
@@ -179,32 +182,19 @@ cv::viz::Camera::Camera(const Matx44f &proj, const Size &window_size)
     double bottom = near * (proj(1,2)-1) / proj(1,1);
     double top = 2.0 * near / proj(1,1) + bottom;
     
-    if (fabs(left-right) < std::numeric_limits<double>::epsilon()) 
-    { 
-        principal_point_[0] = -1.0f; 
-        focal_[0] = -1.0f;
-    }
-    else 
-    { 
-        principal_point_[0] = (left * static_cast<float>(window_size.width)) / (left - right); 
-        focal_[0] = - near * principal_point_[0] / left;
-    }
+    if (fabs(left-right) < std::numeric_limits<double>::epsilon()) principal_point_[0] = static_cast<float>(window_size.width) * 0.5f;
+    else principal_point_[0] = (left * static_cast<float>(window_size.width)) / (left - right); 
+    focal_[0] = -near * principal_point_[0] / left;
     
-    if (fabs(top-bottom) < std::numeric_limits<double>::epsilon()) 
-    { 
-        principal_point_[1] = -1.0f; 
-        focal_[1] = -1.0f;
-    }
-    else 
-    { 
-        principal_point_[1] = (top * static_cast<float>(window_size.height)) / (top - bottom); 
-        focal_[1] = near * principal_point_[1] / top;
-    }
+    if (fabs(top-bottom) < std::numeric_limits<double>::epsilon()) principal_point_[1] = static_cast<float>(window_size.height) * 0.5f; 
+    else principal_point_[1] = (top * static_cast<float>(window_size.height)) / (top - bottom); 
+    focal_[1] = near * principal_point_[1] / top;
     
     setClip(Vec2d(near, far));
-    // Set the vertical field of view
+    fov_[0] = (atan2(principal_point_[0],focal_[0]) + atan2(window_size.width-principal_point_[0],focal_[0]));
     fov_[1] = (atan2(principal_point_[1],focal_[1]) + atan2(window_size.height-principal_point_[1],focal_[1]));
-    setWindowSize(window_size);
+    
+    window_size_ = window_size;
 }
 
 void cv::viz::Camera::init(float f_x, float f_y, float c_x, float c_y, const Size &window_size)
@@ -221,50 +211,32 @@ void cv::viz::Camera::init(float f_x, float f_y, float c_x, float c_y, const Siz
     focal_[0] = f_x;
     focal_[1] = f_y;
     
-    setWindowSize(window_size);
+    window_size_ = window_size;
 }
 
 void cv::viz::Camera::setWindowSize(const Size &window_size)
 {
     CV_Assert(window_size.width > 0 && window_size.height > 0);
     
-    // Vertical field of view is fixed! 
-    // Horizontal field of view is expandable based on the aspect ratio
-    float aspect_ratio_new = static_cast<float>(window_size.width) / static_cast<float>(window_size.height);
-    
     // Get the scale factor and update the principal points
-    if (window_size_.height != 0)
-    {
-        float aspect_ratio_old = window_size_.width / window_size_.height;
-        float expected_width = aspect_ratio_old * window_size.height;
-        float scale = window_size_.width / expected_width;
-        principal_point_[0] *= scale;
-        principal_point_[1] *= static_cast<float>(window_size.height) / static_cast<float>(window_size_.height);
-    }
-        
-    if (principal_point_[0] < 0.0f)
-        fov_[0] = 2.f * atan(tan(fov_[1] * 0.5f) * aspect_ratio_new); // This assumes that the lens is symmetric!
-    else
-        fov_[0] = (atan2(principal_point_[0],focal_[0]) + atan2(window_size.width-principal_point_[0],focal_[0]));
+    float scalex = static_cast<float>(window_size.width) / static_cast<float>(window_size_.width);
+    float scaley = static_cast<float>(window_size.height) / static_cast<float>(window_size_.height);
+    
+    principal_point_[0] *= scalex;
+    principal_point_[1] *= scaley;
+    focal_ *= scaley;
+    // Vertical field of view is fixed!  Update horizontal field of view
+    fov_[0] = (atan2(principal_point_[0],focal_[0]) + atan2(window_size.width-principal_point_[0],focal_[0]));
     
     window_size_ = window_size;
 }
 
 void cv::viz::Camera::computeProjectionMatrix(Matx44f &proj) const
 {
-    // Symmetric case
-    double top    = clip_[0] * tan (0.5 * fov_[1]);
-    double left   = -(top * window_size_.width) / window_size_.height;
-    double right  = -left;
-    double bottom = -top;
-    // If principal point is defined (i.e intrinsic parameters are known)
-    if (principal_point_[0] > 0.0f)
-    {
-        top = clip_[0] * principal_point_[1] / focal_[1];
-        left = -clip_[0] * principal_point_[0] / focal_[0];
-        right = clip_[0] * (window_size_.width - principal_point_[0]) / focal_[0];
-        bottom = -clip_[0] * (window_size_.height - principal_point_[1]) / focal_[1];
-    }
+    double top = clip_[0] * principal_point_[1] / focal_[1];
+    double left = -clip_[0] * principal_point_[0] / focal_[0];
+    double right = clip_[0] * (window_size_.width - principal_point_[0]) / focal_[0];
+    double bottom = -clip_[0] * (window_size_.height - principal_point_[1]) / focal_[1];
     
     double temp1 = 2.0 * clip_[0];
     double temp2 = 1.0 / (right - left);
index a236b68..a2aa31b 100644 (file)
@@ -569,18 +569,16 @@ void cv::viz::Viz3d::VizImpl::setCamera(const Camera &camera)
     vtkCamera& active_camera = *renderer_->GetActiveCamera();
     
     // Set the intrinsic parameters of the camera
-    active_camera.SetUseHorizontalViewAngle (0); // Horizontal view angle is set based on the window size
-    active_camera.SetViewAngle (camera.getFov()[1] * 180.0f / CV_PI);
-    active_camera.SetClippingRange (camera.getClip()[0], camera.getClip()[1]);
     window_->SetSize (camera.getWindowSize().width, camera.getWindowSize().height);
+    double aspect_ratio = static_cast<double>(camera.getWindowSize().width)/static_cast<double>(camera.getWindowSize().height);
     
+    Matx44f proj_mat;
+    camera.computeProjectionMatrix(proj_mat);
     // Use the intrinsic parameters of the camera to simulate more realistically
-    Matx44f proj_matrix;
-    camera.computeProjectionMatrix(proj_matrix);
-    Matx44f old_proj_matrix = convertToMatx(active_camera.GetProjectionTransformMatrix(static_cast<float>(camera.getWindowSize().width) / static_cast<float>(camera.getWindowSize().height), -1.0f, 1.0f));
-    vtkTransform * transform = vtkTransform::New();
+    Matx44f old_proj_mat = convertToMatx(active_camera.GetProjectionTransformMatrix(aspect_ratio, -1.0, 1.0));
+    vtkTransform *transform = vtkTransform::New();
     // This is a hack around not being able to set Projection Matrix
-    transform->SetMatrix(convertToVtkMatrix(proj_matrix * old_proj_matrix.inv())); 
+    transform->SetMatrix(convertToVtkMatrix(proj_mat * old_proj_mat.inv()));
     active_camera.SetUserTransform(transform);
     transform->Delete();
 }
@@ -590,13 +588,12 @@ cv::viz::Camera cv::viz::Viz3d::VizImpl::getCamera() const
 {
     vtkCamera& active_camera = *renderer_->GetActiveCamera();
     
-    Vec2f fov(0.0, active_camera.GetViewAngle() * CV_PI / 180.0f);
-    Vec2d clip(active_camera.GetClippingRange());
     Size window_size(renderer_->GetRenderWindow()->GetSize()[0],
                      renderer_->GetRenderWindow()->GetSize()[1]);
-    Matx44f old_proj_matrix = convertToMatx(active_camera.GetProjectionTransformMatrix(((float)window_size.width) / window_size.height, -1.0f, 1.0f));
-    Camera camera(old_proj_matrix, window_size);
-//     camera.setClip(clip);
+    double aspect_ratio = static_cast<double>(window_size.width) / static_cast<double>(window_size.height);
+    
+    Matx44f proj_matrix = convertToMatx(active_camera.GetProjectionTransformMatrix(aspect_ratio, -1.0f, 1.0f));
+    Camera camera(proj_matrix, window_size);
     return camera;
 }