mirror of
https://github.com/opencv/opencv.git
synced 2026-07-29 15:23:05 +04:00
Merge pull request #29101 from asmorkalov:as/geometry_module
Moved geometry transformations from imgproc to 3d, future geometry module #29101 The first step of 2d geometry operations migration to the future geometry module. I created 2d.hpp to isolate the moved functions for now. I propose to create geometry.hpp when the module is renamed and include all things there. OpenCV contrib: https://github.com/opencv/opencv_contrib/pull/4126 ### Pull Request Readiness Checklist See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [x] I agree to contribute to the project under Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [ ] The PR is proposed to the proper branch - [ ] There is a reference to the original bug report and related work - [ ] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [ ] The feature is well documented and sample code can be built with the project CMake
This commit is contained in:
committed by
GitHub
parent
ccb808ba55
commit
aac582119c
+1
-1
@@ -404,7 +404,7 @@ DIAFILE_DIRS =
|
||||
PLANTUML_JAR_PATH =
|
||||
PLANTUML_CFG_FILE =
|
||||
PLANTUML_INCLUDE_PATH =
|
||||
DOT_GRAPH_MAX_NODES = 250
|
||||
DOT_GRAPH_MAX_NODES = 300
|
||||
MAX_DOT_GRAPH_DEPTH = 0
|
||||
DOT_MULTI_TARGETS = NO
|
||||
GENERATE_LEGEND = YES
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "opencv2/core.hpp"
|
||||
#include "opencv2/core/utils/logger.hpp"
|
||||
|
||||
#include "opencv2/3d/2d.hpp"
|
||||
#include "opencv2/3d/depth.hpp"
|
||||
#include "opencv2/3d/odometry.hpp"
|
||||
#include "opencv2/3d/odometry_frame.hpp"
|
||||
|
||||
@@ -0,0 +1,811 @@
|
||||
// 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 imgproc_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
|
||||
};
|
||||
|
||||
//! Variants of Line Segment %Detector
|
||||
enum LineSegmentDetectorModes {
|
||||
LSD_REFINE_NONE = 0, //!< No refinement applied
|
||||
LSD_REFINE_STD = 1, //!< Standard refinement is applied. E.g. breaking arches into smaller straighter line approximations.
|
||||
LSD_REFINE_ADV = 2 //!< Advanced refinement. Number of false alarms is calculated, lines are
|
||||
//!< refined through increase of precision, decrement in size, etc.
|
||||
};
|
||||
|
||||
//! @addtogroup imgproc_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 )
|
||||
*
|
||||
* 
|
||||
*
|
||||
* @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;
|
||||
};
|
||||
|
||||
//! @} imgproc_subdiv2d
|
||||
|
||||
//! @addtogroup imgproc_feature
|
||||
//! @{
|
||||
|
||||
/** @example samples/cpp/snippets/lsd_lines.cpp
|
||||
An example using the LineSegmentDetector
|
||||
\image html building_lsd.png "Sample output image" width=434 height=300
|
||||
*/
|
||||
|
||||
/** @brief Line segment detector class
|
||||
|
||||
following the algorithm described at @cite Rafael12 .
|
||||
|
||||
@note Implementation has been removed from OpenCV version 3.4.6 to 3.4.15 and version 4.1.0 to 4.5.3 due original code license conflict.
|
||||
restored again after [Computation of a NFA](https://github.com/rafael-grompone-von-gioi/binomial_nfa) code published under the MIT license.
|
||||
*/
|
||||
class CV_EXPORTS_W LineSegmentDetector : public Algorithm
|
||||
{
|
||||
public:
|
||||
|
||||
/** @brief Finds lines in the input image.
|
||||
|
||||
This is the output of the default parameters of the algorithm on the above shown image.
|
||||
|
||||

|
||||
|
||||
@param image A grayscale (CV_8UC1) input image. If only a roi needs to be selected, use:
|
||||
`lsd_ptr-\>detect(image(roi), lines, ...); lines += Scalar(roi.x, roi.y, roi.x, roi.y);`
|
||||
@param lines A vector of Vec4f elements specifying the beginning and ending point of a line. Where
|
||||
Vec4f is (x1, y1, x2, y2), point 1 is the start, point 2 - end. Returned lines are strictly
|
||||
oriented depending on the gradient.
|
||||
@param width Vector of widths of the regions, where the lines are found. E.g. Width of line.
|
||||
@param prec Vector of precisions with which the lines are found.
|
||||
@param nfa Vector containing number of false alarms in the line region, with precision of 10%. The
|
||||
bigger the value, logarithmically better the detection.
|
||||
- -1 corresponds to 10 mean false alarms
|
||||
- 0 corresponds to 1 mean false alarm
|
||||
- 1 corresponds to 0.1 mean false alarms
|
||||
This vector will be calculated only when the objects type is #LSD_REFINE_ADV.
|
||||
*/
|
||||
CV_WRAP virtual void detect(InputArray image, OutputArray lines,
|
||||
OutputArray width = noArray(), OutputArray prec = noArray(),
|
||||
OutputArray nfa = noArray()) = 0;
|
||||
|
||||
/** @brief Draws the line segments on a given image.
|
||||
@param image The image, where the lines will be drawn. Should be bigger or equal to the image,
|
||||
where the lines were found.
|
||||
@param lines A vector of the lines that needed to be drawn.
|
||||
*/
|
||||
CV_WRAP virtual void drawSegments(InputOutputArray image, InputArray lines) = 0;
|
||||
|
||||
/** @brief Draws two groups of lines in blue and red, counting the non overlapping (mismatching) pixels.
|
||||
|
||||
@param size The size of the image, where lines1 and lines2 were found.
|
||||
@param lines1 The first group of lines that needs to be drawn. It is visualized in blue color.
|
||||
@param lines2 The second group of lines. They visualized in red color.
|
||||
@param image Optional image, where the lines will be drawn. The image should be color(3-channel)
|
||||
in order for lines1 and lines2 to be drawn in the above mentioned colors.
|
||||
*/
|
||||
CV_WRAP virtual int compareSegments(const Size& size, InputArray lines1, InputArray lines2, InputOutputArray image = noArray()) = 0;
|
||||
|
||||
virtual ~LineSegmentDetector() { }
|
||||
};
|
||||
|
||||
/** @brief Creates a smart pointer to a LineSegmentDetector object and initializes it.
|
||||
|
||||
The LineSegmentDetector algorithm is defined using the standard values. Only advanced users may want
|
||||
to edit those, as to tailor it for their own application.
|
||||
|
||||
@param refine The way found lines will be refined, see #LineSegmentDetectorModes
|
||||
@param scale The scale of the image that will be used to find the lines. Range (0..1].
|
||||
@param sigma_scale Sigma for Gaussian filter. It is computed as sigma = sigma_scale/scale.
|
||||
@param quant Bound to the quantization error on the gradient norm.
|
||||
@param ang_th Gradient angle tolerance in degrees.
|
||||
@param log_eps Detection threshold: -log10(NFA) \> log_eps. Used only when advance refinement is chosen.
|
||||
@param density_th Minimal density of aligned region points in the enclosing rectangle.
|
||||
@param n_bins Number of bins in pseudo-ordering of gradient modulus.
|
||||
*/
|
||||
CV_EXPORTS_W Ptr<LineSegmentDetector> createLineSegmentDetector(
|
||||
LineSegmentDetectorModes refine = LSD_REFINE_STD, double scale = 0.8,
|
||||
double sigma_scale = 0.6, double quant = 2.0, double ang_th = 22.5,
|
||||
double log_eps = 0, double density_th = 0.7, int n_bins = 1024);
|
||||
|
||||
//! @} imgproc_feature
|
||||
|
||||
/** @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*.
|
||||
*
|
||||
* 
|
||||
*
|
||||
* 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 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:
|
||||
*
|
||||
* 
|
||||
*
|
||||
* @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:
|
||||
*
|
||||
* 
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* 
|
||||
*
|
||||
* @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 );
|
||||
|
||||
} // namespace cv
|
||||
|
||||
#endif // OPENCV_2D_HPP
|
||||
@@ -1,17 +1,23 @@
|
||||
package org.opencv.test.cv3d;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.opencv.cv3d.Cv3d;
|
||||
import org.opencv.core.Core;
|
||||
import org.opencv.core.CvType;
|
||||
import org.opencv.core.Mat;
|
||||
import org.opencv.core.MatOfDouble;
|
||||
import org.opencv.core.MatOfPoint;
|
||||
import org.opencv.core.MatOfPoint2f;
|
||||
import org.opencv.core.MatOfPoint3f;
|
||||
import org.opencv.core.MatOfInt;
|
||||
import org.opencv.core.MatOfInt4;
|
||||
import org.opencv.core.Point;
|
||||
import org.opencv.core.Scalar;
|
||||
import org.opencv.core.Size;
|
||||
import org.opencv.core.RotatedRect;
|
||||
import org.opencv.test.OpenCVTestCase;
|
||||
import org.opencv.imgproc.Imgproc;
|
||||
|
||||
@@ -583,4 +589,156 @@ public class Cv3dTest extends OpenCVTestCase {
|
||||
|
||||
assertMatEqual(K_new, K_new_truth, EPS);
|
||||
}
|
||||
|
||||
public void testApproxPolyDP() {
|
||||
MatOfPoint2f curve = new MatOfPoint2f(new Point(1, 3), new Point(2, 4), new Point(3, 5), new Point(4, 4), new Point(5, 3));
|
||||
|
||||
MatOfPoint2f approxCurve = new MatOfPoint2f();
|
||||
|
||||
Cv3d.approxPolyDP(curve, approxCurve, EPS, true);
|
||||
|
||||
List<Point> approxCurveGold = new ArrayList<Point>(3);
|
||||
approxCurveGold.add(new Point(1, 3));
|
||||
approxCurveGold.add(new Point(3, 5));
|
||||
approxCurveGold.add(new Point(5, 3));
|
||||
|
||||
assertListPointEquals(approxCurve.toList(), approxCurveGold, EPS);
|
||||
}
|
||||
|
||||
public void testConvexHullMatMat() {
|
||||
MatOfPoint points = new MatOfPoint(
|
||||
new Point(20, 0),
|
||||
new Point(40, 0),
|
||||
new Point(30, 20),
|
||||
new Point(0, 20),
|
||||
new Point(20, 10),
|
||||
new Point(30, 10)
|
||||
);
|
||||
|
||||
MatOfInt hull = new MatOfInt();
|
||||
|
||||
Cv3d.convexHull(points, hull);
|
||||
|
||||
MatOfInt expHull = new MatOfInt(
|
||||
0, 1, 2, 3
|
||||
);
|
||||
assertMatEqual(expHull, hull.reshape(1, (int)hull.total()), EPS);
|
||||
}
|
||||
|
||||
public void testConvexHullMatMatBooleanBoolean() {
|
||||
MatOfPoint points = new MatOfPoint(
|
||||
new Point(2, 0),
|
||||
new Point(4, 0),
|
||||
new Point(3, 2),
|
||||
new Point(0, 2),
|
||||
new Point(2, 1),
|
||||
new Point(3, 1)
|
||||
);
|
||||
|
||||
MatOfInt hull = new MatOfInt();
|
||||
|
||||
Cv3d.convexHull(points, hull, true);
|
||||
|
||||
MatOfInt expHull = new MatOfInt(
|
||||
3, 2, 1, 0
|
||||
);
|
||||
assertMatEqual(expHull, hull.reshape(1, hull.cols()), EPS);
|
||||
}
|
||||
|
||||
public void testConvexityDefects() {
|
||||
MatOfPoint points = new MatOfPoint(
|
||||
new Point(20, 0),
|
||||
new Point(40, 0),
|
||||
new Point(30, 20),
|
||||
new Point(0, 20),
|
||||
new Point(20, 10),
|
||||
new Point(30, 10)
|
||||
);
|
||||
|
||||
MatOfInt hull = new MatOfInt();
|
||||
Cv3d.convexHull(points, hull);
|
||||
|
||||
MatOfInt4 convexityDefects = new MatOfInt4();
|
||||
Cv3d.convexityDefects(points, hull, convexityDefects);
|
||||
|
||||
assertMatEqual(new MatOfInt4(3, 0, 5, 3620), convexityDefects.reshape(4, convexityDefects.cols()));
|
||||
}
|
||||
|
||||
public void testFitEllipse() {
|
||||
MatOfPoint2f points = new MatOfPoint2f(new Point(0, 0), new Point(-1, 1), new Point(1, 1), new Point(1, -1), new Point(-1, -1));
|
||||
RotatedRect rrect = new RotatedRect();
|
||||
|
||||
rrect = Cv3d.fitEllipse(points);
|
||||
|
||||
double FIT_ELLIPSE_CENTER_EPS = 0.01;
|
||||
double FIT_ELLIPSE_SIZE_EPS = 0.4;
|
||||
|
||||
assertEquals(0.0, rrect.center.x, FIT_ELLIPSE_CENTER_EPS);
|
||||
assertEquals(0.0, rrect.center.y, FIT_ELLIPSE_CENTER_EPS);
|
||||
assertEquals(2.828, rrect.size.width, FIT_ELLIPSE_SIZE_EPS);
|
||||
assertEquals(2.828, rrect.size.height, FIT_ELLIPSE_SIZE_EPS);
|
||||
}
|
||||
|
||||
public void testFitLine() {
|
||||
Mat points = new Mat(1, 4, CvType.CV_32FC2);
|
||||
points.put(0, 0, 0, 0, 2, 3, 3, 4, 5, 8);
|
||||
|
||||
Mat linePoints = new Mat(4, 1, CvType.CV_32FC1);
|
||||
linePoints.put(0, 0, 0.53198653, 0.84675282, 2.5, 3.75);
|
||||
|
||||
Cv3d.fitLine(points, dst, Imgproc.DIST_L12, 0, 0.01, 0.01);
|
||||
|
||||
assertMatEqual(linePoints, dst, EPS);
|
||||
}
|
||||
|
||||
public void testIsContourConvex() {
|
||||
MatOfPoint contour1 = new MatOfPoint(new Point(0, 0), new Point(10, 0), new Point(10, 10), new Point(5, 4));
|
||||
|
||||
assertFalse(Cv3d.isContourConvex(contour1));
|
||||
|
||||
MatOfPoint contour2 = new MatOfPoint(new Point(0, 0), new Point(10, 0), new Point(10, 10), new Point(5, 6));
|
||||
|
||||
assertTrue(Cv3d.isContourConvex(contour2));
|
||||
}
|
||||
|
||||
public void testMatchShapes() {
|
||||
Mat contour1 = new Mat(1, 4, CvType.CV_32FC2);
|
||||
Mat contour2 = new Mat(1, 4, CvType.CV_32FC2);
|
||||
contour1.put(0, 0, 1, 1, 5, 1, 4, 3, 6, 2);
|
||||
contour2.put(0, 0, 1, 1, 6, 1, 4, 1, 2, 5);
|
||||
|
||||
double distance = Cv3d.matchShapes(contour1, contour2, Imgproc.CONTOURS_MATCH_I1, 1);
|
||||
|
||||
assertEquals(2.81109697365334, distance, EPS);
|
||||
}
|
||||
|
||||
public void testMinAreaRect() {
|
||||
MatOfPoint2f points = new MatOfPoint2f(new Point(1, 1), new Point(5, 1), new Point(4, 3), new Point(6, 2));
|
||||
|
||||
RotatedRect rrect = Cv3d.minAreaRect(points);
|
||||
|
||||
assertEquals(new Size(2, 5), rrect.size);
|
||||
assertEquals(-90., rrect.angle);
|
||||
assertEquals(new Point(3.5, 2), rrect.center);
|
||||
}
|
||||
|
||||
public void testMinEnclosingCircle() {
|
||||
MatOfPoint2f points = new MatOfPoint2f(new Point(0, 0), new Point(-100, 0), new Point(0, -100), new Point(100, 0), new Point(0, 100));
|
||||
Point actualCenter = new Point();
|
||||
float[] radius = new float[1];
|
||||
|
||||
Cv3d.minEnclosingCircle(points, actualCenter, radius);
|
||||
|
||||
assertEquals(new Point(0, 0), actualCenter);
|
||||
assertEquals(100.0f, radius[0], 1.0);
|
||||
}
|
||||
|
||||
public void testPointPolygonTest() {
|
||||
MatOfPoint2f contour = new MatOfPoint2f(new Point(0, 0), new Point(1, 3), new Point(3, 4), new Point(4, 3), new Point(2, 1));
|
||||
double sign1 = Cv3d.pointPolygonTest(contour, new Point(2, 2), false);
|
||||
assertEquals(1.0, sign1);
|
||||
|
||||
double sign2 = Cv3d.pointPolygonTest(contour, new Point(4, 4), true);
|
||||
assertEquals(-Math.sqrt(0.5), sign2);
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
package org.opencv.test.imgproc;
|
||||
package org.opencv.test.cv3d;
|
||||
|
||||
import org.opencv.core.MatOfFloat6;
|
||||
import org.opencv.core.Point;
|
||||
import org.opencv.core.Rect;
|
||||
import org.opencv.imgproc.Subdiv2D;
|
||||
import org.opencv.cv3d.Subdiv2D;
|
||||
import org.opencv.test.OpenCVTestCase;
|
||||
|
||||
public class Subdiv2DTest extends OpenCVTestCase {
|
||||
@@ -0,0 +1,47 @@
|
||||
// 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.
|
||||
#include "perf_precomp.hpp"
|
||||
#include "opencv2/ts.hpp"
|
||||
#include "opencv2/ts/ts_perf.hpp"
|
||||
|
||||
namespace opencv_test { namespace {
|
||||
|
||||
using namespace perf;
|
||||
|
||||
typedef TestBaseWithParam< tuple<MatDepth, int> > TestMinEnclosingCircle;
|
||||
PERF_TEST_P(TestMinEnclosingCircle, minEnclosingCircle,
|
||||
Combine(
|
||||
testing::Values(CV_32S, CV_32F),
|
||||
Values(400, 1000, 10000, 100000)
|
||||
))
|
||||
{
|
||||
int ptType = get<0>(GetParam());
|
||||
int n = get<1>(GetParam());
|
||||
Mat pts(n, 2, ptType);
|
||||
declare.in(pts, WARMUP_RNG);
|
||||
|
||||
Point2f center;
|
||||
float radius;
|
||||
TEST_CYCLE() minEnclosingCircle(pts, center, radius);
|
||||
SANITY_CHECK_NOTHING();
|
||||
}
|
||||
|
||||
typedef TestBaseWithParam<int> TestMinEnclosingCircleWorstCase;
|
||||
PERF_TEST_P(TestMinEnclosingCircleWorstCase, minEnclosingCircle_sequential,
|
||||
Values(400, 1000, 5000, 10000))
|
||||
{
|
||||
int n = GetParam();
|
||||
vector<Point2f> contour;
|
||||
for(int i = 0; i < n; ++i) {
|
||||
float angle = (float)(i * 2 * CV_PI / n);
|
||||
contour.push_back(Point2f(cos(angle) * 100, sin(angle) * 100));
|
||||
}
|
||||
|
||||
Point2f center;
|
||||
float radius;
|
||||
TEST_CYCLE() minEnclosingCircle(contour, center, radius);
|
||||
SANITY_CHECK_NOTHING();
|
||||
}
|
||||
|
||||
}} // namespace
|
||||
@@ -554,214 +554,3 @@ float cv::intersectConvexConvex( InputArray _p1, InputArray _p2, OutputArray _p1
|
||||
}
|
||||
return (float)fabs(area);
|
||||
}
|
||||
|
||||
static Rect maskBoundingRect( const Mat& img )
|
||||
{
|
||||
CV_Assert( img.depth() <= CV_8S && img.channels() == 1 );
|
||||
|
||||
Size size = img.size();
|
||||
int xmin = size.width, ymin = -1, xmax = -1, ymax = -1, i, j, k;
|
||||
|
||||
for( i = 0; i < size.height; i++ )
|
||||
{
|
||||
const uchar* _ptr = img.ptr(i);
|
||||
const uchar* ptr = (const uchar*)alignPtr(_ptr, 4);
|
||||
int have_nz = 0, k_min, offset = (int)(ptr - _ptr);
|
||||
j = 0;
|
||||
offset = MIN(offset, size.width);
|
||||
for( ; j < offset; j++ )
|
||||
if( _ptr[j] )
|
||||
{
|
||||
if( j < xmin )
|
||||
xmin = j;
|
||||
if( j > xmax )
|
||||
xmax = j;
|
||||
have_nz = 1;
|
||||
}
|
||||
if( offset < size.width )
|
||||
{
|
||||
xmin -= offset;
|
||||
xmax -= offset;
|
||||
size.width -= offset;
|
||||
j = 0;
|
||||
for( ; j <= xmin - 4; j += 4 )
|
||||
if( *((int*)(ptr+j)) )
|
||||
break;
|
||||
for( ; j < xmin; j++ )
|
||||
if( ptr[j] )
|
||||
{
|
||||
xmin = j;
|
||||
if( j > xmax )
|
||||
xmax = j;
|
||||
have_nz = 1;
|
||||
break;
|
||||
}
|
||||
k_min = MAX(j-1, xmax);
|
||||
k = size.width - 1;
|
||||
for( ; k > k_min && (k&3) != 3; k-- )
|
||||
if( ptr[k] )
|
||||
break;
|
||||
if( k > k_min && (k&3) == 3 )
|
||||
{
|
||||
for( ; k > k_min+3; k -= 4 )
|
||||
if( *((int*)(ptr+k-3)) )
|
||||
break;
|
||||
}
|
||||
for( ; k > k_min; k-- )
|
||||
if( ptr[k] )
|
||||
{
|
||||
xmax = k;
|
||||
have_nz = 1;
|
||||
break;
|
||||
}
|
||||
if( !have_nz )
|
||||
{
|
||||
j &= ~3;
|
||||
for( ; j <= k - 3; j += 4 )
|
||||
if( *((int*)(ptr+j)) )
|
||||
break;
|
||||
for( ; j <= k; j++ )
|
||||
if( ptr[j] )
|
||||
{
|
||||
have_nz = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
xmin += offset;
|
||||
xmax += offset;
|
||||
size.width += offset;
|
||||
}
|
||||
if( have_nz )
|
||||
{
|
||||
if( ymin < 0 )
|
||||
ymin = i;
|
||||
ymax = i;
|
||||
}
|
||||
}
|
||||
|
||||
if( xmin >= size.width )
|
||||
xmin = ymin = 0;
|
||||
return Rect(xmin, ymin, xmax - xmin + 1, ymax - ymin + 1);
|
||||
}
|
||||
|
||||
// Calculates bounding rectangle of a point set or retrieves already calculated
|
||||
static Rect pointSetBoundingRect( const Mat& points )
|
||||
{
|
||||
int npoints = points.checkVector(2);
|
||||
int depth = points.depth();
|
||||
CV_Assert(npoints >= 0 && (depth == CV_32F || depth == CV_32S));
|
||||
|
||||
int xmin = 0, ymin = 0, xmax = -1, ymax = -1, i = 0;
|
||||
bool is_float = depth == CV_32F;
|
||||
|
||||
if( npoints == 0 )
|
||||
return Rect();
|
||||
|
||||
if( !is_float )
|
||||
{
|
||||
const int32_t* pts = points.ptr<int32_t>();
|
||||
int64_t firstval = 0;
|
||||
std::memcpy(&firstval, pts, sizeof(pts[0]) * 2);
|
||||
xmin = xmax = pts[0];
|
||||
ymin = ymax = pts[1];
|
||||
#if CV_SIMD || CV_SIMD_SCALABLE
|
||||
v_int32 minval, maxval;
|
||||
minval = maxval = v_reinterpret_as_s32(vx_setall_s64(firstval)); //min[0]=pt.x, min[1]=pt.y, min[2]=pt.x, min[3]=pt.y
|
||||
const int nlanes = VTraits<v_int32>::vlanes()/2;
|
||||
for (; i < npoints; i += nlanes)
|
||||
{
|
||||
if (i > npoints - nlanes)
|
||||
{
|
||||
if (i == 0)
|
||||
break;
|
||||
i = npoints - nlanes;
|
||||
}
|
||||
v_int32 ptXY2 = vx_load(pts + 2 * i);
|
||||
minval = v_min(ptXY2, minval);
|
||||
maxval = v_max(ptXY2, maxval);
|
||||
}
|
||||
constexpr int max_nlanes = VTraits<v_int32>::max_nlanes;
|
||||
int arr_minval[max_nlanes], arr_maxval[max_nlanes];
|
||||
vx_store(arr_minval, minval);
|
||||
vx_store(arr_maxval, maxval);
|
||||
for (int j = 0; j < nlanes; j++)
|
||||
{
|
||||
xmin = std::min(xmin, arr_minval[2*j]);
|
||||
ymin = std::min(ymin, arr_minval[2*j+1]);
|
||||
xmax = std::max(xmax, arr_maxval[2*j]);
|
||||
ymax = std::max(ymax, arr_maxval[2*j+1]);
|
||||
}
|
||||
#endif
|
||||
for( ; i < npoints; i++ )
|
||||
{
|
||||
int pt_x = pts[2*i];
|
||||
int pt_y = pts[2*i+1];
|
||||
|
||||
xmin = std::min(xmin, pt_x);
|
||||
xmax = std::max(xmax, pt_x);
|
||||
ymin = std::min(ymin, pt_y);
|
||||
ymax = std::max(ymax, pt_y);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const float* pts = points.ptr<float>();
|
||||
int64_t firstval = 0;
|
||||
std::memcpy(&firstval, pts, sizeof(pts[0]) * 2);
|
||||
xmin = xmax = cvFloor(pts[0]);
|
||||
ymin = ymax = cvFloor(pts[1]);
|
||||
#if CV_SIMD || CV_SIMD_SCALABLE
|
||||
v_float32 minval, maxval;
|
||||
minval = maxval = v_reinterpret_as_f32(vx_setall_s64(firstval)); //min[0]=pt.x, min[1]=pt.y, min[2]=pt.x, min[3]=pt.y
|
||||
const int nlanes = VTraits<v_float32>::vlanes()/2;
|
||||
for (; i < npoints; i += nlanes)
|
||||
{
|
||||
if (i > npoints - nlanes)
|
||||
{
|
||||
if (i == 0)
|
||||
break;
|
||||
i = npoints - nlanes;
|
||||
}
|
||||
v_float32 ptXY2 = vx_load(pts + 2 * i);
|
||||
minval = v_min(ptXY2, minval);
|
||||
maxval = v_max(ptXY2, maxval);
|
||||
}
|
||||
constexpr int max_nlanes = VTraits<v_int32>::max_nlanes;
|
||||
float arr_minval[max_nlanes], arr_maxval[max_nlanes];
|
||||
vx_store(arr_minval, minval);
|
||||
vx_store(arr_maxval, maxval);
|
||||
for (int j = 0; j < nlanes; j++)
|
||||
{
|
||||
int _xmin = cvFloor(arr_minval[2*j]), _ymin = cvFloor(arr_minval[2*j+1]);
|
||||
int _xmax = cvFloor(arr_maxval[2*j]), _ymax = cvFloor(arr_maxval[2*j+1]);
|
||||
xmin = std::min(xmin, _xmin);
|
||||
ymin = std::min(ymin, _ymin);
|
||||
xmax = std::max(xmax, _xmax);
|
||||
ymax = std::max(ymax, _ymax);
|
||||
}
|
||||
#endif
|
||||
for( ; i < npoints; i++ )
|
||||
{
|
||||
// because right and bottom sides of the bounding rectangle are not inclusive
|
||||
// (note +1 in width and height calculation below), cvFloor is used here instead of cvCeil
|
||||
int pt_x = cvFloor(pts[2*i]);
|
||||
int pt_y = cvFloor(pts[2*i+1]);
|
||||
|
||||
xmin = std::min(xmin, pt_x);
|
||||
xmax = std::max(xmax, pt_x);
|
||||
ymin = std::min(ymin, pt_y);
|
||||
ymax = std::max(ymax, pt_y);
|
||||
}
|
||||
}
|
||||
|
||||
return Rect(xmin, ymin, xmax - xmin + 1, ymax - ymin + 1);
|
||||
}
|
||||
|
||||
|
||||
cv::Rect cv::boundingRect(InputArray array)
|
||||
{
|
||||
CV_INSTRUMENT_REGION();
|
||||
|
||||
Mat m = array.getMat();
|
||||
return m.depth() <= CV_8U ? maskBoundingRect(m) : pointSetBoundingRect(m);
|
||||
}
|
||||
@@ -90,8 +90,8 @@ static void fitLine2D_wods( const Point2f* points, int count, float *weights, fl
|
||||
dxy = xy - x * y;
|
||||
|
||||
t = (float) atan2( 2 * dxy, dx2 - dy2 ) / 2;
|
||||
line[0] = (float) cos( t );
|
||||
line[1] = (float) sin( t );
|
||||
line[0] = (float) std::cos( t );
|
||||
line[1] = (float) std::sin( t );
|
||||
|
||||
line[2] = (float) x;
|
||||
line[3] = (float) y;
|
||||
@@ -394,7 +394,7 @@ static void fitLine2D( const Point2f * points, int count, int dist,
|
||||
double t = _line[0] * _lineprev[0] + _line[1] * _lineprev[1];
|
||||
t = MAX(t,-1.);
|
||||
t = MIN(t,1.);
|
||||
if( fabs(acos(t)) < adelta )
|
||||
if( fabs(std::acos(t)) < adelta )
|
||||
{
|
||||
float x, y, d;
|
||||
|
||||
@@ -535,7 +535,7 @@ static void fitLine3D( Point3f * points, int count, int dist,
|
||||
double t = _line[0] * _lineprev[0] + _line[1] * _lineprev[1] + _line[2] * _lineprev[2];
|
||||
t = MAX(t,-1.);
|
||||
t = MIN(t,1.);
|
||||
if( fabs(acos(t)) < adelta )
|
||||
if( fabs(std::acos(t)) < adelta )
|
||||
{
|
||||
float x, y, z, ax, ay, az, dx, dy, dz, d;
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
|
||||
#include "precomp.hpp"
|
||||
#include <vector>
|
||||
#include <cmath>
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Default LSD parameters
|
||||
@@ -450,7 +451,7 @@ void LineSegmentDetectorImpl::flsd(std::vector<Vec4f>& lines,
|
||||
// Angle tolerance
|
||||
const double prec = CV_PI * ANG_TH / 180;
|
||||
const double p = ANG_TH / 180;
|
||||
const double rho = QUANT / sin(prec); // gradient magnitude threshold
|
||||
const double rho = QUANT / std::sin(prec); // gradient magnitude threshold
|
||||
|
||||
if(SCALE != 1)
|
||||
{
|
||||
@@ -642,8 +643,8 @@ void LineSegmentDetectorImpl::region_grow(const Point2i& s, std::vector<RegionPo
|
||||
reg.push_back(region_point);
|
||||
|
||||
// Update region's angle
|
||||
sumdx += cos(float(angle));
|
||||
sumdy += sin(float(angle));
|
||||
sumdx += std::cos(float(angle));
|
||||
sumdy += std::sin(float(angle));
|
||||
// reg_angle is used in the isAligned, so it needs to be updates?
|
||||
reg_angle = fastAtan2(sumdy, sumdx) * DEG_TO_RADS;
|
||||
}
|
||||
@@ -674,8 +675,8 @@ void LineSegmentDetectorImpl::region2rect(const std::vector<RegionPoint>& reg,
|
||||
double theta = get_theta(reg, x, y, reg_angle, prec);
|
||||
|
||||
// Find length and width
|
||||
double dx = cos(theta);
|
||||
double dy = sin(theta);
|
||||
double dx = std::cos(theta);
|
||||
double dy = std::sin(theta);
|
||||
double l_min = 0, l_max = 0, w_min = 0, w_max = 0;
|
||||
|
||||
for(size_t i = 0; i < reg.size(); ++i)
|
||||
@@ -82,6 +82,7 @@
|
||||
#include <unordered_set>
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
#include <cmath>
|
||||
|
||||
#define GET_OPTIMIZED(func) (func)
|
||||
|
||||
|
||||
@@ -237,75 +237,6 @@ void cv::minEnclosingCircle( InputArray _points, Point2f& _center, float& _radiu
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// calculates length of a curve (e.g. contour perimeter)
|
||||
double cv::arcLength( InputArray _curve, bool is_closed )
|
||||
{
|
||||
CV_INSTRUMENT_REGION();
|
||||
|
||||
Mat curve = _curve.getMat();
|
||||
int count = curve.checkVector(2);
|
||||
int depth = curve.depth();
|
||||
CV_Assert( count >= 0 && (depth == CV_32F || depth == CV_32S));
|
||||
double perimeter = 0;
|
||||
|
||||
int i;
|
||||
|
||||
if( count <= 1 )
|
||||
return 0.;
|
||||
|
||||
bool is_float = depth == CV_32F;
|
||||
int last = is_closed ? count-1 : 0;
|
||||
const Point* pti = curve.ptr<Point>();
|
||||
const Point2f* ptf = curve.ptr<Point2f>();
|
||||
|
||||
Point2f prev = is_float ? ptf[last] : Point2f((float)pti[last].x,(float)pti[last].y);
|
||||
|
||||
for( i = 0; i < count; i++ )
|
||||
{
|
||||
Point2f p = is_float ? ptf[i] : Point2f((float)pti[i].x,(float)pti[i].y);
|
||||
float dx = p.x - prev.x, dy = p.y - prev.y;
|
||||
perimeter += std::sqrt(dx*dx + dy*dy);
|
||||
|
||||
prev = p;
|
||||
}
|
||||
|
||||
return perimeter;
|
||||
}
|
||||
|
||||
// area of a whole sequence
|
||||
double cv::contourArea( InputArray _contour, bool oriented )
|
||||
{
|
||||
CV_INSTRUMENT_REGION();
|
||||
|
||||
Mat contour = _contour.getMat();
|
||||
int npoints = contour.checkVector(2);
|
||||
int depth = contour.depth();
|
||||
CV_Assert(npoints >= 0 && (depth == CV_32F || depth == CV_32S));
|
||||
|
||||
if( npoints == 0 )
|
||||
return 0.;
|
||||
|
||||
double a00 = 0;
|
||||
bool is_float = depth == CV_32F;
|
||||
const Point* ptsi = contour.ptr<Point>();
|
||||
const Point2f* ptsf = contour.ptr<Point2f>();
|
||||
Point2f prev = is_float ? ptsf[npoints-1] : Point2f((float)ptsi[npoints-1].x, (float)ptsi[npoints-1].y);
|
||||
|
||||
for( int i = 0; i < npoints; i++ )
|
||||
{
|
||||
Point2f p = is_float ? ptsf[i] : Point2f((float)ptsi[i].x, (float)ptsi[i].y);
|
||||
a00 += (double)prev.x * p.y - (double)prev.y * p.x;
|
||||
prev = p;
|
||||
}
|
||||
|
||||
a00 *= 0.5;
|
||||
if( !oriented )
|
||||
a00 = fabs(a00);
|
||||
|
||||
return a00;
|
||||
}
|
||||
|
||||
namespace cv
|
||||
{
|
||||
|
||||
@@ -442,7 +373,7 @@ static RotatedRect fitEllipseNoDirect( InputArray _points )
|
||||
// store angle and radii
|
||||
rp[4] = -0.5 * atan2(gfp[2], gfp[1] - gfp[0]); // convert from APP angle usage
|
||||
if( fabs(gfp[2]) > min_eps )
|
||||
t = gfp[2]/sin(-2.0 * rp[4]);
|
||||
t = gfp[2]/std::sin(-2.0 * rp[4]);
|
||||
else // ellipse is rotated by an integer multiple of pi/2
|
||||
t = gfp[1] - gfp[0];
|
||||
rp[2] = fabs(gfp[0] + gfp[1] - t);
|
||||
@@ -598,6 +598,20 @@ TEST(Imgproc_minAreaRect, roundtrip_accuracy)
|
||||
EXPECT_LT(std::abs(rect.angle - rect_out.angle), 1e-5);
|
||||
}
|
||||
|
||||
TEST(Imgproc_PointPolygonTest, regression_10222)
|
||||
{
|
||||
vector<Point> contour;
|
||||
contour.push_back(Point(0, 0));
|
||||
contour.push_back(Point(0, 100000));
|
||||
contour.push_back(Point(100000, 100000));
|
||||
contour.push_back(Point(100000, 50000));
|
||||
contour.push_back(Point(100000, 0));
|
||||
|
||||
const Point2f point(40000, 40000);
|
||||
const double result = cv::pointPolygonTest(contour, point, false);
|
||||
EXPECT_GT(result, 0) << "Desired result: point is inside polygon - actual result: point is not inside polygon";
|
||||
}
|
||||
|
||||
TEST(Imgproc_minEnclosingTriangle, regression_17585)
|
||||
{
|
||||
const int N = 3;
|
||||
@@ -416,4 +416,83 @@ TEST_F(Imgproc_LSD_Common, drawSegmentsEmpty)
|
||||
);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TEST(Imgproc_fitLine_vector_3d, regression)
|
||||
{
|
||||
std::vector<Point3f> points_vector;
|
||||
|
||||
Point3f p21(4,4,4);
|
||||
Point3f p22(8,8,8);
|
||||
|
||||
points_vector.push_back(p21);
|
||||
points_vector.push_back(p22);
|
||||
|
||||
std::vector<float> line;
|
||||
|
||||
cv::fitLine(points_vector, line, DIST_L2, 0 ,0 ,0);
|
||||
|
||||
ASSERT_EQ(line.size(), (size_t)6);
|
||||
|
||||
}
|
||||
|
||||
TEST(Imgproc_fitLine_vector_2d, regression)
|
||||
{
|
||||
std::vector<Point2f> points_vector;
|
||||
|
||||
Point2f p21(4,4);
|
||||
Point2f p22(8,8);
|
||||
Point2f p23(16,16);
|
||||
|
||||
points_vector.push_back(p21);
|
||||
points_vector.push_back(p22);
|
||||
points_vector.push_back(p23);
|
||||
|
||||
std::vector<float> line;
|
||||
|
||||
cv::fitLine(points_vector, line, DIST_L2, 0 ,0 ,0);
|
||||
|
||||
ASSERT_EQ(line.size(), (size_t)4);
|
||||
}
|
||||
|
||||
TEST(Imgproc_fitLine_Mat_2dC2, regression)
|
||||
{
|
||||
cv::Mat mat1 = Mat::zeros(3, 1, CV_32SC2);
|
||||
std::vector<float> line1;
|
||||
|
||||
cv::fitLine(mat1, line1, DIST_L2, 0 ,0 ,0);
|
||||
|
||||
ASSERT_EQ(line1.size(), (size_t)4);
|
||||
}
|
||||
|
||||
TEST(Imgproc_fitLine_Mat_2dC1, regression)
|
||||
{
|
||||
cv::Matx<int, 3, 2> mat2;
|
||||
std::vector<float> line2;
|
||||
|
||||
cv::fitLine(mat2, line2, DIST_L2, 0 ,0 ,0);
|
||||
|
||||
ASSERT_EQ(line2.size(), (size_t)4);
|
||||
}
|
||||
|
||||
TEST(Imgproc_fitLine_Mat_3dC3, regression)
|
||||
{
|
||||
cv::Mat mat1 = Mat::zeros(2, 1, CV_32SC3);
|
||||
std::vector<float> line1;
|
||||
|
||||
cv::fitLine(mat1, line1, DIST_L2, 0 ,0 ,0);
|
||||
|
||||
ASSERT_EQ(line1.size(), (size_t)6);
|
||||
}
|
||||
|
||||
TEST(Imgproc_fitLine_Mat_3dC1, regression)
|
||||
{
|
||||
cv::Mat mat2 = Mat::zeros(2, 3, CV_32SC1);
|
||||
std::vector<float> line2;
|
||||
|
||||
cv::fitLine(mat2, line2, DIST_L2, 0 ,0 ,0);
|
||||
|
||||
ASSERT_EQ(line2.size(), (size_t)6);
|
||||
}
|
||||
|
||||
}} // namespace
|
||||
@@ -19,7 +19,7 @@ ocv_add_dispatched_file_force_all("layers/cpu_kernels/transpose_kernels" AVX AVX
|
||||
ocv_add_dispatched_file_force_all("layers/cpu_kernels/gridsample_kernels" AVX AVX2 NEON RVV LASX)
|
||||
ocv_add_dispatched_file_force_all("layers/cpu_kernels/nary_eltwise_kernels" AVX AVX2 NEON RVV LASX)
|
||||
|
||||
ocv_add_module(dnn opencv_core opencv_imgproc WRAP python java objc js)
|
||||
ocv_add_module(dnn opencv_core opencv_imgproc opencv_3d WRAP python java objc js)
|
||||
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/cmake/plugin.cmake)
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <iterator>
|
||||
|
||||
#include <opencv2/imgproc.hpp>
|
||||
#include <opencv2/3d.hpp>
|
||||
|
||||
namespace cv {
|
||||
namespace dnn {
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "nms.inl.hpp"
|
||||
|
||||
#include <opencv2/imgproc.hpp>
|
||||
#include <opencv2/3d.hpp>
|
||||
|
||||
namespace cv { namespace dnn {
|
||||
CV__DNN_INLINE_NS_BEGIN
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
#include <opencv2/core/utils/configuration.private.hpp>
|
||||
#include <opencv2/core/utils/logger.hpp>
|
||||
#include <opencv2/3d.hpp>
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifndef NOMINMAX
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include "test_precomp.hpp"
|
||||
#include <opencv2/dnn/shape_utils.hpp>
|
||||
#include <opencv2/3d.hpp>
|
||||
#include "npy_blob.hpp"
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
@@ -6,7 +6,7 @@ set(debug_modules "")
|
||||
if(DEBUG_opencv_features)
|
||||
list(APPEND debug_modules opencv_highgui)
|
||||
endif()
|
||||
ocv_define_module(features opencv_imgproc ${debug_modules} OPTIONAL opencv_flann WRAP java objc python js)
|
||||
ocv_define_module(features opencv_imgproc opencv_3d ${debug_modules} OPTIONAL opencv_flann WRAP java objc python js)
|
||||
|
||||
ocv_install_3rdparty_licenses(mscr "${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/mscr/chi_table_LICENSE.txt")
|
||||
ocv_install_3rdparty_licenses(annoylib "${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/annoy/LICENSE")
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
|
||||
#include "precomp.hpp"
|
||||
#include <iostream>
|
||||
|
||||
namespace cv {
|
||||
|
||||
class AffineFeature_Impl CV_FINAL : public AffineFeature
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
|
||||
#include "opencv2/features.hpp"
|
||||
#include "opencv2/imgproc.hpp"
|
||||
#include "opencv2/3d.hpp"
|
||||
|
||||
#include "opencv2/core/utility.hpp"
|
||||
#include "opencv2/core/private.hpp"
|
||||
|
||||
@@ -490,14 +490,6 @@ enum HoughModes {
|
||||
HOUGH_GRADIENT_ALT = 4, //!< variation of HOUGH_GRADIENT to get better accuracy
|
||||
};
|
||||
|
||||
//! Variants of Line Segment %Detector
|
||||
enum LineSegmentDetectorModes {
|
||||
LSD_REFINE_NONE = 0, //!< No refinement applied
|
||||
LSD_REFINE_STD = 1, //!< Standard refinement is applied. E.g. breaking arches into smaller straighter line approximations.
|
||||
LSD_REFINE_ADV = 2 //!< Advanced refinement. Number of false alarms is calculated, lines are
|
||||
//!< refined through increase of precision, decrement in size, etc.
|
||||
};
|
||||
|
||||
//! @} imgproc_feature
|
||||
|
||||
/** Histogram comparison methods
|
||||
@@ -882,13 +874,6 @@ enum ColorConversionCodes {
|
||||
//! @addtogroup imgproc_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
|
||||
};
|
||||
|
||||
/** types of line
|
||||
@ingroup imgproc_draw
|
||||
*/
|
||||
@@ -1087,370 +1072,6 @@ public:
|
||||
|
||||
//! @} imgproc_hist
|
||||
|
||||
//! @addtogroup imgproc_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 )
|
||||
|
||||

|
||||
|
||||
@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;
|
||||
};
|
||||
|
||||
//! @} imgproc_subdiv2d
|
||||
|
||||
|
||||
//! @addtogroup imgproc_feature
|
||||
//! @{
|
||||
|
||||
/** @example samples/cpp/snippets/lsd_lines.cpp
|
||||
An example using the LineSegmentDetector
|
||||
\image html building_lsd.png "Sample output image" width=434 height=300
|
||||
*/
|
||||
|
||||
/** @brief Line segment detector class
|
||||
|
||||
following the algorithm described at @cite Rafael12 .
|
||||
|
||||
@note Implementation has been removed from OpenCV version 3.4.6 to 3.4.15 and version 4.1.0 to 4.5.3 due original code license conflict.
|
||||
restored again after [Computation of a NFA](https://github.com/rafael-grompone-von-gioi/binomial_nfa) code published under the MIT license.
|
||||
*/
|
||||
class CV_EXPORTS_W LineSegmentDetector : public Algorithm
|
||||
{
|
||||
public:
|
||||
|
||||
/** @brief Finds lines in the input image.
|
||||
|
||||
This is the output of the default parameters of the algorithm on the above shown image.
|
||||
|
||||

|
||||
|
||||
@param image A grayscale (CV_8UC1) input image. If only a roi needs to be selected, use:
|
||||
`lsd_ptr-\>detect(image(roi), lines, ...); lines += Scalar(roi.x, roi.y, roi.x, roi.y);`
|
||||
@param lines A vector of Vec4f elements specifying the beginning and ending point of a line. Where
|
||||
Vec4f is (x1, y1, x2, y2), point 1 is the start, point 2 - end. Returned lines are strictly
|
||||
oriented depending on the gradient.
|
||||
@param width Vector of widths of the regions, where the lines are found. E.g. Width of line.
|
||||
@param prec Vector of precisions with which the lines are found.
|
||||
@param nfa Vector containing number of false alarms in the line region, with precision of 10%. The
|
||||
bigger the value, logarithmically better the detection.
|
||||
- -1 corresponds to 10 mean false alarms
|
||||
- 0 corresponds to 1 mean false alarm
|
||||
- 1 corresponds to 0.1 mean false alarms
|
||||
This vector will be calculated only when the objects type is #LSD_REFINE_ADV.
|
||||
*/
|
||||
CV_WRAP virtual void detect(InputArray image, OutputArray lines,
|
||||
OutputArray width = noArray(), OutputArray prec = noArray(),
|
||||
OutputArray nfa = noArray()) = 0;
|
||||
|
||||
/** @brief Draws the line segments on a given image.
|
||||
@param image The image, where the lines will be drawn. Should be bigger or equal to the image,
|
||||
where the lines were found.
|
||||
@param lines A vector of the lines that needed to be drawn.
|
||||
*/
|
||||
CV_WRAP virtual void drawSegments(InputOutputArray image, InputArray lines) = 0;
|
||||
|
||||
/** @brief Draws two groups of lines in blue and red, counting the non overlapping (mismatching) pixels.
|
||||
|
||||
@param size The size of the image, where lines1 and lines2 were found.
|
||||
@param lines1 The first group of lines that needs to be drawn. It is visualized in blue color.
|
||||
@param lines2 The second group of lines. They visualized in red color.
|
||||
@param image Optional image, where the lines will be drawn. The image should be color(3-channel)
|
||||
in order for lines1 and lines2 to be drawn in the above mentioned colors.
|
||||
*/
|
||||
CV_WRAP virtual int compareSegments(const Size& size, InputArray lines1, InputArray lines2, InputOutputArray image = noArray()) = 0;
|
||||
|
||||
virtual ~LineSegmentDetector() { }
|
||||
};
|
||||
|
||||
/** @brief Creates a smart pointer to a LineSegmentDetector object and initializes it.
|
||||
|
||||
The LineSegmentDetector algorithm is defined using the standard values. Only advanced users may want
|
||||
to edit those, as to tailor it for their own application.
|
||||
|
||||
@param refine The way found lines will be refined, see #LineSegmentDetectorModes
|
||||
@param scale The scale of the image that will be used to find the lines. Range (0..1].
|
||||
@param sigma_scale Sigma for Gaussian filter. It is computed as sigma = sigma_scale/scale.
|
||||
@param quant Bound to the quantization error on the gradient norm.
|
||||
@param ang_th Gradient angle tolerance in degrees.
|
||||
@param log_eps Detection threshold: -log10(NFA) \> log_eps. Used only when advance refinement is chosen.
|
||||
@param density_th Minimal density of aligned region points in the enclosing rectangle.
|
||||
@param n_bins Number of bins in pseudo-ordering of gradient modulus.
|
||||
*/
|
||||
CV_EXPORTS_W Ptr<LineSegmentDetector> createLineSegmentDetector(
|
||||
LineSegmentDetectorModes refine = LSD_REFINE_STD, double scale = 0.8,
|
||||
double sigma_scale = 0.6, double quant = 2.0, double ang_th = 22.5,
|
||||
double log_eps = 0, double density_th = 0.7, int n_bins = 1024);
|
||||
|
||||
//! @} imgproc_feature
|
||||
|
||||
|
||||
//! @addtogroup imgproc_filter
|
||||
//! @{
|
||||
|
||||
@@ -2576,50 +2197,50 @@ Mat getRotationMatrix2D(Point2f center, double angle, double scale)
|
||||
}
|
||||
|
||||
/** @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
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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);
|
||||
|
||||
@@ -3995,48 +3616,14 @@ CV_EXPORTS_W void findContoursLinkRuns(InputArray image, OutputArrayOfArrays con
|
||||
//! @overload
|
||||
CV_EXPORTS_W void findContoursLinkRuns(InputArray image, OutputArrayOfArrays contours);
|
||||
|
||||
/** @example samples/python/snippets/squares.py
|
||||
An example using approxPolyDP function in python.
|
||||
*/
|
||||
|
||||
/** @brief Approximates a polygonal curve(s) with the specified precision.
|
||||
|
||||
The function cv::approxPolyDP approximates a curve or a polygon 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.
|
||||
/** @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 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.
|
||||
|
||||
The 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);
|
||||
CV_EXPORTS_W Rect boundingRect( InputArray array );
|
||||
|
||||
/** @brief Calculates a contour perimeter or a curve length.
|
||||
|
||||
@@ -4047,15 +3634,6 @@ The function computes a curve length or a closed contour perimeter.
|
||||
*/
|
||||
CV_EXPORTS_W double arcLength( InputArray curve, bool closed );
|
||||
|
||||
/** @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 a contour area.
|
||||
|
||||
The function computes a contour area. Similarly to moments , the area is computed using the Green
|
||||
@@ -4088,378 +3666,6 @@ false, which means that the absolute value is returned.
|
||||
*/
|
||||
CV_EXPORTS_W double contourArea( InputArray contour, bool oriented = false );
|
||||
|
||||
/** @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*.
|
||||
|
||||

|
||||
|
||||
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 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:
|
||||
|
||||

|
||||
|
||||
@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:
|
||||
|
||||

|
||||
|
||||
@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.
|
||||
|
||||

|
||||
|
||||
@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 Creates a smart pointer to a cv::GeneralizedHoughBallard class and initializes it.
|
||||
*/
|
||||
|
||||
@@ -145,21 +145,6 @@ public class ImgprocTest extends OpenCVTestCase {
|
||||
assertEquals(src.rows(), Core.countNonZero(dst));
|
||||
}
|
||||
|
||||
public void testApproxPolyDP() {
|
||||
MatOfPoint2f curve = new MatOfPoint2f(new Point(1, 3), new Point(2, 4), new Point(3, 5), new Point(4, 4), new Point(5, 3));
|
||||
|
||||
MatOfPoint2f approxCurve = new MatOfPoint2f();
|
||||
|
||||
Imgproc.approxPolyDP(curve, approxCurve, EPS, true);
|
||||
|
||||
List<Point> approxCurveGold = new ArrayList<Point>(3);
|
||||
approxCurveGold.add(new Point(1, 3));
|
||||
approxCurveGold.add(new Point(3, 5));
|
||||
approxCurveGold.add(new Point(5, 3));
|
||||
|
||||
assertListPointEquals(approxCurve.toList(), approxCurveGold, EPS);
|
||||
}
|
||||
|
||||
public void testArcLength() {
|
||||
MatOfPoint2f curve = new MatOfPoint2f(new Point(1, 3), new Point(2, 4), new Point(3, 5), new Point(4, 4), new Point(5, 3));
|
||||
|
||||
@@ -412,65 +397,6 @@ public class ImgprocTest extends OpenCVTestCase {
|
||||
assertMatEqual(truthMap2, dstmap2);
|
||||
}
|
||||
|
||||
public void testConvexHullMatMat() {
|
||||
MatOfPoint points = new MatOfPoint(
|
||||
new Point(20, 0),
|
||||
new Point(40, 0),
|
||||
new Point(30, 20),
|
||||
new Point(0, 20),
|
||||
new Point(20, 10),
|
||||
new Point(30, 10)
|
||||
);
|
||||
|
||||
MatOfInt hull = new MatOfInt();
|
||||
|
||||
Imgproc.convexHull(points, hull);
|
||||
|
||||
MatOfInt expHull = new MatOfInt(
|
||||
0, 1, 2, 3
|
||||
);
|
||||
assertMatEqual(expHull, hull.reshape(1, (int)hull.total()), EPS);
|
||||
}
|
||||
|
||||
public void testConvexHullMatMatBooleanBoolean() {
|
||||
MatOfPoint points = new MatOfPoint(
|
||||
new Point(2, 0),
|
||||
new Point(4, 0),
|
||||
new Point(3, 2),
|
||||
new Point(0, 2),
|
||||
new Point(2, 1),
|
||||
new Point(3, 1)
|
||||
);
|
||||
|
||||
MatOfInt hull = new MatOfInt();
|
||||
|
||||
Imgproc.convexHull(points, hull, true);
|
||||
|
||||
MatOfInt expHull = new MatOfInt(
|
||||
3, 2, 1, 0
|
||||
);
|
||||
assertMatEqual(expHull, hull.reshape(1, hull.cols()), EPS);
|
||||
}
|
||||
|
||||
public void testConvexityDefects() {
|
||||
MatOfPoint points = new MatOfPoint(
|
||||
new Point(20, 0),
|
||||
new Point(40, 0),
|
||||
new Point(30, 20),
|
||||
new Point(0, 20),
|
||||
new Point(20, 10),
|
||||
new Point(30, 10)
|
||||
);
|
||||
|
||||
MatOfInt hull = new MatOfInt();
|
||||
Imgproc.convexHull(points, hull);
|
||||
|
||||
MatOfInt4 convexityDefects = new MatOfInt4();
|
||||
Imgproc.convexityDefects(points, hull, convexityDefects);
|
||||
|
||||
assertMatEqual(new MatOfInt4(3, 0, 5, 3620), convexityDefects.reshape(4, convexityDefects.cols()));
|
||||
}
|
||||
|
||||
public void testCornerEigenValsAndVecsMatMatIntInt() {
|
||||
fail("Not yet implemented");
|
||||
// TODO: write better test
|
||||
@@ -791,33 +717,6 @@ public class ImgprocTest extends OpenCVTestCase {
|
||||
*/
|
||||
}
|
||||
|
||||
public void testFitEllipse() {
|
||||
MatOfPoint2f points = new MatOfPoint2f(new Point(0, 0), new Point(-1, 1), new Point(1, 1), new Point(1, -1), new Point(-1, -1));
|
||||
RotatedRect rrect = new RotatedRect();
|
||||
|
||||
rrect = Imgproc.fitEllipse(points);
|
||||
|
||||
double FIT_ELLIPSE_CENTER_EPS = 0.01;
|
||||
double FIT_ELLIPSE_SIZE_EPS = 0.4;
|
||||
|
||||
assertEquals(0.0, rrect.center.x, FIT_ELLIPSE_CENTER_EPS);
|
||||
assertEquals(0.0, rrect.center.y, FIT_ELLIPSE_CENTER_EPS);
|
||||
assertEquals(2.828, rrect.size.width, FIT_ELLIPSE_SIZE_EPS);
|
||||
assertEquals(2.828, rrect.size.height, FIT_ELLIPSE_SIZE_EPS);
|
||||
}
|
||||
|
||||
public void testFitLine() {
|
||||
Mat points = new Mat(1, 4, CvType.CV_32FC2);
|
||||
points.put(0, 0, 0, 0, 2, 3, 3, 4, 5, 8);
|
||||
|
||||
Mat linePoints = new Mat(4, 1, CvType.CV_32FC1);
|
||||
linePoints.put(0, 0, 0.53198653, 0.84675282, 2.5, 3.75);
|
||||
|
||||
Imgproc.fitLine(points, dst, Imgproc.DIST_L12, 0, 0.01, 0.01);
|
||||
|
||||
assertMatEqual(linePoints, dst, EPS);
|
||||
}
|
||||
|
||||
public void testFloodFillMatMatPointScalar() {
|
||||
Mat mask = new Mat(matSize + 2, matSize + 2, CvType.CV_8U, new Scalar(0));
|
||||
Mat img = gray0;
|
||||
@@ -1243,16 +1142,6 @@ public class ImgprocTest extends OpenCVTestCase {
|
||||
assertMatEqual(truth, dst, EPS);
|
||||
}
|
||||
|
||||
public void testIsContourConvex() {
|
||||
MatOfPoint contour1 = new MatOfPoint(new Point(0, 0), new Point(10, 0), new Point(10, 10), new Point(5, 4));
|
||||
|
||||
assertFalse(Imgproc.isContourConvex(contour1));
|
||||
|
||||
MatOfPoint contour2 = new MatOfPoint(new Point(0, 0), new Point(10, 0), new Point(10, 10), new Point(5, 6));
|
||||
|
||||
assertTrue(Imgproc.isContourConvex(contour2));
|
||||
}
|
||||
|
||||
public void testLaplacianMatMatInt() {
|
||||
Imgproc.Laplacian(gray0, dst, CvType.CV_8U);
|
||||
|
||||
@@ -1282,17 +1171,6 @@ public class ImgprocTest extends OpenCVTestCase {
|
||||
assertMatEqual(truth, dst, EPS);
|
||||
}
|
||||
|
||||
public void testMatchShapes() {
|
||||
Mat contour1 = new Mat(1, 4, CvType.CV_32FC2);
|
||||
Mat contour2 = new Mat(1, 4, CvType.CV_32FC2);
|
||||
contour1.put(0, 0, 1, 1, 5, 1, 4, 3, 6, 2);
|
||||
contour2.put(0, 0, 1, 1, 6, 1, 4, 1, 2, 5);
|
||||
|
||||
double distance = Imgproc.matchShapes(contour1, contour2, Imgproc.CONTOURS_MATCH_I1, 1);
|
||||
|
||||
assertEquals(2.81109697365334, distance, EPS);
|
||||
}
|
||||
|
||||
public void testMatchTemplate() {
|
||||
Mat image = new Mat(imgprocSz, imgprocSz, CvType.CV_8U);
|
||||
Mat templ = new Mat(imgprocSz, imgprocSz, CvType.CV_8U);
|
||||
@@ -1319,27 +1197,6 @@ public class ImgprocTest extends OpenCVTestCase {
|
||||
// TODO_: write better test
|
||||
}
|
||||
|
||||
public void testMinAreaRect() {
|
||||
MatOfPoint2f points = new MatOfPoint2f(new Point(1, 1), new Point(5, 1), new Point(4, 3), new Point(6, 2));
|
||||
|
||||
RotatedRect rrect = Imgproc.minAreaRect(points);
|
||||
|
||||
assertEquals(new Size(2, 5), rrect.size);
|
||||
assertEquals(-90., rrect.angle);
|
||||
assertEquals(new Point(3.5, 2), rrect.center);
|
||||
}
|
||||
|
||||
public void testMinEnclosingCircle() {
|
||||
MatOfPoint2f points = new MatOfPoint2f(new Point(0, 0), new Point(-100, 0), new Point(0, -100), new Point(100, 0), new Point(0, 100));
|
||||
Point actualCenter = new Point();
|
||||
float[] radius = new float[1];
|
||||
|
||||
Imgproc.minEnclosingCircle(points, actualCenter, radius);
|
||||
|
||||
assertEquals(new Point(0, 0), actualCenter);
|
||||
assertEquals(100.0f, radius[0], 1.0);
|
||||
}
|
||||
|
||||
public void testMomentsMat() {
|
||||
fail("Not yet implemented");
|
||||
}
|
||||
@@ -1389,15 +1246,6 @@ public class ImgprocTest extends OpenCVTestCase {
|
||||
// TODO_: write better test
|
||||
}
|
||||
|
||||
public void testPointPolygonTest() {
|
||||
MatOfPoint2f contour = new MatOfPoint2f(new Point(0, 0), new Point(1, 3), new Point(3, 4), new Point(4, 3), new Point(2, 1));
|
||||
double sign1 = Imgproc.pointPolygonTest(contour, new Point(2, 2), false);
|
||||
assertEquals(1.0, sign1);
|
||||
|
||||
double sign2 = Imgproc.pointPolygonTest(contour, new Point(4, 4), true);
|
||||
assertEquals(-Math.sqrt(0.5), sign2);
|
||||
}
|
||||
|
||||
public void testPreCornerDetectMatMatInt() {
|
||||
Mat src = new Mat(4, 4, CvType.CV_32F, new Scalar(1));
|
||||
int ksize = 3;
|
||||
|
||||
@@ -106,41 +106,6 @@ PERF_TEST_P(TestBoundingRect, BoundingRect,
|
||||
SANITY_CHECK_NOTHING();
|
||||
}
|
||||
|
||||
typedef TestBaseWithParam< tuple<MatDepth, int> > TestMinEnclosingCircle;
|
||||
PERF_TEST_P(TestMinEnclosingCircle, minEnclosingCircle,
|
||||
Combine(
|
||||
testing::Values(CV_32S, CV_32F),
|
||||
Values(400, 1000, 10000, 100000)
|
||||
))
|
||||
{
|
||||
int ptType = get<0>(GetParam());
|
||||
int n = get<1>(GetParam());
|
||||
Mat pts(n, 2, ptType);
|
||||
declare.in(pts, WARMUP_RNG);
|
||||
|
||||
Point2f center;
|
||||
float radius;
|
||||
TEST_CYCLE() minEnclosingCircle(pts, center, radius);
|
||||
SANITY_CHECK_NOTHING();
|
||||
}
|
||||
|
||||
typedef TestBaseWithParam<int> TestMinEnclosingCircleWorstCase;
|
||||
PERF_TEST_P(TestMinEnclosingCircleWorstCase, minEnclosingCircle_sequential,
|
||||
Values(400, 1000, 5000, 10000))
|
||||
{
|
||||
int n = GetParam();
|
||||
vector<Point2f> contour;
|
||||
for(int i = 0; i < n; ++i) {
|
||||
float angle = (float)(i * 2 * CV_PI / n);
|
||||
contour.push_back(Point2f(cos(angle) * 100, sin(angle) * 100));
|
||||
}
|
||||
|
||||
Point2f center;
|
||||
float radius;
|
||||
TEST_CYCLE() minEnclosingCircle(contour, center, radius);
|
||||
SANITY_CHECK_NOTHING();
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// findTRUContours performance tests
|
||||
// ============================================================
|
||||
|
||||
@@ -6,10 +6,290 @@
|
||||
#include "contours_common.hpp"
|
||||
#include <map>
|
||||
#include <limits>
|
||||
#include "opencv2/core/hal/intrin.hpp"
|
||||
#include "opencv2/core/check.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace cv;
|
||||
|
||||
// calculates length of a curve (e.g. contour perimeter)
|
||||
double cv::arcLength( InputArray _curve, bool is_closed )
|
||||
{
|
||||
CV_INSTRUMENT_REGION();
|
||||
|
||||
Mat curve = _curve.getMat();
|
||||
int count = curve.checkVector(2);
|
||||
int depth = curve.depth();
|
||||
CV_Assert( count >= 0 && (depth == CV_32F || depth == CV_32S));
|
||||
double perimeter = 0;
|
||||
|
||||
int i;
|
||||
|
||||
if( count <= 1 )
|
||||
return 0.;
|
||||
|
||||
bool is_float = depth == CV_32F;
|
||||
int last = is_closed ? count-1 : 0;
|
||||
const Point* pti = curve.ptr<Point>();
|
||||
const Point2f* ptf = curve.ptr<Point2f>();
|
||||
|
||||
Point2f prev = is_float ? ptf[last] : Point2f((float)pti[last].x,(float)pti[last].y);
|
||||
|
||||
for( i = 0; i < count; i++ )
|
||||
{
|
||||
Point2f p = is_float ? ptf[i] : Point2f((float)pti[i].x,(float)pti[i].y);
|
||||
float dx = p.x - prev.x, dy = p.y - prev.y;
|
||||
perimeter += std::sqrt(dx*dx + dy*dy);
|
||||
|
||||
prev = p;
|
||||
}
|
||||
|
||||
return perimeter;
|
||||
}
|
||||
|
||||
static Rect maskBoundingRect( const Mat& img )
|
||||
{
|
||||
CV_Assert( img.depth() <= CV_8S && img.channels() == 1 );
|
||||
|
||||
Size size = img.size();
|
||||
int xmin = size.width, ymin = -1, xmax = -1, ymax = -1, i, j, k;
|
||||
|
||||
for( i = 0; i < size.height; i++ )
|
||||
{
|
||||
const uchar* _ptr = img.ptr(i);
|
||||
const uchar* ptr = (const uchar*)alignPtr(_ptr, 4);
|
||||
int have_nz = 0, k_min, offset = (int)(ptr - _ptr);
|
||||
j = 0;
|
||||
offset = MIN(offset, size.width);
|
||||
for( ; j < offset; j++ )
|
||||
if( _ptr[j] )
|
||||
{
|
||||
if( j < xmin )
|
||||
xmin = j;
|
||||
if( j > xmax )
|
||||
xmax = j;
|
||||
have_nz = 1;
|
||||
}
|
||||
if( offset < size.width )
|
||||
{
|
||||
xmin -= offset;
|
||||
xmax -= offset;
|
||||
size.width -= offset;
|
||||
j = 0;
|
||||
for( ; j <= xmin - 4; j += 4 )
|
||||
if( *((int*)(ptr+j)) )
|
||||
break;
|
||||
for( ; j < xmin; j++ )
|
||||
if( ptr[j] )
|
||||
{
|
||||
xmin = j;
|
||||
if( j > xmax )
|
||||
xmax = j;
|
||||
have_nz = 1;
|
||||
break;
|
||||
}
|
||||
k_min = MAX(j-1, xmax);
|
||||
k = size.width - 1;
|
||||
for( ; k > k_min && (k&3) != 3; k-- )
|
||||
if( ptr[k] )
|
||||
break;
|
||||
if( k > k_min && (k&3) == 3 )
|
||||
{
|
||||
for( ; k > k_min+3; k -= 4 )
|
||||
if( *((int*)(ptr+k-3)) )
|
||||
break;
|
||||
}
|
||||
for( ; k > k_min; k-- )
|
||||
if( ptr[k] )
|
||||
{
|
||||
xmax = k;
|
||||
have_nz = 1;
|
||||
break;
|
||||
}
|
||||
if( !have_nz )
|
||||
{
|
||||
j &= ~3;
|
||||
for( ; j <= k - 3; j += 4 )
|
||||
if( *((int*)(ptr+j)) )
|
||||
break;
|
||||
for( ; j <= k; j++ )
|
||||
if( ptr[j] )
|
||||
{
|
||||
have_nz = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
xmin += offset;
|
||||
xmax += offset;
|
||||
size.width += offset;
|
||||
}
|
||||
if( have_nz )
|
||||
{
|
||||
if( ymin < 0 )
|
||||
ymin = i;
|
||||
ymax = i;
|
||||
}
|
||||
}
|
||||
|
||||
if( xmin >= size.width )
|
||||
xmin = ymin = 0;
|
||||
return Rect(xmin, ymin, xmax - xmin + 1, ymax - ymin + 1);
|
||||
}
|
||||
|
||||
// Calculates bounding rectangle of a point set or retrieves already calculated
|
||||
static Rect pointSetBoundingRect( const Mat& points )
|
||||
{
|
||||
int npoints = points.checkVector(2);
|
||||
int depth = points.depth();
|
||||
CV_Assert(npoints >= 0 && (depth == CV_32F || depth == CV_32S));
|
||||
|
||||
int xmin = 0, ymin = 0, xmax = -1, ymax = -1, i = 0;
|
||||
bool is_float = depth == CV_32F;
|
||||
|
||||
if( npoints == 0 )
|
||||
return Rect();
|
||||
|
||||
if( !is_float )
|
||||
{
|
||||
const int32_t* pts = points.ptr<int32_t>();
|
||||
int64_t firstval = 0;
|
||||
std::memcpy(&firstval, pts, sizeof(pts[0]) * 2);
|
||||
xmin = xmax = pts[0];
|
||||
ymin = ymax = pts[1];
|
||||
#if CV_SIMD || CV_SIMD_SCALABLE
|
||||
v_int32 minval, maxval;
|
||||
minval = maxval = v_reinterpret_as_s32(vx_setall_s64(firstval)); //min[0]=pt.x, min[1]=pt.y, min[2]=pt.x, min[3]=pt.y
|
||||
const int nlanes = VTraits<v_int32>::vlanes()/2;
|
||||
for (; i < npoints; i += nlanes)
|
||||
{
|
||||
if (i > npoints - nlanes)
|
||||
{
|
||||
if (i == 0)
|
||||
break;
|
||||
i = npoints - nlanes;
|
||||
}
|
||||
v_int32 ptXY2 = vx_load(pts + 2 * i);
|
||||
minval = v_min(ptXY2, minval);
|
||||
maxval = v_max(ptXY2, maxval);
|
||||
}
|
||||
constexpr int max_nlanes = VTraits<v_int32>::max_nlanes;
|
||||
int arr_minval[max_nlanes], arr_maxval[max_nlanes];
|
||||
vx_store(arr_minval, minval);
|
||||
vx_store(arr_maxval, maxval);
|
||||
for (int j = 0; j < nlanes; j++)
|
||||
{
|
||||
xmin = std::min(xmin, arr_minval[2*j]);
|
||||
ymin = std::min(ymin, arr_minval[2*j+1]);
|
||||
xmax = std::max(xmax, arr_maxval[2*j]);
|
||||
ymax = std::max(ymax, arr_maxval[2*j+1]);
|
||||
}
|
||||
#endif
|
||||
for( ; i < npoints; i++ )
|
||||
{
|
||||
int pt_x = pts[2*i];
|
||||
int pt_y = pts[2*i+1];
|
||||
|
||||
xmin = std::min(xmin, pt_x);
|
||||
xmax = std::max(xmax, pt_x);
|
||||
ymin = std::min(ymin, pt_y);
|
||||
ymax = std::max(ymax, pt_y);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const float* pts = points.ptr<float>();
|
||||
int64_t firstval = 0;
|
||||
std::memcpy(&firstval, pts, sizeof(pts[0]) * 2);
|
||||
xmin = xmax = cvFloor(pts[0]);
|
||||
ymin = ymax = cvFloor(pts[1]);
|
||||
#if CV_SIMD || CV_SIMD_SCALABLE
|
||||
v_float32 minval, maxval;
|
||||
minval = maxval = v_reinterpret_as_f32(vx_setall_s64(firstval)); //min[0]=pt.x, min[1]=pt.y, min[2]=pt.x, min[3]=pt.y
|
||||
const int nlanes = VTraits<v_float32>::vlanes()/2;
|
||||
for (; i < npoints; i += nlanes)
|
||||
{
|
||||
if (i > npoints - nlanes)
|
||||
{
|
||||
if (i == 0)
|
||||
break;
|
||||
i = npoints - nlanes;
|
||||
}
|
||||
v_float32 ptXY2 = vx_load(pts + 2 * i);
|
||||
minval = v_min(ptXY2, minval);
|
||||
maxval = v_max(ptXY2, maxval);
|
||||
}
|
||||
constexpr int max_nlanes = VTraits<v_int32>::max_nlanes;
|
||||
float arr_minval[max_nlanes], arr_maxval[max_nlanes];
|
||||
vx_store(arr_minval, minval);
|
||||
vx_store(arr_maxval, maxval);
|
||||
for (int j = 0; j < nlanes; j++)
|
||||
{
|
||||
int _xmin = cvFloor(arr_minval[2*j]), _ymin = cvFloor(arr_minval[2*j+1]);
|
||||
int _xmax = cvFloor(arr_maxval[2*j]), _ymax = cvFloor(arr_maxval[2*j+1]);
|
||||
xmin = std::min(xmin, _xmin);
|
||||
ymin = std::min(ymin, _ymin);
|
||||
xmax = std::max(xmax, _xmax);
|
||||
ymax = std::max(ymax, _ymax);
|
||||
}
|
||||
#endif
|
||||
for( ; i < npoints; i++ )
|
||||
{
|
||||
// because right and bottom sides of the bounding rectangle are not inclusive
|
||||
// (note +1 in width and height calculation below), cvFloor is used here instead of cvCeil
|
||||
int pt_x = cvFloor(pts[2*i]);
|
||||
int pt_y = cvFloor(pts[2*i+1]);
|
||||
|
||||
xmin = std::min(xmin, pt_x);
|
||||
xmax = std::max(xmax, pt_x);
|
||||
ymin = std::min(ymin, pt_y);
|
||||
ymax = std::max(ymax, pt_y);
|
||||
}
|
||||
}
|
||||
|
||||
return Rect(xmin, ymin, xmax - xmin + 1, ymax - ymin + 1);
|
||||
}
|
||||
|
||||
cv::Rect cv::boundingRect(InputArray array)
|
||||
{
|
||||
CV_INSTRUMENT_REGION();
|
||||
|
||||
Mat m = array.getMat();
|
||||
return m.depth() <= CV_8U ? maskBoundingRect(m) : pointSetBoundingRect(m);
|
||||
}
|
||||
|
||||
// area of a whole sequence
|
||||
double cv::contourArea( InputArray _contour, bool oriented )
|
||||
{
|
||||
CV_INSTRUMENT_REGION();
|
||||
|
||||
Mat contour = _contour.getMat();
|
||||
int npoints = contour.checkVector(2);
|
||||
int depth = contour.depth();
|
||||
CV_Assert(npoints >= 0 && (depth == CV_32F || depth == CV_32S));
|
||||
|
||||
if( npoints == 0 )
|
||||
return 0.;
|
||||
|
||||
double a00 = 0;
|
||||
bool is_float = depth == CV_32F;
|
||||
const Point* ptsi = contour.ptr<Point>();
|
||||
const Point2f* ptsf = contour.ptr<Point2f>();
|
||||
Point2f prev = is_float ? ptsf[npoints-1] : Point2f((float)ptsi[npoints-1].x, (float)ptsi[npoints-1].y);
|
||||
|
||||
for( int i = 0; i < npoints; i++ )
|
||||
{
|
||||
Point2f p = is_float ? ptsf[i] : Point2f((float)ptsi[i].x, (float)ptsi[i].y);
|
||||
a00 += (double)prev.x * p.y - (double)prev.y * p.x;
|
||||
prev = p;
|
||||
}
|
||||
|
||||
a00 *= 0.5;
|
||||
if( !oriented )
|
||||
a00 = fabs(a00);
|
||||
|
||||
return a00;
|
||||
}
|
||||
|
||||
void cv::contourTreeToResults(CTree& tree,
|
||||
int res_type,
|
||||
OutputArrayOfArrays& _contours,
|
||||
|
||||
Executable → Regular
@@ -208,20 +208,6 @@ TEST(Imgproc_DrawContours, regression_26264)
|
||||
ASSERT_EQ(0, cvtest::norm(img2, img3, NORM_INF));
|
||||
}
|
||||
|
||||
TEST(Imgproc_PointPolygonTest, regression_10222)
|
||||
{
|
||||
vector<Point> contour;
|
||||
contour.push_back(Point(0, 0));
|
||||
contour.push_back(Point(0, 100000));
|
||||
contour.push_back(Point(100000, 100000));
|
||||
contour.push_back(Point(100000, 50000));
|
||||
contour.push_back(Point(100000, 0));
|
||||
|
||||
const Point2f point(40000, 40000);
|
||||
const double result = cv::pointPolygonTest(contour, point, false);
|
||||
EXPECT_GT(result, 0) << "Desired result: point is inside polygon - actual result: point is not inside polygon";
|
||||
}
|
||||
|
||||
TEST(Imgproc_DrawContours, MatListOfMatIntScalarInt)
|
||||
{
|
||||
Mat gray0 = Mat::zeros(10, 10, CV_8U);
|
||||
|
||||
@@ -599,85 +599,6 @@ static void check_resize_area(const Mat& expected, const Mat& actual, double tol
|
||||
ASSERT_EQ(0, cvtest::norm(one_channel_diff, cv::NORM_INF));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TEST(Imgproc_fitLine_vector_3d, regression)
|
||||
{
|
||||
std::vector<Point3f> points_vector;
|
||||
|
||||
Point3f p21(4,4,4);
|
||||
Point3f p22(8,8,8);
|
||||
|
||||
points_vector.push_back(p21);
|
||||
points_vector.push_back(p22);
|
||||
|
||||
std::vector<float> line;
|
||||
|
||||
cv::fitLine(points_vector, line, DIST_L2, 0 ,0 ,0);
|
||||
|
||||
ASSERT_EQ(line.size(), (size_t)6);
|
||||
|
||||
}
|
||||
|
||||
TEST(Imgproc_fitLine_vector_2d, regression)
|
||||
{
|
||||
std::vector<Point2f> points_vector;
|
||||
|
||||
Point2f p21(4,4);
|
||||
Point2f p22(8,8);
|
||||
Point2f p23(16,16);
|
||||
|
||||
points_vector.push_back(p21);
|
||||
points_vector.push_back(p22);
|
||||
points_vector.push_back(p23);
|
||||
|
||||
std::vector<float> line;
|
||||
|
||||
cv::fitLine(points_vector, line, DIST_L2, 0 ,0 ,0);
|
||||
|
||||
ASSERT_EQ(line.size(), (size_t)4);
|
||||
}
|
||||
|
||||
TEST(Imgproc_fitLine_Mat_2dC2, regression)
|
||||
{
|
||||
cv::Mat mat1 = Mat::zeros(3, 1, CV_32SC2);
|
||||
std::vector<float> line1;
|
||||
|
||||
cv::fitLine(mat1, line1, DIST_L2, 0 ,0 ,0);
|
||||
|
||||
ASSERT_EQ(line1.size(), (size_t)4);
|
||||
}
|
||||
|
||||
TEST(Imgproc_fitLine_Mat_2dC1, regression)
|
||||
{
|
||||
cv::Matx<int, 3, 2> mat2;
|
||||
std::vector<float> line2;
|
||||
|
||||
cv::fitLine(mat2, line2, DIST_L2, 0 ,0 ,0);
|
||||
|
||||
ASSERT_EQ(line2.size(), (size_t)4);
|
||||
}
|
||||
|
||||
TEST(Imgproc_fitLine_Mat_3dC3, regression)
|
||||
{
|
||||
cv::Mat mat1 = Mat::zeros(2, 1, CV_32SC3);
|
||||
std::vector<float> line1;
|
||||
|
||||
cv::fitLine(mat1, line1, DIST_L2, 0 ,0 ,0);
|
||||
|
||||
ASSERT_EQ(line1.size(), (size_t)6);
|
||||
}
|
||||
|
||||
TEST(Imgproc_fitLine_Mat_3dC1, regression)
|
||||
{
|
||||
cv::Mat mat2 = Mat::zeros(2, 3, CV_32SC1);
|
||||
std::vector<float> line2;
|
||||
|
||||
cv::fitLine(mat2, line2, DIST_L2, 0 ,0 ,0);
|
||||
|
||||
ASSERT_EQ(line2.size(), (size_t)6);
|
||||
}
|
||||
|
||||
TEST(Imgproc_resize_area, regression)
|
||||
{
|
||||
static ushort input_data[16 * 16] = {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
#include "../precomp.hpp"
|
||||
#include "bardetect.hpp"
|
||||
|
||||
#include "opencv2/3d.hpp"
|
||||
|
||||
namespace cv {
|
||||
namespace barcode {
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
#include "opencv2/objdetect.hpp"
|
||||
#include "opencv2/objdetect/barcode.hpp"
|
||||
#include "opencv2/imgproc.hpp"
|
||||
#include "opencv2/3d.hpp"
|
||||
|
||||
#include <opencv2/core/utils/logger.hpp>
|
||||
#include "opencv2/core/utility.hpp"
|
||||
@@ -61,7 +62,6 @@ namespace cv {
|
||||
|
||||
int checkChessboardBinary(const Mat & img, const Size & size);
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
#include "test_chessboardgenerator.hpp"
|
||||
|
||||
#include <functional>
|
||||
#include <numeric>
|
||||
|
||||
namespace opencv_test { namespace {
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ if(HAVE_CUDA)
|
||||
ocv_warnings_disable(CMAKE_CXX_FLAGS -Wundef -Wmissing-declarations -Wshadow)
|
||||
endif()
|
||||
|
||||
ocv_define_module(photo opencv_imgproc OPTIONAL opencv_cudaarithm opencv_cudaimgproc WRAP java objc python js)
|
||||
ocv_define_module(photo opencv_imgproc opencv_3d OPTIONAL opencv_cudaarithm opencv_cudaimgproc WRAP java objc python js)
|
||||
|
||||
if(HAVE_CUDA AND ENABLE_CUDA_FIRST_CLASS_LANGUAGE AND HAVE_opencv_cudaarithm AND HAVE_opencv_cudaimgproc)
|
||||
ocv_target_link_libraries(${the_module} PRIVATE CUDA::cudart${CUDA_LIB_EXT})
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
|
||||
#include "precomp.hpp"
|
||||
#include "opencv2/photo.hpp"
|
||||
#include "opencv2/3d.hpp"
|
||||
|
||||
#include "seamless_cloning.hpp"
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#include <opencv2/3d.hpp>
|
||||
#include <opencv2/imgproc.hpp>
|
||||
#include <opencv2/highgui.hpp>
|
||||
#include <iostream>
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
*
|
||||
*********************************************************************************/
|
||||
|
||||
#include "opencv2/3d.hpp"
|
||||
#include "opencv2/imgproc.hpp"
|
||||
#include "opencv2/highgui.hpp"
|
||||
#include <iostream>
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
* A program that illustrates intersectConvexConvex in various scenarios
|
||||
*/
|
||||
|
||||
#include "opencv2/3d.hpp"
|
||||
#include "opencv2/imgproc.hpp"
|
||||
#include "opencv2/highgui.hpp"
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#include "opencv2/3d.hpp"
|
||||
#include "opencv2/imgproc.hpp"
|
||||
#include "opencv2/imgcodecs.hpp"
|
||||
#include "opencv2/highgui.hpp"
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
// each image
|
||||
|
||||
#include "opencv2/core.hpp"
|
||||
#include "opencv2/3d.hpp"
|
||||
#include "opencv2/imgproc.hpp"
|
||||
#include "opencv2/imgcodecs.hpp"
|
||||
#include "opencv2/highgui.hpp"
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include "opencv2/imgcodecs.hpp"
|
||||
#include "opencv2/highgui.hpp"
|
||||
#include "opencv2/3d.hpp"
|
||||
#include "opencv2/imgproc.hpp"
|
||||
#include <iostream>
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include "opencv2/imgcodecs.hpp"
|
||||
#include "opencv2/highgui.hpp"
|
||||
#include "opencv2/3d.hpp"
|
||||
#include "opencv2/imgproc.hpp"
|
||||
#include <iostream>
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include "opencv2/imgcodecs.hpp"
|
||||
#include "opencv2/highgui.hpp"
|
||||
#include "opencv2/3d.hpp"
|
||||
#include "opencv2/imgproc.hpp"
|
||||
#include <iostream>
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
*/
|
||||
|
||||
#include "opencv2/highgui.hpp"
|
||||
#include "opencv2/3d.hpp"
|
||||
#include "opencv2/imgproc.hpp"
|
||||
#include <iostream>
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "opencv2/core.hpp"
|
||||
#include "opencv2/core/ocl.hpp"
|
||||
#include "opencv2/core/utility.hpp"
|
||||
#include "opencv2/3d.hpp"
|
||||
#include "opencv2/imgproc.hpp"
|
||||
#include "opencv2/imgcodecs.hpp"
|
||||
#include "opencv2/highgui.hpp"
|
||||
|
||||
Reference in New Issue
Block a user