diff --git a/modules/viz/include/opencv2/viz/types.hpp b/modules/viz/include/opencv2/viz/types.hpp index dc158664eb..3c88fbaa5a 100644 --- a/modules/viz/include/opencv2/viz/types.hpp +++ b/modules/viz/include/opencv2/viz/types.hpp @@ -119,6 +119,12 @@ namespace cv class CV_EXPORTS Mesh { public: + enum { + LOAD_AUTO = 0, + LOAD_PLY = 1, + LOAD_OBJ = 2 + }; + Mat cloud, colors, normals; //! Raw integer list of the form: (n,id1,id2,...,idn, n,id1,id2,...,idn, ...) @@ -127,11 +133,17 @@ namespace cv Mat texture, tcoords; - /** @brief Loads a mesh from a ply file. + /** @brief Loads a mesh from a ply or a obj file. - @param file File name (for now only PLY is supported) + @param file File name + @param type File type (for now only PLY and OBJ are supported) + + **File type** can be one of the following: + - **LOAD_PLY** + - **LOAD_OBJ** */ - static Mesh load(const String& file); + static Mesh load(const String& file, int type = LOAD_PLY); + }; /** @brief This class wraps intrinsic parameters of a camera. diff --git a/modules/viz/include/opencv2/viz/viz3d.hpp b/modules/viz/include/opencv2/viz/viz3d.hpp index 447004f6f2..33c278e457 100644 --- a/modules/viz/include/opencv2/viz/viz3d.hpp +++ b/modules/viz/include/opencv2/viz/viz3d.hpp @@ -189,6 +189,10 @@ namespace cv */ String getWindowName() const; + /** @brief Returns the Mat screenshot of the current scene. + */ + cv::Mat getScreenshot() const; + /** @brief Saves screenshot of the current scene. @param file Name of the file. @@ -224,6 +228,26 @@ namespace cv */ void spinOnce(int time = 1, bool force_redraw = false); + /** @brief Create a window in memory instead of on the screen. + */ + void setOffScreenRendering(); + + /** @brief Remove all lights from the current scene. + */ + void removeAllLights(); + + /** @brief Add a light in the scene. + + @param position The position of the light. + @param focalPoint The point at which the light is shining + @param color The color of the light + @param diffuseColor The diffuse color of the light + @param ambientColor The ambient color of the light + @param specularColor The specular color of the light + */ + void addLight(Vec3d position, Vec3d focalPoint = Vec3d(0, 0, 0), Color color = Color::white(), + Color diffuseColor = Color::white(), Color ambientColor = Color::black(), Color specularColor = Color::white()); + /** @brief Returns whether the event loop has been stopped. */ bool wasStopped() const; diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index b4699ebb5f..fde4fc2c7d 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -66,7 +66,8 @@ namespace cv FONT_SIZE, REPRESENTATION, IMMEDIATE_RENDERING, - SHADING + SHADING, + AMBIENT }; enum RepresentationValues @@ -136,6 +137,7 @@ namespace cv - **OPACITY** - **LINE_WIDTH** - **FONT_SIZE** + - **AMBIENT** - **REPRESENTATION**: Expected values are : - **REPRESENTATION_POINTS** @@ -494,6 +496,12 @@ namespace cv @param image BGR or Gray-Scale image. */ void setImage(InputArray image); + + /** @brief Sets the image size of the widget. + + @param size the new size of the image. + */ + void setSize(const Size& size); }; ///////////////////////////////////////////////////////////////////////////// diff --git a/modules/viz/src/precomp.hpp b/modules/viz/src/precomp.hpp index 50cc1caf95..9af052a728 100644 --- a/modules/viz/src/precomp.hpp +++ b/modules/viz/src/precomp.hpp @@ -130,6 +130,7 @@ #include #include #include +#include #include "vtkCallbackCommand.h" #if !defined(_WIN32) || defined(__CYGWIN__) diff --git a/modules/viz/src/shapes.cpp b/modules/viz/src/shapes.cpp index e42a7ab2eb..1dfa7c38e1 100644 --- a/modules/viz/src/shapes.cpp +++ b/modules/viz/src/shapes.cpp @@ -728,6 +728,24 @@ void cv::viz::WImage3D::setImage(InputArray image) actor->SetTexture(texture); } +void cv::viz::WImage3D::setSize(const cv::Size& size) +{ + vtkSmartPointer actor = vtkActor::SafeDownCast(WidgetAccessor::getProp(*this)); + vtkSmartPointer mapper = vtkPolyDataMapper::SafeDownCast(actor->GetMapper()); + vtkSmartPointer textured_plane; + vtkSmartPointer plane; + #if VTK_MAJOR_VERSION <= 5 + textured_plane = vtkTextureMapToPlane::SafeDownCast(mapper->GetInputConnection(0,0)->GetProducer()); + plane = vtkPlaneSource::SafeDownCast(textured_plane->GetInputConnection(0,0)->GetProducer()); + #else + textured_plane = vtkTextureMapToPlane::SafeDownCast(mapper->GetInputAlgorithm()); + plane = vtkPlaneSource::SafeDownCast(textured_plane->GetInputAlgorithm()); + #endif + plane->SetOrigin(-0.5 * size.width, -0.5 * size.height, 0.0); + plane->SetPoint1( 0.5 * size.width, -0.5 * size.height, 0.0); + plane->SetPoint2(-0.5 * size.width, 0.5 * size.height, 0.0); +} + template<> cv::viz::WImage3D cv::viz::Widget::cast() { Widget3D widget = this->cast(); diff --git a/modules/viz/src/types.cpp b/modules/viz/src/types.cpp index 2e32a63279..16d3d930ad 100644 --- a/modules/viz/src/types.cpp +++ b/modules/viz/src/types.cpp @@ -57,11 +57,35 @@ cv::viz::MouseEvent::MouseEvent(const Type& _type, const MouseButton& _button, c //////////////////////////////////////////////////////////////////// /// cv::viz::Mesh3d -cv::viz::Mesh cv::viz::Mesh::load(const String& file) +cv::viz::Mesh cv::viz::Mesh::load(const String& file, int type) { - vtkSmartPointer reader = vtkSmartPointer::New(); - reader->SetFileName(file.c_str()); - reader->Update(); + vtkSmartPointer reader = vtkSmartPointer::New(); + switch (type) { + case LOAD_AUTO: + { + CV_Assert(!"cv::viz::Mesh::LOAD_AUTO: Not implemented yet"); + break; + } + case LOAD_PLY: + { + vtkSmartPointer ply_reader = vtkSmartPointer::New(); + ply_reader->SetFileName(file.c_str()); + ply_reader->Update(); + reader = ply_reader; + break; + } + case LOAD_OBJ: + { + vtkSmartPointer obj_reader = vtkSmartPointer::New(); + obj_reader->SetFileName(file.c_str()); + obj_reader->Update(); + reader = obj_reader; + break; + } + default: + CV_Assert(!"cv::viz::Mesh::load: Unknown file type"); + break; + } vtkSmartPointer polydata = reader->GetOutput(); CV_Assert("File does not exist or file format is not supported." && polydata); diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp index 6e7dfcae78..7f201222a4 100644 --- a/modules/viz/src/viz3d.cpp +++ b/modules/viz/src/viz3d.cpp @@ -100,6 +100,10 @@ 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); } +void cv::viz::Viz3d::setOffScreenRendering() { impl_->setOffScreenRendering(); } +void cv::viz::Viz3d::removeAllLights() { impl_->removeAllLights(); } +void cv::viz::Viz3d::addLight(Vec3d position, Vec3d focalPoint, Color color, Color diffuseColor, Color ambientColor, Color specularColor) +{ impl_->addLight(position, focalPoint, color, diffuseColor, ambientColor, specularColor); } bool cv::viz::Viz3d::wasStopped() const { return impl_->wasStopped(); } void cv::viz::Viz3d::close() { impl_->close(); } @@ -134,6 +138,7 @@ void cv::viz::Viz3d::converTo3DRay(const Point3d &window_coord, Point3d &origin, cv::Size cv::viz::Viz3d::getWindowSize() const { return impl_->getWindowSize(); } void cv::viz::Viz3d::setWindowSize(const Size &window_size) { impl_->setWindowSize(window_size); } cv::String cv::viz::Viz3d::getWindowName() const { return impl_->getWindowName(); } +cv::Mat cv::viz::Viz3d::getScreenshot() const { return impl_->getScreenshot(); } void cv::viz::Viz3d::saveScreenshot(const String &file) { impl_->saveScreenshot(file); } void cv::viz::Viz3d::setWindowPosition(const Point& window_position) { impl_->setWindowPosition(window_position); } void cv::viz::Viz3d::setFullScreen(bool mode) { impl_->setFullScreen(mode); } diff --git a/modules/viz/src/vizimpl.cpp b/modules/viz/src/vizimpl.cpp index b2ec7603fc..a927ca65ac 100644 --- a/modules/viz/src/vizimpl.cpp +++ b/modules/viz/src/vizimpl.cpp @@ -68,6 +68,8 @@ cv::viz::Viz3d::VizImpl::VizImpl(const String &name) : spin_once_state_(false), exit_callback_ = vtkSmartPointer::New(); exit_callback_->viz = this; + offScreenMode_ = false; + setBackgroundMeshLab(); } @@ -187,6 +189,38 @@ void cv::viz::Viz3d::VizImpl::spinOnce(int time, bool force_redraw) local->DestroyTimer(timer_callback_->timer_id); } +///////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::Viz3d::VizImpl::setOffScreenRendering() +{ + window_->SetOffScreenRendering(1); + offScreenMode_ = true; +} + +///////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::Viz3d::VizImpl::removeAllLights() +{ + renderer_->RemoveAllLights(); +} + +///////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::Viz3d::VizImpl::addLight(Vec3d position, Vec3d focalPoint, Color color, Color diffuseColor, Color ambientColor, Color specularColor) +{ + Color color_ = vtkcolor(color); + Color diffuseColor_ = vtkcolor(diffuseColor); + Color ambientColor_ = vtkcolor(ambientColor); + Color specularColor_ = vtkcolor(specularColor); + + vtkSmartPointer light = vtkSmartPointer::New(); + light->SetPosition(position.val); + light->SetFocalPoint(focalPoint.val); + light->SetColor(color_.val); + light->SetDiffuseColor(diffuseColor_.val); + light->SetAmbientColor(ambientColor_.val); + light->SetSpecularColor(specularColor_.val); + + renderer_->AddLight(light); +} + ///////////////////////////////////////////////////////////////////////////////////////////// void cv::viz::Viz3d::VizImpl::showWidget(const String &id, const Widget &widget, const Affine3d &pose) { @@ -293,6 +327,39 @@ cv::Affine3d cv::viz::Viz3d::VizImpl::getWidgetPose(const String &id) const ///////////////////////////////////////////////////////////////////////////////////////////// void cv::viz::Viz3d::VizImpl::saveScreenshot(const String &file) { style_->saveScreenshot(file.c_str()); } +///////////////////////////////////////////////////////////////////////////////////////////// +cv::Mat cv::viz::Viz3d::VizImpl::getScreenshot() const +{ + vtkSmartPointer windowToImageFilter = + vtkSmartPointer::New(); + windowToImageFilter->SetInput(window_); + windowToImageFilter->ReadFrontBufferOff(); // read from the back buffer + windowToImageFilter->Update(); + + vtkImageData *resultImage = windowToImageFilter->GetOutput(); + int * dim = resultImage->GetDimensions(); + cv::Mat image(dim[1], dim[0], CV_8UC3); + + Vec3b* dptr = reinterpret_cast(resultImage->GetScalarPointer()); + size_t elem_step = resultImage->GetIncrements()[1]/sizeof(Vec3b); + + for (int y = 0; y < image.rows; ++y) + { + const Vec3b* drow = dptr + elem_step * y; + unsigned char *srow = image.ptr(image.rows - y - 1); + for (int x = 0; x < image.cols; ++x, srow += image.channels()) + { + srow[0] = drow[x][2]; + srow[1] = drow[x][1]; + srow[2] = drow[x][0]; + } + } + + resultImage = 0; + + return image; +} + ///////////////////////////////////////////////////////////////////////////////////////////// void cv::viz::Viz3d::VizImpl::registerMouseCallback(MouseCallback callback, void* cookie) { style_->registerMouseCallback(callback, cookie); } diff --git a/modules/viz/src/vizimpl.hpp b/modules/viz/src/vizimpl.hpp index 92113afa02..65edffb3dc 100644 --- a/modules/viz/src/vizimpl.hpp +++ b/modules/viz/src/vizimpl.hpp @@ -62,6 +62,10 @@ public: void spin(); void spinOnce(int time = 1, bool force_redraw = false); + void setOffScreenRendering(); + + void removeAllLights(); + void addLight(Vec3d position, Vec3d focalPoint, Color color, Color diffuseColor, Color ambientColor, Color specularColor); void showWidget(const String &id, const Widget &widget, const Affine3d &pose = Affine3d::Identity()); void removeWidget(const String &id); @@ -89,6 +93,7 @@ public: void convertToWindowCoordinates(const Point3d &pt, Point3d &window_coord); void converTo3DRay(const Point3d &window_coord, Point3d &origin, Vec3d &direction); + Mat getScreenshot() const; void saveScreenshot(const String &file); void setWindowPosition(const Point& position); Size getWindowSize() const; @@ -131,6 +136,8 @@ private: vtkSmartPointer style_; Ptr widget_actor_map_; + bool offScreenMode_; + bool removeActorFromRenderer(vtkSmartPointer actor); void recreateRenderWindow(); }; diff --git a/modules/viz/src/widget.cpp b/modules/viz/src/widget.cpp index 33b467ebc7..698f21c9ae 100644 --- a/modules/viz/src/widget.cpp +++ b/modules/viz/src/widget.cpp @@ -114,6 +114,7 @@ void cv::viz::Widget::setRenderingProperty(int property, double value) 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 AMBIENT: actor->GetProperty()->SetAmbient(float(value)); break; case FONT_SIZE: { vtkTextActor* text_actor = vtkTextActor::SafeDownCast(actor);