Commit 9710b25c authored by Roman Donchenko's avatar Roman Donchenko Committed by OpenCV Buildbot

Merge pull request #2173 from Nerei:viz

parents 9dc93ce3 ac035b9b
......@@ -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()
\ No newline at end of file
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)
{
......
This diff is collapsed.
This diff is collapsed.
......@@ -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 */
......
This diff is collapsed.
......@@ -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
\ No newline at end of file
#endif
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -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
This diff is collapsed.
......@@ -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); }
This diff is collapsed.
......@@ -41,71 +41,29 @@
// * 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)
cv::Affine3d cv::viz::makeTransformToGlobal(const Vec3d& axis_x, const Vec3d& axis_y, const Vec3d& axis_z, const Vec3d& origin)
{
Affine3f::Mat3 R(axis_x[0], axis_y[0], axis_z[0],
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 Affine3f(R, origin);
return Affine3d(R, origin);
}
cv::Affine3f cv::viz::makeCameraPose(const Vec3f& position, const Vec3f& focal_point, const Vec3f& y_dir)
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
Vec3f n = normalize(focal_point - position);
Vec3f u = normalize(y_dir.cross(n));
Vec3f v = n.cross(u);
Vec3d n = normalize(focal_point - position);
Vec3d u = normalize(y_dir.cross(n));
Vec3d 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
......@@ -161,5 +119,194 @@ cv::String cv::viz::VizStorage::generateWindowName(const String &window_name)
return output;
}
cv::viz::Viz3d cv::viz::get(const String &window_name) { return Viz3d (window_name); }
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();
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
#include "test_precomp.hpp"
CV_TEST_MAIN("cv")
CV_TEST_MAIN("viz")
#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;
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment