Merge pull request #2173 from Nerei:viz
This commit is contained in:
commit
9710b25c7d
@ -116,7 +116,7 @@ endif()
|
||||
OCV_OPTION(WITH_1394 "Include IEEE1394 support" ON IF (NOT ANDROID AND NOT 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_VTK "Include VTK library support (and build opencv_viz module eiher)" OFF IF (NOT ANDROID AND NOT IOS) )
|
||||
OCV_OPTION(WITH_VTK "Include VTK library support (and build opencv_viz module eiher)" ON IF (NOT ANDROID AND NOT IOS) )
|
||||
OCV_OPTION(WITH_CUDA "Include NVidia Cuda Runtime support" ON IF (NOT IOS) )
|
||||
OCV_OPTION(WITH_CUFFT "Include NVidia Cuda Fast Fourier Transform (FFT) library support" ON IF (NOT IOS) )
|
||||
OCV_OPTION(WITH_CUBLAS "Include NVidia Cuda Basic Linear Algebra Subprograms (BLAS) library support" OFF IF (NOT IOS) )
|
||||
|
@ -2,7 +2,7 @@ if(NOT WITH_VTK OR ANDROID OR IOS)
|
||||
return()
|
||||
endif()
|
||||
|
||||
find_package(VTK 6.0 QUIET COMPONENTS vtkRenderingCore vtkInteractionWidgets vtkInteractionStyle vtkIOLegacy vtkIOPLY vtkRenderingFreeType vtkRenderingLOD vtkFiltersTexture NO_MODULE)
|
||||
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)
|
||||
@ -18,4 +18,4 @@ if(VTK_FOUND)
|
||||
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()
|
||||
endif()
|
||||
|
@ -43,7 +43,7 @@ You can download the code from :download:`here <../../../../samples/cpp/tutorial
|
||||
cout << "First event loop is over" << endl;
|
||||
|
||||
/// Access window via its name
|
||||
viz::Viz3d sameWindow = viz::get("Viz Demo");
|
||||
viz::Viz3d sameWindow = viz::getWindowByName("Viz Demo");
|
||||
|
||||
/// Start event loop
|
||||
sameWindow.spin();
|
||||
|
@ -55,9 +55,9 @@ namespace cv
|
||||
{
|
||||
public:
|
||||
typedef T float_type;
|
||||
typedef cv::Matx<float_type, 3, 3> Mat3;
|
||||
typedef cv::Matx<float_type, 4, 4> Mat4;
|
||||
typedef cv::Vec<float_type, 3> Vec3;
|
||||
typedef Matx<float_type, 3, 3> Mat3;
|
||||
typedef Matx<float_type, 4, 4> Mat4;
|
||||
typedef Vec<float_type, 3> Vec3;
|
||||
|
||||
Affine3();
|
||||
|
||||
@ -70,11 +70,11 @@ namespace cv
|
||||
//Rodrigues vector
|
||||
Affine3(const Vec3& rvec, const Vec3& t = Vec3::all(0));
|
||||
|
||||
//Combines all contructors above. Supports 4x4, 3x3, 1x3, 3x1 sizes of data matrix
|
||||
explicit Affine3(const cv::Mat& data, const Vec3& t = Vec3::all(0));
|
||||
//Combines all contructors above. Supports 4x4, 3x4, 3x3, 1x3, 3x1 sizes of data matrix
|
||||
explicit Affine3(const Mat& data, const Vec3& t = Vec3::all(0));
|
||||
|
||||
//Euler angles
|
||||
Affine3(float_type alpha, float_type beta, float_type gamma, const Vec3& t = Vec3::all(0));
|
||||
//From 16th element array
|
||||
explicit Affine3(const float_type* vals);
|
||||
|
||||
static Affine3 Identity();
|
||||
|
||||
@ -87,9 +87,6 @@ namespace cv
|
||||
//Combines rotation methods above. Suports 3x3, 1x3, 3x1 sizes of data matrix;
|
||||
void rotation(const Mat& data);
|
||||
|
||||
//Euler angles
|
||||
void rotation(float_type alpha, float_type beta, float_type gamma);
|
||||
|
||||
void linear(const Mat3& L);
|
||||
void translation(const Vec3& t);
|
||||
|
||||
@ -105,6 +102,9 @@ namespace cv
|
||||
// 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;
|
||||
|
||||
@ -113,6 +113,8 @@ namespace cv
|
||||
|
||||
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
|
||||
@ -132,10 +134,26 @@ namespace cv
|
||||
typedef Affine3<float> Affine3f;
|
||||
typedef Affine3<double> Affine3d;
|
||||
|
||||
static cv::Vec3f operator*(const cv::Affine3f& affine, const cv::Vec3f& vector);
|
||||
static cv::Vec3d operator*(const cv::Affine3d& affine, const cv::Vec3d& vector);
|
||||
}
|
||||
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;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
@ -179,6 +197,12 @@ cv::Affine3<T>::Affine3(const cv::Mat& data, const Vec3& t)
|
||||
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);
|
||||
@ -187,13 +211,8 @@ cv::Affine3<T>::Affine3(const cv::Mat& data, const Vec3& t)
|
||||
}
|
||||
|
||||
template<typename T> inline
|
||||
cv::Affine3<T>::Affine3(float_type alpha, float_type beta, float_type gamma, const Vec3& t)
|
||||
{
|
||||
rotation(alpha, beta, gamma);
|
||||
translation(t);
|
||||
matrix.val[12] = matrix.val[13] = matrix.val[14] = 0;
|
||||
matrix.val[15] = 1;
|
||||
}
|
||||
cv::Affine3<T>::Affine3(const float_type* vals) : matrix(vals)
|
||||
{}
|
||||
|
||||
template<typename T> inline
|
||||
cv::Affine3<T> cv::Affine3<T>::Identity()
|
||||
@ -261,12 +280,6 @@ void cv::Affine3<T>::rotation(const cv::Mat& data)
|
||||
CV_Assert(!"Input marix can be 3x3, 1x3 or 3x1");
|
||||
}
|
||||
|
||||
template<typename T> inline
|
||||
void cv::Affine3<T>::rotation(float_type alpha, float_type beta, float_type gamma)
|
||||
{
|
||||
rotation(Vec3(alpha, beta, gamma));
|
||||
}
|
||||
|
||||
template<typename T> inline
|
||||
void cv::Affine3<T>::linear(const Mat3& L)
|
||||
{
|
||||
@ -382,6 +395,12 @@ cv::Affine3<T> cv::Affine3<T>::rotate(const Mat3& R) const
|
||||
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
|
||||
{
|
||||
@ -404,6 +423,12 @@ 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)
|
||||
{
|
||||
|
@ -13,7 +13,7 @@ viz::makeTransformToGlobal
|
||||
--------------------------
|
||||
Takes coordinate frame data and builds transform to global coordinate frame.
|
||||
|
||||
.. ocv:function:: Affine3f viz::makeTransformToGlobal(const Vec3f& axis_x, const Vec3f& axis_y, const Vec3f& axis_z, const Vec3f& origin = Vec3f::all(0))
|
||||
.. 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.
|
||||
@ -26,7 +26,7 @@ viz::makeCameraPose
|
||||
-------------------
|
||||
Constructs camera pose from position, focal_point and up_vector (see gluLookAt() for more infromation).
|
||||
|
||||
.. ocv:function:: Affine3f makeCameraPose(const Vec3f& position, const Vec3f& focal_point, const Vec3f& y_dir)
|
||||
.. 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.
|
||||
@ -34,11 +34,11 @@ Constructs camera pose from position, focal_point and up_vector (see gluLookAt()
|
||||
|
||||
This function returns pose of the camera in global coordinate frame.
|
||||
|
||||
viz::get
|
||||
--------
|
||||
viz::getWindowByName
|
||||
--------------------
|
||||
Retrieves a window by its name.
|
||||
|
||||
.. ocv:function:: Viz3d get(const String &window_name)
|
||||
.. ocv:function:: Viz3d getWindowByName(const String &window_name)
|
||||
|
||||
:param window_name: Name of the window that is to be retrieved.
|
||||
|
||||
@ -51,8 +51,8 @@ This function returns a :ocv:class:`Viz3d` object with the given name.
|
||||
.. code-block:: cpp
|
||||
|
||||
/// window and window_2 are the same windows.
|
||||
viz::Viz3d window = viz::get("myWindow");
|
||||
viz::Viz3d window_2 = viz::get("Viz - myWindow");
|
||||
viz::Viz3d window = viz::getWindowByName("myWindow");
|
||||
viz::Viz3d window_2 = viz::getWindowByName("Viz - myWindow");
|
||||
|
||||
viz::isNan
|
||||
----------
|
||||
@ -94,19 +94,21 @@ The Viz3d class represents a 3D visualizer window. This class is implicitly shar
|
||||
Viz3d& operator=(const Viz3d&);
|
||||
~Viz3d();
|
||||
|
||||
void showWidget(const String &id, const Widget &widget, const Affine3f &pose = Affine3f::Identity());
|
||||
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 Affine3f &pose);
|
||||
void updateWidgetPose(const String &id, const Affine3f &pose);
|
||||
Affine3f getWidgetPose(const String &id) const;
|
||||
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;
|
||||
Affine3f getViewerPose();
|
||||
void setViewerPose(const Affine3f &pose);
|
||||
Affine3d getViewerPose();
|
||||
void setViewerPose(const Affine3d &pose);
|
||||
|
||||
void resetCameraViewpoint (const String &id);
|
||||
void resetCamera();
|
||||
@ -132,8 +134,6 @@ The Viz3d class represents a 3D visualizer window. This class is implicitly shar
|
||||
void setRenderingProperty(const String &id, int property, double value);
|
||||
double getRenderingProperty(const String &id, int property);
|
||||
|
||||
void setDesiredUpdateRate(double rate);
|
||||
double getDesiredUpdateRate();
|
||||
|
||||
void setRepresentation(int representation);
|
||||
private:
|
||||
@ -152,7 +152,7 @@ viz::Viz3d::showWidget
|
||||
----------------------
|
||||
Shows a widget in the window.
|
||||
|
||||
.. ocv:function:: void Viz3d::showWidget(const String &id, const Widget &widget, const Affine3f &pose = Affine3f::Identity())
|
||||
.. 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.
|
||||
@ -182,11 +182,20 @@ 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 Affine3f &pose)
|
||||
.. 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.
|
||||
@ -195,7 +204,7 @@ viz::Viz3d::updateWidgetPose
|
||||
----------------------------
|
||||
Updates pose of a widget in the window by pre-multiplying its current pose.
|
||||
|
||||
.. ocv:function:: void updateWidgetPose(const String &id, const Affine3f &pose)
|
||||
.. 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.
|
||||
@ -204,7 +213,7 @@ viz::Viz3d::getWidgetPose
|
||||
-------------------------
|
||||
Returns the current pose of a widget in the window.
|
||||
|
||||
.. ocv:function:: Affine3f getWidgetPose(const String &id) const
|
||||
.. ocv:function:: Affine3d getWidgetPose(const String &id) const
|
||||
|
||||
:param id: The id of the widget whose pose will be returned.
|
||||
|
||||
@ -226,13 +235,13 @@ viz::Viz3d::getViewerPose
|
||||
-------------------------
|
||||
Returns the current pose of the viewer.
|
||||
|
||||
..ocv:function:: Affine3f getViewerPose()
|
||||
..ocv:function:: Affine3d getViewerPose()
|
||||
|
||||
viz::Viz3d::setViewerPose
|
||||
-------------------------
|
||||
Sets pose of the viewer.
|
||||
|
||||
.. ocv:function:: void setViewerPose(const Affine3f &pose)
|
||||
.. ocv:function:: void setViewerPose(const Affine3d &pose)
|
||||
|
||||
:param pose: The new pose of the viewer.
|
||||
|
||||
@ -414,20 +423,6 @@ Returns rendering property of a widget.
|
||||
* **SHADING_GOURAUD**
|
||||
* **SHADING_PHONG**
|
||||
|
||||
viz::Viz3d::setDesiredUpdateRate
|
||||
--------------------------------
|
||||
Sets desired update rate of the window.
|
||||
|
||||
.. ocv:function:: void setDesiredUpdateRate(double rate)
|
||||
|
||||
:param rate: Desired update rate. The default is 30.
|
||||
|
||||
viz::Viz3d::getDesiredUpdateRate
|
||||
--------------------------------
|
||||
Returns desired update rate of the window.
|
||||
|
||||
.. ocv:function:: double getDesiredUpdateRate()
|
||||
|
||||
viz::Viz3d::setRepresentation
|
||||
-----------------------------
|
||||
Sets geometry representation of the widgets to surface, wireframe or points.
|
||||
@ -468,33 +463,33 @@ This class a represents BGR color. ::
|
||||
static Color gray();
|
||||
};
|
||||
|
||||
viz::Mesh3d
|
||||
viz::Mesh
|
||||
-----------
|
||||
.. ocv:class:: Mesh3d
|
||||
.. ocv:class:: Mesh
|
||||
|
||||
This class wraps mesh attributes, and it can load a mesh from a ``ply`` file. ::
|
||||
|
||||
class CV_EXPORTS Mesh3d
|
||||
class CV_EXPORTS Mesh
|
||||
{
|
||||
public:
|
||||
|
||||
Mat cloud, colors;
|
||||
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 Mesh3d loadMesh(const String& file);
|
||||
|
||||
private:
|
||||
/* hidden */
|
||||
static Mesh load(const String& file);
|
||||
};
|
||||
|
||||
viz::Mesh3d::loadMesh
|
||||
viz::Mesh::load
|
||||
---------------------
|
||||
Loads a mesh from a ``ply`` file.
|
||||
|
||||
.. ocv:function:: static Mesh3d loadMesh(const String& file)
|
||||
.. ocv:function:: static Mesh load(const String& file)
|
||||
|
||||
:param file: File name.
|
||||
:param file: File name (for no only PLY is supported)
|
||||
|
||||
|
||||
viz::KeyboardEvent
|
||||
@ -506,40 +501,28 @@ This class represents a keyboard event. ::
|
||||
class CV_EXPORTS KeyboardEvent
|
||||
{
|
||||
public:
|
||||
static const unsigned int Alt = 1;
|
||||
static const unsigned int Ctrl = 2;
|
||||
static const unsigned int Shift = 4;
|
||||
enum { ALT = 1, CTRL = 2, SHIFT = 4 };
|
||||
enum Action { KEY_UP = 0, KEY_DOWN = 1 };
|
||||
|
||||
//! Create a keyboard event
|
||||
//! - Note that action is true if key is pressed, false if released
|
||||
KeyboardEvent (bool action, const std::string& key_sym, unsigned char key, bool alt, bool ctrl, bool shift);
|
||||
KeyboardEvent(Action action, const String& symbol, unsigned char code, int modifiers);
|
||||
|
||||
bool isAltPressed () const;
|
||||
bool isCtrlPressed () const;
|
||||
bool isShiftPressed () const;
|
||||
|
||||
unsigned char getKeyCode () const;
|
||||
|
||||
const String& getKeySym () const;
|
||||
bool keyDown () const;
|
||||
bool keyUp () const;
|
||||
|
||||
protected:
|
||||
/* hidden */
|
||||
Action action;
|
||||
String symbol;
|
||||
unsigned char code;
|
||||
int modifiers;
|
||||
};
|
||||
|
||||
viz::KeyboardEvent::KeyboardEvent
|
||||
---------------------------------
|
||||
Constructs a KeyboardEvent.
|
||||
|
||||
.. ocv:function:: KeyboardEvent (bool action, const std::string& key_sym, unsigned char key, bool alt, bool ctrl, bool shift)
|
||||
.. 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.
|
||||
|
||||
:param action: If true, key is pressed. If false, key is released.
|
||||
:param key_sym: Name of the key.
|
||||
:param key: Code of the key.
|
||||
:param alt: If true, ``alt`` is pressed.
|
||||
:param ctrl: If true, ``ctrl`` is pressed.
|
||||
:param shift: If true, ``shift`` is pressed.
|
||||
|
||||
viz::MouseEvent
|
||||
---------------
|
||||
@ -553,26 +536,24 @@ This class represents a mouse event. ::
|
||||
enum Type { MouseMove = 1, MouseButtonPress, MouseButtonRelease, MouseScrollDown, MouseScrollUp, MouseDblClick } ;
|
||||
enum MouseButton { NoButton = 0, LeftButton, MiddleButton, RightButton, VScroll } ;
|
||||
|
||||
MouseEvent (const Type& type, const MouseButton& button, const Point& p, bool alt, bool ctrl, bool shift);
|
||||
MouseEvent(const Type& type, const MouseButton& button, const Point& pointer, int modifiers);
|
||||
|
||||
Type type;
|
||||
MouseButton button;
|
||||
Point pointer;
|
||||
unsigned int key_state;
|
||||
int modifiers;
|
||||
};
|
||||
|
||||
viz::MouseEvent::MouseEvent
|
||||
---------------------------
|
||||
Constructs a MouseEvent.
|
||||
|
||||
.. ocv:function:: MouseEvent (const Type& type, const MouseButton& button, const Point& p, bool alt, bool ctrl, bool shift)
|
||||
.. 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 alt: If true, ``alt`` is pressed.
|
||||
:param ctrl: If true, ``ctrl`` is pressed.
|
||||
:param shift: If true, ``shift`` is pressed.
|
||||
:param modifiers: Signals if ``alt``, ``ctrl`` or ``shift`` are pressed or their combination.
|
||||
|
||||
viz::Camera
|
||||
-----------
|
||||
@ -585,24 +566,24 @@ that can extract the intrinsic parameters from ``field of view``, ``intrinsic ma
|
||||
class CV_EXPORTS Camera
|
||||
{
|
||||
public:
|
||||
Camera(float f_x, float f_y, float c_x, float c_y, const Size &window_size);
|
||||
Camera(const Vec2f &fov, const Size &window_size);
|
||||
Camera(const cv::Matx33f &K, const Size &window_size);
|
||||
Camera(const cv::Matx44f &proj, const Size &window_size);
|
||||
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 { return clip_; }
|
||||
inline void setClip(const Vec2d &clip) { clip_ = clip; }
|
||||
inline const Vec2d & getClip() const;
|
||||
inline void setClip(const Vec2d &clip);
|
||||
|
||||
inline const Size & getWindowSize() const { return window_size_; }
|
||||
inline const Size & getWindowSize() const;
|
||||
void setWindowSize(const Size &window_size);
|
||||
|
||||
inline const Vec2f & getFov() const { return fov_; }
|
||||
inline void setFov(const Vec2f & fov) { fov_ = fov; }
|
||||
inline const Vec2d & getFov() const;
|
||||
inline void setFov(const Vec2d & fov);
|
||||
|
||||
inline const Vec2f & getPrincipalPoint() const { return principal_point_; }
|
||||
inline const Vec2f & getFocalLength() const { return focal_; }
|
||||
inline const Vec2d & getPrincipalPoint() const;
|
||||
inline const Vec2d & getFocalLength() const;
|
||||
|
||||
void computeProjectionMatrix(Matx44f &proj) const;
|
||||
void computeProjectionMatrix(Matx44d &proj) const;
|
||||
|
||||
static Camera KinectCamera(const Size &window_size);
|
||||
|
||||
@ -614,7 +595,7 @@ viz::Camera::Camera
|
||||
-------------------
|
||||
Constructs a Camera.
|
||||
|
||||
.. ocv:function:: Camera(float f_x, float f_y, float c_x, float c_y, const Size &window_size)
|
||||
.. 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.
|
||||
@ -622,19 +603,19 @@ Constructs a Camera.
|
||||
:param c_y: y coordinate of the principal point.
|
||||
:param window_size: Size of the window. This together with focal length and principal point determines the field of view.
|
||||
|
||||
.. ocv:function:: Camera(const Vec2f &fov, const Size &window_size)
|
||||
.. 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 cv::Matx33f &K, const Size &window_size)
|
||||
.. 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 cv::Matx44f &proj, const Size &window_size)
|
||||
.. 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.
|
||||
@ -643,7 +624,7 @@ viz::Camera::computeProjectionMatrix
|
||||
------------------------------------
|
||||
Computes projection matrix using intrinsic parameters of the camera.
|
||||
|
||||
.. ocv:function:: void computeProjectionMatrix(Matx44f &proj) const
|
||||
.. ocv:function:: void computeProjectionMatrix(Matx44d &proj) const
|
||||
|
||||
:param proj: Output projection matrix.
|
||||
|
||||
|
@ -170,20 +170,23 @@ Base class of all 3D widgets. ::
|
||||
public:
|
||||
Widget3D() {}
|
||||
|
||||
void setPose(const Affine3f &pose);
|
||||
void updatePose(const Affine3f &pose);
|
||||
Affine3f getPose() const;
|
||||
//! widget position manipulation, i.e. place where it is rendered.
|
||||
void setPose(const Affine3d &pose);
|
||||
void updatePose(const Affine3d &pose);
|
||||
Affine3d getPose() const;
|
||||
|
||||
//! updates internal widget data, i.e. points, normals, etc.
|
||||
void applyTransform(const Affine3d &transform);
|
||||
|
||||
void setColor(const Color &color);
|
||||
private:
|
||||
/* hidden */
|
||||
|
||||
};
|
||||
|
||||
viz::Widget3D::setPose
|
||||
----------------------
|
||||
Sets pose of the widget.
|
||||
|
||||
.. ocv:function:: void setPose(const Affine3f &pose)
|
||||
.. ocv:function:: void setPose(const Affine3d &pose)
|
||||
|
||||
:param pose: The new pose of the widget.
|
||||
|
||||
@ -191,7 +194,7 @@ viz::Widget3D::updateWidgetPose
|
||||
-------------------------------
|
||||
Updates pose of the widget by pre-multiplying its current pose.
|
||||
|
||||
.. ocv:function:: void updateWidgetPose(const Affine3f &pose)
|
||||
.. ocv:function:: void updateWidgetPose(const Affine3d &pose)
|
||||
|
||||
:param pose: The pose that the current pose of the widget will be pre-multiplied by.
|
||||
|
||||
@ -199,7 +202,16 @@ viz::Widget3D::getPose
|
||||
----------------------
|
||||
Returns the current pose of the widget.
|
||||
|
||||
.. ocv:function:: Affine3f getWidgetPose() const
|
||||
.. ocv:function:: Affine3d getWidgetPose() const
|
||||
|
||||
|
||||
viz::Widget3D::applyTransform
|
||||
-------------------------------
|
||||
Transforms internal widget data (i.e. points, normals) using the given transform.
|
||||
|
||||
.. ocv:function:: void applyTransform(const Affine3d &transform)
|
||||
|
||||
:param transform: Specified transformation to apply.
|
||||
|
||||
viz::Widget3D::setColor
|
||||
-----------------------
|
||||
@ -262,27 +274,31 @@ This 3D Widget defines a finite plane. ::
|
||||
class CV_EXPORTS WPlane : public Widget3D
|
||||
{
|
||||
public:
|
||||
WPlane(const Vec4f& coefs, float size = 1.0, const Color &color = Color::white());
|
||||
WPlane(const Vec4f& coefs, const Point3f& pt, float size = 1.0, const Color &color = Color::white());
|
||||
private:
|
||||
/* hidden */
|
||||
//! 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_plane_yaxis,const Size2d& size = Size2d(1.0, 1.0), const Color &color = Color::white());
|
||||
};
|
||||
|
||||
viz::WPlane::WPlane
|
||||
-------------------
|
||||
Constructs a WPlane.
|
||||
Constructs a default plane with center point at origin and normal oriented along z-axis.
|
||||
|
||||
.. ocv:function:: WPlane(const Vec4f& coefs, float size = 1.0, const Color &color = Color::white())
|
||||
.. ocv:function:: WPlane(const Size2d& size = Size2d(1.0, 1.0), const Color &color = Color::white())
|
||||
|
||||
:param coefs: Plane coefficients as in (A,B,C,D) where Ax + By + Cz + D = 0.
|
||||
:param size: Size of the plane.
|
||||
:param size: Size of the plane
|
||||
:param color: :ocv:class:`Color` of the plane.
|
||||
|
||||
.. ocv:function:: WPlane(const Vec4f& coefs, const Point3f& pt, float size = 1.0, const Color &color = Color::white())
|
||||
viz::WPlane::WPlane
|
||||
-------------------
|
||||
Constructs a repositioned plane
|
||||
|
||||
:param coefs: Plane coefficients as in (A,B,C,D) where Ax + By + Cz + D = 0.
|
||||
:param pt: Position of the plane.
|
||||
:param size: Size of the plane.
|
||||
.. ocv:function:: WPlane(const Point3d& center, const Vec3d& normal, const Vec3d& new_yaxis,const Size2d& size = Size2d(1.0, 1.0), const Color &color = Color::white())
|
||||
|
||||
:param center: Center of the plane
|
||||
:param normal: Plane normal orientation
|
||||
:param new_yaxis: Up-vector. New orientation of plane y-axis.
|
||||
:param color: :ocv:class:`Color` of the plane.
|
||||
|
||||
viz::WSphere
|
||||
@ -294,14 +310,14 @@ This 3D Widget defines a sphere. ::
|
||||
class CV_EXPORTS WSphere : public Widget3D
|
||||
{
|
||||
public:
|
||||
WSphere(const cv::Point3f ¢er, float radius, int sphere_resolution = 10, const Color &color = Color::white())
|
||||
WSphere(const cv::Point3f ¢er, double radius, int sphere_resolution = 10, const Color &color = Color::white())
|
||||
};
|
||||
|
||||
viz::WSphere::WSphere
|
||||
---------------------
|
||||
Constructs a WSphere.
|
||||
|
||||
.. ocv:function:: WSphere(const cv::Point3f ¢er, float radius, int sphere_resolution = 10, const Color &color = Color::white())
|
||||
.. ocv:function:: WSphere(const cv::Point3f ¢er, double radius, int sphere_resolution = 10, const Color &color = Color::white())
|
||||
|
||||
:param center: Center of the sphere.
|
||||
:param radius: Radius of the sphere.
|
||||
@ -317,14 +333,14 @@ This 3D Widget defines an arrow. ::
|
||||
class CV_EXPORTS WArrow : public Widget3D
|
||||
{
|
||||
public:
|
||||
WArrow(const Point3f& pt1, const Point3f& pt2, float thickness = 0.03, const Color &color = Color::white());
|
||||
WArrow(const Point3f& pt1, const Point3f& pt2, double thickness = 0.03, const Color &color = Color::white());
|
||||
};
|
||||
|
||||
viz::WArrow::WArrow
|
||||
-----------------------------
|
||||
Constructs an WArrow.
|
||||
|
||||
.. ocv:function:: WArrow(const Point3f& pt1, const Point3f& pt2, float thickness = 0.03, const Color &color = Color::white())
|
||||
.. ocv:function:: WArrow(const Point3f& pt1, const Point3f& pt2, double thickness = 0.03, const Color &color = Color::white())
|
||||
|
||||
:param pt1: Start point of the arrow.
|
||||
:param pt2: End point of the arrow.
|
||||
@ -342,20 +358,75 @@ This 3D Widget defines a circle. ::
|
||||
class CV_EXPORTS WCircle : public Widget3D
|
||||
{
|
||||
public:
|
||||
WCircle(const Point3f& pt, float radius, float thickness = 0.01, const Color &color = Color::white());
|
||||
//! 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());
|
||||
};
|
||||
|
||||
viz::WCircle::WCircle
|
||||
-------------------------------
|
||||
Constructs a WCircle.
|
||||
Constructs default planar circle centred at origin with plane normal along z-axis
|
||||
|
||||
.. ocv:function:: WCircle(const Point3f& pt, float radius, float thickness = 0.01, const Color &color = Color::white())
|
||||
.. ocv:function:: WCircle(double radius, double thickness = 0.01, const Color &color = Color::white())
|
||||
|
||||
:param pt: Center of the circle.
|
||||
:param radius: Radius of the circle.
|
||||
:param thickness: Thickness of the circle.
|
||||
:param color: :ocv:class:`Color` of the circle.
|
||||
|
||||
viz::WCircle::WCircle
|
||||
-------------------------------
|
||||
Constructs repositioned planar circle.
|
||||
|
||||
.. ocv:function:: WCircle(double radius, const Point3d& center, const Vec3d& normal, double thickness = 0.01, const Color &color = Color::white())
|
||||
|
||||
:param radius: Radius of the circle.
|
||||
:param center: Center of the circle.
|
||||
:param normal: Normal of the plane in which the circle lies.
|
||||
:param thickness: Thickness of the circle.
|
||||
:param color: :ocv:class:`Color` of the circle.
|
||||
|
||||
|
||||
viz::WCone
|
||||
-------------------------------
|
||||
.. ocv:class:: WCone
|
||||
|
||||
This 3D Widget defines a cone. ::
|
||||
|
||||
class CV_EXPORTS WCone : public Widget3D
|
||||
{
|
||||
public:
|
||||
//! create default cone, oriented along x-axis with center of its base located at origin
|
||||
WCone(double lenght, 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());
|
||||
};
|
||||
|
||||
viz::WCone::WCone
|
||||
-------------------------------
|
||||
Constructs default cone oriented along x-axis with center of its base located at origin
|
||||
|
||||
.. ocv:function:: WCone(double length, double radius, int resolution = 6.0, const Color &color = Color::white())
|
||||
|
||||
:param length: Length of the cone.
|
||||
:param radius: Radius of the cone.
|
||||
:param resolution: Resolution of the cone.
|
||||
:param color: :ocv:class:`Color` of the cone.
|
||||
|
||||
viz::WCone::WCone
|
||||
-------------------------------
|
||||
Constructs repositioned planar cone.
|
||||
|
||||
.. ocv:function:: WCone(double radius, const Point3d& center, const Point3d& tip, int resolution = 6.0, const Color &color = Color::white())
|
||||
|
||||
:param radius: Radius of the cone.
|
||||
:param center: Center of the cone base.
|
||||
:param tip: Tip of the cone.
|
||||
:param resolution: Resolution of the cone.
|
||||
:param color: :ocv:class:`Color` of the cone.
|
||||
|
||||
viz::WCylinder
|
||||
--------------
|
||||
.. ocv:class:: WCylinder
|
||||
@ -365,17 +436,17 @@ This 3D Widget defines a cylinder. ::
|
||||
class CV_EXPORTS WCylinder : public Widget3D
|
||||
{
|
||||
public:
|
||||
WCylinder(const Point3f& pt_on_axis, const Point3f& axis_direction, float radius, int numsides = 30, const Color &color = Color::white());
|
||||
WCylinder(const Point3d& axis_point1, const Point3d& axis_point2, double radius, int numsides = 30, const Color &color = Color::white());
|
||||
};
|
||||
|
||||
viz::WCylinder::WCylinder
|
||||
-----------------------------------
|
||||
Constructs a WCylinder.
|
||||
|
||||
.. ocv:function:: WCylinder(const Point3f& pt_on_axis, const Point3f& axis_direction, float radius, int numsides = 30, const Color &color = Color::white())
|
||||
.. ocv:function:: WCylinder(const Point3f& pt_on_axis, const Point3f& axis_direction, double radius, int numsides = 30, const Color &color = Color::white())
|
||||
|
||||
:param pt_on_axis: A point on the axis of the cylinder.
|
||||
:param axis_direction: Direction of the axis of the cylinder.
|
||||
:param axis_point1: A point1 on the axis of the cylinder.
|
||||
:param axis_point2: A point2 on the axis of the cylinder.
|
||||
:param radius: Radius of the cylinder.
|
||||
:param numsides: Resolution of the cylinder.
|
||||
:param color: :ocv:class:`Color` of the cylinder.
|
||||
@ -416,14 +487,14 @@ This 3D Widget represents a coordinate system. ::
|
||||
class CV_EXPORTS WCoordinateSystem : public Widget3D
|
||||
{
|
||||
public:
|
||||
WCoordinateSystem(float scale = 1.0);
|
||||
WCoordinateSystem(double scale = 1.0);
|
||||
};
|
||||
|
||||
viz::WCoordinateSystem::WCoordinateSystem
|
||||
---------------------------------------------------
|
||||
Constructs a WCoordinateSystem.
|
||||
|
||||
.. ocv:function:: WCoordinateSystem(float scale = 1.0)
|
||||
.. ocv:function:: WCoordinateSystem(double scale = 1.0)
|
||||
|
||||
:param scale: Determines the size of the axes.
|
||||
|
||||
@ -437,9 +508,6 @@ This 3D Widget defines a poly line. ::
|
||||
{
|
||||
public:
|
||||
WPolyLine(InputArray points, const Color &color = Color::white());
|
||||
|
||||
private:
|
||||
/* hidden */
|
||||
};
|
||||
|
||||
viz::WPolyLine::WPolyLine
|
||||
@ -460,30 +528,32 @@ This 3D Widget defines a grid. ::
|
||||
class CV_EXPORTS WGrid : public Widget3D
|
||||
{
|
||||
public:
|
||||
//! Creates grid at the origin
|
||||
WGrid(const Vec2i &dimensions, const Vec2d &spacing, const Color &color = Color::white());
|
||||
//! Creates grid based on the plane equation
|
||||
WGrid(const Vec4f &coeffs, const Vec2i &dimensions, const Vec2d &spacing, const Color &color = Color::white());
|
||||
private:
|
||||
/* hidden */
|
||||
//! 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());
|
||||
};
|
||||
|
||||
viz::WGrid::WGrid
|
||||
---------------------------
|
||||
Constructs a WGrid.
|
||||
|
||||
.. ocv:function:: WGrid(const Vec2i &dimensions, const Vec2d &spacing, const Color &color = Color::white())
|
||||
.. ocv:function:: WGrid(const Vec2i &cells = Vec2i::all(10), const Vec2d &cells_spacing = Vec2d::all(1.0), const Color &color = Color::white())
|
||||
|
||||
:param dimensions: Number of columns and rows, respectively.
|
||||
:param spacing: Size of each column and row, respectively.
|
||||
:param cells: Number of cell columns and rows, respectively.
|
||||
:param cells_spacing: Size of each cell, respectively.
|
||||
:param color: :ocv:class:`Color` of the grid.
|
||||
|
||||
.. ocv:function: WGrid(const Vec4f &coeffs, const Vec2i &dimensions, const Vec2d &spacing, const Color &color = Color::white())
|
||||
.. ocv:function: WGrid(const Point3d& center, const Vec3d& normal, const Vec3d& new_yaxis, Vec2i &cells, const Vec2d &cells_spacing, const Color &color;
|
||||
|
||||
:param coeffs: Plane coefficients as in (A,B,C,D) where Ax + By + Cz + D = 0.
|
||||
:param dimensions: Number of columns and rows, respectively.
|
||||
:param spacing: Size of each column and row, respectively.
|
||||
:param color: :ocv:class:`Color` of the grid.
|
||||
:param center: Center of the grid
|
||||
:param normal: Grid normal orientation
|
||||
:param new_yaxis: Up-vector. New orientation of grid y-axis.
|
||||
:param cells: Number of cell columns and rows, respectively.
|
||||
:param cells_spacing: Size of each cell, respectively.
|
||||
:param color: :ocv:class:`Color` of the grid..
|
||||
|
||||
viz::WText3D
|
||||
------------
|
||||
@ -494,7 +564,7 @@ This 3D Widget represents 3D text. The text always faces the camera. ::
|
||||
class CV_EXPORTS WText3D : public Widget3D
|
||||
{
|
||||
public:
|
||||
WText3D(const String &text, const Point3f &position, float text_scale = 1.0, bool face_camera = true, const Color &color = Color::white());
|
||||
WText3D(const String &text, const Point3f &position, double text_scale = 1.0, bool face_camera = true, const Color &color = Color::white());
|
||||
|
||||
void setText(const String &text);
|
||||
String getText() const;
|
||||
@ -504,7 +574,7 @@ viz::WText3D::WText3D
|
||||
-------------------------------
|
||||
Constructs a WText3D.
|
||||
|
||||
.. ocv:function:: WText3D(const String &text, const Point3f &position, float text_scale = 1.0, bool face_camera = true, const Color &color = Color::white())
|
||||
.. ocv:function:: WText3D(const String &text, const Point3f &position, double text_scale = 1.0, bool face_camera = true, const Color &color = Color::white())
|
||||
|
||||
:param text: Text content of the widget.
|
||||
:param position: Position of the text.
|
||||
@ -575,16 +645,16 @@ This 2D Widget represents an image overlay. ::
|
||||
class CV_EXPORTS WImageOverlay : public Widget2D
|
||||
{
|
||||
public:
|
||||
WImageOverlay(const Mat &image, const Rect &rect);
|
||||
WImageOverlay(InputArray image, const Rect &rect);
|
||||
|
||||
void setImage(const Mat &image);
|
||||
void setImage(InputArray image);
|
||||
};
|
||||
|
||||
viz::WImageOverlay::WImageOverlay
|
||||
---------------------------------
|
||||
Constructs an WImageOverlay.
|
||||
|
||||
.. ocv:function:: WImageOverlay(const Mat &image, const Rect &rect)
|
||||
.. ocv:function:: WImageOverlay(InputArray image, const Rect &rect)
|
||||
|
||||
:param image: BGR or Gray-Scale image.
|
||||
:param rect: Image is scaled and positioned based on rect.
|
||||
@ -593,7 +663,7 @@ viz::WImageOverlay::setImage
|
||||
----------------------------
|
||||
Sets the image content of the widget.
|
||||
|
||||
.. ocv:function:: void setImage(const Mat &image)
|
||||
.. ocv:function:: void setImage(InputArray image)
|
||||
|
||||
:param image: BGR or Gray-Scale image.
|
||||
|
||||
@ -607,23 +677,23 @@ This 3D Widget represents an image in 3D space. ::
|
||||
{
|
||||
public:
|
||||
//! Creates 3D image at the origin
|
||||
WImage3D(const Mat &image, const Size &size);
|
||||
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(const Vec3f &position, const Vec3f &normal, const Vec3f &up_vector, const Mat &image, const Size &size);
|
||||
WImage3D(InputArray image, const Size2d &size, const Vec3d &position, const Vec3d &normal, const Vec3d &up_vector);
|
||||
|
||||
void setImage(const Mat &image);
|
||||
void setImage(InputArray image);
|
||||
};
|
||||
|
||||
viz::WImage3D::WImage3D
|
||||
-----------------------
|
||||
Constructs an WImage3D.
|
||||
|
||||
.. ocv:function:: WImage3D(const Mat &image, const Size &size)
|
||||
.. ocv:function:: WImage3D(InputArray image, const Size2d &size)
|
||||
|
||||
:param image: BGR or Gray-Scale image.
|
||||
:param size: Size of the image.
|
||||
|
||||
.. ocv:function:: WImage3D(const Vec3f &position, const Vec3f &normal, const Vec3f &up_vector, const Mat &image, const Size &size)
|
||||
.. ocv:function:: WImage3D(InputArray image, const Size2d &size, const Vec3d &position, const Vec3d &normal, const Vec3d &up_vector)
|
||||
|
||||
:param position: Position of the image.
|
||||
:param normal: Normal of the plane that represents the image.
|
||||
@ -635,7 +705,7 @@ viz::WImage3D::setImage
|
||||
-----------------------
|
||||
Sets the image content of the widget.
|
||||
|
||||
.. ocv:function:: void setImage(const Mat &image)
|
||||
.. ocv:function:: void setImage(InputArray image)
|
||||
|
||||
:param image: BGR or Gray-Scale image.
|
||||
|
||||
@ -649,15 +719,15 @@ This 3D Widget represents camera position in a scene by its axes or viewing frus
|
||||
{
|
||||
public:
|
||||
//! Creates camera coordinate frame (axes) at the origin
|
||||
WCameraPosition(float scale = 1.0);
|
||||
WCameraPosition(double scale = 1.0);
|
||||
//! Creates frustum based on the intrinsic marix K at the origin
|
||||
WCameraPosition(const Matx33f &K, float scale = 1.0, const Color &color = Color::white());
|
||||
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 Vec2f &fov, float scale = 1.0, const Color &color = Color::white());
|
||||
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 Matx33f &K, const Mat &img, float scale = 1.0, const Color &color = Color::white());
|
||||
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 Vec2f &fov, const Mat &img, float scale = 1.0, const Color &color = Color::white());
|
||||
WCameraPosition(const Vec2d &fov, InputArray image, double scale = 1.0, const Color &color = Color::white());
|
||||
};
|
||||
|
||||
viz::WCameraPosition::WCameraPosition
|
||||
@ -666,7 +736,7 @@ Constructs a WCameraPosition.
|
||||
|
||||
- **Display camera coordinate frame.**
|
||||
|
||||
.. ocv:function:: WCameraPosition(float scale = 1.0)
|
||||
.. ocv:function:: WCameraPosition(double scale = 1.0)
|
||||
|
||||
Creates camera coordinate frame at the origin.
|
||||
|
||||
@ -676,7 +746,7 @@ Constructs a WCameraPosition.
|
||||
|
||||
- **Display the viewing frustum.**
|
||||
|
||||
.. ocv:function:: WCameraPosition(const Matx33f &K, float scale = 1.0, const Color &color = Color::white())
|
||||
.. ocv:function:: WCameraPosition(const Matx33d &K, double scale = 1.0, const Color &color = Color::white())
|
||||
|
||||
:param K: Intrinsic matrix of the camera.
|
||||
:param scale: Scale of the frustum.
|
||||
@ -684,7 +754,7 @@ Constructs a WCameraPosition.
|
||||
|
||||
Creates viewing frustum of the camera based on its intrinsic matrix K.
|
||||
|
||||
.. ocv:function:: WCameraPosition(const Vec2f &fov, float scale = 1.0, const Color &color = Color::white())
|
||||
.. ocv:function:: WCameraPosition(const Vec2d &fov, double scale = 1.0, const Color &color = Color::white())
|
||||
|
||||
:param fov: Field of view of the camera (horizontal, vertical).
|
||||
:param scale: Scale of the frustum.
|
||||
@ -698,7 +768,7 @@ Constructs a WCameraPosition.
|
||||
|
||||
- **Display image on the far plane of the viewing frustum.**
|
||||
|
||||
.. ocv:function:: WCameraPosition(const Matx33f &K, const Mat &img, float scale = 1.0, const Color &color = Color::white())
|
||||
.. ocv:function:: WCameraPosition(const Matx33d &K, InputArray image, double scale = 1.0, const Color &color = Color::white())
|
||||
|
||||
:param K: Intrinsic matrix of the camera.
|
||||
:param img: BGR or Gray-Scale image that is going to be displayed on the far plane of the frustum.
|
||||
@ -707,7 +777,7 @@ Constructs a WCameraPosition.
|
||||
|
||||
Creates viewing frustum of the camera based on its intrinsic matrix K, and displays image on the far end plane.
|
||||
|
||||
.. ocv:function:: WCameraPosition(const Vec2f &fov, const Mat &img, float scale = 1.0, const Color &color = Color::white())
|
||||
.. ocv:function:: WCameraPosition(const Vec2d &fov, InputArray image, double scale = 1.0, const Color &color = Color::white())
|
||||
|
||||
:param fov: Field of view of the camera (horizontal, vertical).
|
||||
:param img: BGR or Gray-Scale image that is going to be displayed on the far plane of the frustum.
|
||||
@ -729,81 +799,91 @@ This 3D Widget represents a trajectory. ::
|
||||
class CV_EXPORTS WTrajectory : public Widget3D
|
||||
{
|
||||
public:
|
||||
enum {DISPLAY_FRAMES = 1, DISPLAY_PATH = 2};
|
||||
enum {FRAMES = 1, PATH = 2, BOTH = FRAMES + PATH};
|
||||
|
||||
//! Displays trajectory of the given path either by coordinate frames or polyline
|
||||
WTrajectory(const std::vector<Affine3f> &path, int display_mode = WTrajectory::DISPLAY_PATH, const Color &color = Color::white(), float scale = 1.0);
|
||||
//! Displays trajectory of the given path by frustums
|
||||
WTrajectory(const std::vector<Affine3f> &path, const Matx33f &K, float scale = 1.0, const Color &color = Color::white());
|
||||
//! Displays trajectory of the given path by frustums
|
||||
WTrajectory(const std::vector<Affine3f> &path, const Vec2f &fov, float scale = 1.0, const Color &color = Color::white());
|
||||
|
||||
private:
|
||||
/* hidden */
|
||||
WTrajectory(InputArray path, int display_mode = WTrajectory::PATH, double scale = 1.0, const Color &color = Color::white(),;
|
||||
};
|
||||
|
||||
viz::WTrajectory::WTrajectory
|
||||
-----------------------------
|
||||
Constructs a WTrajectory.
|
||||
|
||||
.. ocv:function:: WTrajectory(const std::vector<Affine3f> &path, int display_mode = WTrajectory::DISPLAY_PATH, const Color &color = Color::white(), float scale = 1.0)
|
||||
.. ocv:function:: WTrajectory(InputArray path, int display_mode = WTrajectory::PATH, double scale = 1.0, const Color &color = Color::white())
|
||||
|
||||
:param path: List of poses on a trajectory.
|
||||
:param display_mode: Display mode. This can be DISPLAY_PATH, DISPLAY_FRAMES, DISPLAY_PATH & DISPLAY_FRAMES.
|
||||
:param color: :ocv:class:`Color` of the polyline that represents path. Frames are not affected.
|
||||
:param path: List of poses on a trajectory. Takes std::vector<Affine<T>> with T == [float | double]
|
||||
:param display_mode: Display mode. This can be PATH, FRAMES, and BOTH.
|
||||
:param scale: Scale of the frames. Polyline is not affected.
|
||||
:param color: :ocv:class:`Color` of the polyline that represents path. Frames are not affected.
|
||||
|
||||
Displays trajectory of the given path as follows:
|
||||
|
||||
* DISPLAY_PATH : Displays a poly line that represents the path.
|
||||
* DISPLAY_FRAMES : Displays coordinate frames at each pose.
|
||||
* DISPLAY_PATH & DISPLAY_FRAMES : Displays both poly line and coordinate frames.
|
||||
* PATH : Displays a poly line that represents the path.
|
||||
* FRAMES : Displays coordinate frames at each pose.
|
||||
* PATH & FRAMES : Displays both poly line and coordinate frames.
|
||||
|
||||
.. ocv:function:: WTrajectory(const std::vector<Affine3f> &path, const Matx33f &K, float scale = 1.0, const Color &color = Color::white())
|
||||
viz::WTrajectoryFrustums
|
||||
------------------------
|
||||
.. ocv:class:: WTrajectoryFrustums
|
||||
|
||||
:param path: List of poses on a trajectory.
|
||||
This 3D Widget represents a trajectory. ::
|
||||
|
||||
class CV_EXPORTS WTrajectoryFrustums : public Widget3D
|
||||
{
|
||||
public:
|
||||
//! Displays trajectory of the given path by frustums
|
||||
WTrajectoryFrustums(InputArray path, const Matx33d &K, double scale = 1.0, const Color &color = Color::white());
|
||||
//! Displays trajectory of the given path by frustums
|
||||
WTrajectoryFrustums(InputArray path, const Vec2d &fov, double scale = 1.0, const Color &color = Color::white());
|
||||
};
|
||||
|
||||
viz::WTrajectoryFrustums::WTrajectoryFrustums
|
||||
---------------------------------------------
|
||||
Constructs a WTrajectoryFrustums.
|
||||
|
||||
.. ocv:function:: WTrajectoryFrustums(const std::vector<Affine3d> &path, const Matx33d &K, double scale = 1.0, const Color &color = Color::white())
|
||||
|
||||
:param path: List of poses on a trajectory. Takes std::vector<Affine<T>> with T == [float | double]
|
||||
:param K: Intrinsic matrix of the camera.
|
||||
:param scale: Scale of the frustums.
|
||||
:param color: :ocv:class:`Color` of the frustums.
|
||||
|
||||
Displays frustums at each pose of the trajectory.
|
||||
|
||||
.. ocv:function:: WTrajectory(const std::vector<Affine3f> &path, const Vec2f &fov, float scale = 1.0, const Color &color = Color::white())
|
||||
.. ocv:function:: WTrajectoryFrustums(const std::vector<Affine3d> &path, const Vec2d &fov, double scale = 1.0, const Color &color = Color::white())
|
||||
|
||||
:param path: List of poses on a trajectory.
|
||||
:param path: List of poses on a trajectory. Takes std::vector<Affine<T>> with T == [float | double]
|
||||
:param fov: Field of view of the camera (horizontal, vertical).
|
||||
:param scale: Scale of the frustums.
|
||||
:param color: :ocv:class:`Color` of the frustums.
|
||||
|
||||
Displays frustums at each pose of the trajectory.
|
||||
|
||||
viz::WSpheresTrajectory
|
||||
viz::WTrajectorySpheres
|
||||
-----------------------
|
||||
.. ocv:class:: WSpheresTrajectory
|
||||
.. ocv:class:: WTrajectorySpheres
|
||||
|
||||
This 3D Widget represents a trajectory using spheres and lines, where spheres represent the positions of the camera, and lines
|
||||
represent the direction from previous position to the current. ::
|
||||
|
||||
class CV_EXPORTS WSpheresTrajectory : public Widget3D
|
||||
class CV_EXPORTS WTrajectorySpheres : public Widget3D
|
||||
{
|
||||
public:
|
||||
WSpheresTrajectory(const std::vector<Affine3f> &path, float line_length = 0.05f,
|
||||
float init_sphere_radius = 0.021, sphere_radius = 0.007,
|
||||
Color &line_color = Color::white(), const Color &sphere_color = Color::white());
|
||||
WTrajectorySpheres(InputArray path, double line_length = 0.05, double radius = 0.007,
|
||||
const Color &from = Color::red(), const Color &to = Color::white());
|
||||
};
|
||||
|
||||
viz::WSpheresTrajectory::WSpheresTrajectory
|
||||
viz::WTrajectorySpheres::WTrajectorySpheres
|
||||
-------------------------------------------
|
||||
Constructs a WSpheresTrajectory.
|
||||
Constructs a WTrajectorySpheres.
|
||||
|
||||
.. ocv:function:: WSpheresTrajectory(const std::vector<Affine3f> &path, float line_length = 0.05f, float init_sphere_radius = 0.021, float sphere_radius = 0.007, const Color &line_color = Color::white(), const Color &sphere_color = Color::white())
|
||||
.. ocv:function:: WTrajectorySpheres(InputArray path, double line_length = 0.05, double radius = 0.007, const Color &from = Color::red(), const Color &to = Color::white())
|
||||
|
||||
:param path: List of poses on a trajectory.
|
||||
:param line_length: Length of the lines.
|
||||
:param init_sphere_radius: Radius of the first sphere which represents the initial position of the camera.
|
||||
:param sphere_radius: Radius of the rest of the spheres.
|
||||
:param line_color: :ocv:class:`Color` of the lines.
|
||||
:param sphere_color: :ocv:class:`Color` of the spheres.
|
||||
:param path: List of poses on a trajectory. Takes std::vector<Affine<T>> with T == [float | double]
|
||||
:param line_length: Max length of the lines which point to previous position
|
||||
:param sphere_radius: Radius of the spheres.
|
||||
:param from: :ocv:class:`Color` for first sphere.
|
||||
:param to: :ocv:class:`Color` for last sphere. Intermediate spheres will have interpolated color.
|
||||
|
||||
viz::WCloud
|
||||
-----------
|
||||
@ -818,9 +898,6 @@ This 3D Widget defines a point cloud. ::
|
||||
WCloud(InputArray cloud, InputArray colors);
|
||||
//! All points in cloud have the same color
|
||||
WCloud(InputArray cloud, const Color &color = Color::white());
|
||||
|
||||
private:
|
||||
/* hidden */
|
||||
};
|
||||
|
||||
viz::WCloud::WCloud
|
||||
@ -855,12 +932,9 @@ This 3D Widget defines a collection of clouds. ::
|
||||
WCloudCollection();
|
||||
|
||||
//! Each point in cloud is mapped to a color in colors
|
||||
void addCloud(InputArray cloud, InputArray colors, const Affine3f &pose = Affine3f::Identity());
|
||||
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(), Affine3f &pose = Affine3f::Identity());
|
||||
|
||||
private:
|
||||
/* hidden */
|
||||
void addCloud(InputArray cloud, const Color &color = Color::white(), Affine3d &pose = Affine3d::Identity());
|
||||
};
|
||||
|
||||
viz::WCloudCollection::WCloudCollection
|
||||
@ -873,7 +947,7 @@ viz::WCloudCollection::addCloud
|
||||
-------------------------------
|
||||
Adds a cloud to the collection.
|
||||
|
||||
.. ocv:function:: void addCloud(InputArray cloud, InputArray colors, const Affine3f &pose = Affine3f::Identity())
|
||||
.. ocv:function:: void addCloud(InputArray cloud, InputArray colors, const Affine3d &pose = Affine3d::Identity())
|
||||
|
||||
:param cloud: Point set which can be of type: ``CV_32FC3``, ``CV_32FC4``, ``CV_64FC3``, ``CV_64FC4``.
|
||||
:param colors: Set of colors. It has to be of the same size with cloud.
|
||||
@ -881,7 +955,7 @@ Adds a cloud to the collection.
|
||||
|
||||
Points in the cloud belong to mask when they are set to (NaN, NaN, NaN).
|
||||
|
||||
.. ocv:function:: void addCloud(InputArray cloud, const Color &color = Color::white(), const Affine3f &pose = Affine3f::Identity())
|
||||
.. ocv:function:: void addCloud(InputArray cloud, const Color &color = Color::white(), const Affine3d &pose = Affine3d::Identity())
|
||||
|
||||
:param cloud: Point set which can be of type: ``CV_32FC3``, ``CV_32FC4``, ``CV_64FC3``, ``CV_64FC4``.
|
||||
:param colors: A single :ocv:class:`Color` for the whole cloud.
|
||||
@ -900,17 +974,14 @@ This 3D Widget represents normals of a point cloud. ::
|
||||
class CV_EXPORTS WCloudNormals : public Widget3D
|
||||
{
|
||||
public:
|
||||
WCloudNormals(InputArray cloud, InputArray normals, int level = 100, float scale = 0.02f, const Color &color = Color::white());
|
||||
|
||||
private:
|
||||
/* hidden */
|
||||
WCloudNormals(InputArray cloud, InputArray normals, int level = 100, double scale = 0.02f, const Color &color = Color::white());
|
||||
};
|
||||
|
||||
viz::WCloudNormals::WCloudNormals
|
||||
---------------------------------
|
||||
Constructs a WCloudNormals.
|
||||
|
||||
.. ocv:function:: WCloudNormals(InputArray cloud, InputArray normals, int level = 100, float scale = 0.02f, const Color &color = Color::white())
|
||||
.. ocv:function:: WCloudNormals(InputArray cloud, InputArray normals, int level = 100, double scale = 0.02f, const Color &color = Color::white())
|
||||
|
||||
:param cloud: Point set which can be of type: ``CV_32FC3``, ``CV_32FC4``, ``CV_64FC3``, ``CV_64FC4``.
|
||||
:param normals: A set of normals that has to be of same type with cloud.
|
||||
@ -929,16 +1000,21 @@ This 3D Widget defines a mesh. ::
|
||||
class CV_EXPORTS WMesh : public Widget3D
|
||||
{
|
||||
public:
|
||||
WMesh(const Mesh3d &mesh);
|
||||
|
||||
private:
|
||||
/* hidden */
|
||||
WMesh(const Mesh &mesh);
|
||||
WMesh(InputArray cloud, InputArray polygons, InputArray colors = noArray(), InputArray normals = noArray());
|
||||
};
|
||||
|
||||
viz::WMesh::WMesh
|
||||
-----------------
|
||||
Constructs a WMesh.
|
||||
|
||||
.. ocv:function:: WMesh(const Mesh3d &mesh)
|
||||
.. ocv:function:: WMesh(const Mesh &mesh)
|
||||
|
||||
:param mesh: :ocv:class:`Mesh3d` object that will be displayed.
|
||||
:param mesh: :ocv:class:`Mesh` object that will be displayed.
|
||||
|
||||
.. ocv:function:: WMesh(InputArray cloud, InputArray polygons, InputArray colors = noArray(), InputArray normals = noArray())
|
||||
|
||||
:param cloud: Points of the mesh object.
|
||||
:param polygons: Points of the mesh object.
|
||||
:param colors: Point colors.
|
||||
:param normals: Point normals.
|
||||
|
@ -41,9 +41,6 @@
|
||||
// * Ozan Tonkal, ozantonkal@gmail.com
|
||||
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
|
||||
//
|
||||
// OpenCV Viz module is complete rewrite of
|
||||
// PCL visualization module (www.pointclouds.org)
|
||||
//
|
||||
//M*/
|
||||
|
||||
#ifndef __OPENCV_VIZ_HPP__
|
||||
@ -58,17 +55,20 @@ namespace cv
|
||||
namespace viz
|
||||
{
|
||||
//! takes coordiante frame data and builds transfrom to global coordinate frame
|
||||
CV_EXPORTS Affine3f makeTransformToGlobal(const Vec3f& axis_x, const Vec3f& axis_y, const Vec3f& axis_z, const Vec3f& origin = Vec3f::all(0));
|
||||
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 Affine3f makeCameraPose(const Vec3f& position, const Vec3f& focal_point, const Vec3f& y_dir);
|
||||
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 get(const String &window_name);
|
||||
CV_EXPORTS Viz3d getWindowByName(const String &window_name);
|
||||
|
||||
//! Unregisters all Viz windows from internal database. After it 'get()' will create new windows instead getting existing from the database.
|
||||
//! 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)
|
||||
{
|
||||
@ -91,6 +91,36 @@ namespace cv
|
||||
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 */
|
||||
|
||||
|
@ -41,9 +41,6 @@
|
||||
// * Ozan Tonkal, ozantonkal@gmail.com
|
||||
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
|
||||
//
|
||||
// OpenCV Viz module is complete rewrite of
|
||||
// PCL visualization module (www.pointclouds.org)
|
||||
//
|
||||
//M*/
|
||||
|
||||
#ifndef __OPENCV_VIZ_TYPES_HPP__
|
||||
@ -77,49 +74,99 @@ namespace cv
|
||||
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 Mesh3d
|
||||
class CV_EXPORTS Mesh
|
||||
{
|
||||
public:
|
||||
Mat cloud, colors, normals;
|
||||
|
||||
Mat cloud, colors;
|
||||
//! 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 cv::viz::Mesh3d loadMesh(const String& file);
|
||||
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:
|
||||
struct loadMeshImpl;
|
||||
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:
|
||||
static const unsigned int Alt = 1;
|
||||
static const unsigned int Ctrl = 2;
|
||||
static const unsigned int Shift = 4;
|
||||
enum { NONE = 0, ALT = 1, CTRL = 2, SHIFT = 4 };
|
||||
enum Action { KEY_UP = 0, KEY_DOWN = 1 };
|
||||
|
||||
//! Create a keyboard event
|
||||
//! - Note that action is true if key is pressed, false if released
|
||||
KeyboardEvent(bool action, const String& key_sym, unsigned char key, bool alt, bool ctrl, bool shift);
|
||||
KeyboardEvent(Action action, const String& symbol, unsigned char code, int modifiers);
|
||||
|
||||
bool isAltPressed() const;
|
||||
bool isCtrlPressed() const;
|
||||
bool isShiftPressed() const;
|
||||
|
||||
unsigned char getKeyCode() const;
|
||||
|
||||
const String& getKeySym() const;
|
||||
bool keyDown() const;
|
||||
bool keyUp() const;
|
||||
|
||||
protected:
|
||||
|
||||
bool action_;
|
||||
unsigned int modifiers_;
|
||||
unsigned char key_code_;
|
||||
String key_sym_;
|
||||
Action action;
|
||||
String symbol;
|
||||
unsigned char code;
|
||||
int modifiers;
|
||||
};
|
||||
|
||||
class CV_EXPORTS MouseEvent
|
||||
@ -128,46 +175,12 @@ namespace cv
|
||||
enum Type { MouseMove = 1, MouseButtonPress, MouseButtonRelease, MouseScrollDown, MouseScrollUp, MouseDblClick } ;
|
||||
enum MouseButton { NoButton = 0, LeftButton, MiddleButton, RightButton, VScroll } ;
|
||||
|
||||
MouseEvent(const Type& type, const MouseButton& button, const Point& p, bool alt, bool ctrl, bool shift);
|
||||
MouseEvent(const Type& type, const MouseButton& button, const Point& pointer, int modifiers);
|
||||
|
||||
Type type;
|
||||
MouseButton button;
|
||||
Point pointer;
|
||||
unsigned int key_state;
|
||||
};
|
||||
|
||||
class CV_EXPORTS Camera
|
||||
{
|
||||
public:
|
||||
Camera(float f_x, float f_y, float c_x, float c_y, const Size &window_size);
|
||||
Camera(const Vec2f &fov, const Size &window_size);
|
||||
Camera(const cv::Matx33f &K, const Size &window_size);
|
||||
Camera(const cv::Matx44f &proj, const Size &window_size);
|
||||
|
||||
inline const Vec2d & getClip() const { return clip_; }
|
||||
inline void setClip(const Vec2d &clip) { clip_ = clip; }
|
||||
|
||||
inline const Size & getWindowSize() const { return window_size_; }
|
||||
void setWindowSize(const Size &window_size);
|
||||
|
||||
inline const Vec2f & getFov() const { return fov_; }
|
||||
inline void setFov(const Vec2f & fov) { fov_ = fov; }
|
||||
|
||||
inline const Vec2f & getPrincipalPoint() const { return principal_point_; }
|
||||
inline const Vec2f & getFocalLength() const { return focal_; }
|
||||
|
||||
void computeProjectionMatrix(Matx44f &proj) const;
|
||||
|
||||
static Camera KinectCamera(const Size &window_size);
|
||||
|
||||
private:
|
||||
void init(float f_x, float f_y, float c_x, float c_y, const Size &window_size);
|
||||
|
||||
Vec2d clip_;
|
||||
Vec2f fov_;
|
||||
Size window_size_;
|
||||
Vec2f principal_point_;
|
||||
Vec2f focal_;
|
||||
int modifiers;
|
||||
};
|
||||
} /* namespace viz */
|
||||
} /* namespace cv */
|
||||
@ -180,15 +193,44 @@ 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::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
|
||||
|
@ -41,9 +41,6 @@
|
||||
// * Ozan Tonkal, ozantonkal@gmail.com
|
||||
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
|
||||
//
|
||||
// OpenCV Viz module is complete rewrite of
|
||||
// PCL visualization module (www.pointclouds.org)
|
||||
//
|
||||
//M*/
|
||||
|
||||
#ifndef __OPENCV_VIZ_VIZ3D_HPP__
|
||||
@ -64,6 +61,7 @@ namespace cv
|
||||
class CV_EXPORTS Viz3d
|
||||
{
|
||||
public:
|
||||
typedef cv::viz::Color Color;
|
||||
typedef void (*KeyboardCallback)(const KeyboardEvent&, void*);
|
||||
typedef void (*MouseCallback)(const MouseEvent&, void*);
|
||||
|
||||
@ -72,19 +70,21 @@ namespace cv
|
||||
Viz3d& operator=(const Viz3d&);
|
||||
~Viz3d();
|
||||
|
||||
void showWidget(const String &id, const Widget &widget, const Affine3f &pose = Affine3f::Identity());
|
||||
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 Affine3f &pose);
|
||||
void updateWidgetPose(const String &id, const Affine3f &pose);
|
||||
Affine3f getWidgetPose(const String &id) const;
|
||||
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;
|
||||
Affine3f getViewerPose();
|
||||
void setViewerPose(const Affine3f &pose);
|
||||
Affine3d getViewerPose();
|
||||
void setViewerPose(const Affine3d &pose);
|
||||
|
||||
void resetCameraViewpoint(const String &id);
|
||||
void resetCamera();
|
||||
@ -96,13 +96,16 @@ namespace cv
|
||||
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 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);
|
||||
@ -110,9 +113,6 @@ namespace cv
|
||||
void setRenderingProperty(const String &id, int property, double value);
|
||||
double getRenderingProperty(const String &id, int property);
|
||||
|
||||
void setDesiredUpdateRate(double rate);
|
||||
double getDesiredUpdateRate();
|
||||
|
||||
void setRepresentation(int representation);
|
||||
private:
|
||||
|
||||
|
@ -41,9 +41,6 @@
|
||||
// * Ozan Tonkal, ozantonkal@gmail.com
|
||||
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
|
||||
//
|
||||
// OpenCV Viz module is complete rewrite of
|
||||
// PCL visualization module (www.pointclouds.org)
|
||||
//
|
||||
//M*/
|
||||
|
||||
#ifndef __OPENCV_VIZ_WIDGET_ACCESSOR_HPP__
|
||||
@ -69,4 +66,4 @@ namespace cv
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@ -41,9 +41,6 @@
|
||||
// * Ozan Tonkal, ozantonkal@gmail.com
|
||||
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
|
||||
//
|
||||
// OpenCV Viz module is complete rewrite of
|
||||
// PCL visualization module (www.pointclouds.org)
|
||||
//
|
||||
//M*/
|
||||
|
||||
#ifndef __OPENCV_VIZ_WIDGETS_HPP__
|
||||
@ -68,14 +65,14 @@ namespace cv
|
||||
SHADING
|
||||
};
|
||||
|
||||
enum RenderingRepresentationProperties
|
||||
enum RepresentationValues
|
||||
{
|
||||
REPRESENTATION_POINTS,
|
||||
REPRESENTATION_WIREFRAME,
|
||||
REPRESENTATION_SURFACE
|
||||
};
|
||||
|
||||
enum ShadingRepresentationProperties
|
||||
enum ShadingValues
|
||||
{
|
||||
SHADING_FLAT,
|
||||
SHADING_GOURAUD,
|
||||
@ -114,13 +111,15 @@ namespace cv
|
||||
public:
|
||||
Widget3D() {}
|
||||
|
||||
void setPose(const Affine3f &pose);
|
||||
void updatePose(const Affine3f &pose);
|
||||
Affine3f getPose() const;
|
||||
//! 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);
|
||||
private:
|
||||
struct MatrixConverter;
|
||||
|
||||
};
|
||||
|
||||
@ -134,92 +133,94 @@ namespace cv
|
||||
void setColor(const Color &color);
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
/// Simple widgets
|
||||
|
||||
class CV_EXPORTS WLine : public Widget3D
|
||||
{
|
||||
public:
|
||||
WLine(const Point3f &pt1, const Point3f &pt2, const Color &color = Color::white());
|
||||
WLine(const Point3d &pt1, const Point3d &pt2, const Color &color = Color::white());
|
||||
};
|
||||
|
||||
class CV_EXPORTS WPlane : public Widget3D
|
||||
{
|
||||
public:
|
||||
WPlane(const Vec4f& coefs, float size = 1.f, const Color &color = Color::white());
|
||||
WPlane(const Vec4f& coefs, const Point3f& pt, float size = 1.f, const Color &color = Color::white());
|
||||
private:
|
||||
struct SetSizeImpl;
|
||||
//! 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::Point3f ¢er, float radius, int sphere_resolution = 10, const Color &color = Color::white());
|
||||
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 Point3f& pt1, const Point3f& pt2, float thickness = 0.03f, const Color &color = Color::white());
|
||||
WArrow(const Point3d& pt1, const Point3d& pt2, double thickness = 0.03, const Color &color = Color::white());
|
||||
};
|
||||
|
||||
class CV_EXPORTS WCircle : public Widget3D
|
||||
{
|
||||
public:
|
||||
WCircle(const Point3f& pt, float radius, float thickness = 0.01f, const Color &color = Color::white());
|
||||
//! 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 Point3f& pt_on_axis, const Point3f& axis_direction, float radius, int numsides = 30, const Color &color = Color::white());
|
||||
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 Point3f& pt_min, const Point3f& pt_max, bool wire_frame = true, const Color &color = Color::white());
|
||||
};
|
||||
|
||||
class CV_EXPORTS WCoordinateSystem : public Widget3D
|
||||
{
|
||||
public:
|
||||
WCoordinateSystem(float scale = 1.f);
|
||||
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());
|
||||
|
||||
private:
|
||||
struct CopyImpl;
|
||||
};
|
||||
|
||||
class CV_EXPORTS WGrid : public Widget3D
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
/// Text and image widgets
|
||||
|
||||
class CV_EXPORTS WText : public Widget2D
|
||||
{
|
||||
public:
|
||||
//! Creates grid at the origin
|
||||
WGrid(const Vec2i &dimensions, const Vec2d &spacing, const Color &color = Color::white());
|
||||
//! Creates grid based on the plane equation
|
||||
WGrid(const Vec4f &coeffs, const Vec2i &dimensions, const Vec2d &spacing, const Color &color = Color::white());
|
||||
|
||||
private:
|
||||
struct GridImpl;
|
||||
|
||||
};
|
||||
|
||||
class CV_EXPORTS WText3D : public Widget3D
|
||||
{
|
||||
public:
|
||||
WText3D(const String &text, const Point3f &position, float text_scale = 1.f, bool face_camera = true, const Color &color = Color::white());
|
||||
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 WText : public Widget2D
|
||||
class CV_EXPORTS WText3D : public Widget3D
|
||||
{
|
||||
public:
|
||||
WText(const String &text, const Point2i &pos, int font_size = 10, const Color &color = Color::white());
|
||||
//! 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;
|
||||
@ -228,63 +229,91 @@ namespace cv
|
||||
class CV_EXPORTS WImageOverlay : public Widget2D
|
||||
{
|
||||
public:
|
||||
WImageOverlay(const Mat &image, const Rect &rect);
|
||||
|
||||
void setImage(const Mat &image);
|
||||
WImageOverlay(InputArray image, const Rect &rect);
|
||||
void setImage(InputArray image);
|
||||
};
|
||||
|
||||
class CV_EXPORTS WImage3D : public Widget3D
|
||||
{
|
||||
public:
|
||||
//! Creates 3D image at the origin
|
||||
WImage3D(const Mat &image, const Size &size);
|
||||
//! Creates 3D image at a given position, pointing in the direction of the normal, and having the up_vector orientation
|
||||
WImage3D(const Vec3f &position, const Vec3f &normal, const Vec3f &up_vector, const Mat &image, const Size &size);
|
||||
//! 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);
|
||||
|
||||
void setImage(const Mat &image);
|
||||
//! 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(float scale = 1.f);
|
||||
WCameraPosition(double scale = 1.0);
|
||||
//! Creates frustum based on the intrinsic marix K at the origin
|
||||
WCameraPosition(const Matx33f &K, float scale = 1.f, const Color &color = Color::white());
|
||||
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 Vec2f &fov, float scale = 1.f, const Color &color = Color::white());
|
||||
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 Matx33f &K, const Mat &img, float scale = 1.f, const Color &color = Color::white());
|
||||
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 Vec2f &fov, const Mat &img, float scale = 1.f, const Color &color = Color::white());
|
||||
|
||||
private:
|
||||
struct ProjectImage;
|
||||
WCameraPosition(const Vec2d &fov, InputArray image, double scale = 1.0, const Color &color = Color::white());
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
/// Trajectories
|
||||
|
||||
class CV_EXPORTS WTrajectory : public Widget3D
|
||||
{
|
||||
public:
|
||||
enum {DISPLAY_FRAMES = 1, DISPLAY_PATH = 2};
|
||||
enum {FRAMES = 1, PATH = 2, BOTH = FRAMES + PATH };
|
||||
|
||||
//! Displays trajectory of the given path either by coordinate frames or polyline
|
||||
WTrajectory(const std::vector<Affine3f> &path, int display_mode = WTrajectory::DISPLAY_PATH, const Color &color = Color::white(), float scale = 1.f);
|
||||
//! Displays trajectory of the given path by frustums
|
||||
WTrajectory(const std::vector<Affine3f> &path, const Matx33f &K, float scale = 1.f, const Color &color = Color::white());
|
||||
//! Displays trajectory of the given path by frustums
|
||||
WTrajectory(const std::vector<Affine3f> &path, const Vec2f &fov, float scale = 1.f, const Color &color = Color::white());
|
||||
|
||||
private:
|
||||
struct ApplyPath;
|
||||
//! 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 WSpheresTrajectory: public Widget3D
|
||||
class CV_EXPORTS WTrajectoryFrustums : public Widget3D
|
||||
{
|
||||
public:
|
||||
WSpheresTrajectory(const std::vector<Affine3f> &path, float line_length = 0.05f, float init_sphere_radius = 0.021f,
|
||||
float sphere_radius = 0.007f, const Color &line_color = Color::white(), const Color &sphere_color = Color::white());
|
||||
//! 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:
|
||||
@ -292,9 +321,19 @@ namespace cv
|
||||
WCloud(InputArray cloud, InputArray colors);
|
||||
//! All points in cloud have the same color
|
||||
WCloud(InputArray cloud, const Color &color = Color::white());
|
||||
};
|
||||
|
||||
private:
|
||||
struct CreateCloudWidget;
|
||||
class CV_EXPORTS 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
|
||||
@ -303,32 +342,27 @@ namespace cv
|
||||
WCloudCollection();
|
||||
|
||||
//! Each point in cloud is mapped to a color in colors
|
||||
void addCloud(InputArray cloud, InputArray colors, const Affine3f &pose = Affine3f::Identity());
|
||||
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 Affine3f &pose = Affine3f::Identity());
|
||||
|
||||
private:
|
||||
struct CreateCloudWidget;
|
||||
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 = 100, float scale = 0.02f, const Color &color = Color::white());
|
||||
|
||||
private:
|
||||
struct ApplyCloudNormals;
|
||||
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 Mesh3d &mesh);
|
||||
|
||||
private:
|
||||
struct CopyImpl;
|
||||
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>();
|
||||
@ -337,6 +371,7 @@ namespace cv
|
||||
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>();
|
||||
@ -347,8 +382,10 @@ namespace cv
|
||||
template<> CV_EXPORTS WImage3D Widget::cast<WImage3D>();
|
||||
template<> CV_EXPORTS WCameraPosition Widget::cast<WCameraPosition>();
|
||||
template<> CV_EXPORTS WTrajectory Widget::cast<WTrajectory>();
|
||||
template<> CV_EXPORTS WSpheresTrajectory Widget::cast<WSpheresTrajectory>();
|
||||
template<> CV_EXPORTS 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>();
|
||||
|
@ -1,773 +0,0 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
// Authors:
|
||||
// * Ozan Tonkal, ozantonkal@gmail.com
|
||||
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
|
||||
//
|
||||
// OpenCV Viz module is complete rewrite of
|
||||
// PCL visualization module (www.pointclouds.org)
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "precomp.hpp"
|
||||
|
||||
namespace cv
|
||||
{
|
||||
namespace viz
|
||||
{
|
||||
template<typename _Tp> Vec<_Tp, 3>* vtkpoints_data(vtkSmartPointer<vtkPoints>& points);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// Point Cloud Widget implementation
|
||||
|
||||
struct cv::viz::WCloud::CreateCloudWidget
|
||||
{
|
||||
static inline vtkSmartPointer<vtkPolyData> create(const Mat &cloud, vtkIdType &nr_points)
|
||||
{
|
||||
vtkSmartPointer<vtkPolyData> polydata = vtkSmartPointer<vtkPolyData>::New();
|
||||
vtkSmartPointer<vtkCellArray> vertices = vtkSmartPointer<vtkCellArray>::New();
|
||||
|
||||
polydata->SetVerts(vertices);
|
||||
|
||||
vtkSmartPointer<vtkPoints> points = polydata->GetPoints();
|
||||
vtkSmartPointer<vtkIdTypeArray> initcells;
|
||||
nr_points = cloud.total();
|
||||
|
||||
if (!points)
|
||||
{
|
||||
points = vtkSmartPointer<vtkPoints>::New();
|
||||
if (cloud.depth() == CV_32F)
|
||||
points->SetDataTypeToFloat();
|
||||
else if (cloud.depth() == CV_64F)
|
||||
points->SetDataTypeToDouble();
|
||||
polydata->SetPoints(points);
|
||||
}
|
||||
points->SetNumberOfPoints(nr_points);
|
||||
|
||||
if (cloud.depth() == CV_32F)
|
||||
{
|
||||
// Get a pointer to the beginning of the data array
|
||||
Vec3f *data_beg = vtkpoints_data<float>(points);
|
||||
Vec3f *data_end = NanFilter::copy(cloud, data_beg, cloud);
|
||||
nr_points = data_end - data_beg;
|
||||
}
|
||||
else if (cloud.depth() == CV_64F)
|
||||
{
|
||||
// Get a pointer to the beginning of the data array
|
||||
Vec3d *data_beg = vtkpoints_data<double>(points);
|
||||
Vec3d *data_end = NanFilter::copy(cloud, data_beg, cloud);
|
||||
nr_points = data_end - data_beg;
|
||||
}
|
||||
points->SetNumberOfPoints(nr_points);
|
||||
|
||||
// Update cells
|
||||
vtkSmartPointer<vtkIdTypeArray> cells = vertices->GetData();
|
||||
// If no init cells and cells has not been initialized...
|
||||
if (!cells)
|
||||
cells = vtkSmartPointer<vtkIdTypeArray>::New();
|
||||
|
||||
// If we have less values then we need to recreate the array
|
||||
if (cells->GetNumberOfTuples() < nr_points)
|
||||
{
|
||||
cells = vtkSmartPointer<vtkIdTypeArray>::New();
|
||||
|
||||
// If init cells is given, and there's enough data in it, use it
|
||||
if (initcells && initcells->GetNumberOfTuples() >= nr_points)
|
||||
{
|
||||
cells->DeepCopy(initcells);
|
||||
cells->SetNumberOfComponents(2);
|
||||
cells->SetNumberOfTuples(nr_points);
|
||||
}
|
||||
else
|
||||
{
|
||||
// If the number of tuples is still too small, we need to recreate the array
|
||||
cells->SetNumberOfComponents(2);
|
||||
cells->SetNumberOfTuples(nr_points);
|
||||
vtkIdType *cell = cells->GetPointer(0);
|
||||
// Fill it with 1s
|
||||
std::fill_n(cell, nr_points * 2, 1);
|
||||
cell++;
|
||||
for (vtkIdType i = 0; i < nr_points; ++i, cell += 2)
|
||||
*cell = i;
|
||||
// Save the results in initcells
|
||||
initcells = vtkSmartPointer<vtkIdTypeArray>::New();
|
||||
initcells->DeepCopy(cells);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// The assumption here is that the current set of cells has more data than needed
|
||||
cells->SetNumberOfComponents(2);
|
||||
cells->SetNumberOfTuples(nr_points);
|
||||
}
|
||||
|
||||
// Set the cells and the vertices
|
||||
vertices->SetCells(nr_points, cells);
|
||||
return polydata;
|
||||
}
|
||||
};
|
||||
|
||||
cv::viz::WCloud::WCloud(InputArray _cloud, InputArray _colors)
|
||||
{
|
||||
Mat cloud = _cloud.getMat();
|
||||
Mat colors = _colors.getMat();
|
||||
CV_Assert(cloud.type() == CV_32FC3 || cloud.type() == CV_64FC3 || cloud.type() == CV_32FC4 || cloud.type() == CV_64FC4);
|
||||
CV_Assert(colors.type() == CV_8UC3 && cloud.size() == colors.size());
|
||||
|
||||
if (cloud.isContinuous() && colors.isContinuous())
|
||||
{
|
||||
cloud.reshape(cloud.channels(), 1);
|
||||
colors.reshape(colors.channels(), 1);
|
||||
}
|
||||
|
||||
vtkIdType nr_points;
|
||||
vtkSmartPointer<vtkPolyData> polydata = CreateCloudWidget::create(cloud, nr_points);
|
||||
|
||||
// Filter colors
|
||||
Vec3b* colors_data = new Vec3b[nr_points];
|
||||
NanFilter::copyColor(colors, colors_data, cloud);
|
||||
|
||||
vtkSmartPointer<vtkUnsignedCharArray> scalars = vtkSmartPointer<vtkUnsignedCharArray>::New();
|
||||
scalars->SetNumberOfComponents(3);
|
||||
scalars->SetNumberOfTuples(nr_points);
|
||||
scalars->SetArray(colors_data->val, 3 * nr_points, 0);
|
||||
|
||||
// Assign the colors
|
||||
polydata->GetPointData()->SetScalars(scalars);
|
||||
|
||||
vtkSmartPointer<vtkDataSetMapper> mapper = vtkSmartPointer<vtkDataSetMapper>::New();
|
||||
#if VTK_MAJOR_VERSION <= 5
|
||||
mapper->SetInput(polydata);
|
||||
#else
|
||||
mapper->SetInputData(polydata);
|
||||
#endif
|
||||
|
||||
Vec3d minmax(scalars->GetRange());
|
||||
mapper->SetScalarRange(minmax.val);
|
||||
mapper->SetScalarModeToUsePointData();
|
||||
|
||||
bool interpolation = (polydata && polydata->GetNumberOfCells() != polydata->GetNumberOfVerts());
|
||||
|
||||
mapper->SetInterpolateScalarsBeforeMapping(interpolation);
|
||||
mapper->ScalarVisibilityOn();
|
||||
|
||||
mapper->ImmediateModeRenderingOff();
|
||||
|
||||
vtkSmartPointer<vtkLODActor> actor = vtkSmartPointer<vtkLODActor>::New();
|
||||
actor->SetNumberOfCloudPoints(int(std::max<vtkIdType>(1, polydata->GetNumberOfPoints() / 10)));
|
||||
actor->GetProperty()->SetInterpolationToFlat();
|
||||
actor->GetProperty()->BackfaceCullingOn();
|
||||
actor->SetMapper(mapper);
|
||||
|
||||
WidgetAccessor::setProp(*this, actor);
|
||||
}
|
||||
|
||||
cv::viz::WCloud::WCloud(InputArray _cloud, const Color &color)
|
||||
{
|
||||
Mat cloud = _cloud.getMat();
|
||||
CV_Assert(cloud.type() == CV_32FC3 || cloud.type() == CV_64FC3 || cloud.type() == CV_32FC4 || cloud.type() == CV_64FC4);
|
||||
|
||||
vtkIdType nr_points;
|
||||
vtkSmartPointer<vtkPolyData> polydata = CreateCloudWidget::create(cloud, nr_points);
|
||||
|
||||
vtkSmartPointer<vtkDataSetMapper> mapper = vtkSmartPointer<vtkDataSetMapper>::New();
|
||||
#if VTK_MAJOR_VERSION <= 5
|
||||
mapper->SetInput(polydata);
|
||||
#else
|
||||
mapper->SetInputData(polydata);
|
||||
#endif
|
||||
|
||||
bool interpolation = (polydata && polydata->GetNumberOfCells() != polydata->GetNumberOfVerts());
|
||||
|
||||
mapper->SetInterpolateScalarsBeforeMapping(interpolation);
|
||||
mapper->ScalarVisibilityOff();
|
||||
|
||||
mapper->ImmediateModeRenderingOff();
|
||||
|
||||
vtkSmartPointer<vtkLODActor> actor = vtkSmartPointer<vtkLODActor>::New();
|
||||
actor->SetNumberOfCloudPoints(int(std::max<vtkIdType>(1, polydata->GetNumberOfPoints() / 10)));
|
||||
actor->GetProperty()->SetInterpolationToFlat();
|
||||
actor->GetProperty()->BackfaceCullingOn();
|
||||
actor->SetMapper(mapper);
|
||||
|
||||
WidgetAccessor::setProp(*this, actor);
|
||||
setColor(color);
|
||||
}
|
||||
|
||||
template<> cv::viz::WCloud cv::viz::Widget::cast<cv::viz::WCloud>()
|
||||
{
|
||||
Widget3D widget = this->cast<Widget3D>();
|
||||
return static_cast<WCloud&>(widget);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// Cloud Collection Widget implementation
|
||||
|
||||
struct cv::viz::WCloudCollection::CreateCloudWidget
|
||||
{
|
||||
static inline vtkSmartPointer<vtkPolyData> create(const Mat &cloud, vtkIdType &nr_points)
|
||||
{
|
||||
vtkSmartPointer<vtkPolyData> polydata = vtkSmartPointer<vtkPolyData>::New();
|
||||
vtkSmartPointer<vtkCellArray> vertices = vtkSmartPointer<vtkCellArray>::New();
|
||||
|
||||
polydata->SetVerts(vertices);
|
||||
|
||||
vtkSmartPointer<vtkPoints> points = polydata->GetPoints();
|
||||
vtkSmartPointer<vtkIdTypeArray> initcells;
|
||||
nr_points = cloud.total();
|
||||
|
||||
if (!points)
|
||||
{
|
||||
points = vtkSmartPointer<vtkPoints>::New();
|
||||
if (cloud.depth() == CV_32F)
|
||||
points->SetDataTypeToFloat();
|
||||
else if (cloud.depth() == CV_64F)
|
||||
points->SetDataTypeToDouble();
|
||||
polydata->SetPoints(points);
|
||||
}
|
||||
points->SetNumberOfPoints(nr_points);
|
||||
|
||||
if (cloud.depth() == CV_32F)
|
||||
{
|
||||
// Get a pointer to the beginning of the data array
|
||||
Vec3f *data_beg = vtkpoints_data<float>(points);
|
||||
Vec3f *data_end = NanFilter::copy(cloud, data_beg, cloud);
|
||||
nr_points = data_end - data_beg;
|
||||
}
|
||||
else if (cloud.depth() == CV_64F)
|
||||
{
|
||||
// Get a pointer to the beginning of the data array
|
||||
Vec3d *data_beg = vtkpoints_data<double>(points);
|
||||
Vec3d *data_end = NanFilter::copy(cloud, data_beg, cloud);
|
||||
nr_points = data_end - data_beg;
|
||||
}
|
||||
points->SetNumberOfPoints(nr_points);
|
||||
|
||||
// Update cells
|
||||
vtkSmartPointer<vtkIdTypeArray> cells = vertices->GetData();
|
||||
// If no init cells and cells has not been initialized...
|
||||
if (!cells)
|
||||
cells = vtkSmartPointer<vtkIdTypeArray>::New();
|
||||
|
||||
// If we have less values then we need to recreate the array
|
||||
if (cells->GetNumberOfTuples() < nr_points)
|
||||
{
|
||||
cells = vtkSmartPointer<vtkIdTypeArray>::New();
|
||||
|
||||
// If init cells is given, and there's enough data in it, use it
|
||||
if (initcells && initcells->GetNumberOfTuples() >= nr_points)
|
||||
{
|
||||
cells->DeepCopy(initcells);
|
||||
cells->SetNumberOfComponents(2);
|
||||
cells->SetNumberOfTuples(nr_points);
|
||||
}
|
||||
else
|
||||
{
|
||||
// If the number of tuples is still too small, we need to recreate the array
|
||||
cells->SetNumberOfComponents(2);
|
||||
cells->SetNumberOfTuples(nr_points);
|
||||
vtkIdType *cell = cells->GetPointer(0);
|
||||
// Fill it with 1s
|
||||
std::fill_n(cell, nr_points * 2, 1);
|
||||
cell++;
|
||||
for (vtkIdType i = 0; i < nr_points; ++i, cell += 2)
|
||||
*cell = i;
|
||||
// Save the results in initcells
|
||||
initcells = vtkSmartPointer<vtkIdTypeArray>::New();
|
||||
initcells->DeepCopy(cells);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// The assumption here is that the current set of cells has more data than needed
|
||||
cells->SetNumberOfComponents(2);
|
||||
cells->SetNumberOfTuples(nr_points);
|
||||
}
|
||||
|
||||
// Set the cells and the vertices
|
||||
vertices->SetCells(nr_points, cells);
|
||||
return polydata;
|
||||
}
|
||||
|
||||
static void createMapper(vtkSmartPointer<vtkLODActor> actor, vtkSmartPointer<vtkPolyData> poly_data, Vec3d& minmax)
|
||||
{
|
||||
vtkDataSetMapper *mapper = vtkDataSetMapper::SafeDownCast(actor->GetMapper());
|
||||
if (!mapper)
|
||||
{
|
||||
// This is the first cloud
|
||||
vtkSmartPointer<vtkDataSetMapper> mapper_new = vtkSmartPointer<vtkDataSetMapper>::New();
|
||||
#if VTK_MAJOR_VERSION <= 5
|
||||
mapper_new->SetInputConnection(poly_data->GetProducerPort());
|
||||
#else
|
||||
mapper_new->SetInputData(poly_data);
|
||||
#endif
|
||||
|
||||
mapper_new->SetScalarRange(minmax.val);
|
||||
mapper_new->SetScalarModeToUsePointData();
|
||||
|
||||
bool interpolation = (poly_data && poly_data->GetNumberOfCells() != poly_data->GetNumberOfVerts());
|
||||
|
||||
mapper_new->SetInterpolateScalarsBeforeMapping(interpolation);
|
||||
mapper_new->ScalarVisibilityOn();
|
||||
mapper_new->ImmediateModeRenderingOff();
|
||||
|
||||
actor->SetNumberOfCloudPoints(int(std::max<vtkIdType>(1, poly_data->GetNumberOfPoints() / 10)));
|
||||
actor->GetProperty()->SetInterpolationToFlat();
|
||||
actor->GetProperty()->BackfaceCullingOn();
|
||||
actor->SetMapper(mapper_new);
|
||||
return ;
|
||||
}
|
||||
|
||||
vtkPolyData *data = vtkPolyData::SafeDownCast(mapper->GetInput());
|
||||
CV_Assert("Cloud Widget without data" && data);
|
||||
|
||||
vtkSmartPointer<vtkAppendPolyData> appendFilter = vtkSmartPointer<vtkAppendPolyData>::New();
|
||||
#if VTK_MAJOR_VERSION <= 5
|
||||
appendFilter->AddInputConnection(mapper->GetInput()->GetProducerPort());
|
||||
appendFilter->AddInputConnection(poly_data->GetProducerPort());
|
||||
#else
|
||||
appendFilter->AddInputData(data);
|
||||
appendFilter->AddInputData(poly_data);
|
||||
#endif
|
||||
mapper->SetInputConnection(appendFilter->GetOutputPort());
|
||||
|
||||
// Update the number of cloud points
|
||||
vtkIdType old_cloud_points = actor->GetNumberOfCloudPoints();
|
||||
actor->SetNumberOfCloudPoints(int(std::max<vtkIdType>(1, old_cloud_points+poly_data->GetNumberOfPoints() / 10)));
|
||||
}
|
||||
};
|
||||
|
||||
cv::viz::WCloudCollection::WCloudCollection()
|
||||
{
|
||||
// Just create the actor
|
||||
vtkSmartPointer<vtkLODActor> actor = vtkSmartPointer<vtkLODActor>::New();
|
||||
WidgetAccessor::setProp(*this, actor);
|
||||
}
|
||||
|
||||
void cv::viz::WCloudCollection::addCloud(InputArray _cloud, InputArray _colors, const Affine3f &pose)
|
||||
{
|
||||
Mat cloud = _cloud.getMat();
|
||||
Mat colors = _colors.getMat();
|
||||
CV_Assert(cloud.type() == CV_32FC3 || cloud.type() == CV_64FC3 || cloud.type() == CV_32FC4 || cloud.type() == CV_64FC4);
|
||||
CV_Assert(colors.type() == CV_8UC3 && cloud.size() == colors.size());
|
||||
|
||||
if (cloud.isContinuous() && colors.isContinuous())
|
||||
{
|
||||
cloud.reshape(cloud.channels(), 1);
|
||||
colors.reshape(colors.channels(), 1);
|
||||
}
|
||||
|
||||
vtkIdType nr_points;
|
||||
vtkSmartPointer<vtkPolyData> polydata = CreateCloudWidget::create(cloud, nr_points);
|
||||
|
||||
// Filter colors
|
||||
Vec3b* colors_data = new Vec3b[nr_points];
|
||||
NanFilter::copyColor(colors, colors_data, cloud);
|
||||
|
||||
vtkSmartPointer<vtkUnsignedCharArray> scalars = vtkSmartPointer<vtkUnsignedCharArray>::New();
|
||||
scalars->SetNumberOfComponents(3);
|
||||
scalars->SetNumberOfTuples(nr_points);
|
||||
scalars->SetArray(colors_data->val, 3 * nr_points, 0);
|
||||
|
||||
// Assign the colors
|
||||
polydata->GetPointData()->SetScalars(scalars);
|
||||
|
||||
// Transform the poly data based on the pose
|
||||
vtkSmartPointer<vtkTransform> transform = vtkSmartPointer<vtkTransform>::New();
|
||||
transform->PreMultiply();
|
||||
transform->SetMatrix(convertToVtkMatrix(pose.matrix));
|
||||
|
||||
vtkSmartPointer<vtkTransformPolyDataFilter> transform_filter = vtkSmartPointer<vtkTransformPolyDataFilter>::New();
|
||||
transform_filter->SetTransform(transform);
|
||||
#if VTK_MAJOR_VERSION <= 5
|
||||
transform_filter->SetInputConnection(polydata->GetProducerPort());
|
||||
#else
|
||||
transform_filter->SetInputData(polydata);
|
||||
#endif
|
||||
transform_filter->Update();
|
||||
|
||||
vtkLODActor *actor = vtkLODActor::SafeDownCast(WidgetAccessor::getProp(*this));
|
||||
CV_Assert("Incompatible widget type." && actor);
|
||||
|
||||
Vec3d minmax(scalars->GetRange());
|
||||
CreateCloudWidget::createMapper(actor, transform_filter->GetOutput(), minmax);
|
||||
}
|
||||
|
||||
void cv::viz::WCloudCollection::addCloud(InputArray _cloud, const Color &color, const Affine3f &pose)
|
||||
{
|
||||
Mat cloud = _cloud.getMat();
|
||||
CV_Assert(cloud.type() == CV_32FC3 || cloud.type() == CV_64FC3 || cloud.type() == CV_32FC4 || cloud.type() == CV_64FC4);
|
||||
|
||||
vtkIdType nr_points;
|
||||
vtkSmartPointer<vtkPolyData> polydata = CreateCloudWidget::create(cloud, nr_points);
|
||||
|
||||
vtkSmartPointer<vtkUnsignedCharArray> scalars = vtkSmartPointer<vtkUnsignedCharArray>::New();
|
||||
scalars->SetNumberOfComponents(3);
|
||||
scalars->SetNumberOfTuples(nr_points);
|
||||
scalars->FillComponent(0, color[2]);
|
||||
scalars->FillComponent(1, color[1]);
|
||||
scalars->FillComponent(2, color[0]);
|
||||
|
||||
// Assign the colors
|
||||
polydata->GetPointData()->SetScalars(scalars);
|
||||
|
||||
// Transform the poly data based on the pose
|
||||
vtkSmartPointer<vtkTransform> transform = vtkSmartPointer<vtkTransform>::New();
|
||||
transform->PreMultiply();
|
||||
transform->SetMatrix(convertToVtkMatrix(pose.matrix));
|
||||
|
||||
vtkSmartPointer<vtkTransformPolyDataFilter> transform_filter = vtkSmartPointer<vtkTransformPolyDataFilter>::New();
|
||||
transform_filter->SetTransform(transform);
|
||||
#if VTK_MAJOR_VERSION <= 5
|
||||
transform_filter->SetInputConnection(polydata->GetProducerPort());
|
||||
#else
|
||||
transform_filter->SetInputData(polydata);
|
||||
#endif
|
||||
transform_filter->Update();
|
||||
|
||||
vtkLODActor *actor = vtkLODActor::SafeDownCast(WidgetAccessor::getProp(*this));
|
||||
CV_Assert("Incompatible widget type." && actor);
|
||||
|
||||
Vec3d minmax(scalars->GetRange());
|
||||
CreateCloudWidget::createMapper(actor, transform_filter->GetOutput(), minmax);
|
||||
}
|
||||
|
||||
template<> cv::viz::WCloudCollection cv::viz::Widget::cast<cv::viz::WCloudCollection>()
|
||||
{
|
||||
Widget3D widget = this->cast<Widget3D>();
|
||||
return static_cast<WCloudCollection&>(widget);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// Cloud Normals Widget implementation
|
||||
|
||||
struct cv::viz::WCloudNormals::ApplyCloudNormals
|
||||
{
|
||||
template<typename _Tp>
|
||||
struct Impl
|
||||
{
|
||||
static vtkSmartPointer<vtkCellArray> applyOrganized(const Mat &cloud, const Mat& normals, double level, float scale, _Tp *&pts, vtkIdType &nr_normals)
|
||||
{
|
||||
vtkIdType point_step = static_cast<vtkIdType>(std::sqrt(level));
|
||||
nr_normals = (static_cast<vtkIdType>((cloud.cols - 1) / point_step) + 1) *
|
||||
(static_cast<vtkIdType>((cloud.rows - 1) / point_step) + 1);
|
||||
vtkSmartPointer<vtkCellArray> lines = vtkSmartPointer<vtkCellArray>::New();
|
||||
|
||||
pts = new _Tp[2 * nr_normals * 3];
|
||||
|
||||
int cch = cloud.channels();
|
||||
vtkIdType cell_count = 0;
|
||||
for (vtkIdType y = 0; y < cloud.rows; y += point_step)
|
||||
{
|
||||
const _Tp *prow = cloud.ptr<_Tp>(y);
|
||||
const _Tp *nrow = normals.ptr<_Tp>(y);
|
||||
for (vtkIdType x = 0; x < cloud.cols; x += point_step * cch)
|
||||
{
|
||||
pts[2 * cell_count * 3 + 0] = prow[x];
|
||||
pts[2 * cell_count * 3 + 1] = prow[x+1];
|
||||
pts[2 * cell_count * 3 + 2] = prow[x+2];
|
||||
pts[2 * cell_count * 3 + 3] = prow[x] + nrow[x] * scale;
|
||||
pts[2 * cell_count * 3 + 4] = prow[x+1] + nrow[x+1] * scale;
|
||||
pts[2 * cell_count * 3 + 5] = prow[x+2] + nrow[x+2] * scale;
|
||||
|
||||
lines->InsertNextCell(2);
|
||||
lines->InsertCellPoint(2 * cell_count);
|
||||
lines->InsertCellPoint(2 * cell_count + 1);
|
||||
cell_count++;
|
||||
}
|
||||
}
|
||||
return lines;
|
||||
}
|
||||
|
||||
static vtkSmartPointer<vtkCellArray> applyUnorganized(const Mat &cloud, const Mat& normals, int level, float scale, _Tp *&pts, vtkIdType &nr_normals)
|
||||
{
|
||||
vtkSmartPointer<vtkCellArray> lines = vtkSmartPointer<vtkCellArray>::New();
|
||||
nr_normals = (cloud.size().area() - 1) / level + 1 ;
|
||||
pts = new _Tp[2 * nr_normals * 3];
|
||||
|
||||
int cch = cloud.channels();
|
||||
const _Tp *p = cloud.ptr<_Tp>();
|
||||
const _Tp *n = normals.ptr<_Tp>();
|
||||
for (vtkIdType i = 0, j = 0; j < nr_normals; j++, i = j * level * cch)
|
||||
{
|
||||
|
||||
pts[2 * j * 3 + 0] = p[i];
|
||||
pts[2 * j * 3 + 1] = p[i+1];
|
||||
pts[2 * j * 3 + 2] = p[i+2];
|
||||
pts[2 * j * 3 + 3] = p[i] + n[i] * scale;
|
||||
pts[2 * j * 3 + 4] = p[i+1] + n[i+1] * scale;
|
||||
pts[2 * j * 3 + 5] = p[i+2] + n[i+2] * scale;
|
||||
|
||||
lines->InsertNextCell(2);
|
||||
lines->InsertCellPoint(2 * j);
|
||||
lines->InsertCellPoint(2 * j + 1);
|
||||
}
|
||||
return lines;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename _Tp>
|
||||
static inline vtkSmartPointer<vtkCellArray> apply(const Mat &cloud, const Mat& normals, int level, float scale, _Tp *&pts, vtkIdType &nr_normals)
|
||||
{
|
||||
if (cloud.cols > 1 && cloud.rows > 1)
|
||||
return ApplyCloudNormals::Impl<_Tp>::applyOrganized(cloud, normals, level, scale, pts, nr_normals);
|
||||
else
|
||||
return ApplyCloudNormals::Impl<_Tp>::applyUnorganized(cloud, normals, level, scale, pts, nr_normals);
|
||||
}
|
||||
};
|
||||
|
||||
cv::viz::WCloudNormals::WCloudNormals(InputArray _cloud, InputArray _normals, int level, float scale, const Color &color)
|
||||
{
|
||||
Mat cloud = _cloud.getMat();
|
||||
Mat normals = _normals.getMat();
|
||||
CV_Assert(cloud.type() == CV_32FC3 || cloud.type() == CV_64FC3 || cloud.type() == CV_32FC4 || cloud.type() == CV_64FC4);
|
||||
CV_Assert(cloud.size() == normals.size() && cloud.type() == normals.type());
|
||||
|
||||
vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
|
||||
vtkSmartPointer<vtkCellArray> lines = vtkSmartPointer<vtkCellArray>::New();
|
||||
vtkIdType nr_normals = 0;
|
||||
|
||||
if (cloud.depth() == CV_32F)
|
||||
{
|
||||
points->SetDataTypeToFloat();
|
||||
|
||||
vtkSmartPointer<vtkFloatArray> data = vtkSmartPointer<vtkFloatArray>::New();
|
||||
data->SetNumberOfComponents(3);
|
||||
|
||||
float* pts = 0;
|
||||
lines = ApplyCloudNormals::apply(cloud, normals, level, scale, pts, nr_normals);
|
||||
data->SetArray(&pts[0], 2 * nr_normals * 3, 0);
|
||||
points->SetData(data);
|
||||
}
|
||||
else
|
||||
{
|
||||
points->SetDataTypeToDouble();
|
||||
|
||||
vtkSmartPointer<vtkDoubleArray> data = vtkSmartPointer<vtkDoubleArray>::New();
|
||||
data->SetNumberOfComponents(3);
|
||||
|
||||
double* pts = 0;
|
||||
lines = ApplyCloudNormals::apply(cloud, normals, level, scale, pts, nr_normals);
|
||||
data->SetArray(&pts[0], 2 * nr_normals * 3, 0);
|
||||
points->SetData(data);
|
||||
}
|
||||
|
||||
vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
|
||||
polyData->SetPoints(points);
|
||||
polyData->SetLines(lines);
|
||||
|
||||
vtkSmartPointer<vtkDataSetMapper> mapper = vtkSmartPointer<vtkDataSetMapper>::New();
|
||||
#if VTK_MAJOR_VERSION <= 5
|
||||
mapper->SetInput(polyData);
|
||||
#else
|
||||
mapper->SetInputData(polyData);
|
||||
#endif
|
||||
mapper->SetColorModeToMapScalars();
|
||||
mapper->SetScalarModeToUsePointData();
|
||||
|
||||
vtkSmartPointer<vtkLODActor> actor = vtkSmartPointer<vtkLODActor>::New();
|
||||
actor->SetMapper(mapper);
|
||||
WidgetAccessor::setProp(*this, actor);
|
||||
setColor(color);
|
||||
}
|
||||
|
||||
template<> cv::viz::WCloudNormals cv::viz::Widget::cast<cv::viz::WCloudNormals>()
|
||||
{
|
||||
Widget3D widget = this->cast<Widget3D>();
|
||||
return static_cast<WCloudNormals&>(widget);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// Mesh Widget implementation
|
||||
|
||||
struct cv::viz::WMesh::CopyImpl
|
||||
{
|
||||
template<typename _Tp>
|
||||
static Vec<_Tp, 3> * copy(const Mat &source, Vec<_Tp, 3> *output, int *look_up, const Mat &nan_mask)
|
||||
{
|
||||
CV_Assert(DataDepth<_Tp>::value == source.depth() && source.size() == nan_mask.size());
|
||||
CV_Assert(nan_mask.channels() == 3 || nan_mask.channels() == 4);
|
||||
CV_DbgAssert(DataDepth<_Tp>::value == nan_mask.depth());
|
||||
|
||||
int s_chs = source.channels();
|
||||
int m_chs = nan_mask.channels();
|
||||
|
||||
int index = 0;
|
||||
const _Tp* srow = source.ptr<_Tp>(0);
|
||||
const _Tp* mrow = nan_mask.ptr<_Tp>(0);
|
||||
|
||||
for (int x = 0; x < source.cols; ++x, srow += s_chs, mrow += m_chs)
|
||||
{
|
||||
if (!isNan(mrow[0]) && !isNan(mrow[1]) && !isNan(mrow[2]))
|
||||
{
|
||||
look_up[x] = index;
|
||||
*output++ = Vec<_Tp, 3>(srow);
|
||||
++index;
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
};
|
||||
|
||||
cv::viz::WMesh::WMesh(const Mesh3d &mesh)
|
||||
{
|
||||
CV_Assert(mesh.cloud.rows == 1 && (mesh.cloud.type() == CV_32FC3 || mesh.cloud.type() == CV_64FC3 || mesh.cloud.type() == CV_32FC4 || mesh.cloud.type() == CV_64FC4));
|
||||
CV_Assert(mesh.colors.empty() || (mesh.colors.type() == CV_8UC3 && mesh.cloud.size() == mesh.colors.size()));
|
||||
CV_Assert(!mesh.polygons.empty() && mesh.polygons.type() == CV_32SC1);
|
||||
|
||||
vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
|
||||
vtkIdType nr_points = mesh.cloud.total();
|
||||
Mat look_up_mat(1, nr_points, CV_32SC1);
|
||||
int * look_up = look_up_mat.ptr<int>();
|
||||
points->SetNumberOfPoints(nr_points);
|
||||
|
||||
// Copy data from cloud to vtkPoints
|
||||
if (mesh.cloud.depth() == CV_32F)
|
||||
{
|
||||
points->SetDataTypeToFloat();
|
||||
Vec3f *data_beg = vtkpoints_data<float>(points);
|
||||
Vec3f *data_end = CopyImpl::copy(mesh.cloud, data_beg, look_up, mesh.cloud);
|
||||
nr_points = data_end - data_beg;
|
||||
}
|
||||
else
|
||||
{
|
||||
points->SetDataTypeToDouble();
|
||||
Vec3d *data_beg = vtkpoints_data<double>(points);
|
||||
Vec3d *data_end = CopyImpl::copy(mesh.cloud, data_beg, look_up, mesh.cloud);
|
||||
nr_points = data_end - data_beg;
|
||||
}
|
||||
|
||||
vtkSmartPointer<vtkUnsignedCharArray> scalars;
|
||||
|
||||
if (!mesh.colors.empty())
|
||||
{
|
||||
Vec3b * colors_data = 0;
|
||||
colors_data = new Vec3b[nr_points];
|
||||
NanFilter::copyColor(mesh.colors, colors_data, mesh.cloud);
|
||||
|
||||
scalars = vtkSmartPointer<vtkUnsignedCharArray>::New();
|
||||
scalars->SetNumberOfComponents(3);
|
||||
scalars->SetNumberOfTuples(nr_points);
|
||||
scalars->SetArray(colors_data->val, 3 * nr_points, 0);
|
||||
}
|
||||
|
||||
points->SetNumberOfPoints(nr_points);
|
||||
|
||||
vtkSmartPointer<vtkPointSet> data;
|
||||
|
||||
if (mesh.polygons.size().area() > 1)
|
||||
{
|
||||
vtkSmartPointer<vtkCellArray> cell_array = vtkSmartPointer<vtkCellArray>::New();
|
||||
const int * polygons = mesh.polygons.ptr<int>();
|
||||
|
||||
int idx = 0;
|
||||
int poly_size = mesh.polygons.total();
|
||||
for (int i = 0; i < poly_size; ++idx)
|
||||
{
|
||||
int n_points = polygons[i++];
|
||||
|
||||
cell_array->InsertNextCell(n_points);
|
||||
for (int j = 0; j < n_points; ++j, ++idx)
|
||||
cell_array->InsertCellPoint(look_up[polygons[i++]]);
|
||||
}
|
||||
vtkSmartPointer<vtkPolyData> polydata = vtkSmartPointer<vtkPolyData>::New();
|
||||
cell_array->GetData()->SetNumberOfValues(idx);
|
||||
cell_array->Squeeze();
|
||||
polydata->SetStrips(cell_array);
|
||||
polydata->SetPoints(points);
|
||||
|
||||
if (scalars)
|
||||
polydata->GetPointData()->SetScalars(scalars);
|
||||
|
||||
data = polydata;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Only one polygon
|
||||
vtkSmartPointer<vtkPolygon> polygon = vtkSmartPointer<vtkPolygon>::New();
|
||||
const int * polygons = mesh.polygons.ptr<int>();
|
||||
int n_points = polygons[0];
|
||||
|
||||
polygon->GetPointIds()->SetNumberOfIds(n_points);
|
||||
|
||||
for (int j = 1; j < n_points+1; ++j)
|
||||
polygon->GetPointIds()->SetId(j, look_up[polygons[j]]);
|
||||
|
||||
vtkSmartPointer<vtkUnstructuredGrid> poly_grid = vtkSmartPointer<vtkUnstructuredGrid>::New();
|
||||
poly_grid->Allocate(1, 1);
|
||||
poly_grid->InsertNextCell(polygon->GetCellType(), polygon->GetPointIds());
|
||||
poly_grid->SetPoints(points);
|
||||
|
||||
if (scalars)
|
||||
poly_grid->GetPointData()->SetScalars(scalars);
|
||||
|
||||
data = poly_grid;
|
||||
}
|
||||
|
||||
vtkSmartPointer<vtkLODActor> actor = vtkSmartPointer<vtkLODActor>::New();
|
||||
|
||||
actor->GetProperty()->SetRepresentationToSurface();
|
||||
actor->GetProperty()->BackfaceCullingOff(); // Backface culling is off for higher efficiency
|
||||
actor->GetProperty()->SetInterpolationToFlat();
|
||||
actor->GetProperty()->EdgeVisibilityOff();
|
||||
actor->GetProperty()->ShadingOff();
|
||||
|
||||
vtkSmartPointer<vtkDataSetMapper> mapper = vtkSmartPointer<vtkDataSetMapper>::New();
|
||||
#if VTK_MAJOR_VERSION <= 5
|
||||
mapper->SetInput(data);
|
||||
#else
|
||||
mapper->SetInputData(data);
|
||||
#endif
|
||||
mapper->ImmediateModeRenderingOff();
|
||||
|
||||
vtkIdType numberOfCloudPoints = nr_points * 0.1;
|
||||
actor->SetNumberOfCloudPoints(int(numberOfCloudPoints > 1 ? numberOfCloudPoints : 1));
|
||||
actor->SetMapper(mapper);
|
||||
|
||||
WidgetAccessor::setProp(*this, actor);
|
||||
}
|
||||
|
||||
template<> CV_EXPORTS cv::viz::WMesh cv::viz::Widget::cast<cv::viz::WMesh>()
|
||||
{
|
||||
Widget3D widget = this->cast<Widget3D>();
|
||||
return static_cast<WMesh&>(widget);
|
||||
}
|
441
modules/viz/src/clouds.cpp
Normal file
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);
|
||||
}
|
@ -48,20 +48,21 @@
|
||||
|
||||
#include "precomp.hpp"
|
||||
|
||||
|
||||
namespace cv { namespace viz
|
||||
{
|
||||
vtkStandardNewMacro(InteractorStyle)
|
||||
}}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::InteractorStyle::Initialize()
|
||||
{
|
||||
modifier_ = cv::viz::InteractorStyle::KB_MOD_ALT;
|
||||
// Set windows size (width, height) to unknown (-1)
|
||||
win_size_ = Vec2i(-1, -1);
|
||||
win_pos_ = Vec2i(0, 0);
|
||||
max_win_size_ = Vec2i(-1, -1);
|
||||
|
||||
// Create the image filter and PNG writer objects
|
||||
wif_ = vtkSmartPointer<vtkWindowToImageFilter>::New();
|
||||
snapshot_writer_ = vtkSmartPointer<vtkPNGWriter>::New();
|
||||
snapshot_writer_->SetInputConnection(wif_->GetOutputPort());
|
||||
|
||||
init_ = true;
|
||||
stereo_anaglyph_mask_default_ = true;
|
||||
|
||||
@ -78,11 +79,37 @@ void cv::viz::InteractorStyle::Initialize()
|
||||
void cv::viz::InteractorStyle::saveScreenshot(const String &file)
|
||||
{
|
||||
FindPokedRenderer(Interactor->GetEventPosition()[0], Interactor->GetEventPosition()[1]);
|
||||
wif_->SetInput(Interactor->GetRenderWindow());
|
||||
wif_->Modified(); // Update the WindowToImageFilter
|
||||
snapshot_writer_->Modified();
|
||||
snapshot_writer_->SetFileName(file.c_str());
|
||||
snapshot_writer_->Write();
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -121,13 +148,7 @@ void cv::viz::InteractorStyle::OnChar()
|
||||
else if (key.find("XF86ZoomOut") != String::npos)
|
||||
zoomOut();
|
||||
|
||||
int keymod = false;
|
||||
switch (modifier_)
|
||||
{
|
||||
case KB_MOD_ALT: keymod = Interactor->GetAltKey(); break;
|
||||
case KB_MOD_CTRL: keymod = Interactor->GetControlKey(); break;
|
||||
case KB_MOD_SHIFT: keymod = Interactor->GetShiftKey(); break;
|
||||
}
|
||||
int keymod = Interactor->GetAltKey();
|
||||
|
||||
switch (Interactor->GetKeyCode())
|
||||
{
|
||||
@ -180,43 +201,32 @@ void cv::viz::InteractorStyle::registerKeyboardCallback(void (*callback)(const K
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool cv::viz::InteractorStyle::getAltKey() { return Interactor->GetAltKey() != 0; }
|
||||
bool cv::viz::InteractorStyle::getShiftKey() { return Interactor->GetShiftKey()!= 0; }
|
||||
bool cv::viz::InteractorStyle::getControlKey() { return Interactor->GetControlKey()!= 0; }
|
||||
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()
|
||||
void cv::viz::InteractorStyle::OnKeyDown()
|
||||
{
|
||||
CV_Assert("Interactor style not initialized. Please call Initialize() before continuing" && init_);
|
||||
CV_Assert("No renderer given! Use SetRendererCollection() before continuing." && renderer_);
|
||||
|
||||
FindPokedRenderer(Interactor->GetEventPosition()[0], Interactor->GetEventPosition()[1]);
|
||||
|
||||
if (wif_->GetInput() == NULL)
|
||||
{
|
||||
wif_->SetInput(Interactor->GetRenderWindow());
|
||||
wif_->Modified();
|
||||
snapshot_writer_->Modified();
|
||||
}
|
||||
|
||||
// Save the initial windows width/height
|
||||
if (win_size_[0] == -1 || win_size_[1] == -1)
|
||||
win_size_ = Vec2i(Interactor->GetRenderWindow()->GetSize());
|
||||
|
||||
|
||||
// Get the status of special keys (Cltr+Alt+Shift)
|
||||
bool shift = getShiftKey();
|
||||
bool ctrl = getControlKey();
|
||||
bool alt = getAltKey();
|
||||
|
||||
bool keymod = false;
|
||||
switch (modifier_)
|
||||
{
|
||||
case KB_MOD_ALT: keymod = alt; break;
|
||||
case KB_MOD_CTRL: keymod = ctrl; break;
|
||||
case KB_MOD_SHIFT: keymod = shift; break;
|
||||
}
|
||||
bool alt = Interactor->GetAltKey() != 0;
|
||||
|
||||
std::string key(Interactor->GetKeySym());
|
||||
if (key.find("XF86ZoomIn") != std::string::npos)
|
||||
@ -235,8 +245,10 @@ cv::viz::InteractorStyle::OnKeyDown()
|
||||
" 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\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"
|
||||
@ -249,7 +261,7 @@ cv::viz::InteractorStyle::OnKeyDown()
|
||||
" ALT + s, S : turn stereo mode on/off\n"
|
||||
" ALT + f, F : switch between maximized window mode and original size\n"
|
||||
"\n"
|
||||
<< std::endl;
|
||||
<< std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -261,66 +273,41 @@ cv::viz::InteractorStyle::OnKeyDown()
|
||||
for (ac->InitTraversal(ait); vtkActor* actor = ac->GetNextActor(ait); )
|
||||
for (actor->InitPathTraversal(); vtkAssemblyPath* path = actor->GetNextPath(); )
|
||||
{
|
||||
vtkActor* apart = reinterpret_cast <vtkActor*>(path->GetLastNode()->GetViewProp());
|
||||
vtkActor* apart = vtkActor::SafeDownCast(path->GetLastNode()->GetViewProp());
|
||||
apart->GetProperty()->SetRepresentationToPoints();
|
||||
}
|
||||
break;
|
||||
}
|
||||
// Save a PNG snapshot with the current screen
|
||||
|
||||
// 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':
|
||||
{
|
||||
unsigned int t = static_cast<unsigned int>(time(0));
|
||||
String png_file = cv::format("screenshot-%d.png", t);
|
||||
String cam_file = cv::format("screenshot-%d.cam", t);
|
||||
|
||||
vtkSmartPointer<vtkCamera> cam = Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->GetActiveCamera();
|
||||
Vec2d clip;
|
||||
Vec3d focal, pos, view;
|
||||
cam->GetClippingRange(clip.val);
|
||||
cam->GetFocalPoint(focal.val);
|
||||
cam->GetPosition(pos.val);
|
||||
cam->GetViewUp(view.val);
|
||||
Vec2i win_pos(Interactor->GetRenderWindow()->GetPosition());
|
||||
Vec2i win_size(Interactor->GetRenderWindow()->GetSize());
|
||||
double angle = cam->GetViewAngle() / 180.0 * CV_PI;
|
||||
|
||||
String data = cv::format("%f,%f/%f,%f,%f/%f,%f,%f/%f,%f,%f/%f/%d,%d/%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]);
|
||||
|
||||
saveScreenshot(png_file);
|
||||
ofstream ofs_cam(cam_file.c_str());
|
||||
ofs_cam << data.c_str() << endl;
|
||||
ofs_cam.close();
|
||||
|
||||
cout << "Screenshot (" << png_file.c_str() << ") and camera information (" << cam_file.c_str() << ") successfully captured." << endl;
|
||||
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;
|
||||
Vec3d focal, pose, view;
|
||||
cam->GetClippingRange(clip.val);
|
||||
cam->GetFocalPoint(focal.val);
|
||||
cam->GetPosition(pose.val);
|
||||
cam->GetViewUp(view.val);
|
||||
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;
|
||||
|
||||
cv::print(Mat(clip, false).reshape(1, 1));
|
||||
std::cout << "/";
|
||||
cv::print(Mat(focal, false).reshape(1, 1));
|
||||
std::cout << "/";
|
||||
cv::print(Mat(pose, false).reshape(1, 1));
|
||||
std::cout << "/";
|
||||
cv::print(Mat(view, false).reshape(1, 1));
|
||||
std::cout << "/" << cam->GetViewAngle () / 180.0 * CV_PI;
|
||||
cv::print(Mat(win_size, false).reshape(1, 1));
|
||||
std::cout << "/";
|
||||
cv::print(Mat(win_pos, false).reshape(1, 1));
|
||||
std::cout << std::endl;
|
||||
break;
|
||||
}
|
||||
case '=':
|
||||
@ -339,7 +326,7 @@ cv::viz::InteractorStyle::OnKeyDown()
|
||||
for (ac->InitTraversal(ait); vtkActor* actor = ac->GetNextActor(ait); )
|
||||
for (actor->InitPathTraversal(); vtkAssemblyPath* path = actor->GetNextPath(); )
|
||||
{
|
||||
vtkActor* apart = reinterpret_cast <vtkActor*>(path->GetLastNode()->GetViewProp());
|
||||
vtkActor* apart = vtkActor::SafeDownCast(path->GetLastNode()->GetViewProp());
|
||||
float psize = apart->GetProperty()->GetPointSize();
|
||||
if (psize < 63.0f)
|
||||
apart->GetProperty()->SetPointSize(psize + 1.0f);
|
||||
@ -358,7 +345,7 @@ cv::viz::InteractorStyle::OnKeyDown()
|
||||
for (ac->InitTraversal(ait); vtkActor* actor = ac->GetNextActor(ait); )
|
||||
for (actor->InitPathTraversal(); vtkAssemblyPath* path = actor->GetNextPath(); )
|
||||
{
|
||||
vtkActor* apart = static_cast<vtkActor*>(path->GetLastNode()->GetViewProp());
|
||||
vtkActor* apart = vtkActor::SafeDownCast(path->GetLastNode()->GetViewProp());
|
||||
float psize = apart->GetProperty()->GetPointSize();
|
||||
if (psize > 1.0f)
|
||||
apart->GetProperty()->SetPointSize(psize - 1.0f);
|
||||
@ -369,7 +356,7 @@ cv::viz::InteractorStyle::OnKeyDown()
|
||||
// Switch between maximize and original window size
|
||||
case 'f': case 'F':
|
||||
{
|
||||
if (keymod)
|
||||
if (alt)
|
||||
{
|
||||
Vec2i screen_size(Interactor->GetRenderWindow()->GetScreenSize());
|
||||
Vec2i win_size(Interactor->GetRenderWindow()->GetSize());
|
||||
@ -397,13 +384,11 @@ cv::viz::InteractorStyle::OnKeyDown()
|
||||
else
|
||||
{
|
||||
AnimState = VTKIS_ANIM_ON;
|
||||
vtkAssemblyPath *path = NULL;
|
||||
Interactor->GetPicker()->Pick(Interactor->GetEventPosition()[0], Interactor->GetEventPosition()[1], 0.0, CurrentRenderer);
|
||||
vtkAbstractPropPicker *picker;
|
||||
if ((picker = vtkAbstractPropPicker::SafeDownCast(Interactor->GetPicker())))
|
||||
path = picker->GetPath();
|
||||
if (path != NULL)
|
||||
Interactor->FlyTo(CurrentRenderer, picker->GetPickPosition());
|
||||
vtkSmartPointer<vtkAbstractPropPicker> picker = vtkAbstractPropPicker::SafeDownCast(Interactor->GetPicker());
|
||||
if (picker)
|
||||
if (picker->GetPath())
|
||||
Interactor->FlyTo(CurrentRenderer, picker->GetPickPosition());
|
||||
AnimState = VTKIS_ANIM_OFF;
|
||||
}
|
||||
break;
|
||||
@ -411,24 +396,16 @@ cv::viz::InteractorStyle::OnKeyDown()
|
||||
// 's'/'S' w/out ALT
|
||||
case 's': case 'S':
|
||||
{
|
||||
if (keymod)
|
||||
if (alt)
|
||||
{
|
||||
int stereo_render = Interactor->GetRenderWindow()->GetStereoRender();
|
||||
if (!stereo_render)
|
||||
vtkSmartPointer<vtkRenderWindow> window = Interactor->GetRenderWindow();
|
||||
if (!window->GetStereoRender())
|
||||
{
|
||||
if (stereo_anaglyph_mask_default_)
|
||||
{
|
||||
Interactor->GetRenderWindow()->SetAnaglyphColorMask(4, 3);
|
||||
stereo_anaglyph_mask_default_ = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Interactor->GetRenderWindow()->SetAnaglyphColorMask(2, 5);
|
||||
stereo_anaglyph_mask_default_ = true;
|
||||
}
|
||||
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_;
|
||||
}
|
||||
Interactor->GetRenderWindow()->SetStereoRender(!stereo_render);
|
||||
Interactor->GetRenderWindow()->Render();
|
||||
window->SetStereoRender(!window->GetStereoRender());
|
||||
Interactor->Render();
|
||||
}
|
||||
else
|
||||
@ -440,43 +417,34 @@ cv::viz::InteractorStyle::OnKeyDown()
|
||||
{
|
||||
vtkSmartPointer<vtkCamera> cam = CurrentRenderer->GetActiveCamera();
|
||||
cam->SetParallelProjection(!cam->GetParallelProjection());
|
||||
CurrentRenderer->SetActiveCamera(cam);
|
||||
CurrentRenderer->Render();
|
||||
break;
|
||||
}
|
||||
|
||||
// Overwrite the camera reset
|
||||
// Overwrite the camera reset
|
||||
case 'r': case 'R':
|
||||
{
|
||||
if (!keymod)
|
||||
if (!alt)
|
||||
{
|
||||
Superclass::OnKeyDown();
|
||||
break;
|
||||
}
|
||||
|
||||
vtkSmartPointer<vtkCamera> cam = CurrentRenderer->GetActiveCamera();
|
||||
|
||||
static WidgetActorMap::iterator it = widget_actor_map_->begin();
|
||||
WidgetActorMap::iterator it = widget_actor_map_->begin();
|
||||
// it might be that some actors don't have a valid transformation set -> we skip them to avoid a seg fault.
|
||||
bool found_transformation = false;
|
||||
|
||||
for (size_t idx = 0; idx < widget_actor_map_->size(); ++idx, ++it)
|
||||
for (; it != widget_actor_map_->end(); ++it)
|
||||
{
|
||||
if (it == widget_actor_map_->end())
|
||||
it = widget_actor_map_->begin();
|
||||
|
||||
vtkProp3D * actor = vtkProp3D::SafeDownCast(it->second);
|
||||
if (actor && actor->GetUserMatrix())
|
||||
{
|
||||
found_transformation = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
vtkSmartPointer<vtkCamera> cam = CurrentRenderer->GetActiveCamera();
|
||||
|
||||
// if a valid transformation was found, use it otherwise fall back to default view point.
|
||||
if (found_transformation)
|
||||
if (it != widget_actor_map_->end())
|
||||
{
|
||||
const vtkMatrix4x4* m = vtkProp3D::SafeDownCast(it->second)->GetUserMatrix();
|
||||
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),
|
||||
@ -516,23 +484,18 @@ cv::viz::InteractorStyle::OnKeyDown()
|
||||
}
|
||||
}
|
||||
|
||||
KeyboardEvent event(true, Interactor->GetKeySym(), Interactor->GetKeyCode(), getAltKey(), getControlKey(), getShiftKey());
|
||||
// Check if there is a keyboard callback registered
|
||||
KeyboardEvent event(KeyboardEvent::KEY_DOWN, Interactor->GetKeySym(), Interactor->GetKeyCode(), getModifiers());
|
||||
if (keyboardCallback_)
|
||||
keyboardCallback_(event, keyboard_callback_cookie_);
|
||||
|
||||
renderer_->Render();
|
||||
keyboardCallback_(event, keyboard_callback_cookie_);
|
||||
Interactor->Render();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::InteractorStyle::OnKeyUp()
|
||||
{
|
||||
KeyboardEvent event(false, Interactor->GetKeySym(), Interactor->GetKeyCode(), getAltKey(), getControlKey(), getShiftKey());
|
||||
// Check if there is a keyboard callback registered
|
||||
KeyboardEvent event(KeyboardEvent::KEY_UP, Interactor->GetKeySym(), Interactor->GetKeyCode(), getModifiers());
|
||||
if (keyboardCallback_)
|
||||
keyboardCallback_(event, keyboard_callback_cookie_);
|
||||
|
||||
keyboardCallback_(event, keyboard_callback_cookie_);
|
||||
Superclass::OnKeyUp();
|
||||
}
|
||||
|
||||
@ -540,9 +503,9 @@ void cv::viz::InteractorStyle::OnKeyUp()
|
||||
void cv::viz::InteractorStyle::OnMouseMove()
|
||||
{
|
||||
Vec2i p(Interactor->GetEventPosition());
|
||||
MouseEvent event(MouseEvent::MouseMove, MouseEvent::NoButton, p, getAltKey(), getControlKey(), getShiftKey());
|
||||
MouseEvent event(MouseEvent::MouseMove, MouseEvent::NoButton, p, getModifiers());
|
||||
if (mouseCallback_)
|
||||
mouseCallback_(event, mouse_callback_cookie_);
|
||||
mouseCallback_(event, mouse_callback_cookie_);
|
||||
Superclass::OnMouseMove();
|
||||
}
|
||||
|
||||
@ -551,9 +514,9 @@ 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, getAltKey(), getControlKey(), getShiftKey());
|
||||
MouseEvent event(type, MouseEvent::LeftButton, p, getModifiers());
|
||||
if (mouseCallback_)
|
||||
mouseCallback_(event, mouse_callback_cookie_);
|
||||
mouseCallback_(event, mouse_callback_cookie_);
|
||||
Superclass::OnLeftButtonDown();
|
||||
}
|
||||
|
||||
@ -561,9 +524,9 @@ void cv::viz::InteractorStyle::OnLeftButtonDown()
|
||||
void cv::viz::InteractorStyle::OnLeftButtonUp()
|
||||
{
|
||||
Vec2i p(Interactor->GetEventPosition());
|
||||
MouseEvent event(MouseEvent::MouseButtonRelease, MouseEvent::LeftButton, p, getAltKey(), getControlKey(), getShiftKey());
|
||||
MouseEvent event(MouseEvent::MouseButtonRelease, MouseEvent::LeftButton, p, getModifiers());
|
||||
if (mouseCallback_)
|
||||
mouseCallback_(event, mouse_callback_cookie_);
|
||||
mouseCallback_(event, mouse_callback_cookie_);
|
||||
Superclass::OnLeftButtonUp();
|
||||
}
|
||||
|
||||
@ -571,11 +534,10 @@ void cv::viz::InteractorStyle::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, getAltKey(), getControlKey(), getShiftKey());
|
||||
MouseEvent event(type, MouseEvent::MiddleButton, p, getModifiers());
|
||||
if (mouseCallback_)
|
||||
mouseCallback_(event, mouse_callback_cookie_);
|
||||
mouseCallback_(event, mouse_callback_cookie_);
|
||||
Superclass::OnMiddleButtonDown();
|
||||
}
|
||||
|
||||
@ -583,9 +545,9 @@ void cv::viz::InteractorStyle::OnMiddleButtonDown()
|
||||
void cv::viz::InteractorStyle::OnMiddleButtonUp()
|
||||
{
|
||||
Vec2i p(Interactor->GetEventPosition());
|
||||
MouseEvent event(MouseEvent::MouseButtonRelease, MouseEvent::MiddleButton, p, getAltKey(), getControlKey(), getShiftKey());
|
||||
MouseEvent event(MouseEvent::MouseButtonRelease, MouseEvent::MiddleButton, p, getModifiers());
|
||||
if (mouseCallback_)
|
||||
mouseCallback_(event, mouse_callback_cookie_);
|
||||
mouseCallback_(event, mouse_callback_cookie_);
|
||||
Superclass::OnMiddleButtonUp();
|
||||
}
|
||||
|
||||
@ -593,11 +555,10 @@ void cv::viz::InteractorStyle::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, getAltKey(), getControlKey(), getShiftKey());
|
||||
MouseEvent event(type, MouseEvent::RightButton, p, getModifiers());
|
||||
if (mouseCallback_)
|
||||
mouseCallback_(event, mouse_callback_cookie_);
|
||||
mouseCallback_(event, mouse_callback_cookie_);
|
||||
Superclass::OnRightButtonDown();
|
||||
}
|
||||
|
||||
@ -605,9 +566,9 @@ void cv::viz::InteractorStyle::OnRightButtonDown()
|
||||
void cv::viz::InteractorStyle::OnRightButtonUp()
|
||||
{
|
||||
Vec2i p(Interactor->GetEventPosition());
|
||||
MouseEvent event(MouseEvent::MouseButtonRelease, MouseEvent::RightButton, p, getAltKey(), getControlKey(), getShiftKey());
|
||||
MouseEvent event(MouseEvent::MouseButtonRelease, MouseEvent::RightButton, p, getModifiers());
|
||||
if (mouseCallback_)
|
||||
mouseCallback_(event, mouse_callback_cookie_);
|
||||
mouseCallback_(event, mouse_callback_cookie_);
|
||||
Superclass::OnRightButtonUp();
|
||||
}
|
||||
|
||||
@ -615,12 +576,11 @@ void cv::viz::InteractorStyle::OnRightButtonUp()
|
||||
void cv::viz::InteractorStyle::OnMouseWheelForward()
|
||||
{
|
||||
Vec2i p(Interactor->GetEventPosition());
|
||||
MouseEvent event(MouseEvent::MouseScrollUp, MouseEvent::VScroll, p, getAltKey(), getControlKey(), getShiftKey());
|
||||
// If a mouse callback registered, call it!
|
||||
MouseEvent event(MouseEvent::MouseScrollUp, MouseEvent::VScroll, p, getModifiers());
|
||||
if (mouseCallback_)
|
||||
mouseCallback_(event, mouse_callback_cookie_);
|
||||
mouseCallback_(event, mouse_callback_cookie_);
|
||||
if (Interactor->GetRepeatCount() && mouseCallback_)
|
||||
mouseCallback_(event, mouse_callback_cookie_);
|
||||
mouseCallback_(event, mouse_callback_cookie_);
|
||||
|
||||
if (Interactor->GetAltKey())
|
||||
{
|
||||
@ -632,11 +592,9 @@ void cv::viz::InteractorStyle::OnMouseWheelForward()
|
||||
|
||||
cam->SetViewAngle(opening_angle);
|
||||
cam->Modified();
|
||||
CurrentRenderer->SetActiveCamera(cam);
|
||||
CurrentRenderer->ResetCameraClippingRange();
|
||||
CurrentRenderer->Modified();
|
||||
CurrentRenderer->Render();
|
||||
renderer_->Render();
|
||||
Interactor->Render();
|
||||
}
|
||||
else
|
||||
@ -647,13 +605,12 @@ void cv::viz::InteractorStyle::OnMouseWheelForward()
|
||||
void cv::viz::InteractorStyle::OnMouseWheelBackward()
|
||||
{
|
||||
Vec2i p(Interactor->GetEventPosition());
|
||||
MouseEvent event(MouseEvent::MouseScrollDown, MouseEvent::VScroll, p, getAltKey(), getControlKey(), getShiftKey());
|
||||
// If a mouse callback registered, call it!
|
||||
MouseEvent event(MouseEvent::MouseScrollDown, MouseEvent::VScroll, p, getModifiers());
|
||||
if (mouseCallback_)
|
||||
mouseCallback_(event, mouse_callback_cookie_);
|
||||
mouseCallback_(event, mouse_callback_cookie_);
|
||||
|
||||
if (Interactor->GetRepeatCount() && mouseCallback_)
|
||||
mouseCallback_(event, mouse_callback_cookie_);
|
||||
mouseCallback_(event, mouse_callback_cookie_);
|
||||
|
||||
if (Interactor->GetAltKey())
|
||||
{
|
||||
@ -665,11 +622,9 @@ void cv::viz::InteractorStyle::OnMouseWheelBackward()
|
||||
|
||||
cam->SetViewAngle(opening_angle);
|
||||
cam->Modified();
|
||||
CurrentRenderer->SetActiveCamera(cam);
|
||||
CurrentRenderer->ResetCameraClippingRange();
|
||||
CurrentRenderer->Modified();
|
||||
CurrentRenderer->Render();
|
||||
renderer_->Render();
|
||||
Interactor->Render();
|
||||
}
|
||||
else
|
||||
@ -680,13 +635,5 @@ void cv::viz::InteractorStyle::OnMouseWheelBackward()
|
||||
void cv::viz::InteractorStyle::OnTimer()
|
||||
{
|
||||
CV_Assert("Interactor style not initialized." && init_);
|
||||
CV_Assert("Renderer has not been set." && renderer_);
|
||||
renderer_->Render();
|
||||
Interactor->Render();
|
||||
}
|
||||
|
||||
namespace cv { namespace viz
|
||||
{
|
||||
//Standard VTK macro for *New()
|
||||
vtkStandardNewMacro(InteractorStyle)
|
||||
}}
|
||||
|
@ -41,9 +41,6 @@
|
||||
// * Ozan Tonkal, ozantonkal@gmail.com
|
||||
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
|
||||
//
|
||||
// OpenCV Viz module is complete rewrite of
|
||||
// PCL visualization module (www.pointclouds.org)
|
||||
//
|
||||
//M*/
|
||||
|
||||
#ifndef __OPENCV_VIZ_INTERACTOR_STYLE_H__
|
||||
@ -56,9 +53,6 @@ namespace cv
|
||||
class InteractorStyle : public vtkInteractorStyleTrackballCamera
|
||||
{
|
||||
public:
|
||||
|
||||
enum KeyboardModifier { KB_MOD_ALT, KB_MOD_CTRL, KB_MOD_SHIFT };
|
||||
|
||||
static InteractorStyle *New();
|
||||
virtual ~InteractorStyle() {}
|
||||
|
||||
@ -69,31 +63,21 @@ namespace cv
|
||||
virtual void Initialize();
|
||||
|
||||
void setWidgetActorMap(const Ptr<WidgetActorMap>& actors) { widget_actor_map_ = actors; }
|
||||
void setRenderer(vtkSmartPointer<vtkRenderer>& ren) { renderer_ = ren; }
|
||||
void registerMouseCallback(void (*callback)(const MouseEvent&, void*), void* cookie = 0);
|
||||
void registerKeyboardCallback(void (*callback)(const KeyboardEvent&, void*), void * cookie = 0);
|
||||
void saveScreenshot(const String &file);
|
||||
|
||||
/** \brief Change the default keyboard modified from ALT to a different special key.*/
|
||||
inline void setKeyboardModifier(const KeyboardModifier &modifier) { modifier_ = modifier; }
|
||||
void exportScene(const String &file);
|
||||
|
||||
private:
|
||||
/** \brief Set to true after initialization is complete. */
|
||||
bool init_;
|
||||
|
||||
vtkSmartPointer<vtkRenderer> renderer_;
|
||||
Ptr<WidgetActorMap> widget_actor_map_;
|
||||
|
||||
Vec2i win_size_;
|
||||
Vec2i win_pos_;
|
||||
Vec2i max_win_size_;
|
||||
|
||||
/** \brief A PNG writer for screenshot captures. */
|
||||
vtkSmartPointer<vtkPNGWriter> snapshot_writer_;
|
||||
|
||||
/** \brief Internal window to image filter. Needed by \a snapshot_writer_. */
|
||||
vtkSmartPointer<vtkWindowToImageFilter> wif_;
|
||||
|
||||
/** \brief Interactor style internal method. Gets called whenever a key is pressed. */
|
||||
virtual void OnChar();
|
||||
|
||||
@ -121,17 +105,13 @@ namespace cv
|
||||
/** \brief True if we're using red-blue colors for anaglyphic stereo, false if magenta-green. */
|
||||
bool stereo_anaglyph_mask_default_;
|
||||
|
||||
KeyboardModifier modifier_;
|
||||
|
||||
void (*keyboardCallback_)(const KeyboardEvent&, void*);
|
||||
void *keyboard_callback_cookie_;
|
||||
|
||||
void (*mouseCallback_)(const MouseEvent&, void*);
|
||||
void *mouse_callback_cookie_;
|
||||
|
||||
bool getAltKey();
|
||||
bool getControlKey();
|
||||
bool getShiftKey();
|
||||
int getModifiers();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -41,9 +41,6 @@
|
||||
// * Ozan Tonkal, ozantonkal@gmail.com
|
||||
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
|
||||
//
|
||||
// OpenCV Viz module is complete rewrite of
|
||||
// PCL visualization module (www.pointclouds.org)
|
||||
//
|
||||
//M*/
|
||||
|
||||
#ifndef __OPENCV_VIZ_PRECOMP_HPP__
|
||||
@ -53,6 +50,8 @@
|
||||
#include <ctime>
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <iomanip>
|
||||
#include <limits>
|
||||
|
||||
#include <vtkAppendPolyData.h>
|
||||
#include <vtkAssemblyPath.h>
|
||||
@ -94,13 +93,13 @@
|
||||
#include <vtkInteractorStyleTrackballCamera.h>
|
||||
#include <vtkProperty.h>
|
||||
#include <vtkCamera.h>
|
||||
#include <vtkObjectFactory.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>
|
||||
@ -110,12 +109,50 @@
|
||||
#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.hpp>
|
||||
#include <opencv2/viz.hpp>
|
||||
#include <opencv2/viz/widget_accessor.hpp>
|
||||
#include <opencv2/core/utility.hpp>
|
||||
|
||||
|
||||
namespace cv
|
||||
{
|
||||
namespace viz
|
||||
@ -144,11 +181,145 @@ namespace cv
|
||||
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 "viz3d_impl.hpp"
|
||||
#include "vizimpl.hpp"
|
||||
|
||||
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
1088
modules/viz/src/shapes.cpp
Normal file
1088
modules/viz/src/shapes.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -41,138 +41,63 @@
|
||||
// * Ozan Tonkal, ozantonkal@gmail.com
|
||||
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
|
||||
//
|
||||
// OpenCV Viz module is complete rewrite of
|
||||
// PCL visualization module (www.pointclouds.org)
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "precomp.hpp"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/// cv::viz::KeyboardEvent
|
||||
/// Events
|
||||
|
||||
cv::viz::KeyboardEvent::KeyboardEvent(bool _action, const String& _key_sym, unsigned char key, bool alt, bool ctrl, bool shift)
|
||||
: action_(_action), modifiers_(0), key_code_(key), key_sym_(_key_sym)
|
||||
{
|
||||
if (alt)
|
||||
modifiers_ = Alt;
|
||||
cv::viz::KeyboardEvent::KeyboardEvent(Action _action, const String& _symbol, unsigned char _code, int _modifiers)
|
||||
: action(_action), symbol(_symbol), code(_code), modifiers(_modifiers) {}
|
||||
|
||||
if (ctrl)
|
||||
modifiers_ |= Ctrl;
|
||||
|
||||
if (shift)
|
||||
modifiers_ |= Shift;
|
||||
}
|
||||
|
||||
bool cv::viz::KeyboardEvent::isAltPressed() const { return (modifiers_ & Alt) != 0; }
|
||||
bool cv::viz::KeyboardEvent::isCtrlPressed() const { return (modifiers_ & Ctrl) != 0; }
|
||||
bool cv::viz::KeyboardEvent::isShiftPressed() const { return (modifiers_ & Shift) != 0; }
|
||||
unsigned char cv::viz::KeyboardEvent::getKeyCode() const { return key_code_; }
|
||||
const cv::String& cv::viz::KeyboardEvent::getKeySym() const { return key_sym_; }
|
||||
bool cv::viz::KeyboardEvent::keyDown() const { return action_; }
|
||||
bool cv::viz::KeyboardEvent::keyUp() const { return !action_; }
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/// cv::viz::MouseEvent
|
||||
|
||||
cv::viz::MouseEvent::MouseEvent(const Type& _type, const MouseButton& _button, const Point& _p, bool alt, bool ctrl, bool shift)
|
||||
: type(_type), button(_button), pointer(_p), key_state(0)
|
||||
{
|
||||
if (alt)
|
||||
key_state = KeyboardEvent::Alt;
|
||||
|
||||
if (ctrl)
|
||||
key_state |= KeyboardEvent::Ctrl;
|
||||
|
||||
if (shift)
|
||||
key_state |= KeyboardEvent::Shift;
|
||||
}
|
||||
cv::viz::MouseEvent::MouseEvent(const Type& _type, const MouseButton& _button, const Point& _pointer, int _modifiers)
|
||||
: type(_type), button(_button), pointer(_pointer), modifiers(_modifiers) {}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/// cv::viz::Mesh3d
|
||||
|
||||
struct cv::viz::Mesh3d::loadMeshImpl
|
||||
cv::viz::Mesh cv::viz::Mesh::load(const String& file)
|
||||
{
|
||||
static cv::viz::Mesh3d loadMesh(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))
|
||||
{
|
||||
Mesh3d mesh;
|
||||
|
||||
vtkSmartPointer<vtkPLYReader> reader = vtkSmartPointer<vtkPLYReader>::New();
|
||||
reader->SetFileName(file.c_str());
|
||||
reader->Update();
|
||||
|
||||
vtkSmartPointer<vtkPolyData> poly_data = reader->GetOutput();
|
||||
CV_Assert("File does not exist or file format is not supported." && poly_data);
|
||||
|
||||
vtkSmartPointer<vtkPoints> mesh_points = poly_data->GetPoints();
|
||||
vtkIdType nr_points = mesh_points->GetNumberOfPoints();
|
||||
|
||||
mesh.cloud.create(1, nr_points, CV_32FC3);
|
||||
|
||||
Vec3f *mesh_cloud = mesh.cloud.ptr<Vec3f>();
|
||||
for (vtkIdType i = 0; i < mesh_points->GetNumberOfPoints(); i++)
|
||||
{
|
||||
Vec3d point;
|
||||
mesh_points->GetPoint(i, point.val);
|
||||
mesh_cloud[i] = point;
|
||||
}
|
||||
|
||||
// Then the color information, if any
|
||||
vtkUnsignedCharArray* poly_colors = 0;
|
||||
if (poly_data->GetPointData())
|
||||
poly_colors = vtkUnsignedCharArray::SafeDownCast(poly_data->GetPointData()->GetScalars());
|
||||
|
||||
if (poly_colors && (poly_colors->GetNumberOfComponents() == 3))
|
||||
{
|
||||
mesh.colors.create(1, nr_points, CV_8UC3);
|
||||
Vec3b *mesh_colors = mesh.colors.ptr<cv::Vec3b>();
|
||||
|
||||
for (vtkIdType i = 0; i < mesh_points->GetNumberOfPoints(); i++)
|
||||
{
|
||||
Vec3b point_color;
|
||||
poly_colors->GetTupleValue(i, point_color.val);
|
||||
|
||||
std::swap(point_color[0], point_color[2]); // RGB -> BGR
|
||||
mesh_colors[i] = point_color;
|
||||
}
|
||||
}
|
||||
else
|
||||
mesh.colors.release();
|
||||
|
||||
// Now handle the polygons
|
||||
vtkIdType* cell_points;
|
||||
vtkIdType nr_cell_points;
|
||||
vtkCellArray * mesh_polygons = poly_data->GetPolys();
|
||||
mesh_polygons->InitTraversal();
|
||||
|
||||
mesh.polygons.create(1, mesh_polygons->GetSize(), CV_32SC1);
|
||||
|
||||
int* polygons = mesh.polygons.ptr<int>();
|
||||
while (mesh_polygons->GetNextCell(nr_cell_points, cell_points))
|
||||
{
|
||||
*polygons++ = nr_cell_points;
|
||||
for (int i = 0; i < nr_cell_points; ++i)
|
||||
*polygons++ = static_cast<int>(cell_points[i]);
|
||||
}
|
||||
|
||||
return mesh;
|
||||
*poly_ptr++ = nr_cell_points;
|
||||
for (vtkIdType i = 0; i < nr_cell_points; ++i)
|
||||
*poly_ptr++ = (int)cell_points[i];
|
||||
}
|
||||
};
|
||||
|
||||
cv::viz::Mesh3d cv::viz::Mesh3d::loadMesh(const String& file)
|
||||
{
|
||||
return loadMeshImpl::loadMesh(file);
|
||||
return mesh;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/// Camera implementation
|
||||
|
||||
cv::viz::Camera::Camera(float f_x, float f_y, float c_x, float c_y, const Size &window_size)
|
||||
cv::viz::Camera::Camera(double fx, double fy, double cx, double cy, const Size &window_size)
|
||||
{
|
||||
init(f_x, f_y, c_x, c_y, window_size);
|
||||
init(fx, fy, cx, cy, window_size);
|
||||
}
|
||||
|
||||
cv::viz::Camera::Camera(const Vec2f &fov, const Size &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
|
||||
@ -183,16 +108,16 @@ cv::viz::Camera::Camera(const Vec2f &fov, const Size &window_size)
|
||||
focal_ = Vec2f(principal_point_[0] / tan(fov_[0]*0.5f), principal_point_[1] / tan(fov_[1]*0.5f));
|
||||
}
|
||||
|
||||
cv::viz::Camera::Camera(const cv::Matx33f & K, const Size &window_size)
|
||||
cv::viz::Camera::Camera(const cv::Matx33d & K, const Size &window_size)
|
||||
{
|
||||
float f_x = K(0,0);
|
||||
float f_y = K(1,1);
|
||||
float c_x = K(0,2);
|
||||
float c_y = K(1,2);
|
||||
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 Matx44f &proj, const Size &window_size)
|
||||
cv::viz::Camera::Camera(const Matx44d &proj, const Size &window_size)
|
||||
{
|
||||
CV_Assert(window_size.width > 0 && window_size.height > 0);
|
||||
|
||||
@ -205,34 +130,32 @@ cv::viz::Camera::Camera(const Matx44f &proj, const Size &window_size)
|
||||
|
||||
double epsilon = 2.2204460492503131e-16;
|
||||
|
||||
if (fabs(left-right) < epsilon) principal_point_[0] = static_cast<float>(window_size.width) * 0.5f;
|
||||
else principal_point_[0] = (left * static_cast<float>(window_size.width)) / (left - right);
|
||||
focal_[0] = -near * principal_point_[0] / left;
|
||||
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);
|
||||
|
||||
if (fabs(top-bottom) < epsilon) principal_point_[1] = static_cast<float>(window_size.height) * 0.5f;
|
||||
else principal_point_[1] = (top * static_cast<float>(window_size.height)) / (top - bottom);
|
||||
focal_[1] = near * principal_point_[1] / top;
|
||||
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]));
|
||||
fov_[0] = atan2(principal_point_[0], focal_[0]) + atan2(window_size.width-principal_point_[0], focal_[0]);
|
||||
fov_[1] = atan2(principal_point_[1], focal_[1]) + atan2(window_size.height-principal_point_[1], focal_[1]);
|
||||
|
||||
window_size_ = window_size;
|
||||
}
|
||||
|
||||
void cv::viz::Camera::init(float f_x, float f_y, float c_x, float c_y, const Size &window_size)
|
||||
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(c_x,f_x) + atan2(window_size.width-c_x,f_x));
|
||||
fov_[1] = (atan2(c_y,f_y) + atan2(window_size.height-c_y,f_y));
|
||||
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] = c_x;
|
||||
principal_point_[1] = c_y;
|
||||
principal_point_[0] = cx;
|
||||
principal_point_[1] = cy;
|
||||
|
||||
focal_[0] = f_x;
|
||||
focal_[1] = f_y;
|
||||
focal_[0] = fx;
|
||||
focal_[1] = fy;
|
||||
|
||||
window_size_ = window_size;
|
||||
}
|
||||
@ -254,7 +177,7 @@ void cv::viz::Camera::setWindowSize(const Size &window_size)
|
||||
window_size_ = window_size;
|
||||
}
|
||||
|
||||
void cv::viz::Camera::computeProjectionMatrix(Matx44f &proj) const
|
||||
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];
|
||||
@ -278,13 +201,6 @@ void cv::viz::Camera::computeProjectionMatrix(Matx44f &proj) const
|
||||
|
||||
cv::viz::Camera cv::viz::Camera::KinectCamera(const Size &window_size)
|
||||
{
|
||||
// Without distortion, RGB Camera
|
||||
// Received from http://nicolas.burrus.name/index.php/Research/KinectCalibration
|
||||
Matx33f K = Matx33f::zeros();
|
||||
K(0,0) = 5.2921508098293293e+02;
|
||||
K(0,2) = 3.2894272028759258e+02;
|
||||
K(1,1) = 5.2556393630057437e+02;
|
||||
K(1,2) = 2.6748068171871557e+02;
|
||||
K(2,2) = 1.0f;
|
||||
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);
|
||||
}
|
||||
|
@ -1,165 +0,0 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
// Authors:
|
||||
// * Ozan Tonkal, ozantonkal@gmail.com
|
||||
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
|
||||
//
|
||||
// OpenCV Viz module is complete rewrite of
|
||||
// PCL visualization module (www.pointclouds.org)
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "precomp.hpp"
|
||||
|
||||
cv::Affine3f cv::viz::makeTransformToGlobal(const Vec3f& axis_x, const Vec3f& axis_y, const Vec3f& axis_z, const Vec3f& origin)
|
||||
{
|
||||
Affine3f::Mat3 R(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 Affine3f(R, origin);
|
||||
}
|
||||
|
||||
cv::Affine3f cv::viz::makeCameraPose(const Vec3f& position, const Vec3f& focal_point, const Vec3f& y_dir)
|
||||
{
|
||||
// Compute the transformation matrix for drawing the camera frame in a scene
|
||||
Vec3f n = normalize(focal_point - position);
|
||||
Vec3f u = normalize(y_dir.cross(n));
|
||||
Vec3f v = n.cross(u);
|
||||
|
||||
return makeTransformToGlobal(u, v, n, position);
|
||||
}
|
||||
|
||||
vtkSmartPointer<vtkMatrix4x4> cv::viz::convertToVtkMatrix(const cv::Matx44f &m)
|
||||
{
|
||||
vtkSmartPointer<vtkMatrix4x4> vtk_matrix = vtkSmartPointer<vtkMatrix4x4>::New();
|
||||
for (int i = 0; i < 4; i++)
|
||||
for (int k = 0; k < 4; k++)
|
||||
vtk_matrix->SetElement(i, k, m(i, k));
|
||||
return vtk_matrix;
|
||||
}
|
||||
|
||||
cv::Matx44f cv::viz::convertToMatx(const vtkSmartPointer<vtkMatrix4x4>& vtk_matrix)
|
||||
{
|
||||
cv::Matx44f m;
|
||||
for (int i = 0; i < 4; i++)
|
||||
for (int k = 0; k < 4; k++)
|
||||
m(i, k) = vtk_matrix->GetElement(i, k);
|
||||
return m;
|
||||
}
|
||||
|
||||
namespace cv { namespace viz
|
||||
{
|
||||
template<typename _Tp> Vec<_Tp, 3>* vtkpoints_data(vtkSmartPointer<vtkPoints>& points);
|
||||
|
||||
template<> Vec3f* vtkpoints_data<float>(vtkSmartPointer<vtkPoints>& points)
|
||||
{
|
||||
CV_Assert(points->GetDataType() == VTK_FLOAT);
|
||||
vtkDataArray *data = points->GetData();
|
||||
float *pointer = static_cast<vtkFloatArray*>(data)->GetPointer(0);
|
||||
return reinterpret_cast<Vec3f*>(pointer);
|
||||
}
|
||||
|
||||
template<> Vec3d* vtkpoints_data<double>(vtkSmartPointer<vtkPoints>& points)
|
||||
{
|
||||
CV_Assert(points->GetDataType() == VTK_DOUBLE);
|
||||
vtkDataArray *data = points->GetData();
|
||||
double *pointer = static_cast<vtkDoubleArray*>(data)->GetPointer(0);
|
||||
return reinterpret_cast<Vec3d*>(pointer);
|
||||
}
|
||||
}}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// 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::get(const String &window_name) { return Viz3d (window_name); }
|
||||
void cv::viz::unregisterAllWindows() { VizStorage::unregisterAll(); }
|
@ -41,9 +41,6 @@
|
||||
// * 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"
|
||||
@ -104,6 +101,7 @@ void cv::viz::Viz3d::release()
|
||||
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); }
|
||||
@ -111,18 +109,21 @@ void cv::viz::Viz3d::registerKeyboardCallback(KeyboardCallback callback, void* c
|
||||
void cv::viz::Viz3d::registerMouseCallback(MouseCallback callback, void* cookie)
|
||||
{ impl_->registerMouseCallback(callback, cookie); }
|
||||
|
||||
void cv::viz::Viz3d::showWidget(const String &id, const Widget &widget, const Affine3f &pose) { impl_->showWidget(id, widget, pose); }
|
||||
void cv::viz::Viz3d::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::setWidgetPose(const String &id, const Affine3f &pose) { impl_->setWidgetPose(id, pose); }
|
||||
void cv::viz::Viz3d::updateWidgetPose(const String &id, const Affine3f &pose) { impl_->updateWidgetPose(id, pose); }
|
||||
cv::Affine3f cv::viz::Viz3d::getWidgetPose(const String &id) const { return impl_->getWidgetPose(id); }
|
||||
|
||||
void cv::viz::Viz3d::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 Affine3f &pose) { impl_->setViewerPose(pose); }
|
||||
cv::Affine3f cv::viz::Viz3d::getViewerPose() { return impl_->getViewerPose(); }
|
||||
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(); }
|
||||
@ -131,17 +132,17 @@ void cv::viz::Viz3d::convertToWindowCoordinates(const Point3d &pt, Point3d &wind
|
||||
void cv::viz::Viz3d::converTo3DRay(const Point3d &window_coord, Point3d &origin, Vec3d &direction) { impl_->converTo3DRay(window_coord, origin, direction); }
|
||||
|
||||
cv::Size cv::viz::Viz3d::getWindowSize() const { return impl_->getWindowSize(); }
|
||||
void cv::viz::Viz3d::setWindowSize(const Size &window_size) { impl_->setWindowSize(window_size.width, window_size.height); }
|
||||
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(int x, int y) { impl_->setWindowPosition(x,y); }
|
||||
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) { impl_->setBackgroundColor(color); }
|
||||
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::setDesiredUpdateRate(double rate) { impl_->setDesiredUpdateRate(rate); }
|
||||
double cv::viz::Viz3d::getDesiredUpdateRate() { return impl_->getDesiredUpdateRate(); }
|
||||
|
||||
void cv::viz::Viz3d::setRepresentation(int representation) { impl_->setRepresentation(representation); }
|
||||
|
@ -1,368 +0,0 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
// Authors:
|
||||
// * Ozan Tonkal, ozantonkal@gmail.com
|
||||
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
|
||||
//
|
||||
// OpenCV Viz module is complete rewrite of
|
||||
// PCL visualization module (www.pointclouds.org)
|
||||
//
|
||||
//M*/
|
||||
|
||||
#ifndef __OPENCV_VIZ_VIZ3D_IMPL_HPP__
|
||||
#define __OPENCV_VIZ_VIZ3D_IMPL_HPP__
|
||||
|
||||
struct cv::viz::Viz3d::VizImpl
|
||||
{
|
||||
public:
|
||||
typedef Viz3d::KeyboardCallback KeyboardCallback;
|
||||
typedef Viz3d::MouseCallback MouseCallback;
|
||||
|
||||
int ref_counter;
|
||||
|
||||
VizImpl(const String &name);
|
||||
virtual ~VizImpl();
|
||||
|
||||
void showWidget(const String &id, const Widget &widget, const Affine3f &pose = Affine3f::Identity());
|
||||
void removeWidget(const String &id);
|
||||
Widget getWidget(const String &id) const;
|
||||
void removeAllWidgets();
|
||||
|
||||
void setWidgetPose(const String &id, const Affine3f &pose);
|
||||
void updateWidgetPose(const String &id, const Affine3f &pose);
|
||||
Affine3f getWidgetPose(const String &id) const;
|
||||
|
||||
void setDesiredUpdateRate(double rate);
|
||||
double getDesiredUpdateRate();
|
||||
|
||||
/** \brief Returns true when the user tried to close the window */
|
||||
bool wasStopped() const { if (interactor_ != NULL) return (stopped_); else return true; }
|
||||
|
||||
/** \brief Set the stopped flag back to false */
|
||||
void resetStoppedFlag() { if (interactor_ != NULL) stopped_ = false; }
|
||||
|
||||
/** \brief Stop the interaction and close the visualizaton window. */
|
||||
void close()
|
||||
{
|
||||
stopped_ = true;
|
||||
if (interactor_)
|
||||
{
|
||||
interactor_->GetRenderWindow()->Finalize();
|
||||
interactor_->TerminateApp(); // This tends to close the window...
|
||||
}
|
||||
}
|
||||
|
||||
void setRepresentation(int representation);
|
||||
|
||||
void setCamera(const Camera &camera);
|
||||
Camera getCamera() const;
|
||||
|
||||
/** \brief Reset the camera to a given widget */
|
||||
void resetCameraViewpoint(const String& id);
|
||||
void resetCamera();
|
||||
|
||||
void setViewerPose(const Affine3f &pose);
|
||||
Affine3f getViewerPose();
|
||||
|
||||
void convertToWindowCoordinates(const Point3d &pt, Point3d &window_coord);
|
||||
void converTo3DRay(const Point3d &window_coord, Point3d &origin, Vec3d &direction);
|
||||
|
||||
void saveScreenshot(const String &file);
|
||||
void setWindowPosition(int x, int y);
|
||||
Size getWindowSize() const;
|
||||
void setWindowSize(int xw, int yw);
|
||||
void setFullScreen(bool mode);
|
||||
String getWindowName() const;
|
||||
void setBackgroundColor(const Color& color);
|
||||
|
||||
void spin();
|
||||
void spinOnce(int time = 1, bool force_redraw = false);
|
||||
|
||||
void registerKeyboardCallback(KeyboardCallback callback, void* cookie = 0);
|
||||
void registerMouseCallback(MouseCallback callback, void* cookie = 0);
|
||||
|
||||
private:
|
||||
vtkSmartPointer<vtkRenderWindowInteractor> interactor_;
|
||||
|
||||
struct ExitMainLoopTimerCallback : public vtkCommand
|
||||
{
|
||||
static ExitMainLoopTimerCallback* New() { return new ExitMainLoopTimerCallback; }
|
||||
virtual void Execute(vtkObject* vtkNotUsed(caller), unsigned long event_id, void* call_data)
|
||||
{
|
||||
if (event_id != vtkCommand::TimerEvent)
|
||||
return;
|
||||
|
||||
int timer_id = *reinterpret_cast<int*>(call_data);
|
||||
if (timer_id != right_timer_id)
|
||||
return;
|
||||
|
||||
// Stop vtk loop and send notification to app to wake it up
|
||||
viz_->interactor_->TerminateApp();
|
||||
}
|
||||
int right_timer_id;
|
||||
VizImpl* viz_;
|
||||
};
|
||||
|
||||
struct ExitCallback : public vtkCommand
|
||||
{
|
||||
static ExitCallback* New() { return new ExitCallback; }
|
||||
virtual void Execute(vtkObject*, unsigned long event_id, void*)
|
||||
{
|
||||
if (event_id == vtkCommand::ExitEvent)
|
||||
{
|
||||
viz_->stopped_ = true;
|
||||
viz_->interactor_->GetRenderWindow()->Finalize();
|
||||
viz_->interactor_->TerminateApp();
|
||||
}
|
||||
}
|
||||
VizImpl* viz_;
|
||||
};
|
||||
|
||||
/** \brief Set to false if the interaction loop is running. */
|
||||
bool stopped_;
|
||||
|
||||
double s_lastDone_;
|
||||
|
||||
/** \brief Global timer ID. Used in destructor only. */
|
||||
int timer_id_;
|
||||
|
||||
/** \brief Callback object enabling us to leave the main loop, when a timer fires. */
|
||||
vtkSmartPointer<ExitMainLoopTimerCallback> exit_main_loop_timer_callback_;
|
||||
vtkSmartPointer<ExitCallback> exit_callback_;
|
||||
|
||||
vtkSmartPointer<vtkRenderer> renderer_;
|
||||
vtkSmartPointer<vtkRenderWindow> window_;
|
||||
|
||||
/** \brief The render window interactor style. */
|
||||
vtkSmartPointer<InteractorStyle> style_;
|
||||
|
||||
/** \brief Internal list with actor pointers and name IDs for all widget actors */
|
||||
cv::Ptr<WidgetActorMap> widget_actor_map_;
|
||||
|
||||
/** \brief Boolean that holds whether or not the camera parameters were manually initialized*/
|
||||
bool camera_set_;
|
||||
|
||||
bool removeActorFromRenderer(const vtkSmartPointer<vtkProp> &actor);
|
||||
};
|
||||
|
||||
|
||||
|
||||
namespace cv
|
||||
{
|
||||
namespace viz
|
||||
{
|
||||
vtkSmartPointer<vtkMatrix4x4> convertToVtkMatrix(const cv::Matx44f &m);
|
||||
cv::Matx44f convertToMatx(const vtkSmartPointer<vtkMatrix4x4>& vtk_matrix);
|
||||
|
||||
struct NanFilter
|
||||
{
|
||||
template<typename _Tp, typename _Msk>
|
||||
struct Impl
|
||||
{
|
||||
typedef Vec<_Tp, 3> _Out;
|
||||
|
||||
static _Out* copy(const Mat& source, _Out* output, const Mat& nan_mask)
|
||||
{
|
||||
CV_Assert(DataDepth<_Tp>::value == source.depth() && source.size() == nan_mask.size());
|
||||
CV_Assert(nan_mask.channels() == 3 || nan_mask.channels() == 4);
|
||||
CV_DbgAssert(DataDepth<_Msk>::value == nan_mask.depth());
|
||||
|
||||
int s_chs = source.channels();
|
||||
int m_chs = nan_mask.channels();
|
||||
|
||||
for (int y = 0; y < source.rows; ++y)
|
||||
{
|
||||
const _Tp* srow = source.ptr<_Tp>(y);
|
||||
const _Msk* mrow = nan_mask.ptr<_Msk>(y);
|
||||
|
||||
for (int x = 0; x < source.cols; ++x, srow += s_chs, mrow += m_chs)
|
||||
if (!isNan(mrow[0]) && !isNan(mrow[1]) && !isNan(mrow[2]))
|
||||
*output++ = _Out(srow);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
static _Out* copyColor(const Mat& source, _Out* output, const Mat& nan_mask)
|
||||
{
|
||||
CV_Assert(DataDepth<_Tp>::value == source.depth() && source.size() == nan_mask.size());
|
||||
CV_Assert(nan_mask.channels() == 3 || nan_mask.channels() == 4);
|
||||
CV_DbgAssert(DataDepth<_Msk>::value == nan_mask.depth());
|
||||
|
||||
int s_chs = source.channels();
|
||||
int m_chs = nan_mask.channels();
|
||||
|
||||
for (int y = 0; y < source.rows; ++y)
|
||||
{
|
||||
const _Tp* srow = source.ptr<_Tp>(y);
|
||||
const _Msk* mrow = nan_mask.ptr<_Msk>(y);
|
||||
|
||||
for (int x = 0; x < source.cols; ++x, srow += s_chs, mrow += m_chs)
|
||||
if (!isNan(mrow[0]) && !isNan(mrow[1]) && !isNan(mrow[2]))
|
||||
{
|
||||
*output = _Out(srow);
|
||||
std::swap((*output)[0], (*output)[2]); // BGR -> RGB
|
||||
++output;
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename _Tp>
|
||||
static inline Vec<_Tp, 3>* copy(const Mat& source, Vec<_Tp, 3>* output, const Mat& nan_mask)
|
||||
{
|
||||
CV_Assert(nan_mask.depth() == CV_32F || nan_mask.depth() == CV_64F);
|
||||
|
||||
typedef Vec<_Tp, 3>* (*copy_func)(const Mat&, Vec<_Tp, 3>*, const Mat&);
|
||||
const static copy_func table[2] = { &NanFilter::Impl<_Tp, float>::copy, &NanFilter::Impl<_Tp, double>::copy };
|
||||
|
||||
return table[nan_mask.depth() - 5](source, output, nan_mask);
|
||||
}
|
||||
|
||||
template<typename _Tp>
|
||||
static inline Vec<_Tp, 3>* copyColor(const Mat& source, Vec<_Tp, 3>* output, const Mat& nan_mask)
|
||||
{
|
||||
CV_Assert(nan_mask.depth() == CV_32F || nan_mask.depth() == CV_64F);
|
||||
|
||||
typedef Vec<_Tp, 3>* (*copy_func)(const Mat&, Vec<_Tp, 3>*, const Mat&);
|
||||
const static copy_func table[2] = { &NanFilter::Impl<_Tp, float>::copyColor, &NanFilter::Impl<_Tp, double>::copyColor };
|
||||
|
||||
return table[nan_mask.depth() - 5](source, output, nan_mask);
|
||||
}
|
||||
};
|
||||
|
||||
struct ApplyAffine
|
||||
{
|
||||
const Affine3f& affine_;
|
||||
ApplyAffine(const Affine3f& affine) : affine_(affine) {}
|
||||
|
||||
template<typename _Tp> Point3_<_Tp> operator()(const Point3_<_Tp>& p) const { return affine_ * p; }
|
||||
|
||||
template<typename _Tp> Vec<_Tp, 3> operator()(const Vec<_Tp, 3>& v) const
|
||||
{
|
||||
const float* m = affine_.matrix.val;
|
||||
|
||||
Vec<_Tp, 3> result;
|
||||
result[0] = (_Tp)(m[0] * v[0] + m[1] * v[1] + m[ 2] * v[2] + m[ 3]);
|
||||
result[1] = (_Tp)(m[4] * v[0] + m[5] * v[1] + m[ 6] * v[2] + m[ 7]);
|
||||
result[2] = (_Tp)(m[8] * v[0] + m[9] * v[1] + m[10] * v[2] + m[11]);
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
ApplyAffine(const ApplyAffine&);
|
||||
ApplyAffine& operator=(const ApplyAffine&);
|
||||
};
|
||||
|
||||
|
||||
inline Color vtkcolor(const Color& color)
|
||||
{
|
||||
Color scaled_color = color * (1.0/255.0);
|
||||
std::swap(scaled_color[0], scaled_color[2]);
|
||||
return scaled_color;
|
||||
}
|
||||
|
||||
inline Vec3d vtkpoint(const Point3f& point) { return Vec3d(point.x, point.y, point.z); }
|
||||
template<typename _Tp> inline _Tp normalized(const _Tp& v) { return v * 1/cv::norm(v); }
|
||||
|
||||
struct ConvertToVtkImage
|
||||
{
|
||||
struct Impl
|
||||
{
|
||||
static void copyImageMultiChannel(const Mat &image, vtkSmartPointer<vtkImageData> output)
|
||||
{
|
||||
int i_chs = image.channels();
|
||||
|
||||
for (int i = 0; i < image.rows; ++i)
|
||||
{
|
||||
const unsigned char * irows = image.ptr<unsigned char>(i);
|
||||
for (int j = 0; j < image.cols; ++j, irows += i_chs)
|
||||
{
|
||||
unsigned char * vrows = static_cast<unsigned char *>(output->GetScalarPointer(j,i,0));
|
||||
memcpy(vrows, irows, i_chs);
|
||||
std::swap(vrows[0], vrows[2]); // BGR -> RGB
|
||||
}
|
||||
}
|
||||
output->Modified();
|
||||
}
|
||||
|
||||
static void copyImageSingleChannel(const Mat &image, vtkSmartPointer<vtkImageData> output)
|
||||
{
|
||||
for (int i = 0; i < image.rows; ++i)
|
||||
{
|
||||
const unsigned char * irows = image.ptr<unsigned char>(i);
|
||||
for (int j = 0; j < image.cols; ++j, ++irows)
|
||||
{
|
||||
unsigned char * vrows = static_cast<unsigned char *>(output->GetScalarPointer(j,i,0));
|
||||
*vrows = *irows;
|
||||
}
|
||||
}
|
||||
output->Modified();
|
||||
}
|
||||
};
|
||||
|
||||
static void convert(const Mat &image, vtkSmartPointer<vtkImageData> output)
|
||||
{
|
||||
// Create the vtk image
|
||||
output->SetDimensions(image.cols, image.rows, 1);
|
||||
#if VTK_MAJOR_VERSION <= 5
|
||||
output->SetNumberOfScalarComponents(image.channels());
|
||||
output->SetScalarTypeToUnsignedChar();
|
||||
output->AllocateScalars();
|
||||
#else
|
||||
output->AllocateScalars(VTK_UNSIGNED_CHAR, image.channels());
|
||||
#endif
|
||||
|
||||
int i_chs = image.channels();
|
||||
if (i_chs > 1)
|
||||
{
|
||||
// Multi channel images are handled differently because of BGR <-> RGB
|
||||
Impl::copyImageMultiChannel(image, output);
|
||||
}
|
||||
else
|
||||
{
|
||||
Impl::copyImageSingleChannel(image, output);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
312
modules/viz/src/vizcore.cpp
Normal file
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.getObj();
|
||||
|
||||
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();
|
||||
}
|
@ -41,94 +41,143 @@
|
||||
// * 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"
|
||||
|
||||
vtkRenderWindowInteractor* vtkRenderWindowInteractorFixNew();
|
||||
|
||||
#if 1 || !defined __APPLE__
|
||||
vtkRenderWindowInteractor* vtkRenderWindowInteractorFixNew()
|
||||
{
|
||||
return vtkRenderWindowInteractor::New();
|
||||
}
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
cv::viz::Viz3d::VizImpl::VizImpl(const String &name)
|
||||
: s_lastDone_(0.0), style_(vtkSmartPointer<cv::viz::InteractorStyle>::New()), widget_actor_map_(new WidgetActorMap)
|
||||
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 a RendererWindow
|
||||
// Create render window
|
||||
window_ = vtkSmartPointer<vtkRenderWindow>::New();
|
||||
|
||||
// Set the window size as 1/2 of the screen size
|
||||
cv::Vec2i window_size = cv::Vec2i(window_->GetScreenSize()) / 2;
|
||||
window_->SetSize(window_size.val);
|
||||
|
||||
window_->AddRenderer(renderer_);
|
||||
|
||||
// Create the interactor style
|
||||
style_->Initialize();
|
||||
style_->setRenderer(renderer_);
|
||||
style_ = vtkSmartPointer<InteractorStyle>::New();
|
||||
style_->setWidgetActorMap(widget_actor_map_);
|
||||
style_->UseTimersOn();
|
||||
style_->Initialize();
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
interactor_ = vtkSmartPointer<vtkRenderWindowInteractor>::Take(vtkRenderWindowInteractorFixNew());
|
||||
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();
|
||||
|
||||
interactor_->SetRenderWindow(window_);
|
||||
interactor_->SetInteractorStyle(style_);
|
||||
interactor_->SetDesiredUpdateRate(30.0);
|
||||
|
||||
// Initialize and create timer, also create window
|
||||
interactor_->Initialize();
|
||||
timer_id_ = interactor_->CreateRepeatingTimer(5000L);
|
||||
|
||||
// Set a simple PointPicker
|
||||
//vtkSmartPointer<vtkPointPicker> pp = vtkSmartPointer<vtkPointPicker>::New();
|
||||
//pp->SetTolerance(pp->GetTolerance() * 2);
|
||||
//interactor_->SetPicker(pp);
|
||||
|
||||
exit_main_loop_timer_callback_ = vtkSmartPointer<ExitMainLoopTimerCallback>::New();
|
||||
exit_main_loop_timer_callback_->viz_ = this;
|
||||
exit_main_loop_timer_callback_->right_timer_id = -1;
|
||||
interactor_->AddObserver(vtkCommand::TimerEvent, exit_main_loop_timer_callback_);
|
||||
|
||||
exit_callback_ = vtkSmartPointer<ExitCallback>::New();
|
||||
exit_callback_->viz_ = this;
|
||||
interactor_->AddObserver(vtkCommand::ExitEvent, exit_callback_);
|
||||
|
||||
resetStoppedFlag();
|
||||
|
||||
|
||||
//////////////////////////////
|
||||
String window_name = VizStorage::generateWindowName(name);
|
||||
window_->SetWindowName(window_name.c_str());
|
||||
window_->Render();
|
||||
window_->SetWindowName(window_name_.c_str());
|
||||
interactor_->Start();
|
||||
interactor_ = 0;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
cv::viz::Viz3d::VizImpl::~VizImpl()
|
||||
void cv::viz::Viz3d::VizImpl::spinOnce(int time, bool force_redraw)
|
||||
{
|
||||
if (interactor_)
|
||||
interactor_->DestroyTimer(timer_id_);
|
||||
if (renderer_)
|
||||
renderer_->Clear();
|
||||
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 Affine3f &pose)
|
||||
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();
|
||||
@ -142,7 +191,7 @@ void cv::viz::Viz3d::VizImpl::showWidget(const String &id, const Widget &widget,
|
||||
if (actor)
|
||||
{
|
||||
// If the actor is 3D, apply pose
|
||||
vtkSmartPointer<vtkMatrix4x4> matrix = convertToVtkMatrix(pose.matrix);
|
||||
vtkSmartPointer<vtkMatrix4x4> matrix = vtkmatrix(pose.matrix);
|
||||
actor->SetUserMatrix(matrix);
|
||||
actor->Modified();
|
||||
}
|
||||
@ -180,7 +229,7 @@ cv::viz::Widget cv::viz::Viz3d::VizImpl::getWidget(const String &id) const
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::Viz3d::VizImpl::setWidgetPose(const String &id, const Affine3f &pose)
|
||||
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();
|
||||
@ -189,13 +238,13 @@ void cv::viz::Viz3d::VizImpl::setWidgetPose(const String &id, const Affine3f &po
|
||||
vtkProp3D *actor = vtkProp3D::SafeDownCast(wam_itr->second);
|
||||
CV_Assert("Widget is not 3D." && actor);
|
||||
|
||||
vtkSmartPointer<vtkMatrix4x4> matrix = convertToVtkMatrix(pose.matrix);
|
||||
vtkSmartPointer<vtkMatrix4x4> matrix = vtkmatrix(pose.matrix);
|
||||
actor->SetUserMatrix(matrix);
|
||||
actor->Modified();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::Viz3d::VizImpl::updateWidgetPose(const String &id, const Affine3f &pose)
|
||||
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();
|
||||
@ -210,16 +259,15 @@ void cv::viz::Viz3d::VizImpl::updateWidgetPose(const String &id, const Affine3f
|
||||
setWidgetPose(id, pose);
|
||||
return ;
|
||||
}
|
||||
Matx44f matrix_cv = convertToMatx(matrix);
|
||||
Affine3f updated_pose = pose * Affine3f(matrix_cv);
|
||||
matrix = convertToVtkMatrix(updated_pose.matrix);
|
||||
Affine3d updated_pose = pose * Affine3d(*matrix->Element);
|
||||
matrix = vtkmatrix(updated_pose.matrix);
|
||||
|
||||
actor->SetUserMatrix(matrix);
|
||||
actor->Modified();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
cv::Affine3f cv::viz::Viz3d::VizImpl::getWidgetPose(const String &id) const
|
||||
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();
|
||||
@ -228,24 +276,7 @@ cv::Affine3f cv::viz::Viz3d::VizImpl::getWidgetPose(const String &id) const
|
||||
vtkProp3D *actor = vtkProp3D::SafeDownCast(wam_itr->second);
|
||||
CV_Assert("Widget is not 3D." && actor);
|
||||
|
||||
vtkSmartPointer<vtkMatrix4x4> matrix = actor->GetUserMatrix();
|
||||
Matx44f matrix_cv = convertToMatx(matrix);
|
||||
return Affine3f(matrix_cv);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::Viz3d::VizImpl::setDesiredUpdateRate(double rate)
|
||||
{
|
||||
if (interactor_)
|
||||
interactor_->SetDesiredUpdateRate(rate);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
double cv::viz::Viz3d::VizImpl::getDesiredUpdateRate()
|
||||
{
|
||||
if (interactor_)
|
||||
return interactor_->GetDesiredUpdateRate();
|
||||
return 0.0;
|
||||
return Affine3d(*actor->GetUserMatrix()->Element);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -258,37 +289,6 @@ void cv::viz::Viz3d::VizImpl::registerMouseCallback(MouseCallback callback, void
|
||||
void cv::viz::Viz3d::VizImpl::registerKeyboardCallback(KeyboardCallback callback, void* cookie)
|
||||
{ style_->registerKeyboardCallback(callback, cookie); }
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::Viz3d::VizImpl::spin()
|
||||
{
|
||||
resetStoppedFlag();
|
||||
window_->Render();
|
||||
interactor_->Start();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::Viz3d::VizImpl::spinOnce(int time, bool force_redraw)
|
||||
{
|
||||
resetStoppedFlag();
|
||||
|
||||
if (time <= 0)
|
||||
time = 1;
|
||||
|
||||
if (force_redraw)
|
||||
interactor_->Render();
|
||||
|
||||
double s_now_ = cv::getTickCount() / cv::getTickFrequency();
|
||||
if (s_lastDone_ > s_now_)
|
||||
s_lastDone_ = s_now_;
|
||||
|
||||
if ((s_now_ - s_lastDone_) > (1.0 / interactor_->GetDesiredUpdateRate()))
|
||||
{
|
||||
exit_main_loop_timer_callback_->right_timer_id = interactor_->CreateRepeatingTimer(time);
|
||||
interactor_->Start();
|
||||
interactor_->DestroyTimer(exit_main_loop_timer_callback_->right_timer_id);
|
||||
s_lastDone_ = s_now_;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::Viz3d::VizImpl::removeAllWidgets()
|
||||
@ -296,50 +296,98 @@ 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(const vtkSmartPointer<vtkProp> &actor)
|
||||
bool cv::viz::Viz3d::VizImpl::removeActorFromRenderer(vtkSmartPointer<vtkProp> actor)
|
||||
{
|
||||
vtkProp* actor_to_remove = vtkProp::SafeDownCast(actor);
|
||||
|
||||
vtkPropCollection* actors = renderer_->GetViewProps();
|
||||
actors->InitTraversal();
|
||||
vtkProp* current_actor = NULL;
|
||||
while ((current_actor = actors->GetNextProp()) != NULL)
|
||||
{
|
||||
if (current_actor != actor_to_remove)
|
||||
continue;
|
||||
renderer_->RemoveActor(actor);
|
||||
return true;
|
||||
}
|
||||
if (current_actor == actor)
|
||||
{
|
||||
renderer_->RemoveActor(actor);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::Viz3d::VizImpl::setBackgroundColor(const Color& color)
|
||||
void cv::viz::Viz3d::VizImpl::setBackgroundColor(const Color& color, const Color& color2)
|
||||
{
|
||||
Color c = vtkcolor(color);
|
||||
renderer_->SetBackground(c.val);
|
||||
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)
|
||||
{
|
||||
vtkCamera& active_camera = *renderer_->GetActiveCamera();
|
||||
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);
|
||||
|
||||
Matx44f proj_mat;
|
||||
Matx44d proj_mat;
|
||||
camera.computeProjectionMatrix(proj_mat);
|
||||
|
||||
// Use the intrinsic parameters of the camera to simulate more realistically
|
||||
Matx44f old_proj_mat = convertToMatx(active_camera.GetProjectionTransformMatrix(aspect_ratio, -1.0, 1.0));
|
||||
vtkTransform *transform = vtkTransform::New();
|
||||
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
|
||||
transform->SetMatrix(convertToVtkMatrix(proj_mat * old_proj_mat.inv()));
|
||||
active_camera.SetUserTransform(transform);
|
||||
transform->Delete();
|
||||
vtkSmartPointer<vtkTransform> transform = vtkSmartPointer<vtkTransform>::New();
|
||||
transform->SetMatrix(vtkmatrix(proj_mat * old_proj_mat.inv()));
|
||||
active_camera->SetUserTransform(transform);
|
||||
|
||||
renderer_->ResetCameraClippingRange();
|
||||
renderer_->Render();
|
||||
@ -348,44 +396,42 @@ void cv::viz::Viz3d::VizImpl::setCamera(const Camera &camera)
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
cv::viz::Camera cv::viz::Viz3d::VizImpl::getCamera() const
|
||||
{
|
||||
vtkCamera& active_camera = *renderer_->GetActiveCamera();
|
||||
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;
|
||||
|
||||
Matx44f proj_matrix = convertToMatx(active_camera.GetProjectionTransformMatrix(aspect_ratio, -1.0f, 1.0f));
|
||||
Camera camera(proj_matrix, window_size);
|
||||
return camera;
|
||||
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 Affine3f &pose)
|
||||
void cv::viz::Viz3d::VizImpl::setViewerPose(const Affine3d &pose)
|
||||
{
|
||||
vtkCamera& camera = *renderer_->GetActiveCamera();
|
||||
|
||||
// Position = extrinsic translation
|
||||
cv::Vec3f pos_vec = pose.translation();
|
||||
cv::Vec3d pos_vec = pose.translation();
|
||||
|
||||
// Rotate the view vector
|
||||
cv::Matx33f rotation = pose.rotation();
|
||||
cv::Vec3f y_axis(0.f, 1.f, 0.f);
|
||||
cv::Vec3f up_vec(rotation * y_axis);
|
||||
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::Vec3f z_axis(0.f, 0.f, 1.f);
|
||||
cv::Vec3f focal_vec = pos_vec + rotation * z_axis;
|
||||
cv::Vec3d z_axis(0.0, 0.0, 1.0);
|
||||
cv::Vec3d focal_vec = pos_vec + rotation * z_axis;
|
||||
|
||||
camera.SetPosition(pos_vec[0], pos_vec[1], pos_vec[2]);
|
||||
camera.SetFocalPoint(focal_vec[0], focal_vec[1], focal_vec[2]);
|
||||
camera.SetViewUp(up_vec[0], up_vec[1], up_vec[2]);
|
||||
camera.SetPosition(pos_vec.val);
|
||||
camera.SetFocalPoint(focal_vec.val);
|
||||
camera.SetViewUp(up_vec.val);
|
||||
|
||||
renderer_->ResetCameraClippingRange();
|
||||
renderer_->Render();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
cv::Affine3f cv::viz::Viz3d::VizImpl::getViewerPose()
|
||||
cv::Affine3d cv::viz::Viz3d::VizImpl::getViewerPose()
|
||||
{
|
||||
vtkCamera& camera = *renderer_->GetActiveCamera();
|
||||
|
||||
@ -397,20 +443,7 @@ cv::Affine3f cv::viz::Viz3d::VizImpl::getViewerPose()
|
||||
Vec3d z_axis = normalized(focal - pos);
|
||||
Vec3d x_axis = normalized(y_axis.cross(z_axis));
|
||||
|
||||
cv::Matx33d R;
|
||||
R(0, 0) = x_axis[0];
|
||||
R(0, 1) = y_axis[0];
|
||||
R(0, 2) = z_axis[0];
|
||||
|
||||
R(1, 0) = x_axis[1];
|
||||
R(1, 1) = y_axis[1];
|
||||
R(1, 2) = z_axis[1];
|
||||
|
||||
R(2, 0) = x_axis[2];
|
||||
R(2, 1) = y_axis[2];
|
||||
R(2, 2) = z_axis[2];
|
||||
|
||||
return cv::Affine3f(R, pos);
|
||||
return makeTransformToGlobal(x_axis, y_axis, z_axis, pos);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -426,10 +459,7 @@ void cv::viz::Viz3d::VizImpl::converTo3DRay(const Point3d &window_coord, Point3d
|
||||
{
|
||||
Vec4d world_pt;
|
||||
vtkInteractorObserver::ComputeDisplayToWorld(renderer_, window_coord.x, window_coord.y, window_coord.z, world_pt.val);
|
||||
|
||||
vtkCamera &active_camera = *renderer_->GetActiveCamera();
|
||||
Vec3d cam_pos;
|
||||
active_camera.GetPosition(cam_pos.val);
|
||||
Vec3d cam_pos(renderer_->GetActiveCamera()->GetPosition());
|
||||
origin = cam_pos;
|
||||
direction = normalize(Vec3d(world_pt.val) - cam_pos);
|
||||
}
|
||||
@ -504,21 +534,9 @@ void cv::viz::Viz3d::VizImpl::setRepresentation(int representation)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::Viz3d::VizImpl::setFullScreen(bool mode)
|
||||
{
|
||||
if (window_)
|
||||
window_->SetFullScreen(mode);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
cv::String cv::viz::Viz3d::VizImpl::getWindowName() const
|
||||
{
|
||||
return (window_ ? window_->GetWindowName() : "");
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void cv::viz::Viz3d::VizImpl::setWindowPosition(int x, int y) { window_->SetPosition(x, y); }
|
||||
void cv::viz::Viz3d::VizImpl::setWindowSize(int xw, int yw) { window_->SetSize(xw, yw); }
|
||||
cv::Size cv::viz::Viz3d::VizImpl::getWindowSize() const { return Size(window_->GetSize()[0], window_->GetSize()[1]); }
|
||||
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
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
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
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.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
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
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.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
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
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
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";
|
||||
}
|
@ -38,12 +38,42 @@
|
||||
// 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"
|
||||
#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
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
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
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
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
|
@ -41,9 +41,6 @@
|
||||
// * 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"
|
||||
@ -55,7 +52,6 @@ class cv::viz::Widget::Impl
|
||||
{
|
||||
public:
|
||||
vtkSmartPointer<vtkProp> prop;
|
||||
|
||||
Impl() : prop(0) {}
|
||||
};
|
||||
|
||||
@ -63,13 +59,17 @@ 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;
|
||||
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;
|
||||
if (!impl_)
|
||||
impl_ = new Impl();
|
||||
|
||||
if (other.impl_)
|
||||
impl_->prop = other.impl_->prop;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -84,45 +84,22 @@ cv::viz::Widget::~Widget()
|
||||
|
||||
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<vtkDataSet> data = reader->GetOutput();
|
||||
CV_Assert("File does not exist or file format is not supported." && data);
|
||||
|
||||
vtkSmartPointer<vtkLODActor> actor = vtkSmartPointer<vtkLODActor>::New();
|
||||
|
||||
vtkSmartPointer<vtkDataSetMapper> mapper = vtkSmartPointer<vtkDataSetMapper>::New();
|
||||
#if VTK_MAJOR_VERSION <= 5
|
||||
mapper->SetInput(data);
|
||||
#else
|
||||
mapper->SetInputData(data);
|
||||
#endif
|
||||
|
||||
vtkSmartPointer<vtkDataArray> scalars = data->GetPointData()->GetScalars();
|
||||
if (scalars)
|
||||
{
|
||||
cv::Vec3d minmax(scalars->GetRange());
|
||||
mapper->SetScalarRange(minmax.val);
|
||||
mapper->SetScalarModeToUsePointData();
|
||||
|
||||
// interpolation OFF, if data is a vtkPolyData that contains only vertices, ON for anything else.
|
||||
vtkPolyData* polyData = vtkPolyData::SafeDownCast(data);
|
||||
bool interpolation = (polyData && polyData->GetNumberOfCells() != polyData->GetNumberOfVerts());
|
||||
|
||||
mapper->SetInterpolateScalarsBeforeMapping(interpolation);
|
||||
mapper->ScalarVisibilityOn();
|
||||
}
|
||||
mapper->SetInputConnection( reader->GetOutputPort() );
|
||||
mapper->ImmediateModeRenderingOff();
|
||||
|
||||
actor->SetNumberOfCloudPoints(int(std::max<vtkIdType>(1, data->GetNumberOfPoints() / 10)));
|
||||
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
|
||||
actor->GetProperty()->SetInterpolationToFlat();
|
||||
actor->GetProperty()->BackfaceCullingOn();
|
||||
|
||||
actor->SetMapper(mapper);
|
||||
|
||||
Widget widget;
|
||||
widget.impl_->prop = actor;
|
||||
WidgetAccessor::setProp(widget, actor);
|
||||
return widget;
|
||||
}
|
||||
|
||||
@ -133,37 +110,15 @@ void cv::viz::Widget::setRenderingProperty(int property, double value)
|
||||
|
||||
switch (property)
|
||||
{
|
||||
case POINT_SIZE:
|
||||
{
|
||||
actor->GetProperty()->SetPointSize(float(value));
|
||||
actor->Modified();
|
||||
break;
|
||||
}
|
||||
case OPACITY:
|
||||
{
|
||||
actor->GetProperty()->SetOpacity(value);
|
||||
actor->Modified();
|
||||
break;
|
||||
}
|
||||
case IMMEDIATE_RENDERING:
|
||||
{
|
||||
actor->GetMapper()->SetImmediateModeRendering(int(value));
|
||||
actor->Modified();
|
||||
break;
|
||||
}
|
||||
case LINE_WIDTH:
|
||||
{
|
||||
actor->GetProperty()->SetLineWidth(float(value));
|
||||
actor->Modified();
|
||||
break;
|
||||
}
|
||||
case 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);
|
||||
vtkSmartPointer<vtkTextProperty> tprop = text_actor->GetTextProperty();
|
||||
tprop->SetFontSize(int(value));
|
||||
text_actor->Modified();
|
||||
text_actor->GetTextProperty()->SetFontSize(int(value));
|
||||
break;
|
||||
}
|
||||
case REPRESENTATION:
|
||||
@ -174,7 +129,6 @@ void cv::viz::Widget::setRenderingProperty(int property, double value)
|
||||
case REPRESENTATION_WIREFRAME: actor->GetProperty()->SetRepresentationToWireframe(); break;
|
||||
case REPRESENTATION_SURFACE: actor->GetProperty()->SetRepresentationToSurface(); break;
|
||||
}
|
||||
actor->Modified();
|
||||
break;
|
||||
}
|
||||
case SHADING:
|
||||
@ -186,14 +140,11 @@ void cv::viz::Widget::setRenderingProperty(int property, double value)
|
||||
{
|
||||
if (!actor->GetMapper()->GetInput()->GetPointData()->GetNormals())
|
||||
{
|
||||
vtkSmartPointer<vtkPolyDataNormals> normals = vtkSmartPointer<vtkPolyDataNormals>::New();
|
||||
#if VTK_MAJOR_VERSION <= 5
|
||||
normals->SetInput(actor->GetMapper()->GetInput());
|
||||
#else
|
||||
normals->SetInputData(actor->GetMapper()->GetInput());
|
||||
#endif
|
||||
normals->Update();
|
||||
vtkDataSetMapper::SafeDownCast(actor->GetMapper())->SetInputConnection(normals->GetOutputPort());
|
||||
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;
|
||||
@ -202,27 +153,22 @@ void cv::viz::Widget::setRenderingProperty(int property, double value)
|
||||
{
|
||||
if (!actor->GetMapper()->GetInput()->GetPointData()->GetNormals())
|
||||
{
|
||||
vtkSmartPointer<vtkPolyDataNormals> normals = vtkSmartPointer<vtkPolyDataNormals>::New();
|
||||
#if VTK_MAJOR_VERSION <= 5
|
||||
normals->SetInput(actor->GetMapper()->GetInput());
|
||||
#else
|
||||
normals->SetInputData(actor->GetMapper()->GetInput());
|
||||
#endif
|
||||
normals->Update();
|
||||
vtkDataSetMapper::SafeDownCast(actor->GetMapper())->SetInputConnection(normals->GetOutputPort());
|
||||
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;
|
||||
}
|
||||
}
|
||||
actor->Modified();
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
default:
|
||||
CV_Assert("setPointCloudRenderingProperties: Unknown property");
|
||||
}
|
||||
actor->Modified();
|
||||
}
|
||||
|
||||
double cv::viz::Widget::getRenderingProperty(int property) const
|
||||
@ -233,32 +179,16 @@ double cv::viz::Widget::getRenderingProperty(int property) const
|
||||
double value = 0.0;
|
||||
switch (property)
|
||||
{
|
||||
case POINT_SIZE:
|
||||
{
|
||||
value = actor->GetProperty()->GetPointSize();
|
||||
break;
|
||||
}
|
||||
case OPACITY:
|
||||
{
|
||||
value = actor->GetProperty()->GetOpacity();
|
||||
break;
|
||||
}
|
||||
case IMMEDIATE_RENDERING:
|
||||
{
|
||||
value = actor->GetMapper()->GetImmediateModeRendering();
|
||||
break;
|
||||
}
|
||||
case LINE_WIDTH:
|
||||
{
|
||||
value = actor->GetProperty()->GetLineWidth();
|
||||
break;
|
||||
}
|
||||
case 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);
|
||||
vtkSmartPointer<vtkTextProperty> tprop = text_actor->GetTextProperty();
|
||||
value = tprop->GetFontSize();
|
||||
value = text_actor->GetTextProperty()->GetFontSize();;
|
||||
break;
|
||||
}
|
||||
case REPRESENTATION:
|
||||
@ -303,38 +233,17 @@ void cv::viz::WidgetAccessor::setProp(Widget& widget, vtkSmartPointer<vtkProp> p
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// widget3D implementation
|
||||
|
||||
struct cv::viz::Widget3D::MatrixConverter
|
||||
{
|
||||
static Matx44f convertToMatx(const vtkSmartPointer<vtkMatrix4x4>& vtk_matrix)
|
||||
{
|
||||
Matx44f m;
|
||||
for (int i = 0; i < 4; i++)
|
||||
for (int k = 0; k < 4; k++)
|
||||
m(i, k) = vtk_matrix->GetElement(i, k);
|
||||
return m;
|
||||
}
|
||||
|
||||
static vtkSmartPointer<vtkMatrix4x4> convertToVtkMatrix(const Matx44f& m)
|
||||
{
|
||||
vtkSmartPointer<vtkMatrix4x4> vtk_matrix = vtkSmartPointer<vtkMatrix4x4>::New();
|
||||
for (int i = 0; i < 4; i++)
|
||||
for (int k = 0; k < 4; k++)
|
||||
vtk_matrix->SetElement(i, k, m(i, k));
|
||||
return vtk_matrix;
|
||||
}
|
||||
};
|
||||
|
||||
void cv::viz::Widget3D::setPose(const Affine3f &pose)
|
||||
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 = convertToVtkMatrix(pose.matrix);
|
||||
vtkSmartPointer<vtkMatrix4x4> matrix = vtkmatrix(pose.matrix);
|
||||
actor->SetUserMatrix(matrix);
|
||||
actor->Modified();
|
||||
}
|
||||
|
||||
void cv::viz::Widget3D::updatePose(const Affine3f &pose)
|
||||
void cv::viz::Widget3D::updatePose(const Affine3d &pose)
|
||||
{
|
||||
vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getProp(*this));
|
||||
CV_Assert("Widget is not 3D." && actor);
|
||||
@ -343,25 +252,33 @@ void cv::viz::Widget3D::updatePose(const Affine3f &pose)
|
||||
if (!matrix)
|
||||
{
|
||||
setPose(pose);
|
||||
return ;
|
||||
return;
|
||||
}
|
||||
Matx44f matrix_cv = MatrixConverter::convertToMatx(matrix);
|
||||
|
||||
Affine3f updated_pose = pose * Affine3f(matrix_cv);
|
||||
matrix = MatrixConverter::convertToVtkMatrix(updated_pose.matrix);
|
||||
Affine3d updated_pose = pose * Affine3d(*matrix->Element);
|
||||
matrix = vtkmatrix(updated_pose.matrix);
|
||||
|
||||
actor->SetUserMatrix(matrix);
|
||||
actor->Modified();
|
||||
}
|
||||
|
||||
cv::Affine3f cv::viz::Widget3D::getPose() const
|
||||
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);
|
||||
}
|
||||
|
||||
vtkSmartPointer<vtkMatrix4x4> matrix = actor->GetUserMatrix();
|
||||
Matx44f matrix_cv = MatrixConverter::convertToMatx(matrix);
|
||||
return Affine3f(matrix_cv);
|
||||
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)
|
||||
|
@ -1,3 +1,3 @@
|
||||
#include "test_precomp.hpp"
|
||||
|
||||
CV_TEST_MAIN("cv")
|
||||
CV_TEST_MAIN("viz")
|
||||
|
@ -1 +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;
|
||||
}
|
||||
|
@ -41,9 +41,6 @@
|
||||
// * Ozan Tonkal, ozantonkal@gmail.com
|
||||
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
|
||||
//
|
||||
// OpenCV Viz module is complete rewrite of
|
||||
// PCL visualization module (www.pointclouds.org)
|
||||
//
|
||||
//M*/
|
||||
|
||||
#ifdef __GNUC__
|
||||
@ -66,5 +63,42 @@
|
||||
#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
|
||||
|
@ -12,34 +12,34 @@ void tutorial2()
|
||||
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));
|
||||
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(Point3f(0.5,0.5,0.0), Point3f(0.0,0.0,-0.5), true, viz::Color::blue());
|
||||
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
|
||||
Mat rot_vec = Mat::zeros(1,3,CV_32F);
|
||||
float translation_phase = 0.0, translation = 0.0;
|
||||
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.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;
|
||||
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.01f;
|
||||
translation_phase += CV_PI * 0.01;
|
||||
translation = sin(translation_phase);
|
||||
|
||||
/// Construct pose
|
||||
Affine3f pose(rot_vec, Vec3f(translation, translation, translation));
|
||||
Affine3d pose(rot_vec, Vec3d(translation, translation, translation));
|
||||
|
||||
myWindow.setWidgetPose("Cube Widget", pose);
|
||||
|
||||
@ -48,7 +48,7 @@ void tutorial2()
|
||||
}
|
||||
|
||||
|
||||
TEST(Viz_viz3d, DISABLED_tutorial2_pose_of_widget)
|
||||
TEST(Viz, DISABLED_tutorial2_pose_of_widget)
|
||||
{
|
||||
tutorial2();
|
||||
}
|
||||
|
@ -3,28 +3,6 @@
|
||||
using namespace cv;
|
||||
using namespace std;
|
||||
|
||||
/**
|
||||
* @function cvcloud_load
|
||||
* @brief load bunny.ply
|
||||
*/
|
||||
Mat cvcloud_load()
|
||||
{
|
||||
Mat cloud(1, 20000, CV_32FC3);
|
||||
ifstream ifs("d:/cloud_dragon.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 < 20000; ++i)
|
||||
ifs >> data[i].x >> data[i].y >> data[i].z;// >> dummy1 >> dummy2;
|
||||
|
||||
//cloud *= 5.0f;
|
||||
return cloud;
|
||||
}
|
||||
|
||||
/**
|
||||
* @function main
|
||||
*/
|
||||
@ -37,29 +15,29 @@ void tutorial3(bool camera_pov)
|
||||
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);
|
||||
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
|
||||
Affine3f cam_pose = viz::makeCameraPose(cam_pos, cam_focal_point, cam_y_dir);
|
||||
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
|
||||
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);
|
||||
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 bunny_cloud = cvcloud_load();
|
||||
viz::WCloud cloud_widget(bunny_cloud, viz::Color::green());
|
||||
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
|
||||
Affine3f cloud_pose = Affine3f().translate(Vec3f(0.0f,0.0f,3.0f));
|
||||
Affine3d cloud_pose = Affine3d().translate(Vec3d(0.0, 0.0, 3.0));
|
||||
/// Pose of the widget in global frame
|
||||
Affine3f cloud_pose_global = transform * cloud_pose;
|
||||
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.889484, 0.523599)); // Camera frustum
|
||||
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);
|
||||
}
|
||||
@ -75,12 +53,12 @@ void tutorial3(bool camera_pov)
|
||||
myWindow.spin();
|
||||
}
|
||||
|
||||
TEST(Viz_viz3d, DISABLED_tutorial3_global_view)
|
||||
TEST(Viz, DISABLED_tutorial3_global_view)
|
||||
{
|
||||
tutorial3(false);
|
||||
}
|
||||
|
||||
TEST(Viz_viz3d, DISABLED_tutorial3_camera_view)
|
||||
TEST(Viz, DISABLED_tutorial3_camera_view)
|
||||
{
|
||||
tutorial3(true);
|
||||
}
|
||||
|
@ -41,141 +41,24 @@
|
||||
//M*/
|
||||
#include "test_precomp.hpp"
|
||||
|
||||
|
||||
using namespace cv;
|
||||
|
||||
static cv::Mat cvcloud_load()
|
||||
TEST(Viz_viz3d, DISABLED_develop)
|
||||
{
|
||||
cv::Mat cloud(1, 20000, CV_32FC3);
|
||||
std::ifstream ifs("/Users/nerei/cloud_dragon.ply");
|
||||
cv::Mat cloud = cv::viz::readCloud(get_dragon_ply_file_path());
|
||||
|
||||
std::string str;
|
||||
for(size_t i = 0; i < 11; ++i)
|
||||
std::getline(ifs, str);
|
||||
|
||||
cv::Point3f* data = cloud.ptr<cv::Point3f>();
|
||||
for(size_t i = 0; i < 20000; ++i)
|
||||
ifs >> data[i].x >> data[i].y >> data[i].z;
|
||||
|
||||
return cloud;
|
||||
}
|
||||
|
||||
bool constant_cam = true;
|
||||
cv::viz::Widget cam_1, cam_coordinates;
|
||||
|
||||
void keyboard_callback(const viz::KeyboardEvent & event, void * cookie)
|
||||
{
|
||||
if (event.keyDown())
|
||||
{
|
||||
if (event.getKeySym() == "space")
|
||||
{
|
||||
viz::Viz3d &viz = *((viz::Viz3d *) cookie);
|
||||
constant_cam = !constant_cam;
|
||||
if (constant_cam)
|
||||
{
|
||||
viz.showWidget("cam_1", cam_1);
|
||||
viz.showWidget("cam_coordinate", cam_coordinates);
|
||||
viz.showWidget("cam_text", viz::WText("Global View", Point2i(5,5), 28));
|
||||
viz.resetCamera();
|
||||
}
|
||||
else
|
||||
{
|
||||
viz.showWidget("cam_text", viz::WText("Cam View", Point2i(5,5), 28));
|
||||
viz.removeWidget("cam_1");
|
||||
viz.removeWidget("cam_coordinate");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Viz_viz3d, develop)
|
||||
{
|
||||
cv::viz::Viz3d viz("abc");
|
||||
viz.setBackgroundMeshLab();
|
||||
viz.showWidget("coo", cv::viz::WCoordinateSystem(1));
|
||||
viz.showWidget("cloud", cv::viz::WPaintedCloud(cloud));
|
||||
|
||||
cv::viz::Mesh3d bunny_mesh = cv::viz::Mesh3d::loadMesh("bunny.ply");
|
||||
cv::viz::WMesh bunny_widget(bunny_mesh);
|
||||
bunny_widget.setColor(cv::viz::Color::cyan());
|
||||
//---->>>>> <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>
|
||||
|
||||
cam_1 = cv::viz::WCameraPosition(cv::Vec2f(0.6f, 0.4f), 0.2, cv::viz::Color::green());
|
||||
cam_coordinates = cv::viz::WCameraPosition(0.2);
|
||||
|
||||
viz.showWidget("bunny", bunny_widget);
|
||||
viz.showWidget("cam_1", cam_1, viz::makeCameraPose(Point3f(1.f,0.f,0.f), Point3f(0.f,0.f,0.f), Point3f(0.f,1.f,0.f)));
|
||||
viz.showWidget("cam_coordinate", cam_coordinates, viz::makeCameraPose(Point3f(1.f,0.f,0.f), Point3f(0.f,0.f,0.f), Point3f(0.f,1.f,0.f)));
|
||||
|
||||
std::vector<Affine3f> cam_path;
|
||||
|
||||
for (int i = 0, j = 0; i <= 360; ++i, j+=5)
|
||||
{
|
||||
cam_path.push_back(viz::makeCameraPose(Vec3d(0.5*cos(i*CV_PI/180.0), 0.5*sin(j*CV_PI/180.0), 0.5*sin(i*CV_PI/180.0)), Vec3f(0.f, 0.f, 0.f), Vec3f(0.f, 1.f, 0.f)));
|
||||
}
|
||||
|
||||
int path_counter = 0;
|
||||
int cam_path_size = cam_path.size();
|
||||
|
||||
// OTHER WIDGETS
|
||||
cv::Mat img = imread("opencv.png");
|
||||
|
||||
int downSample = 4;
|
||||
|
||||
int row_max = img.rows/downSample;
|
||||
int col_max = img.cols/downSample;
|
||||
|
||||
cv::Mat *clouds = new cv::Mat[img.cols/downSample];
|
||||
cv::Mat *colors = new cv::Mat[img.cols/downSample];
|
||||
|
||||
for (int col = 0; col < col_max; ++col)
|
||||
{
|
||||
clouds[col] = Mat::zeros(img.rows/downSample, 1, CV_32FC3);
|
||||
colors[col] = Mat::zeros(img.rows/downSample, 1, CV_8UC3);
|
||||
for (int row = 0; row < row_max; ++row)
|
||||
{
|
||||
clouds[col].at<Vec3f>(row) = Vec3f(downSample * float(col) / img.cols, 1.f-(downSample * float(row) / img.rows), 0.f);
|
||||
colors[col].at<Vec3b>(row) = img.at<Vec3b>(row*downSample,col*downSample);
|
||||
}
|
||||
}
|
||||
|
||||
for (int col = 0; col < col_max; ++col)
|
||||
{
|
||||
std::stringstream strstrm;
|
||||
strstrm << "cloud_" << col;
|
||||
viz.showWidget(strstrm.str(), viz::WCloud(clouds[col], colors[col]));
|
||||
viz.getWidget(strstrm.str()).setRenderingProperty(viz::POINT_SIZE, 3.0);
|
||||
viz.getWidget(strstrm.str()).setRenderingProperty(viz::OPACITY, 0.45);
|
||||
}
|
||||
|
||||
viz.showWidget("trajectory", viz::WTrajectory(cam_path, viz::WTrajectory::DISPLAY_PATH, viz::Color::yellow()));
|
||||
viz.showWidget("cam_text", viz::WText("Global View", Point2i(5,5), 28));
|
||||
viz.registerKeyboardCallback(keyboard_callback, (void *) &viz);
|
||||
|
||||
int angle = 0;
|
||||
|
||||
while(!viz.wasStopped())
|
||||
{
|
||||
if (path_counter == cam_path_size)
|
||||
{
|
||||
path_counter = 0;
|
||||
}
|
||||
|
||||
if (!constant_cam)
|
||||
{
|
||||
viz.setViewerPose(cam_path[path_counter]);
|
||||
}
|
||||
|
||||
if (angle == 360) angle = 0;
|
||||
|
||||
cam_1.cast<viz::WCameraPosition>().setPose(cam_path[path_counter]);
|
||||
cam_coordinates.cast<viz::WCameraPosition>().setPose(cam_path[path_counter++]);
|
||||
|
||||
for (int i = 0; i < col_max; ++i)
|
||||
{
|
||||
std::stringstream strstrm;
|
||||
strstrm << "cloud_" << i;
|
||||
viz.setWidgetPose(strstrm.str(), Affine3f().translate(Vec3f(-0.5f, 0.f, (float)(-0.7 + 0.2*sin((angle+i*10)*CV_PI / 180.0)))));
|
||||
}
|
||||
angle += 10;
|
||||
viz.spinOnce(42, true);
|
||||
}
|
||||
|
||||
volatile void* a = (void*)&cvcloud_load; (void)a; //fixing warnings
|
||||
viz.spin();
|
||||
}
|
||||
|
407
modules/viz/test/tests_simple.cpp
Normal file
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.size()) * 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();
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user