Commit 4a1573de authored by ozantonkal's avatar ozantonkal

principal point is always set even though the intrinsic parameters are not given…

principal point is always set even though the intrinsic parameters are not given (center of window), fixed computation mistakes in setWindowSize in camera class
parent bb057491
...@@ -155,10 +155,11 @@ cv::viz::Camera::Camera(const Vec2f &fov, const Size &window_size) ...@@ -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); CV_Assert(window_size.width > 0 && window_size.height > 0);
setClip(Vec2d(0.01, 1000.01)); // Default clipping 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); 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) 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) ...@@ -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::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 near = proj(2,3) / (proj(2,2) - 1.0);
double far = near * (proj(2,2) - 1.0) / (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); 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) ...@@ -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 bottom = near * (proj(1,2)-1) / proj(1,1);
double top = 2.0 * near / proj(1,1) + bottom; double top = 2.0 * near / proj(1,1) + bottom;
if (fabs(left-right) < std::numeric_limits<double>::epsilon()) 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);
principal_point_[0] = -1.0f; focal_[0] = -near * principal_point_[0] / left;
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(top-bottom) < std::numeric_limits<double>::epsilon()) 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);
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; focal_[1] = near * principal_point_[1] / top;
}
setClip(Vec2d(near, far)); 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])); 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) void cv::viz::Camera::init(float f_x, float f_y, float c_x, float c_y, const Size &window_size)
...@@ -221,30 +211,21 @@ void cv::viz::Camera::init(float f_x, float f_y, float c_x, float c_y, const Siz ...@@ -221,30 +211,21 @@ void cv::viz::Camera::init(float f_x, float f_y, float c_x, float c_y, const Siz
focal_[0] = f_x; focal_[0] = f_x;
focal_[1] = f_y; focal_[1] = f_y;
setWindowSize(window_size); window_size_ = window_size;
} }
void cv::viz::Camera::setWindowSize(const Size &window_size) void cv::viz::Camera::setWindowSize(const Size &window_size)
{ {
CV_Assert(window_size.width > 0 && window_size.height > 0); 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 // Get the scale factor and update the principal points
if (window_size_.height != 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);
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) principal_point_[0] *= scalex;
fov_[0] = 2.f * atan(tan(fov_[1] * 0.5f) * aspect_ratio_new); // This assumes that the lens is symmetric! principal_point_[1] *= scaley;
else 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])); fov_[0] = (atan2(principal_point_[0],focal_[0]) + atan2(window_size.width-principal_point_[0],focal_[0]));
window_size_ = window_size; window_size_ = window_size;
...@@ -252,19 +233,10 @@ void cv::viz::Camera::setWindowSize(const Size &window_size) ...@@ -252,19 +233,10 @@ void cv::viz::Camera::setWindowSize(const Size &window_size)
void cv::viz::Camera::computeProjectionMatrix(Matx44f &proj) const void cv::viz::Camera::computeProjectionMatrix(Matx44f &proj) const
{ {
// Symmetric case double top = clip_[0] * principal_point_[1] / focal_[1];
double top = clip_[0] * tan (0.5 * fov_[1]); double left = -clip_[0] * principal_point_[0] / focal_[0];
double left = -(top * window_size_.width) / window_size_.height; double right = clip_[0] * (window_size_.width - principal_point_[0]) / focal_[0];
double right = -left; double bottom = -clip_[0] * (window_size_.height - principal_point_[1]) / focal_[1];
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 temp1 = 2.0 * clip_[0]; double temp1 = 2.0 * clip_[0];
double temp2 = 1.0 / (right - left); double temp2 = 1.0 / (right - left);
......
...@@ -569,18 +569,16 @@ void cv::viz::Viz3d::VizImpl::setCamera(const Camera &camera) ...@@ -569,18 +569,16 @@ void cv::viz::Viz3d::VizImpl::setCamera(const Camera &camera)
vtkCamera& active_camera = *renderer_->GetActiveCamera(); vtkCamera& active_camera = *renderer_->GetActiveCamera();
// Set the intrinsic parameters of the camera // 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); 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 // Use the intrinsic parameters of the camera to simulate more realistically
Matx44f proj_matrix; Matx44f old_proj_mat = convertToMatx(active_camera.GetProjectionTransformMatrix(aspect_ratio, -1.0, 1.0));
camera.computeProjectionMatrix(proj_matrix); vtkTransform *transform = vtkTransform::New();
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();
// This is a hack around not being able to set Projection Matrix // 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); active_camera.SetUserTransform(transform);
transform->Delete(); transform->Delete();
} }
...@@ -590,13 +588,12 @@ cv::viz::Camera cv::viz::Viz3d::VizImpl::getCamera() const ...@@ -590,13 +588,12 @@ cv::viz::Camera cv::viz::Viz3d::VizImpl::getCamera() const
{ {
vtkCamera& active_camera = *renderer_->GetActiveCamera(); 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], Size window_size(renderer_->GetRenderWindow()->GetSize()[0],
renderer_->GetRenderWindow()->GetSize()[1]); renderer_->GetRenderWindow()->GetSize()[1]);
Matx44f old_proj_matrix = convertToMatx(active_camera.GetProjectionTransformMatrix(((float)window_size.width) / window_size.height, -1.0f, 1.0f)); double aspect_ratio = static_cast<double>(window_size.width) / static_cast<double>(window_size.height);
Camera camera(old_proj_matrix, window_size);
// camera.setClip(clip); Matx44f proj_matrix = convertToMatx(active_camera.GetProjectionTransformMatrix(aspect_ratio, -1.0f, 1.0f));
Camera camera(proj_matrix, window_size);
return camera; return camera;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment