Skip to content

python binding for viz #2882

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Apr 2, 2021
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 64 additions & 52 deletions modules/viz/include/opencv2/viz/types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,64 +60,71 @@ namespace cv

/** @brief This class represents color in BGR order.
*/
class Color : public Scalar
class CV_EXPORTS_W_SIMPLE Color
#ifndef OPENCV_BINDING_PARSER
: public Scalar
#endif
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/cc @mshabunin Perhaps we need some CV_WRAP_WITHOUT_BASE marker for bindings.

{
public:
Color();
CV_WRAP Color();
//! The three channels will have the same value equal to gray.
Color(double gray);
Color(double blue, double green, double red);
CV_WRAP Color(double gray);
CV_WRAP Color(double blue, double green, double red);

Color(const Scalar& color);

operator Vec3b() const;

static Color black();
static Color blue();
static Color green();
static Color red();
static Color cyan();
static Color yellow();
static Color magenta();
static Color white();

static Color gray();
static Color silver();

static Color mlab();

static Color navy();
static Color maroon();
static Color teal();
static Color olive();
static Color purple();
static Color azure();
static Color chartreuse();
static Color rose();

static Color lime();
static Color gold();
static Color orange();
static Color orange_red();
static Color indigo();

static Color brown();
static Color apricot();
static Color pink();
static Color raspberry();
static Color cherry();
static Color violet();
static Color amethyst();
static Color bluberry();
static Color celestial_blue();
static Color turquoise();

static Color not_set();
CV_WRAP static Color black();
CV_WRAP static Color blue();
CV_WRAP static Color green();
CV_WRAP static Color red();
CV_WRAP static Color cyan();
CV_WRAP static Color yellow();
CV_WRAP static Color magenta();
CV_WRAP static Color white();

CV_WRAP static Color gray();
CV_WRAP static Color silver();

CV_WRAP static Color mlab();

CV_WRAP static Color navy();
CV_WRAP static Color maroon();
CV_WRAP static Color teal();
CV_WRAP static Color olive();
CV_WRAP static Color purple();
CV_WRAP static Color azure();
CV_WRAP static Color chartreuse();
CV_WRAP static Color rose();

CV_WRAP static Color lime();
CV_WRAP static Color gold();
CV_WRAP static Color orange();
CV_WRAP static Color orange_red();
CV_WRAP static Color indigo();

CV_WRAP static Color brown();
CV_WRAP static Color apricot();
CV_WRAP static Color pink();
CV_WRAP static Color raspberry();
CV_WRAP static Color cherry();
CV_WRAP static Color violet();
CV_WRAP static Color amethyst();
CV_WRAP static Color bluberry();
CV_WRAP static Color celestial_blue();
CV_WRAP static Color turquoise();

CV_WRAP static Color not_set();

CV_WRAP double get_blue() { return (*this)[0]; };
CV_WRAP double get_green() { return (*this)[1]; };
CV_WRAP double get_red() { return (*this)[2]; };
};

/** @brief This class wraps mesh attributes, and it can load a mesh from a ply file. :
*/
class CV_EXPORTS Mesh
class CV_EXPORTS_W_SIMPLE Mesh
{
public:
enum {
Expand All @@ -126,16 +133,21 @@ namespace cv
LOAD_OBJ = 2
};

Mat cloud; //!< point coordinates of type CV_32FC3 or CV_64FC3 with only 1 row
Mat colors; //!< point color of type CV_8UC3 or CV_8UC4 with only 1 row
Mat normals; //!< point normals of type CV_32FC3, CV_32FC4, CV_64FC3 or CV_64FC4 with only 1 row
CV_PROP_RW Mat cloud; //!< point coordinates of type CV_32FC3 or CV_64FC3 with only 1 row
CV_PROP_RW Mat colors; //!< point color of type CV_8UC3 or CV_8UC4 with only 1 row
CV_PROP_RW Mat normals; //!< point normals of type CV_32FC3, CV_32FC4, CV_64FC3 or CV_64FC4 with only 1 row

//! Raw integer list of the form: (n,id1,id2,...,idn, n,id1,id2,...,idn, ...)
//! where n is the number of points in the polygon, and id is a zero-offset index into an associated cloud.
Mat polygons; //!< CV_32SC1 with only 1 row
CV_PROP_RW Mat polygons; //!< CV_32SC1 with only 1 row

CV_PROP_RW Mat texture;
CV_PROP_RW Mat tcoords; //!< CV_32FC2 or CV_64FC2 with only 1 row

Mat texture;
Mat tcoords; //!< CV_32FC2 or CV_64FC2 with only 1 row
CV_WRAP Mesh()
{
// nothing
}

/** @brief Loads a mesh from a ply or a obj file.

Expand Down
8 changes: 4 additions & 4 deletions modules/viz/include/opencv2/viz/vizcore.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ namespace cv
* Supported channels: 3 and 4.
* @param binary Used only for PLY format.
*/
CV_EXPORTS void writeCloud(const String& file, InputArray cloud, InputArray colors = noArray(), InputArray normals = noArray(), bool binary = false);
CV_EXPORTS_W void writeCloud(const String& file, InputArray cloud, InputArray colors = noArray(), InputArray normals = noArray(), bool binary = false);

/**
* @param file Filename with extension. Supported formats: PLY, XYZ, OBJ and STL.
Expand All @@ -157,12 +157,12 @@ namespace cv
* @return A mat containing the point coordinates with depth CV_32F or CV_64F and number of
* channels 3 or 4 with only 1 row.
*/
CV_EXPORTS Mat readCloud (const String& file, OutputArray colors = noArray(), OutputArray normals = noArray());
CV_EXPORTS_W 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);
CV_EXPORTS_W Mesh readMesh(const String& file);

///////////////////////////////////////////////////////////////////////////////////////////////
/// Read/write poses and trajectories
Expand Down Expand Up @@ -211,7 +211,7 @@ namespace cv
* @param mesh Input mesh.
* @param normals Normals at very point in the mesh of type CV_64FC3.
*/
CV_EXPORTS void computeNormals(const Mesh& mesh, OutputArray normals);
CV_EXPORTS_W void computeNormals(const Mesh& mesh, OutputArray normals);

//! @}

Expand Down
9 changes: 6 additions & 3 deletions modules/viz/include/opencv2/viz/widgets.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -785,11 +785,14 @@ namespace cv
@param colors Point colors.
@param normals Point normals.
*/
class CV_EXPORTS WMesh : public Widget3D
class CV_EXPORTS_W WMesh
#ifndef OPENCV_BINDING_PARSER
: public Widget3D
#endif
{
public:
WMesh(const Mesh &mesh);
WMesh(InputArray cloud, InputArray polygons, InputArray colors = noArray(), InputArray normals = noArray());
CV_WRAP WMesh(const Mesh &mesh);
CV_WRAP WMesh(InputArray cloud, InputArray polygons, InputArray colors = noArray(), InputArray normals = noArray());
};

/** @brief This class allows to merge several widgets to single one.
Expand Down
114 changes: 114 additions & 0 deletions modules/viz/misc/python/pyopencv_viz.impl.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
#ifndef OPENCV_PYTHON_VIZ_IMPL_HPP
#define OPENCV_PYTHON_VIZ_IMPL_HPP

#include "python_viz.hpp"

namespace cv { namespace viz {

PyAffine3d makeTransformToGlobalPy(const Vec3d& axis_x, const Vec3d& axis_y, const Vec3d& axis_z, const Vec3d& origin)
{
return makeTransformToGlobal(axis_x, axis_y, axis_z, origin);
}

PyAffine3d makeCameraPosePy(const Vec3d& position, const Vec3d& focal_point, const Vec3d& y_dir)
{
return makeCameraPose(position, focal_point, y_dir);
}

#define WRAP_SHOW_WIDGET_1 return Viz3d::showWidget(id, *widget.widget.get())
#define WRAP_SHOW_WIDGET_2 return Viz3d::showWidget(id, *widget.widget.get(), pose)
inline void PyViz3d::showWidget(const String &id, PyWLine &widget) { WRAP_SHOW_WIDGET_1; }
inline void PyViz3d::showWidget(const String &id, PyWLine &widget, PyAffine3d &pose) { WRAP_SHOW_WIDGET_2; }
inline void PyViz3d::showWidget(const String &id, PyWSphere &widget) { WRAP_SHOW_WIDGET_1; }
inline void PyViz3d::showWidget(const String &id, PyWSphere &widget, PyAffine3d &pose) { WRAP_SHOW_WIDGET_2; }
inline void PyViz3d::showWidget(const String &id, PyWCameraPosition &widget) { WRAP_SHOW_WIDGET_1; }
inline void PyViz3d::showWidget(const String &id, PyWCameraPosition &widget, PyAffine3d &pose) { WRAP_SHOW_WIDGET_2; }
inline void PyViz3d::showWidget(const String &id, PyWArrow &widget) { WRAP_SHOW_WIDGET_1; }
inline void PyViz3d::showWidget(const String &id, PyWArrow &widget, PyAffine3d &pose) { WRAP_SHOW_WIDGET_2; }
inline void PyViz3d::showWidget(const String &id, PyWCircle &widget) { WRAP_SHOW_WIDGET_1; }
inline void PyViz3d::showWidget(const String &id, PyWCircle &widget, PyAffine3d &pose) { WRAP_SHOW_WIDGET_2; }
inline void PyViz3d::showWidget(const String &id, PyWPlane &widget) { WRAP_SHOW_WIDGET_1; }
inline void PyViz3d::showWidget(const String &id, PyWPlane &widget, PyAffine3d &pose) { WRAP_SHOW_WIDGET_2; }
inline void PyViz3d::showWidget(const String &id, PyWCone &widget) { WRAP_SHOW_WIDGET_1; }
inline void PyViz3d::showWidget(const String &id, PyWCone &widget, PyAffine3d &pose) { WRAP_SHOW_WIDGET_2; }
inline void PyViz3d::showWidget(const String &id, PyWCube &widget) { WRAP_SHOW_WIDGET_1; }
inline void PyViz3d::showWidget(const String &id, PyWCube &widget, PyAffine3d &pose) { WRAP_SHOW_WIDGET_2; }
inline void PyViz3d::showWidget(const String &id, PyWCylinder &widget) { WRAP_SHOW_WIDGET_1; }
inline void PyViz3d::showWidget(const String &id, PyWCylinder &widget, PyAffine3d &pose) { WRAP_SHOW_WIDGET_2; }
inline void PyViz3d::showWidget(const String &id, PyWCoordinateSystem &widget) { WRAP_SHOW_WIDGET_1; }
inline void PyViz3d::showWidget(const String &id, PyWPaintedCloud &widget) { WRAP_SHOW_WIDGET_1; }
inline void PyViz3d::showWidget(const String &id, PyWPaintedCloud &widget, PyAffine3d &pose) { WRAP_SHOW_WIDGET_2; }
inline void PyViz3d::showWidget(const String &id, PyWCloudCollection &widget) { WRAP_SHOW_WIDGET_1; }
inline void PyViz3d::showWidget(const String &id, PyWCloudCollection &widget, PyAffine3d &pose) { WRAP_SHOW_WIDGET_2; }
inline void PyViz3d::showWidget(const String &id, PyWGrid &widget) { WRAP_SHOW_WIDGET_1; }
inline void PyViz3d::showWidget(const String &id, PyWGrid &widget, PyAffine3d &pose) { WRAP_SHOW_WIDGET_2; }
inline void PyViz3d::showWidget(const String &id, const cv::Ptr<WMesh> &widget) { return Viz3d::showWidget(id, *widget.get()); }
inline void PyViz3d::showWidget(const String &id, const cv::Ptr<WMesh> &widget, PyAffine3d &pose) { return Viz3d::showWidget(id, *widget.get(), pose); }
inline void PyViz3d::showWidget(const String &id, PyWPolyLine &widget) { WRAP_SHOW_WIDGET_1; }
inline void PyViz3d::showWidget(const String &id, PyWPolyLine &widget, PyAffine3d &pose) { WRAP_SHOW_WIDGET_2; }
inline void PyViz3d::showWidget(const String &id, PyWCloud &widget) { WRAP_SHOW_WIDGET_1; }
inline void PyViz3d::showWidget(const String &id, PyWCloud &widget, PyAffine3d &pose) { WRAP_SHOW_WIDGET_2; }
inline void PyViz3d::showWidget(const String &id, PyWImage3D &widget, PyAffine3d &pose) { WRAP_SHOW_WIDGET_2; }
inline void PyViz3d::showWidget(const String &id, PyWImage3D &widget) { WRAP_SHOW_WIDGET_1; }
inline void PyViz3d::showWidget(const String &id, PyWImageOverlay &widget, PyAffine3d &pose) { WRAP_SHOW_WIDGET_2; }
inline void PyViz3d::showWidget(const String &id, PyWImageOverlay &widget) { WRAP_SHOW_WIDGET_1; }
inline void PyViz3d::showWidget(const String &id, PyWText &widget) { WRAP_SHOW_WIDGET_1; }
inline void PyViz3d::showWidget(const String &id, PyWText &widget, PyAffine3d &pose) { WRAP_SHOW_WIDGET_2; }
inline void PyViz3d::showWidget(const String &id, PyWText3D &widget) { WRAP_SHOW_WIDGET_1; }
inline void PyViz3d::showWidget(const String &id, PyWText3D &widget, PyAffine3d &pose) { WRAP_SHOW_WIDGET_2; }
inline void PyViz3d::showWidget(const String &id, PyWCloudNormals &widget, PyAffine3d &pose) { WRAP_SHOW_WIDGET_2; }
inline void PyViz3d::showWidget(const String &id, PyWCloudNormals &widget) { WRAP_SHOW_WIDGET_1; }
inline void PyViz3d::showWidget(const String &id, PyWTrajectory &widget, PyAffine3d &pose) { WRAP_SHOW_WIDGET_2; }
inline void PyViz3d::showWidget(const String &id, PyWTrajectory &widget) { WRAP_SHOW_WIDGET_1; }
inline void PyViz3d::showWidget(const String &id, PyWTrajectorySpheres &widget, PyAffine3d &pose) { WRAP_SHOW_WIDGET_2; }
inline void PyViz3d::showWidget(const String &id, PyWTrajectorySpheres &widget) { WRAP_SHOW_WIDGET_1; }
inline void PyViz3d::showWidget(const String &id, PyWTrajectoryFrustums &widget, PyAffine3d &pose) { WRAP_SHOW_WIDGET_2; }
inline void PyViz3d::showWidget(const String &id, PyWTrajectoryFrustums &widget) { WRAP_SHOW_WIDGET_1; }
#undef WRAP_SHOW_WIDGET_1
#undef WRAP_SHOW_WIDGET_2


PyWGrid::PyWGrid(InputArray cells, InputArray cells_spacing, const Color &color)
{
if (cells.kind() == _InputArray::MAT && cells_spacing.kind() == _InputArray::MAT)
{
Mat k = cells.getMat();
Mat l = cells_spacing.getMat();
if (k.total() == 2 && l.total() == 2 )
{
CV_Assert(k.type() == CV_64FC1 && k.type() == CV_64FC1);
Vec2i c1(k.at<double>(0), k.at<double>(1));
Vec2d c2(l.at<double>(0), l.at<double>(1));
widget = cv::makePtr<WGrid>(c1, c2, color);
}
else
CV_Error(cv::Error::StsVecLengthErr, "unknown size");
}
else
CV_Error(cv::Error::StsUnsupportedFormat, "unknown type");
}


PyWTrajectoryFrustums::PyWTrajectoryFrustums(InputArray path, InputArray K, double scale, const Color &color)
{
if (K.kind() == _InputArray::MAT)
{
Mat k = K.getMat();
if (k.rows == 3 && k.cols == 3)
{
Matx33d x = k;
widget = cv::makePtr<WTrajectoryFrustums>(path, x, scale, color);

}
else if (k.total() == 2)
widget = cv::makePtr<WTrajectoryFrustums>(path, Vec2d(k.at<double>(0), k.at<double>(1)), 1.0, color);
else
CV_Error(cv::Error::StsVecLengthErr, "unknown size");
}
else
CV_Error(cv::Error::StsVecLengthErr, "unknown size");
}


}} // namespace
#endif // OPENCV_PYTHON_VIZ_IMPL_HPP
Loading