diff --git a/modules/imgproc/doc/pics/delaunay_voronoi.png b/modules/imgproc/doc/pics/delaunay_voronoi.png new file mode 100644 index 0000000000..ca09c7b5ab Binary files /dev/null and b/modules/imgproc/doc/pics/delaunay_voronoi.png differ diff --git a/modules/imgproc/include/opencv2/imgproc.hpp b/modules/imgproc/include/opencv2/imgproc.hpp index 08c6036a7e..5ee790468b 100644 --- a/modules/imgproc/include/opencv2/imgproc.hpp +++ b/modules/imgproc/include/opencv2/imgproc.hpp @@ -194,6 +194,19 @@ int main(int argc, const char *argv[]) @see cv::ColormapTypes + @defgroup imgproc_subdiv2d Planar Subdivision + +The Subdiv2D class described in this section is used to perform various planar subdivision on +a set of 2D points (represented as vector of Point2f). OpenCV subdivides a plane into triangles +using the Delaunay’s algorithm, which corresponds to the dual graph of the Voronoi diagram. +In the figure below, the Delaunay’s triangulation is marked with black lines and the Voronoi +diagram with red lines. + +![Delaunay triangulation (black) and Voronoi (red)](pics/delaunay_voronoi.png) + +The subdivisions can be used for the 3D piece-wise transformation of a plane, morphing, fast +location of points on the plane, building special graphs (such as NNG,RNG), and so forth. + @defgroup imgproc_hist Histograms @defgroup imgproc_shape Structural Analysis and Shape Descriptors @defgroup imgproc_motion Motion Analysis and Object Tracking @@ -874,16 +887,21 @@ public: }; +//! @addtogroup imgproc_subdiv2d +//! @{ + class CV_EXPORTS_W Subdiv2D { public: - enum { PTLOC_ERROR = -2, - PTLOC_OUTSIDE_RECT = -1, - PTLOC_INSIDE = 0, - PTLOC_VERTEX = 1, - PTLOC_ON_EDGE = 2 + /** Subdiv2D point location cases */ + enum { PTLOC_ERROR = -2, //!< Point location error + PTLOC_OUTSIDE_RECT = -1, //!< Point outside the subdivision bounding rect + PTLOC_INSIDE = 0, //!< Point inside some facet + PTLOC_VERTEX = 1, //!< Point coincides with one of the subdivision vertices + PTLOC_ON_EDGE = 2 //!< Point on some edge }; + /** Subdiv2D edge type navigation (see: getEdge()) */ enum { NEXT_AROUND_ORG = 0x00, NEXT_AROUND_DST = 0x22, PREV_AROUND_ORG = 0x11, @@ -894,27 +912,181 @@ public: PREV_AROUND_RIGHT = 0x02 }; + /** creates an empty Subdiv2D object. + To create a new empty Delaunay subdivision you need to use the initDelaunay() function. + */ CV_WRAP Subdiv2D(); + + /** @overload + + @param rect – Rectangle that includes all of the 2D points that are to be added to the subdivision. + + The function creates an empty Delaunay subdivision where 2D points can be added using the function + insert() . All of the points to be added must be within the specified rectangle, otherwise a runtime + error is raised. + */ CV_WRAP Subdiv2D(Rect rect); + + /** @brief Creates a new empty Delaunay subdivision + + @param rect – Rectangle that includes all of the 2D points that are to be added to the subdivision. + + */ CV_WRAP void initDelaunay(Rect rect); + /** @brief Insert a single point into a Delaunay triangulation. + + @param pt – Point to insert. + + The function inserts a single point into a subdivision and modifies the subdivision topology + appropriately. If a point with the same coordinates exists already, no new point is added. + @returns the ID of the point. + + @note If the point is outside of the triangulation specified rect a runtime error is raised. + */ CV_WRAP int insert(Point2f pt); + + /** @brief Insert multiple points into a Delaunay triangulation. + + @param ptvec – Points to insert. + + The function inserts a vector of points into a subdivision and modifies the subdivision topology + appropriately. + */ CV_WRAP void insert(const std::vector& ptvec); + + /** @brief Returns the location of a point within a Delaunay triangulation. + + @param pt – Point to locate. + @param edge – Output edge that the point belongs to or is located to the right of it. + @param vertex – Optional output vertex the input point coincides with. + + The function locates the input point within the subdivision and gives one of the triangle edges + or vertices. + + @returns an integer which specify one of the following five cases for point location: + - The point falls into some facet. The function returns PTLOC_INSIDE and edge will contain one of + edges of the facet. + - The point falls onto the edge. The function returns PTLOC_ON_EDGE and edge will contain this edge. + - The point coincides with one of the subdivision vertices. The function returns PTLOC_VERTEX and + vertex will contain a pointer to the vertex. + - The point is outside the subdivision reference rectangle. The function returns PTLOC_OUTSIDE_RECT + and no pointers are filled. + - One of input arguments is invalid. A runtime error is raised or, if silent or “parent” error + processing mode is selected, CV_PTLOC_ERROR is returnd. + */ CV_WRAP int locate(Point2f pt, CV_OUT int& edge, CV_OUT int& vertex); + /** @brief Finds the subdivision vertex closest to the given point. + + @param pt – Input point. + @param nearestPt – Output subdivision vertex point. + + The function is another function that locates the input point within the subdivision. It finds the + subdivision vertex that is the closest to the input point. It is not necessarily one of vertices + of the facet containing the input point, though the facet (located using locate() ) is used as a + starting point. + + @returns vertex ID. + */ CV_WRAP int findNearest(Point2f pt, CV_OUT Point2f* nearestPt = 0); + + /** @brief Returns a list of all edges. + + @param edgeList – Output vector. + + The function gives each edge as a 4 numbers vector, where each two are one of the edge + vertices. i.e. org_x = v[0], org_y = v[1], dst_x = v[2], dst_y = v[3]. + */ CV_WRAP void getEdgeList(CV_OUT std::vector& edgeList) const; + + /** @brief Returns a list of all triangles. + + @param triangleList – Output vector. + + The function gives each triangle as a 6 numbers vector, where each two are one of the triangle + vertices. i.e. p1_x = v[0], p1_y = v[1], p2_x = v[2], p2_y = v[3], p3_x = v[4], p3_y = v[5]. + */ CV_WRAP void getTriangleList(CV_OUT std::vector& triangleList) const; + + /** @brief Returns a list of all Voroni facets. + + @param idx – Vector of vertices IDs to consider. For all vertices you can pass empty vector. + @param facetList – Output vector of the Voroni facets. + @param facetCenters – Output vector of the Voroni facets center points. + + */ CV_WRAP void getVoronoiFacetList(const std::vector& idx, CV_OUT std::vector >& facetList, CV_OUT std::vector& facetCenters); + /** @brief Returns vertex location from vertex ID. + + @param vertex – vertex ID. + @returns vertex (x,y) + + */ CV_WRAP Point2f getVertex(int vertex, CV_OUT int* firstEdge = 0) const; + /** @brief Returns one of the edges related to the given edge. + + @param edge – Subdivision edge ID. + @param nextEdgeType - Parameter specifying which of the related edges to return. + The following values are possible: + - NEXT_AROUND_ORG next around the edge origin ( eOnext on the picture below if e is the input edge) + - NEXT_AROUND_DST next around the edge vertex ( eDnext ) + - PREV_AROUND_ORG previous around the edge origin (reversed eRnext ) + - PREV_AROUND_DST previous around the edge destination (reversed eLnext ) + - NEXT_AROUND_LEFT next around the left facet ( eLnext ) + - NEXT_AROUND_RIGHT next around the right facet ( eRnext ) + - PREV_AROUND_LEFT previous around the left facet (reversed eOnext ) + - PREV_AROUND_RIGHT previous around the right facet (reversed eDnext ) + + ![sample output](pics/quadedge.png) + + @returns edge ID related to the input edge. + */ CV_WRAP int getEdge( int edge, int nextEdgeType ) const; + + /** @brief Returns next edge around the edge origin. + + @param edge – Subdivision edge ID. + + @returns an integer which is next edge ID around the edge origin: eOnext on the + picture above if e is the input edge). + */ CV_WRAP int nextEdge(int edge) const; + + /** @brief Returns another edge of the same quad-edge. + + @param edge – Subdivision edge ID. + @param rotate - Parameter specifying which of the edges of the same quad-edge as the input + one to return. The following values are possible: + - 0 - the input edge ( e on the picture below if e is the input edge) + - 1 - the rotated edge ( eRot ) + - 2 - the reversed edge (reversed e (in green)) + - 3 - the reversed rotated edge (reversed eRot (in green)) + + @returns one of the edges ID of the same quad-edge as the input edge. + */ CV_WRAP int rotateEdge(int edge, int rotate) const; CV_WRAP int symEdge(int edge) const; + + /** @brief Returns the edge origin. + + @param edge – Subdivision edge ID. + @param orgpt – Output vertex location. + + @returns vertex ID. + */ CV_WRAP int edgeOrg(int edge, CV_OUT Point2f* orgpt = 0) const; + + /** @brief Returns the edge destination. + + @param edge – Subdivision edge ID. + @param dstpt – Output vertex location. + + @returns vertex ID. + */ CV_WRAP int edgeDst(int edge, CV_OUT Point2f* dstpt = 0) const; protected: @@ -953,17 +1125,23 @@ protected: int pt[4]; }; + //! All of the vertices std::vector vtx; + //! All of the edges std::vector qedges; int freeQEdge; int freePoint; bool validGeometry; int recentEdge; + //! Top left corner of the bounding rect Point2f topLeft; + //! Bottom right corner of the bounding rect Point2f bottomRight; }; +//! @} imgproc_subdiv2d + //! @addtogroup imgproc_feature //! @{