Merge pull request #2178 from Nerei:viz_backport
@ -128,6 +128,7 @@ OCV_OPTION(WITH_1394 "Include IEEE1394 support" ON
|
|||||||
OCV_OPTION(WITH_AVFOUNDATION "Use AVFoundation for Video I/O" ON IF IOS)
|
OCV_OPTION(WITH_AVFOUNDATION "Use AVFoundation for Video I/O" ON IF IOS)
|
||||||
OCV_OPTION(WITH_CARBON "Use Carbon for UI instead of Cocoa" OFF IF APPLE )
|
OCV_OPTION(WITH_CARBON "Use Carbon for UI instead of Cocoa" OFF IF APPLE )
|
||||||
OCV_OPTION(WITH_CUDA "Include NVidia Cuda Runtime support" ON IF (CMAKE_VERSION VERSION_GREATER "2.8" AND NOT IOS) )
|
OCV_OPTION(WITH_CUDA "Include NVidia Cuda Runtime support" ON IF (CMAKE_VERSION VERSION_GREATER "2.8" AND NOT IOS) )
|
||||||
|
OCV_OPTION(WITH_VTK "Include VTK library support (and build opencv_viz module eiher)" OFF IF (NOT ANDROID AND NOT IOS) )
|
||||||
OCV_OPTION(WITH_CUFFT "Include NVidia Cuda Fast Fourier Transform (FFT) library support" ON IF (CMAKE_VERSION VERSION_GREATER "2.8" AND NOT IOS) )
|
OCV_OPTION(WITH_CUFFT "Include NVidia Cuda Fast Fourier Transform (FFT) library support" ON IF (CMAKE_VERSION VERSION_GREATER "2.8" AND NOT IOS) )
|
||||||
OCV_OPTION(WITH_CUBLAS "Include NVidia Cuda Basic Linear Algebra Subprograms (BLAS) library support" OFF IF (CMAKE_VERSION VERSION_GREATER "2.8" AND NOT IOS) )
|
OCV_OPTION(WITH_CUBLAS "Include NVidia Cuda Basic Linear Algebra Subprograms (BLAS) library support" OFF IF (CMAKE_VERSION VERSION_GREATER "2.8" AND NOT IOS) )
|
||||||
OCV_OPTION(WITH_NVCUVID "Include NVidia Video Decoding library support" OFF IF (CMAKE_VERSION VERSION_GREATER "2.8" AND NOT ANDROID AND NOT IOS AND NOT APPLE) )
|
OCV_OPTION(WITH_NVCUVID "Include NVidia Video Decoding library support" OFF IF (CMAKE_VERSION VERSION_GREATER "2.8" AND NOT ANDROID AND NOT IOS AND NOT APPLE) )
|
||||||
@ -477,6 +478,9 @@ if(WITH_OPENCL)
|
|||||||
include(cmake/OpenCVDetectOpenCL.cmake)
|
include(cmake/OpenCVDetectOpenCL.cmake)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# --- VTK support ---
|
||||||
|
include(cmake/OpenCVDetectVTK.cmake)
|
||||||
|
|
||||||
# ----------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------
|
||||||
# Add CUDA libraries (needed for apps/tools, samples)
|
# Add CUDA libraries (needed for apps/tools, samples)
|
||||||
# ----------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------
|
||||||
@ -724,6 +728,7 @@ else()
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
status(" OpenGL support:" HAVE_OPENGL THEN "YES (${OPENGL_LIBRARIES})" ELSE NO)
|
status(" OpenGL support:" HAVE_OPENGL THEN "YES (${OPENGL_LIBRARIES})" ELSE NO)
|
||||||
|
status(" VTK support:" HAVE_VTK THEN "YES (ver ${VTK_VERSION})" ELSE NO)
|
||||||
|
|
||||||
# ========================== MEDIA IO ==========================
|
# ========================== MEDIA IO ==========================
|
||||||
status("")
|
status("")
|
||||||
|
26
cmake/OpenCVDetectVTK.cmake
Normal file
@ -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()
|
BIN
doc/tutorials/images/viz.jpg
Normal file
After Width: | Height: | Size: 31 KiB |
@ -186,6 +186,21 @@ As always, we would be happy to hear your comments and receive your contribution
|
|||||||
:width: 80pt
|
:width: 80pt
|
||||||
:alt: gpu icon
|
:alt: gpu icon
|
||||||
|
|
||||||
|
* :ref:`Table-Of-Content-Viz`
|
||||||
|
|
||||||
|
.. tabularcolumns:: m{100pt} m{300pt}
|
||||||
|
.. cssclass:: toctableopencv
|
||||||
|
|
||||||
|
=========== =======================================================
|
||||||
|
|Viz| These tutorials show how to use Viz module effectively.
|
||||||
|
|
||||||
|
=========== =======================================================
|
||||||
|
|
||||||
|
.. |Viz| image:: images/viz.jpg
|
||||||
|
:height: 80pt
|
||||||
|
:width: 80pt
|
||||||
|
:alt: viz icon
|
||||||
|
|
||||||
* :ref:`Table-Of-Content-General`
|
* :ref:`Table-Of-Content-General`
|
||||||
|
|
||||||
.. tabularcolumns:: m{100pt} m{300pt}
|
.. tabularcolumns:: m{100pt} m{300pt}
|
||||||
@ -221,4 +236,5 @@ As always, we would be happy to hear your comments and receive your contribution
|
|||||||
gpu/table_of_content_gpu/table_of_content_gpu
|
gpu/table_of_content_gpu/table_of_content_gpu
|
||||||
contrib/table_of_content_contrib/table_of_content_contrib
|
contrib/table_of_content_contrib/table_of_content_contrib
|
||||||
ios/table_of_content_ios/table_of_content_ios
|
ios/table_of_content_ios/table_of_content_ios
|
||||||
|
viz/table_of_content_viz/table_of_content_viz
|
||||||
general/table_of_content_general/table_of_content_general
|
general/table_of_content_general/table_of_content_general
|
||||||
|
159
doc/tutorials/viz/creating_widgets/creating_widgets.rst
Normal file
@ -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
|
BIN
doc/tutorials/viz/creating_widgets/images/red_triangle.png
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
doc/tutorials/viz/launching_viz/images/window_demo.png
Normal file
After Width: | Height: | Size: 7.3 KiB |
118
doc/tutorials/viz/launching_viz/launching_viz.rst
Normal file
@ -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
|
BIN
doc/tutorials/viz/table_of_content_viz/images/facedetect.jpg
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
doc/tutorials/viz/table_of_content_viz/images/image_effects.png
Normal file
After Width: | Height: | Size: 29 KiB |
BIN
doc/tutorials/viz/table_of_content_viz/images/intro.png
Normal file
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
|
BIN
doc/tutorials/viz/transformations/images/camera_view_point.png
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
doc/tutorials/viz/transformations/images/global_view_point.png
Normal file
After Width: | Height: | Size: 13 KiB |
202
doc/tutorials/viz/transformations/transformations.rst
Normal file
@ -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
|
BIN
doc/tutorials/viz/widget_pose/images/widgetpose.png
Normal file
After Width: | Height: | Size: 40 KiB |
162
doc/tutorials/viz/widget_pose/widget_pose.rst
Normal file
@ -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>
|
509
modules/core/include/opencv2/core/affine.hpp
Normal file
@ -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__ */
|
@ -892,6 +892,7 @@ public:
|
|||||||
typedef Point_<int> Point2i;
|
typedef Point_<int> Point2i;
|
||||||
typedef Point2i Point;
|
typedef Point2i Point;
|
||||||
typedef Size_<int> Size2i;
|
typedef Size_<int> Size2i;
|
||||||
|
typedef Size_<double> Size2d;
|
||||||
typedef Size2i Size;
|
typedef Size2i Size;
|
||||||
typedef Rect_<int> Rect;
|
typedef Rect_<int> Rect;
|
||||||
typedef Point_<float> Point2f;
|
typedef Point_<float> Point2f;
|
||||||
|
11
modules/viz/CMakeLists.txt
Normal file
@ -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()
|
BIN
modules/viz/doc/images/cpw1.png
Normal file
After Width: | Height: | Size: 4.2 KiB |
BIN
modules/viz/doc/images/cpw2.png
Normal file
After Width: | Height: | Size: 3.5 KiB |
BIN
modules/viz/doc/images/cpw3.png
Normal file
After Width: | Height: | Size: 17 KiB |
BIN
modules/viz/doc/images/cube_widget.png
Normal file
After Width: | Height: | Size: 6.4 KiB |
9
modules/viz/doc/viz.rst
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
***********************
|
||||||
|
viz. 3D Visualizer
|
||||||
|
***********************
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 2
|
||||||
|
|
||||||
|
viz3d.rst
|
||||||
|
widget.rst
|
637
modules/viz/doc/viz3d.rst
Normal file
@ -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.
|
1019
modules/viz/doc/widget.rst
Normal file
236
modules/viz/include/opencv2/viz/types.hpp
Normal file
@ -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
|
131
modules/viz/include/opencv2/viz/viz3d.hpp
Normal file
@ -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
|
127
modules/viz/include/opencv2/viz/vizcore.hpp
Normal file
@ -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__ */
|
69
modules/viz/include/opencv2/viz/widget_accessor.hpp
Normal file
@ -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
|
396
modules/viz/include/opencv2/viz/widgets.hpp
Normal file
@ -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
|
441
modules/viz/src/clouds.cpp
Normal file
@ -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);
|
||||||
|
}
|
639
modules/viz/src/interactor_style.cpp
Normal file
@ -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();
|
||||||
|
}
|
119
modules/viz/src/interactor_style.hpp
Normal file
@ -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
|
324
modules/viz/src/precomp.hpp
Normal file
@ -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
|
1088
modules/viz/src/shapes.cpp
Normal file
206
modules/viz/src/types.cpp
Normal file
@ -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);
|
||||||
|
}
|
148
modules/viz/src/viz3d.cpp
Normal file
@ -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); }
|
312
modules/viz/src/vizcore.cpp
Normal file
@ -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();
|
||||||
|
}
|
542
modules/viz/src/vizimpl.cpp
Normal file
@ -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()))); }
|
138
modules/viz/src/vizimpl.hpp
Normal file
@ -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
|
158
modules/viz/src/vtk/vtkCloudMatSink.cpp
Normal file
@ -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";
|
||||||
|
}
|
79
modules/viz/src/vtk/vtkCloudMatSink.h
Normal file
@ -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
|
286
modules/viz/src/vtk/vtkCloudMatSource.cpp
Normal file
@ -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);
|
||||||
|
}
|
||||||
|
}
|
96
modules/viz/src/vtk/vtkCloudMatSource.h
Normal file
@ -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
|
143
modules/viz/src/vtk/vtkImageMatSource.cpp
Normal file
@ -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]);
|
||||||
|
}
|
||||||
|
}
|
82
modules/viz/src/vtk/vtkImageMatSource.h
Normal file
@ -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
|
241
modules/viz/src/vtk/vtkOBJWriter.cpp
Normal file
@ -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";
|
||||||
|
}
|
79
modules/viz/src/vtk/vtkOBJWriter.h
Normal file
@ -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
|
110
modules/viz/src/vtk/vtkTrajectorySource.cpp
Normal file
@ -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;
|
||||||
|
}
|
84
modules/viz/src/vtk/vtkTrajectorySource.h
Normal file
@ -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
|
93
modules/viz/src/vtk/vtkXYZWriter.cpp
Normal file
@ -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";
|
||||||
|
}
|
78
modules/viz/src/vtk/vtkXYZWriter.h
Normal file
@ -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
|
327
modules/viz/src/widget.cpp
Normal file
@ -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;
|
||||||
|
}
|
3
modules/viz/test/test_main.cpp
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
#include "test_precomp.hpp"
|
||||||
|
|
||||||
|
CV_TEST_MAIN("viz")
|
24
modules/viz/test/test_precomp.cpp
Normal file
@ -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;
|
||||||
|
}
|
104
modules/viz/test/test_precomp.hpp
Normal file
@ -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
|
54
modules/viz/test/test_tutorial2.cpp
Normal file
@ -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();
|
||||||
|
}
|
64
modules/viz/test/test_tutorial3.cpp
Normal file
@ -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);
|
||||||
|
}
|
64
modules/viz/test/test_viz3d.cpp
Normal file
@ -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();
|
||||||
|
}
|
407
modules/viz/test/tests_simple.cpp
Normal file
@ -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();
|
||||||
|
}
|
@ -82,6 +82,8 @@ if(BUILD_EXAMPLES AND OCV_DEPENDENCIES_FOUND)
|
|||||||
ocv_list_filterout(cpp_samples "/gpu/")
|
ocv_list_filterout(cpp_samples "/gpu/")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
ocv_list_filterout(cpp_samples "viz")
|
||||||
|
|
||||||
foreach(sample_filename ${cpp_samples})
|
foreach(sample_filename ${cpp_samples})
|
||||||
get_filename_component(sample ${sample_filename} NAME_WE)
|
get_filename_component(sample ${sample_filename} NAME_WE)
|
||||||
OPENCV_DEFINE_CPP_EXAMPLE(${sample} ${sample_filename})
|
OPENCV_DEFINE_CPP_EXAMPLE(${sample} ${sample_filename})
|
||||||
|
5752
samples/cpp/tutorial_code/viz/bunny.ply
Normal file
113
samples/cpp/tutorial_code/viz/creating_widgets.cpp
Normal file
@ -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;
|
||||||
|
}
|
66
samples/cpp/tutorial_code/viz/launching_viz.cpp
Normal file
@ -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;
|
||||||
|
}
|
112
samples/cpp/tutorial_code/viz/transformations.cpp
Normal file
@ -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;
|
||||||
|
}
|
79
samples/cpp/tutorial_code/viz/widget_pose.cpp
Normal file
@ -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;
|
||||||
|
}
|