Merge pull request #1471 from ozantonkal:master

pull/1497/merge
Alexander Smorkalov 11 years ago committed by OpenCV Buildbot
commit c6ab8cb6ee
  1. BIN
      doc/tutorials/images/viz.jpg
  2. 16
      doc/tutorials/tutorials.rst
  3. 159
      doc/tutorials/viz/creating_widgets/creating_widgets.rst
  4. BIN
      doc/tutorials/viz/creating_widgets/images/red_triangle.png
  5. BIN
      doc/tutorials/viz/launching_viz/images/window_demo.png
  6. 118
      doc/tutorials/viz/launching_viz/launching_viz.rst
  7. BIN
      doc/tutorials/viz/table_of_content_viz/images/facedetect.jpg
  8. BIN
      doc/tutorials/viz/table_of_content_viz/images/image_effects.png
  9. BIN
      doc/tutorials/viz/table_of_content_viz/images/intro.png
  10. 94
      doc/tutorials/viz/table_of_content_viz/table_of_content_viz.rst
  11. BIN
      doc/tutorials/viz/transformations/images/camera_view_point.png
  12. BIN
      doc/tutorials/viz/transformations/images/global_view_point.png
  13. 202
      doc/tutorials/viz/transformations/transformations.rst
  14. BIN
      doc/tutorials/viz/widget_pose/images/widgetpose.png
  15. 162
      doc/tutorials/viz/widget_pose/widget_pose.rst
  16. 57
      modules/viz/CMakeLists.txt
  17. BIN
      modules/viz/doc/images/cpw1.png
  18. BIN
      modules/viz/doc/images/cpw2.png
  19. BIN
      modules/viz/doc/images/cpw3.png
  20. BIN
      modules/viz/doc/images/cube_widget.png
  21. 9
      modules/viz/doc/viz.rst
  22. 718
      modules/viz/doc/viz3d.rst
  23. 944
      modules/viz/doc/widget.rst
  24. 121
      modules/viz/include/opencv2/viz.hpp
  25. 176
      modules/viz/include/opencv2/viz/types.hpp
  26. 130
      modules/viz/include/opencv2/viz/viz3d.hpp
  27. 72
      modules/viz/include/opencv2/viz/widget_accessor.hpp
  28. 359
      modules/viz/include/opencv2/viz/widgets.hpp
  29. 773
      modules/viz/src/cloud_widgets.cpp
  30. 717
      modules/viz/src/interactor_style.cpp
  31. 152
      modules/viz/src/interactor_style.h
  32. 49
      modules/viz/src/precomp.cpp
  33. 154
      modules/viz/src/precomp.hpp
  34. 1497
      modules/viz/src/shape_widgets.cpp
  35. 310
      modules/viz/src/types.cpp
  36. 227
      modules/viz/src/viz.cpp
  37. 137
      modules/viz/src/viz3d.cpp
  38. 608
      modules/viz/src/viz3d_impl.cpp
  39. 395
      modules/viz/src/viz3d_impl.hpp
  40. 410
      modules/viz/src/widget.cpp
  41. 3
      modules/viz/test/test_main.cpp
  42. 1
      modules/viz/test/test_precomp.cpp
  43. 68
      modules/viz/test/test_precomp.hpp
  44. 182
      modules/viz/test/test_viz3d.cpp
  45. 2
      samples/cpp/CMakeLists.txt
  46. 5752
      samples/cpp/tutorial_code/viz/bunny.ply
  47. 113
      samples/cpp/tutorial_code/viz/creating_widgets.cpp
  48. 66
      samples/cpp/tutorial_code/viz/launching_viz.cpp
  49. 112
      samples/cpp/tutorial_code/viz/transformations.cpp
  50. 79
      samples/cpp/tutorial_code/viz/widget_pose.cpp

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

@ -186,6 +186,21 @@ As always, we would be happy to hear your comments and receive your contribution
:width: 80pt :width: 80pt
:alt: gpu icon :alt: gpu icon
* :ref:`Table-Of-Content-Viz`
.. tabularcolumns:: m{100pt} m{300pt}
.. cssclass:: toctableopencv
=========== =======================================================
|Viz| These tutorials show how to use Viz module effectively.
=========== =======================================================
.. |Viz| image:: images/viz.jpg
:height: 80pt
:width: 80pt
:alt: viz icon
* :ref:`Table-Of-Content-General` * :ref:`Table-Of-Content-General`
.. tabularcolumns:: m{100pt} m{300pt} .. tabularcolumns:: m{100pt} m{300pt}
@ -221,4 +236,5 @@ As always, we would be happy to hear your comments and receive your contribution
gpu/table_of_content_gpu/table_of_content_gpu gpu/table_of_content_gpu/table_of_content_gpu
bioinspired/table_of_content_bioinspired/table_of_content_bioinspired bioinspired/table_of_content_bioinspired/table_of_content_bioinspired
ios/table_of_content_ios/table_of_content_ios ios/table_of_content_ios/table_of_content_ios
viz/table_of_content_viz/table_of_content_viz
general/table_of_content_general/table_of_content_general general/table_of_content_general/table_of_content_general

@ -0,0 +1,159 @@
.. _creating_widgets:
Creating Widgets
****************
Goal
====
In this tutorial you will learn how to
.. container:: enumeratevisibleitemswithsquare
* Create your own widgets using WidgetAccessor and VTK.
* Show your widget in the visualization window.
Code
====
You can download the code from :download:`here <../../../../samples/cpp/tutorial_code/viz/creating_widgets.cpp>`.
.. code-block:: cpp
#include <opencv2/viz.hpp>
#include <opencv2/viz/widget_accessor.hpp>
#include <iostream>
#include <vtkPoints.h>
#include <vtkTriangle.h>
#include <vtkCellArray.h>
#include <vtkPolyData.h>
#include <vtkPolyDataMapper.h>
#include <vtkIdList.h>
#include <vtkActor.h>
#include <vtkProp.h>
using namespace cv;
using namespace std;
/**
* @class WTriangle
* @brief Defining our own 3D Triangle widget
*/
class WTriangle : public viz::Widget3D
{
public:
WTriangle(const Point3f &pt1, const Point3f &pt2, const Point3f &pt3, const viz::Color & color = viz::Color::white());
};
/**
* @function WTriangle::WTriangle
*/
WTriangle::WTriangle(const Point3f &pt1, const Point3f &pt2, const Point3f &pt3, const viz::Color & color)
{
// Create a triangle
vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
points->InsertNextPoint(pt1.x, pt1.y, pt1.z);
points->InsertNextPoint(pt2.x, pt2.y, pt2.z);
points->InsertNextPoint(pt3.x, pt3.y, pt3.z);
vtkSmartPointer<vtkTriangle> triangle = vtkSmartPointer<vtkTriangle>::New();
triangle->GetPointIds()->SetId(0,0);
triangle->GetPointIds()->SetId(1,1);
triangle->GetPointIds()->SetId(2,2);
vtkSmartPointer<vtkCellArray> cells = vtkSmartPointer<vtkCellArray>::New();
cells->InsertNextCell(triangle);
// Create a polydata object
vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
// Add the geometry and topology to the polydata
polyData->SetPoints(points);
polyData->SetPolys(cells);
// Create mapper and actor
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
#if VTK_MAJOR_VERSION <= 5
mapper->SetInput(polyData);
#else
mapper->SetInputData(polyData);
#endif
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
// Store this actor in the widget in order that visualizer can access it
viz::WidgetAccessor::setProp(*this, actor);
// Set the color of the widget. This has to be called after WidgetAccessor.
setColor(color);
}
/**
* @function main
*/
int main()
{
/// Create a window
viz::Viz3d myWindow("Creating Widgets");
/// Create a triangle widget
WTriangle tw(Point3f(0.0,0.0,0.0), Point3f(1.0,1.0,1.0), Point3f(0.0,1.0,0.0), viz::Color::red());
/// Show widget in the visualizer window
myWindow.showWidget("TRIANGLE", tw);
/// Start event loop
myWindow.spin();
return 0;
}
Explanation
===========
Here is the general structure of the program:
* Extend Widget3D class to create a new 3D widget.
.. code-block:: cpp
class WTriangle : public viz::Widget3D
{
public:
WTriangle(const Point3f &pt1, const Point3f &pt2, const Point3f &pt3, const viz::Color & color = viz::Color::white());
};
* Assign a VTK actor to the widget.
.. code-block:: cpp
// Store this actor in the widget in order that visualizer can access it
viz::WidgetAccessor::setProp(*this, actor);
* Set color of the widget.
.. code-block:: cpp
// Set the color of the widget. This has to be called after WidgetAccessor.
setColor(color);
* Construct a triangle widget and display it in the window.
.. code-block:: cpp
/// Create a triangle widget
WTriangle tw(Point3f(0.0,0.0,0.0), Point3f(1.0,1.0,1.0), Point3f(0.0,1.0,0.0), viz::Color::red());
/// Show widget in the visualizer window
myWindow.showWidget("TRIANGLE", tw);
Results
=======
Here is the result of the program.
.. image:: images/red_triangle.png
:alt: Creating Widgets
:align: center

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

@ -0,0 +1,118 @@
.. _launching_viz:
Launching Viz
*************
Goal
====
In this tutorial you will learn how to
.. container:: enumeratevisibleitemswithsquare
* Open a visualization window.
* Access a window by its name.
* Start event loop.
* Start event loop for a given amount of time.
Code
====
You can download the code from :download:`here <../../../../samples/cpp/tutorial_code/viz/launching_viz.cpp>`.
.. code-block:: cpp
#include <opencv2/viz.hpp>
#include <iostream>
using namespace cv;
using namespace std;
/**
* @function main
*/
int main()
{
/// Create a window
viz::Viz3d myWindow("Viz Demo");
/// Start event loop
myWindow.spin();
/// Event loop is over when pressed q, Q, e, E
cout << "First event loop is over" << endl;
/// Access window via its name
viz::Viz3d sameWindow = viz::get("Viz Demo");
/// Start event loop
sameWindow.spin();
/// Event loop is over when pressed q, Q, e, E
cout << "Second event loop is over" << endl;
/// Event loop is over when pressed q, Q, e, E
/// Start event loop once for 1 millisecond
sameWindow.spinOnce(1, true);
while(!sameWindow.wasStopped())
{
/// Interact with window
/// Event loop for 1 millisecond
sameWindow.spinOnce(1, true);
}
/// Once more event loop is stopped
cout << "Last event loop is over" << endl;
return 0;
}
Explanation
===========
Here is the general structure of the program:
* Create a window.
.. code-block:: cpp
/// Create a window
viz::Viz3d myWindow("Viz Demo");
* Start event loop. This event loop will run until user terminates it by pressing **e**, **E**, **q**, **Q**.
.. code-block:: cpp
/// Start event loop
myWindow.spin();
* Access same window via its name. Since windows are implicitly shared, **sameWindow** is exactly the same with **myWindow**. If the name does not exist, a new window is created.
.. code-block:: cpp
/// Access window via its name
viz::Viz3d sameWindow = viz::get("Viz Demo");
* Start a controlled event loop. Once it starts, **wasStopped** is set to false. Inside the while loop, in each iteration, **spinOnce** is called to prevent event loop from completely stopping. Inside the while loop, user can execute other statements including those which interact with the window.
.. code-block:: cpp
/// Event loop is over when pressed q, Q, e, E
/// Start event loop once for 1 millisecond
sameWindow.spinOnce(1, true);
while(!sameWindow.wasStopped())
{
/// Interact with window
/// Event loop for 1 millisecond
sameWindow.spinOnce(1, true);
}
Results
=======
Here is the result of the program.
.. image:: images/window_demo.png
:alt: Launching Viz
:align: center

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

@ -0,0 +1,94 @@
.. _Table-Of-Content-Viz:
**OpenCV Viz**
-----------------------------------------------------------
.. include:: ../../definitions/tocDefinitions.rst
+
.. tabularcolumns:: m{100pt} m{300pt}
.. cssclass:: toctableopencv
================== ===============================================================================
|VizLaunchingViz| **Title:** :ref:`launching_viz`
*Compatibility:* > OpenCV 3.0.0
*Author:* Ozan Tonkal
You will learn how to launch a viz window.
================== ===============================================================================
.. |VizLaunchingViz| image:: ../launching_viz/images/window_demo.png
:height: 120pt
:width: 90pt
+
.. tabularcolumns:: m{100pt} m{300pt}
.. cssclass:: toctableopencv
================ ============================================================================
|WidgetPose| **Title:** :ref:`widget_pose`
*Compatibility:* > OpenCV 3.0.0
*Author:* Ozan Tonkal
You will learn how to change pose of a widget.
================ ============================================================================
.. |WidgetPose| image:: ../widget_pose/images/widgetpose.png
:height: 90pt
:width: 90pt
+
.. tabularcolumns:: m{100pt} m{300pt}
.. cssclass:: toctableopencv
================== ============================================================================
|Transformations| **Title:** :ref:`transformations`
*Compatibility:* > OpenCV 3.0.0
*Author:* Ozan Tonkal
You will learn how to transform between global and camera frames.
================== ============================================================================
.. |Transformations| image:: ../transformations/images/global_view_point.png
:height: 120pt
:width: 90pt
+
.. tabularcolumns:: m{100pt} m{300pt}
.. cssclass:: toctableopencv
================== ============================================================================
|CreatingWidgets| **Title:** :ref:`creating_widgets`
*Compatibility:* > OpenCV 3.0.0
*Author:* Ozan Tonkal
You will learn how to create your own widgets.
================== ============================================================================
.. |CreatingWidgets| image:: ../creating_widgets/images/red_triangle.png
:height: 120pt
:width: 90pt
.. raw:: latex
\pagebreak
.. toctree::
:hidden:
../launching_viz/launching_viz
../widget_pose/widget_pose
../transformations/transformations
../creating_widgets/creating_widgets

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

@ -0,0 +1,202 @@
.. _transformations:
Transformations
***************
Goal
====
In this tutorial you will learn how to
.. container:: enumeratevisibleitemswithsquare
* How to use makeTransformToGlobal to compute pose
* How to use makeCameraPose and Viz3d::setViewerPose
* How to visualize camera position by axes and by viewing frustum
Code
====
You can download the code from :download:`here <../../../../samples/cpp/tutorial_code/viz/transformations.cpp>`.
.. code-block:: cpp
#include <opencv2/viz.hpp>
#include <iostream>
#include <fstream>
using namespace cv;
using namespace std;
/**
* @function cvcloud_load
* @brief load bunny.ply
*/
Mat cvcloud_load()
{
Mat cloud(1, 1889, CV_32FC3);
ifstream ifs("bunny.ply");
string str;
for(size_t i = 0; i < 12; ++i)
getline(ifs, str);
Point3f* data = cloud.ptr<cv::Point3f>();
float dummy1, dummy2;
for(size_t i = 0; i < 1889; ++i)
ifs >> data[i].x >> data[i].y >> data[i].z >> dummy1 >> dummy2;
cloud *= 5.0f;
return cloud;
}
/**
* @function main
*/
int main(int argn, char **argv)
{
if (argn < 2)
{
cout << "Usage: " << endl << "./transformations [ G | C ]" << endl;
return 1;
}
bool camera_pov = (argv[1][0] == 'C');
/// Create a window
viz::Viz3d myWindow("Coordinate Frame");
/// Add coordinate axes
myWindow.showWidget("Coordinate Widget", viz::WCoordinateSystem());
/// Let's assume camera has the following properties
Point3f cam_pos(3.0f,3.0f,3.0f), cam_focal_point(3.0f,3.0f,2.0f), cam_y_dir(-1.0f,0.0f,0.0f);
/// We can get the pose of the cam using makeCameraPose
Affine3f cam_pose = viz::makeCameraPose(cam_pos, cam_focal_point, cam_y_dir);
/// We can get the transformation matrix from camera coordinate system to global using
/// - makeTransformToGlobal. We need the axes of the camera
Affine3f transform = viz::makeTransformToGlobal(Vec3f(0.0f,-1.0f,0.0f), Vec3f(-1.0f,0.0f,0.0f), Vec3f(0.0f,0.0f,-1.0f), cam_pos);
/// Create a cloud widget.
Mat bunny_cloud = cvcloud_load();
viz::WCloud cloud_widget(bunny_cloud, viz::Color::green());
/// Pose of the widget in camera frame
Affine3f cloud_pose = Affine3f().translate(Vec3f(0.0f,0.0f,3.0f));
/// Pose of the widget in global frame
Affine3f cloud_pose_global = transform * cloud_pose;
/// Visualize camera frame
if (!camera_pov)
{
viz::WCameraPosition cpw(0.5); // Coordinate axes
viz::WCameraPosition cpw_frustum(Vec2f(0.889484, 0.523599)); // Camera frustum
myWindow.showWidget("CPW", cpw, cam_pose);
myWindow.showWidget("CPW_FRUSTUM", cpw_frustum, cam_pose);
}
/// Visualize widget
myWindow.showWidget("bunny", cloud_widget, cloud_pose_global);
/// Set the viewer pose to that of camera
if (camera_pov)
myWindow.setViewerPose(cam_pose);
/// Start event loop.
myWindow.spin();
return 0;
}
Explanation
===========
Here is the general structure of the program:
* Create a visualization window.
.. code-block:: cpp
/// Create a window
viz::Viz3d myWindow("Transformations");
* Get camera pose from camera position, camera focal point and y direction.
.. code-block:: cpp
/// Let's assume camera has the following properties
Point3f cam_pos(3.0f,3.0f,3.0f), cam_focal_point(3.0f,3.0f,2.0f), cam_y_dir(-1.0f,0.0f,0.0f);
/// We can get the pose of the cam using makeCameraPose
Affine3f cam_pose = viz::makeCameraPose(cam_pos, cam_focal_point, cam_y_dir);
* Obtain transform matrix knowing the axes of camera coordinate system.
.. code-block:: cpp
/// We can get the transformation matrix from camera coordinate system to global using
/// - makeTransformToGlobal. We need the axes of the camera
Affine3f transform = viz::makeTransformToGlobal(Vec3f(0.0f,-1.0f,0.0f), Vec3f(-1.0f,0.0f,0.0f), Vec3f(0.0f,0.0f,-1.0f), cam_pos);
* Create a cloud widget from bunny.ply file
.. code-block:: cpp
/// Create a cloud widget.
Mat bunny_cloud = cvcloud_load();
viz::WCloud cloud_widget(bunny_cloud, viz::Color::green());
* Given the pose in camera coordinate system, estimate the global pose.
.. code-block:: cpp
/// Pose of the widget in camera frame
Affine3f cloud_pose = Affine3f().translate(Vec3f(0.0f,0.0f,3.0f));
/// Pose of the widget in global frame
Affine3f cloud_pose_global = transform * cloud_pose;
* If the view point is set to be global, visualize camera coordinate frame and viewing frustum.
.. code-block:: cpp
/// Visualize camera frame
if (!camera_pov)
{
viz::WCameraPosition cpw(0.5); // Coordinate axes
viz::WCameraPosition cpw_frustum(Vec2f(0.889484, 0.523599)); // Camera frustum
myWindow.showWidget("CPW", cpw, cam_pose);
myWindow.showWidget("CPW_FRUSTUM", cpw_frustum, cam_pose);
}
* Visualize the cloud widget with the estimated global pose
.. code-block:: cpp
/// Visualize widget
myWindow.showWidget("bunny", cloud_widget, cloud_pose_global);
* If the view point is set to be camera's, set viewer pose to **cam_pose**.
.. code-block:: cpp
/// Set the viewer pose to that of camera
if (camera_pov)
myWindow.setViewerPose(cam_pose);
Results
=======
#. Here is the result from the camera point of view.
.. image:: images/camera_view_point.png
:alt: Camera Viewpoint
:align: center
#. Here is the result from global point of view.
.. image:: images/global_view_point.png
:alt: Global Viewpoint
:align: center

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

@ -0,0 +1,162 @@
.. _widget_pose:
Pose of a widget
****************
Goal
====
In this tutorial you will learn how to
.. container:: enumeratevisibleitemswithsquare
* Add widgets to the visualization window
* Use Affine3 to set pose of a widget
* Rotating and translating a widget along an axis
Code
====
You can download the code from :download:`here <../../../../samples/cpp/tutorial_code/viz/widget_pose.cpp>`.
.. code-block:: cpp
#include <opencv2/viz.hpp>
#include <opencv2/calib3d.hpp>
#include <iostream>
using namespace cv;
using namespace std;
/**
* @function main
*/
int main()
{
/// Create a window
viz::Viz3d myWindow("Coordinate Frame");
/// Add coordinate axes
myWindow.showWidget("Coordinate Widget", viz::WCoordinateSystem());
/// Add line to represent (1,1,1) axis
viz::WLine axis(Point3f(-1.0f,-1.0f,-1.0f), Point3f(1.0f,1.0f,1.0f));
axis.setRenderingProperty(viz::LINE_WIDTH, 4.0);
myWindow.showWidget("Line Widget", axis);
/// Construct a cube widget
viz::WCube cube_widget(Point3f(0.5,0.5,0.0), Point3f(0.0,0.0,-0.5), true, viz::Color::blue());
cube_widget.setRenderingProperty(viz::LINE_WIDTH, 4.0);
/// Display widget (update if already displayed)
myWindow.showWidget("Cube Widget", cube_widget);
/// Rodrigues vector
Mat rot_vec = Mat::zeros(1,3,CV_32F);
float translation_phase = 0.0, translation = 0.0;
while(!myWindow.wasStopped())
{
/* Rotation using rodrigues */
/// Rotate around (1,1,1)
rot_vec.at<float>(0,0) += CV_PI * 0.01f;
rot_vec.at<float>(0,1) += CV_PI * 0.01f;
rot_vec.at<float>(0,2) += CV_PI * 0.01f;
/// Shift on (1,1,1)
translation_phase += CV_PI * 0.01f;
translation = sin(translation_phase);
Mat rot_mat;
Rodrigues(rot_vec, rot_mat);
/// Construct pose
Affine3f pose(rot_mat, Vec3f(translation, translation, translation));
myWindow.setWidgetPose("Cube Widget", pose);
myWindow.spinOnce(1, true);
}
return 0;
}
Explanation
===========
Here is the general structure of the program:
* Create a visualization window.
.. code-block:: cpp
/// Create a window
viz::Viz3d myWindow("Coordinate Frame");
* Show coordinate axes in the window using CoordinateSystemWidget.
.. code-block:: cpp
/// Add coordinate axes
myWindow.showWidget("Coordinate Widget", viz::WCoordinateSystem());
* Display a line representing the axis (1,1,1).
.. code-block:: cpp
/// Add line to represent (1,1,1) axis
viz::WLine axis(Point3f(-1.0f,-1.0f,-1.0f), Point3f(1.0f,1.0f,1.0f));
axis.setRenderingProperty(viz::LINE_WIDTH, 4.0);
myWindow.showWidget("Line Widget", axis);
* Construct a cube.
.. code-block:: cpp
/// Construct a cube widget
viz::WCube cube_widget(Point3f(0.5,0.5,0.0), Point3f(0.0,0.0,-0.5), true, viz::Color::blue());
cube_widget.setRenderingProperty(viz::LINE_WIDTH, 4.0);
myWindow.showWidget("Cube Widget", cube_widget);
* Create rotation matrix from rodrigues vector
.. code-block:: cpp
/// Rotate around (1,1,1)
rot_vec.at<float>(0,0) += CV_PI * 0.01f;
rot_vec.at<float>(0,1) += CV_PI * 0.01f;
rot_vec.at<float>(0,2) += CV_PI * 0.01f;
...
Mat rot_mat;
Rodrigues(rot_vec, rot_mat);
* Use Affine3f to set pose of the cube.
.. code-block:: cpp
/// Construct pose
Affine3f pose(rot_mat, Vec3f(translation, translation, translation));
myWindow.setWidgetPose("Cube Widget", pose);
* Animate the rotation using wasStopped and spinOnce
.. code-block:: cpp
while(!myWindow.wasStopped())
{
...
myWindow.spinOnce(1, true);
}
Results
=======
Here is the result of the program.
.. raw:: html
<div align="center">
<iframe width="420" height="315" src="https://www.youtube.com/embed/Jo47zc6-hvI" frameborder="0" allowfullscreen></iframe>
</div>

@ -0,0 +1,57 @@
macro(find_qvtk)
find_library (QVTK_LIBRARY QVTK HINTS ${VTK_DIR} ${VTK_DIR}/bin)
find_path (QVTK_INCLUDE_DIR QVTKWidget.h HINT ${VTK_INCLUDE_DIRS})
find_package_handle_standard_args(QVTK DEFAULT_MSG QVTK_LIBRARY QVTK_INCLUDE_DIR)
if(QVTK_FOUND)
get_filename_component (QVTK_LIBRARY_DIR ${QVTK_LIBRARY} PATH)
list(APPEND VTK_LIBRARY_DIRS ${QVTK_LIBRARY_DIR})
list(APPEND VTK_INCLUDE_DIRS ${QVTK_INCLUDE_DIR})
set (VTK_USE_QVTK ON)
endif()
endmacro()
macro(find_vtk)
find_package(VTK)
if(${VTK_MAJOR_VERSION} LESS 5)
MESSAGE(FATAL_ERROR "VTK 5 or more required!")
endif()
if(VTK_FOUND)
if (BUILD_SHARED_LIBS OR (NOT BUILD_SHARED_LIBS AND NOT VTK_BUILD_SHARED_LIBS))
find_qvtk()
message(STATUS "VTK found (include: ${VTK_INCLUDE_DIRS}, lib: ${VTK_LIBRARY_DIRS})")
link_directories(${VTK_LIBRARY_DIRS})
include_directories(SYSTEM ${VTK_INCLUDE_DIRS})
set(HAVE_VTK ON)
else ()
set(HAVE_VTK OFF)
message (FATAL_ERROR "VTK disabled. You are to build OpenCV in STATIC but VTK is SHARED!")
endif ()
endif()
endmacro()
if (NOT OPENCV_INITIAL_PASS AND DEFINED BUILD_opencv_viz AND BUILD_opencv_viz)
find_vtk()
endif()
if(DEFINED HAVE_VTK AND HAVE_VTK)
set(VTK_USE_FILE ${VTK_USE_FILE} CACHE INTERNAL "VTK_USE_FILE")
include (${VTK_USE_FILE})
add_definitions(-DHAVE_VTK)
endif()
set(the_description "Viz")
set(BUILD_opencv_viz_INIT OFF)
include_directories(src)
ocv_define_module(viz opencv_core)
if(DEFINED BUILD_opencv_viz AND BUILD_opencv_viz AND DEFINED HAVE_VTK AND HAVE_VTK)
if (${VTK_VERSION_MAJOR} EQUAL 5)
target_link_libraries(opencv_viz vtkCommon vtkWidgets vtkFiltering vtkRendering)
else()
target_link_libraries(opencv_viz vtkViewsCore vtkRenderingLOD vtkIOPLY vtkRenderingFreeTypeOpenGL vtkRenderingVolumeOpenGL vtkFiltersTexture)
endif()
if(APPLE)
target_link_libraries(opencv_viz "-framework Cocoa")
endif()
endif()

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

@ -0,0 +1,9 @@
***********************
viz. 3D Visualizer
***********************
.. toctree::
:maxdepth: 2
viz3d.rst
widget.rst

@ -0,0 +1,718 @@
Viz
===
.. highlight:: cpp
This section describes 3D visualization window as well as classes and methods
that are used to interact with it.
3D visualization window (see :ocv:class:`Viz3d`) is used to display widgets (see :ocv:class:`Widget`), and it provides
several methods to interact with scene and widgets.
viz::makeTransformToGlobal
--------------------------
Takes coordinate frame data and builds transform to global coordinate frame.
.. ocv:function:: Affine3f viz::makeTransformToGlobal(const Vec3f& axis_x, const Vec3f& axis_y, const Vec3f& axis_z, const Vec3f& origin = Vec3f::all(0))
:param axis_x: X axis vector in global coordinate frame.
:param axis_y: Y axis vector in global coordinate frame.
:param axis_z: Z axis vector in global coordinate frame.
:param origin: Origin of the coordinate frame in global coordinate frame.
This function returns affine transform that describes transformation between global coordinate frame and a given coordinate frame.
viz::makeCameraPose
-------------------
Constructs camera pose from position, focal_point and up_vector (see gluLookAt() for more infromation).
.. ocv:function:: Affine3f makeCameraPose(const Vec3f& position, const Vec3f& focal_point, const Vec3f& y_dir)
:param position: Position of the camera in global coordinate frame.
:param focal_point: Focal point of the camera in global coordinate frame.
:param y_dir: Up vector of the camera in global coordinate frame.
This function returns pose of the camera in global coordinate frame.
viz::get
--------
Retrieves a window by its name.
.. ocv:function:: Viz3d get(const String &window_name)
:param window_name: Name of the window that is to be retrieved.
This function returns a :ocv:class:`Viz3d` object with the given name.
.. note:: If the window with that name already exists, that window is returned. Otherwise, new window is created with the given name, and it is returned.
.. note:: Window names are automatically prefixed by "Viz - " if it is not done by the user.
.. code-block:: cpp
/// window and window_2 are the same windows.
viz::Viz3d window = viz::get("myWindow");
viz::Viz3d window_2 = viz::get("Viz - myWindow");
viz::isNan
----------
Checks **float/double** value for nan.
.. ocv:function:: bool isNan(float x)
.. ocv:function:: bool isNan(double x)
:param x: return true if nan.
Checks **vector** for nan.
.. ocv:function:: bool isNan(const Vec<_Tp, cn>& v)
:param v: return true if **any** of the elements of the vector is *nan*.
Checks **point** for nan
.. ocv:function:: bool isNan(const Point3_<_Tp>& p)
:param p: return true if **any** of the elements of the point is *nan*.
viz::VizAccessor
----------------
.. ocv:class:: VizAccessor
A singleton class that provides access by name infrastructure for 3D visualization windows. ::
class CV_EXPORTS VizAccessor
{
public:
static VizAccessor & getInstance();
static void release();
Viz3d get(const String &window_name);
//! window names automatically have Viz - prefix even though not provided by the users
static void generateWindowName(const String &window_name, String &output);
private:
/* hidden */
};
viz::VizAccessor::getInstance
-----------------------------
Returns the single instance of VizAccessor.
.. ocv:function:: static VizAccessor & getInstance()
viz::VizAccessor::release
-------------------------
Deletes the single instance of VizAccessor.
.. ocv:function:: static void release()
viz::VizAccessor::get
---------------------
Retrieves a window by its name.
.. ocv:function:: Viz3d get(const String &window_name)
:param window_name: Name of the window that is to be retrieved.
This function returns a :ocv:class:`Viz3d` object with the given name.
.. note:: If the window with that name already exists, that window is returned. Otherwise, new window is created with the given name, and it is returned.
.. note:: Window names are automatically prefixed by "Viz - " if it is not done by the user.
.. code-block:: cpp
/// window and window_2 are the same windows.
viz::Viz3d window = viz::get("myWindow");
viz::Viz3d window_2 = viz::get("Viz - myWindow");
viz::VizAccessor::generateWindowName
------------------------------------
Generates a window name by prefixing "Viz - " if it has not already been prefixed.
.. ocv:function:: static void generateWindowName(const String &window_name, String &output)
:param window_name: Window name
:param output: Prefixed window name
viz::Viz3d
----------
.. ocv:class:: Viz3d
The Viz3d class represents a 3D visualizer window. This class is implicitly shared. ::
class CV_EXPORTS Viz3d
{
public:
typedef cv::Ptr<Viz3d> Ptr;
typedef void (*KeyboardCallback)(const KeyboardEvent&, void*);
typedef void (*MouseCallback)(const MouseEvent&, void*);
Viz3d(const String& window_name = String());
Viz3d(const Viz3d&);
Viz3d& operator=(const Viz3d&);
~Viz3d();
void showWidget(const String &id, const Widget &widget, const Affine3f &pose = Affine3f::Identity());
void removeWidget(const String &id);
Widget getWidget(const String &id) const;
void removeAllWidgets();
void setWidgetPose(const String &id, const Affine3f &pose);
void updateWidgetPose(const String &id, const Affine3f &pose);
Affine3f getWidgetPose(const String &id) const;
void setCamera(const Camera &camera);
Camera getCamera() const;
Affine3f getViewerPose();
void setViewerPose(const Affine3f &pose);
void resetCameraViewpoint (const String &id);
void resetCamera();
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);
String getWindowName() const;
void saveScreenshot (const String &file);
void setWindowPosition (int x, int y);
void setFullScreen (bool mode);
void setBackgroundColor(const Color& color = Color::black());
void spin();
void spinOnce(int time = 1, bool force_redraw = false);
bool wasStopped() const;
void registerKeyboardCallback(KeyboardCallback callback, void* cookie = 0);
void registerMouseCallback(MouseCallback callback, void* cookie = 0);
void setRenderingProperty(const String &id, int property, double value);
double getRenderingProperty(const String &id, int property);
void setDesiredUpdateRate(double rate);
double getDesiredUpdateRate();
void setRepresentation(int representation);
private:
/* hidden */
};
viz::Viz3d::Viz3d
-----------------
The constructors.
.. ocv:function:: Viz3d::Viz3d(const String& window_name = String())
:param window_name: Name of the window.
viz::Viz3d::showWidget
----------------------
Shows a widget in the window.
.. ocv:function:: void Viz3d::showWidget(const String &id, const Widget &widget, const Affine3f &pose = Affine3f::Identity())
:param id: A unique id for the widget.
:param widget: The widget to be displayed in the window.
:param pose: Pose of the widget.
viz::Viz3d::removeWidget
------------------------
Removes a widget from the window.
.. ocv:function:: void removeWidget(const String &id)
:param id: The id of the widget that will be removed.
viz::Viz3d::getWidget
---------------------
Retrieves a widget from the window. A widget is implicitly shared;
that is, if the returned widget is modified, the changes will be
immediately visible in the window.
.. ocv:function:: Widget getWidget(const String &id) const
:param id: The id of the widget that will be returned.
viz::Viz3d::removeAllWidgets
----------------------------
Removes all widgets from the window.
.. ocv:function:: void removeAllWidgets()
viz::Viz3d::setWidgetPose
-------------------------
Sets pose of a widget in the window.
.. ocv:function:: void setWidgetPose(const String &id, const Affine3f &pose)
:param id: The id of the widget whose pose will be set.
:param pose: The new pose of the widget.
viz::Viz3d::updateWidgetPose
----------------------------
Updates pose of a widget in the window by pre-multiplying its current pose.
.. ocv:function:: void updateWidgetPose(const String &id, const Affine3f &pose)
:param id: The id of the widget whose pose will be updated.
:param pose: The pose that the current pose of the widget will be pre-multiplied by.
viz::Viz3d::getWidgetPose
-------------------------
Returns the current pose of a widget in the window.
.. ocv:function:: Affine3f getWidgetPose(const String &id) const
:param id: The id of the widget whose pose will be returned.
viz::Viz3d::setCamera
---------------------
Sets the intrinsic parameters of the viewer using Camera.
.. ocv:function:: void setCamera(const Camera &camera)
:param camera: Camera object wrapping intrinsinc parameters.
viz::Viz3d::getCamera
---------------------
Returns a camera object that contains intrinsic parameters of the current viewer.
.. ocv:function:: Camera getCamera() const
viz::Viz3d::getViewerPose
-------------------------
Returns the current pose of the viewer.
..ocv:function:: Affine3f getViewerPose()
viz::Viz3d::setViewerPose
-------------------------
Sets pose of the viewer.
.. ocv:function:: void setViewerPose(const Affine3f &pose)
:param pose: The new pose of the viewer.
viz::Viz3d::resetCameraViewpoint
--------------------------------
Resets camera viewpoint to a 3D widget in the scene.
.. ocv:function:: void resetCameraViewpoint (const String &id)
:param pose: Id of a 3D widget.
viz::Viz3d::resetCamera
-----------------------
Resets camera.
.. ocv:function:: void resetCamera()
viz::Viz3d::convertToWindowCoordinates
--------------------------------------
Transforms a point in world coordinate system to window coordinate system.
.. ocv:function:: void convertToWindowCoordinates(const Point3d &pt, Point3d &window_coord)
:param pt: Point in world coordinate system.
:param window_coord: Output point in window coordinate system.
viz::Viz3d::converTo3DRay
-------------------------
Transforms a point in window coordinate system to a 3D ray in world coordinate system.
.. ocv:function:: void converTo3DRay(const Point3d &window_coord, Point3d &origin, Vec3d &direction)
:param window_coord: Point in window coordinate system.
:param origin: Output origin of the ray.
:param direction: Output direction of the ray.
viz::Viz3d::getWindowSize
-------------------------
Returns the current size of the window.
.. ocv:function:: Size getWindowSize() const
viz::Viz3d::setWindowSize
-------------------------
Sets the size of the window.
.. ocv:function:: void setWindowSize(const Size &window_size)
:param window_size: New size of the window.
viz::Viz3d::getWindowName
-------------------------
Returns the name of the window which has been set in the constructor.
.. ocv:function:: String getWindowName() const
viz::Viz3d::saveScreenshot
--------------------------
Saves screenshot of the current scene.
.. ocv:function:: void saveScreenshot(const String &file)
:param file: Name of the file.
viz::Viz3d::setWindowPosition
-----------------------------
Sets the position of the window in the screen.
.. ocv:function:: void setWindowPosition(int x, int y)
:param x: x coordinate of the window
:param y: y coordinate of the window
viz::Viz3d::setFullScreen
-------------------------
Sets or unsets full-screen rendering mode.
.. ocv:function:: void setFullScreen(bool mode)
:param mode: If true, window will use full-screen mode.
viz::Viz3d::setBackgroundColor
------------------------------
Sets background color.
.. ocv:function:: void setBackgroundColor(const Color& color = Color::black())
viz::Viz3d::spin
----------------
The window renders and starts the event loop.
.. ocv:function:: void spin()
viz::Viz3d::spinOnce
--------------------
Starts the event loop for a given time.
.. ocv:function:: void spinOnce(int time = 1, bool force_redraw = false)
:param time: Amount of time in milliseconds for the event loop to keep running.
:param force_draw: If true, window renders.
viz::Viz3d::wasStopped
----------------------
Returns whether the event loop has been stopped.
.. ocv:function:: bool wasStopped()
viz::Viz3d::registerKeyboardCallback
------------------------------------
Sets keyboard handler.
.. ocv:function:: void registerKeyboardCallback(KeyboardCallback callback, void* cookie = 0)
:param callback: Keyboard callback ``(void (*KeyboardCallbackFunction(const KeyboardEvent&, void*))``.
:param cookie: The optional parameter passed to the callback.
viz::Viz3d::registerMouseCallback
---------------------------------
Sets mouse handler.
.. ocv:function:: void registerMouseCallback(MouseCallback callback, void* cookie = 0)
:param callback: Mouse callback ``(void (*MouseCallback)(const MouseEvent&, void*))``.
:param cookie: The optional parameter passed to the callback.
viz::Viz3d::setRenderingProperty
--------------------------------
Sets rendering property of a widget.
.. ocv:function:: void setRenderingProperty(const String &id, int property, double value)
:param id: Id of the widget.
:param property: Property that will be modified.
:param value: The new value of the property.
**Rendering property** can be one of the following:
* **POINT_SIZE**
* **OPACITY**
* **LINE_WIDTH**
* **FONT_SIZE**
* **REPRESENTATION**: Expected values are
* **REPRESENTATION_POINTS**
* **REPRESENTATION_WIREFRAME**
* **REPRESENTATION_SURFACE**
* **IMMEDIATE_RENDERING**:
* Turn on immediate rendering by setting the value to ``1``.
* Turn off immediate rendering by setting the value to ``0``.
* **SHADING**: Expected values are
* **SHADING_FLAT**
* **SHADING_GOURAUD**
* **SHADING_PHONG**
viz::Viz3d::getRenderingProperty
--------------------------------
Returns rendering property of a widget.
.. ocv:function:: double getRenderingProperty(const String &id, int property)
:param id: Id of the widget.
:param property: Property.
**Rendering property** can be one of the following:
* **POINT_SIZE**
* **OPACITY**
* **LINE_WIDTH**
* **FONT_SIZE**
* **REPRESENTATION**: Expected values are
* **REPRESENTATION_POINTS**
* **REPRESENTATION_WIREFRAME**
* **REPRESENTATION_SURFACE**
* **IMMEDIATE_RENDERING**:
* Turn on immediate rendering by setting the value to ``1``.
* Turn off immediate rendering by setting the value to ``0``.
* **SHADING**: Expected values are
* **SHADING_FLAT**
* **SHADING_GOURAUD**
* **SHADING_PHONG**
viz::Viz3d::setDesiredUpdateRate
--------------------------------
Sets desired update rate of the window.
.. ocv:function:: void setDesiredUpdateRate(double rate)
:param rate: Desired update rate. The default is 30.
viz::Viz3d::getDesiredUpdateRate
--------------------------------
Returns desired update rate of the window.
.. ocv:function:: double getDesiredUpdateRate()
viz::Viz3d::setRepresentation
-----------------------------
Sets geometry representation of the widgets to surface, wireframe or points.
.. ocv:function:: void setRepresentation(int representation)
:param representation: Geometry representation which can be one of the following:
* **REPRESENTATION_POINTS**
* **REPRESENTATION_WIREFRAME**
* **REPRESENTATION_SURFACE**
viz::Color
----------
.. ocv:class:: Color
This class a represents BGR color. ::
class CV_EXPORTS Color : public Scalar
{
public:
Color();
Color(double gray);
Color(double blue, double green, double red);
Color(const Scalar& color);
static Color black();
static Color blue();
static Color green();
static Color cyan();
static Color red();
static Color magenta();
static Color yellow();
static Color white();
static Color gray();
};
viz::Mesh3d
-----------
.. ocv:class:: Mesh3d
This class wraps mesh attributes, and it can load a mesh from a ``ply`` file. ::
class CV_EXPORTS Mesh3d
{
public:
Mat cloud, colors;
Mat polygons;
//! Loads mesh from a given ply file
static Mesh3d loadMesh(const String& file);
private:
/* hidden */
};
viz::Mesh3d::loadMesh
---------------------
Loads a mesh from a ``ply`` file.
.. ocv:function:: static Mesh3d loadMesh(const String& file)
:param file: File name.
viz::KeyboardEvent
------------------
.. ocv:class:: KeyboardEvent
This class represents a keyboard event. ::
class CV_EXPORTS KeyboardEvent
{
public:
static const unsigned int Alt = 1;
static const unsigned int Ctrl = 2;
static const unsigned int Shift = 4;
//! Create a keyboard event
//! - Note that action is true if key is pressed, false if released
KeyboardEvent (bool action, const std::string& key_sym, unsigned char key, bool alt, bool ctrl, bool shift);
bool isAltPressed () const;
bool isCtrlPressed () const;
bool isShiftPressed () const;
unsigned char getKeyCode () const;
const String& getKeySym () const;
bool keyDown () const;
bool keyUp () const;
protected:
/* hidden */
};
viz::KeyboardEvent::KeyboardEvent
---------------------------------
Constructs a KeyboardEvent.
.. ocv:function:: KeyboardEvent (bool action, const std::string& key_sym, unsigned char key, bool alt, bool ctrl, bool shift)
:param action: If true, key is pressed. If false, key is released.
:param key_sym: Name of the key.
:param key: Code of the key.
:param alt: If true, ``alt`` is pressed.
:param ctrl: If true, ``ctrl`` is pressed.
:param shift: If true, ``shift`` is pressed.
viz::MouseEvent
---------------
.. ocv:class:: MouseEvent
This class represents a mouse event. ::
class CV_EXPORTS MouseEvent
{
public:
enum Type { MouseMove = 1, MouseButtonPress, MouseButtonRelease, MouseScrollDown, MouseScrollUp, MouseDblClick } ;
enum MouseButton { NoButton = 0, LeftButton, MiddleButton, RightButton, VScroll } ;
MouseEvent (const Type& type, const MouseButton& button, const Point& p, bool alt, bool ctrl, bool shift);
Type type;
MouseButton button;
Point pointer;
unsigned int key_state;
};
viz::MouseEvent::MouseEvent
---------------------------
Constructs a MouseEvent.
.. ocv:function:: MouseEvent (const Type& type, const MouseButton& button, const Point& p, bool alt, bool ctrl, bool shift)
:param type: Type of the event. This can be **MouseMove**, **MouseButtonPress**, **MouseButtonRelease**, **MouseScrollDown**, **MouseScrollUp**, **MouseDblClick**.
:param button: Mouse button. This can be **NoButton**, **LeftButton**, **MiddleButton**, **RightButton**, **VScroll**.
:param p: Position of the event.
:param alt: If true, ``alt`` is pressed.
:param ctrl: If true, ``ctrl`` is pressed.
:param shift: If true, ``shift`` is pressed.
viz::Camera
-----------
.. ocv:class:: Camera
This class wraps intrinsic parameters of a camera. It provides several constructors
that can extract the intrinsic parameters from ``field of view``, ``intrinsic matrix`` and
``projection matrix``. ::
class CV_EXPORTS Camera
{
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::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; }
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; }
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);
private:
/* hidden */
};
viz::Camera::Camera
-------------------
Constructs a Camera.
.. ocv:function:: Camera(float f_x, float f_y, float c_x, float c_y, const Size &window_size)
:param f_x: Horizontal focal length.
:param f_y: Vertical focal length.
:param c_x: x coordinate of the principal point.
:param c_y: y coordinate of the principal point.
:param window_size: Size of the window. This together with focal length and principal point determines the field of view.
.. ocv:function:: Camera(const Vec2f &fov, const Size &window_size)
:param fov: Field of view (horizontal, vertical)
:param window_size: Size of the window.
Principal point is at the center of the window by default.
.. ocv:function:: Camera(const cv::Matx33f &K, const Size &window_size)
:param K: Intrinsic matrix of the camera.
:param window_size: Size of the window. This together with intrinsic matrix determines the field of view.
.. ocv:function:: Camera(const cv::Matx44f &proj, const Size &window_size)
:param proj: Projection matrix of the camera.
:param window_size: Size of the window. This together with projection matrix determines the field of view.
viz::Camera::computeProjectionMatrix
------------------------------------
Computes projection matrix using intrinsic parameters of the camera.
.. ocv:function:: void computeProjectionMatrix(Matx44f &proj) const
:param proj: Output projection matrix.
viz::Camera::KinectCamera
-------------------------
Creates a Kinect Camera.
.. ocv:function:: static Camera KinectCamera(const Size &window_size)
:param window_size: Size of the window. This together with intrinsic matrix of a Kinect Camera determines the field of view.

@ -0,0 +1,944 @@
Widget
======
.. highlight:: cpp
In this section, the widget framework is explained. Widgets represent
2D or 3D objects, varying from simple ones such as lines to complex one such as
point clouds and meshes.
Widgets are **implicitly shared**. Therefore, one can add a widget to the scene,
and modify the widget without re-adding the widget.
.. code-block:: cpp
...
/// Create a cloud widget
viz::WCloud cw(cloud, viz::Color::red());
/// Display it in a window
myWindow.showWidget("CloudWidget1", cw);
/// Modify it, and it will be modified in the window.
cw.setColor(viz::Color::yellow());
...
viz::Widget
-----------
.. ocv:class:: Widget
Base class of all widgets. Widget is implicitly shared. ::
class CV_EXPORTS Widget
{
public:
Widget();
Widget(const Widget& other);
Widget& operator=(const Widget& other);
~Widget();
//! Create a widget directly from ply file
static Widget fromPlyFile(const String &file_name);
//! Rendering properties of this particular widget
void setRenderingProperty(int property, double value);
double getRenderingProperty(int property) const;
//! Casting between widgets
template<typename _W> _W cast();
private:
/* hidden */
};
viz::Widget::fromPlyFile
------------------------
Creates a widget from ply file.
.. ocv:function:: static Widget fromPlyFile(const String &file_name)
:param file_name: Ply file name.
viz::Widget::setRenderingProperty
---------------------------------
Sets rendering property of the widget.
.. ocv:function:: void setRenderingProperty(int property, double value)
:param property: Property that will be modified.
:param value: The new value of the property.
**Rendering property** can be one of the following:
* **POINT_SIZE**
* **OPACITY**
* **LINE_WIDTH**
* **FONT_SIZE**
* **REPRESENTATION**: Expected values are
* **REPRESENTATION_POINTS**
* **REPRESENTATION_WIREFRAME**
* **REPRESENTATION_SURFACE**
* **IMMEDIATE_RENDERING**:
* Turn on immediate rendering by setting the value to ``1``.
* Turn off immediate rendering by setting the value to ``0``.
* **SHADING**: Expected values are
* **SHADING_FLAT**
* **SHADING_GOURAUD**
* **SHADING_PHONG**
viz::Widget::getRenderingProperty
---------------------------------
Returns rendering property of the widget.
.. ocv:function:: double getRenderingProperty(int property) const
:param property: Property.
**Rendering property** can be one of the following:
* **POINT_SIZE**
* **OPACITY**
* **LINE_WIDTH**
* **FONT_SIZE**
* **REPRESENTATION**: Expected values are
* **REPRESENTATION_POINTS**
* **REPRESENTATION_WIREFRAME**
* **REPRESENTATION_SURFACE**
* **IMMEDIATE_RENDERING**:
* Turn on immediate rendering by setting the value to ``1``.
* Turn off immediate rendering by setting the value to ``0``.
* **SHADING**: Expected values are
* **SHADING_FLAT**
* **SHADING_GOURAUD**
* **SHADING_PHONG**
viz::Widget::cast
-----------------
Casts a widget to another.
.. ocv:function:: template<typename _W> _W cast()
.. code-block:: cpp
// Create a sphere widget
viz::WSphere sw(Point3f(0.0f,0.0f,0.0f), 0.5f);
// Cast sphere widget to cloud widget
viz::WCloud cw = sw.cast<viz::WCloud>();
.. note:: 3D Widgets can only be cast to 3D Widgets. 2D Widgets can only be cast to 2D Widgets.
viz::WidgetAccessor
-------------------
.. ocv:class:: WidgetAccessor
This class is for users who want to develop their own widgets using VTK library API. ::
struct CV_EXPORTS WidgetAccessor
{
static vtkSmartPointer<vtkProp> getProp(const Widget &widget);
static void setProp(Widget &widget, vtkSmartPointer<vtkProp> prop);
};
viz::WidgetAccessor::getProp
----------------------------
Returns ``vtkProp`` of a given widget.
.. ocv:function:: static vtkSmartPointer<vtkProp> getProp(const Widget &widget)
:param widget: Widget whose ``vtkProp`` is to be returned.
.. note:: vtkProp has to be down cast appropriately to be modified.
.. code-block:: cpp
vtkActor * actor = vtkActor::SafeDownCast(viz::WidgetAccessor::getProp(widget));
viz::WidgetAccessor::setProp
----------------------------
Sets ``vtkProp`` of a given widget.
.. ocv:function:: static void setProp(Widget &widget, vtkSmartPointer<vtkProp> prop)
:param widget: Widget whose ``vtkProp`` is to be set.
:param prop: A ``vtkProp``.
viz::Widget3D
-------------
.. ocv:class:: Widget3D
Base class of all 3D widgets. ::
class CV_EXPORTS Widget3D : public Widget
{
public:
Widget3D() {}
void setPose(const Affine3f &pose);
void updatePose(const Affine3f &pose);
Affine3f getPose() const;
void setColor(const Color &color);
private:
/* hidden */
};
viz::Widget3D::setPose
----------------------
Sets pose of the widget.
.. ocv:function:: void setPose(const Affine3f &pose)
:param pose: The new pose of the widget.
viz::Widget3D::updateWidgetPose
-------------------------------
Updates pose of the widget by pre-multiplying its current pose.
.. ocv:function:: void updateWidgetPose(const Affine3f &pose)
:param pose: The pose that the current pose of the widget will be pre-multiplied by.
viz::Widget3D::getPose
----------------------
Returns the current pose of the widget.
.. ocv:function:: Affine3f getWidgetPose() const
viz::Widget3D::setColor
-----------------------
Sets the color of the widget.
.. ocv:function:: void setColor(const Color &color)
:param color: color of type :ocv:class:`Color`
viz::Widget2D
-------------
.. ocv:class:: Widget2D
Base class of all 2D widgets. ::
class CV_EXPORTS Widget2D : public Widget
{
public:
Widget2D() {}
void setColor(const Color &color);
};
viz::Widget2D::setColor
-----------------------
Sets the color of the widget.
.. ocv:function:: void setColor(const Color &color)
:param color: color of type :ocv:class:`Color`
viz::WLine
----------
.. ocv:class:: WLine
This 3D Widget defines a finite line. ::
class CV_EXPORTS WLine : public Widget3D
{
public:
WLine(const Point3f &pt1, const Point3f &pt2, const Color &color = Color::white());
};
viz::WLine::WLine
-----------------
Constructs a WLine.
.. ocv:function:: WLine(const Point3f &pt1, const Point3f &pt2, const Color &color = Color::white())
:param pt1: Start point of the line.
:param pt2: End point of the line.
:param color: :ocv:class:`Color` of the line.
viz::WPlane
-----------
.. ocv:class:: WPlane
This 3D Widget defines a finite plane. ::
class CV_EXPORTS WPlane : public Widget3D
{
public:
WPlane(const Vec4f& coefs, double size = 1.0, const Color &color = Color::white());
WPlane(const Vec4f& coefs, const Point3f& pt, double size = 1.0, const Color &color = Color::white());
private:
/* hidden */
};
viz::WPlane::WPlane
-------------------
Constructs a WPlane.
.. ocv:function:: WPlane(const Vec4f& coefs, double size = 1.0, const Color &color = Color::white())
:param coefs: Plane coefficients as in (A,B,C,D) where Ax + By + Cz + D = 0.
:param size: Size of the plane.
:param color: :ocv:class:`Color` of the plane.
.. ocv:function:: WPlane(const Vec4f& coefs, const Point3f& pt, double size = 1.0, const Color &color = Color::white())
:param coefs: Plane coefficients as in (A,B,C,D) where Ax + By + Cz + D = 0.
:param pt: Position of the plane.
:param size: Size of the plane.
:param color: :ocv:class:`Color` of the plane.
viz::WSphere
------------
.. ocv:class:: WSphere
This 3D Widget defines a sphere. ::
class CV_EXPORTS WSphere : public Widget3D
{
public:
WSphere(const cv::Point3f &center, float radius, int sphere_resolution = 10, const Color &color = Color::white())
};
viz::WSphere::WSphere
---------------------
Constructs a WSphere.
.. ocv:function:: WSphere(const cv::Point3f &center, float radius, int sphere_resolution = 10, const Color &color = Color::white())
:param center: Center of the sphere.
:param radius: Radius of the sphere.
:param sphere_resolution: Resolution of the sphere.
:param color: :ocv:class:`Color` of the sphere.
viz::WArrow
----------------
.. ocv:class:: WArrow
This 3D Widget defines an arrow. ::
class CV_EXPORTS WArrow : public Widget3D
{
public:
WArrow(const Point3f& pt1, const Point3f& pt2, double thickness = 0.03, const Color &color = Color::white());
};
viz::WArrow::WArrow
-----------------------------
Constructs an WArrow.
.. ocv:function:: WArrow(const Point3f& pt1, const Point3f& pt2, double thickness = 0.03, const Color &color = Color::white())
:param pt1: Start point of the arrow.
:param pt2: End point of the arrow.
:param thickness: Thickness of the arrow. Thickness of arrow head is also adjusted accordingly.
:param color: :ocv:class:`Color` of the arrow.
Arrow head is located at the end point of the arrow.
viz::WCircle
-----------------
.. ocv:class:: WCircle
This 3D Widget defines a circle. ::
class CV_EXPORTS WCircle : public Widget3D
{
public:
WCircle(const Point3f& pt, double radius, double thickness = 0.01, const Color &color = Color::white());
};
viz::WCircle::WCircle
-------------------------------
Constructs a WCircle.
.. ocv:function:: WCircle(const Point3f& pt, double radius, double thickness = 0.01, const Color &color = Color::white())
:param pt: Center of the circle.
:param radius: Radius of the circle.
:param thickness: Thickness of the circle.
:param color: :ocv:class:`Color` of the circle.
viz::WCylinder
--------------
.. ocv:class:: WCylinder
This 3D Widget defines a cylinder. ::
class CV_EXPORTS WCylinder : public Widget3D
{
public:
WCylinder(const Point3f& pt_on_axis, const Point3f& axis_direction, double radius, int numsides = 30, const Color &color = Color::white());
};
viz::WCylinder::WCylinder
-----------------------------------
Constructs a WCylinder.
.. ocv:function:: WCylinder(const Point3f& pt_on_axis, const Point3f& axis_direction, double radius, int numsides = 30, const Color &color = Color::white())
:param pt_on_axis: A point on the axis of the cylinder.
:param axis_direction: Direction of the axis of the cylinder.
:param radius: Radius of the cylinder.
:param numsides: Resolution of the cylinder.
:param color: :ocv:class:`Color` of the cylinder.
viz::WCube
----------
.. ocv:class:: WCube
This 3D Widget defines a cube. ::
class CV_EXPORTS WCube : public Widget3D
{
public:
WCube(const Point3f& pt_min, const Point3f& pt_max, bool wire_frame = true, const Color &color = Color::white());
};
viz::WCube::WCube
---------------------------
Constructs a WCube.
.. ocv:function:: WCube(const Point3f& pt_min, const Point3f& pt_max, bool wire_frame = true, const Color &color = Color::white())
:param pt_min: Specifies minimum point of the bounding box.
:param pt_max: Specifies maximum point of the bounding box.
:param wire_frame: If true, cube is represented as wireframe.
:param color: :ocv:class:`Color` of the cube.
.. image:: images/cube_widget.png
:alt: Cube Widget
:align: center
viz::WCoordinateSystem
----------------------
.. ocv:class:: WCoordinateSystem
This 3D Widget represents a coordinate system. ::
class CV_EXPORTS WCoordinateSystem : public Widget3D
{
public:
WCoordinateSystem(double scale = 1.0);
};
viz::WCoordinateSystem::WCoordinateSystem
---------------------------------------------------
Constructs a WCoordinateSystem.
.. ocv:function:: WCoordinateSystem(double scale = 1.0)
:param scale: Determines the size of the axes.
viz::WPolyLine
--------------
.. ocv:class:: WPolyLine
This 3D Widget defines a poly line. ::
class CV_EXPORTS WPolyLine : public Widget3D
{
public:
WPolyLine(InputArray points, const Color &color = Color::white());
private:
/* hidden */
};
viz::WPolyLine::WPolyLine
-----------------------------------
Constructs a WPolyLine.
.. ocv:function:: WPolyLine(InputArray points, const Color &color = Color::white())
:param points: Point set.
:param color: :ocv:class:`Color` of the poly line.
viz::WGrid
----------
.. ocv:class:: WGrid
This 3D Widget defines a grid. ::
class CV_EXPORTS WGrid : public Widget3D
{
public:
//! Creates grid at the origin
WGrid(const Vec2i &dimensions, const Vec2d &spacing, const Color &color = Color::white());
//! Creates grid based on the plane equation
WGrid(const Vec4f &coeffs, const Vec2i &dimensions, const Vec2d &spacing, const Color &color = Color::white());
private:
/* hidden */
};
viz::WGrid::WGrid
---------------------------
Constructs a WGrid.
.. ocv:function:: WGrid(const Vec2i &dimensions, const Vec2d &spacing, const Color &color = Color::white())
:param dimensions: Number of columns and rows, respectively.
:param spacing: Size of each column and row, respectively.
:param color: :ocv:class:`Color` of the grid.
.. ocv:function: WGrid(const Vec4f &coeffs, const Vec2i &dimensions, const Vec2d &spacing, const Color &color = Color::white())
:param coeffs: Plane coefficients as in (A,B,C,D) where Ax + By + Cz + D = 0.
:param dimensions: Number of columns and rows, respectively.
:param spacing: Size of each column and row, respectively.
:param color: :ocv:class:`Color` of the grid.
viz::WText3D
------------
.. ocv:class:: WText3D
This 3D Widget represents 3D text. The text always faces the camera. ::
class CV_EXPORTS WText3D : public Widget3D
{
public:
WText3D(const String &text, const Point3f &position, double text_scale = 1.0, double face_camera = true, const Color &color = Color::white());
void setText(const String &text);
String getText() const;
};
viz::WText3D::WText3D
-------------------------------
Constructs a WText3D.
.. ocv:function:: WText3D(const String &text, const Point3f &position, double text_scale = 1.0, double face_camera = true, const Color &color = Color::white())
:param text: Text content of the widget.
:param position: Position of the text.
:param text_scale: Size of the text.
:param face_camera: If true, text always faces the camera.
:param color: :ocv:class:`Color` of the text.
viz::WText3D::setText
---------------------
Sets the text content of the widget.
.. ocv:function:: void setText(const String &text)
:param text: Text content of the widget.
viz::WText3D::getText
---------------------
Returns the current text content of the widget.
.. ocv:function:: String getText() const
viz::WText
----------
.. ocv:class:: WText
This 2D Widget represents text overlay. ::
class CV_EXPORTS WText : public Widget2D
{
public:
WText(const String &text, const Point2i &pos, int font_size = 10, const Color &color = Color::white());
void setText(const String &text);
String getText() const;
};
viz::WText::WText
-----------------
Constructs a WText.
.. ocv:function:: WText(const String &text, const Point2i &pos, int font_size = 10, const Color &color = Color::white())
:param text: Text content of the widget.
:param pos: Position of the text.
:param font_size: Font size.
:param color: :ocv:class:`Color` of the text.
viz::WText::setText
-------------------
Sets the text content of the widget.
.. ocv:function:: void setText(const String &text)
:param text: Text content of the widget.
viz::WText::getText
-------------------
Returns the current text content of the widget.
.. ocv:function:: String getText() const
viz::WImageOverlay
------------------
.. ocv:class:: WImageOverlay
This 2D Widget represents an image overlay. ::
class CV_EXPORTS WImageOverlay : public Widget2D
{
public:
WImageOverlay(const Mat &image, const Rect &rect);
void setImage(const Mat &image);
};
viz::WImageOverlay::WImageOverlay
---------------------------------
Constructs an WImageOverlay.
.. ocv:function:: WImageOverlay(const Mat &image, const Rect &rect)
:param image: BGR or Gray-Scale image.
:param rect: Image is scaled and positioned based on rect.
viz::WImageOverlay::setImage
----------------------------
Sets the image content of the widget.
.. ocv:function:: void setImage(const Mat &image)
:param image: BGR or Gray-Scale image.
viz::WImage3D
-------------
.. ocv:class:: WImage3D
This 3D Widget represents an image in 3D space. ::
class CV_EXPORTS WImage3D : public Widget3D
{
public:
//! Creates 3D image at the origin
WImage3D(const Mat &image, const Size &size);
//! Creates 3D image at a given position, pointing in the direction of the normal, and having the up_vector orientation
WImage3D(const Vec3f &position, const Vec3f &normal, const Vec3f &up_vector, const Mat &image, const Size &size);
void setImage(const Mat &image);
};
viz::WImage3D::WImage3D
-----------------------
Constructs an WImage3D.
.. ocv:function:: WImage3D(const Mat &image, const Size &size)
:param image: BGR or Gray-Scale image.
:param size: Size of the image.
.. ocv:function:: WImage3D(const Vec3f &position, const Vec3f &normal, const Vec3f &up_vector, const Mat &image, const Size &size)
:param position: Position of the image.
:param normal: Normal of the plane that represents the image.
:param up_vector: Determines orientation of the image.
:param image: BGR or Gray-Scale image.
:param size: Size of the image.
viz::WImage3D::setImage
-----------------------
Sets the image content of the widget.
.. ocv:function:: void setImage(const Mat &image)
:param image: BGR or Gray-Scale image.
viz::WCameraPosition
--------------------
.. ocv:class:: WCameraPosition
This 3D Widget represents camera position in a scene by its axes or viewing frustum. ::
class CV_EXPORTS WCameraPosition : public Widget3D
{
public:
//! Creates camera coordinate frame (axes) at the origin
WCameraPosition(double scale = 1.0);
//! Creates frustum based on the intrinsic marix K at the origin
WCameraPosition(const Matx33f &K, double scale = 1.0, const Color &color = Color::white());
//! Creates frustum based on the field of view at the origin
WCameraPosition(const Vec2f &fov, double scale = 1.0, const Color &color = Color::white());
//! Creates frustum and display given image at the far plane
WCameraPosition(const Matx33f &K, const Mat &img, double scale = 1.0, const Color &color = Color::white());
//! Creates frustum and display given image at the far plane
WCameraPosition(const Vec2f &fov, const Mat &img, double scale = 1.0, const Color &color = Color::white());
};
viz::WCameraPosition::WCameraPosition
-------------------------------------
Constructs a WCameraPosition.
- **Display camera coordinate frame.**
.. ocv:function:: WCameraPosition(double scale = 1.0)
Creates camera coordinate frame at the origin.
.. image:: images/cpw1.png
:alt: Camera coordinate frame
:align: center
- **Display the viewing frustum.**
.. ocv:function:: WCameraPosition(const Matx33f &K, double scale = 1.0, const Color &color = Color::white())
:param K: Intrinsic matrix of the camera.
:param scale: Scale of the frustum.
:param color: :ocv:class:`Color` of the frustum.
Creates viewing frustum of the camera based on its intrinsic matrix K.
.. ocv:function:: WCameraPosition(const Vec2f &fov, double scale = 1.0, const Color &color = Color::white())
:param fov: Field of view of the camera (horizontal, vertical).
:param scale: Scale of the frustum.
:param color: :ocv:class:`Color` of the frustum.
Creates viewing frustum of the camera based on its field of view fov.
.. image:: images/cpw2.png
:alt: Camera viewing frustum
:align: center
- **Display image on the far plane of the viewing frustum.**
.. ocv:function:: WCameraPosition(const Matx33f &K, const Mat &img, double scale = 1.0, const Color &color = Color::white())
:param K: Intrinsic matrix of the camera.
:param img: BGR or Gray-Scale image that is going to be displayed on the far plane of the frustum.
:param scale: Scale of the frustum and image.
:param color: :ocv:class:`Color` of the frustum.
Creates viewing frustum of the camera based on its intrinsic matrix K, and displays image on the far end plane.
.. ocv:function:: WCameraPosition(const Vec2f &fov, const Mat &img, double scale = 1.0, const Color &color = Color::white())
:param fov: Field of view of the camera (horizontal, vertical).
:param img: BGR or Gray-Scale image that is going to be displayed on the far plane of the frustum.
:param scale: Scale of the frustum and image.
:param color: :ocv:class:`Color` of the frustum.
Creates viewing frustum of the camera based on its intrinsic matrix K, and displays image on the far end plane.
.. image:: images/cpw3.png
:alt: Camera viewing frustum with image
:align: center
viz::WTrajectory
----------------
.. ocv:class:: WTrajectory
This 3D Widget represents a trajectory. ::
class CV_EXPORTS WTrajectory : public Widget3D
{
public:
enum {DISPLAY_FRAMES = 1, DISPLAY_PATH = 2};
//! Displays trajectory of the given path either by coordinate frames or polyline
WTrajectory(const std::vector<Affine3f> &path, int display_mode = WTrajectory::DISPLAY_PATH, const Color &color = Color::white(), double scale = 1.0);
//! Displays trajectory of the given path by frustums
WTrajectory(const std::vector<Affine3f> &path, const Matx33f &K, double scale = 1.0, const Color &color = Color::white());
//! Displays trajectory of the given path by frustums
WTrajectory(const std::vector<Affine3f> &path, const Vec2f &fov, double scale = 1.0, const Color &color = Color::white());
private:
/* hidden */
};
viz::WTrajectory::WTrajectory
-----------------------------
Constructs a WTrajectory.
.. ocv:function:: WTrajectory(const std::vector<Affine3f> &path, int display_mode = WTrajectory::DISPLAY_PATH, const Color &color = Color::white(), double scale = 1.0)
:param path: List of poses on a trajectory.
:param display_mode: Display mode. This can be DISPLAY_PATH, DISPLAY_FRAMES, DISPLAY_PATH & DISPLAY_FRAMES.
:param color: :ocv:class:`Color` of the polyline that represents path. Frames are not affected.
:param scale: Scale of the frames. Polyline is not affected.
Displays trajectory of the given path as follows:
* DISPLAY_PATH : Displays a poly line that represents the path.
* DISPLAY_FRAMES : Displays coordinate frames at each pose.
* DISPLAY_PATH & DISPLAY_FRAMES : Displays both poly line and coordinate frames.
.. ocv:function:: WTrajectory(const std::vector<Affine3f> &path, const Matx33f &K, double scale = 1.0, const Color &color = Color::white())
:param path: List of poses on a trajectory.
:param K: Intrinsic matrix of the camera.
:param scale: Scale of the frustums.
:param color: :ocv:class:`Color` of the frustums.
Displays frustums at each pose of the trajectory.
.. ocv:function:: WTrajectory(const std::vector<Affine3f> &path, const Vec2f &fov, double scale = 1.0, const Color &color = Color::white())
:param path: List of poses on a trajectory.
:param fov: Field of view of the camera (horizontal, vertical).
:param scale: Scale of the frustums.
:param color: :ocv:class:`Color` of the frustums.
Displays frustums at each pose of the trajectory.
viz::WSpheresTrajectory
-----------------------
.. ocv:class:: WSpheresTrajectory
This 3D Widget represents a trajectory using spheres and lines, where spheres represent the positions of the camera, and lines
represent the direction from previous position to the current. ::
class CV_EXPORTS WSpheresTrajectory : public Widget3D
{
public:
WSpheresTrajectory(const std::vector<Affine3f> &path, float line_length = 0.05f,
double init_sphere_radius = 0.021, sphere_radius = 0.007,
Color &line_color = Color::white(), const Color &sphere_color = Color::white());
};
viz::WSpheresTrajectory::WSpheresTrajectory
-------------------------------------------
Constructs a WSpheresTrajectory.
.. ocv:function:: WSpheresTrajectory(const std::vector<Affine3f> &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())
:param path: List of poses on a trajectory.
:param line_length: Length of the lines.
:param init_sphere_radius: Radius of the first sphere which represents the initial position of the camera.
:param sphere_radius: Radius of the rest of the spheres.
:param line_color: :ocv:class:`Color` of the lines.
:param sphere_color: :ocv:class:`Color` of the spheres.
viz::WCloud
-----------
.. ocv:class:: WCloud
This 3D Widget defines a point cloud. ::
class CV_EXPORTS WCloud : public Widget3D
{
public:
//! Each point in cloud is mapped to a color in colors
WCloud(InputArray cloud, InputArray colors);
//! All points in cloud have the same color
WCloud(InputArray cloud, const Color &color = Color::white());
private:
/* hidden */
};
viz::WCloud::WCloud
-------------------
Constructs a WCloud.
.. ocv:function:: WCloud(InputArray cloud, InputArray colors)
:param cloud: Set of points which can be of type: ``CV_32FC3``, ``CV_32FC4``, ``CV_64FC3``, ``CV_64FC4``.
:param colors: Set of colors. It has to be of the same size with cloud.
Points in the cloud belong to mask when they are set to (NaN, NaN, NaN).
.. ocv:function:: WCloud(InputArray cloud, const Color &color = Color::white())
:param cloud: Set of points which can be of type: ``CV_32FC3``, ``CV_32FC4``, ``CV_64FC3``, ``CV_64FC4``.
:param color: A single :ocv:class:`Color` for the whole cloud.
Points in the cloud belong to mask when they are set to (NaN, NaN, NaN).
.. note:: In case there are four channels in the cloud, fourth channel is ignored.
viz::WCloudCollection
---------------------
.. ocv:class:: WCloudCollection
This 3D Widget defines a collection of clouds. ::
class CV_EXPORTS WCloudCollection : public Widget3D
{
public:
WCloudCollection();
//! Each point in cloud is mapped to a color in colors
void addCloud(InputArray cloud, InputArray colors, const Affine3f &pose = Affine3f::Identity());
//! All points in cloud have the same color
void addCloud(InputArray cloud, const Color &color = Color::white(), Affine3f &pose = Affine3f::Identity());
private:
/* hidden */
};
viz::WCloudCollection::WCloudCollection
---------------------------------------
Constructs a WCloudCollection.
.. ocv:function:: WCloudCollection()
viz::WCloudCollection::addCloud
-------------------------------
Adds a cloud to the collection.
.. ocv:function:: void addCloud(InputArray cloud, InputArray colors, const Affine3f &pose = Affine3f::Identity())
:param cloud: Point set which can be of type: ``CV_32FC3``, ``CV_32FC4``, ``CV_64FC3``, ``CV_64FC4``.
:param colors: Set of colors. It has to be of the same size with cloud.
:param pose: Pose of the cloud.
Points in the cloud belong to mask when they are set to (NaN, NaN, NaN).
.. ocv:function:: void addCloud(InputArray cloud, const Color &color = Color::white(), const Affine3f &pose = Affine3f::Identity())
:param cloud: Point set which can be of type: ``CV_32FC3``, ``CV_32FC4``, ``CV_64FC3``, ``CV_64FC4``.
:param colors: A single :ocv:class:`Color` for the whole cloud.
:param pose: Pose of the cloud.
Points in the cloud belong to mask when they are set to (NaN, NaN, NaN).
.. note:: In case there are four channels in the cloud, fourth channel is ignored.
viz::WCloudNormals
------------------
.. ocv:class:: WCloudNormals
This 3D Widget represents normals of a point cloud. ::
class CV_EXPORTS WCloudNormals : public Widget3D
{
public:
WCloudNormals(InputArray cloud, InputArray normals, int level = 100, float scale = 0.02f, const Color &color = Color::white());
private:
/* hidden */
};
viz::WCloudNormals::WCloudNormals
---------------------------------
Constructs a WCloudNormals.
.. ocv:function:: WCloudNormals(InputArray cloud, InputArray normals, int level = 100, float scale = 0.02f, const Color &color = Color::white())
:param cloud: Point set which can be of type: ``CV_32FC3``, ``CV_32FC4``, ``CV_64FC3``, ``CV_64FC4``.
:param normals: A set of normals that has to be of same type with cloud.
:param level: Display only every ``level`` th normal.
:param scale: Scale of the arrows that represent normals.
:param color: :ocv:class:`Color` of the arrows that represent normals.
.. note:: In case there are four channels in the cloud, fourth channel is ignored.
viz::WMesh
----------
.. ocv:class:: WMesh
This 3D Widget defines a mesh. ::
class CV_EXPORTS WMesh : public Widget3D
{
public:
WMesh(const Mesh3d &mesh);
private:
/* hidden */
};
viz::WMesh::WMesh
-----------------
Constructs a WMesh.
.. ocv:function:: WMesh(const Mesh3d &mesh)
:param mesh: :ocv:class:`Mesh3d` object that will be displayed.

@ -0,0 +1,121 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
// Authors:
// * Ozan Tonkal, ozantonkal@gmail.com
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
//
// OpenCV Viz module is complete rewrite of
// PCL visualization module (www.pointclouds.org)
//
//M*/
#ifndef __OPENCV_VIZ_HPP__
#define __OPENCV_VIZ_HPP__
#include <opencv2/viz/types.hpp>
#include <opencv2/viz/widgets.hpp>
#include <opencv2/viz/viz3d.hpp>
namespace cv
{
namespace viz
{
//! takes coordiante frame data and builds transfrom to global coordinate frame
CV_EXPORTS Affine3f makeTransformToGlobal(const Vec3f& axis_x, const Vec3f& axis_y, const Vec3f& axis_z, const Vec3f& origin = Vec3f::all(0));
//! constructs camera pose from position, focal_point and up_vector (see gluLookAt() for more infromation)
CV_EXPORTS Affine3f makeCameraPose(const Vec3f& position, const Vec3f& focal_point, const Vec3f& y_dir);
//! retrieves a window by its name
CV_EXPORTS Viz3d get(const String &window_name);
//! checks float value for Nan
inline bool isNan(float x)
{
unsigned int *u = reinterpret_cast<unsigned int *>(&x);
return ((u[0] & 0x7f800000) == 0x7f800000) && (u[0] & 0x007fffff);
}
//! checks double value for Nan
inline bool isNan(double x)
{
unsigned int *u = reinterpret_cast<unsigned int *>(&x);
return (u[1] & 0x7ff00000) == 0x7ff00000 && (u[0] != 0 || (u[1] & 0x000fffff) != 0);
}
//! checks vectors for Nans
template<typename _Tp, int cn> inline bool isNan(const Vec<_Tp, cn>& v)
{ return isNan(v.val[0]) || isNan(v.val[1]) || isNan(v.val[2]); }
//! checks point for Nans
template<typename _Tp> inline bool isNan(const Point3_<_Tp>& p)
{ return isNan(p.x) || isNan(p.y) || isNan(p.z); }
//! helper class that provides access by name infrastructure
class CV_EXPORTS VizAccessor
{
public:
static VizAccessor & getInstance();
static void release();
Viz3d get(const String &window_name);
//! window names automatically have Viz - prefix even though not provided by the users
static void generateWindowName(const String &window_name, String &output);
private:
VizAccessor(); // Singleton
~VizAccessor();
void add(Viz3d window);
void remove(const String &window_name);
static VizAccessor * instance_;
static bool is_instantiated_;
struct VizAccessorImpl;
static VizAccessorImpl * impl_;
friend class Viz3d;
};
} /* namespace viz */
} /* namespace cv */
#endif /* __OPENCV_VIZ_HPP__ */

@ -0,0 +1,176 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
// Authors:
// * Ozan Tonkal, ozantonkal@gmail.com
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
//
// OpenCV Viz module is complete rewrite of
// PCL visualization module (www.pointclouds.org)
//
//M*/
#ifndef __OPENCV_VIZ_TYPES_HPP__
#define __OPENCV_VIZ_TYPES_HPP__
#include <string>
#include <opencv2/core.hpp>
#include <opencv2/core/affine.hpp>
namespace cv
{
namespace viz
{
class CV_EXPORTS Color : public Scalar
{
public:
Color();
Color(double gray);
Color(double blue, double green, double red);
Color(const Scalar& color);
static Color black();
static Color blue();
static Color green();
static Color cyan();
static Color red();
static Color magenta();
static Color yellow();
static Color white();
static Color gray();
};
class CV_EXPORTS Mesh3d
{
public:
Mat cloud, colors;
Mat polygons;
//! Loads mesh from a given ply file
static cv::viz::Mesh3d loadMesh(const String& file);
private:
struct loadMeshImpl;
};
class CV_EXPORTS KeyboardEvent
{
public:
static const unsigned int Alt = 1;
static const unsigned int Ctrl = 2;
static const unsigned int Shift = 4;
//! Create a keyboard event
//! - Note that action is true if key is pressed, false if released
KeyboardEvent(bool action, const String& key_sym, unsigned char key, bool alt, bool ctrl, bool shift);
bool isAltPressed() const;
bool isCtrlPressed() const;
bool isShiftPressed() const;
unsigned char getKeyCode() const;
const String& getKeySym() const;
bool keyDown() const;
bool keyUp() const;
protected:
bool action_;
unsigned int modifiers_;
unsigned char key_code_;
String key_sym_;
};
class CV_EXPORTS MouseEvent
{
public:
enum Type { MouseMove = 1, MouseButtonPress, MouseButtonRelease, MouseScrollDown, MouseScrollUp, MouseDblClick } ;
enum MouseButton { NoButton = 0, LeftButton, MiddleButton, RightButton, VScroll } ;
MouseEvent(const Type& type, const MouseButton& button, const Point& p, bool alt, bool ctrl, bool shift);
Type type;
MouseButton button;
Point pointer;
unsigned int key_state;
};
class CV_EXPORTS Camera
{
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::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; }
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; }
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);
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_;
Vec2f principal_point_;
Vec2f focal_;
};
} /* namespace viz */
} /* namespace cv */
#endif

@ -0,0 +1,130 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
// Authors:
// * Ozan Tonkal, ozantonkal@gmail.com
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
//
// OpenCV Viz module is complete rewrite of
// PCL visualization module (www.pointclouds.org)
//
//M*/
#ifndef __OPENCV_VIZ_VIZ3D_HPP__
#define __OPENCV_VIZ_VIZ3D_HPP__
#if !defined YES_I_AGREE_THAT_VIZ_API_IS_NOT_STABLE_NOW_AND_BINARY_COMPARTIBILITY_WONT_BE_SUPPORTED
//#error "Viz is in beta state now. Please define macro above to use it"
#endif
#include <opencv2/core.hpp>
#include <opencv2/viz/types.hpp>
#include <opencv2/viz/widgets.hpp>
namespace cv
{
namespace viz
{
class CV_EXPORTS Viz3d
{
public:
typedef cv::Ptr<Viz3d> Ptr;
typedef void (*KeyboardCallback)(const KeyboardEvent&, void*);
typedef void (*MouseCallback)(const MouseEvent&, void*);
Viz3d(const String& window_name = String());
Viz3d(const Viz3d&);
Viz3d& operator=(const Viz3d&);
~Viz3d();
void showWidget(const String &id, const Widget &widget, const Affine3f &pose = Affine3f::Identity());
void removeWidget(const String &id);
Widget getWidget(const String &id) const;
void removeAllWidgets();
void setWidgetPose(const String &id, const Affine3f &pose);
void updateWidgetPose(const String &id, const Affine3f &pose);
Affine3f getWidgetPose(const String &id) const;
void setCamera(const Camera &camera);
Camera getCamera() const;
Affine3f getViewerPose();
void setViewerPose(const Affine3f &pose);
void resetCameraViewpoint(const String &id);
void resetCamera();
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);
String getWindowName() const;
void saveScreenshot(const String &file);
void setWindowPosition(int x, int y);
void setFullScreen(bool mode);
void setBackgroundColor(const Color& color = Color::black());
void spin();
void spinOnce(int time = 1, bool force_redraw = false);
bool wasStopped() const;
void registerKeyboardCallback(KeyboardCallback callback, void* cookie = 0);
void registerMouseCallback(MouseCallback callback, void* cookie = 0);
void setRenderingProperty(const String &id, int property, double value);
double getRenderingProperty(const String &id, int property);
void setDesiredUpdateRate(double rate);
double getDesiredUpdateRate();
void setRepresentation(int representation);
private:
struct VizImpl;
VizImpl* impl_;
void create(const String &window_name);
void release();
};
} /* namespace viz */
} /* namespace cv */
#endif

@ -0,0 +1,72 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
// Authors:
// * Ozan Tonkal, ozantonkal@gmail.com
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
//
// OpenCV Viz module is complete rewrite of
// PCL visualization module (www.pointclouds.org)
//
//M*/
#ifndef __OPENCV_VIZ_WIDGET_ACCESSOR_HPP__
#define __OPENCV_VIZ_WIDGET_ACCESSOR_HPP__
#include <opencv2/core/cvdef.h>
#include <vtkSmartPointer.h>
#include <vtkProp.h>
namespace cv
{
namespace viz
{
class Widget;
//The class is only that depends on VTK in its interface.
//It is indended for those users who want to develop own widgets system using VTK library API.
struct CV_EXPORTS WidgetAccessor
{
static vtkSmartPointer<vtkProp> getProp(const Widget &widget);
static void setProp(Widget &widget, vtkSmartPointer<vtkProp> prop);
};
}
}
#endif

@ -0,0 +1,359 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
// Authors:
// * Ozan Tonkal, ozantonkal@gmail.com
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
//
// OpenCV Viz module is complete rewrite of
// PCL visualization module (www.pointclouds.org)
//
//M*/
#ifndef __OPENCV_VIZ_WIDGETS_HPP__
#define __OPENCV_VIZ_WIDGETS_HPP__
#include <opencv2/viz/types.hpp>
namespace cv
{
namespace viz
{
/////////////////////////////////////////////////////////////////////////////
/// Widget rendering properties
enum RenderingProperties
{
POINT_SIZE,
OPACITY,
LINE_WIDTH,
FONT_SIZE,
REPRESENTATION,
IMMEDIATE_RENDERING,
SHADING
};
enum RenderingRepresentationProperties
{
REPRESENTATION_POINTS,
REPRESENTATION_WIREFRAME,
REPRESENTATION_SURFACE
};
enum ShadingRepresentationProperties
{
SHADING_FLAT,
SHADING_GOURAUD,
SHADING_PHONG
};
/////////////////////////////////////////////////////////////////////////////
/// The base class for all widgets
class CV_EXPORTS Widget
{
public:
Widget();
Widget(const Widget& other);
Widget& operator=(const Widget& other);
~Widget();
//! Create a widget directly from ply file
static Widget fromPlyFile(const String &file_name);
//! Rendering properties of this particular widget
void setRenderingProperty(int property, double value);
double getRenderingProperty(int property) const;
//! Casting between widgets
template<typename _W> _W cast();
private:
class Impl;
Impl *impl_;
friend struct WidgetAccessor;
};
/////////////////////////////////////////////////////////////////////////////
/// The base class for all 3D widgets
class CV_EXPORTS Widget3D : public Widget
{
public:
Widget3D() {}
void setPose(const Affine3f &pose);
void updatePose(const Affine3f &pose);
Affine3f getPose() const;
void setColor(const Color &color);
private:
struct MatrixConverter;
};
/////////////////////////////////////////////////////////////////////////////
/// The base class for all 2D widgets
class CV_EXPORTS Widget2D : public Widget
{
public:
Widget2D() {}
void setColor(const Color &color);
};
class CV_EXPORTS WLine : public Widget3D
{
public:
WLine(const Point3f &pt1, const Point3f &pt2, const Color &color = Color::white());
};
class CV_EXPORTS WPlane : public Widget3D
{
public:
WPlane(const Vec4f& coefs, double size = 1.0, const Color &color = Color::white());
WPlane(const Vec4f& coefs, const Point3f& pt, double size = 1.0, const Color &color = Color::white());
private:
struct SetSizeImpl;
};
class CV_EXPORTS WSphere : public Widget3D
{
public:
WSphere(const cv::Point3f &center, float radius, int sphere_resolution = 10, const Color &color = Color::white());
};
class CV_EXPORTS WArrow : public Widget3D
{
public:
WArrow(const Point3f& pt1, const Point3f& pt2, double thickness = 0.03, const Color &color = Color::white());
};
class CV_EXPORTS WCircle : public Widget3D
{
public:
WCircle(const Point3f& pt, double radius, double thickness = 0.01, const Color &color = Color::white());
};
class CV_EXPORTS WCylinder : public Widget3D
{
public:
WCylinder(const Point3f& pt_on_axis, const Point3f& axis_direction, double radius, int numsides = 30, const Color &color = Color::white());
};
class CV_EXPORTS WCube : public Widget3D
{
public:
WCube(const Point3f& pt_min, const Point3f& pt_max, bool wire_frame = true, const Color &color = Color::white());
};
class CV_EXPORTS WCoordinateSystem : public Widget3D
{
public:
WCoordinateSystem(double scale = 1.0);
};
class CV_EXPORTS WPolyLine : public Widget3D
{
public:
WPolyLine(InputArray points, const Color &color = Color::white());
private:
struct CopyImpl;
};
class CV_EXPORTS WGrid : public Widget3D
{
public:
//! Creates grid at the origin
WGrid(const Vec2i &dimensions, const Vec2d &spacing, const Color &color = Color::white());
//! Creates grid based on the plane equation
WGrid(const Vec4f &coeffs, const Vec2i &dimensions, const Vec2d &spacing, const Color &color = Color::white());
private:
struct GridImpl;
};
class CV_EXPORTS WText3D : public Widget3D
{
public:
WText3D(const String &text, const Point3f &position, double text_scale = 1.0, bool face_camera = true, const Color &color = Color::white());
void setText(const String &text);
String getText() const;
};
class CV_EXPORTS WText : public Widget2D
{
public:
WText(const String &text, const Point2i &pos, int font_size = 10, const Color &color = Color::white());
void setText(const String &text);
String getText() const;
};
class CV_EXPORTS WImageOverlay : public Widget2D
{
public:
WImageOverlay(const Mat &image, const Rect &rect);
void setImage(const Mat &image);
};
class CV_EXPORTS WImage3D : public Widget3D
{
public:
//! Creates 3D image at the origin
WImage3D(const Mat &image, const Size &size);
//! Creates 3D image at a given position, pointing in the direction of the normal, and having the up_vector orientation
WImage3D(const Vec3f &position, const Vec3f &normal, const Vec3f &up_vector, const Mat &image, const Size &size);
void setImage(const Mat &image);
};
class CV_EXPORTS WCameraPosition : public Widget3D
{
public:
//! Creates camera coordinate frame (axes) at the origin
WCameraPosition(double scale = 1.0);
//! Creates frustum based on the intrinsic marix K at the origin
WCameraPosition(const Matx33f &K, double scale = 1.0, const Color &color = Color::white());
//! Creates frustum based on the field of view at the origin
WCameraPosition(const Vec2f &fov, double scale = 1.0, const Color &color = Color::white());
//! Creates frustum and display given image at the far plane
WCameraPosition(const Matx33f &K, const Mat &img, double scale = 1.0, const Color &color = Color::white());
//! Creates frustum and display given image at the far plane
WCameraPosition(const Vec2f &fov, const Mat &img, double scale = 1.0, const Color &color = Color::white());
private:
struct ProjectImage;
};
class CV_EXPORTS WTrajectory : public Widget3D
{
public:
enum {DISPLAY_FRAMES = 1, DISPLAY_PATH = 2};
//! Displays trajectory of the given path either by coordinate frames or polyline
WTrajectory(const std::vector<Affine3f> &path, int display_mode = WTrajectory::DISPLAY_PATH, const Color &color = Color::white(), double scale = 1.0);
//! Displays trajectory of the given path by frustums
WTrajectory(const std::vector<Affine3f> &path, const Matx33f &K, double scale = 1.0, const Color &color = Color::white());
//! Displays trajectory of the given path by frustums
WTrajectory(const std::vector<Affine3f> &path, const Vec2f &fov, double scale = 1.0, const Color &color = Color::white());
private:
struct ApplyPath;
};
class CV_EXPORTS WSpheresTrajectory: public Widget3D
{
public:
WSpheresTrajectory(const std::vector<Affine3f> &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 WCloud: public Widget3D
{
public:
//! Each point in cloud is mapped to a color in colors
WCloud(InputArray cloud, InputArray colors);
//! All points in cloud have the same color
WCloud(InputArray cloud, const Color &color = Color::white());
private:
struct CreateCloudWidget;
};
class CV_EXPORTS WCloudCollection : public Widget3D
{
public:
WCloudCollection();
//! Each point in cloud is mapped to a color in colors
void addCloud(InputArray cloud, InputArray colors, const Affine3f &pose = Affine3f::Identity());
//! All points in cloud have the same color
void addCloud(InputArray cloud, const Color &color = Color::white(), const Affine3f &pose = Affine3f::Identity());
private:
struct CreateCloudWidget;
};
class CV_EXPORTS WCloudNormals : public Widget3D
{
public:
WCloudNormals(InputArray cloud, InputArray normals, int level = 100, float scale = 0.02f, const Color &color = Color::white());
private:
struct ApplyCloudNormals;
};
class CV_EXPORTS WMesh : public Widget3D
{
public:
WMesh(const Mesh3d &mesh);
private:
struct CopyImpl;
};
template<> CV_EXPORTS Widget2D Widget::cast<Widget2D>();
template<> CV_EXPORTS Widget3D Widget::cast<Widget3D>();
template<> CV_EXPORTS WLine Widget::cast<WLine>();
template<> CV_EXPORTS WPlane Widget::cast<WPlane>();
template<> CV_EXPORTS WSphere Widget::cast<WSphere>();
template<> CV_EXPORTS WCylinder Widget::cast<WCylinder>();
template<> CV_EXPORTS WArrow Widget::cast<WArrow>();
template<> CV_EXPORTS WCircle Widget::cast<WCircle>();
template<> CV_EXPORTS WCube Widget::cast<WCube>();
template<> CV_EXPORTS WCoordinateSystem Widget::cast<WCoordinateSystem>();
template<> CV_EXPORTS WPolyLine Widget::cast<WPolyLine>();
template<> CV_EXPORTS WGrid Widget::cast<WGrid>();
template<> CV_EXPORTS WText3D Widget::cast<WText3D>();
template<> CV_EXPORTS WText Widget::cast<WText>();
template<> CV_EXPORTS WImageOverlay Widget::cast<WImageOverlay>();
template<> CV_EXPORTS WImage3D Widget::cast<WImage3D>();
template<> CV_EXPORTS WCameraPosition Widget::cast<WCameraPosition>();
template<> CV_EXPORTS WTrajectory Widget::cast<WTrajectory>();
template<> CV_EXPORTS WSpheresTrajectory Widget::cast<WSpheresTrajectory>();
template<> CV_EXPORTS WCloud Widget::cast<WCloud>();
template<> CV_EXPORTS WCloudCollection Widget::cast<WCloudCollection>();
template<> CV_EXPORTS WCloudNormals Widget::cast<WCloudNormals>();
template<> CV_EXPORTS WMesh Widget::cast<WMesh>();
} /* namespace viz */
} /* namespace cv */
#endif

@ -0,0 +1,773 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
// Authors:
// * Ozan Tonkal, ozantonkal@gmail.com
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
//
// OpenCV Viz module is complete rewrite of
// PCL visualization module (www.pointclouds.org)
//
//M*/
#include "precomp.hpp"
namespace cv
{
namespace viz
{
template<typename _Tp> Vec<_Tp, 3>* vtkpoints_data(vtkSmartPointer<vtkPoints>& points);
}
}
///////////////////////////////////////////////////////////////////////////////////////////////
/// Point Cloud Widget implementation
struct cv::viz::WCloud::CreateCloudWidget
{
static inline vtkSmartPointer<vtkPolyData> create(const Mat &cloud, vtkIdType &nr_points)
{
vtkSmartPointer<vtkPolyData> polydata = vtkSmartPointer<vtkPolyData>::New();
vtkSmartPointer<vtkCellArray> vertices = vtkSmartPointer<vtkCellArray>::New();
polydata->SetVerts(vertices);
vtkSmartPointer<vtkPoints> points = polydata->GetPoints();
vtkSmartPointer<vtkIdTypeArray> initcells;
nr_points = cloud.total();
if (!points)
{
points = vtkSmartPointer<vtkPoints>::New();
if (cloud.depth() == CV_32F)
points->SetDataTypeToFloat();
else if (cloud.depth() == CV_64F)
points->SetDataTypeToDouble();
polydata->SetPoints(points);
}
points->SetNumberOfPoints(nr_points);
if (cloud.depth() == CV_32F)
{
// Get a pointer to the beginning of the data array
Vec3f *data_beg = vtkpoints_data<float>(points);
Vec3f *data_end = NanFilter::copy(cloud, data_beg, cloud);
nr_points = data_end - data_beg;
}
else if (cloud.depth() == CV_64F)
{
// Get a pointer to the beginning of the data array
Vec3d *data_beg = vtkpoints_data<double>(points);
Vec3d *data_end = NanFilter::copy(cloud, data_beg, cloud);
nr_points = data_end - data_beg;
}
points->SetNumberOfPoints(nr_points);
// Update cells
vtkSmartPointer<vtkIdTypeArray> cells = vertices->GetData();
// If no init cells and cells has not been initialized...
if (!cells)
cells = vtkSmartPointer<vtkIdTypeArray>::New();
// If we have less values then we need to recreate the array
if (cells->GetNumberOfTuples() < nr_points)
{
cells = vtkSmartPointer<vtkIdTypeArray>::New();
// If init cells is given, and there's enough data in it, use it
if (initcells && initcells->GetNumberOfTuples() >= nr_points)
{
cells->DeepCopy(initcells);
cells->SetNumberOfComponents(2);
cells->SetNumberOfTuples(nr_points);
}
else
{
// If the number of tuples is still too small, we need to recreate the array
cells->SetNumberOfComponents(2);
cells->SetNumberOfTuples(nr_points);
vtkIdType *cell = cells->GetPointer(0);
// Fill it with 1s
std::fill_n(cell, nr_points * 2, 1);
cell++;
for (vtkIdType i = 0; i < nr_points; ++i, cell += 2)
*cell = i;
// Save the results in initcells
initcells = vtkSmartPointer<vtkIdTypeArray>::New();
initcells->DeepCopy(cells);
}
}
else
{
// The assumption here is that the current set of cells has more data than needed
cells->SetNumberOfComponents(2);
cells->SetNumberOfTuples(nr_points);
}
// Set the cells and the vertices
vertices->SetCells(nr_points, cells);
return polydata;
}
};
cv::viz::WCloud::WCloud(InputArray _cloud, InputArray _colors)
{
Mat cloud = _cloud.getMat();
Mat colors = _colors.getMat();
CV_Assert(cloud.type() == CV_32FC3 || cloud.type() == CV_64FC3 || cloud.type() == CV_32FC4 || cloud.type() == CV_64FC4);
CV_Assert(colors.type() == CV_8UC3 && cloud.size() == colors.size());
if (cloud.isContinuous() && colors.isContinuous())
{
cloud.reshape(cloud.channels(), 1);
colors.reshape(colors.channels(), 1);
}
vtkIdType nr_points;
vtkSmartPointer<vtkPolyData> polydata = CreateCloudWidget::create(cloud, nr_points);
// Filter colors
Vec3b* colors_data = new Vec3b[nr_points];
NanFilter::copyColor(colors, colors_data, cloud);
vtkSmartPointer<vtkUnsignedCharArray> scalars = vtkSmartPointer<vtkUnsignedCharArray>::New();
scalars->SetNumberOfComponents(3);
scalars->SetNumberOfTuples(nr_points);
scalars->SetArray(colors_data->val, 3 * nr_points, 0);
// Assign the colors
polydata->GetPointData()->SetScalars(scalars);
vtkSmartPointer<vtkDataSetMapper> mapper = vtkSmartPointer<vtkDataSetMapper>::New();
#if VTK_MAJOR_VERSION <= 5
mapper->SetInput(polydata);
#else
mapper->SetInputData(polydata);
#endif
Vec3d minmax(scalars->GetRange());
mapper->SetScalarRange(minmax.val);
mapper->SetScalarModeToUsePointData();
bool interpolation = (polydata && polydata->GetNumberOfCells() != polydata->GetNumberOfVerts());
mapper->SetInterpolateScalarsBeforeMapping(interpolation);
mapper->ScalarVisibilityOn();
mapper->ImmediateModeRenderingOff();
vtkSmartPointer<vtkLODActor> actor = vtkSmartPointer<vtkLODActor>::New();
actor->SetNumberOfCloudPoints(int(std::max<vtkIdType>(1, polydata->GetNumberOfPoints() / 10)));
actor->GetProperty()->SetInterpolationToFlat();
actor->GetProperty()->BackfaceCullingOn();
actor->SetMapper(mapper);
WidgetAccessor::setProp(*this, actor);
}
cv::viz::WCloud::WCloud(InputArray _cloud, const Color &color)
{
Mat cloud = _cloud.getMat();
CV_Assert(cloud.type() == CV_32FC3 || cloud.type() == CV_64FC3 || cloud.type() == CV_32FC4 || cloud.type() == CV_64FC4);
vtkIdType nr_points;
vtkSmartPointer<vtkPolyData> polydata = CreateCloudWidget::create(cloud, nr_points);
vtkSmartPointer<vtkDataSetMapper> mapper = vtkSmartPointer<vtkDataSetMapper>::New();
#if VTK_MAJOR_VERSION <= 5
mapper->SetInput(polydata);
#else
mapper->SetInputData(polydata);
#endif
bool interpolation = (polydata && polydata->GetNumberOfCells() != polydata->GetNumberOfVerts());
mapper->SetInterpolateScalarsBeforeMapping(interpolation);
mapper->ScalarVisibilityOff();
mapper->ImmediateModeRenderingOff();
vtkSmartPointer<vtkLODActor> actor = vtkSmartPointer<vtkLODActor>::New();
actor->SetNumberOfCloudPoints(int(std::max<vtkIdType>(1, polydata->GetNumberOfPoints() / 10)));
actor->GetProperty()->SetInterpolationToFlat();
actor->GetProperty()->BackfaceCullingOn();
actor->SetMapper(mapper);
WidgetAccessor::setProp(*this, actor);
setColor(color);
}
template<> cv::viz::WCloud cv::viz::Widget::cast<cv::viz::WCloud>()
{
Widget3D widget = this->cast<Widget3D>();
return static_cast<WCloud&>(widget);
}
///////////////////////////////////////////////////////////////////////////////////////////////
/// Cloud Collection Widget implementation
struct cv::viz::WCloudCollection::CreateCloudWidget
{
static inline vtkSmartPointer<vtkPolyData> create(const Mat &cloud, vtkIdType &nr_points)
{
vtkSmartPointer<vtkPolyData> polydata = vtkSmartPointer<vtkPolyData>::New();
vtkSmartPointer<vtkCellArray> vertices = vtkSmartPointer<vtkCellArray>::New();
polydata->SetVerts(vertices);
vtkSmartPointer<vtkPoints> points = polydata->GetPoints();
vtkSmartPointer<vtkIdTypeArray> initcells;
nr_points = cloud.total();
if (!points)
{
points = vtkSmartPointer<vtkPoints>::New();
if (cloud.depth() == CV_32F)
points->SetDataTypeToFloat();
else if (cloud.depth() == CV_64F)
points->SetDataTypeToDouble();
polydata->SetPoints(points);
}
points->SetNumberOfPoints(nr_points);
if (cloud.depth() == CV_32F)
{
// Get a pointer to the beginning of the data array
Vec3f *data_beg = vtkpoints_data<float>(points);
Vec3f *data_end = NanFilter::copy(cloud, data_beg, cloud);
nr_points = data_end - data_beg;
}
else if (cloud.depth() == CV_64F)
{
// Get a pointer to the beginning of the data array
Vec3d *data_beg = vtkpoints_data<double>(points);
Vec3d *data_end = NanFilter::copy(cloud, data_beg, cloud);
nr_points = data_end - data_beg;
}
points->SetNumberOfPoints(nr_points);
// Update cells
vtkSmartPointer<vtkIdTypeArray> cells = vertices->GetData();
// If no init cells and cells has not been initialized...
if (!cells)
cells = vtkSmartPointer<vtkIdTypeArray>::New();
// If we have less values then we need to recreate the array
if (cells->GetNumberOfTuples() < nr_points)
{
cells = vtkSmartPointer<vtkIdTypeArray>::New();
// If init cells is given, and there's enough data in it, use it
if (initcells && initcells->GetNumberOfTuples() >= nr_points)
{
cells->DeepCopy(initcells);
cells->SetNumberOfComponents(2);
cells->SetNumberOfTuples(nr_points);
}
else
{
// If the number of tuples is still too small, we need to recreate the array
cells->SetNumberOfComponents(2);
cells->SetNumberOfTuples(nr_points);
vtkIdType *cell = cells->GetPointer(0);
// Fill it with 1s
std::fill_n(cell, nr_points * 2, 1);
cell++;
for (vtkIdType i = 0; i < nr_points; ++i, cell += 2)
*cell = i;
// Save the results in initcells
initcells = vtkSmartPointer<vtkIdTypeArray>::New();
initcells->DeepCopy(cells);
}
}
else
{
// The assumption here is that the current set of cells has more data than needed
cells->SetNumberOfComponents(2);
cells->SetNumberOfTuples(nr_points);
}
// Set the cells and the vertices
vertices->SetCells(nr_points, cells);
return polydata;
}
static void createMapper(vtkSmartPointer<vtkLODActor> actor, vtkSmartPointer<vtkPolyData> poly_data, Vec3d& minmax)
{
vtkDataSetMapper *mapper = vtkDataSetMapper::SafeDownCast(actor->GetMapper());
if (!mapper)
{
// This is the first cloud
vtkSmartPointer<vtkDataSetMapper> mapper_new = vtkSmartPointer<vtkDataSetMapper>::New();
#if VTK_MAJOR_VERSION <= 5
mapper_new->SetInputConnection(poly_data->GetProducerPort());
#else
mapper_new->SetInputData(poly_data);
#endif
mapper_new->SetScalarRange(minmax.val);
mapper_new->SetScalarModeToUsePointData();
bool interpolation = (poly_data && poly_data->GetNumberOfCells() != poly_data->GetNumberOfVerts());
mapper_new->SetInterpolateScalarsBeforeMapping(interpolation);
mapper_new->ScalarVisibilityOn();
mapper_new->ImmediateModeRenderingOff();
actor->SetNumberOfCloudPoints(int(std::max<vtkIdType>(1, poly_data->GetNumberOfPoints() / 10)));
actor->GetProperty()->SetInterpolationToFlat();
actor->GetProperty()->BackfaceCullingOn();
actor->SetMapper(mapper_new);
return ;
}
vtkPolyData *data = vtkPolyData::SafeDownCast(mapper->GetInput());
CV_Assert("Cloud Widget without data" && data);
vtkSmartPointer<vtkAppendPolyData> appendFilter = vtkSmartPointer<vtkAppendPolyData>::New();
#if VTK_MAJOR_VERSION <= 5
appendFilter->AddInputConnection(mapper->GetInput()->GetProducerPort());
appendFilter->AddInputConnection(poly_data->GetProducerPort());
#else
appendFilter->AddInputData(data);
appendFilter->AddInputData(poly_data);
#endif
mapper->SetInputConnection(appendFilter->GetOutputPort());
// Update the number of cloud points
vtkIdType old_cloud_points = actor->GetNumberOfCloudPoints();
actor->SetNumberOfCloudPoints(int(std::max<vtkIdType>(1, old_cloud_points+poly_data->GetNumberOfPoints() / 10)));
}
};
cv::viz::WCloudCollection::WCloudCollection()
{
// Just create the actor
vtkSmartPointer<vtkLODActor> actor = vtkSmartPointer<vtkLODActor>::New();
WidgetAccessor::setProp(*this, actor);
}
void cv::viz::WCloudCollection::addCloud(InputArray _cloud, InputArray _colors, const Affine3f &pose)
{
Mat cloud = _cloud.getMat();
Mat colors = _colors.getMat();
CV_Assert(cloud.type() == CV_32FC3 || cloud.type() == CV_64FC3 || cloud.type() == CV_32FC4 || cloud.type() == CV_64FC4);
CV_Assert(colors.type() == CV_8UC3 && cloud.size() == colors.size());
if (cloud.isContinuous() && colors.isContinuous())
{
cloud.reshape(cloud.channels(), 1);
colors.reshape(colors.channels(), 1);
}
vtkIdType nr_points;
vtkSmartPointer<vtkPolyData> polydata = CreateCloudWidget::create(cloud, nr_points);
// Filter colors
Vec3b* colors_data = new Vec3b[nr_points];
NanFilter::copyColor(colors, colors_data, cloud);
vtkSmartPointer<vtkUnsignedCharArray> scalars = vtkSmartPointer<vtkUnsignedCharArray>::New();
scalars->SetNumberOfComponents(3);
scalars->SetNumberOfTuples(nr_points);
scalars->SetArray(colors_data->val, 3 * nr_points, 0);
// Assign the colors
polydata->GetPointData()->SetScalars(scalars);
// Transform the poly data based on the pose
vtkSmartPointer<vtkTransform> transform = vtkSmartPointer<vtkTransform>::New();
transform->PreMultiply();
transform->SetMatrix(convertToVtkMatrix(pose.matrix));
vtkSmartPointer<vtkTransformPolyDataFilter> transform_filter = vtkSmartPointer<vtkTransformPolyDataFilter>::New();
transform_filter->SetTransform(transform);
#if VTK_MAJOR_VERSION <= 5
transform_filter->SetInputConnection(polydata->GetProducerPort());
#else
transform_filter->SetInputData(polydata);
#endif
transform_filter->Update();
vtkLODActor *actor = vtkLODActor::SafeDownCast(WidgetAccessor::getProp(*this));
CV_Assert("Incompatible widget type." && actor);
Vec3d minmax(scalars->GetRange());
CreateCloudWidget::createMapper(actor, transform_filter->GetOutput(), minmax);
}
void cv::viz::WCloudCollection::addCloud(InputArray _cloud, const Color &color, const Affine3f &pose)
{
Mat cloud = _cloud.getMat();
CV_Assert(cloud.type() == CV_32FC3 || cloud.type() == CV_64FC3 || cloud.type() == CV_32FC4 || cloud.type() == CV_64FC4);
vtkIdType nr_points;
vtkSmartPointer<vtkPolyData> polydata = CreateCloudWidget::create(cloud, nr_points);
vtkSmartPointer<vtkUnsignedCharArray> scalars = vtkSmartPointer<vtkUnsignedCharArray>::New();
scalars->SetNumberOfComponents(3);
scalars->SetNumberOfTuples(nr_points);
scalars->FillComponent(0, color[2]);
scalars->FillComponent(1, color[1]);
scalars->FillComponent(2, color[0]);
// Assign the colors
polydata->GetPointData()->SetScalars(scalars);
// Transform the poly data based on the pose
vtkSmartPointer<vtkTransform> transform = vtkSmartPointer<vtkTransform>::New();
transform->PreMultiply();
transform->SetMatrix(convertToVtkMatrix(pose.matrix));
vtkSmartPointer<vtkTransformPolyDataFilter> transform_filter = vtkSmartPointer<vtkTransformPolyDataFilter>::New();
transform_filter->SetTransform(transform);
#if VTK_MAJOR_VERSION <= 5
transform_filter->SetInputConnection(polydata->GetProducerPort());
#else
transform_filter->SetInputData(polydata);
#endif
transform_filter->Update();
vtkLODActor *actor = vtkLODActor::SafeDownCast(WidgetAccessor::getProp(*this));
CV_Assert("Incompatible widget type." && actor);
Vec3d minmax(scalars->GetRange());
CreateCloudWidget::createMapper(actor, transform_filter->GetOutput(), minmax);
}
template<> cv::viz::WCloudCollection cv::viz::Widget::cast<cv::viz::WCloudCollection>()
{
Widget3D widget = this->cast<Widget3D>();
return static_cast<WCloudCollection&>(widget);
}
///////////////////////////////////////////////////////////////////////////////////////////////
/// Cloud Normals Widget implementation
struct cv::viz::WCloudNormals::ApplyCloudNormals
{
template<typename _Tp>
struct Impl
{
static vtkSmartPointer<vtkCellArray> applyOrganized(const Mat &cloud, const Mat& normals, double level, float scale, _Tp *&pts, vtkIdType &nr_normals)
{
vtkIdType point_step = static_cast<vtkIdType>(std::sqrt(level));
nr_normals = (static_cast<vtkIdType>((cloud.cols - 1) / point_step) + 1) *
(static_cast<vtkIdType>((cloud.rows - 1) / point_step) + 1);
vtkSmartPointer<vtkCellArray> lines = vtkSmartPointer<vtkCellArray>::New();
pts = new _Tp[2 * nr_normals * 3];
int cch = cloud.channels();
vtkIdType cell_count = 0;
for (vtkIdType y = 0; y < cloud.rows; y += point_step)
{
const _Tp *prow = cloud.ptr<_Tp>(y);
const _Tp *nrow = normals.ptr<_Tp>(y);
for (vtkIdType x = 0; x < cloud.cols; x += point_step * cch)
{
pts[2 * cell_count * 3 + 0] = prow[x];
pts[2 * cell_count * 3 + 1] = prow[x+1];
pts[2 * cell_count * 3 + 2] = prow[x+2];
pts[2 * cell_count * 3 + 3] = prow[x] + nrow[x] * scale;
pts[2 * cell_count * 3 + 4] = prow[x+1] + nrow[x+1] * scale;
pts[2 * cell_count * 3 + 5] = prow[x+2] + nrow[x+2] * scale;
lines->InsertNextCell(2);
lines->InsertCellPoint(2 * cell_count);
lines->InsertCellPoint(2 * cell_count + 1);
cell_count++;
}
}
return lines;
}
static vtkSmartPointer<vtkCellArray> applyUnorganized(const Mat &cloud, const Mat& normals, int level, float scale, _Tp *&pts, vtkIdType &nr_normals)
{
vtkSmartPointer<vtkCellArray> lines = vtkSmartPointer<vtkCellArray>::New();
nr_normals = (cloud.size().area() - 1) / level + 1 ;
pts = new _Tp[2 * nr_normals * 3];
int cch = cloud.channels();
const _Tp *p = cloud.ptr<_Tp>();
const _Tp *n = normals.ptr<_Tp>();
for (vtkIdType i = 0, j = 0; j < nr_normals; j++, i = j * level * cch)
{
pts[2 * j * 3 + 0] = p[i];
pts[2 * j * 3 + 1] = p[i+1];
pts[2 * j * 3 + 2] = p[i+2];
pts[2 * j * 3 + 3] = p[i] + n[i] * scale;
pts[2 * j * 3 + 4] = p[i+1] + n[i+1] * scale;
pts[2 * j * 3 + 5] = p[i+2] + n[i+2] * scale;
lines->InsertNextCell(2);
lines->InsertCellPoint(2 * j);
lines->InsertCellPoint(2 * j + 1);
}
return lines;
}
};
template<typename _Tp>
static inline vtkSmartPointer<vtkCellArray> apply(const Mat &cloud, const Mat& normals, int level, float scale, _Tp *&pts, vtkIdType &nr_normals)
{
if (cloud.cols > 1 && cloud.rows > 1)
return ApplyCloudNormals::Impl<_Tp>::applyOrganized(cloud, normals, level, scale, pts, nr_normals);
else
return ApplyCloudNormals::Impl<_Tp>::applyUnorganized(cloud, normals, level, scale, pts, nr_normals);
}
};
cv::viz::WCloudNormals::WCloudNormals(InputArray _cloud, InputArray _normals, int level, float scale, const Color &color)
{
Mat cloud = _cloud.getMat();
Mat normals = _normals.getMat();
CV_Assert(cloud.type() == CV_32FC3 || cloud.type() == CV_64FC3 || cloud.type() == CV_32FC4 || cloud.type() == CV_64FC4);
CV_Assert(cloud.size() == normals.size() && cloud.type() == normals.type());
vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
vtkSmartPointer<vtkCellArray> lines = vtkSmartPointer<vtkCellArray>::New();
vtkIdType nr_normals = 0;
if (cloud.depth() == CV_32F)
{
points->SetDataTypeToFloat();
vtkSmartPointer<vtkFloatArray> data = vtkSmartPointer<vtkFloatArray>::New();
data->SetNumberOfComponents(3);
float* pts = 0;
lines = ApplyCloudNormals::apply(cloud, normals, level, scale, pts, nr_normals);
data->SetArray(&pts[0], 2 * nr_normals * 3, 0);
points->SetData(data);
}
else
{
points->SetDataTypeToDouble();
vtkSmartPointer<vtkDoubleArray> data = vtkSmartPointer<vtkDoubleArray>::New();
data->SetNumberOfComponents(3);
double* pts = 0;
lines = ApplyCloudNormals::apply(cloud, normals, level, scale, pts, nr_normals);
data->SetArray(&pts[0], 2 * nr_normals * 3, 0);
points->SetData(data);
}
vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
polyData->SetPoints(points);
polyData->SetLines(lines);
vtkSmartPointer<vtkDataSetMapper> mapper = vtkSmartPointer<vtkDataSetMapper>::New();
#if VTK_MAJOR_VERSION <= 5
mapper->SetInput(polyData);
#else
mapper->SetInputData(polyData);
#endif
mapper->SetColorModeToMapScalars();
mapper->SetScalarModeToUsePointData();
vtkSmartPointer<vtkLODActor> actor = vtkSmartPointer<vtkLODActor>::New();
actor->SetMapper(mapper);
WidgetAccessor::setProp(*this, actor);
setColor(color);
}
template<> cv::viz::WCloudNormals cv::viz::Widget::cast<cv::viz::WCloudNormals>()
{
Widget3D widget = this->cast<Widget3D>();
return static_cast<WCloudNormals&>(widget);
}
///////////////////////////////////////////////////////////////////////////////////////////////
/// Mesh Widget implementation
struct cv::viz::WMesh::CopyImpl
{
template<typename _Tp>
static Vec<_Tp, 3> * copy(const Mat &source, Vec<_Tp, 3> *output, int *look_up, const Mat &nan_mask)
{
CV_Assert(DataDepth<_Tp>::value == source.depth() && source.size() == nan_mask.size());
CV_Assert(nan_mask.channels() == 3 || nan_mask.channels() == 4);
CV_DbgAssert(DataDepth<_Tp>::value == nan_mask.depth());
int s_chs = source.channels();
int m_chs = nan_mask.channels();
int index = 0;
const _Tp* srow = source.ptr<_Tp>(0);
const _Tp* mrow = nan_mask.ptr<_Tp>(0);
for (int x = 0; x < source.cols; ++x, srow += s_chs, mrow += m_chs)
{
if (!isNan(mrow[0]) && !isNan(mrow[1]) && !isNan(mrow[2]))
{
look_up[x] = index;
*output++ = Vec<_Tp, 3>(srow);
++index;
}
}
return output;
}
};
cv::viz::WMesh::WMesh(const Mesh3d &mesh)
{
CV_Assert(mesh.cloud.rows == 1 && (mesh.cloud.type() == CV_32FC3 || mesh.cloud.type() == CV_64FC3 || mesh.cloud.type() == CV_32FC4 || mesh.cloud.type() == CV_64FC4));
CV_Assert(mesh.colors.empty() || (mesh.colors.type() == CV_8UC3 && mesh.cloud.size() == mesh.colors.size()));
CV_Assert(!mesh.polygons.empty() && mesh.polygons.type() == CV_32SC1);
vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
vtkIdType nr_points = mesh.cloud.total();
Mat look_up_mat(1, nr_points, CV_32SC1);
int * look_up = look_up_mat.ptr<int>();
points->SetNumberOfPoints(nr_points);
// Copy data from cloud to vtkPoints
if (mesh.cloud.depth() == CV_32F)
{
points->SetDataTypeToFloat();
Vec3f *data_beg = vtkpoints_data<float>(points);
Vec3f *data_end = CopyImpl::copy(mesh.cloud, data_beg, look_up, mesh.cloud);
nr_points = data_end - data_beg;
}
else
{
points->SetDataTypeToDouble();
Vec3d *data_beg = vtkpoints_data<double>(points);
Vec3d *data_end = CopyImpl::copy(mesh.cloud, data_beg, look_up, mesh.cloud);
nr_points = data_end - data_beg;
}
vtkSmartPointer<vtkUnsignedCharArray> scalars;
if (!mesh.colors.empty())
{
Vec3b * colors_data = 0;
colors_data = new Vec3b[nr_points];
NanFilter::copyColor(mesh.colors, colors_data, mesh.cloud);
scalars = vtkSmartPointer<vtkUnsignedCharArray>::New();
scalars->SetNumberOfComponents(3);
scalars->SetNumberOfTuples(nr_points);
scalars->SetArray(colors_data->val, 3 * nr_points, 0);
}
points->SetNumberOfPoints(nr_points);
vtkSmartPointer<vtkPointSet> data;
if (mesh.polygons.size().area() > 1)
{
vtkSmartPointer<vtkCellArray> cell_array = vtkSmartPointer<vtkCellArray>::New();
const int * polygons = mesh.polygons.ptr<int>();
int idx = 0;
int poly_size = mesh.polygons.total();
for (int i = 0; i < poly_size; ++idx)
{
int n_points = polygons[i++];
cell_array->InsertNextCell(n_points);
for (int j = 0; j < n_points; ++j, ++idx)
cell_array->InsertCellPoint(look_up[polygons[i++]]);
}
vtkSmartPointer<vtkPolyData> polydata = vtkSmartPointer<vtkPolyData>::New();
cell_array->GetData()->SetNumberOfValues(idx);
cell_array->Squeeze();
polydata->SetStrips(cell_array);
polydata->SetPoints(points);
if (scalars)
polydata->GetPointData()->SetScalars(scalars);
data = polydata;
}
else
{
// Only one polygon
vtkSmartPointer<vtkPolygon> polygon = vtkSmartPointer<vtkPolygon>::New();
const int * polygons = mesh.polygons.ptr<int>();
int n_points = polygons[0];
polygon->GetPointIds()->SetNumberOfIds(n_points);
for (int j = 1; j < n_points+1; ++j)
polygon->GetPointIds()->SetId(j, look_up[polygons[j]]);
vtkSmartPointer<vtkUnstructuredGrid> poly_grid = vtkSmartPointer<vtkUnstructuredGrid>::New();
poly_grid->Allocate(1, 1);
poly_grid->InsertNextCell(polygon->GetCellType(), polygon->GetPointIds());
poly_grid->SetPoints(points);
if (scalars)
poly_grid->GetPointData()->SetScalars(scalars);
data = poly_grid;
}
vtkSmartPointer<vtkLODActor> actor = vtkSmartPointer<vtkLODActor>::New();
actor->GetProperty()->SetRepresentationToSurface();
actor->GetProperty()->BackfaceCullingOff(); // Backface culling is off for higher efficiency
actor->GetProperty()->SetInterpolationToFlat();
actor->GetProperty()->EdgeVisibilityOff();
actor->GetProperty()->ShadingOff();
vtkSmartPointer<vtkDataSetMapper> mapper = vtkSmartPointer<vtkDataSetMapper>::New();
#if VTK_MAJOR_VERSION <= 5
mapper->SetInput(data);
#else
mapper->SetInputData(data);
#endif
mapper->ImmediateModeRenderingOff();
vtkIdType numberOfCloudPoints = nr_points * 0.1;
actor->SetNumberOfCloudPoints(int(numberOfCloudPoints > 1 ? numberOfCloudPoints : 1));
actor->SetMapper(mapper);
WidgetAccessor::setProp(*this, actor);
}
template<> CV_EXPORTS cv::viz::WMesh cv::viz::Widget::cast<cv::viz::WMesh>()
{
Widget3D widget = this->cast<Widget3D>();
return static_cast<WMesh&>(widget);
}

@ -0,0 +1,717 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
// Authors:
// * Ozan Tonkal, ozantonkal@gmail.com
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
//
// OpenCV Viz module is complete rewrite of
// PCL visualization module (www.pointclouds.org)
//
//M*/
#include "precomp.hpp"
#include "interactor_style.h"
using namespace cv;
//////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::InteractorStyle::Initialize()
{
modifier_ = cv::viz::InteractorStyle::KB_MOD_ALT;
// Set windows size (width, height) to unknown (-1)
win_size_ = Vec2i(-1, -1);
win_pos_ = Vec2i(0, 0);
max_win_size_ = Vec2i(-1, -1);
// Create the image filter and PNG writer objects
wif_ = vtkSmartPointer<vtkWindowToImageFilter>::New();
snapshot_writer_ = vtkSmartPointer<vtkPNGWriter>::New();
snapshot_writer_->SetInputConnection(wif_->GetOutputPort());
init_ = true;
stereo_anaglyph_mask_default_ = true;
// Initialize the keyboard event callback as none
keyboardCallback_ = 0;
keyboard_callback_cookie_ = 0;
// Initialize the mouse event callback as none
mouseCallback_ = 0;
mouse_callback_cookie_ = 0;
}
//////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::InteractorStyle::saveScreenshot(const std::string &file)
{
FindPokedRenderer(Interactor->GetEventPosition()[0], Interactor->GetEventPosition()[1]);
wif_->SetInput(Interactor->GetRenderWindow());
wif_->Modified(); // Update the WindowToImageFilter
snapshot_writer_->Modified();
snapshot_writer_->SetFileName(file.c_str());
snapshot_writer_->Write();
}
//////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::InteractorStyle::zoomIn()
{
FindPokedRenderer(Interactor->GetEventPosition()[0], Interactor->GetEventPosition()[1]);
// Zoom in
StartDolly();
double factor = 10.0 * 0.2 * .5;
Dolly(std::pow(1.1, factor));
EndDolly();
}
//////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::InteractorStyle::zoomOut()
{
FindPokedRenderer(Interactor->GetEventPosition()[0], Interactor->GetEventPosition()[1]);
// Zoom out
StartDolly();
double factor = 10.0 * -0.2 * .5;
Dolly(std::pow(1.1, factor));
EndDolly();
}
//////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::InteractorStyle::OnChar()
{
// Make sure we ignore the same events we handle in OnKeyDown to avoid calling things twice
FindPokedRenderer(Interactor->GetEventPosition()[0], Interactor->GetEventPosition()[1]);
if (Interactor->GetKeyCode() >= '0' && Interactor->GetKeyCode() <= '9')
return;
std::string key(Interactor->GetKeySym());
if (key.find("XF86ZoomIn") != std::string::npos)
zoomIn();
else if (key.find("XF86ZoomOut") != std::string::npos)
zoomOut();
int keymod = false;
switch (modifier_)
{
case KB_MOD_ALT:
{
keymod = Interactor->GetAltKey();
break;
}
case KB_MOD_CTRL:
{
keymod = Interactor->GetControlKey();
break;
}
case KB_MOD_SHIFT:
{
keymod = Interactor->GetShiftKey();
break;
}
}
switch (Interactor->GetKeyCode())
{
// All of the options below simply exit
case 'h': case 'H':
case 'l': case 'L':
case 'p': case 'P':
case 'j': case 'J':
case 'c': case 'C':
case 43: // KEY_PLUS
case 45: // KEY_MINUS
case 'f': case 'F':
case 'g': case 'G':
case 'o': case 'O':
case 'u': case 'U':
case 'q': case 'Q':
{
break;
}
// S and R have a special !ALT case
case 'r': case 'R':
case 's': case 'S':
{
if (!keymod)
Superclass::OnChar();
break;
}
default:
{
Superclass::OnChar();
break;
}
}
}
//////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::InteractorStyle::registerMouseCallback(void (*callback)(const MouseEvent&, void*), void* cookie)
{
// Register the callback function and store the user data
mouseCallback_ = callback;
mouse_callback_cookie_ = cookie;
}
//////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::InteractorStyle::registerKeyboardCallback(void (*callback)(const KeyboardEvent&, void*), void *cookie)
{
// Register the callback function and store the user data
keyboardCallback_ = callback;
keyboard_callback_cookie_ = cookie;
}
//////////////////////////////////////////////////////////////////////////////////////////////
void
cv::viz::InteractorStyle::OnKeyDown()
{
CV_Assert("Interactor style not initialized. Please call Initialize() before continuing" && init_);
CV_Assert("No renderer given! Use SetRendererCollection() before continuing." && renderer_);
FindPokedRenderer(Interactor->GetEventPosition()[0], Interactor->GetEventPosition()[1]);
if (wif_->GetInput() == NULL)
{
wif_->SetInput(Interactor->GetRenderWindow());
wif_->Modified();
snapshot_writer_->Modified();
}
// Save the initial windows width/height
if (win_size_[0] == -1 || win_size_[1] == -1)
win_size_ = Vec2i(Interactor->GetRenderWindow()->GetSize());
// Get the status of special keys (Cltr+Alt+Shift)
bool shift = Interactor->GetShiftKey();
bool ctrl = Interactor->GetControlKey();
bool alt = Interactor->GetAltKey();
bool keymod = false;
switch (modifier_)
{
case KB_MOD_ALT: keymod = alt; break;
case KB_MOD_CTRL: keymod = ctrl; break;
case KB_MOD_SHIFT: keymod = shift; break;
}
std::string key(Interactor->GetKeySym());
if (key.find("XF86ZoomIn") != std::string::npos)
zoomIn();
else if (key.find("XF86ZoomOut") != std::string::npos)
zoomOut();
switch (Interactor->GetKeyCode())
{
case 'h': case 'H':
{
std::cout << "| Help:\n"
"-------\n"
" p, P : switch to a point-based representation\n"
" w, W : switch to a wireframe-based representation (where available)\n"
" s, S : switch to a surface-based representation (where available)\n"
"\n"
" j, J : take a .PNG snapshot of the current window view\n"
" c, C : display current camera/window parameters\n"
" f, F : fly to point mode\n"
"\n"
" e, E : exit the interactor\n"
" q, Q : stop and call VTK's TerminateApp\n"
"\n"
" +/- : increment/decrement overall point size\n"
" +/- [+ ALT] : zoom in/out \n"
"\n"
" r, R [+ ALT] : reset camera [to viewpoint = {0, 0, 0} -> center_{x, y, z}]\n"
"\n"
" ALT + s, S : turn stereo mode on/off\n"
" ALT + f, F : switch between maximized window mode and original size\n"
"\n"
<< std::endl;
break;
}
// Switch representation to points
case 'p': case 'P':
{
vtkSmartPointer<vtkActorCollection> ac = CurrentRenderer->GetActors();
vtkCollectionSimpleIterator ait;
for (ac->InitTraversal(ait); vtkActor* actor = ac->GetNextActor(ait); )
{
for (actor->InitPathTraversal(); vtkAssemblyPath* path = actor->GetNextPath(); )
{
vtkActor* apart = reinterpret_cast <vtkActor*>(path->GetLastNode()->GetViewProp());
apart->GetProperty()->SetRepresentationToPoints();
}
}
break;
}
// Save a PNG snapshot with the current screen
case 'j': case 'J':
{
char cam_fn[80], snapshot_fn[80];
unsigned t = static_cast<unsigned>(time(0));
sprintf(snapshot_fn, "screenshot-%d.png" , t);
saveScreenshot(snapshot_fn);
sprintf(cam_fn, "screenshot-%d.cam", t);
ofstream ofs_cam;
ofs_cam.open(cam_fn);
vtkSmartPointer<vtkCamera> cam = Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->GetActiveCamera();
double clip[2], focal[3], pos[3], view[3];
cam->GetClippingRange(clip);
cam->GetFocalPoint(focal);
cam->GetPosition(pos);
cam->GetViewUp(view);
int *win_pos = Interactor->GetRenderWindow()->GetPosition();
int *win_size = Interactor->GetRenderWindow()->GetSize();
ofs_cam << clip[0] << "," << clip[1] << "/" << focal[0] << "," << focal[1] << "," << focal[2] << "/" <<
pos[0] << "," << pos[1] << "," << pos[2] << "/" << view[0] << "," << view[1] << "," << view[2] << "/" <<
cam->GetViewAngle() / 180.0 * CV_PI << "/" << win_size[0] << "," << win_size[1] << "/" << win_pos[0] << "," << win_pos[1]
<< endl;
ofs_cam.close();
std::cout << "Screenshot (" << snapshot_fn << ") and camera information (" << cam_fn << ") successfully captured." << std::endl;
break;
}
// display current camera settings/parameters
case 'c': case 'C':
{
vtkSmartPointer<vtkCamera> cam = Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->GetActiveCamera();
Vec2d clip;
Vec3d focal, pose, view;
cam->GetClippingRange(clip.val);
cam->GetFocalPoint(focal.val);
cam->GetPosition(pose.val);
cam->GetViewUp(view.val);
Vec2i win_pos(Interactor->GetRenderWindow()->GetPosition());
Vec2i win_size(Interactor->GetRenderWindow()->GetSize());
cv::print(Mat(clip, false).reshape(1, 1));
std::cout << "/";
cv::print(Mat(focal, false).reshape(1, 1));
std::cout << "/";
cv::print(Mat(pose, false).reshape(1, 1));
std::cout << "/";
cv::print(Mat(view, false).reshape(1, 1));
std::cout << "/" << cam->GetViewAngle () / 180.0 * CV_PI;
cv::print(Mat(win_size, false).reshape(1, 1));
std::cout << "/";
cv::print(Mat(win_pos, false).reshape(1, 1));
std::cout << std::endl;
break;
}
case '=':
{
zoomIn();
break;
}
case 43: // KEY_PLUS
{
if (alt)
zoomIn();
else
{
vtkSmartPointer<vtkActorCollection> ac = CurrentRenderer->GetActors();
vtkCollectionSimpleIterator ait;
for (ac->InitTraversal(ait); vtkActor* actor = ac->GetNextActor(ait); )
{
for (actor->InitPathTraversal(); vtkAssemblyPath* path = actor->GetNextPath(); )
{
vtkActor* apart = reinterpret_cast <vtkActor*>(path->GetLastNode()->GetViewProp());
float psize = apart->GetProperty()->GetPointSize();
if (psize < 63.0f)
apart->GetProperty()->SetPointSize(psize + 1.0f);
}
}
}
break;
}
case 45: // KEY_MINUS
{
if (alt)
zoomOut();
else
{
vtkSmartPointer<vtkActorCollection> ac = CurrentRenderer->GetActors();
vtkCollectionSimpleIterator ait;
for (ac->InitTraversal(ait); vtkActor* actor = ac->GetNextActor(ait); )
{
for (actor->InitPathTraversal(); vtkAssemblyPath* path = actor->GetNextPath(); )
{
vtkActor* apart = static_cast<vtkActor*>(path->GetLastNode()->GetViewProp());
float psize = apart->GetProperty()->GetPointSize();
if (psize > 1.0f)
apart->GetProperty()->SetPointSize(psize - 1.0f);
}
}
}
break;
}
// Switch between maximize and original window size
case 'f': case 'F':
{
if (keymod)
{
Vec2i screen_size(Interactor->GetRenderWindow()->GetScreenSize());
Vec2i win_size(Interactor->GetRenderWindow()->GetSize());
// Is window size = max?
if (win_size == max_win_size_)
{
Interactor->GetRenderWindow()->SetSize(win_size_.val);
Interactor->GetRenderWindow()->SetPosition(win_pos_.val);
Interactor->GetRenderWindow()->Render();
Interactor->Render();
}
// Set to max
else
{
win_pos_ = Vec2i(Interactor->GetRenderWindow()->GetPosition());
win_size_ = win_size;
Interactor->GetRenderWindow()->SetSize(screen_size.val);
Interactor->GetRenderWindow()->Render();
Interactor->Render();
max_win_size_ = Vec2i(Interactor->GetRenderWindow()->GetSize());
}
}
else
{
AnimState = VTKIS_ANIM_ON;
vtkAssemblyPath *path = NULL;
Interactor->GetPicker()->Pick(Interactor->GetEventPosition()[0], Interactor->GetEventPosition()[1], 0.0, CurrentRenderer);
vtkAbstractPropPicker *picker;
if ((picker = vtkAbstractPropPicker::SafeDownCast(Interactor->GetPicker())))
path = picker->GetPath();
if (path != NULL)
Interactor->FlyTo(CurrentRenderer, picker->GetPickPosition());
AnimState = VTKIS_ANIM_OFF;
}
break;
}
// 's'/'S' w/out ALT
case 's': case 'S':
{
if (keymod)
{
int stereo_render = Interactor->GetRenderWindow()->GetStereoRender();
if (!stereo_render)
{
if (stereo_anaglyph_mask_default_)
{
Interactor->GetRenderWindow()->SetAnaglyphColorMask(4, 3);
stereo_anaglyph_mask_default_ = false;
}
else
{
Interactor->GetRenderWindow()->SetAnaglyphColorMask(2, 5);
stereo_anaglyph_mask_default_ = true;
}
}
Interactor->GetRenderWindow()->SetStereoRender(!stereo_render);
Interactor->GetRenderWindow()->Render();
Interactor->Render();
}
else
Superclass::OnKeyDown();
break;
}
case 'o': case 'O':
{
vtkSmartPointer<vtkCamera> cam = CurrentRenderer->GetActiveCamera();
int flag = cam->GetParallelProjection();
cam->SetParallelProjection(!flag);
CurrentRenderer->SetActiveCamera(cam);
CurrentRenderer->Render();
break;
}
// Overwrite the camera reset
case 'r': case 'R':
{
if (!keymod)
{
Superclass::OnKeyDown();
break;
}
vtkSmartPointer<vtkCamera> cam = CurrentRenderer->GetActiveCamera();
static WidgetActorMap::iterator it = widget_actor_map_->begin();
// it might be that some actors don't have a valid transformation set -> we skip them to avoid a seg fault.
bool found_transformation = false;
for (size_t idx = 0; idx < widget_actor_map_->size(); ++idx, ++it)
{
if (it == widget_actor_map_->end())
it = widget_actor_map_->begin();
vtkProp3D * actor = vtkProp3D::SafeDownCast(it->second);
if (actor && actor->GetUserMatrix())
{
found_transformation = true;
break;
}
}
// if a valid transformation was found, use it otherwise fall back to default view point.
if (found_transformation)
{
vtkProp3D * actor = vtkProp3D::SafeDownCast(it->second);
cam->SetPosition(actor->GetUserMatrix()->GetElement(0, 3),
actor->GetUserMatrix()->GetElement(1, 3),
actor->GetUserMatrix()->GetElement(2, 3));
cam->SetFocalPoint(actor->GetUserMatrix()->GetElement(0, 3) - actor->GetUserMatrix()->GetElement(0, 2),
actor->GetUserMatrix()->GetElement(1, 3) - actor->GetUserMatrix()->GetElement(1, 2),
actor->GetUserMatrix()->GetElement(2, 3) - actor->GetUserMatrix()->GetElement(2, 2));
cam->SetViewUp(actor->GetUserMatrix()->GetElement(0, 1),
actor->GetUserMatrix()->GetElement(1, 1),
actor->GetUserMatrix()->GetElement(2, 1));
}
else
{
cam->SetPosition(0, 0, 0);
cam->SetFocalPoint(0, 0, 1);
cam->SetViewUp(0, -1, 0);
}
// go to the next actor for the next key-press event.
if (it != widget_actor_map_->end())
++it;
else
it = widget_actor_map_->begin();
CurrentRenderer->SetActiveCamera(cam);
CurrentRenderer->ResetCameraClippingRange();
CurrentRenderer->Render();
break;
}
case 'q': case 'Q':
{
Interactor->ExitCallback();
return;
}
default:
{
Superclass::OnKeyDown();
break;
}
}
KeyboardEvent event(true, Interactor->GetKeySym(), Interactor->GetKeyCode(), Interactor->GetAltKey(), Interactor->GetControlKey(), Interactor->GetShiftKey());
// Check if there is a keyboard callback registered
if (keyboardCallback_)
keyboardCallback_(event, keyboard_callback_cookie_);
renderer_->Render();
Interactor->Render();
}
//////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::InteractorStyle::OnKeyUp()
{
KeyboardEvent event(false, Interactor->GetKeySym(), Interactor->GetKeyCode(), Interactor->GetAltKey(), Interactor->GetControlKey(), Interactor->GetShiftKey());
// Check if there is a keyboard callback registered
if (keyboardCallback_)
keyboardCallback_(event, keyboard_callback_cookie_);
Superclass::OnKeyUp();
}
//////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::InteractorStyle::OnMouseMove()
{
Vec2i p(Interactor->GetEventPosition());
MouseEvent event(MouseEvent::MouseMove, MouseEvent::NoButton, p, Interactor->GetAltKey(), Interactor->GetControlKey(), Interactor->GetShiftKey());
if (mouseCallback_)
mouseCallback_(event, mouse_callback_cookie_);
Superclass::OnMouseMove();
}
//////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::InteractorStyle::OnLeftButtonDown()
{
Vec2i p(Interactor->GetEventPosition());
MouseEvent::Type type = (Interactor->GetRepeatCount() == 0) ? MouseEvent::MouseButtonPress : MouseEvent::MouseDblClick;
MouseEvent event(type, MouseEvent::LeftButton, p, Interactor->GetAltKey(), Interactor->GetControlKey(), Interactor->GetShiftKey());
if (mouseCallback_)
mouseCallback_(event, mouse_callback_cookie_);
Superclass::OnLeftButtonDown();
}
//////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::InteractorStyle::OnLeftButtonUp()
{
Vec2i p(Interactor->GetEventPosition());
MouseEvent event(MouseEvent::MouseButtonRelease, MouseEvent::LeftButton, p, Interactor->GetAltKey(), Interactor->GetControlKey(), Interactor->GetShiftKey());
if (mouseCallback_)
mouseCallback_(event, mouse_callback_cookie_);
Superclass::OnLeftButtonUp();
}
//////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::InteractorStyle::OnMiddleButtonDown()
{
Vec2i p(Interactor->GetEventPosition());
MouseEvent::Type type = (Interactor->GetRepeatCount() == 0) ? MouseEvent::MouseButtonPress : MouseEvent::MouseDblClick;
MouseEvent event(type, MouseEvent::MiddleButton, p, Interactor->GetAltKey(), Interactor->GetControlKey(), Interactor->GetShiftKey());
if (mouseCallback_)
mouseCallback_(event, mouse_callback_cookie_);
Superclass::OnMiddleButtonDown();
}
//////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::InteractorStyle::OnMiddleButtonUp()
{
Vec2i p(Interactor->GetEventPosition());
MouseEvent event(MouseEvent::MouseButtonRelease, MouseEvent::MiddleButton, p, Interactor->GetAltKey(), Interactor->GetControlKey(), Interactor->GetShiftKey());
if (mouseCallback_)
mouseCallback_(event, mouse_callback_cookie_);
Superclass::OnMiddleButtonUp();
}
//////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::InteractorStyle::OnRightButtonDown()
{
Vec2i p(Interactor->GetEventPosition());
MouseEvent::Type type = (Interactor->GetRepeatCount() == 0) ? MouseEvent::MouseButtonPress : MouseEvent::MouseDblClick;
MouseEvent event(type, MouseEvent::RightButton, p, Interactor->GetAltKey(), Interactor->GetControlKey(), Interactor->GetShiftKey());
if (mouseCallback_)
mouseCallback_(event, mouse_callback_cookie_);
Superclass::OnRightButtonDown();
}
//////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::InteractorStyle::OnRightButtonUp()
{
Vec2i p(Interactor->GetEventPosition());
MouseEvent event(MouseEvent::MouseButtonRelease, MouseEvent::RightButton, p, Interactor->GetAltKey(), Interactor->GetControlKey(), Interactor->GetShiftKey());
if (mouseCallback_)
mouseCallback_(event, mouse_callback_cookie_);
Superclass::OnRightButtonUp();
}
//////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::InteractorStyle::OnMouseWheelForward()
{
Vec2i p(Interactor->GetEventPosition());
MouseEvent event(MouseEvent::MouseScrollUp, MouseEvent::VScroll, p, Interactor->GetAltKey(), Interactor->GetControlKey(), Interactor->GetShiftKey());
// If a mouse callback registered, call it!
if (mouseCallback_)
mouseCallback_(event, mouse_callback_cookie_);
if (Interactor->GetRepeatCount() && mouseCallback_)
mouseCallback_(event, mouse_callback_cookie_);
if (Interactor->GetAltKey())
{
// zoom
vtkSmartPointer<vtkCamera> cam = CurrentRenderer->GetActiveCamera();
double opening_angle = cam->GetViewAngle();
if (opening_angle > 15.0)
opening_angle -= 1.0;
cam->SetViewAngle(opening_angle);
cam->Modified();
CurrentRenderer->SetActiveCamera(cam);
CurrentRenderer->ResetCameraClippingRange();
CurrentRenderer->Modified();
CurrentRenderer->Render();
renderer_->Render();
Interactor->Render();
}
else
Superclass::OnMouseWheelForward();
}
//////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::InteractorStyle::OnMouseWheelBackward()
{
Vec2i p(Interactor->GetEventPosition());
MouseEvent event(MouseEvent::MouseScrollDown, MouseEvent::VScroll, p, Interactor->GetAltKey(), Interactor->GetControlKey(), Interactor->GetShiftKey());
// If a mouse callback registered, call it!
if (mouseCallback_)
mouseCallback_(event, mouse_callback_cookie_);
if (Interactor->GetRepeatCount() && mouseCallback_)
mouseCallback_(event, mouse_callback_cookie_);
if (Interactor->GetAltKey())
{
// zoom
vtkSmartPointer<vtkCamera> cam = CurrentRenderer->GetActiveCamera();
double opening_angle = cam->GetViewAngle();
if (opening_angle < 170.0)
opening_angle += 1.0;
cam->SetViewAngle(opening_angle);
cam->Modified();
CurrentRenderer->SetActiveCamera(cam);
CurrentRenderer->ResetCameraClippingRange();
CurrentRenderer->Modified();
CurrentRenderer->Render();
renderer_->Render();
Interactor->Render();
}
else
Superclass::OnMouseWheelBackward();
}
//////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::InteractorStyle::OnTimer()
{
CV_Assert("Interactor style not initialized." && init_);
CV_Assert("Renderer has not been set." && renderer_);
renderer_->Render();
Interactor->Render();
}
namespace cv
{
namespace viz
{
//Standard VTK macro for *New()
vtkStandardNewMacro(InteractorStyle)
}
}

@ -0,0 +1,152 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
// Authors:
// * Ozan Tonkal, ozantonkal@gmail.com
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
//
// OpenCV Viz module is complete rewrite of
// PCL visualization module (www.pointclouds.org)
//
//M*/
#ifndef __OPENCV_VIZ_INTERACTOR_STYLE_H__
#define __OPENCV_VIZ_INTERACTOR_STYLE_H__
#include <opencv2/viz/types.hpp>
namespace cv
{
namespace viz
{
class InteractorStyle : public vtkInteractorStyleTrackballCamera
{
public:
enum KeyboardModifier
{
KB_MOD_ALT,
KB_MOD_CTRL,
KB_MOD_SHIFT
};
static InteractorStyle *New();
InteractorStyle() {}
virtual ~InteractorStyle() {}
// this macro defines Superclass, the isA functionality and the safe downcast method
vtkTypeMacro(InteractorStyle, vtkInteractorStyleTrackballCamera)
/** \brief Initialization routine. Must be called before anything else. */
virtual void Initialize();
inline void setWidgetActorMap(const Ptr<WidgetActorMap>& actors) { widget_actor_map_ = actors; }
void setRenderer(vtkSmartPointer<vtkRenderer>& ren) { renderer_ = ren; }
void registerMouseCallback(void (*callback)(const MouseEvent&, void*), void* cookie = 0);
void registerKeyboardCallback(void (*callback)(const KeyboardEvent&, void*), void * cookie = 0);
void saveScreenshot(const std::string &file);
/** \brief Change the default keyboard modified from ALT to a different special key.*/
inline void setKeyboardModifier(const KeyboardModifier &modifier) { modifier_ = modifier; }
protected:
/** \brief Set to true after initialization is complete. */
bool init_;
/** \brief Collection of vtkRenderers stored internally. */
vtkSmartPointer<vtkRenderer> renderer_;
/** \brief Actor map stored internally. */
cv::Ptr<WidgetActorMap> widget_actor_map_;
/** \brief The current window width/height. */
Vec2i win_size_;
/** \brief The current window position x/y. */
Vec2i win_pos_;
/** \brief The maximum resizeable window width/height. */
Vec2i max_win_size_;
/** \brief A PNG writer for screenshot captures. */
vtkSmartPointer<vtkPNGWriter> snapshot_writer_;
/** \brief Internal window to image filter. Needed by \a snapshot_writer_. */
vtkSmartPointer<vtkWindowToImageFilter> wif_;
/** \brief Interactor style internal method. Gets called whenever a key is pressed. */
virtual void OnChar();
// Keyboard events
virtual void OnKeyDown();
virtual void OnKeyUp();
// mouse button events
virtual void OnMouseMove();
virtual void OnLeftButtonDown();
virtual void OnLeftButtonUp();
virtual void OnMiddleButtonDown();
virtual void OnMiddleButtonUp();
virtual void OnRightButtonDown();
virtual void OnRightButtonUp();
virtual void OnMouseWheelForward();
virtual void OnMouseWheelBackward();
/** \brief Interactor style internal method. Gets called periodically if a timer is set. */
virtual void OnTimer();
void zoomIn();
void zoomOut();
/** \brief True if we're using red-blue colors for anaglyphic stereo, false if magenta-green. */
bool stereo_anaglyph_mask_default_;
KeyboardModifier modifier_;
void (*keyboardCallback_)(const KeyboardEvent&, void*);
void *keyboard_callback_cookie_;
void (*mouseCallback_)(const MouseEvent&, void*);
void *mouse_callback_cookie_;
};
}
}
#endif

@ -0,0 +1,49 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
// Authors:
// * Ozan Tonkal, ozantonkal@gmail.com
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
//
// OpenCV Viz module is complete rewrite of
// PCL visualization module (www.pointclouds.org)
//
//M*/
#include "precomp.hpp"

@ -0,0 +1,154 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
// Authors:
// * Ozan Tonkal, ozantonkal@gmail.com
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
//
// OpenCV Viz module is complete rewrite of
// PCL visualization module (www.pointclouds.org)
//
//M*/
#ifndef __OPENCV_VIZ_PRECOMP_HPP__
#define __OPENCV_VIZ_PRECOMP_HPP__
#include <map>
#include <ctime>
#include <list>
#include <vector>
#if defined __GNUC__
#pragma GCC system_header
#ifdef __DEPRECATED
#undef __DEPRECATED
#define __DEPRECATED_DISABLED__
#endif
#endif
#include <vtkAppendPolyData.h>
#include <vtkAssemblyPath.h>
#include <vtkCellData.h>
#include <vtkLineSource.h>
#include <vtkPropPicker.h>
#include <vtkSmartPointer.h>
#include <vtkDataSet.h>
#include <vtkPolygon.h>
#include <vtkPointPicker.h>
#include <vtkUnstructuredGrid.h>
#include <vtkDiskSource.h>
#include <vtkPlaneSource.h>
#include <vtkSphereSource.h>
#include <vtkArrowSource.h>
#include <vtkOutlineSource.h>
#include <vtkTransform.h>
#include <vtkTransformPolyDataFilter.h>
#include <vtkTubeFilter.h>
#include <vtkCubeSource.h>
#include <vtkAxes.h>
#include <vtkFloatArray.h>
#include <vtkDoubleArray.h>
#include <vtkPointData.h>
#include <vtkPolyData.h>
#include <vtkPolyDataReader.h>
#include <vtkPolyDataMapper.h>
#include <vtkDataSetMapper.h>
#include <vtkCellArray.h>
#include <vtkCommand.h>
#include <vtkPLYReader.h>
#include <vtkPolyLine.h>
#include <vtkVectorText.h>
#include <vtkFollower.h>
#include <vtkInteractorStyle.h>
#include <vtkUnsignedCharArray.h>
#include <vtkRendererCollection.h>
#include <vtkPNGWriter.h>
#include <vtkWindowToImageFilter.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkProperty.h>
#include <vtkCamera.h>
#include <vtkObjectFactory.h>
#include <vtkPlanes.h>
#include <vtkImageViewer.h>
#include <vtkImageFlip.h>
#include <vtkRenderWindow.h>
#include <vtkTextProperty.h>
#include <vtkProperty2D.h>
#include <vtkLODActor.h>
#include <vtkTextActor.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkMath.h>
#include <vtkExtractEdges.h>
#include <vtkFrustumSource.h>
#include <vtkTextureMapToPlane.h>
#include <vtkPolyDataNormals.h>
#include <vtkAlgorithmOutput.h>
#if defined __GNUC__ && defined __DEPRECATED_DISABLED__
#define __DEPRECATED
#undef __DEPRECATED_DISABLED__
#endif
#include <opencv2/ts.hpp>
#include <opencv2/core.hpp>
namespace cv
{
namespace viz
{
typedef std::map<String, vtkSmartPointer<vtkProp> > WidgetActorMap;
}
}
#include "viz3d_impl.hpp"
namespace cv
{
namespace viz
{
typedef std::map<String, Viz3d> VizMap;
typedef std::pair<String, Viz3d> VizPair;
}
}
#include <opencv2/viz.hpp>
#include <opencv2/viz/types.hpp>
#include "opencv2/viz/widget_accessor.hpp"
#endif

File diff suppressed because it is too large Load Diff

@ -0,0 +1,310 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
// Authors:
// * Ozan Tonkal, ozantonkal@gmail.com
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
//
// OpenCV Viz module is complete rewrite of
// PCL visualization module (www.pointclouds.org)
//
//M*/
#include "precomp.hpp"
//////////////////////////////////////////////////////////////////////////////////////////////////////
/// cv::viz::Color
cv::viz::Color::Color() : Scalar(0, 0, 0) {}
cv::viz::Color::Color(double gray) : Scalar(gray, gray, gray) {}
cv::viz::Color::Color(double blue, double green, double red) : Scalar(blue, green, red) {}
cv::viz::Color::Color(const Scalar& color) : Scalar(color) {}
cv::viz::Color cv::viz::Color::black() { return Color( 0, 0, 0); }
cv::viz::Color cv::viz::Color::green() { return Color( 0, 255, 0); }
cv::viz::Color cv::viz::Color::blue() { return Color(255, 0, 0); }
cv::viz::Color cv::viz::Color::cyan() { return Color(255, 255, 0); }
cv::viz::Color cv::viz::Color::red() { return Color( 0, 0, 255); }
cv::viz::Color cv::viz::Color::yellow() { return Color( 0, 255, 255); }
cv::viz::Color cv::viz::Color::magenta() { return Color(255, 0, 255); }
cv::viz::Color cv::viz::Color::white() { return Color(255, 255, 255); }
cv::viz::Color cv::viz::Color::gray() { return Color(128, 128, 128); }
////////////////////////////////////////////////////////////////////
/// cv::viz::KeyboardEvent
cv::viz::KeyboardEvent::KeyboardEvent(bool _action, const String& _key_sym, unsigned char key, bool alt, bool ctrl, bool shift)
: action_(_action), modifiers_(0), key_code_(key), key_sym_(_key_sym)
{
if (alt)
modifiers_ = Alt;
if (ctrl)
modifiers_ |= Ctrl;
if (shift)
modifiers_ |= Shift;
}
bool cv::viz::KeyboardEvent::isAltPressed() const { return (modifiers_ & Alt) != 0; }
bool cv::viz::KeyboardEvent::isCtrlPressed() const { return (modifiers_ & Ctrl) != 0; }
bool cv::viz::KeyboardEvent::isShiftPressed() const { return (modifiers_ & Shift) != 0; }
unsigned char cv::viz::KeyboardEvent::getKeyCode() const { return key_code_; }
const cv::String& cv::viz::KeyboardEvent::getKeySym() const { return key_sym_; }
bool cv::viz::KeyboardEvent::keyDown() const { return action_; }
bool cv::viz::KeyboardEvent::keyUp() const { return !action_; }
////////////////////////////////////////////////////////////////////
/// cv::viz::MouseEvent
cv::viz::MouseEvent::MouseEvent(const Type& _type, const MouseButton& _button, const Point& _p, bool alt, bool ctrl, bool shift)
: type(_type), button(_button), pointer(_p), key_state(0)
{
if (alt)
key_state = KeyboardEvent::Alt;
if (ctrl)
key_state |= KeyboardEvent::Ctrl;
if (shift)
key_state |= KeyboardEvent::Shift;
}
////////////////////////////////////////////////////////////////////
/// cv::viz::Mesh3d
struct cv::viz::Mesh3d::loadMeshImpl
{
static cv::viz::Mesh3d loadMesh(const String &file)
{
Mesh3d mesh;
vtkSmartPointer<vtkPLYReader> reader = vtkSmartPointer<vtkPLYReader>::New();
reader->SetFileName(file.c_str());
reader->Update();
vtkSmartPointer<vtkPolyData> poly_data = reader->GetOutput();
CV_Assert("File does not exist or file format is not supported." && poly_data);
vtkSmartPointer<vtkPoints> mesh_points = poly_data->GetPoints();
vtkIdType nr_points = mesh_points->GetNumberOfPoints();
mesh.cloud.create(1, nr_points, CV_32FC3);
Vec3f *mesh_cloud = mesh.cloud.ptr<Vec3f>();
for (vtkIdType i = 0; i < mesh_points->GetNumberOfPoints(); i++)
{
Vec3d point;
mesh_points->GetPoint(i, point.val);
mesh_cloud[i] = point;
}
// Then the color information, if any
vtkUnsignedCharArray* poly_colors = 0;
if (poly_data->GetPointData())
poly_colors = vtkUnsignedCharArray::SafeDownCast(poly_data->GetPointData()->GetScalars());
if (poly_colors && (poly_colors->GetNumberOfComponents() == 3))
{
mesh.colors.create(1, nr_points, CV_8UC3);
Vec3b *mesh_colors = mesh.colors.ptr<cv::Vec3b>();
for (vtkIdType i = 0; i < mesh_points->GetNumberOfPoints(); i++)
{
Vec3b point_color;
poly_colors->GetTupleValue(i, point_color.val);
std::swap(point_color[0], point_color[2]); // RGB -> BGR
mesh_colors[i] = point_color;
}
}
else
mesh.colors.release();
// Now handle the polygons
vtkIdType* cell_points;
vtkIdType nr_cell_points;
vtkCellArray * mesh_polygons = poly_data->GetPolys();
mesh_polygons->InitTraversal();
mesh.polygons.create(1, mesh_polygons->GetSize(), CV_32SC1);
int* polygons = mesh.polygons.ptr<int>();
while (mesh_polygons->GetNextCell(nr_cell_points, cell_points))
{
*polygons++ = nr_cell_points;
for (int i = 0; i < nr_cell_points; ++i)
*polygons++ = static_cast<int>(cell_points[i]);
}
return mesh;
}
};
cv::viz::Mesh3d cv::viz::Mesh3d::loadMesh(const String& file)
{
return loadMeshImpl::loadMesh(file);
}
////////////////////////////////////////////////////////////////////
/// Camera implementation
cv::viz::Camera::Camera(float f_x, float f_y, float c_x, float c_y, const Size &window_size)
{
init(f_x, f_y, c_x, c_y, 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
setFov(fov);
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)
{
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);
}
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);
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;
double epsilon = 2.2204460492503131e-16;
if (fabs(left-right) < epsilon) principal_point_[0] = static_cast<float>(window_size.width) * 0.5f;
else principal_point_[0] = (left * static_cast<float>(window_size.width)) / (left - right);
focal_[0] = -near * principal_point_[0] / left;
if (fabs(top-bottom) < epsilon) principal_point_[1] = static_cast<float>(window_size.height) * 0.5f;
else principal_point_[1] = (top * static_cast<float>(window_size.height)) / (top - bottom);
focal_[1] = near * principal_point_[1] / top;
setClip(Vec2d(near, far));
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]));
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)
{
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));
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;
focal_[0] = f_x;
focal_[1] = f_y;
window_size_ = window_size;
}
void cv::viz::Camera::setWindowSize(const Size &window_size)
{
CV_Assert(window_size.width > 0 && window_size.height > 0);
// Get the scale factor and update the principal points
float scalex = static_cast<float>(window_size.width) / static_cast<float>(window_size_.width);
float scaley = static_cast<float>(window_size.height) / static_cast<float>(window_size_.height);
principal_point_[0] *= scalex;
principal_point_[1] *= scaley;
focal_ *= scaley;
// Vertical field of view is fixed! Update horizontal field of view
fov_[0] = (atan2(principal_point_[0],focal_[0]) + atan2(window_size.width-principal_point_[0],focal_[0]));
window_size_ = window_size;
}
void cv::viz::Camera::computeProjectionMatrix(Matx44f &proj) const
{
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);
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;
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;
}
cv::viz::Camera cv::viz::Camera::KinectCamera(const Size &window_size)
{
// 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;
K(1,1) = 5.2556393630057437e+02;
K(1,2) = 2.6748068171871557e+02;
K(2,2) = 1.0f;
return Camera(K, window_size);
}

@ -0,0 +1,227 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
// Authors:
// * Ozan Tonkal, ozantonkal@gmail.com
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
//
// OpenCV Viz module is complete rewrite of
// PCL visualization module (www.pointclouds.org)
//
//M*/
#include "precomp.hpp"
cv::Affine3f cv::viz::makeTransformToGlobal(const Vec3f& axis_x, const Vec3f& axis_y, const Vec3f& axis_z, const Vec3f& origin)
{
Affine3f::Mat3 R;
R.val[0] = axis_x.val[0];
R.val[3] = axis_x.val[1];
R.val[6] = axis_x.val[2];
R.val[1] = axis_y.val[0];
R.val[4] = axis_y.val[1];
R.val[7] = axis_y.val[2];
R.val[2] = axis_z.val[0];
R.val[5] = axis_z.val[1];
R.val[8] = axis_z.val[2];
return Affine3f(R, origin);
}
cv::Affine3f cv::viz::makeCameraPose(const Vec3f& position, const Vec3f& focal_point, const Vec3f& y_dir)
{
// Compute the transformation matrix for drawing the camera frame in a scene
Vec3f n = normalize(focal_point - position);
Vec3f u = normalize(y_dir.cross(n));
Vec3f v = n.cross(u);
Matx44f pose_mat = Matx44f::zeros();
pose_mat(0,0) = u[0];
pose_mat(0,1) = u[1];
pose_mat(0,2) = u[2];
pose_mat(1,0) = v[0];
pose_mat(1,1) = v[1];
pose_mat(1,2) = v[2];
pose_mat(2,0) = n[0];
pose_mat(2,1) = n[1];
pose_mat(2,2) = n[2];
pose_mat(3,0) = position[0];
pose_mat(3,1) = position[1];
pose_mat(3,2) = position[2];
pose_mat(3,3) = 1.0f;
pose_mat = pose_mat.t();
return pose_mat;
}
vtkSmartPointer<vtkMatrix4x4> cv::viz::convertToVtkMatrix(const cv::Matx44f &m)
{
vtkSmartPointer<vtkMatrix4x4> vtk_matrix = vtkSmartPointer<vtkMatrix4x4>::New();
for (int i = 0; i < 4; i++)
for (int k = 0; k < 4; k++)
vtk_matrix->SetElement(i, k, m(i, k));
return vtk_matrix;
}
cv::Matx44f cv::viz::convertToMatx(const vtkSmartPointer<vtkMatrix4x4>& vtk_matrix)
{
cv::Matx44f m;
for (int i = 0; i < 4; i++)
for (int k = 0; k < 4; k++)
m(i, k) = vtk_matrix->GetElement(i, k);
return m;
}
namespace cv
{
namespace viz
{
template<typename _Tp> Vec<_Tp, 3>* vtkpoints_data(vtkSmartPointer<vtkPoints>& points);
template<> Vec3f* vtkpoints_data<float>(vtkSmartPointer<vtkPoints>& points)
{
CV_Assert(points->GetDataType() == VTK_FLOAT);
vtkDataArray *data = points->GetData();
float *pointer = static_cast<vtkFloatArray*>(data)->GetPointer(0);
return reinterpret_cast<Vec3f*>(pointer);
}
template<> Vec3d* vtkpoints_data<double>(vtkSmartPointer<vtkPoints>& points)
{
CV_Assert(points->GetDataType() == VTK_DOUBLE);
vtkDataArray *data = points->GetData();
double *pointer = static_cast<vtkDoubleArray*>(data)->GetPointer(0);
return reinterpret_cast<Vec3d*>(pointer);
}
}
}
///////////////////////////////////////////////////////////////////////////////////////////////
/// Viz accessor implementation
cv::viz::VizAccessor * cv::viz::VizAccessor::instance_ = 0;
bool cv::viz::VizAccessor::is_instantiated_ = false;
cv::viz::VizAccessor::VizAccessorImpl * cv::viz::VizAccessor::impl_ = 0;
struct cv::viz::VizAccessor::VizAccessorImpl
{
cv::viz::VizMap viz_map;
};
cv::viz::VizAccessor::VizAccessor() { impl_ = new cv::viz::VizAccessor::VizAccessorImpl;}
cv::viz::VizAccessor::~VizAccessor()
{
if(impl_)
{
delete impl_;
impl_ = 0;
}
}
cv::viz::VizAccessor & cv::viz::VizAccessor::getInstance()
{
if (!is_instantiated_)
{
instance_ = new VizAccessor();
is_instantiated_ = true;
}
return *instance_;
}
void cv::viz::VizAccessor::release()
{
if (is_instantiated_)
{
delete instance_;
instance_ = 0;
is_instantiated_ = false;
}
}
cv::viz::Viz3d cv::viz::VizAccessor::get(const String & window_name)
{
// Add the prefix Viz
String name;
generateWindowName(window_name, name);
VizMap::iterator vm_itr = impl_->viz_map.find(name);
bool exists = vm_itr != impl_->viz_map.end();
if (exists) return vm_itr->second;
else return Viz3d(window_name);
}
void cv::viz::VizAccessor::add(Viz3d window)
{
String window_name = window.getWindowName();
VizMap::iterator vm_itr = impl_->viz_map.find(window_name);
bool exists = vm_itr != impl_->viz_map.end();
if (exists) return ;
impl_->viz_map.insert(VizPair(window_name, window));
}
void cv::viz::VizAccessor::remove(const String &window_name)
{
// Add the prefix Viz
String name;
generateWindowName(window_name, name);
VizMap::iterator vm_itr = impl_->viz_map.find(name);
bool exists = vm_itr != impl_->viz_map.end();
if (!exists) return ;
impl_->viz_map.erase(vm_itr);
}
void cv::viz::VizAccessor::generateWindowName(const String &window_name, String &output)
{
output = "Viz";
// Already is Viz
if (window_name == output) return;
String prefixed = output + " - ";
if (window_name.substr(0, prefixed.length()) == prefixed) output = window_name; // Already has "Viz - "
else if (window_name.substr(0, output.length()) == output) output = prefixed + window_name; // Doesn't have prefix
else output = (window_name == "" ? output : prefixed + window_name);
}
cv::viz::Viz3d cv::viz::get(const String &window_name)
{
return cv::viz::VizAccessor::getInstance().get(window_name);
}

@ -0,0 +1,137 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
// Authors:
// * Ozan Tonkal, ozantonkal@gmail.com
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
//
// OpenCV Viz module is complete rewrite of
// PCL visualization module (www.pointclouds.org)
//
//M*/
#include <opencv2/viz/viz3d.hpp>
#include "viz3d_impl.hpp"
cv::viz::Viz3d::Viz3d(const String& window_name) : impl_(0) { create(window_name); }
cv::viz::Viz3d::Viz3d(const Viz3d& other) : impl_(other.impl_)
{
if (impl_) CV_XADD(&impl_->ref_counter, 1);
}
cv::viz::Viz3d& cv::viz::Viz3d::operator=(const Viz3d& other)
{
if (this != &other)
{
release();
impl_ = other.impl_;
if (impl_) CV_XADD(&impl_->ref_counter, 1);
}
return *this;
}
cv::viz::Viz3d::~Viz3d() { release(); }
void cv::viz::Viz3d::create(const String &window_name)
{
if (impl_) release();
impl_ = new VizImpl(window_name);
impl_->ref_counter = 1;
// Register the window
cv::viz::VizAccessor::getInstance().add(*this);
}
void cv::viz::Viz3d::release()
{
// If the current referene count is equal to 2, we can delete it
// - 2 : because minimum there will be two instances, one of which is in the map
if (impl_ && CV_XADD(&impl_->ref_counter, -1) == 2)
{
// Erase the window
cv::viz::VizAccessor::getInstance().remove(getWindowName());
delete impl_;
impl_ = 0;
}
}
void cv::viz::Viz3d::spin() { impl_->spin(); }
void cv::viz::Viz3d::spinOnce(int time, bool force_redraw) { impl_->spinOnce(time, force_redraw); }
bool cv::viz::Viz3d::wasStopped() const { return impl_->wasStopped(); }
void cv::viz::Viz3d::registerKeyboardCallback(KeyboardCallback callback, void* cookie)
{ impl_->registerKeyboardCallback(callback, cookie); }
void cv::viz::Viz3d::registerMouseCallback(MouseCallback callback, void* cookie)
{ impl_->registerMouseCallback(callback, cookie); }
void cv::viz::Viz3d::showWidget(const String &id, const Widget &widget, const Affine3f &pose) { impl_->showWidget(id, widget, pose); }
void cv::viz::Viz3d::removeWidget(const String &id) { impl_->removeWidget(id); }
cv::viz::Widget cv::viz::Viz3d::getWidget(const String &id) const { return impl_->getWidget(id); }
void cv::viz::Viz3d::removeAllWidgets() { impl_->removeAllWidgets(); }
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::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(); }
void cv::viz::Viz3d::resetCameraViewpoint(const String &id) { impl_->resetCameraViewpoint(id); }
void cv::viz::Viz3d::resetCamera() { impl_->resetCamera(); }
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); }
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); }
cv::String cv::viz::Viz3d::getWindowName() const { return impl_->getWindowName(); }
void cv::viz::Viz3d::saveScreenshot(const String &file) { impl_->saveScreenshot(file); }
void cv::viz::Viz3d::setWindowPosition(int x, int y) { impl_->setWindowPosition(x,y); }
void cv::viz::Viz3d::setFullScreen(bool mode) { impl_->setFullScreen(mode); }
void cv::viz::Viz3d::setBackgroundColor(const Color& color) { impl_->setBackgroundColor(color); }
void cv::viz::Viz3d::setRenderingProperty(const String &id, int property, double value) { getWidget(id).setRenderingProperty(property, value); }
double cv::viz::Viz3d::getRenderingProperty(const String &id, int property) { return getWidget(id).getRenderingProperty(property); }
void cv::viz::Viz3d::setDesiredUpdateRate(double rate) { impl_->setDesiredUpdateRate(rate); }
double cv::viz::Viz3d::getDesiredUpdateRate() { return impl_->getDesiredUpdateRate(); }
void cv::viz::Viz3d::setRepresentation(int representation) { impl_->setRepresentation(representation); }

@ -0,0 +1,608 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
// Authors:
// * Ozan Tonkal, ozantonkal@gmail.com
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
//
// OpenCV Viz module is complete rewrite of
// PCL visualization module (www.pointclouds.org)
//
//M*/
#include "precomp.hpp"
#include "viz3d_impl.hpp"
#include <vtkRenderWindowInteractor.h>
#if 1 || !defined __APPLE__
vtkRenderWindowInteractor* vtkRenderWindowInteractorFixNew()
{
return vtkRenderWindowInteractor::New();
}
#endif
/////////////////////////////////////////////////////////////////////////////////////////////
cv::viz::Viz3d::VizImpl::VizImpl(const String &name)
: style_(vtkSmartPointer<cv::viz::InteractorStyle>::New())
, widget_actor_map_(new WidgetActorMap)
, s_lastDone_(0.0)
{
renderer_ = vtkSmartPointer<vtkRenderer>::New();
// Create a RendererWindow
window_ = vtkSmartPointer<vtkRenderWindow>::New();
// Set the window size as 1/2 of the screen size
cv::Vec2i window_size = cv::Vec2i(window_->GetScreenSize()) / 2;
window_->SetSize(window_size.val);
window_->AddRenderer(renderer_);
// Create the interactor style
style_->Initialize();
style_->setRenderer(renderer_);
style_->setWidgetActorMap(widget_actor_map_);
style_->UseTimersOn();
/////////////////////////////////////////////////
interactor_ = vtkSmartPointer <vtkRenderWindowInteractor>::Take(vtkRenderWindowInteractorFixNew());
window_->AlphaBitPlanesOff();
window_->PointSmoothingOff();
window_->LineSmoothingOff();
window_->PolygonSmoothingOff();
window_->SwapBuffersOn();
window_->SetStereoTypeToAnaglyph();
interactor_->SetRenderWindow(window_);
interactor_->SetInteractorStyle(style_);
interactor_->SetDesiredUpdateRate(30.0);
// Initialize and create timer, also create window
interactor_->Initialize();
timer_id_ = interactor_->CreateRepeatingTimer(5000L);
// Set a simple PointPicker
vtkSmartPointer<vtkPointPicker> pp = vtkSmartPointer<vtkPointPicker>::New();
pp->SetTolerance(pp->GetTolerance() * 2);
interactor_->SetPicker(pp);
exit_main_loop_timer_callback_ = vtkSmartPointer<ExitMainLoopTimerCallback>::New();
exit_main_loop_timer_callback_->viz_ = this;
exit_main_loop_timer_callback_->right_timer_id = -1;
interactor_->AddObserver(vtkCommand::TimerEvent, exit_main_loop_timer_callback_);
exit_callback_ = vtkSmartPointer<ExitCallback>::New();
exit_callback_->viz_ = this;
interactor_->AddObserver(vtkCommand::ExitEvent, exit_callback_);
resetStoppedFlag();
//////////////////////////////
String window_name;
VizAccessor::generateWindowName(name, window_name);
window_->SetWindowName(window_name.c_str());
}
/////////////////////////////////////////////////////////////////////////////////////////////
cv::viz::Viz3d::VizImpl::~VizImpl()
{
if (interactor_)
interactor_->DestroyTimer(timer_id_);
if (renderer_) renderer_->Clear();
}
/////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::Viz3d::VizImpl::showWidget(const String &id, const Widget &widget, const Affine3f &pose)
{
WidgetActorMap::iterator wam_itr = widget_actor_map_->find(id);
bool exists = wam_itr != widget_actor_map_->end();
if (exists)
{
// Remove it if it exists and add it again
removeActorFromRenderer(wam_itr->second);
}
// Get the actor and set the user matrix
vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getProp(widget));
if (actor)
{
// If the actor is 3D, apply pose
vtkSmartPointer<vtkMatrix4x4> matrix = convertToVtkMatrix(pose.matrix);
actor->SetUserMatrix(matrix);
actor->Modified();
}
// If the actor is a vtkFollower, then it should always face the camera
vtkFollower *follower = vtkFollower::SafeDownCast(actor);
if (follower)
{
follower->SetCamera(renderer_->GetActiveCamera());
}
renderer_->AddActor(WidgetAccessor::getProp(widget));
(*widget_actor_map_)[id] = WidgetAccessor::getProp(widget);
}
/////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::Viz3d::VizImpl::removeWidget(const String &id)
{
WidgetActorMap::iterator wam_itr = widget_actor_map_->find(id);
bool exists = wam_itr != widget_actor_map_->end();
CV_Assert("Widget does not exist." && exists);
CV_Assert("Widget could not be removed." && removeActorFromRenderer(wam_itr->second));
widget_actor_map_->erase(wam_itr);
}
/////////////////////////////////////////////////////////////////////////////////////////////
cv::viz::Widget cv::viz::Viz3d::VizImpl::getWidget(const String &id) const
{
WidgetActorMap::const_iterator wam_itr = widget_actor_map_->find(id);
bool exists = wam_itr != widget_actor_map_->end();
CV_Assert("Widget does not exist." && exists);
Widget widget;
WidgetAccessor::setProp(widget, wam_itr->second);
return widget;
}
/////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::Viz3d::VizImpl::setWidgetPose(const String &id, const Affine3f &pose)
{
WidgetActorMap::iterator wam_itr = widget_actor_map_->find(id);
bool exists = wam_itr != widget_actor_map_->end();
CV_Assert("Widget does not exist." && exists);
vtkProp3D *actor = vtkProp3D::SafeDownCast(wam_itr->second);
CV_Assert("Widget is not 3D." && actor);
vtkSmartPointer<vtkMatrix4x4> matrix = convertToVtkMatrix(pose.matrix);
actor->SetUserMatrix(matrix);
actor->Modified();
}
/////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::Viz3d::VizImpl::updateWidgetPose(const String &id, const Affine3f &pose)
{
WidgetActorMap::iterator wam_itr = widget_actor_map_->find(id);
bool exists = wam_itr != widget_actor_map_->end();
CV_Assert("Widget does not exist." && exists);
vtkProp3D *actor = vtkProp3D::SafeDownCast(wam_itr->second);
CV_Assert("Widget is not 3D." && actor);
vtkSmartPointer<vtkMatrix4x4> matrix = actor->GetUserMatrix();
if (!matrix)
{
setWidgetPose(id, pose);
return ;
}
Matx44f matrix_cv = convertToMatx(matrix);
Affine3f updated_pose = pose * Affine3f(matrix_cv);
matrix = convertToVtkMatrix(updated_pose.matrix);
actor->SetUserMatrix(matrix);
actor->Modified();
}
/////////////////////////////////////////////////////////////////////////////////////////////
cv::Affine3f cv::viz::Viz3d::VizImpl::getWidgetPose(const String &id) const
{
WidgetActorMap::const_iterator wam_itr = widget_actor_map_->find(id);
bool exists = wam_itr != widget_actor_map_->end();
CV_Assert("Widget does not exist." && exists);
vtkProp3D *actor = vtkProp3D::SafeDownCast(wam_itr->second);
CV_Assert("Widget is not 3D." && actor);
vtkSmartPointer<vtkMatrix4x4> matrix = actor->GetUserMatrix();
Matx44f matrix_cv = convertToMatx(matrix);
return Affine3f(matrix_cv);
}
/////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::Viz3d::VizImpl::setDesiredUpdateRate(double rate)
{
if (interactor_)
interactor_->SetDesiredUpdateRate(rate);
}
/////////////////////////////////////////////////////////////////////////////////////////////
double cv::viz::Viz3d::VizImpl::getDesiredUpdateRate()
{
if (interactor_)
return interactor_->GetDesiredUpdateRate();
return 0.0;
}
/////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::Viz3d::VizImpl::saveScreenshot(const String &file) { style_->saveScreenshot(file.c_str()); }
/////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::Viz3d::VizImpl::registerMouseCallback(MouseCallback callback, void* cookie)
{ style_->registerMouseCallback(callback, cookie); }
void cv::viz::Viz3d::VizImpl::registerKeyboardCallback(KeyboardCallback callback, void* cookie)
{ style_->registerKeyboardCallback(callback, cookie); }
/////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::Viz3d::VizImpl::spin()
{
resetStoppedFlag();
window_->Render();
interactor_->Start();
}
/////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::Viz3d::VizImpl::spinOnce(int time, bool force_redraw)
{
resetStoppedFlag();
if (time <= 0)
time = 1;
if (force_redraw)
interactor_->Render();
double s_now_ = cv::getTickCount() / cv::getTickFrequency();
if (s_lastDone_ > s_now_)
s_lastDone_ = s_now_;
if ((s_now_ - s_lastDone_) > (1.0 / interactor_->GetDesiredUpdateRate()))
{
exit_main_loop_timer_callback_->right_timer_id = interactor_->CreateRepeatingTimer(time);
interactor_->Start();
interactor_->DestroyTimer(exit_main_loop_timer_callback_->right_timer_id);
s_lastDone_ = s_now_;
}
}
//////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::Viz3d::VizImpl::removeAllWidgets()
{
widget_actor_map_->clear();
renderer_->RemoveAllViewProps();
}
/////////////////////////////////////////////////////////////////////////////////////////////
bool cv::viz::Viz3d::VizImpl::removeActorFromRenderer(const vtkSmartPointer<vtkProp> &actor)
{
vtkProp* actor_to_remove = vtkProp::SafeDownCast(actor);
vtkPropCollection* actors = renderer_->GetViewProps();
actors->InitTraversal();
vtkProp* current_actor = NULL;
while ((current_actor = actors->GetNextProp()) != NULL)
{
if (current_actor != actor_to_remove)
continue;
renderer_->RemoveActor(actor);
return true;
}
return false;
}
/////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::Viz3d::VizImpl::createActorFromVTKDataSet(const vtkSmartPointer<vtkDataSet> &data, vtkSmartPointer<vtkLODActor> &actor, bool use_scalars)
{
if (!actor)
actor = vtkSmartPointer<vtkLODActor>::New();
vtkSmartPointer<vtkDataSetMapper> mapper = vtkSmartPointer<vtkDataSetMapper>::New();
#if VTK_MAJOR_VERSION <= 5
mapper->SetInput(data);
#else
mapper->SetInputData(data);
#endif
if (use_scalars)
{
vtkSmartPointer<vtkDataArray> scalars = data->GetPointData()->GetScalars();
if (scalars)
{
cv::Vec3d minmax(scalars->GetRange());
mapper->SetScalarRange(minmax.val);
mapper->SetScalarModeToUsePointData();
// interpolation OFF, if data is a vtkPolyData that contains only vertices, ON for anything else.
vtkPolyData* polyData = vtkPolyData::SafeDownCast(data);
bool interpolation = (polyData && polyData->GetNumberOfCells() != polyData->GetNumberOfVerts());
mapper->SetInterpolateScalarsBeforeMapping(interpolation);
mapper->ScalarVisibilityOn();
}
}
mapper->ImmediateModeRenderingOff();
actor->SetNumberOfCloudPoints(int(std::max<vtkIdType>(1, data->GetNumberOfPoints() / 10)));
actor->GetProperty()->SetInterpolationToFlat();
actor->GetProperty()->BackfaceCullingOn();
actor->SetMapper(mapper);
}
//////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::Viz3d::VizImpl::setBackgroundColor(const Color& color)
{
Color c = vtkcolor(color);
renderer_->SetBackground(c.val);
}
/////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::Viz3d::VizImpl::setCamera(const Camera &camera)
{
vtkCamera& active_camera = *renderer_->GetActiveCamera();
// Set the intrinsic parameters of the camera
window_->SetSize(camera.getWindowSize().width, camera.getWindowSize().height);
double aspect_ratio = static_cast<double>(camera.getWindowSize().width)/static_cast<double>(camera.getWindowSize().height);
Matx44f proj_mat;
camera.computeProjectionMatrix(proj_mat);
// Use the intrinsic parameters of the camera to simulate more realistically
Matx44f 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_mat * old_proj_mat.inv()));
active_camera.SetUserTransform(transform);
transform->Delete();
renderer_->ResetCameraClippingRange();
renderer_->Render();
}
/////////////////////////////////////////////////////////////////////////////////////////////
cv::viz::Camera cv::viz::Viz3d::VizImpl::getCamera() const
{
vtkCamera& active_camera = *renderer_->GetActiveCamera();
Size window_size(renderer_->GetRenderWindow()->GetSize()[0],
renderer_->GetRenderWindow()->GetSize()[1]);
double aspect_ratio = static_cast<double>(window_size.width) / static_cast<double>(window_size.height);
Matx44f proj_matrix = convertToMatx(active_camera.GetProjectionTransformMatrix(aspect_ratio, -1.0f, 1.0f));
Camera camera(proj_matrix, window_size);
return camera;
}
/////////////////////////////////////////////////////////////////////////////////////////////
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]);
renderer_->ResetCameraClippingRange();
renderer_->Render();
}
/////////////////////////////////////////////////////////////////////////////////////////////
cv::Affine3f cv::viz::Viz3d::VizImpl::getViewerPose()
{
vtkCamera& camera = *renderer_->GetActiveCamera();
Vec3d pos(camera.GetPosition());
Vec3d view_up(camera.GetViewUp());
Vec3d focal(camera.GetFocalPoint());
Vec3d y_axis = normalized(view_up);
Vec3d z_axis = normalized(focal - pos);
Vec3d x_axis = normalized(y_axis.cross(z_axis));
cv::Matx33d R;
R(0, 0) = x_axis[0];
R(0, 1) = y_axis[0];
R(0, 2) = z_axis[0];
R(1, 0) = x_axis[1];
R(1, 1) = y_axis[1];
R(1, 2) = z_axis[1];
R(2, 0) = x_axis[2];
R(2, 1) = y_axis[2];
R(2, 2) = z_axis[2];
return cv::Affine3f(R, pos);
}
/////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::Viz3d::VizImpl::convertToWindowCoordinates(const Point3d &pt, Point3d &window_coord)
{
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 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();
Vec3d cam_pos;
active_camera.GetPosition(cam_pos.val);
origin = cam_pos;
direction = normalize(Vec3d(world_pt.val) - cam_pos);
}
/////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::Viz3d::VizImpl::resetCameraViewpoint(const String &id)
{
vtkSmartPointer<vtkMatrix4x4> camera_pose;
static WidgetActorMap::iterator it = widget_actor_map_->find(id);
if (it != widget_actor_map_->end())
{
vtkProp3D *actor = vtkProp3D::SafeDownCast(it->second);
CV_Assert("Widget is not 3D." && actor);
camera_pose = actor->GetUserMatrix();
}
else
return;
// Prevent a segfault
if (!camera_pose) return;
vtkSmartPointer<vtkCamera> cam = renderer_->GetActiveCamera();
cam->SetPosition(camera_pose->GetElement(0, 3),
camera_pose->GetElement(1, 3),
camera_pose->GetElement(2, 3));
cam->SetFocalPoint(camera_pose->GetElement(0, 3) - camera_pose->GetElement(0, 2),
camera_pose->GetElement(1, 3) - camera_pose->GetElement(1, 2),
camera_pose->GetElement(2, 3) - camera_pose->GetElement(2, 2));
cam->SetViewUp(camera_pose->GetElement(0, 1),
camera_pose->GetElement(1, 1),
camera_pose->GetElement(2, 1));
renderer_->SetActiveCamera(cam);
renderer_->ResetCameraClippingRange();
renderer_->Render();
}
///////////////////////////////////////////////////////////////////////////////////
void cv::viz::Viz3d::VizImpl::resetCamera()
{
renderer_->ResetCamera();
}
///////////////////////////////////////////////////////////////////////////////////
void cv::viz::Viz3d::VizImpl::setRepresentation(int representation)
{
vtkActorCollection * actors = renderer_->GetActors();
actors->InitTraversal();
vtkActor * actor;
switch (representation)
{
case REPRESENTATION_POINTS:
{
while ((actor = actors->GetNextActor()) != NULL)
actor->GetProperty()->SetRepresentationToPoints();
break;
}
case REPRESENTATION_SURFACE:
{
while ((actor = actors->GetNextActor()) != NULL)
actor->GetProperty()->SetRepresentationToSurface();
break;
}
case REPRESENTATION_WIREFRAME:
{
while ((actor = actors->GetNextActor()) != NULL)
actor->GetProperty()->SetRepresentationToWireframe();
break;
}
}
}
//////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::Viz3d::VizImpl::updateCells(vtkSmartPointer<vtkIdTypeArray> &cells, vtkSmartPointer<vtkIdTypeArray> &initcells, vtkIdType nr_points)
{
// If no init cells and cells has not been initialized...
if (!cells)
cells = vtkSmartPointer<vtkIdTypeArray>::New();
// If we have less values then we need to recreate the array
if (cells->GetNumberOfTuples() < nr_points)
{
cells = vtkSmartPointer<vtkIdTypeArray>::New();
// If init cells is given, and there's enough data in it, use it
if (initcells && initcells->GetNumberOfTuples() >= nr_points)
{
cells->DeepCopy(initcells);
cells->SetNumberOfComponents(2);
cells->SetNumberOfTuples(nr_points);
}
else
{
// If the number of tuples is still too small, we need to recreate the array
cells->SetNumberOfComponents(2);
cells->SetNumberOfTuples(nr_points);
vtkIdType *cell = cells->GetPointer(0);
// Fill it with 1s
std::fill_n(cell, nr_points * 2, 1);
cell++;
for (vtkIdType i = 0; i < nr_points; ++i, cell += 2)
*cell = i;
// Save the results in initcells
initcells = vtkSmartPointer<vtkIdTypeArray>::New();
initcells->DeepCopy(cells);
}
}
else
{
// The assumption here is that the current set of cells has more data than needed
cells->SetNumberOfComponents(2);
cells->SetNumberOfTuples(nr_points);
}
}
//////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::Viz3d::VizImpl::setFullScreen(bool mode)
{
if (window_)
window_->SetFullScreen(mode);
}
//////////////////////////////////////////////////////////////////////////////////////////////
cv::String cv::viz::Viz3d::VizImpl::getWindowName() const
{
return (window_ ? window_->GetWindowName() : "");
}
//////////////////////////////////////////////////////////////////////////////////////////////
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]); }

@ -0,0 +1,395 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
// Authors:
// * Ozan Tonkal, ozantonkal@gmail.com
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
//
// OpenCV Viz module is complete rewrite of
// PCL visualization module (www.pointclouds.org)
//
//M*/
#ifndef __OPENCV_VIZ_VIZ3D_IMPL_HPP__
#define __OPENCV_VIZ_VIZ3D_IMPL_HPP__
#include <opencv2/viz.hpp>
#include "interactor_style.h"
struct cv::viz::Viz3d::VizImpl
{
public:
typedef cv::Ptr<VizImpl> Ptr;
typedef Viz3d::KeyboardCallback KeyboardCallback;
typedef Viz3d::MouseCallback MouseCallback;
int ref_counter;
VizImpl(const String &name);
virtual ~VizImpl();
void showWidget(const String &id, const Widget &widget, const Affine3f &pose = Affine3f::Identity());
void removeWidget(const String &id);
Widget getWidget(const String &id) const;
void removeAllWidgets();
void setWidgetPose(const String &id, const Affine3f &pose);
void updateWidgetPose(const String &id, const Affine3f &pose);
Affine3f getWidgetPose(const String &id) const;
void setDesiredUpdateRate(double rate);
double getDesiredUpdateRate();
/** \brief Returns true when the user tried to close the window */
bool wasStopped() const { if (interactor_ != NULL) return (stopped_); else return true; }
/** \brief Set the stopped flag back to false */
void resetStoppedFlag() { if (interactor_ != NULL) stopped_ = false; }
/** \brief Stop the interaction and close the visualizaton window. */
void close()
{
stopped_ = true;
if (interactor_)
{
interactor_->GetRenderWindow()->Finalize();
interactor_->TerminateApp(); // This tends to close the window...
}
}
void setRepresentation(int representation);
void setCamera(const Camera &camera);
Camera getCamera() const;
/** \brief Reset the camera to a given widget */
void resetCameraViewpoint(const String& id);
void resetCamera();
void setViewerPose(const Affine3f &pose);
Affine3f getViewerPose();
void convertToWindowCoordinates(const Point3d &pt, Point3d &window_coord);
void converTo3DRay(const Point3d &window_coord, Point3d &origin, Vec3d &direction);
void saveScreenshot(const String &file);
void setWindowPosition(int x, int y);
Size getWindowSize() const;
void setWindowSize(int xw, int yw);
void setFullScreen(bool mode);
String getWindowName() const;
void setBackgroundColor(const Color& color);
void spin();
void spinOnce(int time = 1, bool force_redraw = false);
void registerKeyboardCallback(KeyboardCallback callback, void* cookie = 0);
void registerMouseCallback(MouseCallback callback, void* cookie = 0);
private:
vtkSmartPointer<vtkRenderWindowInteractor> interactor_;
struct ExitMainLoopTimerCallback : public vtkCommand
{
static ExitMainLoopTimerCallback* New()
{
return new ExitMainLoopTimerCallback;
}
virtual void Execute(vtkObject* vtkNotUsed(caller), unsigned long event_id, void* call_data)
{
if (event_id != vtkCommand::TimerEvent)
return;
int timer_id = *reinterpret_cast<int*>(call_data);
if (timer_id != right_timer_id)
return;
// Stop vtk loop and send notification to app to wake it up
viz_->interactor_->TerminateApp();
}
int right_timer_id;
VizImpl* viz_;
};
struct ExitCallback : public vtkCommand
{
static ExitCallback* New()
{
return new ExitCallback;
}
virtual void Execute(vtkObject*, unsigned long event_id, void*)
{
if (event_id == vtkCommand::ExitEvent)
{
viz_->stopped_ = true;
viz_->interactor_->GetRenderWindow()->Finalize();
viz_->interactor_->TerminateApp();
}
}
VizImpl* viz_;
};
/** \brief Set to false if the interaction loop is running. */
bool stopped_;
double s_lastDone_;
/** \brief Global timer ID. Used in destructor only. */
int timer_id_;
/** \brief Callback object enabling us to leave the main loop, when a timer fires. */
vtkSmartPointer<ExitMainLoopTimerCallback> exit_main_loop_timer_callback_;
vtkSmartPointer<ExitCallback> exit_callback_;
vtkSmartPointer<vtkRenderer> renderer_;
vtkSmartPointer<vtkRenderWindow> window_;
/** \brief The render window interactor style. */
vtkSmartPointer<InteractorStyle> style_;
/** \brief Internal list with actor pointers and name IDs for all widget actors */
cv::Ptr<WidgetActorMap> widget_actor_map_;
/** \brief Boolean that holds whether or not the camera parameters were manually initialized*/
bool camera_set_;
bool removeActorFromRenderer(const vtkSmartPointer<vtkProp> &actor);
/** \brief Internal method. Creates a vtk actor from a vtk polydata object.
* \param[in] data the vtk polydata object to create an actor for
* \param[out] actor the resultant vtk actor object
* \param[in] use_scalars set scalar properties to the mapper if it exists in the data. Default: true.
*/
void createActorFromVTKDataSet(const vtkSmartPointer<vtkDataSet> &data, vtkSmartPointer<vtkLODActor> &actor, bool use_scalars = true);
/** \brief Updates a set of cells (vtkIdTypeArray) if the number of points in a cloud changes
* \param[out] cells the vtkIdTypeArray object (set of cells) to update
* \param[out] initcells a previously saved set of cells. If the number of points in the current cloud is
* higher than the number of cells in \a cells, and initcells contains enough data, then a copy from it
* will be made instead of regenerating the entire array.
* \param[in] nr_points the number of points in the new cloud. This dictates how many cells we need to
* generate
*/
void updateCells(vtkSmartPointer<vtkIdTypeArray> &cells, vtkSmartPointer<vtkIdTypeArray> &initcells, vtkIdType nr_points);
};
namespace cv
{
namespace viz
{
vtkSmartPointer<vtkMatrix4x4> convertToVtkMatrix(const cv::Matx44f &m);
cv::Matx44f convertToMatx(const vtkSmartPointer<vtkMatrix4x4>& vtk_matrix);
struct NanFilter
{
template<typename _Tp, typename _Msk>
struct Impl
{
typedef Vec<_Tp, 3> _Out;
static _Out* copy(const Mat& source, _Out* output, const Mat& nan_mask)
{
CV_Assert(DataDepth<_Tp>::value == source.depth() && source.size() == nan_mask.size());
CV_Assert(nan_mask.channels() == 3 || nan_mask.channels() == 4);
CV_DbgAssert(DataDepth<_Msk>::value == nan_mask.depth());
int s_chs = source.channels();
int m_chs = nan_mask.channels();
for (int y = 0; y < source.rows; ++y)
{
const _Tp* srow = source.ptr<_Tp>(y);
const _Msk* mrow = nan_mask.ptr<_Msk>(y);
for (int x = 0; x < source.cols; ++x, srow += s_chs, mrow += m_chs)
if (!isNan(mrow[0]) && !isNan(mrow[1]) && !isNan(mrow[2]))
*output++ = _Out(srow);
}
return output;
}
static _Out* copyColor(const Mat& source, _Out* output, const Mat& nan_mask)
{
CV_Assert(DataDepth<_Tp>::value == source.depth() && source.size() == nan_mask.size());
CV_Assert(nan_mask.channels() == 3 || nan_mask.channels() == 4);
CV_DbgAssert(DataDepth<_Msk>::value == nan_mask.depth());
int s_chs = source.channels();
int m_chs = nan_mask.channels();
for (int y = 0; y < source.rows; ++y)
{
const _Tp* srow = source.ptr<_Tp>(y);
const _Msk* mrow = nan_mask.ptr<_Msk>(y);
for (int x = 0; x < source.cols; ++x, srow += s_chs, mrow += m_chs)
if (!isNan(mrow[0]) && !isNan(mrow[1]) && !isNan(mrow[2]))
{
*output = _Out(srow);
std::swap((*output)[0], (*output)[2]); // BGR -> RGB
++output;
}
}
return output;
}
};
template<typename _Tp>
static inline Vec<_Tp, 3>* copy(const Mat& source, Vec<_Tp, 3>* output, const Mat& nan_mask)
{
CV_Assert(nan_mask.depth() == CV_32F || nan_mask.depth() == CV_64F);
typedef Vec<_Tp, 3>* (*copy_func)(const Mat&, Vec<_Tp, 3>*, const Mat&);
const static copy_func table[2] = { &NanFilter::Impl<_Tp, float>::copy, &NanFilter::Impl<_Tp, double>::copy };
return table[nan_mask.depth() - 5](source, output, nan_mask);
}
template<typename _Tp>
static inline Vec<_Tp, 3>* copyColor(const Mat& source, Vec<_Tp, 3>* output, const Mat& nan_mask)
{
CV_Assert(nan_mask.depth() == CV_32F || nan_mask.depth() == CV_64F);
typedef Vec<_Tp, 3>* (*copy_func)(const Mat&, Vec<_Tp, 3>*, const Mat&);
const static copy_func table[2] = { &NanFilter::Impl<_Tp, float>::copyColor, &NanFilter::Impl<_Tp, double>::copyColor };
return table[nan_mask.depth() - 5](source, output, nan_mask);
}
};
struct ApplyAffine
{
const Affine3f& affine_;
ApplyAffine(const Affine3f& affine) : affine_(affine) {}
template<typename _Tp> Point3_<_Tp> operator()(const Point3_<_Tp>& p) const { return affine_ * p; }
template<typename _Tp> Vec<_Tp, 3> operator()(const Vec<_Tp, 3>& v) const
{
const float* m = affine_.matrix.val;
Vec<_Tp, 3> result;
result[0] = (_Tp)(m[0] * v[0] + m[1] * v[1] + m[ 2] * v[2] + m[ 3]);
result[1] = (_Tp)(m[4] * v[0] + m[5] * v[1] + m[ 6] * v[2] + m[ 7]);
result[2] = (_Tp)(m[8] * v[0] + m[9] * v[1] + m[10] * v[2] + m[11]);
return result;
}
private:
ApplyAffine(const ApplyAffine&);
ApplyAffine& operator=(const ApplyAffine&);
};
inline Color vtkcolor(const Color& color)
{
Color scaled_color = color * (1.0/255.0);
std::swap(scaled_color[0], scaled_color[2]);
return scaled_color;
}
inline Vec3d vtkpoint(const Point3f& point) { return Vec3d(point.x, point.y, point.z); }
template<typename _Tp> inline _Tp normalized(const _Tp& v) { return v * 1/cv::norm(v); }
struct ConvertToVtkImage
{
struct Impl
{
static void copyImageMultiChannel(const Mat &image, vtkSmartPointer<vtkImageData> output)
{
int i_chs = image.channels();
for (int i = 0; i < image.rows; ++i)
{
const unsigned char * irows = image.ptr<unsigned char>(i);
for (int j = 0; j < image.cols; ++j, irows += i_chs)
{
unsigned char * vrows = static_cast<unsigned char *>(output->GetScalarPointer(j,i,0));
memcpy(vrows, irows, i_chs);
std::swap(vrows[0], vrows[2]); // BGR -> RGB
}
}
output->Modified();
}
static void copyImageSingleChannel(const Mat &image, vtkSmartPointer<vtkImageData> output)
{
for (int i = 0; i < image.rows; ++i)
{
const unsigned char * irows = image.ptr<unsigned char>(i);
for (int j = 0; j < image.cols; ++j, ++irows)
{
unsigned char * vrows = static_cast<unsigned char *>(output->GetScalarPointer(j,i,0));
*vrows = *irows;
}
}
output->Modified();
}
};
static void convert(const Mat &image, vtkSmartPointer<vtkImageData> output)
{
// Create the vtk image
output->SetDimensions(image.cols, image.rows, 1);
#if VTK_MAJOR_VERSION <= 5
output->SetNumberOfScalarComponents(image.channels());
output->SetScalarTypeToUnsignedChar();
output->AllocateScalars();
#else
output->AllocateScalars(VTK_UNSIGNED_CHAR, image.channels());
#endif
int i_chs = image.channels();
if (i_chs > 1)
{
// Multi channel images are handled differently because of BGR <-> RGB
Impl::copyImageMultiChannel(image, output);
}
else
{
Impl::copyImageSingleChannel(image, output);
}
}
};
}
}
#endif

@ -0,0 +1,410 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
// Authors:
// * Ozan Tonkal, ozantonkal@gmail.com
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
//
// OpenCV Viz module is complete rewrite of
// PCL visualization module (www.pointclouds.org)
//
//M*/
#include "precomp.hpp"
///////////////////////////////////////////////////////////////////////////////////////////////
/// widget implementation
class cv::viz::Widget::Impl
{
public:
vtkSmartPointer<vtkProp> prop;
Impl() : prop(0) {}
};
cv::viz::Widget::Widget() : impl_( new Impl() ) { }
cv::viz::Widget::Widget(const Widget& other) : impl_( new Impl() )
{
if (other.impl_ && other.impl_->prop) impl_->prop = other.impl_->prop;
}
cv::viz::Widget& cv::viz::Widget::operator=(const Widget& other)
{
if (!impl_) impl_ = new Impl();
if (other.impl_) impl_->prop = other.impl_->prop;
return *this;
}
cv::viz::Widget::~Widget()
{
if (impl_)
{
delete impl_;
impl_ = 0;
}
}
cv::viz::Widget cv::viz::Widget::fromPlyFile(const String &file_name)
{
vtkSmartPointer<vtkPLYReader> reader = vtkSmartPointer<vtkPLYReader>::New();
reader->SetFileName(file_name.c_str());
vtkSmartPointer<vtkDataSet> data = reader->GetOutput();
CV_Assert("File does not exist or file format is not supported." && data);
vtkSmartPointer<vtkLODActor> actor = vtkSmartPointer<vtkLODActor>::New();
vtkSmartPointer<vtkDataSetMapper> mapper = vtkSmartPointer<vtkDataSetMapper>::New();
#if VTK_MAJOR_VERSION <= 5
mapper->SetInput(data);
#else
mapper->SetInputData(data);
#endif
vtkSmartPointer<vtkDataArray> scalars = data->GetPointData()->GetScalars();
if (scalars)
{
cv::Vec3d minmax(scalars->GetRange());
mapper->SetScalarRange(minmax.val);
mapper->SetScalarModeToUsePointData();
// interpolation OFF, if data is a vtkPolyData that contains only vertices, ON for anything else.
vtkPolyData* polyData = vtkPolyData::SafeDownCast(data);
bool interpolation = (polyData && polyData->GetNumberOfCells() != polyData->GetNumberOfVerts());
mapper->SetInterpolateScalarsBeforeMapping(interpolation);
mapper->ScalarVisibilityOn();
}
mapper->ImmediateModeRenderingOff();
actor->SetNumberOfCloudPoints(int(std::max<vtkIdType>(1, data->GetNumberOfPoints() / 10)));
actor->GetProperty()->SetInterpolationToFlat();
actor->GetProperty()->BackfaceCullingOn();
actor->SetMapper(mapper);
Widget widget;
widget.impl_->prop = actor;
return widget;
}
void cv::viz::Widget::setRenderingProperty(int property, double value)
{
vtkActor *actor = vtkActor::SafeDownCast(WidgetAccessor::getProp(*this));
CV_Assert("Widget type is not supported." && actor);
switch (property)
{
case POINT_SIZE:
{
actor->GetProperty()->SetPointSize(float(value));
actor->Modified();
break;
}
case OPACITY:
{
actor->GetProperty()->SetOpacity(value);
actor->Modified();
break;
}
case IMMEDIATE_RENDERING:
{
actor->GetMapper()->SetImmediateModeRendering(int(value));
actor->Modified();
break;
}
case LINE_WIDTH:
{
actor->GetProperty()->SetLineWidth(float(value));
actor->Modified();
break;
}
case FONT_SIZE:
{
vtkTextActor* text_actor = vtkTextActor::SafeDownCast(actor);
CV_Assert("Widget does not have text content." && text_actor);
vtkSmartPointer<vtkTextProperty> tprop = text_actor->GetTextProperty();
tprop->SetFontSize(int(value));
text_actor->Modified();
break;
}
case REPRESENTATION:
{
switch (int(value))
{
case REPRESENTATION_POINTS: actor->GetProperty()->SetRepresentationToPoints(); break;
case REPRESENTATION_WIREFRAME: actor->GetProperty()->SetRepresentationToWireframe(); break;
case REPRESENTATION_SURFACE: actor->GetProperty()->SetRepresentationToSurface(); break;
}
actor->Modified();
break;
}
case SHADING:
{
switch (int(value))
{
case SHADING_FLAT: actor->GetProperty()->SetInterpolationToFlat(); break;
case SHADING_GOURAUD:
{
if (!actor->GetMapper()->GetInput()->GetPointData()->GetNormals())
{
vtkSmartPointer<vtkPolyDataNormals> normals = vtkSmartPointer<vtkPolyDataNormals>::New();
#if VTK_MAJOR_VERSION <= 5
normals->SetInput(actor->GetMapper()->GetInput());
#else
normals->SetInputData(actor->GetMapper()->GetInput());
#endif
normals->Update();
vtkDataSetMapper::SafeDownCast(actor->GetMapper())->SetInputConnection(normals->GetOutputPort());
}
actor->GetProperty()->SetInterpolationToGouraud();
break;
}
case SHADING_PHONG:
{
if (!actor->GetMapper()->GetInput()->GetPointData()->GetNormals())
{
vtkSmartPointer<vtkPolyDataNormals> normals = vtkSmartPointer<vtkPolyDataNormals>::New();
#if VTK_MAJOR_VERSION <= 5
normals->SetInput(actor->GetMapper()->GetInput());
#else
normals->SetInputData(actor->GetMapper()->GetInput());
#endif
normals->Update();
vtkDataSetMapper::SafeDownCast(actor->GetMapper())->SetInputConnection(normals->GetOutputPort());
}
actor->GetProperty()->SetInterpolationToPhong();
break;
}
}
actor->Modified();
break;
}
default:
CV_Assert("setPointCloudRenderingProperties: Unknown property");
}
}
double cv::viz::Widget::getRenderingProperty(int property) const
{
vtkActor *actor = vtkActor::SafeDownCast(WidgetAccessor::getProp(*this));
CV_Assert("Widget type is not supported." && actor);
double value = 0.0;
switch (property)
{
case POINT_SIZE:
{
value = actor->GetProperty()->GetPointSize();
break;
}
case OPACITY:
{
value = actor->GetProperty()->GetOpacity();
break;
}
case IMMEDIATE_RENDERING:
{
value = actor->GetMapper()->GetImmediateModeRendering();
break;
}
case LINE_WIDTH:
{
value = actor->GetProperty()->GetLineWidth();
break;
}
case FONT_SIZE:
{
vtkTextActor* text_actor = vtkTextActor::SafeDownCast(actor);
CV_Assert("Widget does not have text content." && text_actor);
vtkSmartPointer<vtkTextProperty> tprop = text_actor->GetTextProperty();
value = tprop->GetFontSize();
break;
}
case REPRESENTATION:
{
switch (actor->GetProperty()->GetRepresentation())
{
case VTK_POINTS: value = REPRESENTATION_POINTS; break;
case VTK_WIREFRAME: value = REPRESENTATION_WIREFRAME; break;
case VTK_SURFACE: value = REPRESENTATION_SURFACE; break;
}
break;
}
case SHADING:
{
switch (actor->GetProperty()->GetInterpolation())
{
case VTK_FLAT: value = SHADING_FLAT; break;
case VTK_GOURAUD: value = SHADING_GOURAUD; break;
case VTK_PHONG: value = SHADING_PHONG; break;
}
break;
}
default:
CV_Assert("getPointCloudRenderingProperties: Unknown property");
}
return value;
}
///////////////////////////////////////////////////////////////////////////////////////////////
/// widget accessor implementaion
vtkSmartPointer<vtkProp> cv::viz::WidgetAccessor::getProp(const Widget& widget)
{
return widget.impl_->prop;
}
void cv::viz::WidgetAccessor::setProp(Widget& widget, vtkSmartPointer<vtkProp> prop)
{
widget.impl_->prop = prop;
}
///////////////////////////////////////////////////////////////////////////////////////////////
/// widget3D implementation
struct cv::viz::Widget3D::MatrixConverter
{
static Matx44f convertToMatx(const vtkSmartPointer<vtkMatrix4x4>& vtk_matrix)
{
Matx44f m;
for (int i = 0; i < 4; i++)
for (int k = 0; k < 4; k++)
m(i, k) = vtk_matrix->GetElement(i, k);
return m;
}
static vtkSmartPointer<vtkMatrix4x4> convertToVtkMatrix(const Matx44f& m)
{
vtkSmartPointer<vtkMatrix4x4> vtk_matrix = vtkSmartPointer<vtkMatrix4x4>::New();
for (int i = 0; i < 4; i++)
for (int k = 0; k < 4; k++)
vtk_matrix->SetElement(i, k, m(i, k));
return vtk_matrix;
}
};
void cv::viz::Widget3D::setPose(const Affine3f &pose)
{
vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getProp(*this));
CV_Assert("Widget is not 3D." && actor);
vtkSmartPointer<vtkMatrix4x4> matrix = convertToVtkMatrix(pose.matrix);
actor->SetUserMatrix(matrix);
actor->Modified();
}
void cv::viz::Widget3D::updatePose(const Affine3f &pose)
{
vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getProp(*this));
CV_Assert("Widget is not 3D." && actor);
vtkSmartPointer<vtkMatrix4x4> matrix = actor->GetUserMatrix();
if (!matrix)
{
setPose(pose);
return ;
}
Matx44f matrix_cv = MatrixConverter::convertToMatx(matrix);
Affine3f updated_pose = pose * Affine3f(matrix_cv);
matrix = MatrixConverter::convertToVtkMatrix(updated_pose.matrix);
actor->SetUserMatrix(matrix);
actor->Modified();
}
cv::Affine3f cv::viz::Widget3D::getPose() const
{
vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getProp(*this));
CV_Assert("Widget is not 3D." && actor);
vtkSmartPointer<vtkMatrix4x4> matrix = actor->GetUserMatrix();
Matx44f matrix_cv = MatrixConverter::convertToMatx(matrix);
return Affine3f(matrix_cv);
}
void cv::viz::Widget3D::setColor(const Color &color)
{
// Cast to actor instead of prop3d since prop3d doesn't provide getproperty
vtkActor *actor = vtkActor::SafeDownCast(WidgetAccessor::getProp(*this));
CV_Assert("Widget type is not supported." && actor);
Color c = vtkcolor(color);
actor->GetMapper()->ScalarVisibilityOff();
actor->GetProperty()->SetColor(c.val);
actor->GetProperty()->SetEdgeColor(c.val);
actor->Modified();
}
template<> cv::viz::Widget3D cv::viz::Widget::cast<cv::viz::Widget3D>()
{
vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getProp(*this));
CV_Assert("Widget cannot be cast." && actor);
Widget3D widget;
WidgetAccessor::setProp(widget, actor);
return widget;
}
///////////////////////////////////////////////////////////////////////////////////////////////
/// widget2D implementation
void cv::viz::Widget2D::setColor(const Color &color)
{
vtkActor2D *actor = vtkActor2D::SafeDownCast(WidgetAccessor::getProp(*this));
CV_Assert("Widget type is not supported." && actor);
Color c = vtkcolor(color);
actor->GetProperty()->SetColor(c.val);
actor->Modified();
}
template<> cv::viz::Widget2D cv::viz::Widget::cast<cv::viz::Widget2D>()
{
vtkActor2D *actor = vtkActor2D::SafeDownCast(WidgetAccessor::getProp(*this));
CV_Assert("Widget cannot be cast." && actor);
Widget2D widget;
WidgetAccessor::setProp(widget, actor);
return widget;
}

@ -0,0 +1,3 @@
#include "test_precomp.hpp"
CV_TEST_MAIN("cv")

@ -0,0 +1 @@
#include "test_precomp.hpp"

@ -0,0 +1,68 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
// Authors:
// * Ozan Tonkal, ozantonkal@gmail.com
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
//
// OpenCV Viz module is complete rewrite of
// PCL visualization module (www.pointclouds.org)
//
//M*/
#ifdef __GNUC__
# pragma GCC diagnostic ignored "-Wmissing-declarations"
# if defined __clang__ || defined __APPLE__
# pragma GCC diagnostic ignored "-Wmissing-prototypes"
# pragma GCC diagnostic ignored "-Wextra"
# endif
#endif
#ifndef __OPENCV_TEST_PRECOMP_HPP__
#define __OPENCV_TEST_PRECOMP_HPP__
#include "opencv2/ts.hpp"
#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <iostream>
#include <fstream>
#include <string>
#endif

@ -0,0 +1,182 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2008-2013, Willow Garage Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and / or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "test_precomp.hpp"
#include <opencv2/viz.hpp>
#include <opencv2/highgui.hpp>
#include <string>
using namespace cv;
cv::Mat cvcloud_load()
{
cv::Mat cloud(1, 20000, CV_32FC3);
std::ifstream ifs("/Users/nerei/cloud_dragon.ply");
std::string str;
for(size_t i = 0; i < 11; ++i)
std::getline(ifs, str);
cv::Point3f* data = cloud.ptr<cv::Point3f>();
for(size_t i = 0; i < 20000; ++i)
ifs >> data[i].x >> data[i].y >> data[i].z;
return cloud;
}
bool constant_cam = true;
cv::viz::Widget cam_1, cam_coordinates;
void keyboard_callback(const viz::KeyboardEvent & event, void * cookie)
{
if (event.keyDown())
{
if (event.getKeySym() == "space")
{
viz::Viz3d &viz = *((viz::Viz3d *) cookie);
constant_cam = !constant_cam;
if (constant_cam)
{
viz.showWidget("cam_1", cam_1);
viz.showWidget("cam_coordinate", cam_coordinates);
viz.showWidget("cam_text", viz::WText("Global View", Point2i(5,5), 28));
viz.resetCamera();
}
else
{
viz.showWidget("cam_text", viz::WText("Cam View", Point2i(5,5), 28));
viz.removeWidget("cam_1");
viz.removeWidget("cam_coordinate");
}
}
}
}
TEST(Viz_viz3d, accuracy)
{
cv::viz::Viz3d viz("abc");
cv::viz::Mesh3d bunny_mesh = cv::viz::Mesh3d::loadMesh("bunny.ply");
cv::viz::WMesh bunny_widget(bunny_mesh);
bunny_widget.setColor(cv::viz::Color::cyan());
cam_1 = cv::viz::WCameraPosition(cv::Vec2f(0.6, 0.4), 0.2, cv::viz::Color::green());
cam_coordinates = cv::viz::WCameraPosition(0.2);
viz.showWidget("bunny", bunny_widget);
viz.showWidget("cam_1", cam_1, viz::makeCameraPose(Point3f(1.0,0.0,0.0), Point3f(0.0,0.0,0.0), Point3f(0.0,1.0,0.0)));
viz.showWidget("cam_coordinate", cam_coordinates, viz::makeCameraPose(Point3f(1.0,0.0,0.0), Point3f(0.0,0.0,0.0), Point3f(0.0,1.0,0.0)));
std::vector<Affine3f> cam_path;
for (int i = 0, j = 0; i <= 360; ++i, j+=5)
{
cam_path.push_back(viz::makeCameraPose(Point3f(0.5*cos(double(i)*CV_PI/180.0), 0.5*sin(double(j)*CV_PI/180.0), 0.5*sin(double(i)*CV_PI/180.0)),
Point3f(0.0,0.0,0.0), Point3f(0.0,1.0,0.0)));
}
int path_counter = 0;
int cam_path_size = cam_path.size();
// OTHER WIDGETS
cv::Mat img = imread("opencv.png");
int downSample = 4;
int row_max = img.rows/downSample;
int col_max = img.cols/downSample;
cv::Mat *clouds = new cv::Mat[img.cols/downSample];
cv::Mat *colors = new cv::Mat[img.cols/downSample];
for (int col = 0; col < col_max; ++col)
{
clouds[col] = Mat::zeros(img.rows/downSample, 1, CV_32FC3);
colors[col] = Mat::zeros(img.rows/downSample, 1, CV_8UC3);
for (int row = 0; row < row_max; ++row)
{
clouds[col].at<Vec3f>(row) = Vec3f(downSample * float(col) / img.cols, 1.0-(downSample * float(row) / img.rows), 0.0);
colors[col].at<Vec3b>(row) = img.at<Vec3b>(row*downSample,col*downSample);
}
}
for (int col = 0; col < col_max; ++col)
{
std::stringstream strstrm;
strstrm << "cloud_" << col;
viz.showWidget(strstrm.str(), viz::WCloud(clouds[col], colors[col]));
viz.getWidget(strstrm.str()).setRenderingProperty(viz::POINT_SIZE, 3.0);
viz.getWidget(strstrm.str()).setRenderingProperty(viz::OPACITY, 0.45);
}
viz.showWidget("trajectory", viz::WTrajectory(cam_path, viz::WTrajectory::DISPLAY_PATH, viz::Color::yellow()));
viz.showWidget("cam_text", viz::WText("Global View", Point2i(5,5), 28));
viz.registerKeyboardCallback(keyboard_callback, (void *) &viz);
int angle = 0;
while(!viz.wasStopped())
{
if (path_counter == cam_path_size)
{
path_counter = 0;
}
if (!constant_cam)
{
viz.setViewerPose(cam_path[path_counter]);
}
if (angle == 360) angle = 0;
cam_1.cast<viz::WCameraPosition>().setPose(cam_path[path_counter]);
cam_coordinates.cast<viz::WCameraPosition>().setPose(cam_path[path_counter++]);
for (int i = 0; i < col_max; ++i)
{
std::stringstream strstrm;
strstrm << "cloud_" << i;
viz.setWidgetPose(strstrm.str(), Affine3f().translate(Vec3f(-0.5,0.0, -0.7 + 0.2*sin((angle+i*10)*CV_PI / 180.0))));
}
angle += 10;
viz.spinOnce(42, true);
}
}

@ -83,6 +83,8 @@ if(BUILD_EXAMPLES AND OCV_DEPENDENCIES_FOUND)
ocv_list_filterout(cpp_samples "/gpu/") ocv_list_filterout(cpp_samples "/gpu/")
endif() endif()
ocv_list_filterout(cpp_samples "viz")
foreach(sample_filename ${cpp_samples}) foreach(sample_filename ${cpp_samples})
get_filename_component(sample ${sample_filename} NAME_WE) get_filename_component(sample ${sample_filename} NAME_WE)
OPENCV_DEFINE_CPP_EXAMPLE(${sample} ${sample_filename}) OPENCV_DEFINE_CPP_EXAMPLE(${sample} ${sample_filename})

File diff suppressed because it is too large Load Diff

@ -0,0 +1,113 @@
/**
* @file creating_widgets.cpp
* @brief Creating custom widgets using VTK
* @author Ozan Cagri Tonkal
*/
#include <opencv2/viz.hpp>
#include <opencv2/viz/widget_accessor.hpp>
#include <iostream>
#include <vtkPoints.h>
#include <vtkTriangle.h>
#include <vtkCellArray.h>
#include <vtkPolyData.h>
#include <vtkPolyDataMapper.h>
#include <vtkIdList.h>
#include <vtkActor.h>
#include <vtkProp.h>
using namespace cv;
using namespace std;
/**
* @function help
* @brief Display instructions to use this tutorial program
*/
void help()
{
cout
<< "--------------------------------------------------------------------------" << endl
<< "This program shows how to create a custom widget. You can create your own "
<< "widgets by extending Widget2D/Widget3D, and with the help of WidgetAccessor." << endl
<< "Usage:" << endl
<< "./creating_widgets" << endl
<< endl;
}
/**
* @class TriangleWidget
* @brief Defining our own 3D Triangle widget
*/
class WTriangle : public viz::Widget3D
{
public:
WTriangle(const Point3f &pt1, const Point3f &pt2, const Point3f &pt3, const viz::Color & color = viz::Color::white());
};
/**
* @function TriangleWidget::TriangleWidget
* @brief Constructor
*/
WTriangle::WTriangle(const Point3f &pt1, const Point3f &pt2, const Point3f &pt3, const viz::Color & color)
{
// Create a triangle
vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
points->InsertNextPoint(pt1.x, pt1.y, pt1.z);
points->InsertNextPoint(pt2.x, pt2.y, pt2.z);
points->InsertNextPoint(pt3.x, pt3.y, pt3.z);
vtkSmartPointer<vtkTriangle> triangle = vtkSmartPointer<vtkTriangle>::New();
triangle->GetPointIds()->SetId(0,0);
triangle->GetPointIds()->SetId(1,1);
triangle->GetPointIds()->SetId(2,2);
vtkSmartPointer<vtkCellArray> cells = vtkSmartPointer<vtkCellArray>::New();
cells->InsertNextCell(triangle);
// Create a polydata object
vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
// Add the geometry and topology to the polydata
polyData->SetPoints(points);
polyData->SetPolys(cells);
// Create mapper and actor
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
#if VTK_MAJOR_VERSION <= 5
mapper->SetInput(polyData);
#else
mapper->SetInputData(polyData);
#endif
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
// Store this actor in the widget in order that visualizer can access it
viz::WidgetAccessor::setProp(*this, actor);
// Set the color of the widget. This has to be called after WidgetAccessor.
setColor(color);
}
/**
* @function main
*/
int main()
{
help();
/// Create a window
viz::Viz3d myWindow("Creating Widgets");
/// Create a triangle widget
WTriangle tw(Point3f(0.0,0.0,0.0), Point3f(1.0,1.0,1.0), Point3f(0.0,1.0,0.0), viz::Color::red());
/// Show widget in the visualizer window
myWindow.showWidget("TRIANGLE", tw);
/// Start event loop
myWindow.spin();
return 0;
}

@ -0,0 +1,66 @@
/**
* @file launching_viz.cpp
* @brief Launching visualization window
* @author Ozan Cagri Tonkal
*/
#include <opencv2/viz.hpp>
#include <iostream>
using namespace cv;
using namespace std;
/**
* @function help
* @brief Display instructions to use this tutorial program
*/
void help()
{
cout
<< "--------------------------------------------------------------------------" << endl
<< "This program shows how to launch a 3D visualization window. You can stop event loop to continue executing. "
<< "You can access the same window via its name. You can run event loop for a given period of time. " << endl
<< "Usage:" << endl
<< "./launching_viz" << endl
<< endl;
}
/**
* @function main
*/
int main()
{
help();
/// Create a window
viz::Viz3d myWindow("Viz Demo");
/// Start event loop
myWindow.spin();
/// Event loop is over when pressed q, Q, e, E
cout << "First event loop is over" << endl;
/// Access window via its name
viz::Viz3d sameWindow = viz::get("Viz Demo");
/// Start event loop
sameWindow.spin();
/// Event loop is over when pressed q, Q, e, E
cout << "Second event loop is over" << endl;
/// Event loop is over when pressed q, Q, e, E
/// Start event loop once for 1 millisecond
sameWindow.spinOnce(1, true);
while(!sameWindow.wasStopped())
{
/// Interact with window
/// Event loop for 1 millisecond
sameWindow.spinOnce(1, true);
}
/// Once more event loop is stopped
cout << "Last event loop is over" << endl;
return 0;
}

@ -0,0 +1,112 @@
/**
* @file transformations.cpp
* @brief Visualizing cloud in different positions, coordinate frames, camera frustums
* @author Ozan Cagri Tonkal
*/
#include <opencv2/viz.hpp>
#include <iostream>
#include <fstream>
using namespace cv;
using namespace std;
/**
* @function help
* @brief Display instructions to use this tutorial program
*/
void help()
{
cout
<< "--------------------------------------------------------------------------" << endl
<< "This program shows how to use makeTransformToGlobal() to compute required pose,"
<< "how to use makeCameraPose and Viz3d::setViewerPose. You can observe the scene "
<< "from camera point of view (C) or global point of view (G)" << endl
<< "Usage:" << endl
<< "./transformations [ G | C ]" << endl
<< endl;
}
/**
* @function cvcloud_load
* @brief load bunny.ply
*/
Mat cvcloud_load()
{
Mat cloud(1, 1889, CV_32FC3);
ifstream ifs("bunny.ply");
string str;
for(size_t i = 0; i < 12; ++i)
getline(ifs, str);
Point3f* data = cloud.ptr<cv::Point3f>();
float dummy1, dummy2;
for(size_t i = 0; i < 1889; ++i)
ifs >> data[i].x >> data[i].y >> data[i].z >> dummy1 >> dummy2;
cloud *= 5.0f;
return cloud;
}
/**
* @function main
*/
int main(int argn, char **argv)
{
help();
if (argn < 2)
{
cout << "Missing arguments." << endl;
return 1;
}
bool camera_pov = (argv[1][0] == 'C');
/// Create a window
viz::Viz3d myWindow("Coordinate Frame");
/// Add coordinate axes
myWindow.showWidget("Coordinate Widget", viz::WCoordinateSystem());
/// Let's assume camera has the following properties
Point3f cam_pos(3.0f,3.0f,3.0f), cam_focal_point(3.0f,3.0f,2.0f), cam_y_dir(-1.0f,0.0f,0.0f);
/// We can get the pose of the cam using makeCameraPose
Affine3f cam_pose = viz::makeCameraPose(cam_pos, cam_focal_point, cam_y_dir);
/// We can get the transformation matrix from camera coordinate system to global using
/// - makeTransformToGlobal. We need the axes of the camera
Affine3f transform = viz::makeTransformToGlobal(Vec3f(0.0f,-1.0f,0.0f), Vec3f(-1.0f,0.0f,0.0f), Vec3f(0.0f,0.0f,-1.0f), cam_pos);
/// Create a cloud widget.
Mat bunny_cloud = cvcloud_load();
viz::WCloud cloud_widget(bunny_cloud, viz::Color::green());
/// Pose of the widget in camera frame
Affine3f cloud_pose = Affine3f().translate(Vec3f(0.0f,0.0f,3.0f));
/// Pose of the widget in global frame
Affine3f cloud_pose_global = transform * cloud_pose;
/// Visualize camera frame
if (!camera_pov)
{
viz::WCameraPosition cpw(0.5); // Coordinate axes
viz::WCameraPosition cpw_frustum(Vec2f(0.889484, 0.523599)); // Camera frustum
myWindow.showWidget("CPW", cpw, cam_pose);
myWindow.showWidget("CPW_FRUSTUM", cpw_frustum, cam_pose);
}
/// Visualize widget
myWindow.showWidget("bunny", cloud_widget, cloud_pose_global);
/// Set the viewer pose to that of camera
if (camera_pov)
myWindow.setViewerPose(cam_pose);
/// Start event loop.
myWindow.spin();
return 0;
}

@ -0,0 +1,79 @@
/**
* @file widget_pose.cpp
* @brief Setting pose of a widget
* @author Ozan Cagri Tonkal
*/
#include <opencv2/viz.hpp>
#include <opencv2/calib3d.hpp>
#include <iostream>
using namespace cv;
using namespace std;
/**
* @function help
* @brief Display instructions to use this tutorial program
*/
void help()
{
cout
<< "--------------------------------------------------------------------------" << endl
<< "This program shows how to visualize a cube rotated around (1,1,1) and shifted "
<< "using Rodrigues vector." << endl
<< "Usage:" << endl
<< "./widget_pose" << endl
<< endl;
}
/**
* @function main
*/
int main()
{
help();
/// Create a window
viz::Viz3d myWindow("Coordinate Frame");
/// Add coordinate axes
myWindow.showWidget("Coordinate Widget", viz::WCoordinateSystem());
/// Add line to represent (1,1,1) axis
viz::WLine axis(Point3f(-1.0f,-1.0f,-1.0f), Point3f(1.0f,1.0f,1.0f));
axis.setRenderingProperty(viz::LINE_WIDTH, 4.0);
myWindow.showWidget("Line Widget", axis);
/// Construct a cube widget
viz::WCube cube_widget(Point3f(0.5,0.5,0.0), Point3f(0.0,0.0,-0.5), true, viz::Color::blue());
cube_widget.setRenderingProperty(viz::LINE_WIDTH, 4.0);
myWindow.showWidget("Cube Widget", cube_widget);
/// Rodrigues vector
Mat rot_vec = Mat::zeros(1,3,CV_32F);
float translation_phase = 0.0, translation = 0.0;
while(!myWindow.wasStopped())
{
/* Rotation using rodrigues */
/// Rotate around (1,1,1)
rot_vec.at<float>(0,0) += CV_PI * 0.01f;
rot_vec.at<float>(0,1) += CV_PI * 0.01f;
rot_vec.at<float>(0,2) += CV_PI * 0.01f;
/// Shift on (1,1,1)
translation_phase += CV_PI * 0.01f;
translation = sin(translation_phase);
Mat rot_mat;
Rodrigues(rot_vec, rot_mat);
/// Construct pose
Affine3f pose(rot_mat, Vec3f(translation, translation, translation));
myWindow.setWidgetPose("Cube Widget", pose);
myWindow.spinOnce(1, true);
}
return 0;
}
Loading…
Cancel
Save