vendor: OpenCV 5.0.0 snapshot at 40738fb16ceddb5fb3fea747585f7ce6abb0605b

This commit is contained in:
Gitea Mirror Bot
2026-08-22 00:10:33 +08:00
commit f7f077da11
6933 changed files with 2335208 additions and 0 deletions
@@ -0,0 +1,20 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html
#ifndef OPENCV_GEOMETRY_HPP
#define OPENCV_GEOMETRY_HPP
/**
@defgroup geometry Computational geometry primitives module.
*/
//! @addtogroup geometry
//! @{
#include "opencv2/geometry/2d.hpp"
#include "opencv2/geometry/3d.hpp"
//! @} geometry
#endif
@@ -0,0 +1,919 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html
#ifndef OPENCV_2D_HPP
#define OPENCV_2D_HPP
#include "opencv2/core.hpp"
#include "opencv2/core/utils/logger.hpp"
namespace cv {
//! @addtogroup geometry_shape
//! @{
//! types of intersection between rectangles
enum RectanglesIntersectTypes {
INTERSECT_NONE = 0, //!< No intersection
INTERSECT_PARTIAL = 1, //!< There is a partial intersection
INTERSECT_FULL = 2 //!< One of the rectangle is fully enclosed in the other
};
//! Distance types for Distance Transform and M-estimators
//! @see distanceTransform, fitLine
enum DistanceTypes {
DIST_USER = -1, //!< User defined distance
DIST_L1 = 1, //!< distance = |x1-x2| + |y1-y2|
DIST_L2 = 2, //!< the simple euclidean distance
DIST_C = 3, //!< distance = max(|x1-x2|,|y1-y2|)
DIST_L12 = 4, //!< L1-L2 metric: distance = 2(sqrt(1+x*x/2) - 1))
DIST_FAIR = 5, //!< distance = c^2(|x|/c-log(1+|x|/c)), c = 1.3998
DIST_WELSCH = 6, //!< distance = c^2/2(1-exp(-(x/c)^2)), c = 2.9846
DIST_HUBER = 7 //!< distance = |x|<c ? x^2/2 : c(|x|-c/2), c=1.345
};
//! @addtogroup geometry_subdiv2d
//! @{
class CV_EXPORTS_W Subdiv2D
{
public:
/** 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,
PREV_AROUND_DST = 0x33,
NEXT_AROUND_LEFT = 0x13,
NEXT_AROUND_RIGHT = 0x31,
PREV_AROUND_LEFT = 0x20,
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);
/** @overload */
CV_WRAP Subdiv2D(Rect2f rect2f);
/** @overload
*
* @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);
/** @overload
*
* @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_AS(initDelaunay2f) CV_WRAP void initDelaunay(Rect2f 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<Point2f>& 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, #PTLOC_ERROR is returned.
*/
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<Vec4f>& edgeList) const;
/** @brief Returns a list of the leading edge ID connected to each triangle.
*
* @param leadingEdgeList Output vector.
*
* The function gives one edge ID for each triangle.
*/
CV_WRAP void getLeadingEdgeList(CV_OUT std::vector<int>& leadingEdgeList) 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<Vec6f>& triangleList) const;
/** @brief Returns a list of all Voronoi facets.
*
* @param idx Vector of vertices IDs to consider. For all vertices you can pass empty vector.
* @param facetList Output vector of the Voronoi facets.
* @param facetCenters Output vector of the Voronoi facets center points.
*
*/
CV_WRAP void getVoronoiFacetList(const std::vector<int>& idx, CV_OUT std::vector<std::vector<Point2f> >& facetList,
CV_OUT std::vector<Point2f>& facetCenters);
/** @brief Returns vertex location from vertex ID.
*
* @param vertex vertex ID.
* @param firstEdge Optional. The first edge ID which is connected to the vertex.
* @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:
int newEdge();
void deleteEdge(int edge);
int newPoint(Point2f pt, bool isvirtual, int firstEdge = 0);
void deletePoint(int vtx);
void setEdgePoints( int edge, int orgPt, int dstPt );
void splice( int edgeA, int edgeB );
int connectEdges( int edgeA, int edgeB );
void swapEdges( int edge );
int isRightOf(Point2f pt, int edge) const;
void calcVoronoi();
void clearVoronoi();
void checkSubdiv() const;
struct CV_EXPORTS Vertex
{
Vertex();
Vertex(Point2f pt, bool isvirtual, int firstEdge=0);
bool isvirtual() const;
bool isfree() const;
int firstEdge;
int type;
Point2f pt;
};
struct CV_EXPORTS QuadEdge
{
QuadEdge();
QuadEdge(int edgeidx);
bool isfree() const;
int next[4];
int pt[4];
};
//! All of the vertices
std::vector<Vertex> vtx;
//! All of the edges
std::vector<QuadEdge> 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;
};
//! @} geometry_subdiv2d
/** @example samples/python/snippets/squares.py
A n example using approxPolyDP function in python. *
*/
/** @brief Approximates a polygonal curve(s) with the specified precision.
*
T he function cv::approxPolyDP approximates a curve or a p*olygon with another curve/polygon with less
vertices so that the distance between them is less or equal to the specified precision. It uses the
Douglas-Peucker algorithm <https://en.wikipedia.org/wiki/Ramer-Douglas-Peucker_algorithm>
@param curve Input vector of a 2D point stored in std::vector or Mat
@param approxCurve Result of the approximation. The type should match the type of the input curve.
@param epsilon Parameter specifying the approximation accuracy. This is the maximum distance
between the original curve and its approximation.
@param closed If true, the approximated curve is closed (its first and last vertices are
connected). Otherwise, it is not closed.
*/
CV_EXPORTS_W void approxPolyDP( InputArray curve,
OutputArray approxCurve,
double epsilon, bool closed );
/** @brief Approximates a polygon with a convex hull with a specified accuracy and number of sides.
*
T he cv::approxPolyN function approximates a polygon with *a convex hull
so that the difference between the contour area of the original contour and the new polygon is minimal.
It uses a greedy algorithm for contracting two vertices into one in such a way that the additional area is minimal.
Straight lines formed by each edge of the convex contour are drawn and the areas of the resulting triangles are considered.
Each vertex will lie either on the original contour or outside it.
The algorithm based on the paper @cite LowIlie2003 .
@param curve Input vector of a 2D points stored in std::vector or Mat, points must be float or integer.
@param approxCurve Result of the approximation. The type is vector of a 2D point (Point2f or Point) in std::vector or Mat.
@param nsides The parameter defines the number of sides of the result polygon.
@param epsilon_percentage defines the percentage of the maximum of additional area.
If it equals -1, it is not used. Otherwise algorithm stops if additional area is greater than contourArea(_curve) * percentage.
If additional area exceeds the limit, algorithm returns as many vertices as there were at the moment the limit was exceeded.
@param ensure_convex If it is true, algorithm creates a convex hull of input contour. Otherwise input vector should be convex.
*/
CV_EXPORTS_W void approxPolyN(InputArray curve, OutputArray approxCurve,
int nsides, float epsilon_percentage = -1.0,
bool ensure_convex = true);
/** @brief Finds a rotated rectangle of the minimum area enclosing the input 2D point set.
*
* The function calculates and returns the minimum-area bounding rectangle (possibly rotated) for a
* specified point set. The angle of rotation represents the angle between the line connecting the starting
* and ending points (based on the clockwise order with greatest index for the corner with greatest \f$y\f$)
* and the horizontal axis. This angle always falls between \f$[-90, 0)\f$ because, if the object
* rotates more than a rect angle, the next edge is used to measure the angle. The starting and ending points change
* as the object rotates.Developer should keep in mind that the returned RotatedRect can contain negative
* indices when data is close to the containing Mat element boundary.
*
* @param points Input vector of 2D points, stored in std::vector\<\> or Mat
*/
CV_EXPORTS_W RotatedRect minAreaRect( InputArray points );
/** @brief Finds the four vertices of a rotated rect. Useful to draw the rotated rectangle.
*
* The function finds the four vertices of a rotated rectangle. The four vertices are returned
* in clockwise order starting from the point with greatest \f$y\f$. If two points have the
* same \f$y\f$ coordinate the rightmost is the starting point. This function is useful to draw the
* rectangle. In C++, instead of using this function, you can directly use RotatedRect::points method. Please
* visit the @ref tutorial_bounding_rotated_ellipses "tutorial on Creating Bounding rotated boxes and ellipses
* for contours" for more information.
*
* @param box The input rotated rectangle. It may be the output of @ref minAreaRect.
* @param points The output array of four vertices of rectangles.
*/
CV_EXPORTS_W void boxPoints(RotatedRect box, OutputArray points);
/** @brief Finds a circle of the minimum area enclosing a 2D point set.
*
* The function finds the minimal enclosing circle of a 2D point set using an iterative algorithm.
*
* @param points Input vector of 2D points, stored in std::vector\<\> or Mat
* @param center Output center of the circle.
* @param radius Output radius of the circle.
*/
CV_EXPORTS_W void minEnclosingCircle( InputArray points,
CV_OUT Point2f& center, CV_OUT float& radius );
/** @brief Finds a triangle of minimum area enclosing a 2D point set and returns its area.
*
* The function finds a triangle of minimum area enclosing the given set of 2D points and returns its
* area. The output for a given 2D point set is shown in the image below. 2D points are depicted in
*red* and the enclosing triangle in *yellow*.
*
* ![Sample output of the minimum enclosing triangle function](pics/minenclosingtriangle.png)
*
* The implementation of the algorithm is based on O'Rourke's @cite ORourke86 and Klee and Laskowski's
* @cite KleeLaskowski85 papers. O'Rourke provides a \f$\theta(n)\f$ algorithm for finding the minimal
* enclosing triangle of a 2D convex polygon with n vertices. Since the #minEnclosingTriangle function
* takes a 2D point set as input an additional preprocessing step of computing the convex hull of the
* 2D point set is required. The complexity of the #convexHull function is \f$O(n log(n))\f$ which is higher
* than \f$\theta(n)\f$. Thus the overall complexity of the function is \f$O(n log(n))\f$.
*
* @param points Input vector of 2D points with depth CV_32S or CV_32F, stored in std::vector\<\> or Mat
* @param triangle Output vector of three 2D points defining the vertices of the triangle. The depth
* of the OutputArray must be CV_32F.
*/
CV_EXPORTS_W double minEnclosingTriangle( InputArray points, CV_OUT OutputArray triangle );
/**
* @brief Finds a convex polygon of minimum area enclosing a 2D point set and returns its area.
*
* This function takes a given set of 2D points and finds the enclosing polygon with k vertices and minimal
* area. It takes the set of points and the parameter k as input and returns the area of the minimal
* enclosing polygon.
*
* The Implementation is based on a paper by Aggarwal, Chang and Yap @cite Aggarwal1985. They
* provide a \f$\theta(n²log(n)log(k))\f$ algorithm for finding the minimal convex polygon with k
* vertices enclosing a 2D convex polygon with n vertices (k < n). Since the #minEnclosingConvexPolygon
* function takes a 2D point set as input, an additional preprocessing step of computing the convex hull
* of the 2D point set is required. The complexity of the #convexHull function is \f$O(n log(n))\f$ which
* is lower than \f$\theta(n²log(n)log(k))\f$. Thus the overall complexity of the function is
* \f$O(n²log(n)log(k))\f$.
*
* @param points Input vector of 2D points, stored in std::vector\<\> or Mat
* @param polygon Output vector of 2D points defining the vertices of the enclosing polygon
* @param k Number of vertices of the output polygon
*/
CV_EXPORTS_W double minEnclosingConvexPolygon ( InputArray points, OutputArray polygon, int k );
/** @brief Calculates all of the moments up to the third order of a polygon or rasterized shape.
*
* The function computes moments, up to the 3rd order, of a vector shape or a rasterized shape. The
* results are returned in the structure cv::Moments.
*
* @param array Single channel raster image (CV_8U, CV_16U, CV_16S, CV_32F, CV_64F) or an array (
* \f$1 \times N\f$ or \f$N \times 1\f$ ) of 2D points (Point or Point2f).
* @param binaryImage If it is true, all non-zero image pixels are treated as 1's. The parameter is
* used for images only.
* @returns moments.
*
* @note Only applicable to contour moments calculations from Python bindings: Note that the numpy
* type for the input array should be either np.int32 or np.float32.
*
* @note For contour-based moments, the zeroth-order moment \c m00 represents
* the contour area.
*
* If the input contour is degenerate (for example, a single point or all points
* are collinear), the area is zero and therefore \c m00 == 0.
*
* In this case, the centroid coordinates (\c m10/m00, \c m01/m00) are undefined
* and must be handled explicitly by the caller.
*
* A common workaround is to compute the center using cv::boundingRect() or by
* averaging the input points.
*
* @sa contourArea, arcLength
*/
CV_EXPORTS_W Moments moments( InputArray array, bool binaryImage = false );
/** @brief Calculates seven Hu invariants.
*
* The function calculates seven Hu invariants (introduced in @cite Hu62; see also
* <https://en.wikipedia.org/wiki/Image_moment>) defined as:
*
* \f[\begin{array}{l} hu[0]= \eta _{20}+ \eta _{02} \\ hu[1]=( \eta _{20}- \eta _{02})^{2}+4 \eta _{11}^{2} \\ hu[2]=( \eta _{30}-3 \eta _{12})^{2}+ (3 \eta _{21}- \eta _{03})^{2} \\ hu[3]=( \eta _{30}+ \eta _{12})^{2}+ ( \eta _{21}+ \eta _{03})^{2} \\ hu[4]=( \eta _{30}-3 \eta _{12})( \eta _{30}+ \eta _{12})[( \eta _{30}+ \eta _{12})^{2}-3( \eta _{21}+ \eta _{03})^{2}]+(3 \eta _{21}- \eta _{03})( \eta _{21}+ \eta _{03})[3( \eta _{30}+ \eta _{12})^{2}-( \eta _{21}+ \eta _{03})^{2}] \\ hu[5]=( \eta _{20}- \eta _{02})[( \eta _{30}+ \eta _{12})^{2}- ( \eta _{21}+ \eta _{03})^{2}]+4 \eta _{11}( \eta _{30}+ \eta _{12})( \eta _{21}+ \eta _{03}) \\ hu[6]=(3 \eta _{21}- \eta _{03})( \eta _{21}+ \eta _{03})[3( \eta _{30}+ \eta _{12})^{2}-( \eta _{21}+ \eta _{03})^{2}]-( \eta _{30}-3 \eta _{12})( \eta _{21}+ \eta _{03})[3( \eta _{30}+ \eta _{12})^{2}-( \eta _{21}+ \eta _{03})^{2}] \\ \end{array}\f]
*
* where \f$\eta_{ji}\f$ stands for \f$\texttt{Moments::nu}_{ji}\f$ .
*
* These values are proved to be invariants to the image scale, rotation, and reflection except the
* seventh one, whose sign is changed by reflection. This invariance is proved with the assumption of
* infinite image resolution. In case of raster images, the computed Hu invariants for the original and
* transformed images are a bit different.
*
* @param moments Input moments computed with moments .
* @param hu Output Hu invariants.
*
* @sa matchShapes
*/
CV_EXPORTS void HuMoments( const Moments& moments, double hu[7] );
/** @overload */
CV_EXPORTS_W void HuMoments( const Moments& m, OutputArray hu );
/** @brief Compares two shapes.
*
* The function compares two shapes. All three implemented methods use the Hu invariants (see #HuMoments)
*
* @param contour1 First contour or grayscale image.
* @param contour2 Second contour or grayscale image.
* @param method Comparison method, see #ShapeMatchModes
* @param parameter Method-specific parameter (not supported now).
*/
CV_EXPORTS_W double matchShapes( InputArray contour1, InputArray contour2,
int method, double parameter );
/** @example samples/cpp/geometry.cpp
* An example program illustrates the use of cv::convexHull, cv::fitEllipse, cv::minEnclosingTriangle, cv::minEnclosingCircle and cv::minAreaRect.
*/
/** @brief Finds the convex hull of a point set.
*
* The function cv::convexHull finds the convex hull of a 2D point set using the Sklansky's algorithm @cite Sklansky82
* that has *O(N logN)* complexity in the current implementation.
*
* @param points Input 2D point set, stored in std::vector or Mat.
* @param hull Output convex hull. It is either an integer vector of indices or vector of points. In
* the first case, the hull elements are 0-based indices of the convex hull points in the original
* array (since the set of convex hull points is a subset of the original point set). In the second
* case, hull elements are the convex hull points themselves.
* @param clockwise Orientation flag. If it is true, the output convex hull is oriented clockwise.
* Otherwise, it is oriented counter-clockwise. The assumed coordinate system has its X axis pointing
* to the right, and its Y axis pointing upwards.
* @param returnPoints Operation flag. In case of a matrix, when the flag is true, the function
* returns convex hull points. Otherwise, it returns indices of the convex hull points. When the
* output array is std::vector, the flag is ignored, and the output depends on the type of the
* vector: std::vector\<int\> implies returnPoints=false, std::vector\<Point\> implies
* returnPoints=true.
*
* @note `points` and `hull` should be different arrays, inplace processing isn't supported.
*
* Check @ref tutorial_hull "the corresponding tutorial" for more details.
*
* useful links:
*
* https://www.learnopencv.com/convex-hull-using-opencv-in-python-and-c/
*/
CV_EXPORTS_W void convexHull( InputArray points, OutputArray hull,
bool clockwise = false, bool returnPoints = true );
/** @brief Finds the convexity defects of a contour.
*
* The figure below displays convexity defects of a hand contour:
*
* ![image](pics/defects.png)
*
* @param contour Input contour.
* @param convexhull Convex hull obtained using convexHull that should contain indices of the contour
* points that make the hull.
* @param convexityDefects The output vector of convexity defects. In C++ and the new Python/Java
* interface each convexity defect is represented as 4-element integer vector (a.k.a. #Vec4i):
* (start_index, end_index, farthest_pt_index, fixpt_depth), where indices are 0-based indices
* in the original contour of the convexity defect beginning, end and the farthest point, and
* fixpt_depth is fixed-point approximation (with 8 fractional bits) of the distance between the
* farthest contour point and the hull. That is, to get the floating-point value of the depth will be
* fixpt_depth/256.0.
*/
CV_EXPORTS_W void convexityDefects( InputArray contour, InputArray convexhull, OutputArray convexityDefects );
/** @brief Tests a contour convexity.
*
* The function tests whether the input contour is convex or not. The contour must be simple, that is,
* without self-intersections. Otherwise, the function output is undefined.
*
* @param contour Input vector of 2D points, stored in std::vector\<\> or Mat
*/
CV_EXPORTS_W bool isContourConvex( InputArray contour );
/** @example samples/cpp/snippets/intersectExample.cpp
* Examples of how intersectConvexConvex works
*/
/** @brief Finds intersection of two convex polygons
*
* @param p1 First polygon
* @param p2 Second polygon
* @param p12 Output polygon describing the intersecting area
* @param handleNested When true, an intersection is found if one of the polygons is fully enclosed in the other.
* When false, no intersection is found. If the polygons share a side or the vertex of one polygon lies on an edge
* of the other, they are not considered nested and an intersection will be found regardless of the value of handleNested.
*
* @returns Area of intersecting polygon. May be negative, if algorithm has not converged, e.g. non-convex input.
*
* @note intersectConvexConvex doesn't confirm that both polygons are convex and will return invalid results if they aren't.
*/
CV_EXPORTS_W float intersectConvexConvex( InputArray p1, InputArray p2,
OutputArray p12, bool handleNested = true );
/** @brief Fits an ellipse around a set of 2D points.
*
* The function calculates the ellipse that fits (in a least-squares sense) a set of 2D points best of
* all. It returns the rotated rectangle in which the ellipse is inscribed. The first algorithm described by @cite Fitzgibbon95
* is used. Developer should keep in mind that it is possible that the returned
* ellipse/rotatedRect data contains negative indices, due to the data points being close to the
* border of the containing Mat element.
*
* @param points Input 2D point set, stored in std::vector\<\> or Mat
*
* @note Input point types are @ref Point2i or @ref Point2f and at least 5 points are required.
* @note @ref getClosestEllipsePoints function can be used to compute the ellipse fitting error.
*/
CV_EXPORTS_W RotatedRect fitEllipse( InputArray points );
/** @brief Fits an ellipse around a set of 2D points.
*
* The function calculates the ellipse that fits a set of 2D points.
* It returns the rotated rectangle in which the ellipse is inscribed.
* The Approximate Mean Square (AMS) proposed by @cite Taubin1991 is used.
*
* For an ellipse, this basis set is \f$ \chi= \left(x^2, x y, y^2, x, y, 1\right) \f$,
* which is a set of six free coefficients \f$ A^T=\left\{A_{\text{xx}},A_{\text{xy}},A_{\text{yy}},A_x,A_y,A_0\right\} \f$.
* However, to specify an ellipse, all that is needed is five numbers; the major and minor axes lengths \f$ (a,b) \f$,
* the position \f$ (x_0,y_0) \f$, and the orientation \f$ \theta \f$. This is because the basis set includes lines,
* quadratics, parabolic and hyperbolic functions as well as elliptical functions as possible fits.
* If the fit is found to be a parabolic or hyperbolic function then the standard #fitEllipse method is used.
* The AMS method restricts the fit to parabolic, hyperbolic and elliptical curves
* by imposing the condition that \f$ A^T ( D_x^T D_x + D_y^T D_y) A = 1 \f$ where
* the matrices \f$ Dx \f$ and \f$ Dy \f$ are the partial derivatives of the design matrix \f$ D \f$ with
* respect to x and y. The matrices are formed row by row applying the following to
* each of the points in the set:
* \f{align*}{
* D(i,:)&=\left\{x_i^2, x_i y_i, y_i^2, x_i, y_i, 1\right\} &
* D_x(i,:)&=\left\{2 x_i,y_i,0,1,0,0\right\} &
* D_y(i,:)&=\left\{0,x_i,2 y_i,0,1,0\right\}
* \f}
* The AMS method minimizes the cost function
* \f{equation*}{
* \epsilon ^2=\frac{ A^T D^T D A }{ A^T (D_x^T D_x + D_y^T D_y) A^T }
* \f}
*
* The minimum cost is found by solving the generalized eigenvalue problem.
*
* \f{equation*}{
* D^T D A = \lambda \left( D_x^T D_x + D_y^T D_y\right) A
* \f}
*
* @param points Input 2D point set, stored in std::vector\<\> or Mat
*
* @note Input point types are @ref Point2i or @ref Point2f and at least 5 points are required.
* @note @ref getClosestEllipsePoints function can be used to compute the ellipse fitting error.
*/
CV_EXPORTS_W RotatedRect fitEllipseAMS( InputArray points );
/** @brief Fits an ellipse around a set of 2D points.
*
* The function calculates the ellipse that fits a set of 2D points.
* It returns the rotated rectangle in which the ellipse is inscribed.
* The Direct least square (Direct) method by @cite oy1998NumericallySD is used.
*
* For an ellipse, this basis set is \f$ \chi= \left(x^2, x y, y^2, x, y, 1\right) \f$,
* which is a set of six free coefficients \f$ A^T=\left\{A_{\text{xx}},A_{\text{xy}},A_{\text{yy}},A_x,A_y,A_0\right\} \f$.
* However, to specify an ellipse, all that is needed is five numbers; the major and minor axes lengths \f$ (a,b) \f$,
* the position \f$ (x_0,y_0) \f$, and the orientation \f$ \theta \f$. This is because the basis set includes lines,
* quadratics, parabolic and hyperbolic functions as well as elliptical functions as possible fits.
* The Direct method confines the fit to ellipses by ensuring that \f$ 4 A_{xx} A_{yy}- A_{xy}^2 > 0 \f$.
* The condition imposed is that \f$ 4 A_{xx} A_{yy}- A_{xy}^2=1 \f$ which satisfies the inequality
* and as the coefficients can be arbitrarily scaled is not overly restrictive.
*
* \f{equation*}{
* \epsilon ^2= A^T D^T D A \quad \text{with} \quad A^T C A =1 \quad \text{and} \quad C=\left(\begin{matrix}
* 0 & 0 & 2 & 0 & 0 & 0 \\
* 0 & -1 & 0 & 0 & 0 & 0 \\
* 2 & 0 & 0 & 0 & 0 & 0 \\
* 0 & 0 & 0 & 0 & 0 & 0 \\
* 0 & 0 & 0 & 0 & 0 & 0 \\
* 0 & 0 & 0 & 0 & 0 & 0
* \end{matrix} \right)
* \f}
*
* The minimum cost is found by solving the generalized eigenvalue problem.
*
* \f{equation*}{
* D^T D A = \lambda \left( C\right) A
* \f}
*
* The system produces only one positive eigenvalue \f$ \lambda\f$ which is chosen as the solution
* with its eigenvector \f$\mathbf{u}\f$. These are used to find the coefficients
*
* \f{equation*}{
* A = \sqrt{\frac{1}{\mathbf{u}^T C \mathbf{u}}} \mathbf{u}
* \f}
* The scaling factor guarantees that \f$A^T C A =1\f$.
*
* @param points Input 2D point set, stored in std::vector\<\> or Mat
*
* @note Input point types are @ref Point2i or @ref Point2f and at least 5 points are required.
* @note @ref getClosestEllipsePoints function can be used to compute the ellipse fitting error.
*/
CV_EXPORTS_W RotatedRect fitEllipseDirect( InputArray points );
/** @example samples/python/snippets/fitline.py
* An example for fitting line in python
*/
/** @brief Compute for each 2d point the nearest 2d point located on a given ellipse.
*
* The function computes the nearest 2d location on a given ellipse for a vector of 2d points and is based on @cite Chatfield2017 code.
* This function can be used to compute for instance the ellipse fitting error.
*
* @param ellipse_params Ellipse parameters
* @param points Input 2d points
* @param closest_pts For each 2d point, their corresponding closest 2d point located on a given ellipse
*
* @note Input point types are @ref Point2i or @ref Point2f
* @see fitEllipse, fitEllipseAMS, fitEllipseDirect
*/
CV_EXPORTS_W void getClosestEllipsePoints( const RotatedRect& ellipse_params, InputArray points, OutputArray closest_pts );
/** @brief Fits a line to a 2D or 3D point set.
*
* The function fitLine fits a line to a 2D or 3D point set by minimizing \f$\sum_i \rho(r_i)\f$ where
* \f$r_i\f$ is a distance between the \f$i^{th}\f$ point, the line and \f$\rho(r)\f$ is a distance function, one
* of the following:
* - DIST_L2
* \f[\rho (r) = r^2/2 \quad \text{(the simplest and the fastest least-squares method)}\f]
* - DIST_L1
* \f[\rho (r) = r\f]
* - DIST_L12
* \f[\rho (r) = 2 \cdot ( \sqrt{1 + \frac{r^2}{2}} - 1)\f]
* - DIST_FAIR
* \f[\rho \left (r \right ) = C^2 \cdot \left ( \frac{r}{C} - \log{\left(1 + \frac{r}{C}\right)} \right ) \quad \text{where} \quad C=1.3998\f]
* - DIST_WELSCH
* \f[\rho \left (r \right ) = \frac{C^2}{2} \cdot \left ( 1 - \exp{\left(-\left(\frac{r}{C}\right)^2\right)} \right ) \quad \text{where} \quad C=2.9846\f]
* - DIST_HUBER
* \f[\rho (r) = \fork{r^2/2}{if \(r < C\)}{C \cdot (r-C/2)}{otherwise} \quad \text{where} \quad C=1.345\f]
*
* The algorithm is based on the M-estimator ( <https://en.wikipedia.org/wiki/M-estimator> ) technique
* that iteratively fits the line using the weighted least-squares algorithm. After each iteration the
* weights \f$w_i\f$ are adjusted to be inversely proportional to \f$\rho(r_i)\f$ .
*
* @param points Input vector of 2D or 3D points, stored in std::vector\<\> or Mat.
* @param line Output line parameters. In case of 2D fitting, it should be a vector of 4 elements
* (like Vec4f) - (vx, vy, x0, y0), where (vx, vy) is a normalized vector collinear to the line and
* (x0, y0) is a point on the line. In case of 3D fitting, it should be a vector of 6 elements (like
* Vec6f) - (vx, vy, vz, x0, y0, z0), where (vx, vy, vz) is a normalized vector collinear to the line
* and (x0, y0, z0) is a point on the line.
* @param distType Distance used by the M-estimator, see #DistanceTypes
* @param param Numerical parameter ( C ) for some types of distances. If it is 0, an optimal value
* is chosen.
* @param reps Sufficient accuracy for the radius (distance between the coordinate origin and the line).
* @param aeps Sufficient accuracy for the angle. 0.01 would be a good default value for reps and aeps.
*/
CV_EXPORTS_W void fitLine( InputArray points, OutputArray line, int distType,
double param, double reps, double aeps );
/** @brief Performs a point-in-contour test.
*
* The function determines whether the point is inside a contour, outside, or lies on an edge (or
* coincides with a vertex). It returns positive (inside), negative (outside), or zero (on an edge)
* value, correspondingly. When measureDist=false , the return value is +1, -1, and 0, respectively.
* Otherwise, the return value is a signed distance between the point and the nearest contour edge.
*
* See below a sample output of the function where each image pixel is tested against the contour:
*
* ![sample output](pics/pointpolygon.png)
*
* @param contour Input contour.
* @param pt Point tested against the contour.
* @param measureDist If true, the function estimates the signed distance from the point to the
* nearest contour edge. Otherwise, the function only checks if the point is inside a contour or not.
*/
CV_EXPORTS_W double pointPolygonTest( InputArray contour, Point2f pt, bool measureDist );
/** @brief Finds out if there is any intersection between two rotated rectangles.
*
* If there is then the vertices of the intersecting region are returned as well.
*
* Below are some examples of intersection configurations. The hatched pattern indicates the
* intersecting region and the red vertices are returned by the function.
*
* ![intersection examples](pics/intersection.png)
*
* @param rect1 First rectangle
* @param rect2 Second rectangle
* @param intersectingRegion The output array of the vertices of the intersecting region. It returns
* at most 8 vertices. Stored as std::vector\<cv::Point2f\> or cv::Mat as Mx1 of type CV_32FC2.
* @returns One of #RectanglesIntersectTypes
*/
CV_EXPORTS_W int rotatedRectangleIntersection( const RotatedRect& rect1, const RotatedRect& rect2, OutputArray intersectingRegion );
/** @brief Calculates a contour perimeter or a curve length.
*
* The function computes a curve length or a closed contour perimeter.
*
* @param curve Input vector of 2D points, stored in std::vector or Mat.
* @param closed Flag indicating whether the curve is closed or not.
*/
CV_EXPORTS_W double arcLength( InputArray curve, bool closed );
/** @brief Calculates a contour area.
*
* The function computes a contour area. Similarly to moments , the area is computed using the Green
* formula. Thus, the returned area and the number of non-zero pixels, if you draw the contour using
* #drawContours or #fillPoly , can be different. Also, the function will most certainly give a wrong
* results for contours with self-intersections.
*
* Example:
* @code
* vector<Point> contour;
* contour.push_back(Point2f(0, 0));
* contour.push_back(Point2f(10, 0));
* contour.push_back(Point2f(10, 10));
* contour.push_back(Point2f(5, 4));
*
* double area0 = contourArea(contour);
* vector<Point> approx;
* approxPolyDP(contour, approx, 5, true);
* double area1 = contourArea(approx);
*
* cout << "area0 =" << area0 << endl <<
* "area1 =" << area1 << endl <<
* "approx poly vertices" << approx.size() << endl;
* @endcode
* @param contour Input vector of 2D points (contour vertices), stored in std::vector or Mat.
* @param oriented Oriented area flag. If it is true, the function returns a signed area value,
* depending on the contour orientation (clockwise or counter-clockwise). Using this feature you can
* determine orientation of a contour by taking the sign of an area. By default, the parameter is
* false, which means that the absolute value is returned.
*/
CV_EXPORTS_W double contourArea( InputArray contour, bool oriented = false );
/** @brief Calculates the up-right bounding rectangle of a point set or non-zero pixels of gray-scale image.
*
* The function calculates and returns the minimal up-right bounding rectangle for the specified point set or
* non-zero pixels of gray-scale image.
*
* @param array Input gray-scale image or 2D point set, stored in std::vector or Mat.
*/
CV_EXPORTS_W Rect boundingRect( InputArray array );
/** @brief Calculates an affine matrix of 2D rotation.
The function calculates the following matrix:
\f[\begin{bmatrix} \alpha & \beta & (1- \alpha ) \cdot \texttt{center.x} - \beta \cdot \texttt{center.y} \\ - \beta & \alpha & \beta \cdot \texttt{center.x} + (1- \alpha ) \cdot \texttt{center.y} \end{bmatrix}\f]
where
\f[\begin{array}{l} \alpha = \texttt{scale} \cdot \cos \texttt{angle} , \\ \beta = \texttt{scale} \cdot \sin \texttt{angle} \end{array}\f]
The transformation maps the rotation center to itself. If this is not the target, adjust the shift.
@param center Center of the rotation in the source image.
@param angle Rotation angle in degrees. Positive values mean counter-clockwise rotation (the
coordinate origin is assumed to be the top-left corner).
@param scale Isotropic scale factor.
@sa getAffineTransform, warpAffine, transform
*/
CV_EXPORTS_W Mat getRotationMatrix2D(Point2f center, double angle, double scale);
/** @sa getRotationMatrix2D */
CV_EXPORTS Matx23d getRotationMatrix2D_(Point2f center, double angle, double scale);
inline
Mat getRotationMatrix2D(Point2f center, double angle, double scale)
{
return Mat(getRotationMatrix2D_(center, angle, scale), true);
}
/** @brief Calculates an affine transform from three pairs of the corresponding points.
*
* The function calculates the \f$2 \times 3\f$ matrix of an affine transform so that:
*
* \f[\begin{bmatrix} x'_i \\ y'_i \end{bmatrix} = \texttt{map_matrix} \cdot \begin{bmatrix} x_i \\ y_i \\ 1 \end{bmatrix}\f]
*
* where
*
* \f[dst(i)=(x'_i,y'_i), src(i)=(x_i, y_i), i=0,1,2\f]
*
* @param src Coordinates of triangle vertices in the source image.
* @param dst Coordinates of the corresponding triangle vertices in the destination image.
*
* @sa warpAffine, transform
*/
CV_EXPORTS Mat getAffineTransform( const Point2f src[], const Point2f dst[] );
/** @brief Inverts an affine transformation.
*
* The function computes an inverse affine transformation represented by \f$2 \times 3\f$ matrix M:
*
* \f[\begin{bmatrix} a_{11} & a_{12} & b_1 \\ a_{21} & a_{22} & b_2 \end{bmatrix}\f]
*
* The result is also a \f$2 \times 3\f$ matrix of the same type as M.
*
* @param M Original affine transformation.
* @param iM Output reverse affine transformation.
*/
CV_EXPORTS_W void invertAffineTransform( InputArray M, OutputArray iM );
/** @brief Calculates a perspective transform from four pairs of the corresponding points.
*
* The function calculates the \f$3 \times 3\f$ matrix of a perspective transform so that:
*
* \f[\begin{bmatrix} t_i x'_i \\ t_i y'_i \\ t_i \end{bmatrix} = \texttt{map_matrix} \cdot \begin{bmatrix} x_i \\ y_i \\ 1 \end{bmatrix}\f]
*
* where
*
* \f[dst(i)=(x'_i,y'_i), src(i)=(x_i, y_i), i=0,1,2,3\f]
*
* @param src Coordinates of quadrangle vertices in the source image.
* @param dst Coordinates of the corresponding quadrangle vertices in the destination image.
* @param solveMethod method passed to cv::solve (#DecompTypes)
*
* @sa findHomography, warpPerspective, perspectiveTransform
*/
CV_EXPORTS_W Mat getPerspectiveTransform(InputArray src, InputArray dst, int solveMethod = DECOMP_LU);
/** @overload */
CV_EXPORTS Mat getPerspectiveTransform(const Point2f src[], const Point2f dst[], int solveMethod = DECOMP_LU);
CV_EXPORTS_W Mat getAffineTransform( InputArray src, InputArray dst );
} // namespace cv
#endif // OPENCV_2D_HPP
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,395 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#ifndef OPENCV_IMGPROC_DETAIL_GCGRAPH_HPP
#define OPENCV_IMGPROC_DETAIL_GCGRAPH_HPP
//! @cond IGNORED
namespace cv { namespace detail {
template <class TWeight> class GCGraph
{
public:
GCGraph();
GCGraph( unsigned int vtxCount, unsigned int edgeCount );
~GCGraph();
void create( unsigned int vtxCount, unsigned int edgeCount );
int addVtx();
void addEdges( int i, int j, TWeight w, TWeight revw );
void addTermWeights( int i, TWeight sourceW, TWeight sinkW );
TWeight maxFlow();
bool inSourceSegment( int i );
private:
class Vtx
{
public:
Vtx *next; // initialized and used in maxFlow() only
int parent;
int first;
int ts;
int dist;
TWeight weight;
uchar t;
};
class Edge
{
public:
int dst;
int next;
TWeight weight;
};
std::vector<Vtx> vtcs;
std::vector<Edge> edges;
TWeight flow;
};
template <class TWeight>
GCGraph<TWeight>::GCGraph()
{
flow = 0;
}
template <class TWeight>
GCGraph<TWeight>::GCGraph( unsigned int vtxCount, unsigned int edgeCount )
{
create( vtxCount, edgeCount );
}
template <class TWeight>
GCGraph<TWeight>::~GCGraph()
{
}
template <class TWeight>
void GCGraph<TWeight>::create( unsigned int vtxCount, unsigned int edgeCount )
{
vtcs.reserve( vtxCount );
edges.reserve( edgeCount + 2 );
flow = 0;
}
template <class TWeight>
int GCGraph<TWeight>::addVtx()
{
Vtx v;
memset( &v, 0, sizeof(Vtx));
vtcs.push_back(v);
return (int)vtcs.size() - 1;
}
template <class TWeight>
void GCGraph<TWeight>::addEdges( int i, int j, TWeight w, TWeight revw )
{
CV_Assert( i>=0 && i<(int)vtcs.size() );
CV_Assert( j>=0 && j<(int)vtcs.size() );
CV_Assert( w>=0 && revw>=0 );
CV_Assert( i != j );
if( !edges.size() )
edges.resize( 2 );
Edge fromI, toI;
fromI.dst = j;
fromI.next = vtcs[i].first;
fromI.weight = w;
vtcs[i].first = (int)edges.size();
edges.push_back( fromI );
toI.dst = i;
toI.next = vtcs[j].first;
toI.weight = revw;
vtcs[j].first = (int)edges.size();
edges.push_back( toI );
}
template <class TWeight>
void GCGraph<TWeight>::addTermWeights( int i, TWeight sourceW, TWeight sinkW )
{
CV_Assert( i>=0 && i<(int)vtcs.size() );
TWeight dw = vtcs[i].weight;
if( dw > 0 )
sourceW += dw;
else
sinkW -= dw;
flow += (sourceW < sinkW) ? sourceW : sinkW;
vtcs[i].weight = sourceW - sinkW;
}
template <class TWeight>
TWeight GCGraph<TWeight>::maxFlow()
{
CV_Assert(!vtcs.empty());
CV_Assert(!edges.empty());
const int TERMINAL = -1, ORPHAN = -2;
Vtx stub, *nilNode = &stub, *first = nilNode, *last = nilNode;
int curr_ts = 0;
stub.next = nilNode;
Vtx *vtxPtr = &vtcs[0];
Edge *edgePtr = &edges[0];
std::vector<Vtx*> orphans;
// initialize the active queue and the graph vertices
for( int i = 0; i < (int)vtcs.size(); i++ )
{
Vtx* v = vtxPtr + i;
v->ts = 0;
if( v->weight != 0 )
{
last = last->next = v;
v->dist = 1;
v->parent = TERMINAL;
v->t = v->weight < 0;
}
else
v->parent = 0;
}
first = first->next;
last->next = nilNode;
nilNode->next = 0;
// run the search-path -> augment-graph -> restore-trees loop
for(;;)
{
Vtx* v, *u;
int e0 = -1, ei = 0, ej = 0;
TWeight minWeight, weight;
uchar vt;
// grow S & T search trees, find an edge connecting them
while( first != nilNode )
{
v = first;
if( v->parent )
{
vt = v->t;
for( ei = v->first; ei != 0; ei = edgePtr[ei].next )
{
if( edgePtr[ei^vt].weight == 0 )
continue;
u = vtxPtr+edgePtr[ei].dst;
if( !u->parent )
{
u->t = vt;
u->parent = ei ^ 1;
u->ts = v->ts;
u->dist = v->dist + 1;
if( !u->next )
{
u->next = nilNode;
last = last->next = u;
}
continue;
}
if( u->t != vt )
{
e0 = ei ^ vt;
break;
}
if( u->dist > v->dist+1 && u->ts <= v->ts )
{
// reassign the parent
u->parent = ei ^ 1;
u->ts = v->ts;
u->dist = v->dist + 1;
}
}
if( e0 > 0 )
break;
}
// exclude the vertex from the active list
first = first->next;
v->next = 0;
}
if( e0 <= 0 )
break;
// find the minimum edge weight along the path
minWeight = edgePtr[e0].weight;
CV_Assert( minWeight > 0 );
// k = 1: source tree, k = 0: destination tree
for( int k = 1; k >= 0; k-- )
{
for( v = vtxPtr+edgePtr[e0^k].dst;; v = vtxPtr+edgePtr[ei].dst )
{
if( (ei = v->parent) < 0 )
break;
weight = edgePtr[ei^k].weight;
minWeight = MIN(minWeight, weight);
CV_Assert( minWeight > 0 );
}
weight = fabs(v->weight);
minWeight = MIN(minWeight, weight);
CV_Assert( minWeight > 0 );
}
// modify weights of the edges along the path and collect orphans
edgePtr[e0].weight -= minWeight;
edgePtr[e0^1].weight += minWeight;
flow += minWeight;
// k = 1: source tree, k = 0: destination tree
for( int k = 1; k >= 0; k-- )
{
for( v = vtxPtr+edgePtr[e0^k].dst;; v = vtxPtr+edgePtr[ei].dst )
{
if( (ei = v->parent) < 0 )
break;
edgePtr[ei^(k^1)].weight += minWeight;
if( (edgePtr[ei^k].weight -= minWeight) == 0 )
{
orphans.push_back(v);
v->parent = ORPHAN;
}
}
v->weight = v->weight + minWeight*(1-k*2);
if( v->weight == 0 )
{
orphans.push_back(v);
v->parent = ORPHAN;
}
}
// restore the search trees by finding new parents for the orphans
curr_ts++;
while( !orphans.empty() )
{
Vtx* v2 = orphans.back();
orphans.pop_back();
int d, minDist = INT_MAX;
e0 = 0;
vt = v2->t;
for( ei = v2->first; ei != 0; ei = edgePtr[ei].next )
{
if( edgePtr[ei^(vt^1)].weight == 0 )
continue;
u = vtxPtr+edgePtr[ei].dst;
if( u->t != vt || u->parent == 0 )
continue;
// compute the distance to the tree root
for( d = 0;; )
{
if( u->ts == curr_ts )
{
d += u->dist;
break;
}
ej = u->parent;
d++;
if( ej < 0 )
{
if( ej == ORPHAN )
d = INT_MAX-1;
else
{
u->ts = curr_ts;
u->dist = 1;
}
break;
}
u = vtxPtr+edgePtr[ej].dst;
}
// update the distance
if( ++d < INT_MAX )
{
if( d < minDist )
{
minDist = d;
e0 = ei;
}
for( u = vtxPtr+edgePtr[ei].dst; u->ts != curr_ts; u = vtxPtr+edgePtr[u->parent].dst )
{
u->ts = curr_ts;
u->dist = --d;
}
}
}
if( (v2->parent = e0) > 0 )
{
v2->ts = curr_ts;
v2->dist = minDist;
continue;
}
/* no parent is found */
v2->ts = 0;
for( ei = v2->first; ei != 0; ei = edgePtr[ei].next )
{
u = vtxPtr+edgePtr[ei].dst;
ej = u->parent;
if( u->t != vt || !ej )
continue;
if( edgePtr[ei^(vt^1)].weight && !u->next )
{
u->next = nilNode;
last = last->next = u;
}
if( ej > 0 && vtxPtr+edgePtr[ej].dst == v2 )
{
orphans.push_back(u);
u->parent = ORPHAN;
}
}
}
}
return flow;
}
template <class TWeight>
bool GCGraph<TWeight>::inSourceSegment( int i )
{
CV_Assert( i>=0 && i<(int)vtcs.size() );
return vtcs[i].t == 0;
}
}} // namespace detail, cv
//! @endcond
#endif // OPENCV_IMGPROC_DETAIL_GCGRAPH_HPP
@@ -0,0 +1,91 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html
#ifndef OPENCV_3D_DETAIL_OPTIMIZER_HPP
#define OPENCV_3D_DETAIL_OPTIMIZER_HPP
#include "opencv2/core/affine.hpp"
#include "opencv2/core/quaternion.hpp"
#include "opencv2/geometry/3d.hpp"
namespace cv
{
namespace detail
{
/*
This class provides functions required for Levenberg-Marquadt algorithm implementation.
See LevMarqBase::optimize() source code for details.
*/
class CV_EXPORTS LevMarqBackend
{
public:
virtual ~LevMarqBackend() { }
// enables geodesic acceleration support in a backend, returns true on success
virtual bool enableGeo() = 0;
// calculates an energy and/or jacobian at probe param vector
virtual bool calcFunc(double& energy, bool calcEnergy = true, bool calcJacobian = false) = 0;
// adds x to current variables and writes the sum to probe var
// or to geodesic acceleration var if geo flag is set
virtual void currentOplusX(const Mat_<double>& x, bool geo = false) = 0;
// allocates jtj, jtb and other resources for objective function calculation, sets probeX to current X
virtual void prepareVars() = 0;
// returns a J^T*b vector (aka gradient)
virtual const Mat_<double> getJtb() = 0;
// returns a J^T*J diagonal vector
virtual const Mat_<double> getDiag() = 0;
// sets a J^T*J diagonal
virtual void setDiag(const Mat_<double>& d) = 0;
// performs jacobi scaling if the option is turned on
virtual void doJacobiScaling(const Mat_<double>& di) = 0;
// decomposes LevMarq matrix before solution
virtual bool decompose() = 0;
// solves LevMarq equation (J^T*J + lmdiag) * x = -right for current iteration using existing decomposition
// right can be equal to J^T*b for LevMarq equation or J^T*rvv for geodesic acceleration equation
virtual bool solveDecomposed(const Mat_<double>& right, Mat_<double>& x) = 0;
// calculates J^T*f(geo) where geo is geodesic acceleration variable
// this is used for J^T*rvv calculation for geodesic acceleration
// calculates J^T*rvv where rvv is second directional derivative of the function in direction v
// rvv = (f(x0 + v*h) - f(x0))/h - J*v)/h
// where v is a LevMarq equation solution
virtual bool calcJtbv(Mat_<double>& jtbv) = 0;
// sets current params vector to probe params
virtual void acceptProbe() = 0;
};
/** @brief Base class for Levenberg-Marquadt solvers.
This class can be used for general local optimization using sparse linear solvers, exponential param update or fixed variables
implemented in child classes.
This base class does not depend on a type, layout or a group structure of a param vector or an objective function jacobian.
A child class should provide a storage for that data and implement all virtual member functions that process it.
This class does not support fixed/masked variables, this should also be implemented in child classes.
*/
class CV_EXPORTS LevMarqBase
{
public:
virtual ~LevMarqBase() { }
// runs optimization using given termination conditions
virtual LevMarq::Report optimize();
LevMarqBase(const Ptr<LevMarqBackend>& backend_, const LevMarq::Settings& settings_):
backend(backend_), settings(settings_)
{ }
Ptr<LevMarqBackend> backend;
LevMarq::Settings settings;
};
} // namespace detail
} // namespace cv
#endif // include guard
@@ -0,0 +1,65 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html
#ifndef OPENCV_3D_MST_HPP
#define OPENCV_3D_MST_HPP
#include <vector>
namespace cv
{
/**
* @brief Represents an edge in a graph for Minimum Spanning Tree (MST) computation.
*
* Each edge connects two nodes (source and target) and has an associated weight.
*/
struct CV_EXPORTS_W_SIMPLE MSTEdge
{
CV_PROP_RW int source, target;
CV_PROP_RW double weight;
};
/**
* @brief Represents the algorithms available for building a Minimum Spanning Tree (MST).
*
* More algorithms may be added in the future.
*/
enum MSTAlgorithm
{
MST_PRIM = 0,
MST_KRUSKAL = 1
};
/**
* @brief Builds a Minimum Spanning Tree (MST) using the specified algorithm (see @ref MSTAlgorithm).
*
* Supports graphs with negative edge weights. Self-loop edges (edges where source and target are the
* same) are ignored. If multiple edges exist between the same pair of nodes, only the one with the
* lowest weight is considered. If the graph is disconnected or input is invalid, the function
* returns false.
*
* @note The @p root parameter is ignored for algorithms that do not require a starting node.
* @note Additional MST algorithms may be supported in the future via the @p algorithm parameter
* (see @ref MSTAlgorithm).
*
* @param numNodes Number of nodes in the graph (must be greater than 0).
* @param inputEdges Input vector of edges representing the graph.
* @param[out] resultingEdges Output vector to store the edges of the resulting MST.
* @param algorithm Specifies which algorithm to use to compute the MST (see @ref MSTAlgorithm).
* @param root Starting node for the MST algorithm (only used for certain algorithms).
* @return true if a valid MST was successfully built; false otherwise.
* @throws cv::Error (StsBadArg) if an invalid algorithm is specified.
*/
CV_EXPORTS_W bool buildMST(
int numNodes,
const std::vector<MSTEdge>& inputEdges,
CV_OUT std::vector<MSTEdge>& resultingEdges,
MSTAlgorithm algorithm,
int root = 0
);
} // namespace cv
#endif // include guard
@@ -0,0 +1,411 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
//
// Copyright (C) 2021, Yechun Ruan <ruanyc@mail.sustech.edu.cn>
#ifndef OPENCV_3D_PTCLOUD_HPP
#define OPENCV_3D_PTCLOUD_HPP
namespace cv {
//! @addtogroup _3d
//! @{
//! type of the robust estimation algorithm
enum SacMethod
{
/** The RANSAC algorithm described in @cite fischler1981random.
*/
SAC_METHOD_RANSAC,
// SAC_METHOD_MAGSAC,
// SAC_METHOD_LMEDS,
// SAC_METHOD_MSAC,
// SAC_METHOD_RRANSAC,
// SAC_METHOD_RMSAC,
// SAC_METHOD_MLESAC,
// SAC_METHOD_PROSAC
};
enum SacModelType
{
/** The 3D PLANE model coefficients in list **[a, b, c, d]**,
corresponding to the coefficients of equation
\f$ ax + by + cz + d = 0 \f$. */
SAC_MODEL_PLANE,
/** The 3D SPHERE model coefficients in list **[center_x, center_y, center_z, radius]**,
corresponding to the coefficients of equation
\f$ (x - center\_x)^2 + (y - center\_y)^2 + (z - center\_z)^2 = radius^2 \f$.*/
SAC_MODEL_SPHERE,
// SAC_MODEL_CYLINDER,
};
/** @brief Sample Consensus algorithm segmentation of 3D point cloud model.
Example of segmenting plane from a 3D point cloud using the RANSAC algorithm:
@snippet snippets/3d_sac_segmentation.cpp planeSegmentationUsingRANSAC
@see
1. Supported algorithms: enum SacMethod in ptcloud.hpp.
2. Supported models: enum SacModelType in ptcloud.hpp.
*/
class CV_EXPORTS SACSegmentation
{
public:
/** @brief Custom function that take the model coefficients and return whether the model is acceptable or not.
Example of constructing SACSegmentation::ModelConstraintFunction:
@snippet snippets/3d_sac_segmentation.cpp usageExampleSacModelConstraintFunction
@note The content of model_coefficients depends on the model.
Refer to the comments inside enumeration type SacModelType.
*/
using ModelConstraintFunction =
std::function<bool(const std::vector<double> &/*model_coefficients*/)>;
//-------------------------- CREATE -----------------------
static Ptr<SACSegmentation> create(SacModelType sac_model_type = SAC_MODEL_PLANE,
SacMethod sac_method = SAC_METHOD_RANSAC,
double threshold = 0.5, int max_iterations = 1000);
// -------------------------- CONSTRUCTOR, DESTRUCTOR --------------------------
SACSegmentation() = default;
virtual ~SACSegmentation() = default;
//-------------------------- SEGMENT -----------------------
/**
* @brief Execute segmentation using the sample consensus method.
*
* @param input_pts Original point cloud, vector of Point3 or Mat of size Nx3/3xN.
* @param[out] labels The label corresponds to the model number, 0 means it
* does not belong to any model, range [0, Number of final resultant models obtained].
* @param[out] models_coefficients The resultant models coefficients.
* Currently supports passing in cv::Mat. Models coefficients are placed in a matrix of NxK
* with depth CV_64F (will automatically adjust if the passing one does not look like this),
* where N is the number of models and K is the number of coefficients of one model.
* The coefficients for each model refer to the comments inside enumeration type SacModelType.
* @return Number of final resultant models obtained by segmentation.
*/
virtual int
segment(InputArray input_pts, OutputArray labels, OutputArray models_coefficients) = 0;
//-------------------------- Getter and Setter -----------------------
//! Set the type of sample consensus model to use.
virtual void setSacModelType(SacModelType sac_model_type) = 0;
//! Get the type of sample consensus model used.
virtual SacModelType getSacModelType() const = 0;
//! Set the type of sample consensus method to use.
virtual void setSacMethodType(SacMethod sac_method) = 0;
//! Get the type of sample consensus method used.
virtual SacMethod getSacMethodType() const = 0;
//! Set the distance to the model threshold.
//! Considered as inlier point if distance to the model less than threshold.
virtual void setDistanceThreshold(double threshold) = 0;
//! Get the distance to the model threshold.
virtual double getDistanceThreshold() const = 0;
//! Set the minimum and maximum radius limits for the model.
//! Only used for models whose model parameters include a radius.
virtual void setRadiusLimits(double radius_min, double radius_max) = 0;
//! Get the minimum and maximum radius limits for the model.
virtual void getRadiusLimits(double &radius_min, double &radius_max) const = 0;
//! Set the maximum number of iterations to attempt.
virtual void setMaxIterations(int max_iterations) = 0;
//! Get the maximum number of iterations to attempt.
virtual int getMaxIterations() const = 0;
//! Set the confidence that ensure at least one of selections is an error-free set of data points.
virtual void setConfidence(double confidence) = 0;
//! Get the confidence that ensure at least one of selections is an error-free set of data points.
virtual double getConfidence() const = 0;
//! Set the number of models expected.
virtual void setNumberOfModelsExpected(int number_of_models_expected) = 0;
//! Get the expected number of models.
virtual int getNumberOfModelsExpected() const = 0;
//! Set whether to use parallelism or not.
//! The number of threads is set by cv::setNumThreads(int nthreads).
virtual void setParallel(bool is_parallel) = 0;
//! Get whether to use parallelism or not.
virtual bool isParallel() const = 0;
//! Set state used to initialize the RNG(Random Number Generator).
virtual void setRandomGeneratorState(uint64 rng_state) = 0;
//! Get state used to initialize the RNG(Random Number Generator).
virtual uint64 getRandomGeneratorState() const = 0;
//! Set custom model coefficient constraint function.
//! A custom function that takes model coefficients and returns whether the model is acceptable or not.
virtual void
setCustomModelConstraints(const ModelConstraintFunction &custom_model_constraints) = 0;
//! Get custom model coefficient constraint function.
virtual const ModelConstraintFunction &getCustomModelConstraints() const = 0;
};
/**
* @brief Point cloud sampling by Voxel Grid filter downsampling.
*
* Creates a 3D voxel grid (a set of tiny 3D boxes in space) over the input
* point cloud data, in each voxel (i.e., 3D box), all the points present will be
* approximated (i.e., downsampled) with the point closest to their centroid.
*
* @param[out] sampled_point_flags Flags of the sampled point, (pass in std::vector<int> or std::vector<char> etc.)
* sampled_point_flags[i] is 1 means i-th point selected, 0 means it is not selected.
* @param input_pts Original point cloud, vector of Point3 or Mat of size Nx3/3xN.
* @param length Grid length.
* @param width Grid width.
* @param height Grid height.
* @return The number of points actually sampled.
*/
CV_EXPORTS int voxelGridSampling(OutputArray sampled_point_flags, InputArray input_pts,
float length, float width, float height);
/**
* @brief Point cloud sampling by randomly select points.
*
* Use cv::randShuffle to shuffle the point index list,
* then take the points corresponding to the front part of the list.
*
* @param sampled_pts Point cloud after sampling.
* Support cv::Mat(sampled_pts_size, 3, CV_32F), std::vector<cv::Point3f>.
* @param input_pts Original point cloud, vector of Point3 or Mat of size Nx3/3xN.
* @param sampled_pts_size The desired point cloud size after sampling.
* @param rng Optional random number generator used for cv::randShuffle;
* if it is nullptr, theRNG () is used instead.
*/
CV_EXPORTS void randomSampling(OutputArray sampled_pts, InputArray input_pts,
int sampled_pts_size, RNG *rng = nullptr);
/**
* @overload
*
* @param sampled_pts Point cloud after sampling.
* Support cv::Mat(size * sampled_scale, 3, CV_32F), std::vector<cv::Point3f>.
* @param input_pts Original point cloud, vector of Point3 or Mat of size Nx3/3xN.
* @param sampled_scale Range (0, 1), the percentage of the sampled point cloud to the original size,
* that is, sampled size = original size * sampled_scale.
* @param rng Optional random number generator used for cv::randShuffle;
* if it is nullptr, theRNG () is used instead.
*/
CV_EXPORTS void randomSampling(OutputArray sampled_pts, InputArray input_pts,
float sampled_scale, RNG *rng = nullptr);
/**
* @brief Point cloud sampling by Farthest Point Sampling(FPS).
*
* FPS Algorithm:
* + Input: Point cloud *C*, *sampled_pts_size*, *dist_lower_limit*
* + Initialize: Set sampled point cloud S to the empty set
* + Step:
* 1. Randomly take a seed point from C and take it from C to S;
* 2. Find a point in C that is the farthest away from S and take it from C to S;
* (The distance from point to set S is the smallest distance from point to all points in S)
* 3. Repeat *step 2* until the farthest distance of the point in C from S
* is less than *dist_lower_limit*, or the size of S is equal to *sampled_pts_size*.
* + Output: Sampled point cloud S
*
* @param[out] sampled_point_flags Flags of the sampled point, (pass in std::vector<int> or std::vector<char> etc.)
* sampled_point_flags[i] is 1 means i-th point selected, 0 means it is not selected.
* @param input_pts Original point cloud, vector of Point3 or Mat of size Nx3/3xN.
* @param sampled_pts_size The desired point cloud size after sampling.
* @param dist_lower_limit Sampling is terminated early if the distance from
* the farthest point to S is less than dist_lower_limit, default 0.
* @param rng Optional random number generator used for selecting seed point for FPS;
* if it is nullptr, theRNG () is used instead.
* @return The number of points actually sampled.
*/
CV_EXPORTS int farthestPointSampling(OutputArray sampled_point_flags, InputArray input_pts,
int sampled_pts_size, float dist_lower_limit = 0, RNG *rng = nullptr);
/**
* @overload
*
* @param[out] sampled_point_flags Flags of the sampled point, (pass in std::vector<int> or std::vector<char> etc.)
* sampled_point_flags[i] is 1 means i-th point selected, 0 means it is not selected.
* @param input_pts Original point cloud, vector of Point3 or Mat of size Nx3/3xN.
* @param sampled_scale Range (0, 1), the percentage of the sampled point cloud to the original size,
* that is, sampled size = original size * sampled_scale.
* @param dist_lower_limit Sampling is terminated early if the distance from
* the farthest point to S is less than dist_lower_limit, default 0.
* @param rng Optional random number generator used for selecting seed point for FPS;
* if it is nullptr, theRNG () is used instead.
* @return The number of points actually sampled.
*/
CV_EXPORTS int farthestPointSampling(OutputArray sampled_point_flags, InputArray input_pts,
float sampled_scale, float dist_lower_limit = 0, RNG *rng = nullptr);
/**
* @brief Estimate the normal and curvature of each point in point cloud from NN results.
*
* Normal estimation by PCA:
* + Input: Nearest neighbor points of a specific point: \f$ pt\_set \f$
* + Step:
* 1. Calculate the \f$ mean(\bar{x},\bar{y},\bar{z}) \f$ of \f$ pt\_set \f$;
* 2. A 3x3 covariance matrix \f$ cov \f$ is obtained by \f$ mean^T \cdot mean \f$;
* 3. Calculate the eigenvalues(\f$ λ_2 \ge λ_1 \ge λ_0 \f$) and corresponding
* eigenvectors(\f$ v_2, v_1, v_0 \f$) of \f$ cov \f$;
* 4. \f$ v0 \f$ is the normal of the specific point,
* \f$ \frac{λ_0}{λ_0 + λ_1 + λ_2} \f$ is the curvature of the specific point;
* + Output: Normal and curvature of the specific point.
*
* @param[out] normals Normal of each point, support vector<Point3f> and Mat of size Nx3.
* @param[out] curvatures Curvature of each point, support vector<float> and Mat.
* @param input_pts Original point cloud, support vector<Point3f> and Mat of size Nx3/3xN.
* @param nn_idx Index information of nearest neighbors of all points. The first nearest neighbor of
* each point is itself. Support vector<vector<int>>, vector<Mat> and Mat of size NxK.
* If the information in a row is [0, 2, 1, -5, -1, 4, 7 ... negative number], it will
* use only non-negative indexes until it meets a negative number or bound of this row
* i.e. [0, 2, 1].
* @param max_neighbor_num The maximum number of neighbors want to use including itself. Setting to
* a non-positive number or default will use the information from nn_idx.
*/
CV_EXPORTS void normalEstimate(OutputArray normals, OutputArray curvatures, InputArray input_pts,
InputArrayOfArrays nn_idx, int max_neighbor_num = 0);
/**
* @brief Region Growing algorithm in 3D point cloud.
*
* The key idea of region growing is to merge the nearest neighbor points that satisfy a certain
* angle threshold into the same region according to the normal between the two points, so as to
* achieve the purpose of segmentation. For more details, please refer to @cite Rabbani2006SegmentationOP.
*/
class CV_EXPORTS RegionGrowing3D
{
public:
//-------------------------- CREATE -----------------------
static Ptr<RegionGrowing3D> create();
// -------------------------- CONSTRUCTOR, DESTRUCTOR --------------------------
RegionGrowing3D() = default;
virtual ~RegionGrowing3D() = default;
//-------------------------- SEGMENT -----------------------
/**
* @brief Execute segmentation using the Region Growing algorithm.
*
* @param[out] regions_idx Index information of all points in each region, support
* vector<vector<int>>, vector<Mat>.
* @param[out] labels The label corresponds to the model number, 0 means it does not belong to
* any model, range [0, Number of final resultant models obtained]. Support
* vector<int> and Mat.
* @param input_pts Original point cloud, support vector<Point3f> and Mat of size Nx3/3xN.
* @param normals Normal of each point, support vector<Point3f> and Mat of size Nx3.
* @param nn_idx Index information of nearest neighbors of all points. The first nearest
* neighbor of each point is itself. Support vector<vector<int>>, vector<Mat> and
* Mat of size NxK. If the information in a row is
* [0, 2, 1, -5, -1, 4, 7 ... negative number]
* it will use only non-negative indexes until it meets a negative number or bound
* of this row i.e. [0, 2, 1].
* @return Number of final resultant regions obtained by segmentation.
*/
virtual int
segment(OutputArrayOfArrays regions_idx, OutputArray labels, InputArray input_pts,
InputArray normals, InputArrayOfArrays nn_idx) = 0;
//-------------------------- Getter and Setter -----------------------
//! Set the minimum size of region.
//Setting to a non-positive number or default will be unlimited.
virtual void setMinSize(int min_size) = 0;
//! Get the minimum size of region.
virtual int getMinSize() const = 0;
//! Set the maximum size of region.
//Setting to a non-positive number or default will be unlimited.
virtual void setMaxSize(int max_size) = 0;
//! Get the maximum size of region.
virtual int getMaxSize() const = 0;
//! Set whether to use the smoothness mode. Default will be true.
//! If true it will check the angle between the normal of the current point and the normal of its neighbor.
//! Otherwise, it will check the angle between the normal of the seed point and the normal of current neighbor.
virtual void setSmoothModeFlag(bool smooth_mode) = 0;
//! Get whether to use the smoothness mode.
virtual bool getSmoothModeFlag() const = 0;
//! Set threshold value of the angle between normals, the input value is in radian.
//Default will be 30(degree)*PI/180.
virtual void setSmoothnessThreshold(double smoothness_thr) = 0;
//! Get threshold value of the angle between normals.
virtual double getSmoothnessThreshold() const = 0;
//! Set threshold value of curvature. Default will be 0.05.
//! Only points with curvature less than the threshold will be considered to belong to the same region.
//! If the curvature of each point is not set, this option will not work.
virtual void setCurvatureThreshold(double curvature_thr) = 0;
//! Get threshold value of curvature.
virtual double getCurvatureThreshold() const = 0;
//! Set the maximum number of neighbors want to use including itself.
//! Setting to a non-positive number or default will use the information from nn_idx.
virtual void setMaxNumberOfNeighbors(int max_neighbor_num) = 0;
//! Get the maximum number of neighbors including itself.
virtual int getMaxNumberOfNeighbors() const = 0;
//! Set the maximum number of regions you want.
//Setting to a non-positive number or default will be unlimited.
virtual void setNumberOfRegions(int region_num) = 0;
//! Get the maximum number of regions you want.
virtual int getNumberOfRegions() const = 0;
//! Set whether the results need to be sorted in descending order by the number of points.
virtual void setNeedSort(bool need_sort) = 0;
//! Get whether the results need to be sorted you have set.
virtual bool getNeedSort() const = 0;
//! Set the seed points, it will grow according to the seeds.
//! If noArray() is set, the default method will be used:
//! 1. If the curvature of each point is set, the seeds will be sorted in ascending order of curvatures.
//! 2. Otherwise, the natural order of the point cloud will be used.
virtual void setSeeds(InputArray seeds) = 0;
//! Get the seed points.
virtual void getSeeds(OutputArray seeds) const = 0;
//! Set the curvature of each point, support vector<float> and Mat. If not, you can set it to noArray().
virtual void setCurvatures(InputArray curvatures) = 0;
//! Get the curvature of each point if you have set.
virtual void getCurvatures(OutputArray curvatures) const = 0;
};
//! @} _3d
} //end namespace cv
#endif //OPENCV_3D_PTCLOUD_HPP