Merge pull request #1471 from ozantonkal:master
After Width: | Height: | Size: 31 KiB |
@ -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 |
After Width: | Height: | Size: 10 KiB |
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 |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 29 KiB |
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 |
After Width: | Height: | Size: 18 KiB |
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 |
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() |
After Width: | Height: | Size: 4.2 KiB |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 17 KiB |
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 ¢er, float radius, int sphere_resolution = 10, const Color &color = Color::white()) |
||||||
|
}; |
||||||
|
|
||||||
|
viz::WSphere::WSphere |
||||||
|
--------------------- |
||||||
|
Constructs a WSphere. |
||||||
|
|
||||||
|
.. ocv:function:: WSphere(const cv::Point3f ¢er, 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 ¢er, 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 |
@ -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); |
||||||
|
} |
||||||
|
} |
@ -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; |
||||||
|
} |