added painted cloud widget
authorAnatoly Baksheev <no@email>
Sun, 12 Jan 2014 14:05:07 +0000 (18:05 +0400)
committerAnatoly Baksheev <no@email>
Sun, 19 Jan 2014 14:38:57 +0000 (18:38 +0400)
modules/viz/include/opencv2/viz/widgets.hpp
modules/viz/src/clouds.cpp
modules/viz/src/precomp.hpp
modules/viz/test/test_viz3d.cpp
modules/viz/test/tests_simple.cpp

index ec17f65..2c49b9d 100644 (file)
@@ -323,6 +323,19 @@ namespace cv
             WCloud(InputArray cloud, const Color &color = Color::white());
         };
 
+        class CV_EXPORTS WPaintedCloud: public Widget3D
+        {
+        public:
+            //! Paint cloud with default gradient between cloud bounds points
+            WPaintedCloud(InputArray cloud);
+
+            //! Paint cloud with default gradient between given points
+            WPaintedCloud(InputArray cloud, const Point3d& p1, const Point3d& p2);
+
+            //! Paint cloud with gradient specified by given colors between given points
+            WPaintedCloud(InputArray cloud, const Point3d& p1, const Point3d& p2, const Color& c1, const Color c2);
+        };
+
         class CV_EXPORTS WCloudCollection : public Widget3D
         {
         public:
@@ -372,6 +385,7 @@ namespace cv
         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>();
index 9ea1d76..d5283d4 100644 (file)
@@ -73,14 +73,89 @@ cv::viz::WCloud::WCloud(InputArray cloud, InputArray colors)
 
 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());
+
+    WPaintedCloud cloud_widget(cloud, Vec3d(bounds[0], bounds[2], bounds[4]), Vec3d(bounds[1], bounds[3], bounds[5]));
+    *this = cloud_widget;
+}
+
+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, cloud_source->GetOutput());
+    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->ScalarVisibilityOff();
+    mapper->ScalarVisibilityOn();
+    mapper->SetColorModeToMapScalars();
+    mapper->SetLookupTable(color_transfer);
 
     vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
     actor->GetProperty()->SetInterpolationToFlat();
@@ -88,13 +163,12 @@ cv::viz::WCloud::WCloud(InputArray cloud, const Color &color)
     actor->SetMapper(mapper);
 
     WidgetAccessor::setProp(*this, actor);
-    setColor(color);
 }
 
-template<> cv::viz::WCloud cv::viz::Widget::cast<cv::viz::WCloud>()
+template<> cv::viz::WPaintedCloud cv::viz::Widget::cast<cv::viz::WPaintedCloud>()
 {
     Widget3D widget = this->cast<Widget3D>();
-    return static_cast<WCloud&>(widget);
+    return static_cast<WPaintedCloud&>(widget);
 }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////
index 4b96366..d5f969a 100644 (file)
 #include <vtkImageAlgorithm.h>
 #include <vtkTransformFilter.h>
 #include <vtkConeSource.h>
+#include <vtkElevationFilter.h>
+#include <vtkColorTransferFunction.h>
 #include <vtkStreamingDemandDrivenPipeline.h>
 
 #if !defined(_WIN32) || defined(__CYGWIN__)
index 1fd1d4a..66ec25d 100644 (file)
@@ -53,7 +53,9 @@ TEST(Viz_viz3d, develop)
     cv::viz::Viz3d viz("abc");
     viz.setBackgroundMeshLab();
     viz.showWidget("coo", cv::viz::WCoordinateSystem(1));
-    viz.showWidget("cloud", cv::viz::WCloud(cloud));
+    //viz.showWidget("cloud", cv::viz::WPaintedCloud(cloud, Vec3d(0.0, 0.0, -1.0), Vec3d(0.0, 0.0, 1.0)));
+    //viz.showWidget("cloud", cv::viz::WPaintedCloud(cloud, Vec3d(0.0, 0.0, -1.0), Vec3d(0.0, 0.0, 1.0), cv::viz::Color::green(), cv::viz::Color::red()));
+    viz.showWidget("cloud", cv::viz::WPaintedCloud(cloud));
 
     //viz.showWidget("h", cv::viz::Widget::fromPlyFile("d:/horse-red.ply"));
     //viz.showWidget("a", cv::viz::WArrow(cv::Point3f(0,0,0), cv::Point3f(1,1,1)));
index 5a685bb..3e25399 100644 (file)
@@ -95,7 +95,7 @@ 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(1.57, 0, 0)));
+    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)));
 
@@ -105,6 +105,20 @@ TEST(Viz, show_cloud_collection)
     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.0, -1.0), Vec3d(0.0, 0.0, 1.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.spin();
+}
+
 TEST(Viz, show_mesh)
 {
     Mesh mesh = Mesh::load(get_dragon_ply_file_path());