Merge pull request #2178 from Nerei:viz_backport
@ -0,0 +1,26 @@ |
||||
if(NOT WITH_VTK OR ANDROID OR IOS) |
||||
return() |
||||
endif() |
||||
|
||||
if (HAVE_QT5) |
||||
message(STATUS "VTK is disabled because OpenCV is linked with Q5. Some VTK disributives are compiled with Q4 and therefore can't be linked together Qt5.") |
||||
return() |
||||
endif() |
||||
|
||||
find_package(VTK 6.0 QUIET COMPONENTS vtkRenderingCore vtkInteractionWidgets vtkInteractionStyle vtkIOLegacy vtkIOPLY vtkRenderingFreeType vtkRenderingLOD vtkFiltersTexture vtkIOExport NO_MODULE) |
||||
|
||||
if(NOT DEFINED VTK_FOUND OR NOT VTK_FOUND) |
||||
find_package(VTK 5.10 QUIET COMPONENTS vtkCommon vtkFiltering vtkRendering vtkWidgets vtkImaging NO_MODULE) |
||||
endif() |
||||
|
||||
if(NOT DEFINED VTK_FOUND OR NOT VTK_FOUND) |
||||
find_package(VTK 5.8 QUIET COMPONENTS vtkCommon vtkFiltering vtkRendering vtkWidgets vtkImaging NO_MODULE) |
||||
endif() |
||||
|
||||
if(VTK_FOUND) |
||||
set(HAVE_VTK ON) |
||||
message(STATUS "Found VTK ver. ${VTK_VERSION} (usefile: ${VTK_USE_FILE})") |
||||
else() |
||||
set(HAVE_VTK OFF) |
||||
message(STATUS "VTK is not found. Please set -DVTK_DIR in CMake to VTK build directory, or set $VTK_DIR enviroment variable to VTK install subdirectory with VTKConfig.cmake file (for windows)") |
||||
endif() |
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/vizcore.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/vizcore.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::getWindowByName("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/vizcore.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/vizcore.hpp> |
||||
#include <opencv2/calib3d/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/22HKMN657U0" frameborder="0" allowfullscreen></iframe> |
||||
</div> |
@ -0,0 +1,509 @@ |
||||
/*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) 2009, Willow Garage Inc., all rights reserved.
|
||||
// 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.
|
||||
//
|
||||
//M*/
|
||||
|
||||
#ifndef __OPENCV_CORE_AFFINE3_HPP__ |
||||
#define __OPENCV_CORE_AFFINE3_HPP__ |
||||
|
||||
#ifdef __cplusplus |
||||
|
||||
#include <opencv2/core/core.hpp> |
||||
|
||||
namespace cv |
||||
{ |
||||
template<typename T> |
||||
class Affine3 |
||||
{ |
||||
public: |
||||
typedef T float_type; |
||||
typedef Matx<float_type, 3, 3> Mat3; |
||||
typedef Matx<float_type, 4, 4> Mat4; |
||||
typedef Vec<float_type, 3> Vec3; |
||||
|
||||
Affine3(); |
||||
|
||||
//Augmented affine matrix
|
||||
Affine3(const Mat4& affine); |
||||
|
||||
//Rotation matrix
|
||||
Affine3(const Mat3& R, const Vec3& t = Vec3::all(0)); |
||||
|
||||
//Rodrigues vector
|
||||
Affine3(const Vec3& rvec, const Vec3& t = Vec3::all(0)); |
||||
|
||||
//Combines all contructors above. Supports 4x4, 4x3, 3x3, 1x3, 3x1 sizes of data matrix
|
||||
explicit Affine3(const Mat& data, const Vec3& t = Vec3::all(0)); |
||||
|
||||
//From 16th element array
|
||||
explicit Affine3(const float_type* vals); |
||||
|
||||
static Affine3 Identity(); |
||||
|
||||
//Rotation matrix
|
||||
void rotation(const Mat3& R); |
||||
|
||||
//Rodrigues vector
|
||||
void rotation(const Vec3& rvec); |
||||
|
||||
//Combines rotation methods above. Suports 3x3, 1x3, 3x1 sizes of data matrix;
|
||||
void rotation(const Mat& data); |
||||
|
||||
void linear(const Mat3& L); |
||||
void translation(const Vec3& t); |
||||
|
||||
Mat3 rotation() const; |
||||
Mat3 linear() const; |
||||
Vec3 translation() const; |
||||
|
||||
//Rodrigues vector
|
||||
Vec3 rvec() const; |
||||
|
||||
Affine3 inv(int method = cv::DECOMP_SVD) const; |
||||
|
||||
// a.rotate(R) is equivalent to Affine(R, 0) * a;
|
||||
Affine3 rotate(const Mat3& R) const; |
||||
|
||||
// a.rotate(R) is equivalent to Affine(rvec, 0) * a;
|
||||
Affine3 rotate(const Vec3& rvec) const; |
||||
|
||||
// a.translate(t) is equivalent to Affine(E, t) * a;
|
||||
Affine3 translate(const Vec3& t) const; |
||||
|
||||
// a.concatenate(affine) is equivalent to affine * a;
|
||||
Affine3 concatenate(const Affine3& affine) const; |
||||
|
||||
template <typename Y> operator Affine3<Y>() const; |
||||
|
||||
template <typename Y> Affine3<Y> cast() const; |
||||
|
||||
Mat4 matrix; |
||||
|
||||
#if defined EIGEN_WORLD_VERSION && defined EIGEN_GEOMETRY_MODULE_H |
||||
Affine3(const Eigen::Transform<T, 3, Eigen::Affine, (Eigen::RowMajor)>& affine); |
||||
Affine3(const Eigen::Transform<T, 3, Eigen::Affine>& affine); |
||||
operator Eigen::Transform<T, 3, Eigen::Affine, (Eigen::RowMajor)>() const; |
||||
operator Eigen::Transform<T, 3, Eigen::Affine>() const; |
||||
#endif |
||||
}; |
||||
|
||||
template<typename T> static |
||||
Affine3<T> operator*(const Affine3<T>& affine1, const Affine3<T>& affine2); |
||||
|
||||
template<typename T, typename V> static |
||||
V operator*(const Affine3<T>& affine, const V& vector); |
||||
|
||||
typedef Affine3<float> Affine3f; |
||||
typedef Affine3<double> Affine3d; |
||||
|
||||
static Vec3f operator*(const Affine3f& affine, const Vec3f& vector); |
||||
static Vec3d operator*(const Affine3d& affine, const Vec3d& vector); |
||||
|
||||
template<typename _Tp> class DataType< Affine3<_Tp> > |
||||
{ |
||||
public: |
||||
typedef Affine3<_Tp> value_type; |
||||
typedef Affine3<typename DataType<_Tp>::work_type> work_type; |
||||
typedef _Tp channel_type; |
||||
|
||||
enum { generic_type = 0, |
||||
depth = DataType<channel_type>::depth, |
||||
channels = 16, |
||||
fmt = DataType<channel_type>::fmt + ((channels - 1) << 8), |
||||
type = CV_MAKETYPE(depth, channels) |
||||
}; |
||||
|
||||
typedef Vec<channel_type, channels> vec_type; |
||||
}; |
||||
} |
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
/// Implementaiton
|
||||
|
||||
template<typename T> inline |
||||
cv::Affine3<T>::Affine3() |
||||
: matrix(Mat4::eye()) |
||||
{} |
||||
|
||||
template<typename T> inline |
||||
cv::Affine3<T>::Affine3(const Mat4& affine) |
||||
: matrix(affine) |
||||
{} |
||||
|
||||
template<typename T> inline |
||||
cv::Affine3<T>::Affine3(const Mat3& R, const Vec3& t) |
||||
{ |
||||
rotation(R); |
||||
translation(t); |
||||
matrix.val[12] = matrix.val[13] = matrix.val[14] = 0; |
||||
matrix.val[15] = 1; |
||||
} |
||||
|
||||
template<typename T> inline |
||||
cv::Affine3<T>::Affine3(const Vec3& _rvec, const Vec3& t) |
||||
{ |
||||
rotation(_rvec); |
||||
translation(t); |
||||
matrix.val[12] = matrix.val[13] = matrix.val[14] = 0; |
||||
matrix.val[15] = 1; |
||||
} |
||||
|
||||
template<typename T> inline |
||||
cv::Affine3<T>::Affine3(const cv::Mat& data, const Vec3& t) |
||||
{ |
||||
CV_Assert(data.type() == cv::DataType<T>::type); |
||||
|
||||
if (data.cols == 4 && data.rows == 4) |
||||
{ |
||||
data.copyTo(matrix); |
||||
return; |
||||
} |
||||
else if (data.cols == 4 && data.rows == 3) |
||||
{ |
||||
rotation(data(Rect(0, 0, 3, 3))); |
||||
translation(data(Rect(3, 0, 1, 3))); |
||||
return; |
||||
} |
||||
|
||||
rotation(data); |
||||
translation(t); |
||||
matrix.val[12] = matrix.val[13] = matrix.val[14] = 0; |
||||
matrix.val[15] = 1; |
||||
} |
||||
|
||||
template<typename T> inline |
||||
cv::Affine3<T>::Affine3(const float_type* vals) : matrix(vals) |
||||
{} |
||||
|
||||
template<typename T> inline |
||||
cv::Affine3<T> cv::Affine3<T>::Identity() |
||||
{ |
||||
return Affine3<T>(cv::Affine3<T>::Mat4::eye()); |
||||
} |
||||
|
||||
template<typename T> inline |
||||
void cv::Affine3<T>::rotation(const Mat3& R) |
||||
{ |
||||
linear(R); |
||||
} |
||||
|
||||
template<typename T> inline |
||||
void cv::Affine3<T>::rotation(const Vec3& _rvec) |
||||
{ |
||||
double rx = _rvec[0], ry = _rvec[1], rz = _rvec[2]; |
||||
double theta = std::sqrt(rx*rx + ry*ry + rz*rz); |
||||
|
||||
if (theta < DBL_EPSILON) |
||||
rotation(Mat3::eye()); |
||||
else |
||||
{ |
||||
const double I[] = { 1, 0, 0, 0, 1, 0, 0, 0, 1 }; |
||||
|
||||
double c = std::cos(theta); |
||||
double s = std::sin(theta); |
||||
double c1 = 1. - c; |
||||
double itheta = theta ? 1./theta : 0.; |
||||
|
||||
rx *= itheta; ry *= itheta; rz *= itheta; |
||||
|
||||
double rrt[] = { rx*rx, rx*ry, rx*rz, rx*ry, ry*ry, ry*rz, rx*rz, ry*rz, rz*rz }; |
||||
double _r_x_[] = { 0, -rz, ry, rz, 0, -rx, -ry, rx, 0 }; |
||||
Mat3 R; |
||||
|
||||
// R = cos(theta)*I + (1 - cos(theta))*r*rT + sin(theta)*[r_x]
|
||||
// where [r_x] is [0 -rz ry; rz 0 -rx; -ry rx 0]
|
||||
for(int k = 0; k < 9; ++k) |
||||
R.val[k] = static_cast<float_type>(c*I[k] + c1*rrt[k] + s*_r_x_[k]); |
||||
|
||||
rotation(R); |
||||
} |
||||
} |
||||
|
||||
//Combines rotation methods above. Suports 3x3, 1x3, 3x1 sizes of data matrix;
|
||||
template<typename T> inline |
||||
void cv::Affine3<T>::rotation(const cv::Mat& data) |
||||
{ |
||||
CV_Assert(data.type() == cv::DataType<T>::type); |
||||
|
||||
if (data.cols == 3 && data.rows == 3) |
||||
{ |
||||
Mat3 R; |
||||
data.copyTo(R); |
||||
rotation(R); |
||||
} |
||||
else if ((data.cols == 3 && data.rows == 1) || (data.cols == 1 && data.rows == 3)) |
||||
{ |
||||
Vec3 _rvec; |
||||
data.reshape(1, 3).copyTo(_rvec); |
||||
rotation(_rvec); |
||||
} |
||||
else |
||||
CV_Assert(!"Input marix can be 3x3, 1x3 or 3x1"); |
||||
} |
||||
|
||||
template<typename T> inline |
||||
void cv::Affine3<T>::linear(const Mat3& L) |
||||
{ |
||||
matrix.val[0] = L.val[0]; matrix.val[1] = L.val[1]; matrix.val[ 2] = L.val[2]; |
||||
matrix.val[4] = L.val[3]; matrix.val[5] = L.val[4]; matrix.val[ 6] = L.val[5]; |
||||
matrix.val[8] = L.val[6]; matrix.val[9] = L.val[7]; matrix.val[10] = L.val[8]; |
||||
} |
||||
|
||||
template<typename T> inline |
||||
void cv::Affine3<T>::translation(const Vec3& t) |
||||
{ |
||||
matrix.val[3] = t[0]; matrix.val[7] = t[1]; matrix.val[11] = t[2]; |
||||
} |
||||
|
||||
template<typename T> inline |
||||
typename cv::Affine3<T>::Mat3 cv::Affine3<T>::rotation() const |
||||
{ |
||||
return linear(); |
||||
} |
||||
|
||||
template<typename T> inline |
||||
typename cv::Affine3<T>::Mat3 cv::Affine3<T>::linear() const |
||||
{ |
||||
typename cv::Affine3<T>::Mat3 R; |
||||
R.val[0] = matrix.val[0]; R.val[1] = matrix.val[1]; R.val[2] = matrix.val[ 2]; |
||||
R.val[3] = matrix.val[4]; R.val[4] = matrix.val[5]; R.val[5] = matrix.val[ 6]; |
||||
R.val[6] = matrix.val[8]; R.val[7] = matrix.val[9]; R.val[8] = matrix.val[10]; |
||||
return R; |
||||
} |
||||
|
||||
template<typename T> inline |
||||
typename cv::Affine3<T>::Vec3 cv::Affine3<T>::translation() const |
||||
{ |
||||
return Vec3(matrix.val[3], matrix.val[7], matrix.val[11]); |
||||
} |
||||
|
||||
template<typename T> inline |
||||
typename cv::Affine3<T>::Vec3 cv::Affine3<T>::rvec() const |
||||
{ |
||||
cv::Vec3d w; |
||||
cv::Matx33d u, vt, R = rotation(); |
||||
cv::SVD::compute(R, w, u, vt, cv::SVD::FULL_UV + cv::SVD::MODIFY_A); |
||||
R = u * vt; |
||||
|
||||
double rx = R.val[7] - R.val[5]; |
||||
double ry = R.val[2] - R.val[6]; |
||||
double rz = R.val[3] - R.val[1]; |
||||
|
||||
double s = std::sqrt((rx*rx + ry*ry + rz*rz)*0.25); |
||||
double c = (R.val[0] + R.val[4] + R.val[8] - 1) * 0.5; |
||||
c = c > 1.0 ? 1.0 : c < -1.0 ? -1.0 : c; |
||||
double theta = acos(c); |
||||
|
||||
if( s < 1e-5 ) |
||||
{ |
||||
if( c > 0 ) |
||||
rx = ry = rz = 0; |
||||
else |
||||
{ |
||||
double t; |
||||
t = (R.val[0] + 1) * 0.5; |
||||
rx = std::sqrt(std::max(t, 0.0)); |
||||
t = (R.val[4] + 1) * 0.5; |
||||
ry = std::sqrt(std::max(t, 0.0)) * (R.val[1] < 0 ? -1.0 : 1.0); |
||||
t = (R.val[8] + 1) * 0.5; |
||||
rz = std::sqrt(std::max(t, 0.0)) * (R.val[2] < 0 ? -1.0 : 1.0); |
||||
|
||||
if( fabs(rx) < fabs(ry) && fabs(rx) < fabs(rz) && (R.val[5] > 0) != (ry*rz > 0) ) |
||||
rz = -rz; |
||||
theta /= std::sqrt(rx*rx + ry*ry + rz*rz); |
||||
rx *= theta; |
||||
ry *= theta; |
||||
rz *= theta; |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
double vth = 1/(2*s); |
||||
vth *= theta; |
||||
rx *= vth; ry *= vth; rz *= vth; |
||||
} |
||||
|
||||
return cv::Vec3d(rx, ry, rz); |
||||
} |
||||
|
||||
template<typename T> inline |
||||
cv::Affine3<T> cv::Affine3<T>::inv(int method) const |
||||
{ |
||||
return matrix.inv(method); |
||||
} |
||||
|
||||
template<typename T> inline |
||||
cv::Affine3<T> cv::Affine3<T>::rotate(const Mat3& R) const |
||||
{ |
||||
Mat3 Lc = linear(); |
||||
Vec3 tc = translation(); |
||||
Mat4 result; |
||||
result.val[12] = result.val[13] = result.val[14] = 0; |
||||
result.val[15] = 1; |
||||
|
||||
for(int j = 0; j < 3; ++j) |
||||
{ |
||||
for(int i = 0; i < 3; ++i) |
||||
{ |
||||
float_type value = 0; |
||||
for(int k = 0; k < 3; ++k) |
||||
value += R(j, k) * Lc(k, i); |
||||
result(j, i) = value; |
||||
} |
||||
|
||||
result(j, 3) = R.row(j).dot(tc.t()); |
||||
} |
||||
return result; |
||||
} |
||||
|
||||
template<typename T> inline |
||||
cv::Affine3<T> cv::Affine3<T>::rotate(const Vec3& _rvec) const |
||||
{ |
||||
return rotate(Affine3f(_rvec).rotation()); |
||||
} |
||||
|
||||
template<typename T> inline |
||||
cv::Affine3<T> cv::Affine3<T>::translate(const Vec3& t) const |
||||
{ |
||||
Mat4 m = matrix; |
||||
m.val[ 3] += t[0]; |
||||
m.val[ 7] += t[1]; |
||||
m.val[11] += t[2]; |
||||
return m; |
||||
} |
||||
|
||||
template<typename T> inline |
||||
cv::Affine3<T> cv::Affine3<T>::concatenate(const Affine3<T>& affine) const |
||||
{ |
||||
return (*this).rotate(affine.rotation()).translate(affine.translation()); |
||||
} |
||||
|
||||
template<typename T> template <typename Y> inline |
||||
cv::Affine3<T>::operator Affine3<Y>() const |
||||
{ |
||||
return Affine3<Y>(matrix); |
||||
} |
||||
|
||||
template<typename T> template <typename Y> inline |
||||
cv::Affine3<Y> cv::Affine3<T>::cast() const |
||||
{ |
||||
return Affine3<Y>(matrix); |
||||
} |
||||
|
||||
template<typename T> inline |
||||
cv::Affine3<T> cv::operator*(const cv::Affine3<T>& affine1, const cv::Affine3<T>& affine2) |
||||
{ |
||||
return affine2.concatenate(affine1); |
||||
} |
||||
|
||||
template<typename T, typename V> inline |
||||
V cv::operator*(const cv::Affine3<T>& affine, const V& v) |
||||
{ |
||||
const typename Affine3<T>::Mat4& m = affine.matrix; |
||||
|
||||
V r; |
||||
r.x = m.val[0] * v.x + m.val[1] * v.y + m.val[ 2] * v.z + m.val[ 3]; |
||||
r.y = m.val[4] * v.x + m.val[5] * v.y + m.val[ 6] * v.z + m.val[ 7]; |
||||
r.z = m.val[8] * v.x + m.val[9] * v.y + m.val[10] * v.z + m.val[11]; |
||||
return r; |
||||
} |
||||
|
||||
static inline |
||||
cv::Vec3f cv::operator*(const cv::Affine3f& affine, const cv::Vec3f& v) |
||||
{ |
||||
const cv::Matx44f& m = affine.matrix; |
||||
cv::Vec3f r; |
||||
r.val[0] = m.val[0] * v[0] + m.val[1] * v[1] + m.val[ 2] * v[2] + m.val[ 3]; |
||||
r.val[1] = m.val[4] * v[0] + m.val[5] * v[1] + m.val[ 6] * v[2] + m.val[ 7]; |
||||
r.val[2] = m.val[8] * v[0] + m.val[9] * v[1] + m.val[10] * v[2] + m.val[11]; |
||||
return r; |
||||
} |
||||
|
||||
static inline |
||||
cv::Vec3d cv::operator*(const cv::Affine3d& affine, const cv::Vec3d& v) |
||||
{ |
||||
const cv::Matx44d& m = affine.matrix; |
||||
cv::Vec3d r; |
||||
r.val[0] = m.val[0] * v[0] + m.val[1] * v[1] + m.val[ 2] * v[2] + m.val[ 3]; |
||||
r.val[1] = m.val[4] * v[0] + m.val[5] * v[1] + m.val[ 6] * v[2] + m.val[ 7]; |
||||
r.val[2] = m.val[8] * v[0] + m.val[9] * v[1] + m.val[10] * v[2] + m.val[11]; |
||||
return r; |
||||
} |
||||
|
||||
|
||||
|
||||
#if defined EIGEN_WORLD_VERSION && defined EIGEN_GEOMETRY_MODULE_H |
||||
|
||||
template<typename T> inline |
||||
cv::Affine3<T>::Affine3(const Eigen::Transform<T, 3, Eigen::Affine, (Eigen::RowMajor)>& affine) |
||||
{ |
||||
cv::Mat(4, 4, cv::DataType<T>::type, affine.matrix().data()).copyTo(matrix); |
||||
} |
||||
|
||||
template<typename T> inline |
||||
cv::Affine3<T>::Affine3(const Eigen::Transform<T, 3, Eigen::Affine>& affine) |
||||
{ |
||||
Eigen::Transform<T, 3, Eigen::Affine, (Eigen::RowMajor)> a = affine; |
||||
cv::Mat(4, 4, cv::DataType<T>::type, a.matrix().data()).copyTo(matrix); |
||||
} |
||||
|
||||
template<typename T> inline |
||||
cv::Affine3<T>::operator Eigen::Transform<T, 3, Eigen::Affine, (Eigen::RowMajor)>() const |
||||
{ |
||||
Eigen::Transform<T, 3, Eigen::Affine, (Eigen::RowMajor)> r; |
||||
cv::Mat hdr(4, 4, cv::DataType<T>::type, r.matrix().data()); |
||||
cv::Mat(matrix, false).copyTo(hdr); |
||||
return r; |
||||
} |
||||
|
||||
template<typename T> inline |
||||
cv::Affine3<T>::operator Eigen::Transform<T, 3, Eigen::Affine>() const |
||||
{ |
||||
return this->operator Eigen::Transform<T, 3, Eigen::Affine, (Eigen::RowMajor)>(); |
||||
} |
||||
|
||||
#endif /* defined EIGEN_WORLD_VERSION && defined EIGEN_GEOMETRY_MODULE_H */ |
||||
|
||||
|
||||
#endif /* __cplusplus */ |
||||
|
||||
#endif /* __OPENCV_CORE_AFFINE3_HPP__ */ |
@ -0,0 +1,11 @@ |
||||
if(NOT WITH_VTK OR NOT DEFINED HAVE_VTK OR NOT HAVE_VTK) |
||||
ocv_module_disable(viz) |
||||
endif() |
||||
|
||||
include(${VTK_USE_FILE}) |
||||
set(the_description "Viz") |
||||
ocv_define_module(viz opencv_core ${VTK_LIBRARIES}) |
||||
|
||||
if(APPLE AND BUILD_opencv_viz) |
||||
target_link_libraries(opencv_viz "-framework Cocoa") |
||||
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,637 @@ |
||||
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:: Affine3d 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:: Affine3d 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::getWindowByName |
||||
-------------------- |
||||
Retrieves a window by its name. |
||||
|
||||
.. ocv:function:: Viz3d getWindowByName(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::getWindowByName("myWindow"); |
||||
viz::Viz3d window_2 = viz::getWindowByName("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::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 Affine3d &pose = Affine3d::Identity()); |
||||
void removeWidget(const String &id); |
||||
Widget getWidget(const String &id) const; |
||||
void removeAllWidgets(); |
||||
|
||||
void setWidgetPose(const String &id, const Affine3d &pose); |
||||
void updateWidgetPose(const String &id, const Affine3d &pose); |
||||
Affine3d getWidgetPose(const String &id) const; |
||||
|
||||
void showImage(InputArray image, const Size& window_size = Size(-1, -1)); |
||||
|
||||
void setCamera(const Camera &camera); |
||||
Camera getCamera() const; |
||||
Affine3d getViewerPose(); |
||||
void setViewerPose(const Affine3d &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 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 Affine3d &pose = Affine3d::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::showImage |
||||
--------------------- |
||||
Removed all widgets and displays image scaled to whole window area. |
||||
|
||||
.. ocv:function:: void showImage(InputArray image, const Size& window_size = Size(-1, -1)) |
||||
|
||||
:param image: Image to be displayed. |
||||
:param size: Size of Viz3d window. Default value means no change. |
||||
|
||||
viz::Viz3d::setWidgetPose |
||||
------------------------- |
||||
Sets pose of a widget in the window. |
||||
|
||||
.. ocv:function:: void setWidgetPose(const String &id, const Affine3d &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 Affine3d &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:: Affine3d 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:: Affine3d getViewerPose() |
||||
|
||||
viz::Viz3d::setViewerPose |
||||
------------------------- |
||||
Sets pose of the viewer. |
||||
|
||||
.. ocv:function:: void setViewerPose(const Affine3d &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::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::Mesh |
||||
----------- |
||||
.. ocv:class:: Mesh |
||||
|
||||
This class wraps mesh attributes, and it can load a mesh from a ``ply`` file. :: |
||||
|
||||
class CV_EXPORTS Mesh |
||||
{ |
||||
public: |
||||
|
||||
Mat cloud, colors, normals; |
||||
|
||||
//! Raw integer list of the form: (n,id1,id2,...,idn, n,id1,id2,...,idn, ...) |
||||
//! where n is the number of points in the poligon, and id is a zero-offset index into an associated cloud. |
||||
Mat polygons; |
||||
|
||||
//! Loads mesh from a given ply file |
||||
static Mesh load(const String& file); |
||||
}; |
||||
|
||||
viz::Mesh::load |
||||
--------------------- |
||||
Loads a mesh from a ``ply`` file. |
||||
|
||||
.. ocv:function:: static Mesh load(const String& file) |
||||
|
||||
:param file: File name (for no only PLY is supported) |
||||
|
||||
|
||||
viz::KeyboardEvent |
||||
------------------ |
||||
.. ocv:class:: KeyboardEvent |
||||
|
||||
This class represents a keyboard event. :: |
||||
|
||||
class CV_EXPORTS KeyboardEvent |
||||
{ |
||||
public: |
||||
enum { ALT = 1, CTRL = 2, SHIFT = 4 }; |
||||
enum Action { KEY_UP = 0, KEY_DOWN = 1 }; |
||||
|
||||
KeyboardEvent(Action action, const String& symbol, unsigned char code, int modifiers); |
||||
|
||||
Action action; |
||||
String symbol; |
||||
unsigned char code; |
||||
int modifiers; |
||||
}; |
||||
|
||||
viz::KeyboardEvent::KeyboardEvent |
||||
--------------------------------- |
||||
Constructs a KeyboardEvent. |
||||
|
||||
.. ocv:function:: KeyboardEvent (Action action, const String& symbol, unsigned char code, Modifiers modifiers) |
||||
|
||||
:param action: Signals if key is pressed or released. |
||||
:param symbol: Name of the key. |
||||
:param code: Code of the key. |
||||
:param modifiers: Signals if ``alt``, ``ctrl`` or ``shift`` are pressed or their combination. |
||||
|
||||
|
||||
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& pointer, int modifiers); |
||||
|
||||
Type type; |
||||
MouseButton button; |
||||
Point pointer; |
||||
int modifiers; |
||||
}; |
||||
|
||||
viz::MouseEvent::MouseEvent |
||||
--------------------------- |
||||
Constructs a MouseEvent. |
||||
|
||||
.. ocv:function:: MouseEvent (const Type& type, const MouseButton& button, const Point& p, Modifiers modifiers) |
||||
|
||||
: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 modifiers: Signals if ``alt``, ``ctrl`` or ``shift`` are pressed or their combination. |
||||
|
||||
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(double f_x, double f_y, double c_x, double c_y, const Size &window_size); |
||||
Camera(const Vec2d &fov, const Size &window_size); |
||||
Camera(const Matx33d &K, const Size &window_size); |
||||
Camera(const Matx44d &proj, const Size &window_size); |
||||
|
||||
inline const Vec2d & getClip() const; |
||||
inline void setClip(const Vec2d &clip); |
||||
|
||||
inline const Size & getWindowSize() const; |
||||
void setWindowSize(const Size &window_size); |
||||
|
||||
inline const Vec2d & getFov() const; |
||||
inline void setFov(const Vec2d & fov); |
||||
|
||||
inline const Vec2d & getPrincipalPoint() const; |
||||
inline const Vec2d & getFocalLength() const; |
||||
|
||||
void computeProjectionMatrix(Matx44d &proj) const; |
||||
|
||||
static Camera KinectCamera(const Size &window_size); |
||||
|
||||
private: |
||||
/* hidden */ |
||||
}; |
||||
|
||||
viz::Camera::Camera |
||||
------------------- |
||||
Constructs a Camera. |
||||
|
||||
.. ocv:function:: Camera(double f_x, double f_y, double c_x, double 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 Vec2d &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 Matx33d &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 Matx44d &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(Matx44d &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,236 @@ |
||||
/*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
|
||||
//
|
||||
//M*/
|
||||
|
||||
#ifndef __OPENCV_VIZ_TYPES_HPP__ |
||||
#define __OPENCV_VIZ_TYPES_HPP__ |
||||
|
||||
#include <string> |
||||
#include <opencv2/core/core.hpp> |
||||
#include <opencv2/core/affine.hpp> |
||||
|
||||
namespace cv |
||||
{ |
||||
namespace viz |
||||
{ |
||||
class 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(); |
||||
|
||||
static Color mlab(); |
||||
|
||||
static Color navy(); |
||||
static Color olive(); |
||||
static Color maroon(); |
||||
static Color teal(); |
||||
static Color rose(); |
||||
static Color azure(); |
||||
static Color lime(); |
||||
static Color gold(); |
||||
static Color brown(); |
||||
static Color orange(); |
||||
static Color chartreuse(); |
||||
static Color orange_red(); |
||||
static Color purple(); |
||||
static Color indigo(); |
||||
|
||||
static Color pink(); |
||||
static Color cherry(); |
||||
static Color bluberry(); |
||||
static Color raspberry(); |
||||
static Color silver(); |
||||
static Color violet(); |
||||
static Color apricot(); |
||||
static Color turquoise(); |
||||
static Color celestial_blue(); |
||||
static Color amethyst(); |
||||
|
||||
static Color not_set(); |
||||
}; |
||||
|
||||
class CV_EXPORTS Mesh |
||||
{ |
||||
public: |
||||
Mat cloud, colors, normals; |
||||
|
||||
//! Raw integer list of the form: (n,id1,id2,...,idn, n,id1,id2,...,idn, ...)
|
||||
//! where n is the number of points in the poligon, and id is a zero-offset index into an associated cloud.
|
||||
Mat polygons; |
||||
|
||||
Mat texture, tcoords; |
||||
|
||||
//! Loads mesh from a given ply file (no texture load support for now)
|
||||
static Mesh load(const String& file); |
||||
}; |
||||
|
||||
class CV_EXPORTS Camera |
||||
{ |
||||
public: |
||||
Camera(double fx, double fy, double cx, double cy, const Size &window_size); |
||||
explicit Camera(const Vec2d &fov, const Size &window_size); |
||||
explicit Camera(const Matx33d &K, const Size &window_size); |
||||
explicit Camera(const Matx44d &proj, const Size &window_size); |
||||
|
||||
const Vec2d & getClip() const { return clip_; } |
||||
void setClip(const Vec2d &clip) { clip_ = clip; } |
||||
|
||||
const Size & getWindowSize() const { return window_size_; } |
||||
void setWindowSize(const Size &window_size); |
||||
|
||||
const Vec2d& getFov() const { return fov_; } |
||||
void setFov(const Vec2d& fov) { fov_ = fov; } |
||||
|
||||
const Vec2d& getPrincipalPoint() const { return principal_point_; } |
||||
const Vec2d& getFocalLength() const { return focal_; } |
||||
|
||||
void computeProjectionMatrix(Matx44d &proj) const; |
||||
|
||||
static Camera KinectCamera(const Size &window_size); |
||||
|
||||
private: |
||||
void init(double fx, double fy, double cx, double cy, const Size &window_size); |
||||
|
||||
Vec2d clip_; |
||||
Vec2d fov_; |
||||
Size window_size_; |
||||
Vec2d principal_point_; |
||||
Vec2d focal_; |
||||
}; |
||||
|
||||
class CV_EXPORTS KeyboardEvent |
||||
{ |
||||
public: |
||||
enum { NONE = 0, ALT = 1, CTRL = 2, SHIFT = 4 }; |
||||
enum Action { KEY_UP = 0, KEY_DOWN = 1 }; |
||||
|
||||
KeyboardEvent(Action action, const String& symbol, unsigned char code, int modifiers); |
||||
|
||||
Action action; |
||||
String symbol; |
||||
unsigned char code; |
||||
int modifiers; |
||||
}; |
||||
|
||||
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& pointer, int modifiers); |
||||
|
||||
Type type; |
||||
MouseButton button; |
||||
Point pointer; |
||||
int modifiers; |
||||
}; |
||||
} /* namespace viz */ |
||||
} /* namespace cv */ |
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// cv::viz::Color
|
||||
|
||||
inline cv::viz::Color::Color() : Scalar(0, 0, 0) {} |
||||
inline cv::viz::Color::Color(double _gray) : Scalar(_gray, _gray, _gray) {} |
||||
inline cv::viz::Color::Color(double _blue, double _green, double _red) : Scalar(_blue, _green, _red) {} |
||||
inline cv::viz::Color::Color(const Scalar& color) : Scalar(color) {} |
||||
|
||||
inline cv::viz::Color cv::viz::Color::black() { return Color( 0, 0, 0); } |
||||
inline cv::viz::Color cv::viz::Color::green() { return Color( 0, 255, 0); } |
||||
inline cv::viz::Color cv::viz::Color::blue() { return Color(255, 0, 0); } |
||||
inline cv::viz::Color cv::viz::Color::cyan() { return Color(255, 255, 0); } |
||||
inline cv::viz::Color cv::viz::Color::red() { return Color( 0, 0, 255); } |
||||
inline cv::viz::Color cv::viz::Color::yellow() { return Color( 0, 255, 255); } |
||||
inline cv::viz::Color cv::viz::Color::magenta() { return Color(255, 0, 255); } |
||||
inline cv::viz::Color cv::viz::Color::white() { return Color(255, 255, 255); } |
||||
inline cv::viz::Color cv::viz::Color::gray() { return Color(128, 128, 128); } |
||||
|
||||
inline cv::viz::Color cv::viz::Color::mlab() { return Color(255, 128, 128); } |
||||
|
||||
inline cv::viz::Color cv::viz::Color::navy() { return Color(0, 0, 128); } |
||||
inline cv::viz::Color cv::viz::Color::olive() { return Color(0, 128, 128); } |
||||
inline cv::viz::Color cv::viz::Color::maroon() { return Color(0, 0, 128); } |
||||
inline cv::viz::Color cv::viz::Color::teal() { return Color(128, 128, 0); } |
||||
inline cv::viz::Color cv::viz::Color::rose() { return Color(128, 0, 255); } |
||||
inline cv::viz::Color cv::viz::Color::azure() { return Color(255, 128, 0); } |
||||
inline cv::viz::Color cv::viz::Color::lime() { return Color(0, 255, 191); } |
||||
inline cv::viz::Color cv::viz::Color::gold() { return Color(0, 215, 255); } |
||||
inline cv::viz::Color cv::viz::Color::brown() { return Color(0, 75, 150); } |
||||
inline cv::viz::Color cv::viz::Color::orange() { return Color(0, 165, 255); } |
||||
inline cv::viz::Color cv::viz::Color::chartreuse() { return Color(0, 255, 128); } |
||||
inline cv::viz::Color cv::viz::Color::orange_red() { return Color(0, 69, 255); } |
||||
inline cv::viz::Color cv::viz::Color::purple() { return Color(128, 0, 128); } |
||||
inline cv::viz::Color cv::viz::Color::indigo() { return Color(130, 0, 75); } |
||||
|
||||
inline cv::viz::Color cv::viz::Color::pink() { return Color(203, 192, 255); } |
||||
inline cv::viz::Color cv::viz::Color::cherry() { return Color( 99, 29, 222); } |
||||
inline cv::viz::Color cv::viz::Color::bluberry() { return Color(247, 134, 79); } |
||||
inline cv::viz::Color cv::viz::Color::raspberry() { return Color( 92, 11, 227); } |
||||
inline cv::viz::Color cv::viz::Color::silver() { return Color(192, 192, 192); } |
||||
inline cv::viz::Color cv::viz::Color::violet() { return Color(226, 43, 138); } |
||||
inline cv::viz::Color cv::viz::Color::apricot() { return Color(177, 206, 251); } |
||||
inline cv::viz::Color cv::viz::Color::turquoise() { return Color(208, 224, 64); } |
||||
inline cv::viz::Color cv::viz::Color::celestial_blue() { return Color(208, 151, 73); } |
||||
inline cv::viz::Color cv::viz::Color::amethyst() { return Color(204, 102, 153); } |
||||
|
||||
inline cv::viz::Color cv::viz::Color::not_set() { return Color(-1, -1, -1); } |
||||
|
||||
#endif |
@ -0,0 +1,131 @@ |
||||
/*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
|
||||
//
|
||||
//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 && !defined CVAPI_EXPORTS |
||||
//#error "Viz is in beta state now. Please define macro above to use it"
|
||||
#endif |
||||
|
||||
#include <opencv2/core/core.hpp> |
||||
#include <opencv2/viz/types.hpp> |
||||
#include <opencv2/viz/widgets.hpp> |
||||
|
||||
namespace cv |
||||
{ |
||||
namespace viz |
||||
{ |
||||
class CV_EXPORTS Viz3d |
||||
{ |
||||
public: |
||||
typedef cv::viz::Color Color; |
||||
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 Affine3d &pose = Affine3d::Identity()); |
||||
void removeWidget(const String &id); |
||||
Widget getWidget(const String &id) const; |
||||
void removeAllWidgets(); |
||||
|
||||
void showImage(InputArray image, const Size& window_size = Size(-1, -1)); |
||||
|
||||
void setWidgetPose(const String &id, const Affine3d &pose); |
||||
void updateWidgetPose(const String &id, const Affine3d &pose); |
||||
Affine3d getWidgetPose(const String &id) const; |
||||
|
||||
void setCamera(const Camera &camera); |
||||
Camera getCamera() const; |
||||
Affine3d getViewerPose(); |
||||
void setViewerPose(const Affine3d &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(const Point& window_position); |
||||
void setFullScreen(bool mode = true); |
||||
void setBackgroundColor(const Color& color = Color::black(), const Color& color2 = Color::not_set()); |
||||
void setBackgroundTexture(InputArray image = noArray()); |
||||
void setBackgroundMeshLab(); |
||||
|
||||
void spin(); |
||||
void spinOnce(int time = 1, bool force_redraw = false); |
||||
bool wasStopped() const; |
||||
void close(); |
||||
|
||||
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 setRepresentation(int representation); |
||||
private: |
||||
|
||||
struct VizImpl; |
||||
VizImpl* impl_; |
||||
|
||||
void create(const String &window_name); |
||||
void release(); |
||||
|
||||
friend class VizStorage; |
||||
}; |
||||
|
||||
} /* namespace viz */ |
||||
} /* namespace cv */ |
||||
|
||||
#endif |
@ -0,0 +1,127 @@ |
||||
/*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
|
||||
//
|
||||
//M*/
|
||||
|
||||
#ifndef __OPENCV_VIZCORE_HPP__ |
||||
#define __OPENCV_VIZCORE_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 Affine3d makeTransformToGlobal(const Vec3d& axis_x, const Vec3d& axis_y, const Vec3d& axis_z, const Vec3d& origin = Vec3d::all(0)); |
||||
|
||||
//! constructs camera pose from position, focal_point and up_vector (see gluLookAt() for more infromation)
|
||||
CV_EXPORTS Affine3d makeCameraPose(const Vec3d& position, const Vec3d& focal_point, const Vec3d& y_dir); |
||||
|
||||
//! retrieves a window by its name. If no window with such name, then it creates new.
|
||||
CV_EXPORTS Viz3d getWindowByName(const String &window_name); |
||||
|
||||
//! Unregisters all Viz windows from internal database. After it 'getWindowByName()' will create new windows instead getting existing from the database.
|
||||
CV_EXPORTS void unregisterAllWindows(); |
||||
|
||||
//! Displays image in specified window
|
||||
CV_EXPORTS Viz3d imshow(const String& window_name, InputArray image, const Size& window_size = Size(-1, -1)); |
||||
|
||||
//! 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); } |
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// Read/write clouds. Supported formats: ply, xyz, obj and stl (readonly)
|
||||
|
||||
CV_EXPORTS void writeCloud(const String& file, InputArray cloud, InputArray colors = noArray(), InputArray normals = noArray(), bool binary = false); |
||||
CV_EXPORTS Mat readCloud (const String& file, OutputArray colors = noArray(), OutputArray normals = noArray()); |
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// Reads mesh. Only ply format is supported now and no texture load support
|
||||
|
||||
CV_EXPORTS Mesh readMesh(const String& file); |
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// Read/write poses and trajectories
|
||||
|
||||
CV_EXPORTS bool readPose(const String& file, Affine3d& pose, const String& tag = "pose"); |
||||
CV_EXPORTS void writePose(const String& file, const Affine3d& pose, const String& tag = "pose"); |
||||
|
||||
//! takes vector<Affine3<T>> with T = float/dobule and writes to a sequence of files with given filename format
|
||||
CV_EXPORTS void writeTrajectory(InputArray traj, const String& files_format = "pose%05d.xml", int start = 0, const String& tag = "pose"); |
||||
|
||||
//! takes vector<Affine3<T>> with T = float/dobule and loads poses from sequence of files
|
||||
CV_EXPORTS void readTrajectory(OutputArray traj, const String& files_format = "pose%05d.xml", int start = 0, int end = INT_MAX, const String& tag = "pose"); |
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// Computing normals for mesh
|
||||
|
||||
CV_EXPORTS void computeNormals(const Mesh& mesh, OutputArray normals); |
||||
|
||||
} /* namespace viz */ |
||||
} /* namespace cv */ |
||||
|
||||
#endif /* __OPENCV_VIZCORE_HPP__ */ |
@ -0,0 +1,69 @@ |
||||
/*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
|
||||
//
|
||||
//M*/
|
||||
|
||||
#ifndef __OPENCV_VIZ_WIDGET_ACCESSOR_HPP__ |
||||
#define __OPENCV_VIZ_WIDGET_ACCESSOR_HPP__ |
||||
|
||||
#include <opencv2/core/types_c.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,396 @@ |
||||
/*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
|
||||
//
|
||||
//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 RepresentationValues |
||||
{ |
||||
REPRESENTATION_POINTS, |
||||
REPRESENTATION_WIREFRAME, |
||||
REPRESENTATION_SURFACE |
||||
}; |
||||
|
||||
enum ShadingValues |
||||
{ |
||||
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() {} |
||||
|
||||
//! widget position manipulation, i.e. place where it is rendered
|
||||
void setPose(const Affine3d &pose); |
||||
void updatePose(const Affine3d &pose); |
||||
Affine3d getPose() const; |
||||
|
||||
//! update internal widget data, i.e. points, normals, etc.
|
||||
void applyTransform(const Affine3d &transform); |
||||
|
||||
void setColor(const Color &color); |
||||
|
||||
}; |
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
/// The base class for all 2D widgets
|
||||
class CV_EXPORTS Widget2D : public Widget |
||||
{ |
||||
public: |
||||
Widget2D() {} |
||||
|
||||
void setColor(const Color &color); |
||||
}; |
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
/// Simple widgets
|
||||
|
||||
class CV_EXPORTS WLine : public Widget3D |
||||
{ |
||||
public: |
||||
WLine(const Point3d &pt1, const Point3d &pt2, const Color &color = Color::white()); |
||||
}; |
||||
|
||||
class CV_EXPORTS WPlane : public Widget3D |
||||
{ |
||||
public: |
||||
//! created default plane with center point at origin and normal oriented along z-axis
|
||||
WPlane(const Size2d& size = Size2d(1.0, 1.0), const Color &color = Color::white()); |
||||
|
||||
//! repositioned plane
|
||||
WPlane(const Point3d& center, const Vec3d& normal, const Vec3d& new_yaxis, |
||||
const Size2d& size = Size2d(1.0, 1.0), const Color &color = Color::white()); |
||||
}; |
||||
|
||||
class CV_EXPORTS WSphere : public Widget3D |
||||
{ |
||||
public: |
||||
WSphere(const cv::Point3d ¢er, double radius, int sphere_resolution = 10, const Color &color = Color::white()); |
||||
}; |
||||
|
||||
class CV_EXPORTS WArrow : public Widget3D |
||||
{ |
||||
public: |
||||
WArrow(const Point3d& pt1, const Point3d& pt2, double thickness = 0.03, const Color &color = Color::white()); |
||||
}; |
||||
|
||||
class CV_EXPORTS WCircle : public Widget3D |
||||
{ |
||||
public: |
||||
//! creates default planar circle centred at origin with plane normal along z-axis
|
||||
WCircle(double radius, double thickness = 0.01, const Color &color = Color::white()); |
||||
|
||||
//! creates repositioned circle
|
||||
WCircle(double radius, const Point3d& center, const Vec3d& normal, double thickness = 0.01, const Color &color = Color::white()); |
||||
}; |
||||
|
||||
class CV_EXPORTS WCone : public Widget3D |
||||
{ |
||||
public: |
||||
//! create default cone, oriented along x-axis with center of its base located at origin
|
||||
WCone(double length, double radius, int resolution = 6.0, const Color &color = Color::white()); |
||||
|
||||
//! creates repositioned cone
|
||||
WCone(double radius, const Point3d& center, const Point3d& tip, int resolution = 6.0, const Color &color = Color::white()); |
||||
}; |
||||
|
||||
class CV_EXPORTS WCylinder : public Widget3D |
||||
{ |
||||
public: |
||||
WCylinder(const Point3d& axis_point1, const Point3d& axis_point2, double radius, int numsides = 30, const Color &color = Color::white()); |
||||
}; |
||||
|
||||
class CV_EXPORTS WCube : public Widget3D |
||||
{ |
||||
public: |
||||
WCube(const Point3d& min_point = Vec3d::all(-0.5), const Point3d& max_point = Vec3d::all(0.5), |
||||
bool wire_frame = true, const Color &color = Color::white()); |
||||
}; |
||||
|
||||
class CV_EXPORTS WPolyLine : public Widget3D |
||||
{ |
||||
public: |
||||
WPolyLine(InputArray points, const Color &color = Color::white()); |
||||
}; |
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
/// Text and image widgets
|
||||
|
||||
class CV_EXPORTS WText : public Widget2D |
||||
{ |
||||
public: |
||||
WText(const String &text, const Point &pos, int font_size = 20, const Color &color = Color::white()); |
||||
|
||||
void setText(const String &text); |
||||
String getText() const; |
||||
}; |
||||
|
||||
class CV_EXPORTS WText3D : public Widget3D |
||||
{ |
||||
public: |
||||
//! creates text label in 3D. If face_camera = false, text plane normal is oriented along z-axis. Use widget pose to orient it properly
|
||||
WText3D(const String &text, const Point3d &position, double text_scale = 1., bool face_camera = true, const Color &color = Color::white()); |
||||
|
||||
void setText(const String &text); |
||||
String getText() const; |
||||
}; |
||||
|
||||
class CV_EXPORTS WImageOverlay : public Widget2D |
||||
{ |
||||
public: |
||||
WImageOverlay(InputArray image, const Rect &rect); |
||||
void setImage(InputArray image); |
||||
}; |
||||
|
||||
class CV_EXPORTS WImage3D : public Widget3D |
||||
{ |
||||
public: |
||||
//! Creates 3D image in a plane centered at the origin with normal orientaion along z-axis,
|
||||
//! image x- and y-axes are oriented along x- and y-axes of 3d world
|
||||
WImage3D(InputArray image, const Size2d &size); |
||||
|
||||
//! Creates 3D image at a given position, pointing in the direction of the normal, and having the up_vector orientation
|
||||
WImage3D(InputArray image, const Size2d &size, const Vec3d ¢er, const Vec3d &normal, const Vec3d &up_vector); |
||||
|
||||
void setImage(InputArray image); |
||||
}; |
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
/// Compond widgets
|
||||
|
||||
class CV_EXPORTS WCoordinateSystem : public Widget3D |
||||
{ |
||||
public: |
||||
WCoordinateSystem(double scale = 1.0); |
||||
}; |
||||
|
||||
class CV_EXPORTS WGrid : public Widget3D |
||||
{ |
||||
public: |
||||
//! Creates grid at the origin and normal oriented along z-axis
|
||||
WGrid(const Vec2i &cells = Vec2i::all(10), const Vec2d &cells_spacing = Vec2d::all(1.0), const Color &color = Color::white()); |
||||
|
||||
//! Creates repositioned grid
|
||||
WGrid(const Point3d& center, const Vec3d& normal, const Vec3d& new_yaxis, |
||||
const Vec2i &cells = Vec2i::all(10), const Vec2d &cells_spacing = Vec2d::all(1.0), const Color &color = Color::white()); |
||||
}; |
||||
|
||||
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 Matx33d &K, double scale = 1.0, const Color &color = Color::white()); |
||||
//! Creates frustum based on the field of view at the origin
|
||||
WCameraPosition(const Vec2d &fov, double scale = 1.0, const Color &color = Color::white()); |
||||
//! Creates frustum and display given image at the far plane
|
||||
WCameraPosition(const Matx33d &K, InputArray image, double scale = 1.0, const Color &color = Color::white()); |
||||
//! Creates frustum and display given image at the far plane
|
||||
WCameraPosition(const Vec2d &fov, InputArray image, double scale = 1.0, const Color &color = Color::white()); |
||||
}; |
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
/// Trajectories
|
||||
|
||||
class CV_EXPORTS WTrajectory : public Widget3D |
||||
{ |
||||
public: |
||||
enum {FRAMES = 1, PATH = 2, BOTH = FRAMES + PATH }; |
||||
|
||||
//! Takes vector<Affine3<T>> and displays trajectory of the given path either by coordinate frames or polyline
|
||||
WTrajectory(InputArray path, int display_mode = WTrajectory::PATH, double scale = 1.0, const Color &color = Color::white()); |
||||
}; |
||||
|
||||
class CV_EXPORTS WTrajectoryFrustums : public Widget3D |
||||
{ |
||||
public: |
||||
//! Takes vector<Affine3<T>> and displays trajectory of the given path by frustums
|
||||
WTrajectoryFrustums(InputArray path, const Matx33d &K, double scale = 1., const Color &color = Color::white()); |
||||
|
||||
//! Takes vector<Affine3<T>> and displays trajectory of the given path by frustums
|
||||
WTrajectoryFrustums(InputArray path, const Vec2d &fov, double scale = 1., const Color &color = Color::white()); |
||||
}; |
||||
|
||||
class CV_EXPORTS WTrajectorySpheres: public Widget3D |
||||
{ |
||||
public: |
||||
//! Takes vector<Affine3<T>> and displays trajectory of the given path
|
||||
WTrajectorySpheres(InputArray path, double line_length = 0.05, double radius = 0.007, |
||||
const Color &from = Color::red(), const Color &to = Color::white()); |
||||
}; |
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
/// Clouds
|
||||
|
||||
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()); |
||||
}; |
||||
|
||||
class CV_EXPORTS WPaintedCloud: public Widget3D |
||||
{ |
||||
public: |
||||
//! Paint cloud with default gradient between cloud bounds points
|
||||
WPaintedCloud(InputArray cloud); |
||||
|
||||
//! Paint cloud with default gradient between given points
|
||||
WPaintedCloud(InputArray cloud, const Point3d& p1, const Point3d& p2); |
||||
|
||||
//! Paint cloud with gradient specified by given colors between given points
|
||||
WPaintedCloud(InputArray cloud, const Point3d& p1, const Point3d& p2, const Color& c1, const Color c2); |
||||
}; |
||||
|
||||
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 Affine3d &pose = Affine3d::Identity()); |
||||
//! All points in cloud have the same color
|
||||
void addCloud(InputArray cloud, const Color &color = Color::white(), const Affine3d &pose = Affine3d::Identity()); |
||||
}; |
||||
|
||||
class CV_EXPORTS WCloudNormals : public Widget3D |
||||
{ |
||||
public: |
||||
WCloudNormals(InputArray cloud, InputArray normals, int level = 64, double scale = 0.1, const Color &color = Color::white()); |
||||
}; |
||||
|
||||
class CV_EXPORTS WMesh : public Widget3D |
||||
{ |
||||
public: |
||||
WMesh(const Mesh &mesh); |
||||
WMesh(InputArray cloud, InputArray polygons, InputArray colors = noArray(), InputArray normals = noArray()); |
||||
}; |
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
/// Utility exports
|
||||
|
||||
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 WCone Widget::cast<WCone>(); |
||||
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 WTrajectoryFrustums Widget::cast<WTrajectoryFrustums>(); |
||||
template<> CV_EXPORTS WTrajectorySpheres Widget::cast<WTrajectorySpheres>(); |
||||
template<> CV_EXPORTS WCloud Widget::cast<WCloud>(); |
||||
template<> CV_EXPORTS WPaintedCloud Widget::cast<WPaintedCloud>(); |
||||
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,441 @@ |
||||
/*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
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "precomp.hpp" |
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// Point Cloud Widget implementation
|
||||
|
||||
cv::viz::WCloud::WCloud(InputArray cloud, InputArray colors) |
||||
{ |
||||
CV_Assert(!cloud.empty() && !colors.empty()); |
||||
|
||||
vtkSmartPointer<vtkCloudMatSource> cloud_source = vtkSmartPointer<vtkCloudMatSource>::New(); |
||||
cloud_source->SetColorCloud(cloud, colors); |
||||
cloud_source->Update(); |
||||
|
||||
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New(); |
||||
VtkUtils::SetInputData(mapper, cloud_source->GetOutput()); |
||||
mapper->SetScalarModeToUsePointData(); |
||||
mapper->ImmediateModeRenderingOff(); |
||||
mapper->SetScalarRange(0, 255); |
||||
mapper->ScalarVisibilityOn(); |
||||
|
||||
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New(); |
||||
actor->GetProperty()->SetInterpolationToFlat(); |
||||
actor->GetProperty()->BackfaceCullingOn(); |
||||
actor->SetMapper(mapper); |
||||
|
||||
WidgetAccessor::setProp(*this, actor); |
||||
} |
||||
|
||||
cv::viz::WCloud::WCloud(InputArray cloud, const Color &color) |
||||
{ |
||||
WCloud cloud_widget(cloud, Mat(cloud.size(), CV_8UC3, color)); |
||||
*this = cloud_widget; |
||||
} |
||||
|
||||
|
||||
template<> cv::viz::WCloud cv::viz::Widget::cast<cv::viz::WCloud>() |
||||
{ |
||||
Widget3D widget = this->cast<Widget3D>(); |
||||
return static_cast<WCloud&>(widget); |
||||
} |
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// Painted Cloud Widget implementation
|
||||
|
||||
cv::viz::WPaintedCloud::WPaintedCloud(InputArray cloud) |
||||
{ |
||||
vtkSmartPointer<vtkCloudMatSource> cloud_source = vtkSmartPointer<vtkCloudMatSource>::New(); |
||||
cloud_source->SetCloud(cloud); |
||||
cloud_source->Update(); |
||||
|
||||
Vec6d bounds(cloud_source->GetOutput()->GetPoints()->GetBounds()); |
||||
|
||||
vtkSmartPointer<vtkElevationFilter> elevation = vtkSmartPointer<vtkElevationFilter>::New(); |
||||
elevation->SetInputConnection(cloud_source->GetOutputPort()); |
||||
elevation->SetLowPoint(bounds[0], bounds[2], bounds[4]); |
||||
elevation->SetHighPoint(bounds[1], bounds[3], bounds[5]); |
||||
elevation->SetScalarRange(0.0, 1.0); |
||||
elevation->Update(); |
||||
|
||||
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New(); |
||||
VtkUtils::SetInputData(mapper, vtkPolyData::SafeDownCast(elevation->GetOutput())); |
||||
mapper->ImmediateModeRenderingOff(); |
||||
mapper->ScalarVisibilityOn(); |
||||
mapper->SetColorModeToMapScalars(); |
||||
|
||||
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New(); |
||||
actor->GetProperty()->SetInterpolationToFlat(); |
||||
actor->GetProperty()->BackfaceCullingOn(); |
||||
actor->SetMapper(mapper); |
||||
|
||||
WidgetAccessor::setProp(*this, actor); |
||||
} |
||||
|
||||
cv::viz::WPaintedCloud::WPaintedCloud(InputArray cloud, const Point3d& p1, const Point3d& p2) |
||||
{ |
||||
vtkSmartPointer<vtkCloudMatSource> cloud_source = vtkSmartPointer<vtkCloudMatSource>::New(); |
||||
cloud_source->SetCloud(cloud); |
||||
|
||||
vtkSmartPointer<vtkElevationFilter> elevation = vtkSmartPointer<vtkElevationFilter>::New(); |
||||
elevation->SetInputConnection(cloud_source->GetOutputPort()); |
||||
elevation->SetLowPoint(p1.x, p1.y, p1.z); |
||||
elevation->SetHighPoint(p2.x, p2.y, p2.z); |
||||
elevation->SetScalarRange(0.0, 1.0); |
||||
elevation->Update(); |
||||
|
||||
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New(); |
||||
VtkUtils::SetInputData(mapper, vtkPolyData::SafeDownCast(elevation->GetOutput())); |
||||
mapper->ImmediateModeRenderingOff(); |
||||
mapper->ScalarVisibilityOn(); |
||||
mapper->SetColorModeToMapScalars(); |
||||
|
||||
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New(); |
||||
actor->GetProperty()->SetInterpolationToFlat(); |
||||
actor->GetProperty()->BackfaceCullingOn(); |
||||
actor->SetMapper(mapper); |
||||
|
||||
WidgetAccessor::setProp(*this, actor); |
||||
} |
||||
|
||||
cv::viz::WPaintedCloud::WPaintedCloud(InputArray cloud, const Point3d& p1, const Point3d& p2, const Color& c1, const Color c2) |
||||
{ |
||||
vtkSmartPointer<vtkCloudMatSource> cloud_source = vtkSmartPointer<vtkCloudMatSource>::New(); |
||||
cloud_source->SetCloud(cloud); |
||||
|
||||
vtkSmartPointer<vtkElevationFilter> elevation = vtkSmartPointer<vtkElevationFilter>::New(); |
||||
elevation->SetInputConnection(cloud_source->GetOutputPort()); |
||||
elevation->SetLowPoint(p1.x, p1.y, p1.z); |
||||
elevation->SetHighPoint(p2.x, p2.y, p2.z); |
||||
elevation->SetScalarRange(0.0, 1.0); |
||||
elevation->Update(); |
||||
|
||||
Color vc1 = vtkcolor(c1), vc2 = vtkcolor(c2); |
||||
vtkSmartPointer<vtkColorTransferFunction> color_transfer = vtkSmartPointer<vtkColorTransferFunction>::New(); |
||||
color_transfer->SetColorSpaceToRGB(); |
||||
color_transfer->AddRGBPoint(0.0, vc1[0], vc1[1], vc1[2]); |
||||
color_transfer->AddRGBPoint(1.0, vc2[0], vc2[1], vc2[2]); |
||||
color_transfer->SetScaleToLinear(); |
||||
color_transfer->Build(); |
||||
|
||||
//if in future some need to replace color table with real scalars, then this can be done usine next calls:
|
||||
//vtkDataArray *float_scalars = vtkPolyData::SafeDownCast(elevation->GetOutput())->GetPointData()->GetArray("Elevation");
|
||||
//vtkSmartPointer<vtkPolyData> polydata = cloud_source->GetOutput();
|
||||
//polydata->GetPointData()->SetScalars(color_transfer->MapScalars(float_scalars, VTK_COLOR_MODE_DEFAULT, 0));
|
||||
|
||||
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New(); |
||||
VtkUtils::SetInputData(mapper, vtkPolyData::SafeDownCast(elevation->GetOutput())); |
||||
mapper->ImmediateModeRenderingOff(); |
||||
mapper->ScalarVisibilityOn(); |
||||
mapper->SetColorModeToMapScalars(); |
||||
mapper->SetLookupTable(color_transfer); |
||||
|
||||
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New(); |
||||
actor->GetProperty()->SetInterpolationToFlat(); |
||||
actor->GetProperty()->BackfaceCullingOn(); |
||||
actor->SetMapper(mapper); |
||||
|
||||
WidgetAccessor::setProp(*this, actor); |
||||
} |
||||
|
||||
template<> cv::viz::WPaintedCloud cv::viz::Widget::cast<cv::viz::WPaintedCloud>() |
||||
{ |
||||
Widget3D widget = this->cast<Widget3D>(); |
||||
return static_cast<WPaintedCloud&>(widget); |
||||
} |
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// Cloud Collection Widget implementation
|
||||
|
||||
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 Affine3d &pose) |
||||
{ |
||||
vtkSmartPointer<vtkCloudMatSource> source = vtkSmartPointer<vtkCloudMatSource>::New(); |
||||
source->SetColorCloud(cloud, colors); |
||||
|
||||
vtkSmartPointer<vtkPolyData> polydata = VtkUtils::TransformPolydata(source->GetOutputPort(), pose); |
||||
|
||||
vtkSmartPointer<vtkLODActor> actor = vtkLODActor::SafeDownCast(WidgetAccessor::getProp(*this)); |
||||
CV_Assert("Incompatible widget type." && actor); |
||||
|
||||
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkPolyDataMapper::SafeDownCast(actor->GetMapper()); |
||||
if (!mapper) |
||||
{ |
||||
// This is the first cloud
|
||||
mapper = vtkSmartPointer<vtkPolyDataMapper>::New(); |
||||
mapper->SetScalarRange(0, 255); |
||||
mapper->SetScalarModeToUsePointData(); |
||||
mapper->ScalarVisibilityOn(); |
||||
mapper->ImmediateModeRenderingOff(); |
||||
VtkUtils::SetInputData(mapper, polydata); |
||||
|
||||
actor->SetNumberOfCloudPoints(std::max<vtkIdType>(1, polydata->GetNumberOfPoints()/10)); |
||||
actor->GetProperty()->SetInterpolationToFlat(); |
||||
actor->GetProperty()->BackfaceCullingOn(); |
||||
actor->SetMapper(mapper); |
||||
return; |
||||
} |
||||
|
||||
vtkPolyData *currdata = vtkPolyData::SafeDownCast(mapper->GetInput()); |
||||
CV_Assert("Cloud Widget without data" && currdata); |
||||
|
||||
vtkSmartPointer<vtkAppendPolyData> append_filter = vtkSmartPointer<vtkAppendPolyData>::New(); |
||||
VtkUtils::AddInputData(append_filter, currdata); |
||||
VtkUtils::AddInputData(append_filter, polydata); |
||||
append_filter->Update(); |
||||
|
||||
VtkUtils::SetInputData(mapper, append_filter->GetOutput()); |
||||
|
||||
actor->SetNumberOfCloudPoints(std::max<vtkIdType>(1, actor->GetNumberOfCloudPoints() + polydata->GetNumberOfPoints()/10)); |
||||
} |
||||
|
||||
void cv::viz::WCloudCollection::addCloud(InputArray cloud, const Color &color, const Affine3d &pose) |
||||
{ |
||||
addCloud(cloud, Mat(cloud.size(), CV_8UC3, color), pose); |
||||
} |
||||
|
||||
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
|
||||
|
||||
cv::viz::WCloudNormals::WCloudNormals(InputArray _cloud, InputArray _normals, int level, double 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()); |
||||
|
||||
int sqlevel = (int)std::sqrt((double)level); |
||||
int ystep = (cloud.cols > 1 && cloud.rows > 1) ? sqlevel : 1; |
||||
int xstep = (cloud.cols > 1 && cloud.rows > 1) ? sqlevel : level; |
||||
|
||||
vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New(); |
||||
points->SetDataType(cloud.depth() == CV_32F ? VTK_FLOAT : VTK_DOUBLE); |
||||
|
||||
vtkSmartPointer<vtkCellArray> lines = vtkSmartPointer<vtkCellArray>::New(); |
||||
|
||||
int s_chs = cloud.channels(); |
||||
int n_chs = normals.channels(); |
||||
int total = 0; |
||||
|
||||
for(int y = 0; y < cloud.rows; y += ystep) |
||||
{ |
||||
if (cloud.depth() == CV_32F) |
||||
{ |
||||
const float *srow = cloud.ptr<float>(y); |
||||
const float *send = srow + cloud.cols * s_chs; |
||||
const float *nrow = normals.ptr<float>(y); |
||||
|
||||
for (; srow < send; srow += xstep * s_chs, nrow += xstep * n_chs) |
||||
if (!isNan(srow) && !isNan(nrow)) |
||||
{ |
||||
Vec3f endp = Vec3f(srow) + Vec3f(nrow) * (float)scale; |
||||
|
||||
points->InsertNextPoint(srow); |
||||
points->InsertNextPoint(endp.val); |
||||
|
||||
lines->InsertNextCell(2); |
||||
lines->InsertCellPoint(total++); |
||||
lines->InsertCellPoint(total++); |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
const double *srow = cloud.ptr<double>(y); |
||||
const double *send = srow + cloud.cols * s_chs; |
||||
const double *nrow = normals.ptr<double>(y); |
||||
|
||||
for (; srow < send; srow += xstep * s_chs, nrow += xstep * n_chs) |
||||
if (!isNan(srow) && !isNan(nrow)) |
||||
{ |
||||
Vec3d endp = Vec3d(srow) + Vec3d(nrow) * (double)scale; |
||||
|
||||
points->InsertNextPoint(srow); |
||||
points->InsertNextPoint(endp.val); |
||||
|
||||
lines->InsertNextCell(2); |
||||
lines->InsertCellPoint(total++); |
||||
lines->InsertCellPoint(total++); |
||||
} |
||||
} |
||||
} |
||||
|
||||
vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New(); |
||||
polyData->SetPoints(points); |
||||
polyData->SetLines(lines); |
||||
|
||||
vtkSmartPointer<vtkDataSetMapper> mapper = vtkSmartPointer<vtkDataSetMapper>::New(); |
||||
mapper->SetColorModeToMapScalars(); |
||||
mapper->SetScalarModeToUsePointData(); |
||||
VtkUtils::SetInputData(mapper, polyData); |
||||
|
||||
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::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
|
||||
|
||||
cv::viz::WMesh::WMesh(const Mesh &mesh) |
||||
{ |
||||
CV_Assert(mesh.cloud.rows == 1 && mesh.polygons.type() == CV_32SC1); |
||||
|
||||
vtkSmartPointer<vtkCloudMatSource> source = vtkSmartPointer<vtkCloudMatSource>::New(); |
||||
source->SetColorCloudNormalsTCoords(mesh.cloud, mesh.colors, mesh.normals, mesh.tcoords); |
||||
source->Update(); |
||||
|
||||
Mat lookup_buffer(1, mesh.cloud.total(), CV_32SC1); |
||||
int *lookup = lookup_buffer.ptr<int>(); |
||||
for(int y = 0, index = 0; y < mesh.cloud.rows; ++y) |
||||
{ |
||||
int s_chs = mesh.cloud.channels(); |
||||
|
||||
if (mesh.cloud.depth() == CV_32F) |
||||
{ |
||||
const float* srow = mesh.cloud.ptr<float>(y); |
||||
const float* send = srow + mesh.cloud.cols * s_chs; |
||||
|
||||
for (; srow != send; srow += s_chs, ++lookup) |
||||
if (!isNan(srow[0]) && !isNan(srow[1]) && !isNan(srow[2])) |
||||
*lookup = index++; |
||||
} |
||||
|
||||
if (mesh.cloud.depth() == CV_64F) |
||||
{ |
||||
const double* srow = mesh.cloud.ptr<double>(y); |
||||
const double* send = srow + mesh.cloud.cols * s_chs; |
||||
|
||||
for (; srow != send; srow += s_chs, ++lookup) |
||||
if (!isNan(srow[0]) && !isNan(srow[1]) && !isNan(srow[2])) |
||||
*lookup = index++; |
||||
} |
||||
} |
||||
lookup = lookup_buffer.ptr<int>(); |
||||
|
||||
vtkSmartPointer<vtkPolyData> polydata = source->GetOutput(); |
||||
polydata->SetVerts(0); |
||||
|
||||
const int * polygons = mesh.polygons.ptr<int>(); |
||||
vtkSmartPointer<vtkCellArray> cell_array = vtkSmartPointer<vtkCellArray>::New(); |
||||
|
||||
int idx = 0; |
||||
size_t polygons_size = mesh.polygons.total(); |
||||
for (size_t i = 0; i < polygons_size; ++idx) |
||||
{ |
||||
int n_points = polygons[i++]; |
||||
|
||||
cell_array->InsertNextCell(n_points); |
||||
for (int j = 0; j < n_points; ++j, ++idx) |
||||
cell_array->InsertCellPoint(lookup[polygons[i++]]); |
||||
} |
||||
cell_array->GetData()->SetNumberOfValues(idx); |
||||
cell_array->Squeeze(); |
||||
polydata->SetStrips(cell_array); |
||||
|
||||
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New(); |
||||
mapper->SetScalarModeToUsePointData(); |
||||
mapper->ImmediateModeRenderingOff(); |
||||
VtkUtils::SetInputData(mapper, polydata); |
||||
|
||||
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New(); |
||||
//actor->SetNumberOfCloudPoints(std::max(1, polydata->GetNumberOfPoints() / 10));
|
||||
actor->GetProperty()->SetRepresentationToSurface(); |
||||
actor->GetProperty()->BackfaceCullingOff(); // Backface culling is off for higher efficiency
|
||||
actor->GetProperty()->SetInterpolationToFlat(); |
||||
actor->GetProperty()->EdgeVisibilityOff(); |
||||
actor->GetProperty()->ShadingOff(); |
||||
actor->SetMapper(mapper); |
||||
|
||||
if (!mesh.texture.empty()) |
||||
{ |
||||
vtkSmartPointer<vtkImageMatSource> image_source = vtkSmartPointer<vtkImageMatSource>::New(); |
||||
image_source->SetImage(mesh.texture); |
||||
|
||||
vtkSmartPointer<vtkTexture> texture = vtkSmartPointer<vtkTexture>::New(); |
||||
texture->SetInputConnection(image_source->GetOutputPort()); |
||||
actor->SetTexture(texture); |
||||
} |
||||
|
||||
WidgetAccessor::setProp(*this, actor); |
||||
} |
||||
|
||||
cv::viz::WMesh::WMesh(InputArray cloud, InputArray polygons, InputArray colors, InputArray normals) |
||||
{ |
||||
Mesh mesh; |
||||
mesh.cloud = cloud.getMat(); |
||||
mesh.colors = colors.getMat(); |
||||
mesh.normals = normals.getMat(); |
||||
mesh.polygons = polygons.getMat(); |
||||
*this = WMesh(mesh); |
||||
} |
||||
|
||||
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,639 @@ |
||||
/*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 |
||||
{ |
||||
vtkStandardNewMacro(InteractorStyle) |
||||
}} |
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::InteractorStyle::Initialize() |
||||
{ |
||||
// Set windows size (width, height) to unknown (-1)
|
||||
win_size_ = Vec2i(-1, -1); |
||||
win_pos_ = Vec2i(0, 0); |
||||
max_win_size_ = Vec2i(-1, -1); |
||||
|
||||
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 String &file) |
||||
{ |
||||
FindPokedRenderer(Interactor->GetEventPosition()[0], Interactor->GetEventPosition()[1]); |
||||
|
||||
vtkSmartPointer<vtkWindowToImageFilter> wif = vtkSmartPointer<vtkWindowToImageFilter>::New(); |
||||
wif->SetInput(Interactor->GetRenderWindow()); |
||||
|
||||
vtkSmartPointer<vtkPNGWriter> snapshot_writer = vtkSmartPointer<vtkPNGWriter>::New(); |
||||
snapshot_writer->SetInputConnection(wif->GetOutputPort()); |
||||
snapshot_writer->SetFileName(file.c_str()); |
||||
snapshot_writer->Write(); |
||||
|
||||
cout << "Screenshot successfully captured (" << file.c_str() << ")" << endl; |
||||
} |
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::InteractorStyle::exportScene(const String &file) |
||||
{ |
||||
vtkSmartPointer<vtkExporter> exporter; |
||||
if (file.size() > 5 && file.substr(file.size() - 5) == ".vrml") |
||||
{ |
||||
exporter = vtkSmartPointer<vtkVRMLExporter>::New(); |
||||
vtkVRMLExporter::SafeDownCast(exporter)->SetFileName(file.c_str()); |
||||
} |
||||
else |
||||
{ |
||||
exporter = vtkSmartPointer<vtkOBJExporter>::New(); |
||||
vtkOBJExporter::SafeDownCast(exporter)->SetFilePrefix(file.c_str()); |
||||
} |
||||
|
||||
exporter->SetInput(Interactor->GetRenderWindow()); |
||||
exporter->Write(); |
||||
|
||||
cout << "Scene successfully exported (" << file.c_str() << ")" << endl; |
||||
} |
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
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; |
||||
|
||||
String key(Interactor->GetKeySym()); |
||||
if (key.find("XF86ZoomIn") != String::npos) |
||||
zoomIn(); |
||||
else if (key.find("XF86ZoomOut") != String::npos) |
||||
zoomOut(); |
||||
|
||||
int keymod = Interactor->GetAltKey(); |
||||
|
||||
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; |
||||
} |
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
int cv::viz::InteractorStyle::getModifiers() |
||||
{ |
||||
int modifiers = KeyboardEvent::NONE; |
||||
|
||||
if (Interactor->GetAltKey()) |
||||
modifiers |= KeyboardEvent::ALT; |
||||
|
||||
if (Interactor->GetControlKey()) |
||||
modifiers |= KeyboardEvent::CTRL; |
||||
|
||||
if (Interactor->GetShiftKey()) |
||||
modifiers |= KeyboardEvent::SHIFT; |
||||
return modifiers; |
||||
} |
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::InteractorStyle::OnKeyDown() |
||||
{ |
||||
CV_Assert("Interactor style not initialized. Please call Initialize() before continuing" && init_); |
||||
FindPokedRenderer(Interactor->GetEventPosition()[0], Interactor->GetEventPosition()[1]); |
||||
|
||||
// Save the initial windows width/height
|
||||
if (win_size_[0] == -1 || win_size_[1] == -1) |
||||
win_size_ = Vec2i(Interactor->GetRenderWindow()->GetSize()); |
||||
|
||||
bool alt = Interactor->GetAltKey() != 0; |
||||
|
||||
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" |
||||
" k, K : export scene to Wavefront .obj format\n" |
||||
" ALT + k, K : export scene to VRML format\n" |
||||
" c, C : display current camera/window parameters\n" |
||||
" f, F : fly to point mode, hold the key and move mouse where to fly\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 = vtkActor::SafeDownCast(path->GetLastNode()->GetViewProp()); |
||||
apart->GetProperty()->SetRepresentationToPoints(); |
||||
} |
||||
break; |
||||
} |
||||
|
||||
// Save a PNG snapshot
|
||||
case 'j': case 'J': |
||||
saveScreenshot(cv::format("screenshot-%d.png", (unsigned int)time(0))); break; |
||||
|
||||
// Export scene as in obj or vrml format
|
||||
case 'k': case 'K': |
||||
{ |
||||
String format = alt ? "scene-%d.vrml" : "scene-%d"; |
||||
exportScene(cv::format(format.c_str(), (unsigned int)time(0))); |
||||
break; |
||||
} |
||||
|
||||
// display current camera settings/parameters
|
||||
case 'c': case 'C': |
||||
{ |
||||
vtkSmartPointer<vtkCamera> cam = Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->GetActiveCamera(); |
||||
|
||||
Vec2d clip(cam->GetClippingRange()); |
||||
Vec3d focal(cam->GetFocalPoint()), pos(cam->GetPosition()), view(cam->GetViewUp()); |
||||
Vec2i win_pos(Interactor->GetRenderWindow()->GetPosition()); |
||||
Vec2i win_size(Interactor->GetRenderWindow()->GetSize()); |
||||
double angle = cam->GetViewAngle () / 180.0 * CV_PI; |
||||
|
||||
String data = cv::format("clip(%f,%f) focal(%f,%f,%f) pos(%f,%f,%f) view(%f,%f,%f) angle(%f) winsz(%d,%d) winpos(%d,%d)", |
||||
clip[0], clip[1], focal[0], focal[1], focal[2], pos[0], pos[1], pos[2], view[0], view[1], view[2], |
||||
angle, win_size[0], win_size[1], win_pos[0], win_pos[1]); |
||||
|
||||
std::cout << data.c_str() << 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 = vtkActor::SafeDownCast(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 = vtkActor::SafeDownCast(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 (alt) |
||||
{ |
||||
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; |
||||
Interactor->GetPicker()->Pick(Interactor->GetEventPosition()[0], Interactor->GetEventPosition()[1], 0.0, CurrentRenderer); |
||||
vtkSmartPointer<vtkAbstractPropPicker> picker = vtkAbstractPropPicker::SafeDownCast(Interactor->GetPicker()); |
||||
if (picker) |
||||
if (picker->GetPath()) |
||||
Interactor->FlyTo(CurrentRenderer, picker->GetPickPosition()); |
||||
AnimState = VTKIS_ANIM_OFF; |
||||
} |
||||
break; |
||||
} |
||||
// 's'/'S' w/out ALT
|
||||
case 's': case 'S': |
||||
{ |
||||
if (alt) |
||||
{ |
||||
vtkSmartPointer<vtkRenderWindow> window = Interactor->GetRenderWindow(); |
||||
if (!window->GetStereoRender()) |
||||
{ |
||||
static Vec2i red_blue(4, 3), magenta_green(2, 5); |
||||
window->SetAnaglyphColorMask (stereo_anaglyph_mask_default_ ? red_blue.val : magenta_green.val); |
||||
stereo_anaglyph_mask_default_ = !stereo_anaglyph_mask_default_; |
||||
} |
||||
window->SetStereoRender(!window->GetStereoRender()); |
||||
Interactor->Render(); |
||||
} |
||||
else |
||||
Superclass::OnKeyDown(); |
||||
break; |
||||
} |
||||
|
||||
case 'o': case 'O': |
||||
{ |
||||
vtkSmartPointer<vtkCamera> cam = CurrentRenderer->GetActiveCamera(); |
||||
cam->SetParallelProjection(!cam->GetParallelProjection()); |
||||
CurrentRenderer->Render(); |
||||
break; |
||||
} |
||||
|
||||
// Overwrite the camera reset
|
||||
case 'r': case 'R': |
||||
{ |
||||
if (!alt) |
||||
{ |
||||
Superclass::OnKeyDown(); |
||||
break; |
||||
} |
||||
|
||||
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.
|
||||
for (; it != widget_actor_map_->end(); ++it) |
||||
{ |
||||
vtkProp3D * actor = vtkProp3D::SafeDownCast(it->second); |
||||
if (actor && actor->GetUserMatrix()) |
||||
break; |
||||
} |
||||
|
||||
vtkSmartPointer<vtkCamera> cam = CurrentRenderer->GetActiveCamera(); |
||||
|
||||
// if a valid transformation was found, use it otherwise fall back to default view point.
|
||||
if (it != widget_actor_map_->end()) |
||||
{ |
||||
vtkMatrix4x4* m = vtkProp3D::SafeDownCast(it->second)->GetUserMatrix(); |
||||
|
||||
cam->SetFocalPoint(m->GetElement(0, 3) - m->GetElement(0, 2), |
||||
m->GetElement(1, 3) - m->GetElement(1, 2), |
||||
m->GetElement(2, 3) - m->GetElement(2, 2)); |
||||
|
||||
cam->SetViewUp (m->GetElement(0, 1), m->GetElement(1, 1), m->GetElement(2, 1)); |
||||
cam->SetPosition(m->GetElement(0, 3), m->GetElement(1, 3), m->GetElement(2, 3)); |
||||
} |
||||
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(KeyboardEvent::KEY_DOWN, Interactor->GetKeySym(), Interactor->GetKeyCode(), getModifiers()); |
||||
if (keyboardCallback_) |
||||
keyboardCallback_(event, keyboard_callback_cookie_); |
||||
Interactor->Render(); |
||||
} |
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::InteractorStyle::OnKeyUp() |
||||
{ |
||||
KeyboardEvent event(KeyboardEvent::KEY_UP, Interactor->GetKeySym(), Interactor->GetKeyCode(), getModifiers()); |
||||
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, getModifiers()); |
||||
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, getModifiers()); |
||||
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, getModifiers()); |
||||
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, getModifiers()); |
||||
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, getModifiers()); |
||||
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, getModifiers()); |
||||
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, getModifiers()); |
||||
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, getModifiers()); |
||||
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->ResetCameraClippingRange(); |
||||
CurrentRenderer->Modified(); |
||||
CurrentRenderer->Render(); |
||||
Interactor->Render(); |
||||
} |
||||
else |
||||
Superclass::OnMouseWheelForward(); |
||||
} |
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::InteractorStyle::OnMouseWheelBackward() |
||||
{ |
||||
Vec2i p(Interactor->GetEventPosition()); |
||||
MouseEvent event(MouseEvent::MouseScrollDown, MouseEvent::VScroll, p, getModifiers()); |
||||
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->ResetCameraClippingRange(); |
||||
CurrentRenderer->Modified(); |
||||
CurrentRenderer->Render(); |
||||
Interactor->Render(); |
||||
} |
||||
else |
||||
Superclass::OnMouseWheelBackward(); |
||||
} |
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::InteractorStyle::OnTimer() |
||||
{ |
||||
CV_Assert("Interactor style not initialized." && init_); |
||||
Interactor->Render(); |
||||
} |
@ -0,0 +1,119 @@ |
||||
/*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
|
||||
//
|
||||
//M*/
|
||||
|
||||
#ifndef __OPENCV_VIZ_INTERACTOR_STYLE_H__ |
||||
#define __OPENCV_VIZ_INTERACTOR_STYLE_H__ |
||||
|
||||
namespace cv |
||||
{ |
||||
namespace viz |
||||
{ |
||||
class InteractorStyle : public vtkInteractorStyleTrackballCamera |
||||
{ |
||||
public: |
||||
static InteractorStyle *New(); |
||||
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(); |
||||
|
||||
void setWidgetActorMap(const Ptr<WidgetActorMap>& actors) { widget_actor_map_ = actors; } |
||||
void registerMouseCallback(void (*callback)(const MouseEvent&, void*), void* cookie = 0); |
||||
void registerKeyboardCallback(void (*callback)(const KeyboardEvent&, void*), void * cookie = 0); |
||||
void saveScreenshot(const String &file); |
||||
void exportScene(const String &file); |
||||
|
||||
private: |
||||
/** \brief Set to true after initialization is complete. */ |
||||
bool init_; |
||||
|
||||
Ptr<WidgetActorMap> widget_actor_map_; |
||||
|
||||
Vec2i win_size_; |
||||
Vec2i win_pos_; |
||||
Vec2i max_win_size_; |
||||
|
||||
/** \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_; |
||||
|
||||
void (*keyboardCallback_)(const KeyboardEvent&, void*); |
||||
void *keyboard_callback_cookie_; |
||||
|
||||
void (*mouseCallback_)(const MouseEvent&, void*); |
||||
void *mouse_callback_cookie_; |
||||
|
||||
int getModifiers(); |
||||
}; |
||||
} |
||||
} |
||||
|
||||
#endif |
@ -0,0 +1,324 @@ |
||||
/*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
|
||||
//
|
||||
//M*/
|
||||
|
||||
#ifndef __OPENCV_VIZ_PRECOMP_HPP__ |
||||
#define __OPENCV_VIZ_PRECOMP_HPP__ |
||||
|
||||
#include <map> |
||||
#include <ctime> |
||||
#include <list> |
||||
#include <vector> |
||||
#include <iomanip> |
||||
#include <limits> |
||||
|
||||
#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 <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 <vtkPlanes.h> |
||||
#include <vtkImageFlip.h> |
||||
#include <vtkRenderWindow.h> |
||||
#include <vtkTextProperty.h> |
||||
#include <vtkProperty2D.h> |
||||
#include <vtkLODActor.h> |
||||
#include <vtkActor.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> |
||||
#include <vtkImageMapper.h> |
||||
#include <vtkPoints.h> |
||||
#include <vtkInformation.h> |
||||
#include <vtkInformationVector.h> |
||||
#include <vtkObjectFactory.h> |
||||
#include <vtkPolyDataAlgorithm.h> |
||||
#include <vtkMergeFilter.h> |
||||
#include <vtkDataSetWriter.h> |
||||
#include <vtkErrorCode.h> |
||||
#include <vtkPLYWriter.h> |
||||
#include <vtkSTLWriter.h> |
||||
#include <vtkSimplePointsReader.h> |
||||
#include <vtkPLYReader.h> |
||||
#include <vtkOBJReader.h> |
||||
#include <vtkSTLReader.h> |
||||
#include <vtkPNGReader.h> |
||||
#include <vtkOBJExporter.h> |
||||
#include <vtkVRMLExporter.h> |
||||
#include <vtkTensorGlyph.h> |
||||
#include <vtkImageAlgorithm.h> |
||||
#include <vtkTransformFilter.h> |
||||
#include <vtkConeSource.h> |
||||
#include <vtkElevationFilter.h> |
||||
#include <vtkColorTransferFunction.h> |
||||
#include <vtkStreamingDemandDrivenPipeline.h> |
||||
|
||||
#if !defined(_WIN32) || defined(__CYGWIN__) |
||||
# include <unistd.h> /* unlink */ |
||||
#else |
||||
# include <io.h> /* unlink */ |
||||
#endif |
||||
|
||||
#include <vtk/vtkOBJWriter.h> |
||||
#include <vtk/vtkXYZWriter.h> |
||||
#include <vtk/vtkCloudMatSink.h> |
||||
#include <vtk/vtkCloudMatSource.h> |
||||
#include <vtk/vtkTrajectorySource.h> |
||||
#include <vtk/vtkImageMatSource.h> |
||||
|
||||
#include <opencv2/core/core.hpp> |
||||
#include <opencv2/viz/vizcore.hpp> |
||||
#include <opencv2/viz/widget_accessor.hpp> |
||||
|
||||
|
||||
namespace cv |
||||
{ |
||||
namespace viz |
||||
{ |
||||
typedef std::map<String, vtkSmartPointer<vtkProp> > WidgetActorMap; |
||||
typedef std::map<String, Viz3d> VizMap; |
||||
|
||||
class VizStorage |
||||
{ |
||||
public: |
||||
static void unregisterAll(); |
||||
|
||||
//! window names automatically have Viz - prefix even though not provided by the users
|
||||
static String generateWindowName(const String &window_name); |
||||
|
||||
private: |
||||
VizStorage(); // Static
|
||||
~VizStorage(); |
||||
|
||||
static void add(const Viz3d& window); |
||||
static Viz3d& get(const String &window_name); |
||||
static void remove(const String &window_name); |
||||
static bool windowExists(const String &window_name); |
||||
static void removeUnreferenced(); |
||||
|
||||
static VizMap storage; |
||||
friend class Viz3d; |
||||
}; |
||||
|
||||
template<typename _Tp> inline _Tp normalized(const _Tp& v) { return v * 1/norm(v); } |
||||
|
||||
template<typename _Tp> inline bool isNan(const _Tp* data) |
||||
{ |
||||
return isNan(data[0]) || isNan(data[1]) || isNan(data[2]); |
||||
} |
||||
|
||||
inline vtkSmartPointer<vtkActor> getActor(const Widget3D& widget) |
||||
{ |
||||
return vtkActor::SafeDownCast(WidgetAccessor::getProp(widget)); |
||||
} |
||||
|
||||
inline vtkSmartPointer<vtkPolyData> getPolyData(const Widget3D& widget) |
||||
{ |
||||
vtkSmartPointer<vtkMapper> mapper = getActor(widget)->GetMapper(); |
||||
return vtkPolyData::SafeDownCast(mapper->GetInput()); |
||||
} |
||||
|
||||
inline vtkSmartPointer<vtkMatrix4x4> vtkmatrix(const cv::Matx44d &matrix) |
||||
{ |
||||
vtkSmartPointer<vtkMatrix4x4> vtk_matrix = vtkSmartPointer<vtkMatrix4x4>::New(); |
||||
vtk_matrix->DeepCopy(matrix.val); |
||||
return vtk_matrix; |
||||
} |
||||
|
||||
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 get_random_vec(double from = -10.0, double to = 10.0) |
||||
{ |
||||
RNG& rng = theRNG(); |
||||
return Vec3d(rng.uniform(from, to), rng.uniform(from, to), rng.uniform(from, to)); |
||||
} |
||||
|
||||
struct VtkUtils |
||||
{ |
||||
template<class Filter> |
||||
static void SetInputData(vtkSmartPointer<Filter> filter, vtkPolyData* polydata) |
||||
{ |
||||
#if VTK_MAJOR_VERSION <= 5 |
||||
filter->SetInput(polydata); |
||||
#else |
||||
filter->SetInputData(polydata); |
||||
#endif |
||||
} |
||||
template<class Filter> |
||||
static void SetSourceData(vtkSmartPointer<Filter> filter, vtkPolyData* polydata) |
||||
{ |
||||
#if VTK_MAJOR_VERSION <= 5 |
||||
filter->SetSource(polydata); |
||||
#else |
||||
filter->SetSourceData(polydata); |
||||
#endif |
||||
} |
||||
|
||||
template<class Filter> |
||||
static void SetInputData(vtkSmartPointer<Filter> filter, vtkImageData* polydata) |
||||
{ |
||||
#if VTK_MAJOR_VERSION <= 5 |
||||
filter->SetInput(polydata); |
||||
#else |
||||
filter->SetInputData(polydata); |
||||
#endif |
||||
} |
||||
|
||||
template<class Filter> |
||||
static void AddInputData(vtkSmartPointer<Filter> filter, vtkPolyData *polydata) |
||||
{ |
||||
#if VTK_MAJOR_VERSION <= 5 |
||||
filter->AddInput(polydata); |
||||
#else |
||||
filter->AddInputData(polydata); |
||||
#endif |
||||
} |
||||
|
||||
static vtkSmartPointer<vtkUnsignedCharArray> FillScalars(size_t size, const Color& color) |
||||
{ |
||||
Vec3b rgb = Vec3d(color[2], color[1], color[0]); |
||||
Vec3b* color_data = new Vec3b[size]; |
||||
std::fill(color_data, color_data + size, rgb); |
||||
|
||||
vtkSmartPointer<vtkUnsignedCharArray> scalars = vtkSmartPointer<vtkUnsignedCharArray>::New(); |
||||
scalars->SetName("Colors"); |
||||
scalars->SetNumberOfComponents(3); |
||||
scalars->SetNumberOfTuples(size); |
||||
scalars->SetArray(color_data->val, size * 3, 0); |
||||
return scalars; |
||||
} |
||||
|
||||
static vtkSmartPointer<vtkPolyData> ComputeNormals(vtkSmartPointer<vtkPolyData> polydata) |
||||
{ |
||||
vtkSmartPointer<vtkPolyDataNormals> normals_generator = vtkSmartPointer<vtkPolyDataNormals>::New(); |
||||
normals_generator->ComputePointNormalsOn(); |
||||
normals_generator->ComputeCellNormalsOff(); |
||||
normals_generator->SetFeatureAngle(0.1); |
||||
normals_generator->SetSplitting(0); |
||||
normals_generator->SetConsistency(1); |
||||
normals_generator->SetAutoOrientNormals(0); |
||||
normals_generator->SetFlipNormals(0); |
||||
normals_generator->SetNonManifoldTraversal(1); |
||||
VtkUtils::SetInputData(normals_generator, polydata); |
||||
normals_generator->Update(); |
||||
return normals_generator->GetOutput(); |
||||
} |
||||
|
||||
static vtkSmartPointer<vtkPolyData> TransformPolydata(vtkSmartPointer<vtkAlgorithmOutput> algorithm_output_port, const Affine3d& pose) |
||||
{ |
||||
vtkSmartPointer<vtkTransform> transform = vtkSmartPointer<vtkTransform>::New(); |
||||
transform->SetMatrix(vtkmatrix(pose.matrix)); |
||||
|
||||
vtkSmartPointer<vtkTransformPolyDataFilter> transform_filter = vtkSmartPointer<vtkTransformPolyDataFilter>::New(); |
||||
transform_filter->SetTransform(transform); |
||||
transform_filter->SetInputConnection(algorithm_output_port); |
||||
transform_filter->Update(); |
||||
return transform_filter->GetOutput(); |
||||
} |
||||
|
||||
static vtkSmartPointer<vtkPolyData> TransformPolydata(vtkSmartPointer<vtkPolyData> polydata, const Affine3d& pose) |
||||
{ |
||||
vtkSmartPointer<vtkTransform> transform = vtkSmartPointer<vtkTransform>::New(); |
||||
transform->SetMatrix(vtkmatrix(pose.matrix)); |
||||
|
||||
vtkSmartPointer<vtkTransformPolyDataFilter> transform_filter = vtkSmartPointer<vtkTransformPolyDataFilter>::New(); |
||||
VtkUtils::SetInputData(transform_filter, polydata); |
||||
transform_filter->SetTransform(transform); |
||||
transform_filter->Update(); |
||||
return transform_filter->GetOutput(); |
||||
} |
||||
}; |
||||
} |
||||
} |
||||
|
||||
#include "interactor_style.hpp" |
||||
#include "vizimpl.hpp" |
||||
|
||||
|
||||
#endif |
@ -0,0 +1,206 @@ |
||||
/*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
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "precomp.hpp" |
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/// Events
|
||||
|
||||
cv::viz::KeyboardEvent::KeyboardEvent(Action _action, const String& _symbol, unsigned char _code, int _modifiers) |
||||
: action(_action), symbol(_symbol), code(_code), modifiers(_modifiers) {} |
||||
|
||||
cv::viz::MouseEvent::MouseEvent(const Type& _type, const MouseButton& _button, const Point& _pointer, int _modifiers) |
||||
: type(_type), button(_button), pointer(_pointer), modifiers(_modifiers) {} |
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/// cv::viz::Mesh3d
|
||||
|
||||
cv::viz::Mesh cv::viz::Mesh::load(const String& file) |
||||
{ |
||||
vtkSmartPointer<vtkPLYReader> reader = vtkSmartPointer<vtkPLYReader>::New(); |
||||
reader->SetFileName(file.c_str()); |
||||
reader->Update(); |
||||
|
||||
vtkSmartPointer<vtkPolyData> polydata = reader->GetOutput(); |
||||
CV_Assert("File does not exist or file format is not supported." && polydata); |
||||
|
||||
Mesh mesh; |
||||
vtkSmartPointer<vtkCloudMatSink> sink = vtkSmartPointer<vtkCloudMatSink>::New(); |
||||
sink->SetOutput(mesh.cloud, mesh.colors, mesh.normals, mesh.tcoords); |
||||
sink->SetInputConnection(reader->GetOutputPort()); |
||||
sink->Write(); |
||||
|
||||
// Now handle the polygons
|
||||
vtkSmartPointer<vtkCellArray> polygons = polydata->GetPolys(); |
||||
mesh.polygons.create(1, polygons->GetSize(), CV_32SC1); |
||||
int* poly_ptr = mesh.polygons.ptr<int>(); |
||||
|
||||
polygons->InitTraversal(); |
||||
vtkIdType nr_cell_points, *cell_points; |
||||
while (polygons->GetNextCell(nr_cell_points, cell_points)) |
||||
{ |
||||
*poly_ptr++ = nr_cell_points; |
||||
for (vtkIdType i = 0; i < nr_cell_points; ++i) |
||||
*poly_ptr++ = (int)cell_points[i]; |
||||
} |
||||
|
||||
return mesh; |
||||
} |
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/// Camera implementation
|
||||
|
||||
cv::viz::Camera::Camera(double fx, double fy, double cx, double cy, const Size &window_size) |
||||
{ |
||||
init(fx, fy, cx, cy, window_size); |
||||
} |
||||
|
||||
cv::viz::Camera::Camera(const Vec2d &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::Matx33d & K, const Size &window_size) |
||||
{ |
||||
double f_x = K(0,0); |
||||
double f_y = K(1,1); |
||||
double c_x = K(0,2); |
||||
double c_y = K(1,2); |
||||
init(f_x, f_y, c_x, c_y, window_size); |
||||
} |
||||
|
||||
cv::viz::Camera::Camera(const Matx44d &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; |
||||
|
||||
principal_point_[0] = fabs(left-right) < epsilon ? window_size.width * 0.5 : (left * window_size.width) / (left - right); |
||||
principal_point_[1] = fabs(top-bottom) < epsilon ? window_size.height * 0.5 : (top * window_size.height) / (top - bottom); |
||||
|
||||
focal_[0] = -near * principal_point_[0] / left; |
||||
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(double fx, double fy, double cx, double cy, 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(cx, fx) + atan2(window_size.width - cx, fx); |
||||
fov_[1] = atan2(cy, fy) + atan2(window_size.height - cy, fy); |
||||
|
||||
principal_point_[0] = cx; |
||||
principal_point_[1] = cy; |
||||
|
||||
focal_[0] = fx; |
||||
focal_[1] = fy; |
||||
|
||||
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(Matx44d &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) |
||||
{ |
||||
Matx33d K(525.0, 0.0, 320.0, 0.0, 525.0, 240.0, 0.0, 0.0, 1.0); |
||||
return Camera(K, window_size); |
||||
} |
@ -0,0 +1,148 @@ |
||||
/*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
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "precomp.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(); |
||||
|
||||
if (VizStorage::windowExists(window_name)) |
||||
*this = VizStorage::get(window_name); |
||||
else |
||||
{ |
||||
impl_ = new VizImpl(window_name); |
||||
impl_->ref_counter = 1; |
||||
|
||||
// Register the window
|
||||
VizStorage::add(*this); |
||||
} |
||||
} |
||||
|
||||
void cv::viz::Viz3d::release() |
||||
{ |
||||
if (impl_ && CV_XADD(&impl_->ref_counter, -1) == 1) |
||||
{ |
||||
delete impl_; |
||||
impl_ = 0; |
||||
} |
||||
|
||||
if (impl_ && impl_->ref_counter == 1) |
||||
VizStorage::removeUnreferenced(); |
||||
|
||||
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::close() { impl_->close(); } |
||||
|
||||
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 Affine3d &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::showImage(InputArray image, const Size& window_size) { impl_->showImage(image, window_size); } |
||||
|
||||
void cv::viz::Viz3d::setWidgetPose(const String &id, const Affine3d &pose) { impl_->setWidgetPose(id, pose); } |
||||
void cv::viz::Viz3d::updateWidgetPose(const String &id, const Affine3d &pose) { impl_->updateWidgetPose(id, pose); } |
||||
cv::Affine3d 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 Affine3d &pose) { impl_->setViewerPose(pose); } |
||||
cv::Affine3d 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); } |
||||
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(const Point& window_position) { impl_->setWindowPosition(window_position); } |
||||
void cv::viz::Viz3d::setFullScreen(bool mode) { impl_->setFullScreen(mode); } |
||||
void cv::viz::Viz3d::setBackgroundColor(const Color& color, const Color& color2) { impl_->setBackgroundColor(color, color2); } |
||||
|
||||
void cv::viz::Viz3d::setBackgroundTexture(InputArray image) { impl_->setBackgroundTexture(image); } |
||||
void cv::viz::Viz3d::setBackgroundMeshLab() {impl_->setBackgroundMeshLab(); } |
||||
|
||||
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::setRepresentation(int representation) { impl_->setRepresentation(representation); } |
@ -0,0 +1,312 @@ |
||||
/*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
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "precomp.hpp" |
||||
|
||||
cv::Affine3d cv::viz::makeTransformToGlobal(const Vec3d& axis_x, const Vec3d& axis_y, const Vec3d& axis_z, const Vec3d& origin) |
||||
{ |
||||
Affine3d::Mat3 R(axis_x[0], axis_y[0], axis_z[0], |
||||
axis_x[1], axis_y[1], axis_z[1], |
||||
axis_x[2], axis_y[2], axis_z[2]); |
||||
|
||||
return Affine3d(R, origin); |
||||
} |
||||
|
||||
cv::Affine3d cv::viz::makeCameraPose(const Vec3d& position, const Vec3d& focal_point, const Vec3d& y_dir) |
||||
{ |
||||
// Compute the transformation matrix for drawing the camera frame in a scene
|
||||
Vec3d n = normalize(focal_point - position); |
||||
Vec3d u = normalize(y_dir.cross(n)); |
||||
Vec3d v = n.cross(u); |
||||
|
||||
return makeTransformToGlobal(u, v, n, position); |
||||
} |
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// VizStorage implementation
|
||||
|
||||
cv::viz::VizMap cv::viz::VizStorage::storage; |
||||
void cv::viz::VizStorage::unregisterAll() { storage.clear(); } |
||||
|
||||
cv::viz::Viz3d& cv::viz::VizStorage::get(const String &window_name) |
||||
{ |
||||
String name = generateWindowName(window_name); |
||||
VizMap::iterator vm_itr = storage.find(name); |
||||
CV_Assert(vm_itr != storage.end()); |
||||
return vm_itr->second; |
||||
} |
||||
|
||||
void cv::viz::VizStorage::add(const Viz3d& window) |
||||
{ |
||||
String window_name = window.getWindowName(); |
||||
VizMap::iterator vm_itr = storage.find(window_name); |
||||
CV_Assert(vm_itr == storage.end()); |
||||
storage.insert(std::make_pair(window_name, window)); |
||||
} |
||||
|
||||
bool cv::viz::VizStorage::windowExists(const String &window_name) |
||||
{ |
||||
String name = generateWindowName(window_name); |
||||
return storage.find(name) != storage.end(); |
||||
} |
||||
|
||||
void cv::viz::VizStorage::removeUnreferenced() |
||||
{ |
||||
for(VizMap::iterator pos = storage.begin(); pos != storage.end();) |
||||
if(pos->second.impl_->ref_counter == 1) |
||||
storage.erase(pos++); |
||||
else |
||||
++pos; |
||||
} |
||||
|
||||
cv::String cv::viz::VizStorage::generateWindowName(const String &window_name) |
||||
{ |
||||
String output = "Viz"; |
||||
// Already is Viz
|
||||
if (window_name == output) |
||||
return output; |
||||
|
||||
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); |
||||
|
||||
return output; |
||||
} |
||||
|
||||
cv::viz::Viz3d cv::viz::getWindowByName(const String &window_name) { return Viz3d (window_name); } |
||||
void cv::viz::unregisterAllWindows() { VizStorage::unregisterAll(); } |
||||
|
||||
cv::viz::Viz3d cv::viz::imshow(const String& window_name, InputArray image, const Size& window_size) |
||||
{ |
||||
Viz3d viz = getWindowByName(window_name); |
||||
viz.showImage(image, window_size); |
||||
return viz; |
||||
} |
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// Read/write clouds. Supported formats: ply, stl, xyz, obj
|
||||
|
||||
void cv::viz::writeCloud(const String& file, InputArray cloud, InputArray colors, InputArray normals, bool binary) |
||||
{ |
||||
CV_Assert(file.size() > 4 && "Extention is required"); |
||||
String extention = file.substr(file.size()-4); |
||||
|
||||
vtkSmartPointer<vtkCloudMatSource> source = vtkSmartPointer<vtkCloudMatSource>::New(); |
||||
source->SetColorCloudNormals(cloud, colors, normals); |
||||
|
||||
vtkSmartPointer<vtkWriter> writer; |
||||
if (extention == ".xyz") |
||||
{ |
||||
writer = vtkSmartPointer<vtkXYZWriter>::New(); |
||||
vtkXYZWriter::SafeDownCast(writer)->SetFileName(file.c_str()); |
||||
} |
||||
else if (extention == ".ply") |
||||
{ |
||||
writer = vtkSmartPointer<vtkPLYWriter>::New(); |
||||
vtkPLYWriter::SafeDownCast(writer)->SetFileName(file.c_str()); |
||||
vtkPLYWriter::SafeDownCast(writer)->SetFileType(binary ? VTK_BINARY : VTK_ASCII); |
||||
vtkPLYWriter::SafeDownCast(writer)->SetArrayName("Colors"); |
||||
} |
||||
else if (extention == ".obj") |
||||
{ |
||||
writer = vtkSmartPointer<vtkOBJWriter>::New(); |
||||
vtkOBJWriter::SafeDownCast(writer)->SetFileName(file.c_str()); |
||||
} |
||||
else |
||||
CV_Assert(!"Unsupported format"); |
||||
|
||||
writer->SetInputConnection(source->GetOutputPort()); |
||||
writer->Write(); |
||||
} |
||||
|
||||
cv::Mat cv::viz::readCloud(const String& file, OutputArray colors, OutputArray normals) |
||||
{ |
||||
CV_Assert(file.size() > 4 && "Extention is required"); |
||||
String extention = file.substr(file.size()-4); |
||||
|
||||
vtkSmartPointer<vtkPolyDataAlgorithm> reader; |
||||
if (extention == ".xyz") |
||||
{ |
||||
reader = vtkSmartPointer<vtkSimplePointsReader>::New(); |
||||
vtkSimplePointsReader::SafeDownCast(reader)->SetFileName(file.c_str()); |
||||
} |
||||
else if (extention == ".ply") |
||||
{ |
||||
reader = vtkSmartPointer<vtkPLYReader>::New(); |
||||
CV_Assert(vtkPLYReader::CanReadFile(file.c_str())); |
||||
vtkPLYReader::SafeDownCast(reader)->SetFileName(file.c_str()); |
||||
} |
||||
else if (extention == ".obj") |
||||
{ |
||||
reader = vtkSmartPointer<vtkOBJReader>::New(); |
||||
vtkOBJReader::SafeDownCast(reader)->SetFileName(file.c_str()); |
||||
} |
||||
else if (extention == ".stl") |
||||
{ |
||||
reader = vtkSmartPointer<vtkSTLReader>::New(); |
||||
vtkSTLReader::SafeDownCast(reader)->SetFileName(file.c_str()); |
||||
} |
||||
else |
||||
CV_Assert(!"Unsupported format"); |
||||
|
||||
cv::Mat cloud; |
||||
|
||||
vtkSmartPointer<vtkCloudMatSink> sink = vtkSmartPointer<vtkCloudMatSink>::New(); |
||||
sink->SetInputConnection(reader->GetOutputPort()); |
||||
sink->SetOutput(cloud, colors, normals); |
||||
sink->Write(); |
||||
|
||||
return cloud; |
||||
} |
||||
|
||||
cv::viz::Mesh cv::viz::readMesh(const String& file) { return Mesh::load(file); } |
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// Read/write poses and trajectories
|
||||
|
||||
bool cv::viz::readPose(const String& file, Affine3d& pose, const String& tag) |
||||
{ |
||||
FileStorage fs(file, FileStorage::READ); |
||||
if (!fs.isOpened()) |
||||
return false; |
||||
|
||||
Mat hdr(pose.matrix, false); |
||||
fs[tag] >> hdr; |
||||
if (hdr.empty() || hdr.cols != pose.matrix.cols || hdr.rows != pose.matrix.rows) |
||||
return false; |
||||
|
||||
hdr.convertTo(pose.matrix, CV_64F); |
||||
return true; |
||||
} |
||||
|
||||
void cv::viz::writePose(const String& file, const Affine3d& pose, const String& tag) |
||||
{ |
||||
FileStorage fs(file, FileStorage::WRITE); |
||||
fs << tag << Mat(pose.matrix, false); |
||||
} |
||||
|
||||
void cv::viz::readTrajectory(OutputArray _traj, const String& files_format, int start, int end, const String& tag) |
||||
{ |
||||
CV_Assert(_traj.kind() == _InputArray::STD_VECTOR || _traj.kind() == _InputArray::MAT); |
||||
|
||||
start = max(0, std::min(start, end)); |
||||
end = std::max(start, end); |
||||
|
||||
std::vector<Affine3d> traj; |
||||
|
||||
for(int i = start; i < end; ++i) |
||||
{ |
||||
Affine3d affine; |
||||
bool ok = readPose(cv::format(files_format.c_str(), i), affine, tag); |
||||
if (!ok) |
||||
break; |
||||
|
||||
traj.push_back(affine); |
||||
} |
||||
|
||||
Mat(traj).convertTo(_traj, _traj.depth()); |
||||
} |
||||
|
||||
void cv::viz::writeTrajectory(InputArray _traj, const String& files_format, int start, const String& tag) |
||||
{ |
||||
if (_traj.kind() == _InputArray::STD_VECTOR_MAT) |
||||
{ |
||||
std::vector<Mat>& v = *(std::vector<Mat>*)_traj.obj; |
||||
|
||||
for(size_t i = 0, index = max(0, start); i < v.size(); ++i, ++index) |
||||
{ |
||||
Affine3d affine; |
||||
Mat pose = v[i]; |
||||
CV_Assert(pose.type() == CV_32FC(16) || pose.type() == CV_64FC(16)); |
||||
pose.copyTo(affine.matrix); |
||||
writePose(cv::format(files_format.c_str(), index), affine, tag); |
||||
} |
||||
return; |
||||
} |
||||
|
||||
if (_traj.kind() == _InputArray::STD_VECTOR || _traj.kind() == _InputArray::MAT) |
||||
{ |
||||
CV_Assert(_traj.type() == CV_32FC(16) || _traj.type() == CV_64FC(16)); |
||||
|
||||
Mat traj = _traj.getMat(); |
||||
|
||||
if (traj.depth() == CV_32F) |
||||
for(size_t i = 0, index = max(0, start); i < traj.total(); ++i, ++index) |
||||
writePose(cv::format(files_format.c_str(), index), traj.at<Affine3f>(i), tag); |
||||
|
||||
if (traj.depth() == CV_64F) |
||||
for(size_t i = 0, index = max(0, start); i < traj.total(); ++i, ++index) |
||||
writePose(cv::format(files_format.c_str(), index), traj.at<Affine3d>(i), tag); |
||||
} |
||||
|
||||
CV_Assert(!"Unsupported array kind"); |
||||
} |
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// Computing normals for mesh
|
||||
|
||||
void cv::viz::computeNormals(const Mesh& mesh, OutputArray _normals) |
||||
{ |
||||
vtkSmartPointer<vtkPolyData> polydata = getPolyData(WMesh(mesh)); |
||||
vtkSmartPointer<vtkPolyData> with_normals = VtkUtils::ComputeNormals(polydata); |
||||
|
||||
vtkSmartPointer<vtkDataArray> generic_normals = with_normals->GetPointData()->GetNormals(); |
||||
if(generic_normals) |
||||
{ |
||||
Mat normals(1, generic_normals->GetNumberOfTuples(), CV_64FC3); |
||||
Vec3d *optr = normals.ptr<Vec3d>(); |
||||
|
||||
for(int i = 0; i < generic_normals->GetNumberOfTuples(); ++i, ++optr) |
||||
generic_normals->GetTuple(i, optr->val); |
||||
|
||||
normals.convertTo(_normals, mesh.cloud.type()); |
||||
} |
||||
else |
||||
_normals.release(); |
||||
} |
@ -0,0 +1,542 @@ |
||||
/*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
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "precomp.hpp" |
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
cv::viz::Viz3d::VizImpl::VizImpl(const String &name) : spin_once_state_(false), |
||||
window_position_(Vec2i(std::numeric_limits<int>::min())), widget_actor_map_(new WidgetActorMap) |
||||
{ |
||||
renderer_ = vtkSmartPointer<vtkRenderer>::New(); |
||||
window_name_ = VizStorage::generateWindowName(name); |
||||
|
||||
// Create render window
|
||||
window_ = vtkSmartPointer<vtkRenderWindow>::New(); |
||||
cv::Vec2i window_size = cv::Vec2i(window_->GetScreenSize()) / 2; |
||||
window_->SetSize(window_size.val); |
||||
window_->AddRenderer(renderer_); |
||||
|
||||
// Create the interactor style
|
||||
style_ = vtkSmartPointer<InteractorStyle>::New(); |
||||
style_->setWidgetActorMap(widget_actor_map_); |
||||
style_->UseTimersOn(); |
||||
style_->Initialize(); |
||||
|
||||
timer_callback_ = vtkSmartPointer<TimerCallback>::New(); |
||||
exit_callback_ = vtkSmartPointer<ExitCallback>::New(); |
||||
exit_callback_->viz = this; |
||||
} |
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::Viz3d::VizImpl::TimerCallback::Execute(vtkObject* caller, unsigned long event_id, void* cookie) |
||||
{ |
||||
if (event_id == vtkCommand::TimerEvent && timer_id == *reinterpret_cast<int*>(cookie)) |
||||
{ |
||||
vtkSmartPointer<vtkRenderWindowInteractor> interactor = vtkRenderWindowInteractor::SafeDownCast(caller); |
||||
interactor->TerminateApp(); |
||||
} |
||||
} |
||||
|
||||
void cv::viz::Viz3d::VizImpl::ExitCallback::Execute(vtkObject*, unsigned long event_id, void*) |
||||
{ |
||||
if (event_id == vtkCommand::ExitEvent) |
||||
{ |
||||
viz->interactor_->TerminateApp(); |
||||
viz->interactor_ = 0; |
||||
} |
||||
} |
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool cv::viz::Viz3d::VizImpl::wasStopped() const |
||||
{ |
||||
bool stopped = spin_once_state_ ? interactor_ == 0 : false; |
||||
spin_once_state_ &= !stopped; |
||||
return stopped; |
||||
} |
||||
|
||||
void cv::viz::Viz3d::VizImpl::close() |
||||
{ |
||||
if (!interactor_) |
||||
return; |
||||
interactor_->GetRenderWindow()->Finalize(); |
||||
interactor_->TerminateApp(); // This tends to close the window...
|
||||
interactor_ = 0; |
||||
} |
||||
|
||||
void cv::viz::Viz3d::VizImpl::recreateRenderWindow() |
||||
{ |
||||
#if !defined _MSC_VER |
||||
//recreating is workaround for Ubuntu -- a crash in x-server
|
||||
Vec2i window_size(window_->GetSize()); |
||||
int fullscreen = window_->GetFullScreen(); |
||||
|
||||
window_ = vtkSmartPointer<vtkRenderWindow>::New(); |
||||
if (window_position_[0] != std::numeric_limits<int>::min()) //also workaround
|
||||
window_->SetPosition(window_position_.val); |
||||
|
||||
window_->SetSize(window_size.val); |
||||
window_->SetFullScreen(fullscreen); |
||||
window_->AddRenderer(renderer_); |
||||
#endif |
||||
} |
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::Viz3d::VizImpl::spin() |
||||
{ |
||||
recreateRenderWindow(); |
||||
interactor_ = vtkSmartPointer<vtkRenderWindowInteractor>::New(); |
||||
interactor_->SetRenderWindow(window_); |
||||
interactor_->SetInteractorStyle(style_); |
||||
window_->AlphaBitPlanesOff(); |
||||
window_->PointSmoothingOff(); |
||||
window_->LineSmoothingOff(); |
||||
window_->PolygonSmoothingOff(); |
||||
window_->SwapBuffersOn(); |
||||
window_->SetStereoTypeToAnaglyph(); |
||||
window_->Render(); |
||||
window_->SetWindowName(window_name_.c_str()); |
||||
interactor_->Start(); |
||||
interactor_ = 0; |
||||
} |
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::Viz3d::VizImpl::spinOnce(int time, bool force_redraw) |
||||
{ |
||||
if (interactor_ == 0) |
||||
{ |
||||
spin_once_state_ = true; |
||||
recreateRenderWindow(); |
||||
interactor_ = vtkSmartPointer<vtkRenderWindowInteractor>::New(); |
||||
interactor_->SetRenderWindow(window_); |
||||
interactor_->SetInteractorStyle(style_); |
||||
interactor_->AddObserver(vtkCommand::TimerEvent, timer_callback_); |
||||
interactor_->AddObserver(vtkCommand::ExitEvent, exit_callback_); |
||||
window_->AlphaBitPlanesOff(); |
||||
window_->PointSmoothingOff(); |
||||
window_->LineSmoothingOff(); |
||||
window_->PolygonSmoothingOff(); |
||||
window_->SwapBuffersOn(); |
||||
window_->SetStereoTypeToAnaglyph(); |
||||
window_->Render(); |
||||
window_->SetWindowName(window_name_.c_str()); |
||||
} |
||||
|
||||
vtkSmartPointer<vtkRenderWindowInteractor> local = interactor_; |
||||
|
||||
if (force_redraw) |
||||
local->Render(); |
||||
|
||||
timer_callback_->timer_id = local->CreateRepeatingTimer(std::max(1, time)); |
||||
local->Start(); |
||||
local->DestroyTimer(timer_callback_->timer_id); |
||||
} |
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::Viz3d::VizImpl::showWidget(const String &id, const Widget &widget, const Affine3d &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 = vtkmatrix(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 Affine3d &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 = vtkmatrix(pose.matrix); |
||||
actor->SetUserMatrix(matrix); |
||||
actor->Modified(); |
||||
} |
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::Viz3d::VizImpl::updateWidgetPose(const String &id, const Affine3d &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 ; |
||||
} |
||||
Affine3d updated_pose = pose * Affine3d(*matrix->Element); |
||||
matrix = vtkmatrix(updated_pose.matrix); |
||||
|
||||
actor->SetUserMatrix(matrix); |
||||
actor->Modified(); |
||||
} |
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
cv::Affine3d 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); |
||||
|
||||
return Affine3d(*actor->GetUserMatrix()->Element); |
||||
} |
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
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::removeAllWidgets() |
||||
{ |
||||
widget_actor_map_->clear(); |
||||
renderer_->RemoveAllViewProps(); |
||||
} |
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::Viz3d::VizImpl::showImage(InputArray image, const Size& window_size) |
||||
{ |
||||
removeAllWidgets(); |
||||
if (window_size.width > 0 && window_size.height > 0) |
||||
setWindowSize(window_size); |
||||
|
||||
showWidget("showImage", WImageOverlay(image, Rect(Point(0,0), getWindowSize()))); |
||||
} |
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool cv::viz::Viz3d::VizImpl::removeActorFromRenderer(vtkSmartPointer<vtkProp> actor) |
||||
{ |
||||
vtkPropCollection* actors = renderer_->GetViewProps(); |
||||
actors->InitTraversal(); |
||||
vtkProp* current_actor = NULL; |
||||
while ((current_actor = actors->GetNextProp()) != NULL) |
||||
if (current_actor == actor) |
||||
{ |
||||
renderer_->RemoveActor(actor); |
||||
return true; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::Viz3d::VizImpl::setBackgroundColor(const Color& color, const Color& color2) |
||||
{ |
||||
Color c = vtkcolor(color), c2 = vtkcolor(color2); |
||||
bool gradient = color2[0] >= 0 && color2[1] >= 0 && color2[2] >= 0; |
||||
|
||||
if (gradient) |
||||
{ |
||||
renderer_->SetBackground(c2.val); |
||||
renderer_->SetBackground2(c.val); |
||||
renderer_->GradientBackgroundOn(); |
||||
} |
||||
else |
||||
{ |
||||
renderer_->SetBackground(c.val); |
||||
renderer_->GradientBackgroundOff(); |
||||
} |
||||
} |
||||
|
||||
void cv::viz::Viz3d::VizImpl::setBackgroundMeshLab() |
||||
{ setBackgroundColor(Color(2, 1, 1), Color(240, 120, 120)); } |
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::Viz3d::VizImpl::setBackgroundTexture(InputArray image) |
||||
{ |
||||
if (image.empty()) |
||||
{ |
||||
renderer_->SetBackgroundTexture(0); |
||||
renderer_->TexturedBackgroundOff(); |
||||
return; |
||||
} |
||||
|
||||
vtkSmartPointer<vtkImageMatSource> source = vtkSmartPointer<vtkImageMatSource>::New(); |
||||
source->SetImage(image); |
||||
|
||||
vtkSmartPointer<vtkImageFlip> image_flip = vtkSmartPointer<vtkImageFlip>::New(); |
||||
image_flip->SetFilteredAxis(1); // Vertical flip
|
||||
image_flip->SetInputConnection(source->GetOutputPort()); |
||||
|
||||
vtkSmartPointer<vtkTexture> texture = vtkSmartPointer<vtkTexture>::New(); |
||||
texture->SetInputConnection(image_flip->GetOutputPort()); |
||||
//texture->Update();
|
||||
|
||||
renderer_->SetBackgroundTexture(texture); |
||||
renderer_->TexturedBackgroundOn(); |
||||
} |
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::Viz3d::VizImpl::setCamera(const Camera &camera) |
||||
{ |
||||
vtkSmartPointer<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); |
||||
|
||||
Matx44d proj_mat; |
||||
camera.computeProjectionMatrix(proj_mat); |
||||
|
||||
// Use the intrinsic parameters of the camera to simulate more realistically
|
||||
vtkSmartPointer<vtkMatrix4x4> vtk_matrix = active_camera->GetProjectionTransformMatrix(aspect_ratio, -1.0, 1.0); |
||||
Matx44d old_proj_mat(*vtk_matrix->Element); |
||||
|
||||
// This is a hack around not being able to set Projection Matrix
|
||||
vtkSmartPointer<vtkTransform> transform = vtkSmartPointer<vtkTransform>::New(); |
||||
transform->SetMatrix(vtkmatrix(proj_mat * old_proj_mat.inv())); |
||||
active_camera->SetUserTransform(transform); |
||||
|
||||
renderer_->ResetCameraClippingRange(); |
||||
renderer_->Render(); |
||||
} |
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
cv::viz::Camera cv::viz::Viz3d::VizImpl::getCamera() const |
||||
{ |
||||
vtkSmartPointer<vtkCamera> active_camera = renderer_->GetActiveCamera(); |
||||
|
||||
Size window_size(renderer_->GetRenderWindow()->GetSize()[0], |
||||
renderer_->GetRenderWindow()->GetSize()[1]); |
||||
double aspect_ratio = window_size.width / (double)window_size.height; |
||||
|
||||
vtkSmartPointer<vtkMatrix4x4> proj_matrix = active_camera->GetProjectionTransformMatrix(aspect_ratio, -1.0f, 1.0f); |
||||
return Camera(Matx44d(*proj_matrix->Element), window_size); |
||||
} |
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::Viz3d::VizImpl::setViewerPose(const Affine3d &pose) |
||||
{ |
||||
vtkCamera& camera = *renderer_->GetActiveCamera(); |
||||
|
||||
// Position = extrinsic translation
|
||||
cv::Vec3d pos_vec = pose.translation(); |
||||
|
||||
// Rotate the view vector
|
||||
cv::Matx33d rotation = pose.rotation(); |
||||
cv::Vec3d y_axis(0.0, 1.0, 0.0); |
||||
cv::Vec3d up_vec(rotation * y_axis); |
||||
|
||||
// Compute the new focal point
|
||||
cv::Vec3d z_axis(0.0, 0.0, 1.0); |
||||
cv::Vec3d focal_vec = pos_vec + rotation * z_axis; |
||||
|
||||
camera.SetPosition(pos_vec.val); |
||||
camera.SetFocalPoint(focal_vec.val); |
||||
camera.SetViewUp(up_vec.val); |
||||
|
||||
renderer_->ResetCameraClippingRange(); |
||||
} |
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
cv::Affine3d 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)); |
||||
|
||||
return makeTransformToGlobal(x_axis, y_axis, z_axis, 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); |
||||
Vec3d cam_pos(renderer_->GetActiveCamera()->GetPosition()); |
||||
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; |
||||
} |
||||
} |
||||
} |
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
cv::String cv::viz::Viz3d::VizImpl::getWindowName() const { return window_name_; } |
||||
void cv::viz::Viz3d::VizImpl::setFullScreen(bool mode) { window_->SetFullScreen(mode); } |
||||
void cv::viz::Viz3d::VizImpl::setWindowPosition(const Point& position) { window_position_ = position; window_->SetPosition(position.x, position.y); } |
||||
void cv::viz::Viz3d::VizImpl::setWindowSize(const Size& window_size) { window_->SetSize(window_size.width, window_size.height); } |
||||
cv::Size cv::viz::Viz3d::VizImpl::getWindowSize() const { return Size(Point(Vec2i(window_->GetSize()))); } |
@ -0,0 +1,138 @@ |
||||
/*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
|
||||
//
|
||||
//M*/
|
||||
|
||||
#ifndef __OPENCV_VIZ_VIZ3D_IMPL_HPP__ |
||||
#define __OPENCV_VIZ_VIZ3D_IMPL_HPP__ |
||||
|
||||
struct cv::viz::Viz3d::VizImpl |
||||
{ |
||||
public: |
||||
typedef Viz3d::KeyboardCallback KeyboardCallback; |
||||
typedef Viz3d::MouseCallback MouseCallback; |
||||
|
||||
int ref_counter; |
||||
|
||||
VizImpl(const String &name); |
||||
virtual ~VizImpl() {} |
||||
|
||||
bool wasStopped() const; |
||||
void close(); |
||||
|
||||
void spin(); |
||||
void spinOnce(int time = 1, bool force_redraw = false); |
||||
|
||||
void showWidget(const String &id, const Widget &widget, const Affine3d &pose = Affine3d::Identity()); |
||||
void removeWidget(const String &id); |
||||
Widget getWidget(const String &id) const; |
||||
void removeAllWidgets(); |
||||
|
||||
void showImage(InputArray image, const Size& window_size); |
||||
|
||||
void setWidgetPose(const String &id, const Affine3d &pose); |
||||
void updateWidgetPose(const String &id, const Affine3d &pose); |
||||
Affine3d getWidgetPose(const String &id) const; |
||||
|
||||
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 Affine3d &pose); |
||||
Affine3d 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(const Point& position); |
||||
Size getWindowSize() const; |
||||
void setWindowSize(const Size& window_size); |
||||
void setFullScreen(bool mode); |
||||
String getWindowName() const; |
||||
void setBackgroundColor(const Color& color, const Color& color2); |
||||
void setBackgroundTexture(InputArray image); |
||||
void setBackgroundMeshLab(); |
||||
|
||||
void registerKeyboardCallback(KeyboardCallback callback, void* cookie = 0); |
||||
void registerMouseCallback(MouseCallback callback, void* cookie = 0); |
||||
|
||||
private: |
||||
struct TimerCallback : public vtkCommand |
||||
{ |
||||
static TimerCallback* New() { return new TimerCallback; } |
||||
virtual void Execute(vtkObject* caller, unsigned long event_id, void* cookie); |
||||
int timer_id; |
||||
}; |
||||
|
||||
struct ExitCallback : public vtkCommand |
||||
{ |
||||
static ExitCallback* New() { return new ExitCallback; } |
||||
virtual void Execute(vtkObject*, unsigned long event_id, void*); |
||||
VizImpl* viz; |
||||
}; |
||||
|
||||
mutable bool spin_once_state_; |
||||
vtkSmartPointer<vtkRenderWindowInteractor> interactor_; |
||||
|
||||
vtkSmartPointer<vtkRenderWindow> window_; |
||||
String window_name_; |
||||
Vec2i window_position_; |
||||
|
||||
vtkSmartPointer<TimerCallback> timer_callback_; |
||||
vtkSmartPointer<ExitCallback> exit_callback_; |
||||
|
||||
vtkSmartPointer<vtkRenderer> renderer_; |
||||
vtkSmartPointer<InteractorStyle> style_; |
||||
Ptr<WidgetActorMap> widget_actor_map_; |
||||
|
||||
bool removeActorFromRenderer(vtkSmartPointer<vtkProp> actor); |
||||
void recreateRenderWindow(); |
||||
}; |
||||
|
||||
#endif |
@ -0,0 +1,158 @@ |
||||
/*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:
|
||||
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "precomp.hpp" |
||||
|
||||
namespace cv { namespace viz |
||||
{ |
||||
vtkStandardNewMacro(vtkCloudMatSink); |
||||
}} |
||||
|
||||
cv::viz::vtkCloudMatSink::vtkCloudMatSink() {} |
||||
cv::viz::vtkCloudMatSink::~vtkCloudMatSink() {} |
||||
|
||||
void cv::viz::vtkCloudMatSink::SetOutput(OutputArray _cloud, OutputArray _colors, OutputArray _normals, OutputArray _tcoords) |
||||
{ |
||||
cloud = _cloud; |
||||
colors = _colors; |
||||
normals = _normals; |
||||
tcoords = _tcoords; |
||||
} |
||||
|
||||
void cv::viz::vtkCloudMatSink::WriteData() |
||||
{ |
||||
vtkPolyData *input = this->GetInput(); |
||||
if (!input) |
||||
return; |
||||
|
||||
vtkSmartPointer<vtkPoints> points_Data = input->GetPoints(); |
||||
|
||||
if (cloud.needed() && points_Data) |
||||
{ |
||||
int vtktype = points_Data->GetDataType(); |
||||
CV_Assert(vtktype == VTK_FLOAT || vtktype == VTK_DOUBLE); |
||||
|
||||
cloud.create(1, points_Data->GetNumberOfPoints(), vtktype == VTK_FLOAT ? CV_32FC3 : CV_64FC3); |
||||
Vec3d *ddata = cloud.getMat().ptr<Vec3d>(); |
||||
Vec3f *fdata = cloud.getMat().ptr<Vec3f>(); |
||||
|
||||
if (cloud.depth() == CV_32F) |
||||
for(size_t i = 0; i < cloud.total(); ++i) |
||||
*fdata++ = Vec3d(points_Data->GetPoint(i)); |
||||
|
||||
if (cloud.depth() == CV_64F) |
||||
for(size_t i = 0; i < cloud.total(); ++i) |
||||
*ddata++ = Vec3d(points_Data->GetPoint(i)); |
||||
} |
||||
else |
||||
cloud.release(); |
||||
|
||||
vtkSmartPointer<vtkDataArray> scalars_data = input->GetPointData() ? input->GetPointData()->GetScalars() : 0; |
||||
|
||||
if (colors.needed() && scalars_data) |
||||
{ |
||||
int channels = scalars_data->GetNumberOfComponents(); |
||||
int vtktype = scalars_data->GetDataType(); |
||||
|
||||
CV_Assert((channels == 3 || channels == 4) && "Only 3- or 4-channel color data support is implemented"); |
||||
CV_Assert(cloud.total() == (size_t)scalars_data->GetNumberOfTuples()); |
||||
|
||||
Mat buffer(cloud.size(), CV_64FC(channels)); |
||||
Vec3d *cptr = buffer.ptr<Vec3d>(); |
||||
for(size_t i = 0; i < buffer.total(); ++i) |
||||
*cptr++ = Vec3d(scalars_data->GetTuple(i)); |
||||
|
||||
buffer.convertTo(colors, CV_8U, vtktype == VTK_FLOAT || VTK_FLOAT == VTK_DOUBLE ? 255.0 : 1.0); |
||||
} |
||||
else |
||||
colors.release(); |
||||
|
||||
vtkSmartPointer<vtkDataArray> normals_data = input->GetPointData() ? input->GetPointData()->GetNormals() : 0; |
||||
|
||||
if (normals.needed() && normals_data) |
||||
{ |
||||
int channels = normals_data->GetNumberOfComponents(); |
||||
int vtktype = normals_data->GetDataType(); |
||||
|
||||
CV_Assert((vtktype == VTK_FLOAT || VTK_FLOAT == VTK_DOUBLE) && (channels == 3 || channels == 4)); |
||||
CV_Assert(cloud.total() == (size_t)normals_data->GetNumberOfTuples()); |
||||
|
||||
Mat buffer(cloud.size(), CV_64FC(channels)); |
||||
Vec3d *cptr = buffer.ptr<Vec3d>(); |
||||
for(size_t i = 0; i < buffer.total(); ++i) |
||||
*cptr++ = Vec3d(normals_data->GetTuple(i)); |
||||
|
||||
buffer.convertTo(normals, vtktype == VTK_FLOAT ? CV_32F : CV_64F); |
||||
} |
||||
else |
||||
normals.release(); |
||||
|
||||
vtkSmartPointer<vtkDataArray> coords_data = input->GetPointData() ? input->GetPointData()->GetTCoords() : 0; |
||||
|
||||
if (tcoords.needed() && coords_data) |
||||
{ |
||||
int vtktype = coords_data->GetDataType(); |
||||
|
||||
CV_Assert(vtktype == VTK_FLOAT || VTK_FLOAT == VTK_DOUBLE); |
||||
CV_Assert(cloud.total() == (size_t)coords_data->GetNumberOfTuples()); |
||||
|
||||
Mat buffer(cloud.size(), CV_64FC2); |
||||
Vec2d *cptr = buffer.ptr<Vec2d>(); |
||||
for(size_t i = 0; i < buffer.total(); ++i) |
||||
*cptr++ = Vec2d(coords_data->GetTuple(i)); |
||||
|
||||
buffer.convertTo(tcoords, vtktype == VTK_FLOAT ? CV_32F : CV_64F); |
||||
|
||||
} |
||||
else |
||||
tcoords.release(); |
||||
} |
||||
|
||||
void cv::viz::vtkCloudMatSink::PrintSelf(ostream& os, vtkIndent indent) |
||||
{ |
||||
Superclass::PrintSelf(os, indent); |
||||
os << indent << "Cloud: " << cloud.needed() << "\n"; |
||||
os << indent << "Colors: " << colors.needed() << "\n"; |
||||
os << indent << "Normals: " << normals.needed() << "\n"; |
||||
} |
@ -0,0 +1,79 @@ |
||||
/*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:
|
||||
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
|
||||
//
|
||||
//M*/
|
||||
|
||||
#ifndef __vtkCloudMatSink_h |
||||
#define __vtkCloudMatSink_h |
||||
|
||||
#include <opencv2/core/core.hpp> |
||||
#include <vtkPolyDataWriter.h> |
||||
|
||||
namespace cv |
||||
{ |
||||
namespace viz |
||||
{ |
||||
class vtkCloudMatSink : public vtkPolyDataWriter |
||||
{ |
||||
public: |
||||
static vtkCloudMatSink *New(); |
||||
vtkTypeMacro(vtkCloudMatSink,vtkPolyDataWriter) |
||||
void PrintSelf(ostream& os, vtkIndent indent); |
||||
|
||||
void SetOutput(OutputArray cloud, OutputArray colors = noArray(), OutputArray normals = noArray(), OutputArray tcoords = noArray()); |
||||
|
||||
protected: |
||||
vtkCloudMatSink(); |
||||
~vtkCloudMatSink(); |
||||
|
||||
void WriteData(); |
||||
|
||||
_OutputArray cloud, colors, normals, tcoords; |
||||
|
||||
private: |
||||
vtkCloudMatSink(const vtkCloudMatSink&); // Not implemented.
|
||||
void operator=(const vtkCloudMatSink&); // Not implemented.
|
||||
}; |
||||
} |
||||
} |
||||
|
||||
#endif |
@ -0,0 +1,286 @@ |
||||
/*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:
|
||||
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "precomp.hpp" |
||||
|
||||
namespace cv { namespace viz |
||||
{ |
||||
vtkStandardNewMacro(vtkCloudMatSource); |
||||
|
||||
template<typename _Tp> struct VtkDepthTraits; |
||||
|
||||
template<> struct VtkDepthTraits<float> |
||||
{ |
||||
const static int data_type = VTK_FLOAT; |
||||
typedef vtkFloatArray array_type; |
||||
}; |
||||
|
||||
template<> struct VtkDepthTraits<double> |
||||
{ |
||||
const static int data_type = VTK_DOUBLE; |
||||
typedef vtkDoubleArray array_type; |
||||
}; |
||||
}} |
||||
|
||||
cv::viz::vtkCloudMatSource::vtkCloudMatSource() { SetNumberOfInputPorts(0); } |
||||
cv::viz::vtkCloudMatSource::~vtkCloudMatSource() {} |
||||
|
||||
int cv::viz::vtkCloudMatSource::SetCloud(InputArray _cloud) |
||||
{ |
||||
CV_Assert(_cloud.depth() == CV_32F || _cloud.depth() == CV_64F); |
||||
CV_Assert(_cloud.channels() == 3 || _cloud.channels() == 4); |
||||
|
||||
Mat cloud = _cloud.getMat(); |
||||
|
||||
int total = _cloud.depth() == CV_32F ? filterNanCopy<float>(cloud) : filterNanCopy<double>(cloud); |
||||
|
||||
vertices = vtkSmartPointer<vtkCellArray>::New(); |
||||
vertices->Allocate(vertices->EstimateSize(1, total)); |
||||
vertices->InsertNextCell(total); |
||||
for(int i = 0; i < total; ++i) |
||||
vertices->InsertCellPoint(i); |
||||
|
||||
return total; |
||||
} |
||||
|
||||
int cv::viz::vtkCloudMatSource::SetColorCloud(InputArray _cloud, InputArray _colors) |
||||
{ |
||||
int total = SetCloud(_cloud); |
||||
|
||||
if (_colors.empty()) |
||||
return total; |
||||
|
||||
CV_Assert(_colors.depth() == CV_8U && _colors.channels() <= 4 && _colors.channels() != 2); |
||||
CV_Assert(_colors.size() == _cloud.size()); |
||||
|
||||
Mat cloud = _cloud.getMat(); |
||||
Mat colors = _colors.getMat(); |
||||
|
||||
if (cloud.depth() == CV_32F) |
||||
filterNanColorsCopy<float>(colors, cloud, total); |
||||
else if (cloud.depth() == CV_64F) |
||||
filterNanColorsCopy<double>(colors, cloud, total); |
||||
|
||||
return total; |
||||
} |
||||
|
||||
int cv::viz::vtkCloudMatSource::SetColorCloudNormals(InputArray _cloud, InputArray _colors, InputArray _normals) |
||||
{ |
||||
int total = SetColorCloud(_cloud, _colors); |
||||
|
||||
if (_normals.empty()) |
||||
return total; |
||||
|
||||
CV_Assert(_normals.depth() == CV_32F || _normals.depth() == CV_64F); |
||||
CV_Assert(_normals.channels() == 3 || _normals.channels() == 4); |
||||
CV_Assert(_normals.size() == _cloud.size()); |
||||
|
||||
Mat c = _cloud.getMat(); |
||||
Mat n = _normals.getMat(); |
||||
|
||||
if (n.depth() == CV_32F && c.depth() == CV_32F) |
||||
filterNanNormalsCopy<float, float>(n, c, total); |
||||
else if (n.depth() == CV_32F && c.depth() == CV_64F) |
||||
filterNanNormalsCopy<float, double>(n, c, total); |
||||
else if (n.depth() == CV_64F && c.depth() == CV_32F) |
||||
filterNanNormalsCopy<double, float>(n, c, total); |
||||
else if (n.depth() == CV_64F && c.depth() == CV_64F) |
||||
filterNanNormalsCopy<double, double>(n, c, total); |
||||
else |
||||
CV_Assert(!"Unsupported normals/cloud type"); |
||||
|
||||
return total; |
||||
} |
||||
|
||||
int cv::viz::vtkCloudMatSource::SetColorCloudNormalsTCoords(InputArray _cloud, InputArray _colors, InputArray _normals, InputArray _tcoords) |
||||
{ |
||||
int total = SetColorCloudNormals(_cloud, _colors, _normals); |
||||
|
||||
if (_tcoords.empty()) |
||||
return total; |
||||
|
||||
CV_Assert(_tcoords.depth() == CV_32F || _tcoords.depth() == CV_64F); |
||||
CV_Assert(_tcoords.channels() == 2 && _tcoords.size() == _cloud.size()); |
||||
|
||||
Mat cl = _cloud.getMat(); |
||||
Mat tc = _tcoords.getMat(); |
||||
|
||||
if (tc.depth() == CV_32F && cl.depth() == CV_32F) |
||||
filterNanTCoordsCopy<float, float>(tc, cl, total); |
||||
else if (tc.depth() == CV_32F && cl.depth() == CV_64F) |
||||
filterNanTCoordsCopy<float, double>(tc, cl, total); |
||||
else if (tc.depth() == CV_64F && cl.depth() == CV_32F) |
||||
filterNanTCoordsCopy<double, float>(tc, cl, total); |
||||
else if (tc.depth() == CV_64F && cl.depth() == CV_64F) |
||||
filterNanTCoordsCopy<double, double>(tc, cl, total); |
||||
else |
||||
CV_Assert(!"Unsupported tcoords/cloud type"); |
||||
|
||||
return total; |
||||
} |
||||
|
||||
int cv::viz::vtkCloudMatSource::RequestData(vtkInformation *vtkNotUsed(request), vtkInformationVector **vtkNotUsed(inputVector), vtkInformationVector *outputVector) |
||||
{ |
||||
vtkInformation *outInfo = outputVector->GetInformationObject(0); |
||||
vtkPolyData *output = vtkPolyData::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT())); |
||||
|
||||
output->SetPoints(points); |
||||
output->SetVerts(vertices); |
||||
if (scalars) |
||||
output->GetPointData()->SetScalars(scalars); |
||||
|
||||
if (normals) |
||||
output->GetPointData()->SetNormals(normals); |
||||
|
||||
if (tcoords) |
||||
output->GetPointData()->SetTCoords(tcoords); |
||||
|
||||
return 1; |
||||
} |
||||
|
||||
template<typename _Tp> |
||||
int cv::viz::vtkCloudMatSource::filterNanCopy(const Mat& cloud) |
||||
{ |
||||
CV_DbgAssert(DataType<_Tp>::depth == cloud.depth()); |
||||
points = vtkSmartPointer<vtkPoints>::New(); |
||||
points->SetDataType(VtkDepthTraits<_Tp>::data_type); |
||||
points->Allocate(cloud.total()); |
||||
points->SetNumberOfPoints(cloud.total()); |
||||
|
||||
int s_chs = cloud.channels(); |
||||
int total = 0; |
||||
for (int y = 0; y < cloud.rows; ++y) |
||||
{ |
||||
const _Tp* srow = cloud.ptr<_Tp>(y); |
||||
const _Tp* send = srow + cloud.cols * s_chs; |
||||
|
||||
for (; srow != send; srow += s_chs) |
||||
if (!isNan(srow)) |
||||
points->SetPoint(total++, srow); |
||||
} |
||||
points->SetNumberOfPoints(total); |
||||
points->Squeeze(); |
||||
return total; |
||||
} |
||||
|
||||
template<typename _Msk> |
||||
void cv::viz::vtkCloudMatSource::filterNanColorsCopy(const Mat& cloud_colors, const Mat& mask, int total) |
||||
{ |
||||
Vec3b* array = new Vec3b[total]; |
||||
Vec3b* pos = array; |
||||
|
||||
int s_chs = cloud_colors.channels(); |
||||
int m_chs = mask.channels(); |
||||
for (int y = 0; y < cloud_colors.rows; ++y) |
||||
{ |
||||
const unsigned char* srow = cloud_colors.ptr<unsigned char>(y); |
||||
const unsigned char* send = srow + cloud_colors.cols * s_chs; |
||||
const _Msk* mrow = mask.ptr<_Msk>(y); |
||||
|
||||
if (cloud_colors.channels() == 1) |
||||
{ |
||||
for (; srow != send; srow += s_chs, mrow += m_chs) |
||||
if (!isNan(mrow)) |
||||
*pos++ = Vec3b(srow[0], srow[0], srow[0]); |
||||
} |
||||
else |
||||
for (; srow != send; srow += s_chs, mrow += m_chs) |
||||
if (!isNan(mrow)) |
||||
*pos++ = Vec3b(srow[2], srow[1], srow[0]); |
||||
|
||||
} |
||||
|
||||
scalars = vtkSmartPointer<vtkUnsignedCharArray>::New(); |
||||
scalars->SetName("Colors"); |
||||
scalars->SetNumberOfComponents(3); |
||||
scalars->SetNumberOfTuples(total); |
||||
scalars->SetArray(array->val, total * 3, 0); |
||||
} |
||||
|
||||
template<typename _Tn, typename _Msk> |
||||
void cv::viz::vtkCloudMatSource::filterNanNormalsCopy(const Mat& cloud_normals, const Mat& mask, int total) |
||||
{ |
||||
normals = vtkSmartPointer< typename VtkDepthTraits<_Tn>::array_type >::New(); |
||||
normals->SetName("Normals"); |
||||
normals->SetNumberOfComponents(3); |
||||
normals->SetNumberOfTuples(total); |
||||
|
||||
int s_chs = cloud_normals.channels(); |
||||
int m_chs = mask.channels(); |
||||
|
||||
int pos = 0; |
||||
for (int y = 0; y < cloud_normals.rows; ++y) |
||||
{ |
||||
const _Tn* srow = cloud_normals.ptr<_Tn>(y); |
||||
const _Tn* send = srow + cloud_normals.cols * s_chs; |
||||
|
||||
const _Msk* mrow = mask.ptr<_Msk>(y); |
||||
|
||||
for (; srow != send; srow += s_chs, mrow += m_chs) |
||||
if (!isNan(mrow)) |
||||
normals->SetTuple(pos++, srow); |
||||
} |
||||
} |
||||
|
||||
template<typename _Tn, typename _Msk> |
||||
void cv::viz::vtkCloudMatSource::filterNanTCoordsCopy(const Mat& _tcoords, const Mat& mask, int total) |
||||
{ |
||||
typedef Vec<_Tn, 2> Vec2; |
||||
tcoords = vtkSmartPointer< typename VtkDepthTraits<_Tn>::array_type >::New(); |
||||
tcoords->SetName("TextureCoordinates"); |
||||
tcoords->SetNumberOfComponents(2); |
||||
tcoords->SetNumberOfTuples(total); |
||||
|
||||
int pos = 0; |
||||
for (int y = 0; y < mask.rows; ++y) |
||||
{ |
||||
const Vec2* srow = _tcoords.ptr<Vec2>(y); |
||||
const Vec2* send = srow + _tcoords.cols; |
||||
const _Msk* mrow = mask.ptr<_Msk>(y); |
||||
|
||||
for (; srow != send; ++srow, mrow += mask.channels()) |
||||
if (!isNan(mrow)) |
||||
tcoords->SetTuple(pos++, srow->val); |
||||
} |
||||
} |
@ -0,0 +1,96 @@ |
||||
/*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:
|
||||
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
|
||||
//
|
||||
//M*/
|
||||
|
||||
#ifndef __vtkCloudMatSource_h |
||||
#define __vtkCloudMatSource_h |
||||
|
||||
#include <opencv2/core/core.hpp> |
||||
#include <vtkPolyDataAlgorithm.h> |
||||
#include <vtkSmartPointer.h> |
||||
#include <vtkPoints.h> |
||||
#include <vtkCellArray.h> |
||||
|
||||
namespace cv |
||||
{ |
||||
namespace viz |
||||
{ |
||||
class vtkCloudMatSource : public vtkPolyDataAlgorithm |
||||
{ |
||||
public: |
||||
static vtkCloudMatSource *New(); |
||||
vtkTypeMacro(vtkCloudMatSource,vtkPolyDataAlgorithm) |
||||
|
||||
virtual int SetCloud(InputArray cloud); |
||||
virtual int SetColorCloud(InputArray cloud, InputArray colors); |
||||
virtual int SetColorCloudNormals(InputArray cloud, InputArray colors, InputArray normals); |
||||
virtual int SetColorCloudNormalsTCoords(InputArray cloud, InputArray colors, InputArray normals, InputArray tcoords); |
||||
|
||||
protected: |
||||
vtkCloudMatSource(); |
||||
~vtkCloudMatSource(); |
||||
|
||||
int RequestData(vtkInformation *, vtkInformationVector **, vtkInformationVector *); |
||||
|
||||
vtkSmartPointer<vtkPoints> points; |
||||
vtkSmartPointer<vtkCellArray> vertices; |
||||
vtkSmartPointer<vtkUnsignedCharArray> scalars; |
||||
vtkSmartPointer<vtkDataArray> normals; |
||||
vtkSmartPointer<vtkDataArray> tcoords; |
||||
private: |
||||
vtkCloudMatSource(const vtkCloudMatSource&); // Not implemented.
|
||||
void operator=(const vtkCloudMatSource&); // Not implemented.
|
||||
|
||||
template<typename _Tp> int filterNanCopy(const Mat& cloud); |
||||
template<typename _Msk> void filterNanColorsCopy(const Mat& cloud_colors, const Mat& mask, int total); |
||||
|
||||
template<typename _Tn, typename _Msk> |
||||
void filterNanNormalsCopy(const Mat& cloud_normals, const Mat& mask, int total); |
||||
|
||||
template<typename _Tn, typename _Msk> |
||||
void filterNanTCoordsCopy(const Mat& tcoords, const Mat& mask, int total); |
||||
}; |
||||
} |
||||
} |
||||
|
||||
#endif |
@ -0,0 +1,143 @@ |
||||
/*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:
|
||||
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "precomp.hpp" |
||||
|
||||
namespace cv { namespace viz |
||||
{ |
||||
vtkStandardNewMacro(vtkImageMatSource); |
||||
}} |
||||
|
||||
cv::viz::vtkImageMatSource::vtkImageMatSource() |
||||
{ |
||||
this->SetNumberOfInputPorts(0); |
||||
this->ImageData = vtkImageData::New(); |
||||
} |
||||
|
||||
int cv::viz::vtkImageMatSource::RequestInformation(vtkInformation *, vtkInformationVector**, vtkInformationVector *outputVector) |
||||
{ |
||||
vtkInformation* outInfo = outputVector->GetInformationObject(0); |
||||
|
||||
outInfo->Set(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(), this->ImageData->GetExtent(), 6); |
||||
outInfo->Set(vtkDataObject::SPACING(), 1.0, 1.0, 1.0); |
||||
outInfo->Set(vtkDataObject::ORIGIN(), 0.0, 0.0, 0.0); |
||||
|
||||
vtkDataObject::SetPointDataActiveScalarInfo(outInfo, this->ImageData->GetScalarType(), this->ImageData->GetNumberOfScalarComponents()); |
||||
return 1; |
||||
} |
||||
|
||||
int cv::viz::vtkImageMatSource::RequestData(vtkInformation*, vtkInformationVector**, vtkInformationVector *outputVector) |
||||
{ |
||||
vtkInformation *outInfo = outputVector->GetInformationObject(0); |
||||
|
||||
vtkImageData *output = vtkImageData::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT()) ); |
||||
output->ShallowCopy(this->ImageData); |
||||
return 1; |
||||
} |
||||
|
||||
void cv::viz::vtkImageMatSource::SetImage(InputArray _image) |
||||
{ |
||||
CV_Assert(_image.depth() == CV_8U && (_image.channels() == 1 || _image.channels() == 3 || _image.channels() == 4)); |
||||
|
||||
Mat image = _image.getMat(); |
||||
|
||||
this->ImageData->SetDimensions(image.cols, image.rows, 1); |
||||
#if VTK_MAJOR_VERSION <= 5 |
||||
this->ImageData->SetNumberOfScalarComponents(image.channels()); |
||||
this->ImageData->SetScalarTypeToUnsignedChar(); |
||||
this->ImageData->AllocateScalars(); |
||||
#else |
||||
this->ImageData->AllocateScalars(VTK_UNSIGNED_CHAR, image.channels()); |
||||
#endif |
||||
|
||||
switch(image.channels()) |
||||
{ |
||||
case 1: copyGrayImage(image, this->ImageData); break; |
||||
case 3: copyRGBImage (image, this->ImageData); break; |
||||
case 4: copyRGBAImage(image, this->ImageData); break; |
||||
} |
||||
this->ImageData->Modified(); |
||||
} |
||||
|
||||
void cv::viz::vtkImageMatSource::copyGrayImage(const Mat &source, vtkSmartPointer<vtkImageData> output) |
||||
{ |
||||
unsigned char* dptr = reinterpret_cast<unsigned char*>(output->GetScalarPointer()); |
||||
size_t elem_step = output->GetIncrements()[1]/sizeof(unsigned char); |
||||
|
||||
for (int y = 0; y < source.rows; ++y) |
||||
{ |
||||
unsigned char* drow = dptr + elem_step * y; |
||||
const unsigned char *srow = source.ptr<unsigned char>(y); |
||||
for (int x = 0; x < source.cols; ++x) |
||||
drow[x] = *srow++; |
||||
} |
||||
} |
||||
|
||||
void cv::viz::vtkImageMatSource::copyRGBImage(const Mat &source, vtkSmartPointer<vtkImageData> output) |
||||
{ |
||||
Vec3b* dptr = reinterpret_cast<Vec3b*>(output->GetScalarPointer()); |
||||
size_t elem_step = output->GetIncrements()[1]/sizeof(Vec3b); |
||||
|
||||
for (int y = 0; y < source.rows; ++y) |
||||
{ |
||||
Vec3b* drow = dptr + elem_step * y; |
||||
const unsigned char *srow = source.ptr<unsigned char>(y); |
||||
for (int x = 0; x < source.cols; ++x, srow += source.channels()) |
||||
drow[x] = Vec3b(srow[2], srow[1], srow[0]); |
||||
} |
||||
} |
||||
|
||||
void cv::viz::vtkImageMatSource::copyRGBAImage(const Mat &source, vtkSmartPointer<vtkImageData> output) |
||||
{ |
||||
Vec4b* dptr = reinterpret_cast<Vec4b*>(output->GetScalarPointer()); |
||||
size_t elem_step = output->GetIncrements()[1]/sizeof(Vec4b); |
||||
|
||||
for (int y = 0; y < source.rows; ++y) |
||||
{ |
||||
Vec4b* drow = dptr + elem_step * y; |
||||
const unsigned char *srow = source.ptr<unsigned char>(y); |
||||
for (int x = 0; x < source.cols; ++x, srow += source.channels()) |
||||
drow[x] = Vec4b(srow[2], srow[1], srow[0], srow[3]); |
||||
} |
||||
} |
@ -0,0 +1,82 @@ |
||||
/*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:
|
||||
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "precomp.hpp" |
||||
|
||||
#ifndef __vtkImageMatSource_h |
||||
#define __vtkImageMatSource_h |
||||
|
||||
namespace cv |
||||
{ |
||||
namespace viz |
||||
{ |
||||
class vtkImageMatSource : public vtkImageAlgorithm |
||||
{ |
||||
public: |
||||
static vtkImageMatSource *New(); |
||||
vtkTypeMacro(vtkImageMatSource,vtkImageAlgorithm); |
||||
|
||||
void SetImage(InputArray image); |
||||
|
||||
protected: |
||||
vtkImageMatSource(); |
||||
~vtkImageMatSource() {} |
||||
|
||||
vtkSmartPointer<vtkImageData> ImageData; |
||||
|
||||
int RequestInformation(vtkInformation*, vtkInformationVector**, vtkInformationVector*); |
||||
int RequestData (vtkInformation*, vtkInformationVector**, vtkInformationVector*); |
||||
private: |
||||
vtkImageMatSource(const vtkImageMatSource&); // Not implemented.
|
||||
void operator=(const vtkImageMatSource&); // Not implemented.
|
||||
|
||||
static void copyGrayImage(const Mat &source, vtkSmartPointer<vtkImageData> output); |
||||
static void copyRGBImage (const Mat &source, vtkSmartPointer<vtkImageData> output); |
||||
static void copyRGBAImage(const Mat &source, vtkSmartPointer<vtkImageData> output); |
||||
}; |
||||
} |
||||
} |
||||
|
||||
|
||||
#endif |
@ -0,0 +1,241 @@ |
||||
/*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:
|
||||
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "precomp.hpp" |
||||
|
||||
namespace cv { namespace viz |
||||
{ |
||||
vtkStandardNewMacro(vtkOBJWriter); |
||||
}} |
||||
|
||||
cv::viz::vtkOBJWriter::vtkOBJWriter() |
||||
{ |
||||
std::ofstream fout; // only used to extract the default precision
|
||||
this->DecimalPrecision = fout.precision(); |
||||
this->FileName = NULL; |
||||
this->FileType = VTK_ASCII; |
||||
} |
||||
|
||||
cv::viz::vtkOBJWriter::~vtkOBJWriter(){} |
||||
|
||||
void cv::viz::vtkOBJWriter::WriteData() |
||||
{ |
||||
vtkPolyData *input = this->GetInput(); |
||||
if (!input) |
||||
return; |
||||
|
||||
std::ostream *outfilep = this->OpenVTKFile(); |
||||
if (!outfilep) |
||||
return; |
||||
|
||||
std::ostream& outfile = *outfilep; |
||||
|
||||
//write header
|
||||
outfile << "# wavefront obj file written by the visualization toolkit" << std::endl << std::endl; |
||||
outfile << "mtllib NONE" << std::endl << std::endl; |
||||
|
||||
// write out the points
|
||||
for (int i = 0; i < input->GetNumberOfPoints(); i++) |
||||
{ |
||||
Vec3d p; |
||||
input->GetPoint(i, p.val); |
||||
outfile << std::setprecision(this->DecimalPrecision) << "v " << p[0] << " " << p[1] << " " << p[2] << std::endl; |
||||
} |
||||
|
||||
const int idStart = 1; |
||||
|
||||
// write out the point data
|
||||
vtkSmartPointer<vtkDataArray> normals = input->GetPointData()->GetNormals(); |
||||
if(normals) |
||||
{ |
||||
for (int i = 0; i < normals->GetNumberOfTuples(); i++) |
||||
{ |
||||
Vec3d p; |
||||
normals->GetTuple(i, p.val); |
||||
outfile << std::setprecision(this->DecimalPrecision) << "vn " << p[0] << " " << p[1] << " " << p[2] << std::endl; |
||||
} |
||||
} |
||||
|
||||
vtkSmartPointer<vtkDataArray> tcoords = input->GetPointData()->GetTCoords(); |
||||
if (tcoords) |
||||
{ |
||||
for (int i = 0; i < tcoords->GetNumberOfTuples(); i++) |
||||
{ |
||||
Vec2d p; |
||||
tcoords->GetTuple(i, p.val); |
||||
outfile << std::setprecision(this->DecimalPrecision) << "vt " << p[0] << " " << p[1] << std::endl; |
||||
} |
||||
} |
||||
|
||||
// write out a group name and material
|
||||
outfile << std::endl << "g grp" << idStart << std::endl; |
||||
outfile << "usemtl mtlNONE" << std::endl; |
||||
|
||||
// write out verts if any
|
||||
if (input->GetNumberOfVerts() > 0) |
||||
{ |
||||
vtkIdType npts = 0, *index = 0; |
||||
vtkCellArray *cells = input->GetVerts(); |
||||
for (cells->InitTraversal(); cells->GetNextCell(npts, index); ) |
||||
{ |
||||
outfile << "p "; |
||||
for (int i = 0; i < npts; i++) |
||||
outfile << index[i] + idStart << " "; |
||||
outfile << std::endl; |
||||
} |
||||
} |
||||
|
||||
// write out lines if any
|
||||
if (input->GetNumberOfLines() > 0) |
||||
{ |
||||
vtkIdType npts = 0, *index = 0; |
||||
vtkCellArray *cells = input->GetLines(); |
||||
for (cells->InitTraversal(); cells->GetNextCell(npts, index); ) |
||||
{ |
||||
outfile << "l "; |
||||
if (tcoords) |
||||
{ |
||||
for (int i = 0; i < npts; i++) |
||||
outfile << index[i] + idStart << "/" << index[i] + idStart << " "; |
||||
} |
||||
else |
||||
for (int i = 0; i < npts; i++) |
||||
outfile << index[i] + idStart << " "; |
||||
|
||||
outfile << std::endl; |
||||
} |
||||
} |
||||
|
||||
// write out polys if any
|
||||
if (input->GetNumberOfPolys() > 0) |
||||
{ |
||||
vtkIdType npts = 0, *index = 0; |
||||
vtkCellArray *cells = input->GetPolys(); |
||||
for (cells->InitTraversal(); cells->GetNextCell(npts, index); ) |
||||
{ |
||||
outfile << "f "; |
||||
for (int i = 0; i < npts; i++) |
||||
{ |
||||
if (normals) |
||||
{ |
||||
if (tcoords) |
||||
outfile << index[i] + idStart << "/" << index[i] + idStart << "/" << index[i] + idStart << " "; |
||||
else |
||||
outfile << index[i] + idStart << "//" << index[i] + idStart << " "; |
||||
} |
||||
else |
||||
{ |
||||
if (tcoords) |
||||
outfile << index[i] + idStart << " " << index[i] + idStart << " "; |
||||
else |
||||
outfile << index[i] + idStart << " "; |
||||
} |
||||
} |
||||
outfile << std::endl; |
||||
} |
||||
} |
||||
|
||||
// write out tstrips if any
|
||||
if (input->GetNumberOfStrips() > 0) |
||||
{ |
||||
vtkIdType npts = 0, *index = 0; |
||||
vtkCellArray *cells = input->GetStrips(); |
||||
for (cells->InitTraversal(); cells->GetNextCell(npts, index); ) |
||||
{ |
||||
for (int i = 2, i1, i2; i < npts; ++i) |
||||
{ |
||||
if (i % 2) |
||||
{ |
||||
i1 = i - 1; |
||||
i2 = i - 2; |
||||
} |
||||
else |
||||
{ |
||||
i1 = i - 1; |
||||
i2 = i - 2; |
||||
} |
||||
|
||||
if(normals) |
||||
{ |
||||
if (tcoords) |
||||
{ |
||||
outfile << "f " << index[i1] + idStart << "/" << index[i1] + idStart << "/" << index[i1] + idStart << " " |
||||
<< index[i2]+ idStart << "/" << index[i2] + idStart << "/" << index[i2] + idStart << " " |
||||
<< index[i] + idStart << "/" << index[i] + idStart << "/" << index[i] + idStart << std::endl; |
||||
} |
||||
else |
||||
{ |
||||
outfile << "f " << index[i1] + idStart << "//" << index[i1] + idStart << " " << index[i2] + idStart |
||||
<< "//" << index[i2] + idStart << " " << index[i] + idStart << "//" << index[i] + idStart << std::endl; |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
if (tcoords) |
||||
{ |
||||
outfile << "f " << index[i1] + idStart << "/" << index[i1] + idStart << " " << index[i2] + idStart |
||||
<< "/" << index[i2] + idStart << " " << index[i] + idStart << "/" << index[i] + idStart << std::endl; |
||||
} |
||||
else |
||||
outfile << "f " << index[i1] + idStart << " " << index[i2] + idStart << " " << index[i] + idStart << std::endl; |
||||
} |
||||
} /* for (int i = 2; i < npts; ++i) */ |
||||
} |
||||
} /* if (input->GetNumberOfStrips() > 0) */ |
||||
|
||||
this->CloseVTKFile(outfilep); |
||||
|
||||
// Delete the file if an error occurred
|
||||
if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError) |
||||
{ |
||||
vtkErrorMacro("Ran out of disk space; deleting file: " << this->FileName); |
||||
unlink(this->FileName); |
||||
} |
||||
} |
||||
|
||||
void cv::viz::vtkOBJWriter::PrintSelf(ostream& os, vtkIndent indent) |
||||
{ |
||||
Superclass::PrintSelf(os, indent); |
||||
os << indent << "DecimalPrecision: " << DecimalPrecision << "\n"; |
||||
} |
@ -0,0 +1,79 @@ |
||||
/*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:
|
||||
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
|
||||
//
|
||||
//M*/
|
||||
|
||||
#ifndef __vtkOBJWriter_h |
||||
#define __vtkOBJWriter_h |
||||
|
||||
#include <vtkPolyDataWriter.h> |
||||
|
||||
namespace cv |
||||
{ |
||||
namespace viz |
||||
{ |
||||
class vtkOBJWriter : public vtkPolyDataWriter |
||||
{ |
||||
public: |
||||
static vtkOBJWriter *New(); |
||||
vtkTypeMacro(vtkOBJWriter,vtkPolyDataWriter) |
||||
void PrintSelf(ostream& os, vtkIndent indent); |
||||
|
||||
vtkGetMacro(DecimalPrecision, int); |
||||
vtkSetMacro(DecimalPrecision, int); |
||||
|
||||
protected: |
||||
vtkOBJWriter(); |
||||
~vtkOBJWriter(); |
||||
|
||||
void WriteData(); |
||||
|
||||
int DecimalPrecision; |
||||
|
||||
private: |
||||
vtkOBJWriter(const vtkOBJWriter&); // Not implemented.
|
||||
void operator=(const vtkOBJWriter&); // Not implemented.
|
||||
}; |
||||
} |
||||
} |
||||
|
||||
#endif |
@ -0,0 +1,110 @@ |
||||
/*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:
|
||||
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "precomp.hpp" |
||||
|
||||
namespace cv { namespace viz |
||||
{ |
||||
vtkStandardNewMacro(vtkTrajectorySource); |
||||
}} |
||||
|
||||
cv::viz::vtkTrajectorySource::vtkTrajectorySource() { SetNumberOfInputPorts(0); } |
||||
cv::viz::vtkTrajectorySource::~vtkTrajectorySource() {} |
||||
|
||||
void cv::viz::vtkTrajectorySource::SetTrajectory(InputArray _traj) |
||||
{ |
||||
CV_Assert(_traj.kind() == _InputArray::STD_VECTOR || _traj.kind() == _InputArray::MAT); |
||||
CV_Assert(_traj.type() == CV_32FC(16) || _traj.type() == CV_64FC(16)); |
||||
|
||||
Mat traj; |
||||
_traj.getMat().convertTo(traj, CV_64F); |
||||
const Affine3d* dpath = traj.ptr<Affine3d>(); |
||||
size_t total = traj.total(); |
||||
|
||||
points = vtkSmartPointer<vtkPoints>::New(); |
||||
points->SetDataType(VTK_DOUBLE); |
||||
points->SetNumberOfPoints(total); |
||||
|
||||
tensors = vtkSmartPointer<vtkDoubleArray>::New(); |
||||
tensors->SetNumberOfComponents(9); |
||||
tensors->SetNumberOfTuples(total); |
||||
|
||||
for(size_t i = 0; i < total; ++i, ++dpath) |
||||
{ |
||||
Matx33d R = dpath->rotation().t(); // transposed because of
|
||||
tensors->SetTuple(i, R.val); // column major order
|
||||
|
||||
Vec3d p = dpath->translation(); |
||||
points->SetPoint(i, p.val); |
||||
} |
||||
} |
||||
|
||||
cv::Mat cv::viz::vtkTrajectorySource::ExtractPoints(InputArray _traj) |
||||
{ |
||||
CV_Assert(_traj.kind() == _InputArray::STD_VECTOR || _traj.kind() == _InputArray::MAT); |
||||
CV_Assert(_traj.type() == CV_32FC(16) || _traj.type() == CV_64FC(16)); |
||||
|
||||
Mat points(1, _traj.total(), CV_MAKETYPE(_traj.depth(), 3)); |
||||
const Affine3d* dpath = _traj.getMat().ptr<Affine3d>(); |
||||
const Affine3f* fpath = _traj.getMat().ptr<Affine3f>(); |
||||
|
||||
if (_traj.depth() == CV_32F) |
||||
for(int i = 0; i < points.cols; ++i) |
||||
points.at<Vec3f>(i) = fpath[i].translation(); |
||||
|
||||
if (_traj.depth() == CV_64F) |
||||
for(int i = 0; i < points.cols; ++i) |
||||
points.at<Vec3d>(i) = dpath[i].translation(); |
||||
|
||||
return points; |
||||
} |
||||
|
||||
int cv::viz::vtkTrajectorySource::RequestData(vtkInformation *vtkNotUsed(request), vtkInformationVector **vtkNotUsed(inputVector), vtkInformationVector *outputVector) |
||||
{ |
||||
vtkInformation *outInfo = outputVector->GetInformationObject(0); |
||||
vtkPolyData *output = vtkPolyData::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT())); |
||||
output->SetPoints(points); |
||||
output->GetPointData()->SetTensors(tensors); |
||||
return 1; |
||||
} |
@ -0,0 +1,84 @@ |
||||
/*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:
|
||||
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
|
||||
//
|
||||
//M*/
|
||||
|
||||
#ifndef __vtkTrajectorySource_h |
||||
#define __vtkTrajectorySource_h |
||||
|
||||
#include <opencv2/core/mat.hpp> |
||||
#include <vtkPolyDataAlgorithm.h> |
||||
#include <vtkSmartPointer.h> |
||||
#include <vtkPoints.h> |
||||
#include <vtkCellArray.h> |
||||
|
||||
namespace cv |
||||
{ |
||||
namespace viz |
||||
{ |
||||
class vtkTrajectorySource : public vtkPolyDataAlgorithm |
||||
{ |
||||
public: |
||||
static vtkTrajectorySource *New(); |
||||
vtkTypeMacro(vtkTrajectorySource,vtkPolyDataAlgorithm) |
||||
|
||||
virtual void SetTrajectory(InputArray trajectory); |
||||
|
||||
static Mat ExtractPoints(InputArray trajectory); |
||||
|
||||
protected: |
||||
vtkTrajectorySource(); |
||||
~vtkTrajectorySource(); |
||||
|
||||
vtkSmartPointer<vtkPoints> points; |
||||
vtkSmartPointer<vtkDoubleArray> tensors; |
||||
|
||||
int RequestData(vtkInformation *, vtkInformationVector **, vtkInformationVector *); |
||||
private: |
||||
vtkTrajectorySource(const vtkTrajectorySource&); // Not implemented.
|
||||
void operator=(const vtkTrajectorySource&); // Not implemented.
|
||||
|
||||
}; |
||||
} |
||||
} |
||||
|
||||
#endif |
@ -0,0 +1,93 @@ |
||||
/*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:
|
||||
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "precomp.hpp" |
||||
|
||||
namespace cv { namespace viz |
||||
{ |
||||
vtkStandardNewMacro(vtkXYZWriter); |
||||
}} |
||||
|
||||
cv::viz::vtkXYZWriter::vtkXYZWriter() |
||||
{ |
||||
std::ofstream fout; // only used to extract the default precision
|
||||
this->DecimalPrecision = fout.precision(); |
||||
} |
||||
|
||||
void cv::viz::vtkXYZWriter::WriteData() |
||||
{ |
||||
vtkPolyData *input = this->GetInput(); |
||||
if (!input) |
||||
return; |
||||
|
||||
// OpenVTKFile() will report any errors that happen
|
||||
ostream *outfilep = this->OpenVTKFile(); |
||||
if (!outfilep) |
||||
return; |
||||
|
||||
ostream &outfile = *outfilep; |
||||
|
||||
for(vtkIdType i = 0; i < input->GetNumberOfPoints(); ++i) |
||||
{ |
||||
Vec3d p; |
||||
input->GetPoint(i, p.val); |
||||
outfile << std::setprecision(this->DecimalPrecision) << p[0] << " " << p[1] << " " << p[2] << std::endl; |
||||
} |
||||
|
||||
// Close the file
|
||||
this->CloseVTKFile(outfilep); |
||||
|
||||
// Delete the file if an error occurred
|
||||
if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError) |
||||
{ |
||||
vtkErrorMacro("Ran out of disk space; deleting file: " << this->FileName); |
||||
unlink(this->FileName); |
||||
} |
||||
} |
||||
|
||||
void cv::viz::vtkXYZWriter::PrintSelf(ostream& os, vtkIndent indent) |
||||
{ |
||||
this->Superclass::PrintSelf(os,indent); |
||||
os << indent << "DecimalPrecision: " << this->DecimalPrecision << "\n"; |
||||
} |
@ -0,0 +1,78 @@ |
||||
/*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:
|
||||
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
|
||||
//
|
||||
//M*/
|
||||
|
||||
#ifndef __vtkXYZWriter_h |
||||
#define __vtkXYZWriter_h |
||||
|
||||
#include "vtkPolyDataWriter.h" |
||||
|
||||
namespace cv |
||||
{ |
||||
namespace viz |
||||
{ |
||||
class vtkXYZWriter : public vtkPolyDataWriter |
||||
{ |
||||
public: |
||||
static vtkXYZWriter *New(); |
||||
vtkTypeMacro(vtkXYZWriter,vtkPolyDataWriter) |
||||
void PrintSelf(ostream& os, vtkIndent indent); |
||||
|
||||
vtkGetMacro(DecimalPrecision, int) |
||||
vtkSetMacro(DecimalPrecision, int) |
||||
|
||||
protected: |
||||
vtkXYZWriter(); |
||||
~vtkXYZWriter(){} |
||||
|
||||
void WriteData(); |
||||
|
||||
int DecimalPrecision; |
||||
|
||||
private: |
||||
vtkXYZWriter(const vtkXYZWriter&); // Not implemented.
|
||||
void operator=(const vtkXYZWriter&); // Not implemented.
|
||||
}; |
||||
} |
||||
} |
||||
#endif |
@ -0,0 +1,327 @@ |
||||
/*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
|
||||
//
|
||||
//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) |
||||
{ |
||||
CV_Assert(vtkPLYReader::CanReadFile(file_name.c_str())); |
||||
|
||||
vtkSmartPointer<vtkPLYReader> reader = vtkSmartPointer<vtkPLYReader>::New(); |
||||
reader->SetFileName(file_name.c_str()); |
||||
|
||||
vtkSmartPointer<vtkDataSetMapper> mapper = vtkSmartPointer<vtkDataSetMapper>::New(); |
||||
mapper->SetInputConnection( reader->GetOutputPort() ); |
||||
mapper->ImmediateModeRenderingOff(); |
||||
|
||||
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New(); |
||||
actor->GetProperty()->SetInterpolationToFlat(); |
||||
actor->GetProperty()->BackfaceCullingOn(); |
||||
actor->SetMapper(mapper); |
||||
|
||||
Widget widget; |
||||
WidgetAccessor::setProp(widget, 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)); break; |
||||
case OPACITY: actor->GetProperty()->SetOpacity(value); break; |
||||
case LINE_WIDTH: actor->GetProperty()->SetLineWidth(float(value)); break; |
||||
case IMMEDIATE_RENDERING: actor->GetMapper()->SetImmediateModeRendering(int(value)); break; |
||||
case FONT_SIZE: |
||||
{ |
||||
vtkTextActor* text_actor = vtkTextActor::SafeDownCast(actor); |
||||
CV_Assert("Widget does not have text content." && text_actor); |
||||
text_actor->GetTextProperty()->SetFontSize(int(value)); |
||||
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; |
||||
} |
||||
break; |
||||
} |
||||
case SHADING: |
||||
{ |
||||
switch (int(value)) |
||||
{ |
||||
case SHADING_FLAT: actor->GetProperty()->SetInterpolationToFlat(); break; |
||||
case SHADING_GOURAUD: |
||||
{ |
||||
if (!actor->GetMapper()->GetInput()->GetPointData()->GetNormals()) |
||||
{ |
||||
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkPolyDataMapper::SafeDownCast(actor->GetMapper()); |
||||
CV_Assert("Can't set shading property for such type of widget" && mapper); |
||||
|
||||
vtkSmartPointer<vtkPolyData> with_normals = VtkUtils::ComputeNormals(mapper->GetInput()); |
||||
VtkUtils::SetInputData(mapper, with_normals); |
||||
} |
||||
actor->GetProperty()->SetInterpolationToGouraud(); |
||||
break; |
||||
} |
||||
case SHADING_PHONG: |
||||
{ |
||||
if (!actor->GetMapper()->GetInput()->GetPointData()->GetNormals()) |
||||
{ |
||||
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkPolyDataMapper::SafeDownCast(actor->GetMapper()); |
||||
CV_Assert("Can't set shading property for such type of widget" && mapper); |
||||
|
||||
vtkSmartPointer<vtkPolyData> with_normals = VtkUtils::ComputeNormals(mapper->GetInput()); |
||||
VtkUtils::SetInputData(mapper, with_normals); |
||||
} |
||||
actor->GetProperty()->SetInterpolationToPhong(); |
||||
break; |
||||
} |
||||
} |
||||
break; |
||||
} |
||||
default: |
||||
CV_Assert("setPointCloudRenderingProperties: Unknown property"); |
||||
} |
||||
actor->Modified(); |
||||
} |
||||
|
||||
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 LINE_WIDTH: value = actor->GetProperty()->GetLineWidth(); break; |
||||
case IMMEDIATE_RENDERING: value = actor->GetMapper()->GetImmediateModeRendering(); break; |
||||
|
||||
case FONT_SIZE: |
||||
{ |
||||
vtkTextActor* text_actor = vtkTextActor::SafeDownCast(actor); |
||||
CV_Assert("Widget does not have text content." && text_actor); |
||||
value = text_actor->GetTextProperty()->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
|
||||
|
||||
void cv::viz::Widget3D::setPose(const Affine3d &pose) |
||||
{ |
||||
vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getProp(*this)); |
||||
CV_Assert("Widget is not 3D." && actor); |
||||
|
||||
vtkSmartPointer<vtkMatrix4x4> matrix = vtkmatrix(pose.matrix); |
||||
actor->SetUserMatrix(matrix); |
||||
actor->Modified(); |
||||
} |
||||
|
||||
void cv::viz::Widget3D::updatePose(const Affine3d &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; |
||||
} |
||||
|
||||
Affine3d updated_pose = pose * Affine3d(*matrix->Element); |
||||
matrix = vtkmatrix(updated_pose.matrix); |
||||
|
||||
actor->SetUserMatrix(matrix); |
||||
actor->Modified(); |
||||
} |
||||
|
||||
cv::Affine3d cv::viz::Widget3D::getPose() const |
||||
{ |
||||
vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getProp(*this)); |
||||
CV_Assert("Widget is not 3D." && actor); |
||||
return Affine3d(*actor->GetUserMatrix()->Element); |
||||
} |
||||
|
||||
void cv::viz::Widget3D::applyTransform(const Affine3d &transform) |
||||
{ |
||||
vtkActor *actor = vtkActor::SafeDownCast(WidgetAccessor::getProp(*this)); |
||||
CV_Assert("Widget is not 3D actor." && actor); |
||||
|
||||
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkPolyDataMapper::SafeDownCast(actor->GetMapper()); |
||||
CV_Assert("Widget doesn't have a polydata mapper" && mapper); |
||||
mapper->Update(); |
||||
|
||||
VtkUtils::SetInputData(mapper, VtkUtils::TransformPolydata(mapper->GetInput(), transform)); |
||||
} |
||||
|
||||
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("viz") |
@ -0,0 +1,24 @@ |
||||
#include "test_precomp.hpp" |
||||
|
||||
cv::String cv::Path::combine(const String& item1, const String& item2) |
||||
{ |
||||
if (item1.empty()) |
||||
return item2; |
||||
|
||||
if (item2.empty()) |
||||
return item1; |
||||
|
||||
char last = item1[item1.size()-1]; |
||||
|
||||
bool need_append = last != '/' && last != '\\'; |
||||
return item1 + (need_append ? "/" : "") + item2; |
||||
} |
||||
|
||||
cv::String cv::Path::combine(const String& item1, const String& item2, const String& item3) |
||||
{ return combine(combine(item1, item2), item3); } |
||||
|
||||
cv::String cv::Path::change_extension(const String& file, const String& ext) |
||||
{ |
||||
String::size_type pos = file.find_last_of('.'); |
||||
return pos == String::npos ? file : file.substr(0, pos+1) + ext; |
||||
} |
@ -0,0 +1,104 @@ |
||||
/*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
|
||||
//
|
||||
//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/ts.hpp" |
||||
#include <opencv2/core/core.hpp> |
||||
#include <opencv2/imgproc/imgproc.hpp> |
||||
#include <opencv2/highgui/highgui.hpp> |
||||
#include <opencv2/viz/vizcore.hpp> |
||||
|
||||
#include <iostream> |
||||
#include <fstream> |
||||
#include <string> |
||||
#include <limits> |
||||
|
||||
namespace cv |
||||
{ |
||||
struct Path |
||||
{ |
||||
static String combine(const String& item1, const String& item2); |
||||
static String combine(const String& item1, const String& item2, const String& item3); |
||||
static String change_extension(const String& file, const String& ext); |
||||
}; |
||||
|
||||
inline cv::String get_dragon_ply_file_path() |
||||
{ |
||||
return Path::combine(cvtest::TS::ptr()->get_data_path(), "dragon.ply"); |
||||
} |
||||
|
||||
template<typename _Tp> |
||||
inline std::vector< Affine3<_Tp> > generate_test_trajectory() |
||||
{ |
||||
std::vector< Affine3<_Tp> > result; |
||||
|
||||
for (int i = 0, j = 0; i <= 270; i += 3, j += 10) |
||||
{ |
||||
double x = 2 * cos(i * 3 * CV_PI/180.0) * (1.0 + 0.5 * cos(1.2 + i * 1.2 * CV_PI/180.0)); |
||||
double y = 0.25 + i/270.0 + sin(j * CV_PI/180.0) * 0.2 * sin(0.6 + j * 1.5 * CV_PI/180.0); |
||||
double z = 2 * sin(i * 3 * CV_PI/180.0) * (1.0 + 0.5 * cos(1.2 + i * CV_PI/180.0)); |
||||
result.push_back(viz::makeCameraPose(Vec3d(x, y, z), Vec3d::all(0.0), Vec3d(0.0, 1.0, 0.0))); |
||||
} |
||||
return result; |
||||
} |
||||
|
||||
inline Mat make_gray(const Mat& image) |
||||
{ |
||||
Mat chs[3]; split(image, chs); |
||||
return 0.114 * chs[0] + 0.58 * chs[1] + 0.3 * chs[2]; |
||||
} |
||||
} |
||||
|
||||
#endif |
@ -0,0 +1,54 @@ |
||||
#include "test_precomp.hpp" |
||||
|
||||
using namespace cv; |
||||
using namespace std; |
||||
|
||||
void tutorial2() |
||||
{ |
||||
/// 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.0, -1.0, -1.0), Point3d(1.0, 1.0, 1.0)); |
||||
axis.setRenderingProperty(viz::LINE_WIDTH, 4.0); |
||||
myWindow.showWidget("Line Widget", axis); |
||||
|
||||
/// Construct a cube widget
|
||||
viz::WCube cube_widget(Point3d(0.5, 0.5, 0.0), Point3d(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
|
||||
Vec3d rot_vec = Vec3d::all(0); |
||||
double translation_phase = 0.0, translation = 0.0; |
||||
while(!myWindow.wasStopped()) |
||||
{ |
||||
/* Rotation using rodrigues */ |
||||
/// Rotate around (1,1,1)
|
||||
rot_vec[0] += CV_PI * 0.01; |
||||
rot_vec[1] += CV_PI * 0.01; |
||||
rot_vec[2] += CV_PI * 0.01; |
||||
|
||||
/// Shift on (1,1,1)
|
||||
translation_phase += CV_PI * 0.01; |
||||
translation = sin(translation_phase); |
||||
|
||||
/// Construct pose
|
||||
Affine3d pose(rot_vec, Vec3d(translation, translation, translation)); |
||||
|
||||
myWindow.setWidgetPose("Cube Widget", pose); |
||||
|
||||
myWindow.spinOnce(1, true); |
||||
} |
||||
} |
||||
|
||||
|
||||
TEST(Viz, DISABLED_tutorial2_pose_of_widget) |
||||
{ |
||||
tutorial2(); |
||||
} |
@ -0,0 +1,64 @@ |
||||
#include "test_precomp.hpp" |
||||
|
||||
using namespace cv; |
||||
using namespace std; |
||||
|
||||
/**
|
||||
* @function main |
||||
*/ |
||||
void tutorial3(bool camera_pov) |
||||
{ |
||||
/// 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
|
||||
Point3d cam_pos(3.0, 3.0, 3.0), cam_focal_point(3.0, 3.0, 2.0), cam_y_dir(-1.0, 0.0, 0.0); |
||||
|
||||
/// We can get the pose of the cam using makeCameraPose
|
||||
Affine3d 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
|
||||
Affine3d transform = viz::makeTransformToGlobal(Vec3d(0.0, -1.0, 0.0), Vec3d(-1.0, 0.0, 0.0), Vec3d(0.0, 0.0, -1.0), cam_pos); |
||||
|
||||
/// Create a cloud widget.
|
||||
Mat dragon_cloud = viz::readCloud(get_dragon_ply_file_path()); |
||||
viz::WCloud cloud_widget(dragon_cloud, viz::Color::green()); |
||||
|
||||
/// Pose of the widget in camera frame
|
||||
Affine3d cloud_pose = Affine3d().translate(Vec3d(0.0, 0.0, 3.0)); |
||||
/// Pose of the widget in global frame
|
||||
Affine3d 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.889484f, 0.523599f)); // 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(); |
||||
} |
||||
|
||||
TEST(Viz, DISABLED_tutorial3_global_view) |
||||
{ |
||||
tutorial3(false); |
||||
} |
||||
|
||||
TEST(Viz, DISABLED_tutorial3_camera_view) |
||||
{ |
||||
tutorial3(true); |
||||
} |
@ -0,0 +1,64 @@ |
||||
/*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" |
||||
|
||||
using namespace cv; |
||||
|
||||
TEST(Viz_viz3d, DISABLED_develop) |
||||
{ |
||||
cv::Mat cloud = cv::viz::readCloud(get_dragon_ply_file_path()); |
||||
|
||||
cv::viz::Viz3d viz("abc"); |
||||
viz.setBackgroundMeshLab(); |
||||
viz.showWidget("coo", cv::viz::WCoordinateSystem(1)); |
||||
viz.showWidget("cloud", cv::viz::WPaintedCloud(cloud)); |
||||
|
||||
//---->>>>> <to_test_in_future>
|
||||
//std::vector<cv::Affine3d> gt, es;
|
||||
//cv::viz::readTrajectory(gt, "d:/Datasets/trajs/gt%05d.xml");
|
||||
//cv::viz::readTrajectory(es, "d:/Datasets/trajs/es%05d.xml");
|
||||
//cv::Mat cloud = cv::viz::readCloud(get_dragon_ply_file_path());
|
||||
//---->>>>> </to_test_in_future>
|
||||
|
||||
|
||||
viz.spin(); |
||||
} |
@ -0,0 +1,407 @@ |
||||
/*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" |
||||
|
||||
using namespace cv; |
||||
using namespace cv::viz; |
||||
|
||||
TEST(Viz, show_cloud_bluberry) |
||||
{ |
||||
Mat dragon_cloud = readCloud(get_dragon_ply_file_path()); |
||||
|
||||
Affine3d pose = Affine3d().rotate(Vec3d(0, 0.8, 0)); |
||||
|
||||
Viz3d viz("show_cloud_bluberry"); |
||||
viz.showWidget("coosys", WCoordinateSystem()); |
||||
viz.showWidget("dragon", WCloud(dragon_cloud, Color::bluberry()), pose); |
||||
|
||||
viz.showWidget("text2d", WText("Bluberry cloud", Point(20, 20), 20, Color::green())); |
||||
viz.spin(); |
||||
} |
||||
|
||||
TEST(Viz, show_cloud_random_color) |
||||
{ |
||||
Mat dragon_cloud = readCloud(get_dragon_ply_file_path()); |
||||
|
||||
Mat colors(dragon_cloud.size(), CV_8UC3); |
||||
theRNG().fill(colors, RNG::UNIFORM, 0, 255); |
||||
|
||||
Affine3d pose = Affine3d().rotate(Vec3d(0, 0.8, 0)); |
||||
|
||||
Viz3d viz("show_cloud_random_color"); |
||||
viz.setBackgroundMeshLab(); |
||||
viz.showWidget("coosys", WCoordinateSystem()); |
||||
viz.showWidget("dragon", WCloud(dragon_cloud, colors), pose); |
||||
viz.showWidget("text2d", WText("Random color cloud", Point(20, 20), 20, Color::green())); |
||||
viz.spin(); |
||||
} |
||||
|
||||
TEST(Viz, show_cloud_masked) |
||||
{ |
||||
Mat dragon_cloud = readCloud(get_dragon_ply_file_path()); |
||||
|
||||
Vec3f qnan = Vec3f::all(std::numeric_limits<float>::quiet_NaN()); |
||||
for(size_t i = 0; i < dragon_cloud.total(); ++i) |
||||
if (i % 15 != 0) |
||||
dragon_cloud.at<Vec3f>(i) = qnan; |
||||
|
||||
Affine3d pose = Affine3d().rotate(Vec3d(0, 0.8, 0)); |
||||
|
||||
Viz3d viz("show_cloud_masked"); |
||||
viz.showWidget("coosys", WCoordinateSystem()); |
||||
viz.showWidget("dragon", WCloud(dragon_cloud), pose); |
||||
viz.showWidget("text2d", WText("Nan masked cloud", Point(20, 20), 20, Color::green())); |
||||
viz.spin(); |
||||
} |
||||
|
||||
TEST(Viz, show_cloud_collection) |
||||
{ |
||||
Mat cloud = readCloud(get_dragon_ply_file_path()); |
||||
|
||||
WCloudCollection ccol; |
||||
ccol.addCloud(cloud, Color::white(), Affine3d().translate(Vec3d(0, 0, 0)).rotate(Vec3d(CV_PI/2, 0, 0))); |
||||
ccol.addCloud(cloud, Color::blue(), Affine3d().translate(Vec3d(1, 0, 0))); |
||||
ccol.addCloud(cloud, Color::red(), Affine3d().translate(Vec3d(2, 0, 0))); |
||||
|
||||
Viz3d viz("show_cloud_collection"); |
||||
viz.setBackgroundColor(Color::mlab()); |
||||
viz.showWidget("coosys", WCoordinateSystem()); |
||||
viz.showWidget("ccol", ccol); |
||||
viz.showWidget("text2d", WText("Cloud collection", Point(20, 20), 20, Color::green())); |
||||
viz.spin(); |
||||
} |
||||
|
||||
TEST(Viz, show_painted_clouds) |
||||
{ |
||||
Mat cloud = readCloud(get_dragon_ply_file_path()); |
||||
|
||||
Viz3d viz("show_painted_clouds"); |
||||
viz.setBackgroundMeshLab(); |
||||
viz.showWidget("coosys", WCoordinateSystem()); |
||||
viz.showWidget("cloud1", WPaintedCloud(cloud), Affine3d(Vec3d(0.0, -CV_PI/2, 0.0), Vec3d(-1.5, 0.0, 0.0))); |
||||
viz.showWidget("cloud2", WPaintedCloud(cloud, Vec3d(0.0, -0.75, -1.0), Vec3d(0.0, 0.75, 0.0)), Affine3d(Vec3d(0.0, CV_PI/2, 0.0), Vec3d(1.5, 0.0, 0.0))); |
||||
viz.showWidget("cloud3", WPaintedCloud(cloud, Vec3d(0.0, 0.0, -1.0), Vec3d(0.0, 0.0, 1.0), Color::blue(), Color::red())); |
||||
viz.showWidget("arrow", WArrow(Vec3d(0.0, 1.0, -1.0), Vec3d(0.0, 1.0, 1.0), 0.009, Color::raspberry())); |
||||
viz.showWidget("text2d", WText("Painted clouds", Point(20, 20), 20, Color::green())); |
||||
viz.spin(); |
||||
} |
||||
|
||||
TEST(Viz, show_mesh) |
||||
{ |
||||
Mesh mesh = Mesh::load(get_dragon_ply_file_path()); |
||||
|
||||
Affine3d pose = Affine3d().rotate(Vec3d(0, 0.8, 0)); |
||||
|
||||
Viz3d viz("show_mesh"); |
||||
viz.showWidget("coosys", WCoordinateSystem()); |
||||
viz.showWidget("mesh", WMesh(mesh), pose); |
||||
viz.showWidget("text2d", WText("Just mesh", Point(20, 20), 20, Color::green())); |
||||
viz.spin(); |
||||
} |
||||
|
||||
TEST(Viz, show_mesh_random_colors) |
||||
{ |
||||
Mesh mesh = Mesh::load(get_dragon_ply_file_path()); |
||||
theRNG().fill(mesh.colors, RNG::UNIFORM, 0, 255); |
||||
|
||||
Affine3d pose = Affine3d().rotate(Vec3d(0, 0.8, 0)); |
||||
|
||||
Viz3d viz("show_mesh_random_color"); |
||||
viz.showWidget("coosys", WCoordinateSystem()); |
||||
viz.showWidget("mesh", WMesh(mesh), pose); |
||||
viz.setRenderingProperty("mesh", SHADING, SHADING_PHONG); |
||||
viz.showWidget("text2d", WText("Random color mesh", Point(20, 20), 20, Color::green())); |
||||
viz.spin(); |
||||
} |
||||
|
||||
TEST(Viz, show_textured_mesh) |
||||
{ |
||||
Mat lena = imread(Path::combine(cvtest::TS::ptr()->get_data_path(), "lena.png")); |
||||
|
||||
std::vector<Vec3d> points; |
||||
std::vector<Vec2d> tcoords; |
||||
std::vector<int> polygons; |
||||
for(size_t i = 0; i < 64; ++i) |
||||
{ |
||||
double angle = CV_PI/2 * i/64.0; |
||||
points.push_back(Vec3d(0.00, cos(angle), sin(angle))*0.75); |
||||
points.push_back(Vec3d(1.57, cos(angle), sin(angle))*0.75); |
||||
tcoords.push_back(Vec2d(0.0, i/64.0)); |
||||
tcoords.push_back(Vec2d(1.0, i/64.0)); |
||||
} |
||||
|
||||
for(size_t i = 0; i < points.size()/2-1; ++i) |
||||
{ |
||||
int polys[] = {3, 2*i, 2*i+1, 2*i+2, 3, 2*i+1, 2*i+2, 2*i+3}; |
||||
polygons.insert(polygons.end(), polys, polys + sizeof(polys)/sizeof(polys[0])); |
||||
} |
||||
|
||||
cv::viz::Mesh mesh; |
||||
mesh.cloud = Mat(points, true).reshape(3, 1); |
||||
mesh.tcoords = Mat(tcoords, true).reshape(2, 1); |
||||
mesh.polygons = Mat(polygons, true).reshape(1, 1); |
||||
mesh.texture = lena; |
||||
|
||||
Viz3d viz("show_textured_mesh"); |
||||
viz.setBackgroundMeshLab(); |
||||
viz.showWidget("coosys", WCoordinateSystem()); |
||||
viz.showWidget("mesh", WMesh(mesh)); |
||||
viz.setRenderingProperty("mesh", SHADING, SHADING_PHONG); |
||||
viz.showWidget("text2d", WText("Textured mesh", Point(20, 20), 20, Color::green())); |
||||
viz.spin(); |
||||
} |
||||
|
||||
TEST(Viz, show_polyline) |
||||
{ |
||||
Mat polyline(1, 32, CV_64FC3); |
||||
for(size_t i = 0; i < polyline.total(); ++i) |
||||
polyline.at<Vec3d>(i) = Vec3d(i/16.0, cos(i * CV_PI/6), sin(i * CV_PI/6)); |
||||
|
||||
Viz3d viz("show_polyline"); |
||||
viz.showWidget("polyline", WPolyLine(Mat(polyline), Color::apricot())); |
||||
viz.showWidget("coosys", WCoordinateSystem()); |
||||
viz.showWidget("text2d", WText("Polyline", Point(20, 20), 20, Color::green())); |
||||
viz.spin(); |
||||
} |
||||
|
||||
TEST(Viz, show_sampled_normals) |
||||
{ |
||||
Mesh mesh = Mesh::load(get_dragon_ply_file_path()); |
||||
computeNormals(mesh, mesh.normals); |
||||
|
||||
Affine3d pose = Affine3d().rotate(Vec3d(0, 0.8, 0)); |
||||
|
||||
Viz3d viz("show_sampled_normals"); |
||||
viz.showWidget("mesh", WMesh(mesh), pose); |
||||
viz.showWidget("normals", WCloudNormals(mesh.cloud, mesh.normals, 30, 0.1f, Color::green()), pose); |
||||
viz.setRenderingProperty("normals", LINE_WIDTH, 2.0); |
||||
viz.showWidget("text2d", WText("Cloud or mesh normals", Point(20, 20), 20, Color::green())); |
||||
viz.spin(); |
||||
} |
||||
|
||||
TEST(Viz, show_trajectories) |
||||
{ |
||||
std::vector<Affine3d> path = generate_test_trajectory<double>(), sub0, sub1, sub2, sub3, sub4, sub5; |
||||
|
||||
Mat(path).rowRange(0, path.size()/10+1).copyTo(sub0); |
||||
Mat(path).rowRange(path.size()/10, path.size()/5+1).copyTo(sub1); |
||||
Mat(path).rowRange(path.size()/5, 11*path.size()/12).copyTo(sub2); |
||||
Mat(path).rowRange(11*path.size()/12, path.size()).copyTo(sub3); |
||||
Mat(path).rowRange(3*path.size()/4, 33*path.size()/40).copyTo(sub4); |
||||
Mat(path).rowRange(33*path.size()/40, 9*path.size()/10).copyTo(sub5); |
||||
Matx33d K(1024.0, 0.0, 320.0, 0.0, 1024.0, 240.0, 0.0, 0.0, 1.0); |
||||
|
||||
Viz3d viz("show_trajectories"); |
||||
viz.showWidget("coos", WCoordinateSystem()); |
||||
viz.showWidget("sub0", WTrajectorySpheres(sub0, 0.25, 0.07)); |
||||
viz.showWidget("sub1", WTrajectory(sub1, WTrajectory::PATH, 0.2, Color::brown())); |
||||
viz.showWidget("sub2", WTrajectory(sub2, WTrajectory::FRAMES, 0.2)); |
||||
viz.showWidget("sub3", WTrajectory(sub3, WTrajectory::BOTH, 0.2, Color::green())); |
||||
viz.showWidget("sub4", WTrajectoryFrustums(sub4, K, 0.3, Color::yellow())); |
||||
viz.showWidget("sub5", WTrajectoryFrustums(sub5, Vec2d(0.78, 0.78), 0.15)); |
||||
viz.showWidget("text2d", WText("Different kinds of supported trajectories", Point(20, 20), 20, Color::green())); |
||||
|
||||
int i = 0; |
||||
while(!viz.wasStopped()) |
||||
{ |
||||
double a = --i % 360; |
||||
Vec3d pose(sin(a * CV_PI/180), 0.7, cos(a * CV_PI/180)); |
||||
viz.setViewerPose(makeCameraPose(pose * 7.5, Vec3d(0.0, 0.5, 0.0), Vec3d(0.0, 0.1, 0.0))); |
||||
viz.spinOnce(20, true); |
||||
} |
||||
viz.resetCamera(); |
||||
viz.spin(); |
||||
} |
||||
|
||||
TEST(Viz, show_trajectory_reposition) |
||||
{ |
||||
std::vector<Affine3f> path = generate_test_trajectory<float>(); |
||||
|
||||
Viz3d viz("show_trajectory_reposition_to_origin"); |
||||
viz.showWidget("coos", WCoordinateSystem()); |
||||
viz.showWidget("sub3", WTrajectory(Mat(path).rowRange(0, path.size()/3), WTrajectory::BOTH, 0.2, Color::brown()), path.front().inv()); |
||||
viz.showWidget("text2d", WText("Trajectory resposition to origin", Point(20, 20), 20, Color::green())); |
||||
viz.spin(); |
||||
} |
||||
|
||||
TEST(Viz, show_camera_positions) |
||||
{ |
||||
Matx33d K(1024.0, 0.0, 320.0, 0.0, 1024.0, 240.0, 0.0, 0.0, 1.0); |
||||
Mat lena = imread(Path::combine(cvtest::TS::ptr()->get_data_path(), "lena.png")); |
||||
Mat gray = make_gray(lena); |
||||
|
||||
Affine3d poses[2]; |
||||
for(int i = 0; i < 2; ++i) |
||||
{ |
||||
Vec3d pose = 5 * Vec3d(sin(3.14 + 2.7 + i*60 * CV_PI/180), 0.4 - i*0.3, cos(3.14 + 2.7 + i*60 * CV_PI/180)); |
||||
poses[i] = makeCameraPose(pose, Vec3d(0.0, 0.0, 0.0), Vec3d(0.0, -0.1, 0.0)); |
||||
} |
||||
|
||||
Viz3d viz("show_camera_positions"); |
||||
viz.showWidget("sphe", WSphere(Point3d(0,0,0), 1.0, 10, Color::orange_red())); |
||||
viz.showWidget("coos", WCoordinateSystem(1.5)); |
||||
viz.showWidget("pos1", WCameraPosition(0.75), poses[0]); |
||||
viz.showWidget("pos2", WCameraPosition(Vec2d(0.78, 0.78), lena, 2.2, Color::green()), poses[0]); |
||||
viz.showWidget("pos3", WCameraPosition(0.75), poses[1]); |
||||
viz.showWidget("pos4", WCameraPosition(K, gray, 3, Color::indigo()), poses[1]); |
||||
viz.showWidget("text2d", WText("Camera positions with images", Point(20, 20), 20, Color::green())); |
||||
viz.spin(); |
||||
} |
||||
|
||||
TEST(Viz, show_overlay_image) |
||||
{ |
||||
Mat lena = imread(Path::combine(cvtest::TS::ptr()->get_data_path(), "lena.png")); |
||||
Mat gray = make_gray(lena); |
||||
|
||||
Size2d half_lsize = Size2d(lena.cols, lena.rows) * 0.5; |
||||
|
||||
Viz3d viz("show_overlay_image"); |
||||
viz.setBackgroundMeshLab(); |
||||
Size vsz = viz.getWindowSize(); |
||||
|
||||
viz.showWidget("coos", WCoordinateSystem()); |
||||
viz.showWidget("cube", WCube()); |
||||
viz.showWidget("img1", WImageOverlay(lena, Rect(Point(10, 10), half_lsize))); |
||||
viz.showWidget("img2", WImageOverlay(gray, Rect(Point(vsz.width-10-lena.cols/2, 10), half_lsize))); |
||||
viz.showWidget("img3", WImageOverlay(gray, Rect(Point(10, vsz.height-10-lena.rows/2), half_lsize))); |
||||
viz.showWidget("img5", WImageOverlay(lena, Rect(Point(vsz.width-10-lena.cols/2, vsz.height-10-lena.rows/2), half_lsize))); |
||||
viz.showWidget("text2d", WText("Overlay images", Point(20, 20), 20, Color::green())); |
||||
|
||||
int i = 0; |
||||
while(!viz.wasStopped()) |
||||
{ |
||||
double a = ++i % 360; |
||||
Vec3d pose(sin(a * CV_PI/180), 0.7, cos(a * CV_PI/180)); |
||||
viz.setViewerPose(makeCameraPose(pose * 3, Vec3d(0.0, 0.5, 0.0), Vec3d(0.0, 0.1, 0.0))); |
||||
viz.getWidget("img1").cast<WImageOverlay>().setImage(lena * pow(sin(i*10*CV_PI/180) * 0.5 + 0.5, 1.0)); |
||||
viz.spinOnce(1, true); |
||||
} |
||||
viz.showWidget("text2d", WText("Overlay images (stopped)", Point(20, 20), 20, Color::green())); |
||||
viz.spin(); |
||||
} |
||||
|
||||
|
||||
TEST(Viz, show_image_method) |
||||
{ |
||||
Mat lena = imread(Path::combine(cvtest::TS::ptr()->get_data_path(), "lena.png")); |
||||
|
||||
Viz3d viz("show_image_method"); |
||||
viz.showImage(lena); |
||||
viz.spinOnce(1500, true); |
||||
viz.showImage(lena, lena.size()); |
||||
viz.spinOnce(1500, true); |
||||
|
||||
cv::viz::imshow("show_image_method", make_gray(lena)).spin(); |
||||
} |
||||
|
||||
TEST(Viz, show_image_3d) |
||||
{ |
||||
Mat lena = imread(Path::combine(cvtest::TS::ptr()->get_data_path(), "lena.png")); |
||||
Mat gray = make_gray(lena); |
||||
|
||||
Viz3d viz("show_image_3d"); |
||||
viz.setBackgroundMeshLab(); |
||||
viz.showWidget("coos", WCoordinateSystem()); |
||||
viz.showWidget("cube", WCube()); |
||||
viz.showWidget("arr0", WArrow(Vec3d(0.5, 0.0, 0.0), Vec3d(1.5, 0.0, 0.0), 0.009, Color::raspberry())); |
||||
viz.showWidget("img0", WImage3D(lena, Size2d(1.0, 1.0)), Affine3d(Vec3d(0.0, CV_PI/2, 0.0), Vec3d(.5, 0.0, 0.0))); |
||||
viz.showWidget("arr1", WArrow(Vec3d(-0.5, -0.5, 0.0), Vec3d(0.2, 0.2, 0.0), 0.009, Color::raspberry())); |
||||
viz.showWidget("img1", WImage3D(gray, Size2d(1.0, 1.0), Vec3d(-0.5, -0.5, 0.0), Vec3d(1.0, 1.0, 0.0), Vec3d(0.0, 1.0, 0.0))); |
||||
|
||||
viz.showWidget("arr3", WArrow(Vec3d::all(-0.5), Vec3d::all(0.5), 0.009, Color::raspberry())); |
||||
|
||||
viz.showWidget("text2d", WText("Images in 3D", Point(20, 20), 20, Color::green())); |
||||
|
||||
int i = 0; |
||||
while(!viz.wasStopped()) |
||||
{ |
||||
viz.getWidget("img0").cast<WImage3D>().setImage(lena * pow(sin(i++*7.5*CV_PI/180) * 0.5 + 0.5, 1.0)); |
||||
viz.spinOnce(1, true); |
||||
} |
||||
viz.showWidget("text2d", WText("Images in 3D (stopped)", Point(20, 20), 20, Color::green())); |
||||
viz.spin(); |
||||
} |
||||
|
||||
TEST(Viz, show_simple_widgets) |
||||
{ |
||||
Viz3d viz("show_simple_widgets"); |
||||
viz.setBackgroundMeshLab(); |
||||
|
||||
viz.showWidget("coos", WCoordinateSystem()); |
||||
viz.showWidget("cube", WCube()); |
||||
viz.showWidget("cub0", WCube(Vec3d::all(-1.0), Vec3d::all(-0.5), false, Color::indigo())); |
||||
viz.showWidget("arro", WArrow(Vec3d::all(-0.5), Vec3d::all(0.5), 0.009, Color::raspberry())); |
||||
viz.showWidget("cir1", WCircle(0.5, 0.01, Color::bluberry())); |
||||
viz.showWidget("cir2", WCircle(0.5, Point3d(0.5, 0.0, 0.0), Vec3d(1.0, 0.0, 0.0), 0.01, Color::apricot())); |
||||
|
||||
viz.showWidget("cyl0", WCylinder(Vec3d(-0.5, 0.5, -0.5), Vec3d(0.5, 0.5, -0.5), 0.125, 30, Color::brown())); |
||||
viz.showWidget("con0", WCone(0.25, 0.125, 6, Color::azure())); |
||||
viz.showWidget("con1", WCone(0.125, Point3d(0.5, -0.5, 0.5), Point3d(0.5, -1.0, 0.5), 6, Color::turquoise())); |
||||
|
||||
viz.showWidget("text2d", WText("Different simple widgets", Point(20, 20), 20, Color::green())); |
||||
viz.showWidget("text3d", WText3D("Simple 3D text", Point3d( 0.5, 0.5, 0.5), 0.125, false, Color::green())); |
||||
|
||||
viz.showWidget("plane1", WPlane(Size2d(0.25, 0.75))); |
||||
viz.showWidget("plane2", WPlane(Vec3d(0.5, -0.5, -0.5), Vec3d(0.0, 1.0, 1.0), Vec3d(1.0, 1.0, 0.0), Size2d(1.0, 0.5), Color::gold())); |
||||
|
||||
viz.showWidget("grid1", WGrid(Vec2i(7,7), Vec2d::all(0.75), Color::gray()), Affine3d().translate(Vec3d(0.0, 0.0, -1.0))); |
||||
|
||||
viz.spin(); |
||||
viz.getWidget("text2d").cast<WText>().setText("Different simple widgets (updated)"); |
||||
viz.getWidget("text3d").cast<WText3D>().setText("Updated text 3D"); |
||||
viz.spin(); |
||||
} |
||||
|
||||
TEST(Viz, show_follower) |
||||
{ |
||||
Viz3d viz("show_follower"); |
||||
|
||||
viz.showWidget("coos", WCoordinateSystem()); |
||||
viz.showWidget("cube", WCube()); |
||||
viz.showWidget("t3d_2", WText3D("Simple 3D follower", Point3d(-0.5, -0.5, 0.5), 0.125, true, Color::green())); |
||||
viz.showWidget("text2d", WText("Follower: text always facing camera", Point(20, 20), 20, Color::green())); |
||||
viz.setBackgroundMeshLab(); |
||||
viz.spin(); |
||||
viz.getWidget("t3d_2").cast<WText3D>().setText("Updated follower 3D"); |
||||
viz.spin(); |
||||
} |
@ -0,0 +1,113 @@ |
||||
/**
|
||||
* @file creating_widgets.cpp |
||||
* @brief Creating custom widgets using VTK |
||||
* @author Ozan Cagri Tonkal |
||||
*/ |
||||
|
||||
#include <opencv2/viz/vizcore.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/vizcore.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::getWindowByName("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/vizcore.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/vizcore.hpp> |
||||
#include <opencv2/calib3d/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; |
||||
} |