From 8fa6b6a6ef4ed9d49c1a3f00de7f38f724a6038e Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Thu, 1 Aug 2013 15:22:35 +0200 Subject: [PATCH 01/19] initial setViewerPose implementation --- modules/viz/include/opencv2/viz/viz3d.hpp | 3 +++ modules/viz/src/viz3d.cpp | 3 +++ modules/viz/src/viz3d_impl.cpp | 22 ++++++++++++++++++++++ modules/viz/src/viz3d_impl.hpp | 1 + 4 files changed, 29 insertions(+) diff --git a/modules/viz/include/opencv2/viz/viz3d.hpp b/modules/viz/include/opencv2/viz/viz3d.hpp index db8819afd7..8fbaacd55a 100644 --- a/modules/viz/include/opencv2/viz/viz3d.hpp +++ b/modules/viz/include/opencv2/viz/viz3d.hpp @@ -38,6 +38,9 @@ namespace cv void setWidgetPose(const String &id, const Affine3f &pose); void updateWidgetPose(const String &id, const Affine3f &pose); Affine3f getWidgetPose(const String &id) const; + + Affine3f getViewerPose(); + void setViewerPose(const Affine3f &pose); void spin(); void spinOnce(int time = 1, bool force_redraw = false); diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp index f4a300b212..6bf00172c1 100644 --- a/modules/viz/src/viz3d.cpp +++ b/modules/viz/src/viz3d.cpp @@ -45,3 +45,6 @@ cv::viz::Widget cv::viz::Viz3d::getWidget(const String &id) const { return impl_ void cv::viz::Viz3d::setWidgetPose(const String &id, const Affine3f &pose) { impl_->setWidgetPose(id, pose); } void cv::viz::Viz3d::updateWidgetPose(const String &id, const Affine3f &pose) { impl_->updateWidgetPose(id, pose); } cv::Affine3f cv::viz::Viz3d::getWidgetPose(const String &id) const { return impl_->getWidgetPose(id); } + +void cv::viz::Viz3d::setViewerPose(const Affine3f &pose) { impl_->setViewerPose(pose); } +cv::Affine3f cv::viz::Viz3d::getViewerPose() { return impl_->getViewerPose(); } diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index ca4b75bbf7..fb72047c5c 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -591,6 +591,28 @@ void cv::viz::Viz3d::VizImpl::getCameras (cv::viz::Camera& camera) camera.window_pos = cv::Vec2d::all(0); } +///////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::Viz3d::VizImpl::setViewerPose(const Affine3f &pose) +{ + vtkCamera& camera = *renderer_->GetActiveCamera (); + + // Position = extrinsic translation + cv::Vec3f pos_vec = pose.translation(); + + // Rotate the view vector + cv::Matx33f rotation = pose.rotation(); + cv::Vec3f y_axis (0.f, 1.f, 0.f); + cv::Vec3f up_vec (rotation * y_axis); + + // Compute the new focal point + cv::Vec3f z_axis (0.f, 0.f, 1.f); + cv::Vec3f focal_vec = pos_vec + rotation * z_axis; + + camera.SetPosition(pos_vec[0], pos_vec[1], pos_vec[2]); + camera.SetFocalPoint(focal_vec[0], focal_vec[1], focal_vec[2]); + camera.SetViewUp(up_vec[0], up_vec[1], up_vec[2]); +} + ///////////////////////////////////////////////////////////////////////////////////////////// cv::Affine3f cv::viz::Viz3d::VizImpl::getViewerPose () { diff --git a/modules/viz/src/viz3d_impl.hpp b/modules/viz/src/viz3d_impl.hpp index c6bef09885..704cf08a87 100644 --- a/modules/viz/src/viz3d_impl.hpp +++ b/modules/viz/src/viz3d_impl.hpp @@ -140,6 +140,7 @@ public: void getCameras (Camera& camera); //to implement Viz3d set/getViewerPose() + void setViewerPose(const Affine3f &pose); Affine3f getViewerPose(); From a76cc9ef88a3876da371faa4224281ccff6cf1e9 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Fri, 2 Aug 2013 16:33:30 +0200 Subject: [PATCH 02/19] initial camera implementation (camera2), fix bug (zeros method) --- modules/viz/include/opencv2/viz/types.hpp | 25 +++++++++++ modules/viz/src/types.cpp | 54 +++++++++++++++++++++++ 2 files changed, 79 insertions(+) diff --git a/modules/viz/include/opencv2/viz/types.hpp b/modules/viz/include/opencv2/viz/types.hpp index b0e3efda3d..4ef05a68a2 100644 --- a/modules/viz/include/opencv2/viz/types.hpp +++ b/modules/viz/include/opencv2/viz/types.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include @@ -93,6 +94,30 @@ namespace cv Point pointer; unsigned int key_state; }; + + class CV_EXPORTS Camera2 + { + public: + Camera2(float f_x, float f_y, float c_x, float c_y, const Size &window_size); + Camera2(const Vec2f &fov, const Size &window_size); + Camera2(const cv::Mat &K, const Size &window_size); + + inline const Vec2d & getClip() const { return clip_; } + inline void setClip(const Vec2d &clip) { clip_ = clip; } + + inline const Size & getWindowSize() const { return window_size_; } + void setWindowSize(const Size &window_size); + + inline const Vec2f & getFov() const { return fov_; } + inline void setFov(const Vec2f & fov) { fov_ = fov; } + + private: + Vec2d clip_; + Vec2f fov_; + Size window_size_; + Vec2f principal_point_; + Vec2f focal_; + }; } /* namespace viz */ } /* namespace cv */ diff --git a/modules/viz/src/types.cpp b/modules/viz/src/types.cpp index 871c2dbcb6..4ea1b32d37 100644 --- a/modules/viz/src/types.cpp +++ b/modules/viz/src/types.cpp @@ -142,3 +142,57 @@ cv::viz::Mesh3d cv::viz::Mesh3d::loadMesh(const String& file) { return loadMeshImpl::loadMesh(file); } + +//////////////////////////////////////////////////////////////////// +/// Camera implementation + +cv::viz::Camera2::Camera2(float f_x, float f_y, float c_x, float c_y, const Size &window_size) +{ + CV_Assert(window_size.width > 0 && window_size.height > 0); + setClip(Vec2d(0.01, 1000.01));// Default clipping + + fov_[0] = (atan2(c_x,f_x) + atan2(window_size.width-c_x,f_x)) * 180 / CV_PI; + fov_[1] = (atan2(c_y,f_y) + atan2(window_size.height-c_y,f_y)) * 180 / CV_PI; + + principal_point_[0] = c_x; + principal_point_[1] = c_y; + + focal_[0] = f_x; + focal_[1] = f_y; +} + +cv::viz::Camera2::Camera2(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 + window_size_ = window_size; + fov_ = fov; + principal_point_ = Vec2f(-1.0f, -1.0f); // Symmetric lens + focal_ = Vec2f(-1.0f, -1.0f); +} + +cv::viz::Camera2::Camera2(const cv::Mat & K, const Size &window_size) +{ + CV_Assert(K.rows == 3 && K.cols == 3); + CV_Assert(window_size.width > 0 && window_size.height > 0); + + float f_x = K.at(0,0); + float f_y = K.at(1,1); + float c_x = K.at(0,2); + float c_y = K.at(1,2); + Camera2(f_x, f_y, c_x, c_y, window_size); +} + +void cv::viz::Camera2::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 = window_size.width / window_size.height; + + if (principal_point_[0] < 0.0f) + fov_[0] = 2 * atan2(tan(fov_[0] * 0.5), 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])) * 180 / CV_PI; +} From e4e9ed876f2170409e74bd7dbca33dc3cca72413 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Sat, 3 Aug 2013 15:40:36 +0200 Subject: [PATCH 03/19] spheres trajectory widget implementation --- modules/viz/include/opencv2/viz/widgets.hpp | 10 +- modules/viz/src/shape_widgets.cpp | 171 ++++++++++---------- 2 files changed, 98 insertions(+), 83 deletions(-) diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index 603d17df83..c746330498 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -182,14 +182,19 @@ namespace cv enum {DISPLAY_FRAMES = 1, DISPLAY_PATH = 2}; TrajectoryWidget(const std::vector &path, int display_mode = TrajectoryWidget::DISPLAY_PATH, const Color &color = Color::white(), double scale = 1.0); - TrajectoryWidget(const std::vector &path, float line_length, double init_sphere_radius, - double sphere_radius, const Color &line_color = Color::white(), const Color &sphere_color = Color::white()); TrajectoryWidget(const std::vector &path, const Matx33f &K, double scale = 1.0, const Color &color = Color::white()); // Camera frustums TrajectoryWidget(const std::vector &path, const Vec2f &fov, double scale = 1.0, const Color &color = Color::white()); // Camera frustums private: struct ApplyPath; }; + + class CV_EXPORTS SpheresTrajectoryWidget : public Widget3D + { + public: + SpheresTrajectoryWidget(const std::vector &path, float line_length = 0.05f, double init_sphere_radius = 0.021, + double sphere_radius = 0.007, const Color &line_color = Color::white(), const Color &sphere_color = Color::white()); + }; class CV_EXPORTS CloudWidget : public Widget3D { @@ -249,6 +254,7 @@ namespace cv template<> CV_EXPORTS Image3DWidget Widget::cast(); template<> CV_EXPORTS CameraPositionWidget Widget::cast(); template<> CV_EXPORTS TrajectoryWidget Widget::cast(); + template<> CV_EXPORTS SpheresTrajectoryWidget Widget::cast(); template<> CV_EXPORTS CloudWidget Widget::cast(); template<> CV_EXPORTS CloudCollectionWidget Widget::cast(); template<> CV_EXPORTS CloudNormalsWidget Widget::cast(); diff --git a/modules/viz/src/shape_widgets.cpp b/modules/viz/src/shape_widgets.cpp index caa5bf3588..050b978ef6 100644 --- a/modules/viz/src/shape_widgets.cpp +++ b/modules/viz/src/shape_widgets.cpp @@ -1181,87 +1181,6 @@ cv::viz::TrajectoryWidget::TrajectoryWidget(const std::vector &path, i WidgetAccessor::setProp(*this, actor); } -cv::viz::TrajectoryWidget::TrajectoryWidget(const std::vector &path, float line_length, double init_sphere_radius, - double sphere_radius, const Color &line_color, const Color &sphere_color) -{ - vtkSmartPointer appendFilter = vtkSmartPointer::New(); - vtkIdType nr_poses = path.size(); - - // Create color arrays - vtkSmartPointer line_scalars = vtkSmartPointer::New(); - line_scalars->SetNumberOfComponents(3); - line_scalars->InsertNextTuple3(line_color[2], line_color[1], line_color[0]); - - // Create color array for sphere - vtkSphereSource * dummy_sphere = vtkSphereSource::New(); - // Create the array for big sphere - dummy_sphere->SetRadius(init_sphere_radius); - dummy_sphere->Update(); - vtkIdType nr_points = dummy_sphere->GetOutput()->GetNumberOfCells(); - vtkSmartPointer sphere_scalars_init = vtkSmartPointer::New(); - sphere_scalars_init->SetNumberOfComponents(3); - sphere_scalars_init->SetNumberOfTuples(nr_points); - sphere_scalars_init->FillComponent(0, sphere_color[2]); - sphere_scalars_init->FillComponent(1, sphere_color[1]); - sphere_scalars_init->FillComponent(2, sphere_color[0]); - // Create the array for small sphere - dummy_sphere->SetRadius(sphere_radius); - dummy_sphere->Update(); - nr_points = dummy_sphere->GetOutput()->GetNumberOfCells(); - vtkSmartPointer sphere_scalars = vtkSmartPointer::New(); - sphere_scalars->SetNumberOfComponents(3); - sphere_scalars->SetNumberOfTuples(nr_points); - sphere_scalars->FillComponent(0, sphere_color[2]); - sphere_scalars->FillComponent(1, sphere_color[1]); - sphere_scalars->FillComponent(2, sphere_color[0]); - dummy_sphere->Delete(); - - for (vtkIdType i = 0; i < nr_poses; ++i) - { - Point3f new_pos = path[i].translation(); - - vtkSmartPointer sphere_source = vtkSmartPointer::New(); - sphere_source->SetCenter (new_pos.x, new_pos.y, new_pos.z); - if (i == 0) - { - sphere_source->SetRadius(init_sphere_radius); - sphere_source->Update(); - sphere_source->GetOutput()->GetCellData()->SetScalars(sphere_scalars_init); - appendFilter->AddInputConnection(sphere_source->GetOutputPort()); - continue; - } - else - { - sphere_source->SetRadius(sphere_radius); - sphere_source->Update(); - sphere_source->GetOutput()->GetCellData()->SetScalars(sphere_scalars); - appendFilter->AddInputConnection(sphere_source->GetOutputPort()); - } - - - Affine3f relativeAffine = path[i].inv() * path[i-1]; - Vec3f v = path[i].rotation() * relativeAffine.translation(); - v = normalize(v) * line_length; - - vtkSmartPointer line_source = vtkSmartPointer::New(); - line_source->SetPoint1(new_pos.x + v[0], new_pos.y + v[1], new_pos.z + v[2]); - line_source->SetPoint2(new_pos.x, new_pos.y, new_pos.z); - line_source->Update(); - line_source->GetOutput()->GetCellData()->SetScalars(line_scalars); - - appendFilter->AddInputConnection(line_source->GetOutputPort()); - } - - vtkSmartPointer mapper = vtkSmartPointer::New(); - mapper->SetScalarModeToUseCellData(); - mapper->SetInput(appendFilter->GetOutput()); - - vtkSmartPointer actor = vtkSmartPointer::New(); - actor->SetMapper(mapper); - - WidgetAccessor::setProp(*this, actor); -} - cv::viz::TrajectoryWidget::TrajectoryWidget(const std::vector &path, const Matx33f &K, double scale, const Color &color) { vtkSmartPointer camera = vtkSmartPointer::New(); @@ -1350,4 +1269,94 @@ template<> cv::viz::TrajectoryWidget cv::viz::Widget::castcast(); return static_cast(widget); +} + +/////////////////////////////////////////////////////////////////////////////////////////////// +/// spheres trajectory widget implementation + +cv::viz::SpheresTrajectoryWidget::SpheresTrajectoryWidget(const std::vector &path, float line_length, double init_sphere_radius, double sphere_radius, + const Color &line_color, const Color &sphere_color) +{ + vtkSmartPointer appendFilter = vtkSmartPointer::New(); + vtkIdType nr_poses = path.size(); + + // Create color arrays + vtkSmartPointer line_scalars = vtkSmartPointer::New(); + line_scalars->SetNumberOfComponents(3); + line_scalars->InsertNextTuple3(line_color[2], line_color[1], line_color[0]); + + // Create color array for sphere + vtkSphereSource * dummy_sphere = vtkSphereSource::New(); + // Create the array for big sphere + dummy_sphere->SetRadius(init_sphere_radius); + dummy_sphere->Update(); + vtkIdType nr_points = dummy_sphere->GetOutput()->GetNumberOfCells(); + vtkSmartPointer sphere_scalars_init = vtkSmartPointer::New(); + sphere_scalars_init->SetNumberOfComponents(3); + sphere_scalars_init->SetNumberOfTuples(nr_points); + sphere_scalars_init->FillComponent(0, sphere_color[2]); + sphere_scalars_init->FillComponent(1, sphere_color[1]); + sphere_scalars_init->FillComponent(2, sphere_color[0]); + // Create the array for small sphere + dummy_sphere->SetRadius(sphere_radius); + dummy_sphere->Update(); + nr_points = dummy_sphere->GetOutput()->GetNumberOfCells(); + vtkSmartPointer sphere_scalars = vtkSmartPointer::New(); + sphere_scalars->SetNumberOfComponents(3); + sphere_scalars->SetNumberOfTuples(nr_points); + sphere_scalars->FillComponent(0, sphere_color[2]); + sphere_scalars->FillComponent(1, sphere_color[1]); + sphere_scalars->FillComponent(2, sphere_color[0]); + dummy_sphere->Delete(); + + for (vtkIdType i = 0; i < nr_poses; ++i) + { + Point3f new_pos = path[i].translation(); + + vtkSmartPointer sphere_source = vtkSmartPointer::New(); + sphere_source->SetCenter (new_pos.x, new_pos.y, new_pos.z); + if (i == 0) + { + sphere_source->SetRadius(init_sphere_radius); + sphere_source->Update(); + sphere_source->GetOutput()->GetCellData()->SetScalars(sphere_scalars_init); + appendFilter->AddInputConnection(sphere_source->GetOutputPort()); + continue; + } + else + { + sphere_source->SetRadius(sphere_radius); + sphere_source->Update(); + sphere_source->GetOutput()->GetCellData()->SetScalars(sphere_scalars); + appendFilter->AddInputConnection(sphere_source->GetOutputPort()); + } + + + Affine3f relativeAffine = path[i].inv() * path[i-1]; + Vec3f v = path[i].rotation() * relativeAffine.translation(); + v = normalize(v) * line_length; + + vtkSmartPointer line_source = vtkSmartPointer::New(); + line_source->SetPoint1(new_pos.x + v[0], new_pos.y + v[1], new_pos.z + v[2]); + line_source->SetPoint2(new_pos.x, new_pos.y, new_pos.z); + line_source->Update(); + line_source->GetOutput()->GetCellData()->SetScalars(line_scalars); + + appendFilter->AddInputConnection(line_source->GetOutputPort()); + } + + vtkSmartPointer mapper = vtkSmartPointer::New(); + mapper->SetScalarModeToUseCellData(); + mapper->SetInput(appendFilter->GetOutput()); + + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->SetMapper(mapper); + + WidgetAccessor::setProp(*this, actor); +} + +template<> cv::viz::SpheresTrajectoryWidget cv::viz::Widget::cast() +{ + Widget3D widget = this->cast(); + return static_cast(widget); } \ No newline at end of file From 4953786de1e1c21b43bbda79155177368bd1853d Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Sat, 3 Aug 2013 15:42:10 +0200 Subject: [PATCH 04/19] remove boost include (caused by Kdevelop autocomplete) --- modules/viz/include/opencv2/viz/types.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/viz/include/opencv2/viz/types.hpp b/modules/viz/include/opencv2/viz/types.hpp index 4ef05a68a2..33b22325f2 100644 --- a/modules/viz/include/opencv2/viz/types.hpp +++ b/modules/viz/include/opencv2/viz/types.hpp @@ -1,7 +1,6 @@ #pragma once #include -#include #include #include From f445f76213be9337077cf78bc790ba39b2c452fc Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Sat, 3 Aug 2013 16:33:11 +0200 Subject: [PATCH 05/19] initial setCamera implementation --- modules/viz/include/opencv2/viz/viz3d.hpp | 1 + modules/viz/src/types.cpp | 2 +- modules/viz/src/viz3d.cpp | 1 + modules/viz/src/viz3d_impl.cpp | 12 ++++++++++++ modules/viz/src/viz3d_impl.hpp | 2 ++ 5 files changed, 17 insertions(+), 1 deletion(-) diff --git a/modules/viz/include/opencv2/viz/viz3d.hpp b/modules/viz/include/opencv2/viz/viz3d.hpp index 8fbaacd55a..e173fcfca0 100644 --- a/modules/viz/include/opencv2/viz/viz3d.hpp +++ b/modules/viz/include/opencv2/viz/viz3d.hpp @@ -39,6 +39,7 @@ namespace cv void updateWidgetPose(const String &id, const Affine3f &pose); Affine3f getWidgetPose(const String &id) const; + void setCamera(const Camera2 &camera); Affine3f getViewerPose(); void setViewerPose(const Affine3f &pose); diff --git a/modules/viz/src/types.cpp b/modules/viz/src/types.cpp index 4ea1b32d37..e95f67e567 100644 --- a/modules/viz/src/types.cpp +++ b/modules/viz/src/types.cpp @@ -167,7 +167,7 @@ cv::viz::Camera2::Camera2(const Vec2f &fov, const Size &window_size) setClip(Vec2d(0.01, 1000.01)); // Default clipping window_size_ = window_size; fov_ = fov; - principal_point_ = Vec2f(-1.0f, -1.0f); // Symmetric lens + principal_point_ = Vec2f(-1.0f, -1.0f); // Default symmetric lens focal_ = Vec2f(-1.0f, -1.0f); } diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp index 6bf00172c1..8aa97419f7 100644 --- a/modules/viz/src/viz3d.cpp +++ b/modules/viz/src/viz3d.cpp @@ -46,5 +46,6 @@ void cv::viz::Viz3d::setWidgetPose(const String &id, const Affine3f &pose) { imp void cv::viz::Viz3d::updateWidgetPose(const String &id, const Affine3f &pose) { impl_->updateWidgetPose(id, pose); } cv::Affine3f cv::viz::Viz3d::getWidgetPose(const String &id) const { return impl_->getWidgetPose(id); } +void cv::viz::Viz3d::setCamera(const Camera2 &camera) { impl_->setCamera(camera); } void cv::viz::Viz3d::setViewerPose(const Affine3f &pose) { impl_->setViewerPose(pose); } cv::Affine3f cv::viz::Viz3d::getViewerPose() { return impl_->getViewerPose(); } diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index fb72047c5c..78c1441a36 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -591,6 +591,18 @@ void cv::viz::Viz3d::VizImpl::getCameras (cv::viz::Camera& camera) camera.window_pos = cv::Vec2d::all(0); } +///////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::Viz3d::VizImpl::setCamera(const Camera2 &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 (static_cast (camera.getWindowSize().width), static_cast (camera.getWindowSize().height)); +} + ///////////////////////////////////////////////////////////////////////////////////////////// void cv::viz::Viz3d::VizImpl::setViewerPose(const Affine3f &pose) { diff --git a/modules/viz/src/viz3d_impl.hpp b/modules/viz/src/viz3d_impl.hpp index 704cf08a87..26bafd3428 100644 --- a/modules/viz/src/viz3d_impl.hpp +++ b/modules/viz/src/viz3d_impl.hpp @@ -109,6 +109,8 @@ public: // //////////////////////////////////////////////////////////////////////////////////// // All camera methods to refactor into set/getViewwerPose, setCamera() // and 'Camera' class itself with various constructors/fields + + void setCamera(const Camera2 &camera); void initCameraParameters (); /** \brief Initialize camera parameters with some default values. */ bool cameraParamsSet () const; /** \brief Checks whether the camera parameters were manually loaded from file.*/ From 0bb89e767a8f40f6a14683fd0288d8739a18d297 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Sun, 4 Aug 2013 17:01:41 +0200 Subject: [PATCH 06/19] fix field of view formula in camera class, implement get camera --- modules/viz/src/types.cpp | 2 +- modules/viz/src/viz3d_impl.cpp | 10 ++++++++++ modules/viz/src/viz3d_impl.hpp | 1 + 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/modules/viz/src/types.cpp b/modules/viz/src/types.cpp index e95f67e567..827b8b3bc9 100644 --- a/modules/viz/src/types.cpp +++ b/modules/viz/src/types.cpp @@ -192,7 +192,7 @@ void cv::viz::Camera2::setWindowSize(const Size &window_size) float aspect_ratio_new = window_size.width / window_size.height; if (principal_point_[0] < 0.0f) - fov_[0] = 2 * atan2(tan(fov_[0] * 0.5), aspect_ratio_new); // This assumes that the lens is symmetric! + fov_[0] = 2 * atan2(tan(fov_[1] * 0.5), 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])) * 180 / CV_PI; } diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index 78c1441a36..f764c77558 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -603,6 +603,16 @@ void cv::viz::Viz3d::VizImpl::setCamera(const Camera2 &camera) window_->SetSize (static_cast (camera.getWindowSize().width), static_cast (camera.getWindowSize().height)); } +///////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::Viz3d::VizImpl::getCamera(viz::Camera2 &camera) +{ + vtkCamera& active_camera = *renderer_->GetActiveCamera(); + camera.setFov(Vec2f(0.0, active_camera.GetViewAngle() * CV_PI / 180.0f)); + camera.setClip(Vec2d(active_camera.GetClippingRange())); + camera.setWindowSize(Size(renderer_->GetRenderWindow()->GetSize()[0], + renderer_->GetRenderWindow()->GetSize()[1])); +} + ///////////////////////////////////////////////////////////////////////////////////////////// void cv::viz::Viz3d::VizImpl::setViewerPose(const Affine3f &pose) { diff --git a/modules/viz/src/viz3d_impl.hpp b/modules/viz/src/viz3d_impl.hpp index 26bafd3428..5bd4ebdea6 100644 --- a/modules/viz/src/viz3d_impl.hpp +++ b/modules/viz/src/viz3d_impl.hpp @@ -111,6 +111,7 @@ public: // and 'Camera' class itself with various constructors/fields void setCamera(const Camera2 &camera); + void getCamera(Camera2 &camera); void initCameraParameters (); /** \brief Initialize camera parameters with some default values. */ bool cameraParamsSet () const; /** \brief Checks whether the camera parameters were manually loaded from file.*/ From 439ba98e0a14a0f382e58720f5601854e3c1330a Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Mon, 5 Aug 2013 13:01:21 +0200 Subject: [PATCH 07/19] initial implementation of projection matrix, 3D to window coordinates, window coordinates to 3D ray (not yet tested) --- modules/viz/include/opencv2/viz/types.hpp | 2 ++ modules/viz/include/opencv2/viz/viz3d.hpp | 3 ++ modules/viz/src/types.cpp | 23 ++++++++++++ modules/viz/src/viz3d.cpp | 3 ++ modules/viz/src/viz3d_impl.cpp | 44 ++++++++++++++++++++--- modules/viz/src/viz3d_impl.hpp | 6 ++-- 6 files changed, 73 insertions(+), 8 deletions(-) diff --git a/modules/viz/include/opencv2/viz/types.hpp b/modules/viz/include/opencv2/viz/types.hpp index 33b22325f2..8dd68196b4 100644 --- a/modules/viz/include/opencv2/viz/types.hpp +++ b/modules/viz/include/opencv2/viz/types.hpp @@ -110,6 +110,8 @@ namespace cv inline const Vec2f & getFov() const { return fov_; } inline void setFov(const Vec2f & fov) { fov_ = fov; } + void computeProjectionMatrix(Matx44f &proj) const; + private: Vec2d clip_; Vec2f fov_; diff --git a/modules/viz/include/opencv2/viz/viz3d.hpp b/modules/viz/include/opencv2/viz/viz3d.hpp index e173fcfca0..eff8ac000b 100644 --- a/modules/viz/include/opencv2/viz/viz3d.hpp +++ b/modules/viz/include/opencv2/viz/viz3d.hpp @@ -42,6 +42,9 @@ namespace cv void setCamera(const Camera2 &camera); Affine3f getViewerPose(); void setViewerPose(const Affine3f &pose); + + void convertToWindowCoordinates(const Point3f &pt, Point3f &window_coord); + void converTo3DRay(const Point3f &window_coord, Point3f &origin, Vec3f &direction); void spin(); void spinOnce(int time = 1, bool force_redraw = false); diff --git a/modules/viz/src/types.cpp b/modules/viz/src/types.cpp index 827b8b3bc9..e32cf54cb1 100644 --- a/modules/viz/src/types.cpp +++ b/modules/viz/src/types.cpp @@ -196,3 +196,26 @@ void cv::viz::Camera2::setWindowSize(const Size &window_size) else fov_[0] = (atan2(principal_point_[0],focal_[0]) + atan2(window_size.width-principal_point_[0],focal_[0])) * 180 / CV_PI; } + +void cv::viz::Camera2::computeProjectionMatrix(Matx44f &proj) const +{ + double top = clip_[0] * tan (0.5 * fov_[1]); + double left = -(top * window_size_.width) / window_size_.height; + double right = -left; + double bottom = -top; + + double temp1 = 2.0 * clip_[0]; + double temp2 = 1.0 / (right - left); + double temp3 = 1.0 / (top - bottom); + double temp4 = 1.0 / clip_[1] - clip_[0]; + + proj = Matx44d::zeros(); + + proj(0,0) = temp1 * temp2; + proj(1,1) = temp1 * temp3; + proj(0,2) = (right + left) * temp2; + proj(1,2) = (top + bottom) * temp3; + proj(2,2) = (-clip_[1] - clip_[0]) * temp4; + proj(3,2) = -1.0; + proj(2,3) = (-temp1 * clip_[1]) * temp4; +} \ No newline at end of file diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp index 8aa97419f7..2c67025809 100644 --- a/modules/viz/src/viz3d.cpp +++ b/modules/viz/src/viz3d.cpp @@ -49,3 +49,6 @@ cv::Affine3f cv::viz::Viz3d::getWidgetPose(const String &id) const { return impl void cv::viz::Viz3d::setCamera(const Camera2 &camera) { impl_->setCamera(camera); } void cv::viz::Viz3d::setViewerPose(const Affine3f &pose) { impl_->setViewerPose(pose); } cv::Affine3f cv::viz::Viz3d::getViewerPose() { return impl_->getViewerPose(); } + +void cv::viz::Viz3d::convertToWindowCoordinates(const Point3f &pt, Point3f &window_coord) { impl_->convertToWindowCoordinates(pt, window_coord); } +void cv::viz::Viz3d::converTo3DRay(const Point3f &window_coord, Point3f &origin, Vec3f &direction) { impl_->converTo3DRay(window_coord, origin, direction); } \ No newline at end of file diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index f764c77558..70d1e6fee3 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -604,13 +604,18 @@ void cv::viz::Viz3d::VizImpl::setCamera(const Camera2 &camera) } ///////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::Viz3d::VizImpl::getCamera(viz::Camera2 &camera) +cv::viz::Camera2 cv::viz::Viz3d::VizImpl::getCamera() const { vtkCamera& active_camera = *renderer_->GetActiveCamera(); - camera.setFov(Vec2f(0.0, active_camera.GetViewAngle() * CV_PI / 180.0f)); - camera.setClip(Vec2d(active_camera.GetClippingRange())); - camera.setWindowSize(Size(renderer_->GetRenderWindow()->GetSize()[0], - renderer_->GetRenderWindow()->GetSize()[1])); + + 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]); + + Camera2 camera(fov, window_size); + camera.setClip(clip); + return camera; } ///////////////////////////////////////////////////////////////////////////////////////////// @@ -664,6 +669,35 @@ cv::Affine3f cv::viz::Viz3d::VizImpl::getViewerPose () return cv::Affine3f(R, pos); } +///////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::Viz3d::VizImpl::convertToWindowCoordinates(const Point3f &pt, Point3f &window_coord) +{ + // Use the built in function of renderer + double point_wcs[3] = {pt.x, pt.y, pt.z}; + renderer_->WorldToView(point_wcs[0], point_wcs[1], point_wcs[2]); + window_coord.x = point_wcs[0]; + window_coord.y = point_wcs[1]; + window_coord.z = point_wcs[2]; +} + +///////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::Viz3d::VizImpl::converTo3DRay(const Point3f &window_coord, Point3f &origin, Vec3f &direction) +{ + // Use the built in function of renderer + double point_view[3] = {window_coord.x, window_coord.y, window_coord.z}; + renderer_->ViewToWorld(point_view[0], point_view[1], point_view[2]); + + vtkCamera &active_camera = *renderer_->GetActiveCamera(); + double *cam_pos = active_camera.GetPosition(); + origin.x = cam_pos[0]; + origin.y = cam_pos[1]; + origin.z = cam_pos[2]; + direction[0] = point_view[0] - cam_pos[0]; + direction[1] = point_view[1] - cam_pos[1]; + direction[2] = point_view[2] - cam_pos[2]; + normalize(direction); +} + ///////////////////////////////////////////////////////////////////////////////////////////// void cv::viz::Viz3d::VizImpl::resetCamera () { diff --git a/modules/viz/src/viz3d_impl.hpp b/modules/viz/src/viz3d_impl.hpp index 5bd4ebdea6..3b3018ff28 100644 --- a/modules/viz/src/viz3d_impl.hpp +++ b/modules/viz/src/viz3d_impl.hpp @@ -111,7 +111,7 @@ public: // and 'Camera' class itself with various constructors/fields void setCamera(const Camera2 &camera); - void getCamera(Camera2 &camera); + Camera2 getCamera() const; void initCameraParameters (); /** \brief Initialize camera parameters with some default values. */ bool cameraParamsSet () const; /** \brief Checks whether the camera parameters were manually loaded from file.*/ @@ -146,8 +146,8 @@ public: void setViewerPose(const Affine3f &pose); Affine3f getViewerPose(); - - + void convertToWindowCoordinates(const Point3f &pt, Point3f &window_coord); + void converTo3DRay(const Point3f &window_coord, Point3f &origin, Vec3f &direction); From f060eee5a5d5e190b7ee5527d8a5ab42efd5f17f Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Mon, 5 Aug 2013 15:10:17 +0200 Subject: [PATCH 08/19] fix window_size setter, remove camera related old methods from viz3d --- modules/viz/src/types.cpp | 6 +- modules/viz/src/viz3d_impl.cpp | 148 +++++---------------------------- modules/viz/src/viz3d_impl.hpp | 22 +---- 3 files changed, 25 insertions(+), 151 deletions(-) diff --git a/modules/viz/src/types.cpp b/modules/viz/src/types.cpp index e32cf54cb1..ebaf9d324e 100644 --- a/modules/viz/src/types.cpp +++ b/modules/viz/src/types.cpp @@ -165,10 +165,10 @@ cv::viz::Camera2::Camera2(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 - window_size_ = window_size; - fov_ = fov; principal_point_ = Vec2f(-1.0f, -1.0f); // Default symmetric lens focal_ = Vec2f(-1.0f, -1.0f); + setFov(fov); + setWindowSize(window_size); } cv::viz::Camera2::Camera2(const cv::Mat & K, const Size &window_size) @@ -195,6 +195,8 @@ void cv::viz::Camera2::setWindowSize(const Size &window_size) fov_[0] = 2 * atan2(tan(fov_[1] * 0.5), 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])) * 180 / CV_PI; + + window_size_ = window_size; } void cv::viz::Camera2::computeProjectionMatrix(Matx44f &proj) const diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index 70d1e6fee3..ee59b9413b 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -542,25 +542,12 @@ bool cv::viz::Viz3d::VizImpl::setShapeRenderingProperties (int property, double ///////////////////////////////////////////////////////////////////////////////////////////// void cv::viz::Viz3d::VizImpl::initCameraParameters () { - Camera camera_temp; - // Set default camera parameters to something meaningful - camera_temp.clip = Vec2d(0.01, 1000.01); - - // Look straight along the z-axis - camera_temp.focal = Vec3d(0.0, 0.0, 1.0); - - // Position the camera at the origin - camera_temp.pos = Vec3d(0.0, 0.0, 0.0); - - // Set the up-vector of the camera to be the y-axis - camera_temp.view_up = Vec3d(0.0, 1.0, 0.0); - - // Set the camera field of view to about - camera_temp.fovy = 0.8575; - camera_temp.window_size = Vec2i(window_->GetScreenSize()) / 2; - camera_temp.window_pos = Vec2i(0, 0); - - setCameraParameters (camera_temp); + Vec2i window_size(window_->GetScreenSize()); + window_size /= 2; + + Camera2 camera_temp(Vec2f(0.0,0.8575), Size(window_size[0], window_size[1])); + setCamera(camera_temp); + setViewerPose(makeCameraPose(Vec3f(0.0f,0.0f,0.0f), Vec3f(0.0f, 0.0f, 1.0f), Vec3f(0.0f, 1.0f, 0.0f))); } ///////////////////////////////////////////////////////////////////////////////////////////// @@ -577,19 +564,19 @@ void cv::viz::Viz3d::VizImpl::updateCamera () } ///////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::Viz3d::VizImpl::getCameras (cv::viz::Camera& camera) -{ - vtkCamera* active_camera = renderer_->GetActiveCamera (); - - camera.pos = cv::Vec3d(active_camera->GetPosition()); - camera.focal = cv::Vec3d(active_camera->GetFocalPoint()); - camera.clip = cv::Vec2d(active_camera->GetClippingRange()); - camera.view_up = cv::Vec3d(active_camera->GetViewUp()); - - camera.fovy = active_camera->GetViewAngle()/ 180.0 * CV_PI; - camera.window_size = cv::Vec2i(renderer_->GetRenderWindow()->GetSize()); - camera.window_pos = cv::Vec2d::all(0); -} +// void cv::viz::Viz3d::VizImpl::getCameras (cv::viz::Camera& camera) +// { +// vtkCamera* active_camera = renderer_->GetActiveCamera (); +// +// camera.pos = cv::Vec3d(active_camera->GetPosition()); +// camera.focal = cv::Vec3d(active_camera->GetFocalPoint()); +// camera.clip = cv::Vec2d(active_camera->GetClippingRange()); +// camera.view_up = cv::Vec3d(active_camera->GetViewUp()); +// +// camera.fovy = active_camera->GetViewAngle()/ 180.0 * CV_PI; +// camera.window_size = cv::Vec2i(renderer_->GetRenderWindow()->GetSize()); +// camera.window_pos = cv::Vec2d::all(0); +// } ///////////////////////////////////////////////////////////////////////////////////////////// void cv::viz::Viz3d::VizImpl::setCamera(const Camera2 &camera) @@ -704,105 +691,10 @@ void cv::viz::Viz3d::VizImpl::resetCamera () renderer_->ResetCamera (); } -///////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::Viz3d::VizImpl::setCameraPosition (const cv::Vec3d& pos, const cv::Vec3d& view, const cv::Vec3d& up) -{ - vtkSmartPointer cam = renderer_->GetActiveCamera (); - cam->SetPosition (pos[0], pos[1], pos[2]); - cam->SetFocalPoint (view[0], view[1], view[2]); - cam->SetViewUp (up[0], up[1], up[2]); - renderer_->Render (); -} - -///////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::Viz3d::VizImpl::setCameraPosition (double pos_x, double pos_y, double pos_z, double up_x, double up_y, double up_z) -{ - //rens_->InitTraversal (); - vtkSmartPointer cam = renderer_->GetActiveCamera (); - cam->SetPosition (pos_x, pos_y, pos_z); - cam->SetViewUp (up_x, up_y, up_z); - renderer_->Render (); -} - -///////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::Viz3d::VizImpl::setCameraParameters (const cv::Matx33f& intrinsics, const cv::Affine3f& extrinsics) -{ - // Position = extrinsic translation - cv::Vec3f pos_vec = extrinsics.translation(); - - - // Rotate the view vector - cv::Matx33f rotation = extrinsics.rotation(); - cv::Vec3f y_axis (0.f, 1.f, 0.f); - cv::Vec3f up_vec (rotation * y_axis); - - // Compute the new focal point - cv::Vec3f z_axis (0.f, 0.f, 1.f); - cv::Vec3f focal_vec = pos_vec + rotation * z_axis; - - // Get the width and height of the image - assume the calibrated centers are at the center of the image - Eigen::Vector2i window_size; - window_size[0] = static_cast (intrinsics(0, 2)); - window_size[1] = static_cast (intrinsics(1, 2)); - - // Compute the vertical field of view based on the focal length and image heigh - double fovy = 2 * atan (window_size[1] / (2. * intrinsics (1, 1))) * 180.0 / M_PI; - - //rens_->InitTraversal (); - - - vtkSmartPointer cam = renderer_->GetActiveCamera (); - cam->SetPosition (pos_vec[0], pos_vec[1], pos_vec[2]); - cam->SetFocalPoint (focal_vec[0], focal_vec[1], focal_vec[2]); - cam->SetViewUp (up_vec[0], up_vec[1], up_vec[2]); - cam->SetUseHorizontalViewAngle (0); - cam->SetViewAngle (fovy); - cam->SetClippingRange (0.01, 1000.01); - window_->SetSize (window_size[0], window_size[1]); - - renderer_->Render (); -} - -///////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::Viz3d::VizImpl::setCameraParameters (const cv::viz::Camera &camera) -{ - //rens_->InitTraversal (); - - - vtkSmartPointer cam = renderer_->GetActiveCamera (); - cam->SetPosition (camera.pos[0], camera.pos[1], camera.pos[2]); - cam->SetFocalPoint (camera.focal[0], camera.focal[1], camera.focal[2]); - cam->SetViewUp (camera.view_up[0], camera.view_up[1], camera.view_up[2]); - cam->SetClippingRange (camera.clip.val); - cam->SetUseHorizontalViewAngle (0); - cam->SetViewAngle (camera.fovy * 180.0 / M_PI); - - window_->SetSize (static_cast (camera.window_size[0]), static_cast (camera.window_size[1])); -} - -///////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::Viz3d::VizImpl::setCameraClipDistances (double near, double far) -{ - //rens_->InitTraversal (); - - vtkSmartPointer cam = renderer_->GetActiveCamera (); - cam->SetClippingRange (near, far); -} - -///////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::Viz3d::VizImpl::setCameraFieldOfView (double fovy) -{ - //rens_->InitTraversal (); - - vtkSmartPointer cam = renderer_->GetActiveCamera (); - cam->SetUseHorizontalViewAngle (0); - cam->SetViewAngle (fovy * 180.0 / M_PI); - -} - ///////////////////////////////////////////////////////////////////////////////////////////// void cv::viz::Viz3d::VizImpl::resetCameraViewpoint (const std::string &id) { + // TODO Cloud actor is not used vtkSmartPointer camera_pose; static CloudActorMap::iterator it = cloud_actor_map_->find (id); if (it != cloud_actor_map_->end ()) diff --git a/modules/viz/src/viz3d_impl.hpp b/modules/viz/src/viz3d_impl.hpp index 3b3018ff28..86789c8066 100644 --- a/modules/viz/src/viz3d_impl.hpp +++ b/modules/viz/src/viz3d_impl.hpp @@ -121,27 +121,7 @@ public: /** \brief Reset the camera direction from {0, 0, 0} to the center_{x, y, z} of a given dataset. * \param[in] id the point cloud object id (default: cloud) */ void resetCameraViewpoint (const String& id = "cloud"); - /** \brief Set the camera pose given by position, viewpoint and up vector - * \param[in] pos camera location - * \param[in] view the view point of the camera - * \param[in] up the view up direction of the camera */ - void setCameraPosition (const cv::Vec3d& pos, const cv::Vec3d& view, const cv::Vec3d& up); - - /** \brief Set the camera location and viewup according to the given arguments - * \param[in] pos_x,y,z the x,y,z coordinate of the camera location - * \param[in] up_x,y,z the x,y,z component of the view up direction of the camera */ - void setCameraPosition (double pos_x, double pos_y, double pos_z, double up_x, double up_y, double up_z); - - /** \brief Set the camera parameters via an intrinsics and and extrinsics matrix - * \note This assumes that the pixels are square and that the center of the image is at the center of the sensor. - * \param[in] intrinsics the intrinsics that will be used to compute the VTK camera parameters - * \param[in] extrinsics the extrinsics that will be used to compute the VTK camera parameters */ - void setCameraParameters (const cv::Matx33f& intrinsics, const Affine3f& extrinsics); - void setCameraParameters (const Camera &camera); - void setCameraClipDistances (double near, double far); - void setCameraFieldOfView (double fovy); - void getCameras (Camera& camera); - + //to implement Viz3d set/getViewerPose() void setViewerPose(const Affine3f &pose); Affine3f getViewerPose(); From 119d97f1f638f6f757dd66f23ceead10888730de Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Mon, 5 Aug 2013 15:37:08 +0200 Subject: [PATCH 09/19] remove old camera, rename new camera --- modules/viz/include/opencv2/viz/types.hpp | 8 +-- modules/viz/include/opencv2/viz/viz3d.hpp | 3 +- modules/viz/src/common.cpp | 45 -------------- modules/viz/src/common.h | 73 ----------------------- modules/viz/src/types.cpp | 12 ++-- modules/viz/src/viz3d.cpp | 3 +- modules/viz/src/viz3d_impl.cpp | 23 ++----- modules/viz/src/viz3d_impl.hpp | 4 +- 8 files changed, 20 insertions(+), 151 deletions(-) diff --git a/modules/viz/include/opencv2/viz/types.hpp b/modules/viz/include/opencv2/viz/types.hpp index 8dd68196b4..2ebca5d326 100644 --- a/modules/viz/include/opencv2/viz/types.hpp +++ b/modules/viz/include/opencv2/viz/types.hpp @@ -94,12 +94,12 @@ namespace cv unsigned int key_state; }; - class CV_EXPORTS Camera2 + class CV_EXPORTS Camera { public: - Camera2(float f_x, float f_y, float c_x, float c_y, const Size &window_size); - Camera2(const Vec2f &fov, const Size &window_size); - Camera2(const cv::Mat &K, const Size &window_size); + Camera(float f_x, float f_y, float c_x, float c_y, const Size &window_size); + Camera(const Vec2f &fov, const Size &window_size); + Camera(const cv::Mat &K, const Size &window_size); inline const Vec2d & getClip() const { return clip_; } inline void setClip(const Vec2d &clip) { clip_ = clip; } diff --git a/modules/viz/include/opencv2/viz/viz3d.hpp b/modules/viz/include/opencv2/viz/viz3d.hpp index eff8ac000b..921eb3223b 100644 --- a/modules/viz/include/opencv2/viz/viz3d.hpp +++ b/modules/viz/include/opencv2/viz/viz3d.hpp @@ -39,7 +39,8 @@ namespace cv void updateWidgetPose(const String &id, const Affine3f &pose); Affine3f getWidgetPose(const String &id) const; - void setCamera(const Camera2 &camera); + void setCamera(const Camera &camera); + Camera getCamera() const; Affine3f getViewerPose(); void setViewerPose(const Affine3f &pose); diff --git a/modules/viz/src/common.cpp b/modules/viz/src/common.cpp index 08da19b5d7..3c40a00f50 100644 --- a/modules/viz/src/common.cpp +++ b/modules/viz/src/common.cpp @@ -263,48 +263,3 @@ int hull_vertex_table[43][7] = { // return (fabsf (float (sum * 0.5f))); //} - -///////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::Camera::computeViewMatrix (Affine3d& view_mat) const -{ - //constructs view matrix from camera pos, view up, and the point it is looking at - //this code is based off of gluLookAt http://www.opengl.org/wiki/GluLookAt_code - - Vec3d zAxis = normalized(focal - pos); - Vec3d xAxis = normalized(zAxis.cross(view_up)); - Vec3d yAxis = xAxis.cross (zAxis); - - Matx33d R; - - R(0, 0) = xAxis[0]; R(0, 1) = xAxis[1]; R(0, 2) = xAxis[2]; - R(1, 0) = yAxis[0]; R(1, 1) = yAxis[1]; R(1, 2) = yAxis[2]; - R(1, 0) = -zAxis[0]; R(2, 1) = -zAxis[1]; R(2, 2) = -zAxis[2]; - - Vec3d t = R * (-pos); - - view_mat = Affine3d(R, t); -} - -/////////////////////////////////////////////////////////////////////// -void cv::viz::Camera::computeProjectionMatrix (Matx44d& proj) const -{ - double top = clip[0] * tan (0.5 * fovy); - double left = -(top * window_size[0]) / window_size[1]; - double right = -left; - double bottom = -top; - - double temp1 = 2.0 * clip[0]; - double temp2 = 1.0 / (right - left); - double temp3 = 1.0 / (top - bottom); - double temp4 = 1.0 / clip[1] - clip[0]; - - proj = Matx44d::zeros(); - - proj(0,0) = temp1 * temp2; - proj(1,1) = temp1 * temp3; - proj(0,2) = (right + left) * temp2; - proj(1,2) = (top + bottom) * temp3; - proj(2,2) = (-clip[1] - clip[0]) * temp4; - proj(3,2) = -1.0; - proj(2,3) = (-temp1 * clip[1]) * temp4; -} diff --git a/modules/viz/src/common.h b/modules/viz/src/common.h index c19dd8979b..ea89334178 100644 --- a/modules/viz/src/common.h +++ b/modules/viz/src/common.h @@ -48,79 +48,6 @@ namespace cv SHADING_PHONG }; - class CV_EXPORTS Camera - { - public: - /** Focal point or lookAt. The view direction can be obtained by (focal-pos).normalized () */ - Vec3d focal; - - /** \brief Position of the camera. */ - Vec3d pos; - - /** \brief Up vector of the camera. */ - Vec3d view_up; - - /** \brief Near/far clipping planes depths */ - Vec2d clip; - - /** \brief Field of view angle in y direction (radians). */ - double fovy; - - // the following variables are the actual position and size of the window on the screen and NOT the viewport! - // except for the size, which is the same the viewport is assumed to be centered and same size as the window. - Vec2i window_size; - Vec2i window_pos; - - /** \brief Computes View matrix for Camera (Based on gluLookAt) - * \param[out] view_mat the resultant matrix - */ - void computeViewMatrix(Affine3d& view_mat) const; - - /** \brief Computes Projection Matrix for Camera - * \param[out] proj the resultant matrix - */ - void computeProjectionMatrix(Matx44d& proj) const; - - /** \brief converts point to window coordiantes - * \param[in] pt xyz point to be converted - * \param[out] window_cord vector containing the pts' window X,Y, Z and 1 - * - * This function computes the projection and view matrix every time. - * It is very inefficient to use this for every point in the point cloud! - */ - void cvtWindowCoordinates (const cv::Point3f& pt, Vec4d& window_cord) const - { - Affine3d view; - computeViewMatrix (view); - - Matx44d proj; - computeProjectionMatrix (proj); - cvtWindowCoordinates (pt, proj * view.matrix, window_cord); - return; - } - - /** \brief converts point to window coordiantes - * \param[in] pt xyz point to be converted - * \param[out] window_cord vector containing the pts' window X,Y, Z and 1 - * \param[in] composite_mat composite transformation matrix (proj*view) - * - * Use this function to compute window coordinates with a precomputed - * transformation function. The typical composite matrix will be - * the projection matrix * the view matrix. However, additional - * matrices like a camera disortion matrix can also be added. - */ - void cvtWindowCoordinates (const Point3f& pt, const Matx44d& composite_mat, Vec4d& window_cord) const - { - Vec4d pte (pt.x, pt.y, pt.z, 1); - window_cord = composite_mat * pte; - window_cord = window_cord/window_cord[3]; - - window_cord[0] = (window_cord[0]+1.0) / 2.0*window_size[0]; - window_cord[1] = (window_cord[1]+1.0) / 2.0*window_size[1]; - window_cord[2] = (window_cord[2]+1.0) / 2.0; - } - }; - } } diff --git a/modules/viz/src/types.cpp b/modules/viz/src/types.cpp index ebaf9d324e..a7ec893cf9 100644 --- a/modules/viz/src/types.cpp +++ b/modules/viz/src/types.cpp @@ -146,7 +146,7 @@ cv::viz::Mesh3d cv::viz::Mesh3d::loadMesh(const String& file) //////////////////////////////////////////////////////////////////// /// Camera implementation -cv::viz::Camera2::Camera2(float f_x, float f_y, float c_x, float c_y, const Size &window_size) +cv::viz::Camera::Camera(float f_x, float f_y, float c_x, float c_y, const Size &window_size) { CV_Assert(window_size.width > 0 && window_size.height > 0); setClip(Vec2d(0.01, 1000.01));// Default clipping @@ -161,7 +161,7 @@ cv::viz::Camera2::Camera2(float f_x, float f_y, float c_x, float c_y, const Size focal_[1] = f_y; } -cv::viz::Camera2::Camera2(const Vec2f &fov, const Size &window_size) +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 @@ -171,7 +171,7 @@ cv::viz::Camera2::Camera2(const Vec2f &fov, const Size &window_size) setWindowSize(window_size); } -cv::viz::Camera2::Camera2(const cv::Mat & K, const Size &window_size) +cv::viz::Camera::Camera(const cv::Mat & K, const Size &window_size) { CV_Assert(K.rows == 3 && K.cols == 3); CV_Assert(window_size.width > 0 && window_size.height > 0); @@ -180,10 +180,10 @@ cv::viz::Camera2::Camera2(const cv::Mat & K, const Size &window_size) float f_y = K.at(1,1); float c_x = K.at(0,2); float c_y = K.at(1,2); - Camera2(f_x, f_y, c_x, c_y, window_size); + Camera(f_x, f_y, c_x, c_y, window_size); } -void cv::viz::Camera2::setWindowSize(const Size &window_size) +void cv::viz::Camera::setWindowSize(const Size &window_size) { CV_Assert(window_size.width > 0 && window_size.height > 0); @@ -199,7 +199,7 @@ void cv::viz::Camera2::setWindowSize(const Size &window_size) window_size_ = window_size; } -void cv::viz::Camera2::computeProjectionMatrix(Matx44f &proj) const +void cv::viz::Camera::computeProjectionMatrix(Matx44f &proj) const { double top = clip_[0] * tan (0.5 * fov_[1]); double left = -(top * window_size_.width) / window_size_.height; diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp index 2c67025809..9a65740859 100644 --- a/modules/viz/src/viz3d.cpp +++ b/modules/viz/src/viz3d.cpp @@ -46,7 +46,8 @@ void cv::viz::Viz3d::setWidgetPose(const String &id, const Affine3f &pose) { imp void cv::viz::Viz3d::updateWidgetPose(const String &id, const Affine3f &pose) { impl_->updateWidgetPose(id, pose); } cv::Affine3f cv::viz::Viz3d::getWidgetPose(const String &id) const { return impl_->getWidgetPose(id); } -void cv::viz::Viz3d::setCamera(const Camera2 &camera) { impl_->setCamera(camera); } +void cv::viz::Viz3d::setCamera(const Camera &camera) { impl_->setCamera(camera); } +cv::viz::Camera cv::viz::Viz3d::getCamera() const { return impl_->getCamera(); } void cv::viz::Viz3d::setViewerPose(const Affine3f &pose) { impl_->setViewerPose(pose); } cv::Affine3f cv::viz::Viz3d::getViewerPose() { return impl_->getViewerPose(); } diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index ee59b9413b..6bddd02603 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -545,7 +545,7 @@ void cv::viz::Viz3d::VizImpl::initCameraParameters () Vec2i window_size(window_->GetScreenSize()); window_size /= 2; - Camera2 camera_temp(Vec2f(0.0,0.8575), Size(window_size[0], window_size[1])); + Camera camera_temp(Vec2f(0.0,0.8575), Size(window_size[0], window_size[1])); setCamera(camera_temp); setViewerPose(makeCameraPose(Vec3f(0.0f,0.0f,0.0f), Vec3f(0.0f, 0.0f, 1.0f), Vec3f(0.0f, 1.0f, 0.0f))); } @@ -564,22 +564,7 @@ void cv::viz::Viz3d::VizImpl::updateCamera () } ///////////////////////////////////////////////////////////////////////////////////////////// -// void cv::viz::Viz3d::VizImpl::getCameras (cv::viz::Camera& camera) -// { -// vtkCamera* active_camera = renderer_->GetActiveCamera (); -// -// camera.pos = cv::Vec3d(active_camera->GetPosition()); -// camera.focal = cv::Vec3d(active_camera->GetFocalPoint()); -// camera.clip = cv::Vec2d(active_camera->GetClippingRange()); -// camera.view_up = cv::Vec3d(active_camera->GetViewUp()); -// -// camera.fovy = active_camera->GetViewAngle()/ 180.0 * CV_PI; -// camera.window_size = cv::Vec2i(renderer_->GetRenderWindow()->GetSize()); -// camera.window_pos = cv::Vec2d::all(0); -// } - -///////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::Viz3d::VizImpl::setCamera(const Camera2 &camera) +void cv::viz::Viz3d::VizImpl::setCamera(const Camera &camera) { vtkCamera& active_camera = *renderer_->GetActiveCamera(); @@ -591,7 +576,7 @@ void cv::viz::Viz3d::VizImpl::setCamera(const Camera2 &camera) } ///////////////////////////////////////////////////////////////////////////////////////////// -cv::viz::Camera2 cv::viz::Viz3d::VizImpl::getCamera() const +cv::viz::Camera cv::viz::Viz3d::VizImpl::getCamera() const { vtkCamera& active_camera = *renderer_->GetActiveCamera(); @@ -600,7 +585,7 @@ cv::viz::Camera2 cv::viz::Viz3d::VizImpl::getCamera() const Size window_size(renderer_->GetRenderWindow()->GetSize()[0], renderer_->GetRenderWindow()->GetSize()[1]); - Camera2 camera(fov, window_size); + Camera camera(fov, window_size); camera.setClip(clip); return camera; } diff --git a/modules/viz/src/viz3d_impl.hpp b/modules/viz/src/viz3d_impl.hpp index 86789c8066..b0e87f0186 100644 --- a/modules/viz/src/viz3d_impl.hpp +++ b/modules/viz/src/viz3d_impl.hpp @@ -110,8 +110,8 @@ public: // All camera methods to refactor into set/getViewwerPose, setCamera() // and 'Camera' class itself with various constructors/fields - void setCamera(const Camera2 &camera); - Camera2 getCamera() const; + void setCamera(const Camera &camera); + Camera getCamera() const; void initCameraParameters (); /** \brief Initialize camera parameters with some default values. */ bool cameraParamsSet () const; /** \brief Checks whether the camera parameters were manually loaded from file.*/ From f8ad3c02049e9f316928c67ad7eb8556f070209c Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Mon, 5 Aug 2013 16:06:02 +0200 Subject: [PATCH 10/19] fix field of view computation in setWindowSize --- modules/viz/src/types.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/viz/src/types.cpp b/modules/viz/src/types.cpp index a7ec893cf9..9de385ce0f 100644 --- a/modules/viz/src/types.cpp +++ b/modules/viz/src/types.cpp @@ -189,10 +189,10 @@ void cv::viz::Camera::setWindowSize(const Size &window_size) // Vertical field of view is fixed! // Horizontal field of view is expandable based on the aspect ratio - float aspect_ratio_new = window_size.width / window_size.height; + float aspect_ratio_new = static_cast(window_size.width) / static_cast(window_size.height); if (principal_point_[0] < 0.0f) - fov_[0] = 2 * atan2(tan(fov_[1] * 0.5), aspect_ratio_new); // This assumes that the lens is symmetric! + fov_[0] = 2.f * atan(tan(fov_[1] * 0.5) * 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])) * 180 / CV_PI; From 9c20e77013312ce43fb959c1054b9f27cb866d3c Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Mon, 5 Aug 2013 18:39:36 +0200 Subject: [PATCH 11/19] fix conversion functions to use appropriate vtk function --- modules/viz/include/opencv2/viz/viz3d.hpp | 4 +-- modules/viz/src/viz3d.cpp | 4 +-- modules/viz/src/viz3d_impl.cpp | 34 +++++++++-------------- modules/viz/src/viz3d_impl.hpp | 4 +-- 4 files changed, 19 insertions(+), 27 deletions(-) diff --git a/modules/viz/include/opencv2/viz/viz3d.hpp b/modules/viz/include/opencv2/viz/viz3d.hpp index 921eb3223b..72e3076df4 100644 --- a/modules/viz/include/opencv2/viz/viz3d.hpp +++ b/modules/viz/include/opencv2/viz/viz3d.hpp @@ -44,8 +44,8 @@ namespace cv Affine3f getViewerPose(); void setViewerPose(const Affine3f &pose); - void convertToWindowCoordinates(const Point3f &pt, Point3f &window_coord); - void converTo3DRay(const Point3f &window_coord, Point3f &origin, Vec3f &direction); + void convertToWindowCoordinates(const Point3d &pt, Point3d &window_coord); + void converTo3DRay(const Point3d &window_coord, Point3d &origin, Vec3d &direction); void spin(); void spinOnce(int time = 1, bool force_redraw = false); diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp index 9a65740859..6908bc8a46 100644 --- a/modules/viz/src/viz3d.cpp +++ b/modules/viz/src/viz3d.cpp @@ -51,5 +51,5 @@ cv::viz::Camera cv::viz::Viz3d::getCamera() const { return impl_->getCamera(); } void cv::viz::Viz3d::setViewerPose(const Affine3f &pose) { impl_->setViewerPose(pose); } cv::Affine3f cv::viz::Viz3d::getViewerPose() { return impl_->getViewerPose(); } -void cv::viz::Viz3d::convertToWindowCoordinates(const Point3f &pt, Point3f &window_coord) { impl_->convertToWindowCoordinates(pt, window_coord); } -void cv::viz::Viz3d::converTo3DRay(const Point3f &window_coord, Point3f &origin, Vec3f &direction) { impl_->converTo3DRay(window_coord, origin, direction); } \ No newline at end of file +void cv::viz::Viz3d::convertToWindowCoordinates(const Point3d &pt, Point3d &window_coord) { impl_->convertToWindowCoordinates(pt, window_coord); } +void cv::viz::Viz3d::converTo3DRay(const Point3d &window_coord, Point3d &origin, Vec3d &direction) { impl_->converTo3DRay(window_coord, origin, direction); } \ No newline at end of file diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index 6bddd02603..8dbf1fb10e 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -642,32 +642,24 @@ cv::Affine3f cv::viz::Viz3d::VizImpl::getViewerPose () } ///////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::Viz3d::VizImpl::convertToWindowCoordinates(const Point3f &pt, Point3f &window_coord) +void cv::viz::Viz3d::VizImpl::convertToWindowCoordinates(const Point3d &pt, Point3d &window_coord) { - // Use the built in function of renderer - double point_wcs[3] = {pt.x, pt.y, pt.z}; - renderer_->WorldToView(point_wcs[0], point_wcs[1], point_wcs[2]); - window_coord.x = point_wcs[0]; - window_coord.y = point_wcs[1]; - window_coord.z = point_wcs[2]; + Vec3d window_pt; + vtkInteractorObserver::ComputeWorldToDisplay(renderer_, pt.x, pt.y, pt.z, window_pt.val); + window_coord = window_pt; } ///////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::Viz3d::VizImpl::converTo3DRay(const Point3f &window_coord, Point3f &origin, Vec3f &direction) -{ - // Use the built in function of renderer - double point_view[3] = {window_coord.x, window_coord.y, window_coord.z}; - renderer_->ViewToWorld(point_view[0], point_view[1], point_view[2]); - +void cv::viz::Viz3d::VizImpl::converTo3DRay(const Point3d &window_coord, Point3d &origin, Vec3d &direction) +{ + Vec4d world_pt; + vtkInteractorObserver::ComputeDisplayToWorld(renderer_, window_coord.x, window_coord.y, window_coord.z, world_pt.val); + vtkCamera &active_camera = *renderer_->GetActiveCamera(); - double *cam_pos = active_camera.GetPosition(); - origin.x = cam_pos[0]; - origin.y = cam_pos[1]; - origin.z = cam_pos[2]; - direction[0] = point_view[0] - cam_pos[0]; - direction[1] = point_view[1] - cam_pos[1]; - direction[2] = point_view[2] - cam_pos[2]; - normalize(direction); + Vec3d cam_pos; + active_camera.GetPosition(cam_pos.val); + origin = cam_pos; + direction = normalize(Vec3d(world_pt.val) - cam_pos); } ///////////////////////////////////////////////////////////////////////////////////////////// diff --git a/modules/viz/src/viz3d_impl.hpp b/modules/viz/src/viz3d_impl.hpp index b0e87f0186..d38204a25e 100644 --- a/modules/viz/src/viz3d_impl.hpp +++ b/modules/viz/src/viz3d_impl.hpp @@ -126,8 +126,8 @@ public: void setViewerPose(const Affine3f &pose); Affine3f getViewerPose(); - void convertToWindowCoordinates(const Point3f &pt, Point3f &window_coord); - void converTo3DRay(const Point3f &window_coord, Point3f &origin, Vec3f &direction); + void convertToWindowCoordinates(const Point3d &pt, Point3d &window_coord); + void converTo3DRay(const Point3d &window_coord, Point3d &origin, Vec3d &direction); From 32985aa7248bf99c19dcae53da7057d823c6e2aa Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Mon, 5 Aug 2013 19:22:43 +0200 Subject: [PATCH 12/19] fix camera constructor, add tentative KinectCamera method --- modules/viz/include/opencv2/viz/types.hpp | 6 ++- modules/viz/src/types.cpp | 52 +++++++++++++++-------- 2 files changed, 39 insertions(+), 19 deletions(-) diff --git a/modules/viz/include/opencv2/viz/types.hpp b/modules/viz/include/opencv2/viz/types.hpp index 2ebca5d326..d12a4df13f 100644 --- a/modules/viz/include/opencv2/viz/types.hpp +++ b/modules/viz/include/opencv2/viz/types.hpp @@ -99,7 +99,7 @@ namespace cv public: Camera(float f_x, float f_y, float c_x, float c_y, const Size &window_size); Camera(const Vec2f &fov, const Size &window_size); - Camera(const cv::Mat &K, const Size &window_size); + Camera(const cv::Matx33f &K, const Size &window_size); inline const Vec2d & getClip() const { return clip_; } inline void setClip(const Vec2d &clip) { clip_ = clip; } @@ -112,7 +112,11 @@ namespace cv void computeProjectionMatrix(Matx44f &proj) const; + static Camera KinectCamera(const Size &window_size); + private: + void init(float f_x, float f_y, float c_x, float c_y, const Size &window_size); + Vec2d clip_; Vec2f fov_; Size window_size_; diff --git a/modules/viz/src/types.cpp b/modules/viz/src/types.cpp index 9de385ce0f..08fa62882e 100644 --- a/modules/viz/src/types.cpp +++ b/modules/viz/src/types.cpp @@ -148,17 +148,7 @@ cv::viz::Mesh3d cv::viz::Mesh3d::loadMesh(const String& file) cv::viz::Camera::Camera(float f_x, float f_y, float c_x, float c_y, const Size &window_size) { - CV_Assert(window_size.width > 0 && window_size.height > 0); - setClip(Vec2d(0.01, 1000.01));// Default clipping - - fov_[0] = (atan2(c_x,f_x) + atan2(window_size.width-c_x,f_x)) * 180 / CV_PI; - fov_[1] = (atan2(c_y,f_y) + atan2(window_size.height-c_y,f_y)) * 180 / CV_PI; - - principal_point_[0] = c_x; - principal_point_[1] = c_y; - - focal_[0] = f_x; - focal_[1] = f_y; + init(f_x, f_y, c_x, c_y, window_size); } cv::viz::Camera::Camera(const Vec2f &fov, const Size &window_size) @@ -171,16 +161,30 @@ cv::viz::Camera::Camera(const Vec2f &fov, const Size &window_size) setWindowSize(window_size); } -cv::viz::Camera::Camera(const cv::Mat & K, const Size &window_size) +cv::viz::Camera::Camera(const cv::Matx33f & K, const Size &window_size) +{ + float f_x = K(0,0); + float f_y = K(1,1); + float c_x = K(0,2); + float c_y = K(1,2); + init(f_x, f_y, c_x, c_y, window_size); +} + +void cv::viz::Camera::init(float f_x, float f_y, float c_x, float c_y, const Size &window_size) { - CV_Assert(K.rows == 3 && K.cols == 3); CV_Assert(window_size.width > 0 && window_size.height > 0); + setClip(Vec2d(0.01, 1000.01));// Default clipping - float f_x = K.at(0,0); - float f_y = K.at(1,1); - float c_x = K.at(0,2); - float c_y = K.at(1,2); - Camera(f_x, f_y, c_x, c_y, window_size); + fov_[0] = (atan2(c_x,f_x) + atan2(window_size.width-c_x,f_x)) * 180 / CV_PI; + fov_[1] = (atan2(c_y,f_y) + atan2(window_size.height-c_y,f_y)) * 180 / CV_PI; + + principal_point_[0] = c_x; + principal_point_[1] = c_y; + + focal_[0] = f_x; + focal_[1] = f_y; + + setWindowSize(window_size); } void cv::viz::Camera::setWindowSize(const Size &window_size) @@ -220,4 +224,16 @@ void cv::viz::Camera::computeProjectionMatrix(Matx44f &proj) const proj(2,2) = (-clip_[1] - clip_[0]) * temp4; proj(3,2) = -1.0; proj(2,3) = (-temp1 * clip_[1]) * temp4; +} + +cv::viz::Camera cv::viz::Camera::KinectCamera(const Size &window_size) +{ + // Without distortion + Matx33f K = Matx33f::zeros(); + K(0,0) = 5.2921508098293293e+02; + K(0,2) = 3.2894272028759258e+02; + K(1,1) = 5.2556393630057437e+02; + K(1,2) = 2.6748068171871557e+02; + K(2,2) = 1.0f; + return Camera(K, window_size); } \ No newline at end of file From 731a931c0ce71a868bbe2c6ec1979cb6af12610e Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Mon, 5 Aug 2013 19:35:20 +0200 Subject: [PATCH 13/19] field of views are in radians --- modules/viz/src/types.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/modules/viz/src/types.cpp b/modules/viz/src/types.cpp index 08fa62882e..3395b0e66e 100644 --- a/modules/viz/src/types.cpp +++ b/modules/viz/src/types.cpp @@ -175,8 +175,8 @@ void cv::viz::Camera::init(float f_x, float f_y, float c_x, float c_y, const Siz CV_Assert(window_size.width > 0 && window_size.height > 0); setClip(Vec2d(0.01, 1000.01));// Default clipping - fov_[0] = (atan2(c_x,f_x) + atan2(window_size.width-c_x,f_x)) * 180 / CV_PI; - fov_[1] = (atan2(c_y,f_y) + atan2(window_size.height-c_y,f_y)) * 180 / CV_PI; + fov_[0] = (atan2(c_x,f_x) + atan2(window_size.width-c_x,f_x)); + fov_[1] = (atan2(c_y,f_y) + atan2(window_size.height-c_y,f_y)); principal_point_[0] = c_x; principal_point_[1] = c_y; @@ -198,7 +198,7 @@ void cv::viz::Camera::setWindowSize(const Size &window_size) if (principal_point_[0] < 0.0f) fov_[0] = 2.f * atan(tan(fov_[1] * 0.5) * 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])) * 180 / CV_PI; + fov_[0] = (atan2(principal_point_[0],focal_[0]) + atan2(window_size.width-principal_point_[0],focal_[0])); // TODO I need to check this window_size_ = window_size; } @@ -228,7 +228,8 @@ void cv::viz::Camera::computeProjectionMatrix(Matx44f &proj) const cv::viz::Camera cv::viz::Camera::KinectCamera(const Size &window_size) { - // Without distortion + // Without distortion, RGB Camera + // Received from http://nicolas.burrus.name/index.php/Research/KinectCalibration Matx33f K = Matx33f::zeros(); K(0,0) = 5.2921508098293293e+02; K(0,2) = 3.2894272028759258e+02; From 5335489daab048e0869ac81680941137c7d56618 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Wed, 7 Aug 2013 09:28:39 +0200 Subject: [PATCH 14/19] viz getWindowSize, setWindowSize --- modules/viz/include/opencv2/viz/viz3d.hpp | 4 ++++ modules/viz/src/types.cpp | 2 +- modules/viz/src/viz3d.cpp | 5 ++++- modules/viz/src/viz3d_impl.cpp | 1 + modules/viz/src/viz3d_impl.hpp | 2 +- 5 files changed, 11 insertions(+), 3 deletions(-) diff --git a/modules/viz/include/opencv2/viz/viz3d.hpp b/modules/viz/include/opencv2/viz/viz3d.hpp index 72e3076df4..33b2743254 100644 --- a/modules/viz/include/opencv2/viz/viz3d.hpp +++ b/modules/viz/include/opencv2/viz/viz3d.hpp @@ -7,6 +7,7 @@ #include #include #include +#include namespace cv { @@ -46,6 +47,9 @@ namespace cv void convertToWindowCoordinates(const Point3d &pt, Point3d &window_coord); void converTo3DRay(const Point3d &window_coord, Point3d &origin, Vec3d &direction); + + Size getWindowSize() const; + void setWindowSize(const Size &window_size); void spin(); void spinOnce(int time = 1, bool force_redraw = false); diff --git a/modules/viz/src/types.cpp b/modules/viz/src/types.cpp index 3395b0e66e..7ab918fdde 100644 --- a/modules/viz/src/types.cpp +++ b/modules/viz/src/types.cpp @@ -196,7 +196,7 @@ void cv::viz::Camera::setWindowSize(const Size &window_size) float aspect_ratio_new = static_cast(window_size.width) / static_cast(window_size.height); if (principal_point_[0] < 0.0f) - fov_[0] = 2.f * atan(tan(fov_[1] * 0.5) * aspect_ratio_new); // This assumes that the lens is symmetric! + 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])); // TODO I need to check this diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp index 6908bc8a46..ced6e73e18 100644 --- a/modules/viz/src/viz3d.cpp +++ b/modules/viz/src/viz3d.cpp @@ -52,4 +52,7 @@ void cv::viz::Viz3d::setViewerPose(const Affine3f &pose) { impl_->setViewerPose( cv::Affine3f cv::viz::Viz3d::getViewerPose() { return impl_->getViewerPose(); } void cv::viz::Viz3d::convertToWindowCoordinates(const Point3d &pt, Point3d &window_coord) { impl_->convertToWindowCoordinates(pt, window_coord); } -void cv::viz::Viz3d::converTo3DRay(const Point3d &window_coord, Point3d &origin, Vec3d &direction) { impl_->converTo3DRay(window_coord, origin, direction); } \ No newline at end of file +void cv::viz::Viz3d::converTo3DRay(const Point3d &window_coord, Point3d &origin, Vec3d &direction) { impl_->converTo3DRay(window_coord, origin, direction); } + +cv::Size cv::viz::Viz3d::getWindowSize() const { return impl_->getWindowSize(); } +void cv::viz::Viz3d::setWindowSize(const Size &window_size) { impl_->setWindowSize(window_size.width, window_size.height); } \ No newline at end of file diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index 8dbf1fb10e..fc2b3a55d7 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -963,6 +963,7 @@ void cv::viz::Viz3d::VizImpl::setWindowName (const std::string &name) void cv::viz::Viz3d::VizImpl::setWindowPosition (int x, int y) { window_->SetPosition (x, y); } void cv::viz::Viz3d::VizImpl::setWindowSize (int xw, int yw) { window_->SetSize (xw, yw); } +cv::Size cv::viz::Viz3d::VizImpl::getWindowSize() const { return Size(window_->GetSize()[0], window_->GetSize()[1]); } bool cv::viz::Viz3d::VizImpl::addPolygonMesh (const Mesh3d& /*mesh*/, const Mat& /*mask*/, const std::string &/*id*/) { diff --git a/modules/viz/src/viz3d_impl.hpp b/modules/viz/src/viz3d_impl.hpp index d38204a25e..e190b720bb 100644 --- a/modules/viz/src/viz3d_impl.hpp +++ b/modules/viz/src/viz3d_impl.hpp @@ -135,10 +135,10 @@ public: - //to implemnt in Viz3d void saveScreenshot (const String &file); void setWindowPosition (int x, int y); + Size getWindowSize() const; void setWindowSize (int xw, int yw); void setFullScreen (bool mode); void setWindowName (const String &name); From 422b967e9ae802cc0b4aefcabe78a9568a71754b Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Wed, 7 Aug 2013 15:52:24 +0200 Subject: [PATCH 15/19] fix computeProjectionMatrix in Camera class, also check if there is principal point defined --- modules/viz/src/types.cpp | 30 ++++++++++++++++++++++++------ modules/viz/src/viz3d_impl.cpp | 2 +- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/modules/viz/src/types.cpp b/modules/viz/src/types.cpp index 7ab918fdde..631582a646 100644 --- a/modules/viz/src/types.cpp +++ b/modules/viz/src/types.cpp @@ -195,35 +195,53 @@ void cv::viz::Camera::setWindowSize(const Size &window_size) // Horizontal field of view is expandable based on the aspect ratio float aspect_ratio_new = static_cast(window_size.width) / static_cast(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(window_size.height) / static_cast(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])); // TODO I need to check this + 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 + 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 temp2 = 1.0 / (right - left); double temp3 = 1.0 / (top - bottom); - double temp4 = 1.0 / clip_[1] - clip_[0]; + double temp4 = 1.0 / (clip_[0] - clip_[1]); proj = Matx44d::zeros(); - proj(0,0) = temp1 * temp2; proj(1,1) = temp1 * temp3; proj(0,2) = (right + left) * temp2; proj(1,2) = (top + bottom) * temp3; - proj(2,2) = (-clip_[1] - clip_[0]) * temp4; + proj(2,2) = (clip_[1]+clip_[0]) * temp4; proj(3,2) = -1.0; - proj(2,3) = (-temp1 * clip_[1]) * temp4; + proj(2,3) = (temp1 * clip_[1]) * temp4; } cv::viz::Camera cv::viz::Camera::KinectCamera(const Size &window_size) diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index fc2b3a55d7..a24700ce91 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -572,7 +572,7 @@ void cv::viz::Viz3d::VizImpl::setCamera(const Camera &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 (static_cast (camera.getWindowSize().width), static_cast (camera.getWindowSize().height)); + window_->SetSize (camera.getWindowSize().width, camera.getWindowSize().height); } ///////////////////////////////////////////////////////////////////////////////////////////// From 71dc5f8291af1272349e188d8e83f96ae79560fd Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Wed, 7 Aug 2013 16:20:23 +0200 Subject: [PATCH 16/19] simulate real cameras by working around vtkUserTransform to set projection matrix --- modules/viz/src/viz3d_impl.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index a24700ce91..cc732f6d7e 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -573,6 +573,16 @@ void cv::viz::Viz3d::VizImpl::setCamera(const Camera &camera) 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); + + // 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(((float)camera.getWindowSize().width) / camera.getWindowSize().height, -1.0f, 1.0f)); + 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())); + active_camera.SetUserTransform(transform); + transform->Delete(); } ///////////////////////////////////////////////////////////////////////////////////////////// From bb057491eae3ca3b1e39b2d4892f95c0fb06b27e Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Thu, 8 Aug 2013 12:14:27 +0200 Subject: [PATCH 17/19] create camera from projection matrix (used for getCamera in viz) --- modules/viz/include/opencv2/viz/types.hpp | 1 + modules/viz/src/types.cpp | 41 +++++++++++++++++++++-- modules/viz/src/viz3d_impl.cpp | 8 ++--- 3 files changed, 44 insertions(+), 6 deletions(-) diff --git a/modules/viz/include/opencv2/viz/types.hpp b/modules/viz/include/opencv2/viz/types.hpp index d12a4df13f..54b47140eb 100644 --- a/modules/viz/include/opencv2/viz/types.hpp +++ b/modules/viz/include/opencv2/viz/types.hpp @@ -100,6 +100,7 @@ namespace cv Camera(float f_x, float f_y, float c_x, float c_y, const Size &window_size); Camera(const Vec2f &fov, const Size &window_size); Camera(const cv::Matx33f &K, const Size &window_size); + Camera(const cv::Matx44f &proj, const Size &window_size); inline const Vec2d & getClip() const { return clip_; } inline void setClip(const Vec2d &clip) { clip_ = clip; } diff --git a/modules/viz/src/types.cpp b/modules/viz/src/types.cpp index 631582a646..ad9eb2731a 100644 --- a/modules/viz/src/types.cpp +++ b/modules/viz/src/types.cpp @@ -170,6 +170,43 @@ cv::viz::Camera::Camera(const cv::Matx33f & K, const Size &window_size) init(f_x, f_y, c_x, c_y, window_size); } +cv::viz::Camera::Camera(const Matx44f &proj, const Size &window_size) +{ + 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); + double right = 2.0 * near / proj(0,0) + left; + 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::epsilon()) + { + principal_point_[0] = -1.0f; + focal_[0] = -1.0f; + } + else + { + principal_point_[0] = (left * static_cast(window_size.width)) / (left - right); + focal_[0] = - near * principal_point_[0] / left; + } + + if (fabs(top-bottom) < std::numeric_limits::epsilon()) + { + principal_point_[1] = -1.0f; + focal_[1] = -1.0f; + } + else + { + principal_point_[1] = (top * static_cast(window_size.height)) / (top - bottom); + focal_[1] = near * principal_point_[1] / top; + } + + setClip(Vec2d(near, far)); + // Set the vertical field of view + fov_[1] = (atan2(principal_point_[1],focal_[1]) + atan2(window_size.height-principal_point_[1],focal_[1])); + setWindowSize(window_size); +} + void cv::viz::Camera::init(float f_x, float f_y, float c_x, float c_y, const Size &window_size) { CV_Assert(window_size.width > 0 && window_size.height > 0); @@ -220,7 +257,7 @@ void cv::viz::Camera::computeProjectionMatrix(Matx44f &proj) const double left = -(top * window_size_.width) / window_size_.height; double right = -left; double bottom = -top; - // If principal point is defined + // 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]; @@ -233,7 +270,7 @@ void cv::viz::Camera::computeProjectionMatrix(Matx44f &proj) const double temp2 = 1.0 / (right - left); double temp3 = 1.0 / (top - bottom); double temp4 = 1.0 / (clip_[0] - clip_[1]); - + proj = Matx44d::zeros(); proj(0,0) = temp1 * temp2; proj(1,1) = temp1 * temp3; diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index cc732f6d7e..a236b683c9 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -577,7 +577,7 @@ void cv::viz::Viz3d::VizImpl::setCamera(const Camera &camera) // 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(((float)camera.getWindowSize().width) / camera.getWindowSize().height, -1.0f, 1.0f)); + Matx44f old_proj_matrix = convertToMatx(active_camera.GetProjectionTransformMatrix(static_cast(camera.getWindowSize().width) / static_cast(camera.getWindowSize().height), -1.0f, 1.0f)); 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())); @@ -594,9 +594,9 @@ cv::viz::Camera cv::viz::Viz3d::VizImpl::getCamera() const Vec2d clip(active_camera.GetClippingRange()); Size window_size(renderer_->GetRenderWindow()->GetSize()[0], renderer_->GetRenderWindow()->GetSize()[1]); - - Camera camera(fov, window_size); - camera.setClip(clip); + 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); return camera; } From 4a1573de9b779d343cdba3668720a2470d990de9 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Fri, 9 Aug 2013 10:39:30 +0200 Subject: [PATCH 18/19] principal point is always set even though the intrinsic parameters are not given (center of window), fixed computation mistakes in setWindowSize in camera class --- modules/viz/src/types.cpp | 84 ++++++++++++---------------------- modules/viz/src/viz3d_impl.cpp | 23 ++++------ 2 files changed, 38 insertions(+), 69 deletions(-) diff --git a/modules/viz/src/types.cpp b/modules/viz/src/types.cpp index ad9eb2731a..104fc5a1ed 100644 --- a/modules/viz/src/types.cpp +++ b/modules/viz/src/types.cpp @@ -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(window_size.width)*0.5f, static_cast(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::epsilon()) - { - principal_point_[0] = -1.0f; - focal_[0] = -1.0f; - } - else - { - principal_point_[0] = (left * static_cast(window_size.width)) / (left - right); - focal_[0] = - near * principal_point_[0] / left; - } + if (fabs(left-right) < std::numeric_limits::epsilon()) principal_point_[0] = static_cast(window_size.width) * 0.5f; + else principal_point_[0] = (left * static_cast(window_size.width)) / (left - right); + focal_[0] = -near * principal_point_[0] / left; - if (fabs(top-bottom) < std::numeric_limits::epsilon()) - { - principal_point_[1] = -1.0f; - focal_[1] = -1.0f; - } - else - { - principal_point_[1] = (top * static_cast(window_size.height)) / (top - bottom); - focal_[1] = near * principal_point_[1] / top; - } + if (fabs(top-bottom) < std::numeric_limits::epsilon()) principal_point_[1] = static_cast(window_size.height) * 0.5f; + else principal_point_[1] = (top * static_cast(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(window_size.width) / static_cast(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(window_size.height) / static_cast(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(window_size.width) / static_cast(window_size_.width); + float scaley = static_cast(window_size.height) / static_cast(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); diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index a236b683c9..a2aa31bedc 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -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(camera.getWindowSize().width)/static_cast(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(camera.getWindowSize().width) / static_cast(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(window_size.width) / static_cast(window_size.height); + + Matx44f proj_matrix = convertToMatx(active_camera.GetProjectionTransformMatrix(aspect_ratio, -1.0f, 1.0f)); + Camera camera(proj_matrix, window_size); return camera; } From b69a97bef356ee2f0e431753a5163e7dc5ba8029 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Mon, 12 Aug 2013 09:07:50 +0200 Subject: [PATCH 19/19] access focal length and principal point in camera --- modules/viz/include/opencv2/viz/types.hpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/modules/viz/include/opencv2/viz/types.hpp b/modules/viz/include/opencv2/viz/types.hpp index 54b47140eb..f41b5fa0f4 100644 --- a/modules/viz/include/opencv2/viz/types.hpp +++ b/modules/viz/include/opencv2/viz/types.hpp @@ -111,6 +111,9 @@ namespace cv inline const Vec2f & getFov() const { return fov_; } inline void setFov(const Vec2f & fov) { fov_ = fov; } + inline const Vec2f & getPrincipalPoint() const { return principal_point_; } + inline const Vec2f & getFocalLength() const { return focal_; } + void computeProjectionMatrix(Matx44f &proj) const; static Camera KinectCamera(const Size &window_size);