openCV library for Renesas RZ/A
Dependents: RZ_A2M_Mbed_samples
Revision 0:0e0631af0305, committed 2021-01-29
- Comitter:
- RyoheiHagimoto
- Date:
- Fri Jan 29 04:53:38 2021 +0000
- Commit message:
- copied from https://github.com/d-kato/opencv-lib.
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/calib3d.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,2134 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_CALIB3D_HPP
+#define OPENCV_CALIB3D_HPP
+
+#include "opencv2/core.hpp"
+#include "opencv2/features2d.hpp"
+#include "opencv2/core/affine.hpp"
+
+/**
+ @defgroup calib3d Camera Calibration and 3D Reconstruction
+
+The functions in this section use a so-called pinhole camera model. In this model, a scene view is
+formed by projecting 3D points into the image plane using a perspective transformation.
+
+\f[s \; m' = A [R|t] M'\f]
+
+or
+
+\f[s \vecthree{u}{v}{1} = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}
+\begin{bmatrix}
+r_{11} & r_{12} & r_{13} & t_1 \\
+r_{21} & r_{22} & r_{23} & t_2 \\
+r_{31} & r_{32} & r_{33} & t_3
+\end{bmatrix}
+\begin{bmatrix}
+X \\
+Y \\
+Z \\
+1
+\end{bmatrix}\f]
+
+where:
+
+- \f$(X, Y, Z)\f$ are the coordinates of a 3D point in the world coordinate space
+- \f$(u, v)\f$ are the coordinates of the projection point in pixels
+- \f$A\f$ is a camera matrix, or a matrix of intrinsic parameters
+- \f$(cx, cy)\f$ is a principal point that is usually at the image center
+- \f$fx, fy\f$ are the focal lengths expressed in pixel units.
+
+Thus, if an image from the camera is scaled by a factor, all of these parameters should be scaled
+(multiplied/divided, respectively) by the same factor. The matrix of intrinsic parameters does not
+depend on the scene viewed. So, once estimated, it can be re-used as long as the focal length is
+fixed (in case of zoom lens). The joint rotation-translation matrix \f$[R|t]\f$ is called a matrix of
+extrinsic parameters. It is used to describe the camera motion around a static scene, or vice versa,
+rigid motion of an object in front of a still camera. That is, \f$[R|t]\f$ translates coordinates of a
+point \f$(X, Y, Z)\f$ to a coordinate system, fixed with respect to the camera. The transformation above
+is equivalent to the following (when \f$z \ne 0\f$ ):
+
+\f[\begin{array}{l}
+\vecthree{x}{y}{z} = R \vecthree{X}{Y}{Z} + t \\
+x' = x/z \\
+y' = y/z \\
+u = f_x*x' + c_x \\
+v = f_y*y' + c_y
+\end{array}\f]
+
+The following figure illustrates the pinhole camera model.
+
+
+
+Real lenses usually have some distortion, mostly radial distortion and slight tangential distortion.
+So, the above model is extended as:
+
+\f[\begin{array}{l}
+\vecthree{x}{y}{z} = R \vecthree{X}{Y}{Z} + t \\
+x' = x/z \\
+y' = y/z \\
+x'' = x' \frac{1 + k_1 r^2 + k_2 r^4 + k_3 r^6}{1 + k_4 r^2 + k_5 r^4 + k_6 r^6} + 2 p_1 x' y' + p_2(r^2 + 2 x'^2) + s_1 r^2 + s_2 r^4 \\
+y'' = y' \frac{1 + k_1 r^2 + k_2 r^4 + k_3 r^6}{1 + k_4 r^2 + k_5 r^4 + k_6 r^6} + p_1 (r^2 + 2 y'^2) + 2 p_2 x' y' + s_3 r^2 + s_4 r^4 \\
+\text{where} \quad r^2 = x'^2 + y'^2 \\
+u = f_x*x'' + c_x \\
+v = f_y*y'' + c_y
+\end{array}\f]
+
+\f$k_1\f$, \f$k_2\f$, \f$k_3\f$, \f$k_4\f$, \f$k_5\f$, and \f$k_6\f$ are radial distortion coefficients. \f$p_1\f$ and \f$p_2\f$ are
+tangential distortion coefficients. \f$s_1\f$, \f$s_2\f$, \f$s_3\f$, and \f$s_4\f$, are the thin prism distortion
+coefficients. Higher-order coefficients are not considered in OpenCV.
+
+The next figure shows two common types of radial distortion: barrel distortion (typically \f$ k_1 > 0 \f$ and pincushion distortion (typically \f$ k_1 < 0 \f$).
+
+
+
+In some cases the image sensor may be tilted in order to focus an oblique plane in front of the
+camera (Scheimpfug condition). This can be useful for particle image velocimetry (PIV) or
+triangulation with a laser fan. The tilt causes a perspective distortion of \f$x''\f$ and
+\f$y''\f$. This distortion can be modelled in the following way, see e.g. @cite Louhichi07.
+
+\f[\begin{array}{l}
+s\vecthree{x'''}{y'''}{1} =
+\vecthreethree{R_{33}(\tau_x, \tau_y)}{0}{-R_{13}(\tau_x, \tau_y)}
+{0}{R_{33}(\tau_x, \tau_y)}{-R_{23}(\tau_x, \tau_y)}
+{0}{0}{1} R(\tau_x, \tau_y) \vecthree{x''}{y''}{1}\\
+u = f_x*x''' + c_x \\
+v = f_y*y''' + c_y
+\end{array}\f]
+
+where the matrix \f$R(\tau_x, \tau_y)\f$ is defined by two rotations with angular parameter \f$\tau_x\f$
+and \f$\tau_y\f$, respectively,
+
+\f[
+R(\tau_x, \tau_y) =
+\vecthreethree{\cos(\tau_y)}{0}{-\sin(\tau_y)}{0}{1}{0}{\sin(\tau_y)}{0}{\cos(\tau_y)}
+\vecthreethree{1}{0}{0}{0}{\cos(\tau_x)}{\sin(\tau_x)}{0}{-\sin(\tau_x)}{\cos(\tau_x)} =
+\vecthreethree{\cos(\tau_y)}{\sin(\tau_y)\sin(\tau_x)}{-\sin(\tau_y)\cos(\tau_x)}
+{0}{\cos(\tau_x)}{\sin(\tau_x)}
+{\sin(\tau_y)}{-\cos(\tau_y)\sin(\tau_x)}{\cos(\tau_y)\cos(\tau_x)}.
+\f]
+
+In the functions below the coefficients are passed or returned as
+
+\f[(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6 [, s_1, s_2, s_3, s_4[, \tau_x, \tau_y]]]])\f]
+
+vector. That is, if the vector contains four elements, it means that \f$k_3=0\f$ . The distortion
+coefficients do not depend on the scene viewed. Thus, they also belong to the intrinsic camera
+parameters. And they remain the same regardless of the captured image resolution. If, for example, a
+camera has been calibrated on images of 320 x 240 resolution, absolutely the same distortion
+coefficients can be used for 640 x 480 images from the same camera while \f$f_x\f$, \f$f_y\f$, \f$c_x\f$, and
+\f$c_y\f$ need to be scaled appropriately.
+
+The functions below use the above model to do the following:
+
+- Project 3D points to the image plane given intrinsic and extrinsic parameters.
+- Compute extrinsic parameters given intrinsic parameters, a few 3D points, and their
+projections.
+- Estimate intrinsic and extrinsic camera parameters from several views of a known calibration
+pattern (every view is described by several 3D-2D point correspondences).
+- Estimate the relative position and orientation of the stereo camera "heads" and compute the
+*rectification* transformation that makes the camera optical axes parallel.
+
+@note
+ - A calibration sample for 3 cameras in horizontal position can be found at
+ opencv_source_code/samples/cpp/3calibration.cpp
+ - A calibration sample based on a sequence of images can be found at
+ opencv_source_code/samples/cpp/calibration.cpp
+ - A calibration sample in order to do 3D reconstruction can be found at
+ opencv_source_code/samples/cpp/build3dmodel.cpp
+ - A calibration sample of an artificially generated camera and chessboard patterns can be
+ found at opencv_source_code/samples/cpp/calibration_artificial.cpp
+ - A calibration example on stereo calibration can be found at
+ opencv_source_code/samples/cpp/stereo_calib.cpp
+ - A calibration example on stereo matching can be found at
+ opencv_source_code/samples/cpp/stereo_match.cpp
+ - (Python) A camera calibration sample can be found at
+ opencv_source_code/samples/python/calibrate.py
+
+ @{
+ @defgroup calib3d_fisheye Fisheye camera model
+
+ Definitions: Let P be a point in 3D of coordinates X in the world reference frame (stored in the
+ matrix X) The coordinate vector of P in the camera reference frame is:
+
+ \f[Xc = R X + T\f]
+
+ where R is the rotation matrix corresponding to the rotation vector om: R = rodrigues(om); call x, y
+ and z the 3 coordinates of Xc:
+
+ \f[x = Xc_1 \\ y = Xc_2 \\ z = Xc_3\f]
+
+ The pinhole projection coordinates of P is [a; b] where
+
+ \f[a = x / z \ and \ b = y / z \\ r^2 = a^2 + b^2 \\ \theta = atan(r)\f]
+
+ Fisheye distortion:
+
+ \f[\theta_d = \theta (1 + k_1 \theta^2 + k_2 \theta^4 + k_3 \theta^6 + k_4 \theta^8)\f]
+
+ The distorted point coordinates are [x'; y'] where
+
+ \f[x' = (\theta_d / r) a \\ y' = (\theta_d / r) b \f]
+
+ Finally, conversion into pixel coordinates: The final pixel coordinates vector [u; v] where:
+
+ \f[u = f_x (x' + \alpha y') + c_x \\
+ v = f_y y' + c_y\f]
+
+ @defgroup calib3d_c C API
+
+ @}
+ */
+
+namespace cv
+{
+
+//! @addtogroup calib3d
+//! @{
+
+//! type of the robust estimation algorithm
+enum { LMEDS = 4, //!< least-median algorithm
+ RANSAC = 8, //!< RANSAC algorithm
+ RHO = 16 //!< RHO algorithm
+ };
+
+enum { SOLVEPNP_ITERATIVE = 0,
+ SOLVEPNP_EPNP = 1, //!< EPnP: Efficient Perspective-n-Point Camera Pose Estimation @cite lepetit2009epnp
+ SOLVEPNP_P3P = 2, //!< Complete Solution Classification for the Perspective-Three-Point Problem @cite gao2003complete
+ SOLVEPNP_DLS = 3, //!< A Direct Least-Squares (DLS) Method for PnP @cite hesch2011direct
+ SOLVEPNP_UPNP = 4 //!< Exhaustive Linearization for Robust Camera Pose and Focal Length Estimation @cite penate2013exhaustive
+
+};
+
+enum { CALIB_CB_ADAPTIVE_THRESH = 1,
+ CALIB_CB_NORMALIZE_IMAGE = 2,
+ CALIB_CB_FILTER_QUADS = 4,
+ CALIB_CB_FAST_CHECK = 8
+ };
+
+enum { CALIB_CB_SYMMETRIC_GRID = 1,
+ CALIB_CB_ASYMMETRIC_GRID = 2,
+ CALIB_CB_CLUSTERING = 4
+ };
+
+enum { CALIB_USE_INTRINSIC_GUESS = 0x00001,
+ CALIB_FIX_ASPECT_RATIO = 0x00002,
+ CALIB_FIX_PRINCIPAL_POINT = 0x00004,
+ CALIB_ZERO_TANGENT_DIST = 0x00008,
+ CALIB_FIX_FOCAL_LENGTH = 0x00010,
+ CALIB_FIX_K1 = 0x00020,
+ CALIB_FIX_K2 = 0x00040,
+ CALIB_FIX_K3 = 0x00080,
+ CALIB_FIX_K4 = 0x00800,
+ CALIB_FIX_K5 = 0x01000,
+ CALIB_FIX_K6 = 0x02000,
+ CALIB_RATIONAL_MODEL = 0x04000,
+ CALIB_THIN_PRISM_MODEL = 0x08000,
+ CALIB_FIX_S1_S2_S3_S4 = 0x10000,
+ CALIB_TILTED_MODEL = 0x40000,
+ CALIB_FIX_TAUX_TAUY = 0x80000,
+ CALIB_USE_QR = 0x100000, //!< use QR instead of SVD decomposition for solving. Faster but potentially less precise
+ // only for stereo
+ CALIB_FIX_INTRINSIC = 0x00100,
+ CALIB_SAME_FOCAL_LENGTH = 0x00200,
+ // for stereo rectification
+ CALIB_ZERO_DISPARITY = 0x00400,
+ CALIB_USE_LU = (1 << 17), //!< use LU instead of SVD decomposition for solving. much faster but potentially less precise
+ };
+
+//! the algorithm for finding fundamental matrix
+enum { FM_7POINT = 1, //!< 7-point algorithm
+ FM_8POINT = 2, //!< 8-point algorithm
+ FM_LMEDS = 4, //!< least-median algorithm
+ FM_RANSAC = 8 //!< RANSAC algorithm
+ };
+
+
+
+/** @brief Converts a rotation matrix to a rotation vector or vice versa.
+
+@param src Input rotation vector (3x1 or 1x3) or rotation matrix (3x3).
+@param dst Output rotation matrix (3x3) or rotation vector (3x1 or 1x3), respectively.
+@param jacobian Optional output Jacobian matrix, 3x9 or 9x3, which is a matrix of partial
+derivatives of the output array components with respect to the input array components.
+
+\f[\begin{array}{l} \theta \leftarrow norm(r) \\ r \leftarrow r/ \theta \\ R = \cos{\theta} I + (1- \cos{\theta} ) r r^T + \sin{\theta} \vecthreethree{0}{-r_z}{r_y}{r_z}{0}{-r_x}{-r_y}{r_x}{0} \end{array}\f]
+
+Inverse transformation can be also done easily, since
+
+\f[\sin ( \theta ) \vecthreethree{0}{-r_z}{r_y}{r_z}{0}{-r_x}{-r_y}{r_x}{0} = \frac{R - R^T}{2}\f]
+
+A rotation vector is a convenient and most compact representation of a rotation matrix (since any
+rotation matrix has just 3 degrees of freedom). The representation is used in the global 3D geometry
+optimization procedures like calibrateCamera, stereoCalibrate, or solvePnP .
+ */
+CV_EXPORTS_W void Rodrigues( InputArray src, OutputArray dst, OutputArray jacobian = noArray() );
+
+/** @brief Finds a perspective transformation between two planes.
+
+@param srcPoints Coordinates of the points in the original plane, a matrix of the type CV_32FC2
+or vector\<Point2f\> .
+@param dstPoints Coordinates of the points in the target plane, a matrix of the type CV_32FC2 or
+a vector\<Point2f\> .
+@param method Method used to computed a homography matrix. The following methods are possible:
+- **0** - a regular method using all the points
+- **RANSAC** - RANSAC-based robust method
+- **LMEDS** - Least-Median robust method
+- **RHO** - PROSAC-based robust method
+@param ransacReprojThreshold Maximum allowed reprojection error to treat a point pair as an inlier
+(used in the RANSAC and RHO methods only). That is, if
+\f[\| \texttt{dstPoints} _i - \texttt{convertPointsHomogeneous} ( \texttt{H} * \texttt{srcPoints} _i) \| > \texttt{ransacReprojThreshold}\f]
+then the point \f$i\f$ is considered an outlier. If srcPoints and dstPoints are measured in pixels,
+it usually makes sense to set this parameter somewhere in the range of 1 to 10.
+@param mask Optional output mask set by a robust method ( RANSAC or LMEDS ). Note that the input
+mask values are ignored.
+@param maxIters The maximum number of RANSAC iterations, 2000 is the maximum it can be.
+@param confidence Confidence level, between 0 and 1.
+
+The function finds and returns the perspective transformation \f$H\f$ between the source and the
+destination planes:
+
+\f[s_i \vecthree{x'_i}{y'_i}{1} \sim H \vecthree{x_i}{y_i}{1}\f]
+
+so that the back-projection error
+
+\f[\sum _i \left ( x'_i- \frac{h_{11} x_i + h_{12} y_i + h_{13}}{h_{31} x_i + h_{32} y_i + h_{33}} \right )^2+ \left ( y'_i- \frac{h_{21} x_i + h_{22} y_i + h_{23}}{h_{31} x_i + h_{32} y_i + h_{33}} \right )^2\f]
+
+is minimized. If the parameter method is set to the default value 0, the function uses all the point
+pairs to compute an initial homography estimate with a simple least-squares scheme.
+
+However, if not all of the point pairs ( \f$srcPoints_i\f$, \f$dstPoints_i\f$ ) fit the rigid perspective
+transformation (that is, there are some outliers), this initial estimate will be poor. In this case,
+you can use one of the three robust methods. The methods RANSAC, LMeDS and RHO try many different
+random subsets of the corresponding point pairs (of four pairs each), estimate the homography matrix
+using this subset and a simple least-square algorithm, and then compute the quality/goodness of the
+computed homography (which is the number of inliers for RANSAC or the median re-projection error for
+LMeDs). The best subset is then used to produce the initial estimate of the homography matrix and
+the mask of inliers/outliers.
+
+Regardless of the method, robust or not, the computed homography matrix is refined further (using
+inliers only in case of a robust method) with the Levenberg-Marquardt method to reduce the
+re-projection error even more.
+
+The methods RANSAC and RHO can handle practically any ratio of outliers but need a threshold to
+distinguish inliers from outliers. The method LMeDS does not need any threshold but it works
+correctly only when there are more than 50% of inliers. Finally, if there are no outliers and the
+noise is rather small, use the default method (method=0).
+
+The function is used to find initial intrinsic and extrinsic matrices. Homography matrix is
+determined up to a scale. Thus, it is normalized so that \f$h_{33}=1\f$. Note that whenever an H matrix
+cannot be estimated, an empty one will be returned.
+
+@sa
+getAffineTransform, estimateAffine2D, estimateAffinePartial2D, getPerspectiveTransform, warpPerspective,
+perspectiveTransform
+
+
+@note
+ - A example on calculating a homography for image matching can be found at
+ opencv_source_code/samples/cpp/video_homography.cpp
+
+ */
+CV_EXPORTS_W Mat findHomography( InputArray srcPoints, InputArray dstPoints,
+ int method = 0, double ransacReprojThreshold = 3,
+ OutputArray mask=noArray(), const int maxIters = 2000,
+ const double confidence = 0.995);
+
+/** @overload */
+CV_EXPORTS Mat findHomography( InputArray srcPoints, InputArray dstPoints,
+ OutputArray mask, int method = 0, double ransacReprojThreshold = 3 );
+
+/** @brief Computes an RQ decomposition of 3x3 matrices.
+
+@param src 3x3 input matrix.
+@param mtxR Output 3x3 upper-triangular matrix.
+@param mtxQ Output 3x3 orthogonal matrix.
+@param Qx Optional output 3x3 rotation matrix around x-axis.
+@param Qy Optional output 3x3 rotation matrix around y-axis.
+@param Qz Optional output 3x3 rotation matrix around z-axis.
+
+The function computes a RQ decomposition using the given rotations. This function is used in
+decomposeProjectionMatrix to decompose the left 3x3 submatrix of a projection matrix into a camera
+and a rotation matrix.
+
+It optionally returns three rotation matrices, one for each axis, and the three Euler angles in
+degrees (as the return value) that could be used in OpenGL. Note, there is always more than one
+sequence of rotations about the three principal axes that results in the same orientation of an
+object, eg. see @cite Slabaugh . Returned tree rotation matrices and corresponding three Euler angules
+are only one of the possible solutions.
+ */
+CV_EXPORTS_W Vec3d RQDecomp3x3( InputArray src, OutputArray mtxR, OutputArray mtxQ,
+ OutputArray Qx = noArray(),
+ OutputArray Qy = noArray(),
+ OutputArray Qz = noArray());
+
+/** @brief Decomposes a projection matrix into a rotation matrix and a camera matrix.
+
+@param projMatrix 3x4 input projection matrix P.
+@param cameraMatrix Output 3x3 camera matrix K.
+@param rotMatrix Output 3x3 external rotation matrix R.
+@param transVect Output 4x1 translation vector T.
+@param rotMatrixX Optional 3x3 rotation matrix around x-axis.
+@param rotMatrixY Optional 3x3 rotation matrix around y-axis.
+@param rotMatrixZ Optional 3x3 rotation matrix around z-axis.
+@param eulerAngles Optional three-element vector containing three Euler angles of rotation in
+degrees.
+
+The function computes a decomposition of a projection matrix into a calibration and a rotation
+matrix and the position of a camera.
+
+It optionally returns three rotation matrices, one for each axis, and three Euler angles that could
+be used in OpenGL. Note, there is always more than one sequence of rotations about the three
+principal axes that results in the same orientation of an object, eg. see @cite Slabaugh . Returned
+tree rotation matrices and corresponding three Euler angules are only one of the possible solutions.
+
+The function is based on RQDecomp3x3 .
+ */
+CV_EXPORTS_W void decomposeProjectionMatrix( InputArray projMatrix, OutputArray cameraMatrix,
+ OutputArray rotMatrix, OutputArray transVect,
+ OutputArray rotMatrixX = noArray(),
+ OutputArray rotMatrixY = noArray(),
+ OutputArray rotMatrixZ = noArray(),
+ OutputArray eulerAngles =noArray() );
+
+/** @brief Computes partial derivatives of the matrix product for each multiplied matrix.
+
+@param A First multiplied matrix.
+@param B Second multiplied matrix.
+@param dABdA First output derivative matrix d(A\*B)/dA of size
+\f$\texttt{A.rows*B.cols} \times {A.rows*A.cols}\f$ .
+@param dABdB Second output derivative matrix d(A\*B)/dB of size
+\f$\texttt{A.rows*B.cols} \times {B.rows*B.cols}\f$ .
+
+The function computes partial derivatives of the elements of the matrix product \f$A*B\f$ with regard to
+the elements of each of the two input matrices. The function is used to compute the Jacobian
+matrices in stereoCalibrate but can also be used in any other similar optimization function.
+ */
+CV_EXPORTS_W void matMulDeriv( InputArray A, InputArray B, OutputArray dABdA, OutputArray dABdB );
+
+/** @brief Combines two rotation-and-shift transformations.
+
+@param rvec1 First rotation vector.
+@param tvec1 First translation vector.
+@param rvec2 Second rotation vector.
+@param tvec2 Second translation vector.
+@param rvec3 Output rotation vector of the superposition.
+@param tvec3 Output translation vector of the superposition.
+@param dr3dr1
+@param dr3dt1
+@param dr3dr2
+@param dr3dt2
+@param dt3dr1
+@param dt3dt1
+@param dt3dr2
+@param dt3dt2 Optional output derivatives of rvec3 or tvec3 with regard to rvec1, rvec2, tvec1 and
+tvec2, respectively.
+
+The functions compute:
+
+\f[\begin{array}{l} \texttt{rvec3} = \mathrm{rodrigues} ^{-1} \left ( \mathrm{rodrigues} ( \texttt{rvec2} ) \cdot \mathrm{rodrigues} ( \texttt{rvec1} ) \right ) \\ \texttt{tvec3} = \mathrm{rodrigues} ( \texttt{rvec2} ) \cdot \texttt{tvec1} + \texttt{tvec2} \end{array} ,\f]
+
+where \f$\mathrm{rodrigues}\f$ denotes a rotation vector to a rotation matrix transformation, and
+\f$\mathrm{rodrigues}^{-1}\f$ denotes the inverse transformation. See Rodrigues for details.
+
+Also, the functions can compute the derivatives of the output vectors with regards to the input
+vectors (see matMulDeriv ). The functions are used inside stereoCalibrate but can also be used in
+your own code where Levenberg-Marquardt or another gradient-based solver is used to optimize a
+function that contains a matrix multiplication.
+ */
+CV_EXPORTS_W void composeRT( InputArray rvec1, InputArray tvec1,
+ InputArray rvec2, InputArray tvec2,
+ OutputArray rvec3, OutputArray tvec3,
+ OutputArray dr3dr1 = noArray(), OutputArray dr3dt1 = noArray(),
+ OutputArray dr3dr2 = noArray(), OutputArray dr3dt2 = noArray(),
+ OutputArray dt3dr1 = noArray(), OutputArray dt3dt1 = noArray(),
+ OutputArray dt3dr2 = noArray(), OutputArray dt3dt2 = noArray() );
+
+/** @brief Projects 3D points to an image plane.
+
+@param objectPoints Array of object points, 3xN/Nx3 1-channel or 1xN/Nx1 3-channel (or
+vector\<Point3f\> ), where N is the number of points in the view.
+@param rvec Rotation vector. See Rodrigues for details.
+@param tvec Translation vector.
+@param cameraMatrix Camera matrix \f$A = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{_1}\f$ .
+@param distCoeffs Input vector of distortion coefficients
+\f$(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6 [, s_1, s_2, s_3, s_4[, \tau_x, \tau_y]]]])\f$ of
+4, 5, 8, 12 or 14 elements. If the vector is empty, the zero distortion coefficients are assumed.
+@param imagePoints Output array of image points, 2xN/Nx2 1-channel or 1xN/Nx1 2-channel, or
+vector\<Point2f\> .
+@param jacobian Optional output 2Nx(10+\<numDistCoeffs\>) jacobian matrix of derivatives of image
+points with respect to components of the rotation vector, translation vector, focal lengths,
+coordinates of the principal point and the distortion coefficients. In the old interface different
+components of the jacobian are returned via different output parameters.
+@param aspectRatio Optional "fixed aspect ratio" parameter. If the parameter is not 0, the
+function assumes that the aspect ratio (*fx/fy*) is fixed and correspondingly adjusts the jacobian
+matrix.
+
+The function computes projections of 3D points to the image plane given intrinsic and extrinsic
+camera parameters. Optionally, the function computes Jacobians - matrices of partial derivatives of
+image points coordinates (as functions of all the input parameters) with respect to the particular
+parameters, intrinsic and/or extrinsic. The Jacobians are used during the global optimization in
+calibrateCamera, solvePnP, and stereoCalibrate . The function itself can also be used to compute a
+re-projection error given the current intrinsic and extrinsic parameters.
+
+@note By setting rvec=tvec=(0,0,0) or by setting cameraMatrix to a 3x3 identity matrix, or by
+passing zero distortion coefficients, you can get various useful partial cases of the function. This
+means that you can compute the distorted coordinates for a sparse set of points or apply a
+perspective transformation (and also compute the derivatives) in the ideal zero-distortion setup.
+ */
+CV_EXPORTS_W void projectPoints( InputArray objectPoints,
+ InputArray rvec, InputArray tvec,
+ InputArray cameraMatrix, InputArray distCoeffs,
+ OutputArray imagePoints,
+ OutputArray jacobian = noArray(),
+ double aspectRatio = 0 );
+
+/** @brief Finds an object pose from 3D-2D point correspondences.
+
+@param objectPoints Array of object points in the object coordinate space, Nx3 1-channel or
+1xN/Nx1 3-channel, where N is the number of points. vector\<Point3f\> can be also passed here.
+@param imagePoints Array of corresponding image points, Nx2 1-channel or 1xN/Nx1 2-channel,
+where N is the number of points. vector\<Point2f\> can be also passed here.
+@param cameraMatrix Input camera matrix \f$A = \vecthreethree{fx}{0}{cx}{0}{fy}{cy}{0}{0}{1}\f$ .
+@param distCoeffs Input vector of distortion coefficients
+\f$(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6 [, s_1, s_2, s_3, s_4[, \tau_x, \tau_y]]]])\f$ of
+4, 5, 8, 12 or 14 elements. If the vector is NULL/empty, the zero distortion coefficients are
+assumed.
+@param rvec Output rotation vector (see Rodrigues ) that, together with tvec , brings points from
+the model coordinate system to the camera coordinate system.
+@param tvec Output translation vector.
+@param useExtrinsicGuess Parameter used for SOLVEPNP_ITERATIVE. If true (1), the function uses
+the provided rvec and tvec values as initial approximations of the rotation and translation
+vectors, respectively, and further optimizes them.
+@param flags Method for solving a PnP problem:
+- **SOLVEPNP_ITERATIVE** Iterative method is based on Levenberg-Marquardt optimization. In
+this case the function finds such a pose that minimizes reprojection error, that is the sum
+of squared distances between the observed projections imagePoints and the projected (using
+projectPoints ) objectPoints .
+- **SOLVEPNP_P3P** Method is based on the paper of X.S. Gao, X.-R. Hou, J. Tang, H.-F. Chang
+"Complete Solution Classification for the Perspective-Three-Point Problem". In this case the
+function requires exactly four object and image points.
+- **SOLVEPNP_EPNP** Method has been introduced by F.Moreno-Noguer, V.Lepetit and P.Fua in the
+paper "EPnP: Efficient Perspective-n-Point Camera Pose Estimation".
+- **SOLVEPNP_DLS** Method is based on the paper of Joel A. Hesch and Stergios I. Roumeliotis.
+"A Direct Least-Squares (DLS) Method for PnP".
+- **SOLVEPNP_UPNP** Method is based on the paper of A.Penate-Sanchez, J.Andrade-Cetto,
+F.Moreno-Noguer. "Exhaustive Linearization for Robust Camera Pose and Focal Length
+Estimation". In this case the function also estimates the parameters \f$f_x\f$ and \f$f_y\f$
+assuming that both have the same value. Then the cameraMatrix is updated with the estimated
+focal length.
+
+The function estimates the object pose given a set of object points, their corresponding image
+projections, as well as the camera matrix and the distortion coefficients.
+
+@note
+ - An example of how to use solvePnP for planar augmented reality can be found at
+ opencv_source_code/samples/python/plane_ar.py
+ - If you are using Python:
+ - Numpy array slices won't work as input because solvePnP requires contiguous
+ arrays (enforced by the assertion using cv::Mat::checkVector() around line 55 of
+ modules/calib3d/src/solvepnp.cpp version 2.4.9)
+ - The P3P algorithm requires image points to be in an array of shape (N,1,2) due
+ to its calling of cv::undistortPoints (around line 75 of modules/calib3d/src/solvepnp.cpp version 2.4.9)
+ which requires 2-channel information.
+ - Thus, given some data D = np.array(...) where D.shape = (N,M), in order to use a subset of
+ it as, e.g., imagePoints, one must effectively copy it into a new array: imagePoints =
+ np.ascontiguousarray(D[:,:2]).reshape((N,1,2))
+ - The methods **SOLVEPNP_DLS** and **SOLVEPNP_UPNP** cannot be used as the current implementations are
+ unstable and sometimes give completly wrong results. If you pass one of these two flags,
+ **SOLVEPNP_EPNP** method will be used instead.
+ */
+CV_EXPORTS_W bool solvePnP( InputArray objectPoints, InputArray imagePoints,
+ InputArray cameraMatrix, InputArray distCoeffs,
+ OutputArray rvec, OutputArray tvec,
+ bool useExtrinsicGuess = false, int flags = SOLVEPNP_ITERATIVE );
+
+/** @brief Finds an object pose from 3D-2D point correspondences using the RANSAC scheme.
+
+@param objectPoints Array of object points in the object coordinate space, Nx3 1-channel or
+1xN/Nx1 3-channel, where N is the number of points. vector\<Point3f\> can be also passed here.
+@param imagePoints Array of corresponding image points, Nx2 1-channel or 1xN/Nx1 2-channel,
+where N is the number of points. vector\<Point2f\> can be also passed here.
+@param cameraMatrix Input camera matrix \f$A = \vecthreethree{fx}{0}{cx}{0}{fy}{cy}{0}{0}{1}\f$ .
+@param distCoeffs Input vector of distortion coefficients
+\f$(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6 [, s_1, s_2, s_3, s_4[, \tau_x, \tau_y]]]])\f$ of
+4, 5, 8, 12 or 14 elements. If the vector is NULL/empty, the zero distortion coefficients are
+assumed.
+@param rvec Output rotation vector (see Rodrigues ) that, together with tvec , brings points from
+the model coordinate system to the camera coordinate system.
+@param tvec Output translation vector.
+@param useExtrinsicGuess Parameter used for SOLVEPNP_ITERATIVE. If true (1), the function uses
+the provided rvec and tvec values as initial approximations of the rotation and translation
+vectors, respectively, and further optimizes them.
+@param iterationsCount Number of iterations.
+@param reprojectionError Inlier threshold value used by the RANSAC procedure. The parameter value
+is the maximum allowed distance between the observed and computed point projections to consider it
+an inlier.
+@param confidence The probability that the algorithm produces a useful result.
+@param inliers Output vector that contains indices of inliers in objectPoints and imagePoints .
+@param flags Method for solving a PnP problem (see solvePnP ).
+
+The function estimates an object pose given a set of object points, their corresponding image
+projections, as well as the camera matrix and the distortion coefficients. This function finds such
+a pose that minimizes reprojection error, that is, the sum of squared distances between the observed
+projections imagePoints and the projected (using projectPoints ) objectPoints. The use of RANSAC
+makes the function resistant to outliers.
+
+@note
+ - An example of how to use solvePNPRansac for object detection can be found at
+ opencv_source_code/samples/cpp/tutorial_code/calib3d/real_time_pose_estimation/
+ */
+CV_EXPORTS_W bool solvePnPRansac( InputArray objectPoints, InputArray imagePoints,
+ InputArray cameraMatrix, InputArray distCoeffs,
+ OutputArray rvec, OutputArray tvec,
+ bool useExtrinsicGuess = false, int iterationsCount = 100,
+ float reprojectionError = 8.0, double confidence = 0.99,
+ OutputArray inliers = noArray(), int flags = SOLVEPNP_ITERATIVE );
+
+/** @brief Finds an initial camera matrix from 3D-2D point correspondences.
+
+@param objectPoints Vector of vectors of the calibration pattern points in the calibration pattern
+coordinate space. In the old interface all the per-view vectors are concatenated. See
+calibrateCamera for details.
+@param imagePoints Vector of vectors of the projections of the calibration pattern points. In the
+old interface all the per-view vectors are concatenated.
+@param imageSize Image size in pixels used to initialize the principal point.
+@param aspectRatio If it is zero or negative, both \f$f_x\f$ and \f$f_y\f$ are estimated independently.
+Otherwise, \f$f_x = f_y * \texttt{aspectRatio}\f$ .
+
+The function estimates and returns an initial camera matrix for the camera calibration process.
+Currently, the function only supports planar calibration patterns, which are patterns where each
+object point has z-coordinate =0.
+ */
+CV_EXPORTS_W Mat initCameraMatrix2D( InputArrayOfArrays objectPoints,
+ InputArrayOfArrays imagePoints,
+ Size imageSize, double aspectRatio = 1.0 );
+
+/** @brief Finds the positions of internal corners of the chessboard.
+
+@param image Source chessboard view. It must be an 8-bit grayscale or color image.
+@param patternSize Number of inner corners per a chessboard row and column
+( patternSize = cvSize(points_per_row,points_per_colum) = cvSize(columns,rows) ).
+@param corners Output array of detected corners.
+@param flags Various operation flags that can be zero or a combination of the following values:
+- **CV_CALIB_CB_ADAPTIVE_THRESH** Use adaptive thresholding to convert the image to black
+and white, rather than a fixed threshold level (computed from the average image brightness).
+- **CV_CALIB_CB_NORMALIZE_IMAGE** Normalize the image gamma with equalizeHist before
+applying fixed or adaptive thresholding.
+- **CV_CALIB_CB_FILTER_QUADS** Use additional criteria (like contour area, perimeter,
+square-like shape) to filter out false quads extracted at the contour retrieval stage.
+- **CALIB_CB_FAST_CHECK** Run a fast check on the image that looks for chessboard corners,
+and shortcut the call if none is found. This can drastically speed up the call in the
+degenerate condition when no chessboard is observed.
+
+The function attempts to determine whether the input image is a view of the chessboard pattern and
+locate the internal chessboard corners. The function returns a non-zero value if all of the corners
+are found and they are placed in a certain order (row by row, left to right in every row).
+Otherwise, if the function fails to find all the corners or reorder them, it returns 0. For example,
+a regular chessboard has 8 x 8 squares and 7 x 7 internal corners, that is, points where the black
+squares touch each other. The detected coordinates are approximate, and to determine their positions
+more accurately, the function calls cornerSubPix. You also may use the function cornerSubPix with
+different parameters if returned coordinates are not accurate enough.
+
+Sample usage of detecting and drawing chessboard corners: :
+@code
+ Size patternsize(8,6); //interior number of corners
+ Mat gray = ....; //source image
+ vector<Point2f> corners; //this will be filled by the detected corners
+
+ //CALIB_CB_FAST_CHECK saves a lot of time on images
+ //that do not contain any chessboard corners
+ bool patternfound = findChessboardCorners(gray, patternsize, corners,
+ CALIB_CB_ADAPTIVE_THRESH + CALIB_CB_NORMALIZE_IMAGE
+ + CALIB_CB_FAST_CHECK);
+
+ if(patternfound)
+ cornerSubPix(gray, corners, Size(11, 11), Size(-1, -1),
+ TermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 30, 0.1));
+
+ drawChessboardCorners(img, patternsize, Mat(corners), patternfound);
+@endcode
+@note The function requires white space (like a square-thick border, the wider the better) around
+the board to make the detection more robust in various environments. Otherwise, if there is no
+border and the background is dark, the outer black squares cannot be segmented properly and so the
+square grouping and ordering algorithm fails.
+ */
+CV_EXPORTS_W bool findChessboardCorners( InputArray image, Size patternSize, OutputArray corners,
+ int flags = CALIB_CB_ADAPTIVE_THRESH + CALIB_CB_NORMALIZE_IMAGE );
+
+//! finds subpixel-accurate positions of the chessboard corners
+CV_EXPORTS bool find4QuadCornerSubpix( InputArray img, InputOutputArray corners, Size region_size );
+
+/** @brief Renders the detected chessboard corners.
+
+@param image Destination image. It must be an 8-bit color image.
+@param patternSize Number of inner corners per a chessboard row and column
+(patternSize = cv::Size(points_per_row,points_per_column)).
+@param corners Array of detected corners, the output of findChessboardCorners.
+@param patternWasFound Parameter indicating whether the complete board was found or not. The
+return value of findChessboardCorners should be passed here.
+
+The function draws individual chessboard corners detected either as red circles if the board was not
+found, or as colored corners connected with lines if the board was found.
+ */
+CV_EXPORTS_W void drawChessboardCorners( InputOutputArray image, Size patternSize,
+ InputArray corners, bool patternWasFound );
+
+/** @brief Finds centers in the grid of circles.
+
+@param image grid view of input circles; it must be an 8-bit grayscale or color image.
+@param patternSize number of circles per row and column
+( patternSize = Size(points_per_row, points_per_colum) ).
+@param centers output array of detected centers.
+@param flags various operation flags that can be one of the following values:
+- **CALIB_CB_SYMMETRIC_GRID** uses symmetric pattern of circles.
+- **CALIB_CB_ASYMMETRIC_GRID** uses asymmetric pattern of circles.
+- **CALIB_CB_CLUSTERING** uses a special algorithm for grid detection. It is more robust to
+perspective distortions but much more sensitive to background clutter.
+@param blobDetector feature detector that finds blobs like dark circles on light background.
+
+The function attempts to determine whether the input image contains a grid of circles. If it is, the
+function locates centers of the circles. The function returns a non-zero value if all of the centers
+have been found and they have been placed in a certain order (row by row, left to right in every
+row). Otherwise, if the function fails to find all the corners or reorder them, it returns 0.
+
+Sample usage of detecting and drawing the centers of circles: :
+@code
+ Size patternsize(7,7); //number of centers
+ Mat gray = ....; //source image
+ vector<Point2f> centers; //this will be filled by the detected centers
+
+ bool patternfound = findCirclesGrid(gray, patternsize, centers);
+
+ drawChessboardCorners(img, patternsize, Mat(centers), patternfound);
+@endcode
+@note The function requires white space (like a square-thick border, the wider the better) around
+the board to make the detection more robust in various environments.
+ */
+CV_EXPORTS_W bool findCirclesGrid( InputArray image, Size patternSize,
+ OutputArray centers, int flags = CALIB_CB_SYMMETRIC_GRID,
+ const Ptr<FeatureDetector> &blobDetector = SimpleBlobDetector::create());
+
+/** @brief Finds the camera intrinsic and extrinsic parameters from several views of a calibration pattern.
+
+@param objectPoints In the new interface it is a vector of vectors of calibration pattern points in
+the calibration pattern coordinate space (e.g. std::vector<std::vector<cv::Vec3f>>). The outer
+vector contains as many elements as the number of the pattern views. If the same calibration pattern
+is shown in each view and it is fully visible, all the vectors will be the same. Although, it is
+possible to use partially occluded patterns, or even different patterns in different views. Then,
+the vectors will be different. The points are 3D, but since they are in a pattern coordinate system,
+then, if the rig is planar, it may make sense to put the model to a XY coordinate plane so that
+Z-coordinate of each input object point is 0.
+In the old interface all the vectors of object points from different views are concatenated
+together.
+@param imagePoints In the new interface it is a vector of vectors of the projections of calibration
+pattern points (e.g. std::vector<std::vector<cv::Vec2f>>). imagePoints.size() and
+objectPoints.size() and imagePoints[i].size() must be equal to objectPoints[i].size() for each i.
+In the old interface all the vectors of object points from different views are concatenated
+together.
+@param imageSize Size of the image used only to initialize the intrinsic camera matrix.
+@param cameraMatrix Output 3x3 floating-point camera matrix
+\f$A = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}\f$ . If CV\_CALIB\_USE\_INTRINSIC\_GUESS
+and/or CV_CALIB_FIX_ASPECT_RATIO are specified, some or all of fx, fy, cx, cy must be
+initialized before calling the function.
+@param distCoeffs Output vector of distortion coefficients
+\f$(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6 [, s_1, s_2, s_3, s_4[, \tau_x, \tau_y]]]])\f$ of
+4, 5, 8, 12 or 14 elements.
+@param rvecs Output vector of rotation vectors (see Rodrigues ) estimated for each pattern view
+(e.g. std::vector<cv::Mat>>). That is, each k-th rotation vector together with the corresponding
+k-th translation vector (see the next output parameter description) brings the calibration pattern
+from the model coordinate space (in which object points are specified) to the world coordinate
+space, that is, a real position of the calibration pattern in the k-th pattern view (k=0.. *M* -1).
+@param tvecs Output vector of translation vectors estimated for each pattern view.
+@param stdDeviationsIntrinsics Output vector of standard deviations estimated for intrinsic parameters.
+ Order of deviations values:
+\f$(f_x, f_y, c_x, c_y, k_1, k_2, p_1, p_2, k_3, k_4, k_5, k_6 , s_1, s_2, s_3,
+ s_4, \tau_x, \tau_y)\f$ If one of parameters is not estimated, it's deviation is equals to zero.
+@param stdDeviationsExtrinsics Output vector of standard deviations estimated for extrinsic parameters.
+ Order of deviations values: \f$(R_1, T_1, \dotsc , R_M, T_M)\f$ where M is number of pattern views,
+ \f$R_i, T_i\f$ are concatenated 1x3 vectors.
+ @param perViewErrors Output vector of the RMS re-projection error estimated for each pattern view.
+@param flags Different flags that may be zero or a combination of the following values:
+- **CV_CALIB_USE_INTRINSIC_GUESS** cameraMatrix contains valid initial values of
+fx, fy, cx, cy that are optimized further. Otherwise, (cx, cy) is initially set to the image
+center ( imageSize is used), and focal distances are computed in a least-squares fashion.
+Note, that if intrinsic parameters are known, there is no need to use this function just to
+estimate extrinsic parameters. Use solvePnP instead.
+- **CV_CALIB_FIX_PRINCIPAL_POINT** The principal point is not changed during the global
+optimization. It stays at the center or at a different location specified when
+CV_CALIB_USE_INTRINSIC_GUESS is set too.
+- **CV_CALIB_FIX_ASPECT_RATIO** The functions considers only fy as a free parameter. The
+ratio fx/fy stays the same as in the input cameraMatrix . When
+CV_CALIB_USE_INTRINSIC_GUESS is not set, the actual input values of fx and fy are
+ignored, only their ratio is computed and used further.
+- **CV_CALIB_ZERO_TANGENT_DIST** Tangential distortion coefficients \f$(p_1, p_2)\f$ are set
+to zeros and stay zero.
+- **CV_CALIB_FIX_K1,...,CV_CALIB_FIX_K6** The corresponding radial distortion
+coefficient is not changed during the optimization. If CV_CALIB_USE_INTRINSIC_GUESS is
+set, the coefficient from the supplied distCoeffs matrix is used. Otherwise, it is set to 0.
+- **CV_CALIB_RATIONAL_MODEL** Coefficients k4, k5, and k6 are enabled. To provide the
+backward compatibility, this extra flag should be explicitly specified to make the
+calibration function use the rational model and return 8 coefficients. If the flag is not
+set, the function computes and returns only 5 distortion coefficients.
+- **CALIB_THIN_PRISM_MODEL** Coefficients s1, s2, s3 and s4 are enabled. To provide the
+backward compatibility, this extra flag should be explicitly specified to make the
+calibration function use the thin prism model and return 12 coefficients. If the flag is not
+set, the function computes and returns only 5 distortion coefficients.
+- **CALIB_FIX_S1_S2_S3_S4** The thin prism distortion coefficients are not changed during
+the optimization. If CV_CALIB_USE_INTRINSIC_GUESS is set, the coefficient from the
+supplied distCoeffs matrix is used. Otherwise, it is set to 0.
+- **CALIB_TILTED_MODEL** Coefficients tauX and tauY are enabled. To provide the
+backward compatibility, this extra flag should be explicitly specified to make the
+calibration function use the tilted sensor model and return 14 coefficients. If the flag is not
+set, the function computes and returns only 5 distortion coefficients.
+- **CALIB_FIX_TAUX_TAUY** The coefficients of the tilted sensor model are not changed during
+the optimization. If CV_CALIB_USE_INTRINSIC_GUESS is set, the coefficient from the
+supplied distCoeffs matrix is used. Otherwise, it is set to 0.
+@param criteria Termination criteria for the iterative optimization algorithm.
+
+@return the overall RMS re-projection error.
+
+The function estimates the intrinsic camera parameters and extrinsic parameters for each of the
+views. The algorithm is based on @cite Zhang2000 and @cite BouguetMCT . The coordinates of 3D object
+points and their corresponding 2D projections in each view must be specified. That may be achieved
+by using an object with a known geometry and easily detectable feature points. Such an object is
+called a calibration rig or calibration pattern, and OpenCV has built-in support for a chessboard as
+a calibration rig (see findChessboardCorners ). Currently, initialization of intrinsic parameters
+(when CV_CALIB_USE_INTRINSIC_GUESS is not set) is only implemented for planar calibration
+patterns (where Z-coordinates of the object points must be all zeros). 3D calibration rigs can also
+be used as long as initial cameraMatrix is provided.
+
+The algorithm performs the following steps:
+
+- Compute the initial intrinsic parameters (the option only available for planar calibration
+ patterns) or read them from the input parameters. The distortion coefficients are all set to
+ zeros initially unless some of CV_CALIB_FIX_K? are specified.
+
+- Estimate the initial camera pose as if the intrinsic parameters have been already known. This is
+ done using solvePnP .
+
+- Run the global Levenberg-Marquardt optimization algorithm to minimize the reprojection error,
+ that is, the total sum of squared distances between the observed feature points imagePoints and
+ the projected (using the current estimates for camera parameters and the poses) object points
+ objectPoints. See projectPoints for details.
+
+@note
+ If you use a non-square (=non-NxN) grid and findChessboardCorners for calibration, and
+ calibrateCamera returns bad values (zero distortion coefficients, an image center very far from
+ (w/2-0.5,h/2-0.5), and/or large differences between \f$f_x\f$ and \f$f_y\f$ (ratios of 10:1 or more)),
+ then you have probably used patternSize=cvSize(rows,cols) instead of using
+ patternSize=cvSize(cols,rows) in findChessboardCorners .
+
+@sa
+ findChessboardCorners, solvePnP, initCameraMatrix2D, stereoCalibrate, undistort
+ */
+CV_EXPORTS_AS(calibrateCameraExtended) double calibrateCamera( InputArrayOfArrays objectPoints,
+ InputArrayOfArrays imagePoints, Size imageSize,
+ InputOutputArray cameraMatrix, InputOutputArray distCoeffs,
+ OutputArrayOfArrays rvecs, OutputArrayOfArrays tvecs,
+ OutputArray stdDeviationsIntrinsics,
+ OutputArray stdDeviationsExtrinsics,
+ OutputArray perViewErrors,
+ int flags = 0, TermCriteria criteria = TermCriteria(
+ TermCriteria::COUNT + TermCriteria::EPS, 30, DBL_EPSILON) );
+
+/** @overload double calibrateCamera( InputArrayOfArrays objectPoints,
+ InputArrayOfArrays imagePoints, Size imageSize,
+ InputOutputArray cameraMatrix, InputOutputArray distCoeffs,
+ OutputArrayOfArrays rvecs, OutputArrayOfArrays tvecs,
+ OutputArray stdDeviations, OutputArray perViewErrors,
+ int flags = 0, TermCriteria criteria = TermCriteria(
+ TermCriteria::COUNT + TermCriteria::EPS, 30, DBL_EPSILON) )
+ */
+CV_EXPORTS_W double calibrateCamera( InputArrayOfArrays objectPoints,
+ InputArrayOfArrays imagePoints, Size imageSize,
+ InputOutputArray cameraMatrix, InputOutputArray distCoeffs,
+ OutputArrayOfArrays rvecs, OutputArrayOfArrays tvecs,
+ int flags = 0, TermCriteria criteria = TermCriteria(
+ TermCriteria::COUNT + TermCriteria::EPS, 30, DBL_EPSILON) );
+
+/** @brief Computes useful camera characteristics from the camera matrix.
+
+@param cameraMatrix Input camera matrix that can be estimated by calibrateCamera or
+stereoCalibrate .
+@param imageSize Input image size in pixels.
+@param apertureWidth Physical width in mm of the sensor.
+@param apertureHeight Physical height in mm of the sensor.
+@param fovx Output field of view in degrees along the horizontal sensor axis.
+@param fovy Output field of view in degrees along the vertical sensor axis.
+@param focalLength Focal length of the lens in mm.
+@param principalPoint Principal point in mm.
+@param aspectRatio \f$f_y/f_x\f$
+
+The function computes various useful camera characteristics from the previously estimated camera
+matrix.
+
+@note
+ Do keep in mind that the unity measure 'mm' stands for whatever unit of measure one chooses for
+ the chessboard pitch (it can thus be any value).
+ */
+CV_EXPORTS_W void calibrationMatrixValues( InputArray cameraMatrix, Size imageSize,
+ double apertureWidth, double apertureHeight,
+ CV_OUT double& fovx, CV_OUT double& fovy,
+ CV_OUT double& focalLength, CV_OUT Point2d& principalPoint,
+ CV_OUT double& aspectRatio );
+
+/** @brief Calibrates the stereo camera.
+
+@param objectPoints Vector of vectors of the calibration pattern points.
+@param imagePoints1 Vector of vectors of the projections of the calibration pattern points,
+observed by the first camera.
+@param imagePoints2 Vector of vectors of the projections of the calibration pattern points,
+observed by the second camera.
+@param cameraMatrix1 Input/output first camera matrix:
+\f$\vecthreethree{f_x^{(j)}}{0}{c_x^{(j)}}{0}{f_y^{(j)}}{c_y^{(j)}}{0}{0}{1}\f$ , \f$j = 0,\, 1\f$ . If
+any of CV_CALIB_USE_INTRINSIC_GUESS , CV_CALIB_FIX_ASPECT_RATIO ,
+CV_CALIB_FIX_INTRINSIC , or CV_CALIB_FIX_FOCAL_LENGTH are specified, some or all of the
+matrix components must be initialized. See the flags description for details.
+@param distCoeffs1 Input/output vector of distortion coefficients
+\f$(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6 [, s_1, s_2, s_3, s_4[, \tau_x, \tau_y]]]])\f$ of
+4, 5, 8, 12 or 14 elements. The output vector length depends on the flags.
+@param cameraMatrix2 Input/output second camera matrix. The parameter is similar to cameraMatrix1
+@param distCoeffs2 Input/output lens distortion coefficients for the second camera. The parameter
+is similar to distCoeffs1 .
+@param imageSize Size of the image used only to initialize intrinsic camera matrix.
+@param R Output rotation matrix between the 1st and the 2nd camera coordinate systems.
+@param T Output translation vector between the coordinate systems of the cameras.
+@param E Output essential matrix.
+@param F Output fundamental matrix.
+@param flags Different flags that may be zero or a combination of the following values:
+- **CV_CALIB_FIX_INTRINSIC** Fix cameraMatrix? and distCoeffs? so that only R, T, E , and F
+matrices are estimated.
+- **CV_CALIB_USE_INTRINSIC_GUESS** Optimize some or all of the intrinsic parameters
+according to the specified flags. Initial values are provided by the user.
+- **CV_CALIB_FIX_PRINCIPAL_POINT** Fix the principal points during the optimization.
+- **CV_CALIB_FIX_FOCAL_LENGTH** Fix \f$f^{(j)}_x\f$ and \f$f^{(j)}_y\f$ .
+- **CV_CALIB_FIX_ASPECT_RATIO** Optimize \f$f^{(j)}_y\f$ . Fix the ratio \f$f^{(j)}_x/f^{(j)}_y\f$
+.
+- **CV_CALIB_SAME_FOCAL_LENGTH** Enforce \f$f^{(0)}_x=f^{(1)}_x\f$ and \f$f^{(0)}_y=f^{(1)}_y\f$ .
+- **CV_CALIB_ZERO_TANGENT_DIST** Set tangential distortion coefficients for each camera to
+zeros and fix there.
+- **CV_CALIB_FIX_K1,...,CV_CALIB_FIX_K6** Do not change the corresponding radial
+distortion coefficient during the optimization. If CV_CALIB_USE_INTRINSIC_GUESS is set,
+the coefficient from the supplied distCoeffs matrix is used. Otherwise, it is set to 0.
+- **CV_CALIB_RATIONAL_MODEL** Enable coefficients k4, k5, and k6. To provide the backward
+compatibility, this extra flag should be explicitly specified to make the calibration
+function use the rational model and return 8 coefficients. If the flag is not set, the
+function computes and returns only 5 distortion coefficients.
+- **CALIB_THIN_PRISM_MODEL** Coefficients s1, s2, s3 and s4 are enabled. To provide the
+backward compatibility, this extra flag should be explicitly specified to make the
+calibration function use the thin prism model and return 12 coefficients. If the flag is not
+set, the function computes and returns only 5 distortion coefficients.
+- **CALIB_FIX_S1_S2_S3_S4** The thin prism distortion coefficients are not changed during
+the optimization. If CV_CALIB_USE_INTRINSIC_GUESS is set, the coefficient from the
+supplied distCoeffs matrix is used. Otherwise, it is set to 0.
+- **CALIB_TILTED_MODEL** Coefficients tauX and tauY are enabled. To provide the
+backward compatibility, this extra flag should be explicitly specified to make the
+calibration function use the tilted sensor model and return 14 coefficients. If the flag is not
+set, the function computes and returns only 5 distortion coefficients.
+- **CALIB_FIX_TAUX_TAUY** The coefficients of the tilted sensor model are not changed during
+the optimization. If CV_CALIB_USE_INTRINSIC_GUESS is set, the coefficient from the
+supplied distCoeffs matrix is used. Otherwise, it is set to 0.
+@param criteria Termination criteria for the iterative optimization algorithm.
+
+The function estimates transformation between two cameras making a stereo pair. If you have a stereo
+camera where the relative position and orientation of two cameras is fixed, and if you computed
+poses of an object relative to the first camera and to the second camera, (R1, T1) and (R2, T2),
+respectively (this can be done with solvePnP ), then those poses definitely relate to each other.
+This means that, given ( \f$R_1\f$,\f$T_1\f$ ), it should be possible to compute ( \f$R_2\f$,\f$T_2\f$ ). You only
+need to know the position and orientation of the second camera relative to the first camera. This is
+what the described function does. It computes ( \f$R\f$,\f$T\f$ ) so that:
+
+\f[R_2=R*R_1
+T_2=R*T_1 + T,\f]
+
+Optionally, it computes the essential matrix E:
+
+\f[E= \vecthreethree{0}{-T_2}{T_1}{T_2}{0}{-T_0}{-T_1}{T_0}{0} *R\f]
+
+where \f$T_i\f$ are components of the translation vector \f$T\f$ : \f$T=[T_0, T_1, T_2]^T\f$ . And the function
+can also compute the fundamental matrix F:
+
+\f[F = cameraMatrix2^{-T} E cameraMatrix1^{-1}\f]
+
+Besides the stereo-related information, the function can also perform a full calibration of each of
+two cameras. However, due to the high dimensionality of the parameter space and noise in the input
+data, the function can diverge from the correct solution. If the intrinsic parameters can be
+estimated with high accuracy for each of the cameras individually (for example, using
+calibrateCamera ), you are recommended to do so and then pass CV_CALIB_FIX_INTRINSIC flag to the
+function along with the computed intrinsic parameters. Otherwise, if all the parameters are
+estimated at once, it makes sense to restrict some parameters, for example, pass
+CV_CALIB_SAME_FOCAL_LENGTH and CV_CALIB_ZERO_TANGENT_DIST flags, which is usually a
+reasonable assumption.
+
+Similarly to calibrateCamera , the function minimizes the total re-projection error for all the
+points in all the available views from both cameras. The function returns the final value of the
+re-projection error.
+ */
+CV_EXPORTS_W double stereoCalibrate( InputArrayOfArrays objectPoints,
+ InputArrayOfArrays imagePoints1, InputArrayOfArrays imagePoints2,
+ InputOutputArray cameraMatrix1, InputOutputArray distCoeffs1,
+ InputOutputArray cameraMatrix2, InputOutputArray distCoeffs2,
+ Size imageSize, OutputArray R,OutputArray T, OutputArray E, OutputArray F,
+ int flags = CALIB_FIX_INTRINSIC,
+ TermCriteria criteria = TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 30, 1e-6) );
+
+
+/** @brief Computes rectification transforms for each head of a calibrated stereo camera.
+
+@param cameraMatrix1 First camera matrix.
+@param distCoeffs1 First camera distortion parameters.
+@param cameraMatrix2 Second camera matrix.
+@param distCoeffs2 Second camera distortion parameters.
+@param imageSize Size of the image used for stereo calibration.
+@param R Rotation matrix between the coordinate systems of the first and the second cameras.
+@param T Translation vector between coordinate systems of the cameras.
+@param R1 Output 3x3 rectification transform (rotation matrix) for the first camera.
+@param R2 Output 3x3 rectification transform (rotation matrix) for the second camera.
+@param P1 Output 3x4 projection matrix in the new (rectified) coordinate systems for the first
+camera.
+@param P2 Output 3x4 projection matrix in the new (rectified) coordinate systems for the second
+camera.
+@param Q Output \f$4 \times 4\f$ disparity-to-depth mapping matrix (see reprojectImageTo3D ).
+@param flags Operation flags that may be zero or CV_CALIB_ZERO_DISPARITY . If the flag is set,
+the function makes the principal points of each camera have the same pixel coordinates in the
+rectified views. And if the flag is not set, the function may still shift the images in the
+horizontal or vertical direction (depending on the orientation of epipolar lines) to maximize the
+useful image area.
+@param alpha Free scaling parameter. If it is -1 or absent, the function performs the default
+scaling. Otherwise, the parameter should be between 0 and 1. alpha=0 means that the rectified
+images are zoomed and shifted so that only valid pixels are visible (no black areas after
+rectification). alpha=1 means that the rectified image is decimated and shifted so that all the
+pixels from the original images from the cameras are retained in the rectified images (no source
+image pixels are lost). Obviously, any intermediate value yields an intermediate result between
+those two extreme cases.
+@param newImageSize New image resolution after rectification. The same size should be passed to
+initUndistortRectifyMap (see the stereo_calib.cpp sample in OpenCV samples directory). When (0,0)
+is passed (default), it is set to the original imageSize . Setting it to larger value can help you
+preserve details in the original image, especially when there is a big radial distortion.
+@param validPixROI1 Optional output rectangles inside the rectified images where all the pixels
+are valid. If alpha=0 , the ROIs cover the whole images. Otherwise, they are likely to be smaller
+(see the picture below).
+@param validPixROI2 Optional output rectangles inside the rectified images where all the pixels
+are valid. If alpha=0 , the ROIs cover the whole images. Otherwise, they are likely to be smaller
+(see the picture below).
+
+The function computes the rotation matrices for each camera that (virtually) make both camera image
+planes the same plane. Consequently, this makes all the epipolar lines parallel and thus simplifies
+the dense stereo correspondence problem. The function takes the matrices computed by stereoCalibrate
+as input. As output, it provides two rotation matrices and also two projection matrices in the new
+coordinates. The function distinguishes the following two cases:
+
+- **Horizontal stereo**: the first and the second camera views are shifted relative to each other
+ mainly along the x axis (with possible small vertical shift). In the rectified images, the
+ corresponding epipolar lines in the left and right cameras are horizontal and have the same
+ y-coordinate. P1 and P2 look like:
+
+ \f[\texttt{P1} = \begin{bmatrix} f & 0 & cx_1 & 0 \\ 0 & f & cy & 0 \\ 0 & 0 & 1 & 0 \end{bmatrix}\f]
+
+ \f[\texttt{P2} = \begin{bmatrix} f & 0 & cx_2 & T_x*f \\ 0 & f & cy & 0 \\ 0 & 0 & 1 & 0 \end{bmatrix} ,\f]
+
+ where \f$T_x\f$ is a horizontal shift between the cameras and \f$cx_1=cx_2\f$ if
+ CV_CALIB_ZERO_DISPARITY is set.
+
+- **Vertical stereo**: the first and the second camera views are shifted relative to each other
+ mainly in vertical direction (and probably a bit in the horizontal direction too). The epipolar
+ lines in the rectified images are vertical and have the same x-coordinate. P1 and P2 look like:
+
+ \f[\texttt{P1} = \begin{bmatrix} f & 0 & cx & 0 \\ 0 & f & cy_1 & 0 \\ 0 & 0 & 1 & 0 \end{bmatrix}\f]
+
+ \f[\texttt{P2} = \begin{bmatrix} f & 0 & cx & 0 \\ 0 & f & cy_2 & T_y*f \\ 0 & 0 & 1 & 0 \end{bmatrix} ,\f]
+
+ where \f$T_y\f$ is a vertical shift between the cameras and \f$cy_1=cy_2\f$ if CALIB_ZERO_DISPARITY is
+ set.
+
+As you can see, the first three columns of P1 and P2 will effectively be the new "rectified" camera
+matrices. The matrices, together with R1 and R2 , can then be passed to initUndistortRectifyMap to
+initialize the rectification map for each camera.
+
+See below the screenshot from the stereo_calib.cpp sample. Some red horizontal lines pass through
+the corresponding image regions. This means that the images are well rectified, which is what most
+stereo correspondence algorithms rely on. The green rectangles are roi1 and roi2 . You see that
+their interiors are all valid pixels.
+
+
+ */
+CV_EXPORTS_W void stereoRectify( InputArray cameraMatrix1, InputArray distCoeffs1,
+ InputArray cameraMatrix2, InputArray distCoeffs2,
+ Size imageSize, InputArray R, InputArray T,
+ OutputArray R1, OutputArray R2,
+ OutputArray P1, OutputArray P2,
+ OutputArray Q, int flags = CALIB_ZERO_DISPARITY,
+ double alpha = -1, Size newImageSize = Size(),
+ CV_OUT Rect* validPixROI1 = 0, CV_OUT Rect* validPixROI2 = 0 );
+
+/** @brief Computes a rectification transform for an uncalibrated stereo camera.
+
+@param points1 Array of feature points in the first image.
+@param points2 The corresponding points in the second image. The same formats as in
+findFundamentalMat are supported.
+@param F Input fundamental matrix. It can be computed from the same set of point pairs using
+findFundamentalMat .
+@param imgSize Size of the image.
+@param H1 Output rectification homography matrix for the first image.
+@param H2 Output rectification homography matrix for the second image.
+@param threshold Optional threshold used to filter out the outliers. If the parameter is greater
+than zero, all the point pairs that do not comply with the epipolar geometry (that is, the points
+for which \f$|\texttt{points2[i]}^T*\texttt{F}*\texttt{points1[i]}|>\texttt{threshold}\f$ ) are
+rejected prior to computing the homographies. Otherwise,all the points are considered inliers.
+
+The function computes the rectification transformations without knowing intrinsic parameters of the
+cameras and their relative position in the space, which explains the suffix "uncalibrated". Another
+related difference from stereoRectify is that the function outputs not the rectification
+transformations in the object (3D) space, but the planar perspective transformations encoded by the
+homography matrices H1 and H2 . The function implements the algorithm @cite Hartley99 .
+
+@note
+ While the algorithm does not need to know the intrinsic parameters of the cameras, it heavily
+ depends on the epipolar geometry. Therefore, if the camera lenses have a significant distortion,
+ it would be better to correct it before computing the fundamental matrix and calling this
+ function. For example, distortion coefficients can be estimated for each head of stereo camera
+ separately by using calibrateCamera . Then, the images can be corrected using undistort , or
+ just the point coordinates can be corrected with undistortPoints .
+ */
+CV_EXPORTS_W bool stereoRectifyUncalibrated( InputArray points1, InputArray points2,
+ InputArray F, Size imgSize,
+ OutputArray H1, OutputArray H2,
+ double threshold = 5 );
+
+//! computes the rectification transformations for 3-head camera, where all the heads are on the same line.
+CV_EXPORTS_W float rectify3Collinear( InputArray cameraMatrix1, InputArray distCoeffs1,
+ InputArray cameraMatrix2, InputArray distCoeffs2,
+ InputArray cameraMatrix3, InputArray distCoeffs3,
+ InputArrayOfArrays imgpt1, InputArrayOfArrays imgpt3,
+ Size imageSize, InputArray R12, InputArray T12,
+ InputArray R13, InputArray T13,
+ OutputArray R1, OutputArray R2, OutputArray R3,
+ OutputArray P1, OutputArray P2, OutputArray P3,
+ OutputArray Q, double alpha, Size newImgSize,
+ CV_OUT Rect* roi1, CV_OUT Rect* roi2, int flags );
+
+/** @brief Returns the new camera matrix based on the free scaling parameter.
+
+@param cameraMatrix Input camera matrix.
+@param distCoeffs Input vector of distortion coefficients
+\f$(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6 [, s_1, s_2, s_3, s_4[, \tau_x, \tau_y]]]])\f$ of
+4, 5, 8, 12 or 14 elements. If the vector is NULL/empty, the zero distortion coefficients are
+assumed.
+@param imageSize Original image size.
+@param alpha Free scaling parameter between 0 (when all the pixels in the undistorted image are
+valid) and 1 (when all the source image pixels are retained in the undistorted image). See
+stereoRectify for details.
+@param newImgSize Image size after rectification. By default,it is set to imageSize .
+@param validPixROI Optional output rectangle that outlines all-good-pixels region in the
+undistorted image. See roi1, roi2 description in stereoRectify .
+@param centerPrincipalPoint Optional flag that indicates whether in the new camera matrix the
+principal point should be at the image center or not. By default, the principal point is chosen to
+best fit a subset of the source image (determined by alpha) to the corrected image.
+@return new_camera_matrix Output new camera matrix.
+
+The function computes and returns the optimal new camera matrix based on the free scaling parameter.
+By varying this parameter, you may retrieve only sensible pixels alpha=0 , keep all the original
+image pixels if there is valuable information in the corners alpha=1 , or get something in between.
+When alpha\>0 , the undistortion result is likely to have some black pixels corresponding to
+"virtual" pixels outside of the captured distorted image. The original camera matrix, distortion
+coefficients, the computed new camera matrix, and newImageSize should be passed to
+initUndistortRectifyMap to produce the maps for remap .
+ */
+CV_EXPORTS_W Mat getOptimalNewCameraMatrix( InputArray cameraMatrix, InputArray distCoeffs,
+ Size imageSize, double alpha, Size newImgSize = Size(),
+ CV_OUT Rect* validPixROI = 0,
+ bool centerPrincipalPoint = false);
+
+/** @brief Converts points from Euclidean to homogeneous space.
+
+@param src Input vector of N-dimensional points.
+@param dst Output vector of N+1-dimensional points.
+
+The function converts points from Euclidean to homogeneous space by appending 1's to the tuple of
+point coordinates. That is, each point (x1, x2, ..., xn) is converted to (x1, x2, ..., xn, 1).
+ */
+CV_EXPORTS_W void convertPointsToHomogeneous( InputArray src, OutputArray dst );
+
+/** @brief Converts points from homogeneous to Euclidean space.
+
+@param src Input vector of N-dimensional points.
+@param dst Output vector of N-1-dimensional points.
+
+The function converts points homogeneous to Euclidean space using perspective projection. That is,
+each point (x1, x2, ... x(n-1), xn) is converted to (x1/xn, x2/xn, ..., x(n-1)/xn). When xn=0, the
+output point coordinates will be (0,0,0,...).
+ */
+CV_EXPORTS_W void convertPointsFromHomogeneous( InputArray src, OutputArray dst );
+
+/** @brief Converts points to/from homogeneous coordinates.
+
+@param src Input array or vector of 2D, 3D, or 4D points.
+@param dst Output vector of 2D, 3D, or 4D points.
+
+The function converts 2D or 3D points from/to homogeneous coordinates by calling either
+convertPointsToHomogeneous or convertPointsFromHomogeneous.
+
+@note The function is obsolete. Use one of the previous two functions instead.
+ */
+CV_EXPORTS void convertPointsHomogeneous( InputArray src, OutputArray dst );
+
+/** @brief Calculates a fundamental matrix from the corresponding points in two images.
+
+@param points1 Array of N points from the first image. The point coordinates should be
+floating-point (single or double precision).
+@param points2 Array of the second image points of the same size and format as points1 .
+@param method Method for computing a fundamental matrix.
+- **CV_FM_7POINT** for a 7-point algorithm. \f$N = 7\f$
+- **CV_FM_8POINT** for an 8-point algorithm. \f$N \ge 8\f$
+- **CV_FM_RANSAC** for the RANSAC algorithm. \f$N \ge 8\f$
+- **CV_FM_LMEDS** for the LMedS algorithm. \f$N \ge 8\f$
+@param param1 Parameter used for RANSAC. It is the maximum distance from a point to an epipolar
+line in pixels, beyond which the point is considered an outlier and is not used for computing the
+final fundamental matrix. It can be set to something like 1-3, depending on the accuracy of the
+point localization, image resolution, and the image noise.
+@param param2 Parameter used for the RANSAC or LMedS methods only. It specifies a desirable level
+of confidence (probability) that the estimated matrix is correct.
+@param mask
+
+The epipolar geometry is described by the following equation:
+
+\f[[p_2; 1]^T F [p_1; 1] = 0\f]
+
+where \f$F\f$ is a fundamental matrix, \f$p_1\f$ and \f$p_2\f$ are corresponding points in the first and the
+second images, respectively.
+
+The function calculates the fundamental matrix using one of four methods listed above and returns
+the found fundamental matrix. Normally just one matrix is found. But in case of the 7-point
+algorithm, the function may return up to 3 solutions ( \f$9 \times 3\f$ matrix that stores all 3
+matrices sequentially).
+
+The calculated fundamental matrix may be passed further to computeCorrespondEpilines that finds the
+epipolar lines corresponding to the specified points. It can also be passed to
+stereoRectifyUncalibrated to compute the rectification transformation. :
+@code
+ // Example. Estimation of fundamental matrix using the RANSAC algorithm
+ int point_count = 100;
+ vector<Point2f> points1(point_count);
+ vector<Point2f> points2(point_count);
+
+ // initialize the points here ...
+ for( int i = 0; i < point_count; i++ )
+ {
+ points1[i] = ...;
+ points2[i] = ...;
+ }
+
+ Mat fundamental_matrix =
+ findFundamentalMat(points1, points2, FM_RANSAC, 3, 0.99);
+@endcode
+ */
+CV_EXPORTS_W Mat findFundamentalMat( InputArray points1, InputArray points2,
+ int method = FM_RANSAC,
+ double param1 = 3., double param2 = 0.99,
+ OutputArray mask = noArray() );
+
+/** @overload */
+CV_EXPORTS Mat findFundamentalMat( InputArray points1, InputArray points2,
+ OutputArray mask, int method = FM_RANSAC,
+ double param1 = 3., double param2 = 0.99 );
+
+/** @brief Calculates an essential matrix from the corresponding points in two images.
+
+@param points1 Array of N (N \>= 5) 2D points from the first image. The point coordinates should
+be floating-point (single or double precision).
+@param points2 Array of the second image points of the same size and format as points1 .
+@param cameraMatrix Camera matrix \f$K = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}\f$ .
+Note that this function assumes that points1 and points2 are feature points from cameras with the
+same camera matrix.
+@param method Method for computing a fundamental matrix.
+- **RANSAC** for the RANSAC algorithm.
+- **MEDS** for the LMedS algorithm.
+@param prob Parameter used for the RANSAC or LMedS methods only. It specifies a desirable level of
+confidence (probability) that the estimated matrix is correct.
+@param threshold Parameter used for RANSAC. It is the maximum distance from a point to an epipolar
+line in pixels, beyond which the point is considered an outlier and is not used for computing the
+final fundamental matrix. It can be set to something like 1-3, depending on the accuracy of the
+point localization, image resolution, and the image noise.
+@param mask Output array of N elements, every element of which is set to 0 for outliers and to 1
+for the other points. The array is computed only in the RANSAC and LMedS methods.
+
+This function estimates essential matrix based on the five-point algorithm solver in @cite Nister03 .
+@cite SteweniusCFS is also a related. The epipolar geometry is described by the following equation:
+
+\f[[p_2; 1]^T K^{-T} E K^{-1} [p_1; 1] = 0\f]
+
+where \f$E\f$ is an essential matrix, \f$p_1\f$ and \f$p_2\f$ are corresponding points in the first and the
+second images, respectively. The result of this function may be passed further to
+decomposeEssentialMat or recoverPose to recover the relative pose between cameras.
+ */
+CV_EXPORTS_W Mat findEssentialMat( InputArray points1, InputArray points2,
+ InputArray cameraMatrix, int method = RANSAC,
+ double prob = 0.999, double threshold = 1.0,
+ OutputArray mask = noArray() );
+
+/** @overload
+@param points1 Array of N (N \>= 5) 2D points from the first image. The point coordinates should
+be floating-point (single or double precision).
+@param points2 Array of the second image points of the same size and format as points1 .
+@param focal focal length of the camera. Note that this function assumes that points1 and points2
+are feature points from cameras with same focal length and principal point.
+@param pp principal point of the camera.
+@param method Method for computing a fundamental matrix.
+- **RANSAC** for the RANSAC algorithm.
+- **LMEDS** for the LMedS algorithm.
+@param threshold Parameter used for RANSAC. It is the maximum distance from a point to an epipolar
+line in pixels, beyond which the point is considered an outlier and is not used for computing the
+final fundamental matrix. It can be set to something like 1-3, depending on the accuracy of the
+point localization, image resolution, and the image noise.
+@param prob Parameter used for the RANSAC or LMedS methods only. It specifies a desirable level of
+confidence (probability) that the estimated matrix is correct.
+@param mask Output array of N elements, every element of which is set to 0 for outliers and to 1
+for the other points. The array is computed only in the RANSAC and LMedS methods.
+
+This function differs from the one above that it computes camera matrix from focal length and
+principal point:
+
+\f[K =
+\begin{bmatrix}
+f & 0 & x_{pp} \\
+0 & f & y_{pp} \\
+0 & 0 & 1
+\end{bmatrix}\f]
+ */
+CV_EXPORTS_W Mat findEssentialMat( InputArray points1, InputArray points2,
+ double focal = 1.0, Point2d pp = Point2d(0, 0),
+ int method = RANSAC, double prob = 0.999,
+ double threshold = 1.0, OutputArray mask = noArray() );
+
+/** @brief Decompose an essential matrix to possible rotations and translation.
+
+@param E The input essential matrix.
+@param R1 One possible rotation matrix.
+@param R2 Another possible rotation matrix.
+@param t One possible translation.
+
+This function decompose an essential matrix E using svd decomposition @cite HartleyZ00 . Generally 4
+possible poses exists for a given E. They are \f$[R_1, t]\f$, \f$[R_1, -t]\f$, \f$[R_2, t]\f$, \f$[R_2, -t]\f$. By
+decomposing E, you can only get the direction of the translation, so the function returns unit t.
+ */
+CV_EXPORTS_W void decomposeEssentialMat( InputArray E, OutputArray R1, OutputArray R2, OutputArray t );
+
+/** @brief Recover relative camera rotation and translation from an estimated essential matrix and the
+corresponding points in two images, using cheirality check. Returns the number of inliers which pass
+the check.
+
+@param E The input essential matrix.
+@param points1 Array of N 2D points from the first image. The point coordinates should be
+floating-point (single or double precision).
+@param points2 Array of the second image points of the same size and format as points1 .
+@param cameraMatrix Camera matrix \f$K = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}\f$ .
+Note that this function assumes that points1 and points2 are feature points from cameras with the
+same camera matrix.
+@param R Recovered relative rotation.
+@param t Recoverd relative translation.
+@param mask Input/output mask for inliers in points1 and points2.
+: If it is not empty, then it marks inliers in points1 and points2 for then given essential
+matrix E. Only these inliers will be used to recover pose. In the output mask only inliers
+which pass the cheirality check.
+This function decomposes an essential matrix using decomposeEssentialMat and then verifies possible
+pose hypotheses by doing cheirality check. The cheirality check basically means that the
+triangulated 3D points should have positive depth. Some details can be found in @cite Nister03 .
+
+This function can be used to process output E and mask from findEssentialMat. In this scenario,
+points1 and points2 are the same input for findEssentialMat. :
+@code
+ // Example. Estimation of fundamental matrix using the RANSAC algorithm
+ int point_count = 100;
+ vector<Point2f> points1(point_count);
+ vector<Point2f> points2(point_count);
+
+ // initialize the points here ...
+ for( int i = 0; i < point_count; i++ )
+ {
+ points1[i] = ...;
+ points2[i] = ...;
+ }
+
+ // cametra matrix with both focal lengths = 1, and principal point = (0, 0)
+ Mat cameraMatrix = Mat::eye(3, 3, CV_64F);
+
+ Mat E, R, t, mask;
+
+ E = findEssentialMat(points1, points2, cameraMatrix, RANSAC, 0.999, 1.0, mask);
+ recoverPose(E, points1, points2, cameraMatrix, R, t, mask);
+@endcode
+ */
+CV_EXPORTS_W int recoverPose( InputArray E, InputArray points1, InputArray points2,
+ InputArray cameraMatrix, OutputArray R, OutputArray t,
+ InputOutputArray mask = noArray() );
+
+/** @overload
+@param E The input essential matrix.
+@param points1 Array of N 2D points from the first image. The point coordinates should be
+floating-point (single or double precision).
+@param points2 Array of the second image points of the same size and format as points1 .
+@param R Recovered relative rotation.
+@param t Recoverd relative translation.
+@param focal Focal length of the camera. Note that this function assumes that points1 and points2
+are feature points from cameras with same focal length and principal point.
+@param pp principal point of the camera.
+@param mask Input/output mask for inliers in points1 and points2.
+: If it is not empty, then it marks inliers in points1 and points2 for then given essential
+matrix E. Only these inliers will be used to recover pose. In the output mask only inliers
+which pass the cheirality check.
+
+This function differs from the one above that it computes camera matrix from focal length and
+principal point:
+
+\f[K =
+\begin{bmatrix}
+f & 0 & x_{pp} \\
+0 & f & y_{pp} \\
+0 & 0 & 1
+\end{bmatrix}\f]
+ */
+CV_EXPORTS_W int recoverPose( InputArray E, InputArray points1, InputArray points2,
+ OutputArray R, OutputArray t,
+ double focal = 1.0, Point2d pp = Point2d(0, 0),
+ InputOutputArray mask = noArray() );
+
+/** @brief For points in an image of a stereo pair, computes the corresponding epilines in the other image.
+
+@param points Input points. \f$N \times 1\f$ or \f$1 \times N\f$ matrix of type CV_32FC2 or
+vector\<Point2f\> .
+@param whichImage Index of the image (1 or 2) that contains the points .
+@param F Fundamental matrix that can be estimated using findFundamentalMat or stereoRectify .
+@param lines Output vector of the epipolar lines corresponding to the points in the other image.
+Each line \f$ax + by + c=0\f$ is encoded by 3 numbers \f$(a, b, c)\f$ .
+
+For every point in one of the two images of a stereo pair, the function finds the equation of the
+corresponding epipolar line in the other image.
+
+From the fundamental matrix definition (see findFundamentalMat ), line \f$l^{(2)}_i\f$ in the second
+image for the point \f$p^{(1)}_i\f$ in the first image (when whichImage=1 ) is computed as:
+
+\f[l^{(2)}_i = F p^{(1)}_i\f]
+
+And vice versa, when whichImage=2, \f$l^{(1)}_i\f$ is computed from \f$p^{(2)}_i\f$ as:
+
+\f[l^{(1)}_i = F^T p^{(2)}_i\f]
+
+Line coefficients are defined up to a scale. They are normalized so that \f$a_i^2+b_i^2=1\f$ .
+ */
+CV_EXPORTS_W void computeCorrespondEpilines( InputArray points, int whichImage,
+ InputArray F, OutputArray lines );
+
+/** @brief Reconstructs points by triangulation.
+
+@param projMatr1 3x4 projection matrix of the first camera.
+@param projMatr2 3x4 projection matrix of the second camera.
+@param projPoints1 2xN array of feature points in the first image. In case of c++ version it can
+be also a vector of feature points or two-channel matrix of size 1xN or Nx1.
+@param projPoints2 2xN array of corresponding points in the second image. In case of c++ version
+it can be also a vector of feature points or two-channel matrix of size 1xN or Nx1.
+@param points4D 4xN array of reconstructed points in homogeneous coordinates.
+
+The function reconstructs 3-dimensional points (in homogeneous coordinates) by using their
+observations with a stereo camera. Projections matrices can be obtained from stereoRectify.
+
+@note
+ Keep in mind that all input data should be of float type in order for this function to work.
+
+@sa
+ reprojectImageTo3D
+ */
+CV_EXPORTS_W void triangulatePoints( InputArray projMatr1, InputArray projMatr2,
+ InputArray projPoints1, InputArray projPoints2,
+ OutputArray points4D );
+
+/** @brief Refines coordinates of corresponding points.
+
+@param F 3x3 fundamental matrix.
+@param points1 1xN array containing the first set of points.
+@param points2 1xN array containing the second set of points.
+@param newPoints1 The optimized points1.
+@param newPoints2 The optimized points2.
+
+The function implements the Optimal Triangulation Method (see Multiple View Geometry for details).
+For each given point correspondence points1[i] \<-\> points2[i], and a fundamental matrix F, it
+computes the corrected correspondences newPoints1[i] \<-\> newPoints2[i] that minimize the geometric
+error \f$d(points1[i], newPoints1[i])^2 + d(points2[i],newPoints2[i])^2\f$ (where \f$d(a,b)\f$ is the
+geometric distance between points \f$a\f$ and \f$b\f$ ) subject to the epipolar constraint
+\f$newPoints2^T * F * newPoints1 = 0\f$ .
+ */
+CV_EXPORTS_W void correctMatches( InputArray F, InputArray points1, InputArray points2,
+ OutputArray newPoints1, OutputArray newPoints2 );
+
+/** @brief Filters off small noise blobs (speckles) in the disparity map
+
+@param img The input 16-bit signed disparity image
+@param newVal The disparity value used to paint-off the speckles
+@param maxSpeckleSize The maximum speckle size to consider it a speckle. Larger blobs are not
+affected by the algorithm
+@param maxDiff Maximum difference between neighbor disparity pixels to put them into the same
+blob. Note that since StereoBM, StereoSGBM and may be other algorithms return a fixed-point
+disparity map, where disparity values are multiplied by 16, this scale factor should be taken into
+account when specifying this parameter value.
+@param buf The optional temporary buffer to avoid memory allocation within the function.
+ */
+CV_EXPORTS_W void filterSpeckles( InputOutputArray img, double newVal,
+ int maxSpeckleSize, double maxDiff,
+ InputOutputArray buf = noArray() );
+
+//! computes valid disparity ROI from the valid ROIs of the rectified images (that are returned by cv::stereoRectify())
+CV_EXPORTS_W Rect getValidDisparityROI( Rect roi1, Rect roi2,
+ int minDisparity, int numberOfDisparities,
+ int SADWindowSize );
+
+//! validates disparity using the left-right check. The matrix "cost" should be computed by the stereo correspondence algorithm
+CV_EXPORTS_W void validateDisparity( InputOutputArray disparity, InputArray cost,
+ int minDisparity, int numberOfDisparities,
+ int disp12MaxDisp = 1 );
+
+/** @brief Reprojects a disparity image to 3D space.
+
+@param disparity Input single-channel 8-bit unsigned, 16-bit signed, 32-bit signed or 32-bit
+floating-point disparity image. If 16-bit signed format is used, the values are assumed to have no
+fractional bits.
+@param _3dImage Output 3-channel floating-point image of the same size as disparity . Each
+element of _3dImage(x,y) contains 3D coordinates of the point (x,y) computed from the disparity
+map.
+@param Q \f$4 \times 4\f$ perspective transformation matrix that can be obtained with stereoRectify.
+@param handleMissingValues Indicates, whether the function should handle missing values (i.e.
+points where the disparity was not computed). If handleMissingValues=true, then pixels with the
+minimal disparity that corresponds to the outliers (see StereoMatcher::compute ) are transformed
+to 3D points with a very large Z value (currently set to 10000).
+@param ddepth The optional output array depth. If it is -1, the output image will have CV_32F
+depth. ddepth can also be set to CV_16S, CV_32S or CV_32F.
+
+The function transforms a single-channel disparity map to a 3-channel image representing a 3D
+surface. That is, for each pixel (x,y) andthe corresponding disparity d=disparity(x,y) , it
+computes:
+
+\f[\begin{array}{l} [X \; Y \; Z \; W]^T = \texttt{Q} *[x \; y \; \texttt{disparity} (x,y) \; 1]^T \\ \texttt{\_3dImage} (x,y) = (X/W, \; Y/W, \; Z/W) \end{array}\f]
+
+The matrix Q can be an arbitrary \f$4 \times 4\f$ matrix (for example, the one computed by
+stereoRectify). To reproject a sparse set of points {(x,y,d),...} to 3D space, use
+perspectiveTransform .
+ */
+CV_EXPORTS_W void reprojectImageTo3D( InputArray disparity,
+ OutputArray _3dImage, InputArray Q,
+ bool handleMissingValues = false,
+ int ddepth = -1 );
+
+/** @brief Calculates the Sampson Distance between two points.
+
+The function sampsonDistance calculates and returns the first order approximation of the geometric error as:
+\f[sd( \texttt{pt1} , \texttt{pt2} )= \frac{(\texttt{pt2}^t \cdot \texttt{F} \cdot \texttt{pt1})^2}{(\texttt{F} \cdot \texttt{pt1})(0) + (\texttt{F} \cdot \texttt{pt1})(1) + (\texttt{F}^t \cdot \texttt{pt2})(0) + (\texttt{F}^t \cdot \texttt{pt2})(1)}\f]
+The fundamental matrix may be calculated using the cv::findFundamentalMat function. See HZ 11.4.3 for details.
+@param pt1 first homogeneous 2d point
+@param pt2 second homogeneous 2d point
+@param F fundamental matrix
+*/
+CV_EXPORTS_W double sampsonDistance(InputArray pt1, InputArray pt2, InputArray F);
+
+/** @brief Computes an optimal affine transformation between two 3D point sets.
+
+@param src First input 3D point set.
+@param dst Second input 3D point set.
+@param out Output 3D affine transformation matrix \f$3 \times 4\f$ .
+@param inliers Output vector indicating which points are inliers.
+@param ransacThreshold Maximum reprojection error in the RANSAC algorithm to consider a point as
+an inlier.
+@param confidence Confidence level, between 0 and 1, for the estimated transformation. Anything
+between 0.95 and 0.99 is usually good enough. Values too close to 1 can slow down the estimation
+significantly. Values lower than 0.8-0.9 can result in an incorrectly estimated transformation.
+
+The function estimates an optimal 3D affine transformation between two 3D point sets using the
+RANSAC algorithm.
+ */
+CV_EXPORTS_W int estimateAffine3D(InputArray src, InputArray dst,
+ OutputArray out, OutputArray inliers,
+ double ransacThreshold = 3, double confidence = 0.99);
+
+/** @brief Computes an optimal affine transformation between two 2D point sets.
+
+@param from First input 2D point set.
+@param to Second input 2D point set.
+@param inliers Output vector indicating which points are inliers.
+@param method Robust method used to compute tranformation. The following methods are possible:
+- cv::RANSAC - RANSAC-based robust method
+- cv::LMEDS - Least-Median robust method
+RANSAC is the default method.
+@param ransacReprojThreshold Maximum reprojection error in the RANSAC algorithm to consider
+a point as an inlier. Applies only to RANSAC.
+@param maxIters The maximum number of robust method iterations, 2000 is the maximum it can be.
+@param confidence Confidence level, between 0 and 1, for the estimated transformation. Anything
+between 0.95 and 0.99 is usually good enough. Values too close to 1 can slow down the estimation
+significantly. Values lower than 0.8-0.9 can result in an incorrectly estimated transformation.
+@param refineIters Maximum number of iterations of refining algorithm (Levenberg-Marquardt).
+Passing 0 will disable refining, so the output matrix will be output of robust method.
+
+@return Output 2D affine transformation matrix \f$2 \times 3\f$ or empty matrix if transformation
+could not be estimated.
+
+The function estimates an optimal 2D affine transformation between two 2D point sets using the
+selected robust algorithm.
+
+The computed transformation is then refined further (using only inliers) with the
+Levenberg-Marquardt method to reduce the re-projection error even more.
+
+@note
+The RANSAC method can handle practically any ratio of outliers but need a threshold to
+distinguish inliers from outliers. The method LMeDS does not need any threshold but it works
+correctly only when there are more than 50% of inliers.
+
+@sa estimateAffinePartial2D, getAffineTransform
+*/
+CV_EXPORTS_W cv::Mat estimateAffine2D(InputArray from, InputArray to, OutputArray inliers = noArray(),
+ int method = RANSAC, double ransacReprojThreshold = 3,
+ size_t maxIters = 2000, double confidence = 0.99,
+ size_t refineIters = 10);
+
+/** @brief Computes an optimal limited affine transformation with 4 degrees of freedom between
+two 2D point sets.
+
+@param from First input 2D point set.
+@param to Second input 2D point set.
+@param inliers Output vector indicating which points are inliers.
+@param method Robust method used to compute tranformation. The following methods are possible:
+- cv::RANSAC - RANSAC-based robust method
+- cv::LMEDS - Least-Median robust method
+RANSAC is the default method.
+@param ransacReprojThreshold Maximum reprojection error in the RANSAC algorithm to consider
+a point as an inlier. Applies only to RANSAC.
+@param maxIters The maximum number of robust method iterations, 2000 is the maximum it can be.
+@param confidence Confidence level, between 0 and 1, for the estimated transformation. Anything
+between 0.95 and 0.99 is usually good enough. Values too close to 1 can slow down the estimation
+significantly. Values lower than 0.8-0.9 can result in an incorrectly estimated transformation.
+@param refineIters Maximum number of iterations of refining algorithm (Levenberg-Marquardt).
+Passing 0 will disable refining, so the output matrix will be output of robust method.
+
+@return Output 2D affine transformation (4 degrees of freedom) matrix \f$2 \times 3\f$ or
+empty matrix if transformation could not be estimated.
+
+The function estimates an optimal 2D affine transformation with 4 degrees of freedom limited to
+combinations of translation, rotation, and uniform scaling. Uses the selected algorithm for robust
+estimation.
+
+The computed transformation is then refined further (using only inliers) with the
+Levenberg-Marquardt method to reduce the re-projection error even more.
+
+Estimated transformation matrix is:
+\f[ \begin{bmatrix} \cos(\theta)s & -\sin(\theta)s & tx \\
+ \sin(\theta)s & \cos(\theta)s & ty
+\end{bmatrix} \f]
+Where \f$ \theta \f$ is the rotation angle, \f$ s \f$ the scaling factor and \f$ tx, ty \f$ are
+translations in \f$ x, y \f$ axes respectively.
+
+@note
+The RANSAC method can handle practically any ratio of outliers but need a threshold to
+distinguish inliers from outliers. The method LMeDS does not need any threshold but it works
+correctly only when there are more than 50% of inliers.
+
+@sa estimateAffine2D, getAffineTransform
+*/
+CV_EXPORTS_W cv::Mat estimateAffinePartial2D(InputArray from, InputArray to, OutputArray inliers = noArray(),
+ int method = RANSAC, double ransacReprojThreshold = 3,
+ size_t maxIters = 2000, double confidence = 0.99,
+ size_t refineIters = 10);
+
+/** @brief Decompose a homography matrix to rotation(s), translation(s) and plane normal(s).
+
+@param H The input homography matrix between two images.
+@param K The input intrinsic camera calibration matrix.
+@param rotations Array of rotation matrices.
+@param translations Array of translation matrices.
+@param normals Array of plane normal matrices.
+
+This function extracts relative camera motion between two views observing a planar object from the
+homography H induced by the plane. The intrinsic camera matrix K must also be provided. The function
+may return up to four mathematical solution sets. At least two of the solutions may further be
+invalidated if point correspondences are available by applying positive depth constraint (all points
+must be in front of the camera). The decomposition method is described in detail in @cite Malis .
+ */
+CV_EXPORTS_W int decomposeHomographyMat(InputArray H,
+ InputArray K,
+ OutputArrayOfArrays rotations,
+ OutputArrayOfArrays translations,
+ OutputArrayOfArrays normals);
+
+/** @brief The base class for stereo correspondence algorithms.
+ */
+class CV_EXPORTS_W StereoMatcher : public Algorithm
+{
+public:
+ enum { DISP_SHIFT = 4,
+ DISP_SCALE = (1 << DISP_SHIFT)
+ };
+
+ /** @brief Computes disparity map for the specified stereo pair
+
+ @param left Left 8-bit single-channel image.
+ @param right Right image of the same size and the same type as the left one.
+ @param disparity Output disparity map. It has the same size as the input images. Some algorithms,
+ like StereoBM or StereoSGBM compute 16-bit fixed-point disparity map (where each disparity value
+ has 4 fractional bits), whereas other algorithms output 32-bit floating-point disparity map.
+ */
+ CV_WRAP virtual void compute( InputArray left, InputArray right,
+ OutputArray disparity ) = 0;
+
+ CV_WRAP virtual int getMinDisparity() const = 0;
+ CV_WRAP virtual void setMinDisparity(int minDisparity) = 0;
+
+ CV_WRAP virtual int getNumDisparities() const = 0;
+ CV_WRAP virtual void setNumDisparities(int numDisparities) = 0;
+
+ CV_WRAP virtual int getBlockSize() const = 0;
+ CV_WRAP virtual void setBlockSize(int blockSize) = 0;
+
+ CV_WRAP virtual int getSpeckleWindowSize() const = 0;
+ CV_WRAP virtual void setSpeckleWindowSize(int speckleWindowSize) = 0;
+
+ CV_WRAP virtual int getSpeckleRange() const = 0;
+ CV_WRAP virtual void setSpeckleRange(int speckleRange) = 0;
+
+ CV_WRAP virtual int getDisp12MaxDiff() const = 0;
+ CV_WRAP virtual void setDisp12MaxDiff(int disp12MaxDiff) = 0;
+};
+
+
+/** @brief Class for computing stereo correspondence using the block matching algorithm, introduced and
+contributed to OpenCV by K. Konolige.
+ */
+class CV_EXPORTS_W StereoBM : public StereoMatcher
+{
+public:
+ enum { PREFILTER_NORMALIZED_RESPONSE = 0,
+ PREFILTER_XSOBEL = 1
+ };
+
+ CV_WRAP virtual int getPreFilterType() const = 0;
+ CV_WRAP virtual void setPreFilterType(int preFilterType) = 0;
+
+ CV_WRAP virtual int getPreFilterSize() const = 0;
+ CV_WRAP virtual void setPreFilterSize(int preFilterSize) = 0;
+
+ CV_WRAP virtual int getPreFilterCap() const = 0;
+ CV_WRAP virtual void setPreFilterCap(int preFilterCap) = 0;
+
+ CV_WRAP virtual int getTextureThreshold() const = 0;
+ CV_WRAP virtual void setTextureThreshold(int textureThreshold) = 0;
+
+ CV_WRAP virtual int getUniquenessRatio() const = 0;
+ CV_WRAP virtual void setUniquenessRatio(int uniquenessRatio) = 0;
+
+ CV_WRAP virtual int getSmallerBlockSize() const = 0;
+ CV_WRAP virtual void setSmallerBlockSize(int blockSize) = 0;
+
+ CV_WRAP virtual Rect getROI1() const = 0;
+ CV_WRAP virtual void setROI1(Rect roi1) = 0;
+
+ CV_WRAP virtual Rect getROI2() const = 0;
+ CV_WRAP virtual void setROI2(Rect roi2) = 0;
+
+ /** @brief Creates StereoBM object
+
+ @param numDisparities the disparity search range. For each pixel algorithm will find the best
+ disparity from 0 (default minimum disparity) to numDisparities. The search range can then be
+ shifted by changing the minimum disparity.
+ @param blockSize the linear size of the blocks compared by the algorithm. The size should be odd
+ (as the block is centered at the current pixel). Larger block size implies smoother, though less
+ accurate disparity map. Smaller block size gives more detailed disparity map, but there is higher
+ chance for algorithm to find a wrong correspondence.
+
+ The function create StereoBM object. You can then call StereoBM::compute() to compute disparity for
+ a specific stereo pair.
+ */
+ CV_WRAP static Ptr<StereoBM> create(int numDisparities = 0, int blockSize = 21);
+};
+
+/** @brief The class implements the modified H. Hirschmuller algorithm @cite HH08 that differs from the original
+one as follows:
+
+- By default, the algorithm is single-pass, which means that you consider only 5 directions
+instead of 8. Set mode=StereoSGBM::MODE_HH in createStereoSGBM to run the full variant of the
+algorithm but beware that it may consume a lot of memory.
+- The algorithm matches blocks, not individual pixels. Though, setting blockSize=1 reduces the
+blocks to single pixels.
+- Mutual information cost function is not implemented. Instead, a simpler Birchfield-Tomasi
+sub-pixel metric from @cite BT98 is used. Though, the color images are supported as well.
+- Some pre- and post- processing steps from K. Konolige algorithm StereoBM are included, for
+example: pre-filtering (StereoBM::PREFILTER_XSOBEL type) and post-filtering (uniqueness
+check, quadratic interpolation and speckle filtering).
+
+@note
+ - (Python) An example illustrating the use of the StereoSGBM matching algorithm can be found
+ at opencv_source_code/samples/python/stereo_match.py
+ */
+class CV_EXPORTS_W StereoSGBM : public StereoMatcher
+{
+public:
+ enum
+ {
+ MODE_SGBM = 0,
+ MODE_HH = 1,
+ MODE_SGBM_3WAY = 2
+ };
+
+ CV_WRAP virtual int getPreFilterCap() const = 0;
+ CV_WRAP virtual void setPreFilterCap(int preFilterCap) = 0;
+
+ CV_WRAP virtual int getUniquenessRatio() const = 0;
+ CV_WRAP virtual void setUniquenessRatio(int uniquenessRatio) = 0;
+
+ CV_WRAP virtual int getP1() const = 0;
+ CV_WRAP virtual void setP1(int P1) = 0;
+
+ CV_WRAP virtual int getP2() const = 0;
+ CV_WRAP virtual void setP2(int P2) = 0;
+
+ CV_WRAP virtual int getMode() const = 0;
+ CV_WRAP virtual void setMode(int mode) = 0;
+
+ /** @brief Creates StereoSGBM object
+
+ @param minDisparity Minimum possible disparity value. Normally, it is zero but sometimes
+ rectification algorithms can shift images, so this parameter needs to be adjusted accordingly.
+ @param numDisparities Maximum disparity minus minimum disparity. The value is always greater than
+ zero. In the current implementation, this parameter must be divisible by 16.
+ @param blockSize Matched block size. It must be an odd number \>=1 . Normally, it should be
+ somewhere in the 3..11 range.
+ @param P1 The first parameter controlling the disparity smoothness. See below.
+ @param P2 The second parameter controlling the disparity smoothness. The larger the values are,
+ the smoother the disparity is. P1 is the penalty on the disparity change by plus or minus 1
+ between neighbor pixels. P2 is the penalty on the disparity change by more than 1 between neighbor
+ pixels. The algorithm requires P2 \> P1 . See stereo_match.cpp sample where some reasonably good
+ P1 and P2 values are shown (like 8\*number_of_image_channels\*SADWindowSize\*SADWindowSize and
+ 32\*number_of_image_channels\*SADWindowSize\*SADWindowSize , respectively).
+ @param disp12MaxDiff Maximum allowed difference (in integer pixel units) in the left-right
+ disparity check. Set it to a non-positive value to disable the check.
+ @param preFilterCap Truncation value for the prefiltered image pixels. The algorithm first
+ computes x-derivative at each pixel and clips its value by [-preFilterCap, preFilterCap] interval.
+ The result values are passed to the Birchfield-Tomasi pixel cost function.
+ @param uniquenessRatio Margin in percentage by which the best (minimum) computed cost function
+ value should "win" the second best value to consider the found match correct. Normally, a value
+ within the 5-15 range is good enough.
+ @param speckleWindowSize Maximum size of smooth disparity regions to consider their noise speckles
+ and invalidate. Set it to 0 to disable speckle filtering. Otherwise, set it somewhere in the
+ 50-200 range.
+ @param speckleRange Maximum disparity variation within each connected component. If you do speckle
+ filtering, set the parameter to a positive value, it will be implicitly multiplied by 16.
+ Normally, 1 or 2 is good enough.
+ @param mode Set it to StereoSGBM::MODE_HH to run the full-scale two-pass dynamic programming
+ algorithm. It will consume O(W\*H\*numDisparities) bytes, which is large for 640x480 stereo and
+ huge for HD-size pictures. By default, it is set to false .
+
+ The first constructor initializes StereoSGBM with all the default parameters. So, you only have to
+ set StereoSGBM::numDisparities at minimum. The second constructor enables you to set each parameter
+ to a custom value.
+ */
+ CV_WRAP static Ptr<StereoSGBM> create(int minDisparity, int numDisparities, int blockSize,
+ int P1 = 0, int P2 = 0, int disp12MaxDiff = 0,
+ int preFilterCap = 0, int uniquenessRatio = 0,
+ int speckleWindowSize = 0, int speckleRange = 0,
+ int mode = StereoSGBM::MODE_SGBM);
+};
+
+//! @} calib3d
+
+/** @brief The methods in this namespace use a so-called fisheye camera model.
+ @ingroup calib3d_fisheye
+*/
+namespace fisheye
+{
+//! @addtogroup calib3d_fisheye
+//! @{
+
+ enum{
+ CALIB_USE_INTRINSIC_GUESS = 1 << 0,
+ CALIB_RECOMPUTE_EXTRINSIC = 1 << 1,
+ CALIB_CHECK_COND = 1 << 2,
+ CALIB_FIX_SKEW = 1 << 3,
+ CALIB_FIX_K1 = 1 << 4,
+ CALIB_FIX_K2 = 1 << 5,
+ CALIB_FIX_K3 = 1 << 6,
+ CALIB_FIX_K4 = 1 << 7,
+ CALIB_FIX_INTRINSIC = 1 << 8,
+ CALIB_FIX_PRINCIPAL_POINT = 1 << 9
+ };
+
+ /** @brief Projects points using fisheye model
+
+ @param objectPoints Array of object points, 1xN/Nx1 3-channel (or vector\<Point3f\> ), where N is
+ the number of points in the view.
+ @param imagePoints Output array of image points, 2xN/Nx2 1-channel or 1xN/Nx1 2-channel, or
+ vector\<Point2f\>.
+ @param affine
+ @param K Camera matrix \f$K = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{_1}\f$.
+ @param D Input vector of distortion coefficients \f$(k_1, k_2, k_3, k_4)\f$.
+ @param alpha The skew coefficient.
+ @param jacobian Optional output 2Nx15 jacobian matrix of derivatives of image points with respect
+ to components of the focal lengths, coordinates of the principal point, distortion coefficients,
+ rotation vector, translation vector, and the skew. In the old interface different components of
+ the jacobian are returned via different output parameters.
+
+ The function computes projections of 3D points to the image plane given intrinsic and extrinsic
+ camera parameters. Optionally, the function computes Jacobians - matrices of partial derivatives of
+ image points coordinates (as functions of all the input parameters) with respect to the particular
+ parameters, intrinsic and/or extrinsic.
+ */
+ CV_EXPORTS void projectPoints(InputArray objectPoints, OutputArray imagePoints, const Affine3d& affine,
+ InputArray K, InputArray D, double alpha = 0, OutputArray jacobian = noArray());
+
+ /** @overload */
+ CV_EXPORTS_W void projectPoints(InputArray objectPoints, OutputArray imagePoints, InputArray rvec, InputArray tvec,
+ InputArray K, InputArray D, double alpha = 0, OutputArray jacobian = noArray());
+
+ /** @brief Distorts 2D points using fisheye model.
+
+ @param undistorted Array of object points, 1xN/Nx1 2-channel (or vector\<Point2f\> ), where N is
+ the number of points in the view.
+ @param K Camera matrix \f$K = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{_1}\f$.
+ @param D Input vector of distortion coefficients \f$(k_1, k_2, k_3, k_4)\f$.
+ @param alpha The skew coefficient.
+ @param distorted Output array of image points, 1xN/Nx1 2-channel, or vector\<Point2f\> .
+
+ Note that the function assumes the camera matrix of the undistorted points to be indentity.
+ This means if you want to transform back points undistorted with undistortPoints() you have to
+ multiply them with \f$P^{-1}\f$.
+ */
+ CV_EXPORTS_W void distortPoints(InputArray undistorted, OutputArray distorted, InputArray K, InputArray D, double alpha = 0);
+
+ /** @brief Undistorts 2D points using fisheye model
+
+ @param distorted Array of object points, 1xN/Nx1 2-channel (or vector\<Point2f\> ), where N is the
+ number of points in the view.
+ @param K Camera matrix \f$K = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{_1}\f$.
+ @param D Input vector of distortion coefficients \f$(k_1, k_2, k_3, k_4)\f$.
+ @param R Rectification transformation in the object space: 3x3 1-channel, or vector: 3x1/1x3
+ 1-channel or 1x1 3-channel
+ @param P New camera matrix (3x3) or new projection matrix (3x4)
+ @param undistorted Output array of image points, 1xN/Nx1 2-channel, or vector\<Point2f\> .
+ */
+ CV_EXPORTS_W void undistortPoints(InputArray distorted, OutputArray undistorted,
+ InputArray K, InputArray D, InputArray R = noArray(), InputArray P = noArray());
+
+ /** @brief Computes undistortion and rectification maps for image transform by cv::remap(). If D is empty zero
+ distortion is used, if R or P is empty identity matrixes are used.
+
+ @param K Camera matrix \f$K = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{_1}\f$.
+ @param D Input vector of distortion coefficients \f$(k_1, k_2, k_3, k_4)\f$.
+ @param R Rectification transformation in the object space: 3x3 1-channel, or vector: 3x1/1x3
+ 1-channel or 1x1 3-channel
+ @param P New camera matrix (3x3) or new projection matrix (3x4)
+ @param size Undistorted image size.
+ @param m1type Type of the first output map that can be CV_32FC1 or CV_16SC2 . See convertMaps()
+ for details.
+ @param map1 The first output map.
+ @param map2 The second output map.
+ */
+ CV_EXPORTS_W void initUndistortRectifyMap(InputArray K, InputArray D, InputArray R, InputArray P,
+ const cv::Size& size, int m1type, OutputArray map1, OutputArray map2);
+
+ /** @brief Transforms an image to compensate for fisheye lens distortion.
+
+ @param distorted image with fisheye lens distortion.
+ @param undistorted Output image with compensated fisheye lens distortion.
+ @param K Camera matrix \f$K = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{_1}\f$.
+ @param D Input vector of distortion coefficients \f$(k_1, k_2, k_3, k_4)\f$.
+ @param Knew Camera matrix of the distorted image. By default, it is the identity matrix but you
+ may additionally scale and shift the result by using a different matrix.
+ @param new_size
+
+ The function transforms an image to compensate radial and tangential lens distortion.
+
+ The function is simply a combination of fisheye::initUndistortRectifyMap (with unity R ) and remap
+ (with bilinear interpolation). See the former function for details of the transformation being
+ performed.
+
+ See below the results of undistortImage.
+ - a\) result of undistort of perspective camera model (all possible coefficients (k_1, k_2, k_3,
+ k_4, k_5, k_6) of distortion were optimized under calibration)
+ - b\) result of fisheye::undistortImage of fisheye camera model (all possible coefficients (k_1, k_2,
+ k_3, k_4) of fisheye distortion were optimized under calibration)
+ - c\) original image was captured with fisheye lens
+
+ Pictures a) and b) almost the same. But if we consider points of image located far from the center
+ of image, we can notice that on image a) these points are distorted.
+
+ 
+ */
+ CV_EXPORTS_W void undistortImage(InputArray distorted, OutputArray undistorted,
+ InputArray K, InputArray D, InputArray Knew = cv::noArray(), const Size& new_size = Size());
+
+ /** @brief Estimates new camera matrix for undistortion or rectification.
+
+ @param K Camera matrix \f$K = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{_1}\f$.
+ @param image_size
+ @param D Input vector of distortion coefficients \f$(k_1, k_2, k_3, k_4)\f$.
+ @param R Rectification transformation in the object space: 3x3 1-channel, or vector: 3x1/1x3
+ 1-channel or 1x1 3-channel
+ @param P New camera matrix (3x3) or new projection matrix (3x4)
+ @param balance Sets the new focal length in range between the min focal length and the max focal
+ length. Balance is in range of [0, 1].
+ @param new_size
+ @param fov_scale Divisor for new focal length.
+ */
+ CV_EXPORTS_W void estimateNewCameraMatrixForUndistortRectify(InputArray K, InputArray D, const Size &image_size, InputArray R,
+ OutputArray P, double balance = 0.0, const Size& new_size = Size(), double fov_scale = 1.0);
+
+ /** @brief Performs camera calibaration
+
+ @param objectPoints vector of vectors of calibration pattern points in the calibration pattern
+ coordinate space.
+ @param imagePoints vector of vectors of the projections of calibration pattern points.
+ imagePoints.size() and objectPoints.size() and imagePoints[i].size() must be equal to
+ objectPoints[i].size() for each i.
+ @param image_size Size of the image used only to initialize the intrinsic camera matrix.
+ @param K Output 3x3 floating-point camera matrix
+ \f$A = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}\f$ . If
+ fisheye::CALIB_USE_INTRINSIC_GUESS/ is specified, some or all of fx, fy, cx, cy must be
+ initialized before calling the function.
+ @param D Output vector of distortion coefficients \f$(k_1, k_2, k_3, k_4)\f$.
+ @param rvecs Output vector of rotation vectors (see Rodrigues ) estimated for each pattern view.
+ That is, each k-th rotation vector together with the corresponding k-th translation vector (see
+ the next output parameter description) brings the calibration pattern from the model coordinate
+ space (in which object points are specified) to the world coordinate space, that is, a real
+ position of the calibration pattern in the k-th pattern view (k=0.. *M* -1).
+ @param tvecs Output vector of translation vectors estimated for each pattern view.
+ @param flags Different flags that may be zero or a combination of the following values:
+ - **fisheye::CALIB_USE_INTRINSIC_GUESS** cameraMatrix contains valid initial values of
+ fx, fy, cx, cy that are optimized further. Otherwise, (cx, cy) is initially set to the image
+ center ( imageSize is used), and focal distances are computed in a least-squares fashion.
+ - **fisheye::CALIB_RECOMPUTE_EXTRINSIC** Extrinsic will be recomputed after each iteration
+ of intrinsic optimization.
+ - **fisheye::CALIB_CHECK_COND** The functions will check validity of condition number.
+ - **fisheye::CALIB_FIX_SKEW** Skew coefficient (alpha) is set to zero and stay zero.
+ - **fisheye::CALIB_FIX_K1..fisheye::CALIB_FIX_K4** Selected distortion coefficients
+ are set to zeros and stay zero.
+ - **fisheye::CALIB_FIX_PRINCIPAL_POINT** The principal point is not changed during the global
+optimization. It stays at the center or at a different location specified when CALIB_USE_INTRINSIC_GUESS is set too.
+ @param criteria Termination criteria for the iterative optimization algorithm.
+ */
+ CV_EXPORTS_W double calibrate(InputArrayOfArrays objectPoints, InputArrayOfArrays imagePoints, const Size& image_size,
+ InputOutputArray K, InputOutputArray D, OutputArrayOfArrays rvecs, OutputArrayOfArrays tvecs, int flags = 0,
+ TermCriteria criteria = TermCriteria(TermCriteria::COUNT + TermCriteria::EPS, 100, DBL_EPSILON));
+
+ /** @brief Stereo rectification for fisheye camera model
+
+ @param K1 First camera matrix.
+ @param D1 First camera distortion parameters.
+ @param K2 Second camera matrix.
+ @param D2 Second camera distortion parameters.
+ @param imageSize Size of the image used for stereo calibration.
+ @param R Rotation matrix between the coordinate systems of the first and the second
+ cameras.
+ @param tvec Translation vector between coordinate systems of the cameras.
+ @param R1 Output 3x3 rectification transform (rotation matrix) for the first camera.
+ @param R2 Output 3x3 rectification transform (rotation matrix) for the second camera.
+ @param P1 Output 3x4 projection matrix in the new (rectified) coordinate systems for the first
+ camera.
+ @param P2 Output 3x4 projection matrix in the new (rectified) coordinate systems for the second
+ camera.
+ @param Q Output \f$4 \times 4\f$ disparity-to-depth mapping matrix (see reprojectImageTo3D ).
+ @param flags Operation flags that may be zero or CV_CALIB_ZERO_DISPARITY . If the flag is set,
+ the function makes the principal points of each camera have the same pixel coordinates in the
+ rectified views. And if the flag is not set, the function may still shift the images in the
+ horizontal or vertical direction (depending on the orientation of epipolar lines) to maximize the
+ useful image area.
+ @param newImageSize New image resolution after rectification. The same size should be passed to
+ initUndistortRectifyMap (see the stereo_calib.cpp sample in OpenCV samples directory). When (0,0)
+ is passed (default), it is set to the original imageSize . Setting it to larger value can help you
+ preserve details in the original image, especially when there is a big radial distortion.
+ @param balance Sets the new focal length in range between the min focal length and the max focal
+ length. Balance is in range of [0, 1].
+ @param fov_scale Divisor for new focal length.
+ */
+ CV_EXPORTS_W void stereoRectify(InputArray K1, InputArray D1, InputArray K2, InputArray D2, const Size &imageSize, InputArray R, InputArray tvec,
+ OutputArray R1, OutputArray R2, OutputArray P1, OutputArray P2, OutputArray Q, int flags, const Size &newImageSize = Size(),
+ double balance = 0.0, double fov_scale = 1.0);
+
+ /** @brief Performs stereo calibration
+
+ @param objectPoints Vector of vectors of the calibration pattern points.
+ @param imagePoints1 Vector of vectors of the projections of the calibration pattern points,
+ observed by the first camera.
+ @param imagePoints2 Vector of vectors of the projections of the calibration pattern points,
+ observed by the second camera.
+ @param K1 Input/output first camera matrix:
+ \f$\vecthreethree{f_x^{(j)}}{0}{c_x^{(j)}}{0}{f_y^{(j)}}{c_y^{(j)}}{0}{0}{1}\f$ , \f$j = 0,\, 1\f$ . If
+ any of fisheye::CALIB_USE_INTRINSIC_GUESS , fisheye::CV_CALIB_FIX_INTRINSIC are specified,
+ some or all of the matrix components must be initialized.
+ @param D1 Input/output vector of distortion coefficients \f$(k_1, k_2, k_3, k_4)\f$ of 4 elements.
+ @param K2 Input/output second camera matrix. The parameter is similar to K1 .
+ @param D2 Input/output lens distortion coefficients for the second camera. The parameter is
+ similar to D1 .
+ @param imageSize Size of the image used only to initialize intrinsic camera matrix.
+ @param R Output rotation matrix between the 1st and the 2nd camera coordinate systems.
+ @param T Output translation vector between the coordinate systems of the cameras.
+ @param flags Different flags that may be zero or a combination of the following values:
+ - **fisheye::CV_CALIB_FIX_INTRINSIC** Fix K1, K2? and D1, D2? so that only R, T matrices
+ are estimated.
+ - **fisheye::CALIB_USE_INTRINSIC_GUESS** K1, K2 contains valid initial values of
+ fx, fy, cx, cy that are optimized further. Otherwise, (cx, cy) is initially set to the image
+ center (imageSize is used), and focal distances are computed in a least-squares fashion.
+ - **fisheye::CALIB_RECOMPUTE_EXTRINSIC** Extrinsic will be recomputed after each iteration
+ of intrinsic optimization.
+ - **fisheye::CALIB_CHECK_COND** The functions will check validity of condition number.
+ - **fisheye::CALIB_FIX_SKEW** Skew coefficient (alpha) is set to zero and stay zero.
+ - **fisheye::CALIB_FIX_K1..4** Selected distortion coefficients are set to zeros and stay
+ zero.
+ @param criteria Termination criteria for the iterative optimization algorithm.
+ */
+ CV_EXPORTS_W double stereoCalibrate(InputArrayOfArrays objectPoints, InputArrayOfArrays imagePoints1, InputArrayOfArrays imagePoints2,
+ InputOutputArray K1, InputOutputArray D1, InputOutputArray K2, InputOutputArray D2, Size imageSize,
+ OutputArray R, OutputArray T, int flags = fisheye::CALIB_FIX_INTRINSIC,
+ TermCriteria criteria = TermCriteria(TermCriteria::COUNT + TermCriteria::EPS, 100, DBL_EPSILON));
+
+//! @} calib3d_fisheye
+}
+
+} // cv
+
+#ifndef DISABLE_OPENCV_24_COMPATIBILITY
+#include "opencv2/calib3d/calib3d_c.h"
+#endif
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/opencv2/calib3d/calib3d.hpp Fri Jan 29 04:53:38 2021 +0000 @@ -0,0 +1,48 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifdef __OPENCV_BUILD +#error this is a compatibility header which should not be used inside the OpenCV library +#endif + +#include "opencv2/calib3d.hpp"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/calib3d/calib3d_c.h Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,426 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_CALIB3D_C_H
+#define OPENCV_CALIB3D_C_H
+
+#include "opencv2/core/core_c.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @addtogroup calib3d_c
+ @{
+ */
+
+/****************************************************************************************\
+* Camera Calibration, Pose Estimation and Stereo *
+\****************************************************************************************/
+
+typedef struct CvPOSITObject CvPOSITObject;
+
+/* Allocates and initializes CvPOSITObject structure before doing cvPOSIT */
+CVAPI(CvPOSITObject*) cvCreatePOSITObject( CvPoint3D32f* points, int point_count );
+
+
+/* Runs POSIT (POSe from ITeration) algorithm for determining 3d position of
+ an object given its model and projection in a weak-perspective case */
+CVAPI(void) cvPOSIT( CvPOSITObject* posit_object, CvPoint2D32f* image_points,
+ double focal_length, CvTermCriteria criteria,
+ float* rotation_matrix, float* translation_vector);
+
+/* Releases CvPOSITObject structure */
+CVAPI(void) cvReleasePOSITObject( CvPOSITObject** posit_object );
+
+/* updates the number of RANSAC iterations */
+CVAPI(int) cvRANSACUpdateNumIters( double p, double err_prob,
+ int model_points, int max_iters );
+
+CVAPI(void) cvConvertPointsHomogeneous( const CvMat* src, CvMat* dst );
+
+/* Calculates fundamental matrix given a set of corresponding points */
+#define CV_FM_7POINT 1
+#define CV_FM_8POINT 2
+
+#define CV_LMEDS 4
+#define CV_RANSAC 8
+
+#define CV_FM_LMEDS_ONLY CV_LMEDS
+#define CV_FM_RANSAC_ONLY CV_RANSAC
+#define CV_FM_LMEDS CV_LMEDS
+#define CV_FM_RANSAC CV_RANSAC
+
+enum
+{
+ CV_ITERATIVE = 0,
+ CV_EPNP = 1, // F.Moreno-Noguer, V.Lepetit and P.Fua "EPnP: Efficient Perspective-n-Point Camera Pose Estimation"
+ CV_P3P = 2, // X.S. Gao, X.-R. Hou, J. Tang, H.-F. Chang; "Complete Solution Classification for the Perspective-Three-Point Problem"
+ CV_DLS = 3 // Joel A. Hesch and Stergios I. Roumeliotis. "A Direct Least-Squares (DLS) Method for PnP"
+};
+
+CVAPI(int) cvFindFundamentalMat( const CvMat* points1, const CvMat* points2,
+ CvMat* fundamental_matrix,
+ int method CV_DEFAULT(CV_FM_RANSAC),
+ double param1 CV_DEFAULT(3.), double param2 CV_DEFAULT(0.99),
+ CvMat* status CV_DEFAULT(NULL) );
+
+/* For each input point on one of images
+ computes parameters of the corresponding
+ epipolar line on the other image */
+CVAPI(void) cvComputeCorrespondEpilines( const CvMat* points,
+ int which_image,
+ const CvMat* fundamental_matrix,
+ CvMat* correspondent_lines );
+
+/* Triangulation functions */
+
+CVAPI(void) cvTriangulatePoints(CvMat* projMatr1, CvMat* projMatr2,
+ CvMat* projPoints1, CvMat* projPoints2,
+ CvMat* points4D);
+
+CVAPI(void) cvCorrectMatches(CvMat* F, CvMat* points1, CvMat* points2,
+ CvMat* new_points1, CvMat* new_points2);
+
+
+/* Computes the optimal new camera matrix according to the free scaling parameter alpha:
+ alpha=0 - only valid pixels will be retained in the undistorted image
+ alpha=1 - all the source image pixels will be retained in the undistorted image
+*/
+CVAPI(void) cvGetOptimalNewCameraMatrix( const CvMat* camera_matrix,
+ const CvMat* dist_coeffs,
+ CvSize image_size, double alpha,
+ CvMat* new_camera_matrix,
+ CvSize new_imag_size CV_DEFAULT(cvSize(0,0)),
+ CvRect* valid_pixel_ROI CV_DEFAULT(0),
+ int center_principal_point CV_DEFAULT(0));
+
+/* Converts rotation vector to rotation matrix or vice versa */
+CVAPI(int) cvRodrigues2( const CvMat* src, CvMat* dst,
+ CvMat* jacobian CV_DEFAULT(0) );
+
+/* Finds perspective transformation between the object plane and image (view) plane */
+CVAPI(int) cvFindHomography( const CvMat* src_points,
+ const CvMat* dst_points,
+ CvMat* homography,
+ int method CV_DEFAULT(0),
+ double ransacReprojThreshold CV_DEFAULT(3),
+ CvMat* mask CV_DEFAULT(0),
+ int maxIters CV_DEFAULT(2000),
+ double confidence CV_DEFAULT(0.995));
+
+/* Computes RQ decomposition for 3x3 matrices */
+CVAPI(void) cvRQDecomp3x3( const CvMat *matrixM, CvMat *matrixR, CvMat *matrixQ,
+ CvMat *matrixQx CV_DEFAULT(NULL),
+ CvMat *matrixQy CV_DEFAULT(NULL),
+ CvMat *matrixQz CV_DEFAULT(NULL),
+ CvPoint3D64f *eulerAngles CV_DEFAULT(NULL));
+
+/* Computes projection matrix decomposition */
+CVAPI(void) cvDecomposeProjectionMatrix( const CvMat *projMatr, CvMat *calibMatr,
+ CvMat *rotMatr, CvMat *posVect,
+ CvMat *rotMatrX CV_DEFAULT(NULL),
+ CvMat *rotMatrY CV_DEFAULT(NULL),
+ CvMat *rotMatrZ CV_DEFAULT(NULL),
+ CvPoint3D64f *eulerAngles CV_DEFAULT(NULL));
+
+/* Computes d(AB)/dA and d(AB)/dB */
+CVAPI(void) cvCalcMatMulDeriv( const CvMat* A, const CvMat* B, CvMat* dABdA, CvMat* dABdB );
+
+/* Computes r3 = rodrigues(rodrigues(r2)*rodrigues(r1)),
+ t3 = rodrigues(r2)*t1 + t2 and the respective derivatives */
+CVAPI(void) cvComposeRT( const CvMat* _rvec1, const CvMat* _tvec1,
+ const CvMat* _rvec2, const CvMat* _tvec2,
+ CvMat* _rvec3, CvMat* _tvec3,
+ CvMat* dr3dr1 CV_DEFAULT(0), CvMat* dr3dt1 CV_DEFAULT(0),
+ CvMat* dr3dr2 CV_DEFAULT(0), CvMat* dr3dt2 CV_DEFAULT(0),
+ CvMat* dt3dr1 CV_DEFAULT(0), CvMat* dt3dt1 CV_DEFAULT(0),
+ CvMat* dt3dr2 CV_DEFAULT(0), CvMat* dt3dt2 CV_DEFAULT(0) );
+
+/* Projects object points to the view plane using
+ the specified extrinsic and intrinsic camera parameters */
+CVAPI(void) cvProjectPoints2( const CvMat* object_points, const CvMat* rotation_vector,
+ const CvMat* translation_vector, const CvMat* camera_matrix,
+ const CvMat* distortion_coeffs, CvMat* image_points,
+ CvMat* dpdrot CV_DEFAULT(NULL), CvMat* dpdt CV_DEFAULT(NULL),
+ CvMat* dpdf CV_DEFAULT(NULL), CvMat* dpdc CV_DEFAULT(NULL),
+ CvMat* dpddist CV_DEFAULT(NULL),
+ double aspect_ratio CV_DEFAULT(0));
+
+/* Finds extrinsic camera parameters from
+ a few known corresponding point pairs and intrinsic parameters */
+CVAPI(void) cvFindExtrinsicCameraParams2( const CvMat* object_points,
+ const CvMat* image_points,
+ const CvMat* camera_matrix,
+ const CvMat* distortion_coeffs,
+ CvMat* rotation_vector,
+ CvMat* translation_vector,
+ int use_extrinsic_guess CV_DEFAULT(0) );
+
+/* Computes initial estimate of the intrinsic camera parameters
+ in case of planar calibration target (e.g. chessboard) */
+CVAPI(void) cvInitIntrinsicParams2D( const CvMat* object_points,
+ const CvMat* image_points,
+ const CvMat* npoints, CvSize image_size,
+ CvMat* camera_matrix,
+ double aspect_ratio CV_DEFAULT(1.) );
+
+#define CV_CALIB_CB_ADAPTIVE_THRESH 1
+#define CV_CALIB_CB_NORMALIZE_IMAGE 2
+#define CV_CALIB_CB_FILTER_QUADS 4
+#define CV_CALIB_CB_FAST_CHECK 8
+
+// Performs a fast check if a chessboard is in the input image. This is a workaround to
+// a problem of cvFindChessboardCorners being slow on images with no chessboard
+// - src: input image
+// - size: chessboard size
+// Returns 1 if a chessboard can be in this image and findChessboardCorners should be called,
+// 0 if there is no chessboard, -1 in case of error
+CVAPI(int) cvCheckChessboard(IplImage* src, CvSize size);
+
+ /* Detects corners on a chessboard calibration pattern */
+CVAPI(int) cvFindChessboardCorners( const void* image, CvSize pattern_size,
+ CvPoint2D32f* corners,
+ int* corner_count CV_DEFAULT(NULL),
+ int flags CV_DEFAULT(CV_CALIB_CB_ADAPTIVE_THRESH+CV_CALIB_CB_NORMALIZE_IMAGE) );
+
+/* Draws individual chessboard corners or the whole chessboard detected */
+CVAPI(void) cvDrawChessboardCorners( CvArr* image, CvSize pattern_size,
+ CvPoint2D32f* corners,
+ int count, int pattern_was_found );
+
+#define CV_CALIB_USE_INTRINSIC_GUESS 1
+#define CV_CALIB_FIX_ASPECT_RATIO 2
+#define CV_CALIB_FIX_PRINCIPAL_POINT 4
+#define CV_CALIB_ZERO_TANGENT_DIST 8
+#define CV_CALIB_FIX_FOCAL_LENGTH 16
+#define CV_CALIB_FIX_K1 32
+#define CV_CALIB_FIX_K2 64
+#define CV_CALIB_FIX_K3 128
+#define CV_CALIB_FIX_K4 2048
+#define CV_CALIB_FIX_K5 4096
+#define CV_CALIB_FIX_K6 8192
+#define CV_CALIB_RATIONAL_MODEL 16384
+#define CV_CALIB_THIN_PRISM_MODEL 32768
+#define CV_CALIB_FIX_S1_S2_S3_S4 65536
+#define CV_CALIB_TILTED_MODEL 262144
+#define CV_CALIB_FIX_TAUX_TAUY 524288
+
+#define CV_CALIB_NINTRINSIC 18
+
+/* Finds intrinsic and extrinsic camera parameters
+ from a few views of known calibration pattern */
+CVAPI(double) cvCalibrateCamera2( const CvMat* object_points,
+ const CvMat* image_points,
+ const CvMat* point_counts,
+ CvSize image_size,
+ CvMat* camera_matrix,
+ CvMat* distortion_coeffs,
+ CvMat* rotation_vectors CV_DEFAULT(NULL),
+ CvMat* translation_vectors CV_DEFAULT(NULL),
+ int flags CV_DEFAULT(0),
+ CvTermCriteria term_crit CV_DEFAULT(cvTermCriteria(
+ CV_TERMCRIT_ITER+CV_TERMCRIT_EPS,30,DBL_EPSILON)) );
+
+/* Computes various useful characteristics of the camera from the data computed by
+ cvCalibrateCamera2 */
+CVAPI(void) cvCalibrationMatrixValues( const CvMat *camera_matrix,
+ CvSize image_size,
+ double aperture_width CV_DEFAULT(0),
+ double aperture_height CV_DEFAULT(0),
+ double *fovx CV_DEFAULT(NULL),
+ double *fovy CV_DEFAULT(NULL),
+ double *focal_length CV_DEFAULT(NULL),
+ CvPoint2D64f *principal_point CV_DEFAULT(NULL),
+ double *pixel_aspect_ratio CV_DEFAULT(NULL));
+
+#define CV_CALIB_FIX_INTRINSIC 256
+#define CV_CALIB_SAME_FOCAL_LENGTH 512
+
+/* Computes the transformation from one camera coordinate system to another one
+ from a few correspondent views of the same calibration target. Optionally, calibrates
+ both cameras */
+CVAPI(double) cvStereoCalibrate( const CvMat* object_points, const CvMat* image_points1,
+ const CvMat* image_points2, const CvMat* npoints,
+ CvMat* camera_matrix1, CvMat* dist_coeffs1,
+ CvMat* camera_matrix2, CvMat* dist_coeffs2,
+ CvSize image_size, CvMat* R, CvMat* T,
+ CvMat* E CV_DEFAULT(0), CvMat* F CV_DEFAULT(0),
+ int flags CV_DEFAULT(CV_CALIB_FIX_INTRINSIC),
+ CvTermCriteria term_crit CV_DEFAULT(cvTermCriteria(
+ CV_TERMCRIT_ITER+CV_TERMCRIT_EPS,30,1e-6)) );
+
+#define CV_CALIB_ZERO_DISPARITY 1024
+
+/* Computes 3D rotations (+ optional shift) for each camera coordinate system to make both
+ views parallel (=> to make all the epipolar lines horizontal or vertical) */
+CVAPI(void) cvStereoRectify( const CvMat* camera_matrix1, const CvMat* camera_matrix2,
+ const CvMat* dist_coeffs1, const CvMat* dist_coeffs2,
+ CvSize image_size, const CvMat* R, const CvMat* T,
+ CvMat* R1, CvMat* R2, CvMat* P1, CvMat* P2,
+ CvMat* Q CV_DEFAULT(0),
+ int flags CV_DEFAULT(CV_CALIB_ZERO_DISPARITY),
+ double alpha CV_DEFAULT(-1),
+ CvSize new_image_size CV_DEFAULT(cvSize(0,0)),
+ CvRect* valid_pix_ROI1 CV_DEFAULT(0),
+ CvRect* valid_pix_ROI2 CV_DEFAULT(0));
+
+/* Computes rectification transformations for uncalibrated pair of images using a set
+ of point correspondences */
+CVAPI(int) cvStereoRectifyUncalibrated( const CvMat* points1, const CvMat* points2,
+ const CvMat* F, CvSize img_size,
+ CvMat* H1, CvMat* H2,
+ double threshold CV_DEFAULT(5));
+
+
+
+/* stereo correspondence parameters and functions */
+
+#define CV_STEREO_BM_NORMALIZED_RESPONSE 0
+#define CV_STEREO_BM_XSOBEL 1
+
+/* Block matching algorithm structure */
+typedef struct CvStereoBMState
+{
+ // pre-filtering (normalization of input images)
+ int preFilterType; // =CV_STEREO_BM_NORMALIZED_RESPONSE now
+ int preFilterSize; // averaging window size: ~5x5..21x21
+ int preFilterCap; // the output of pre-filtering is clipped by [-preFilterCap,preFilterCap]
+
+ // correspondence using Sum of Absolute Difference (SAD)
+ int SADWindowSize; // ~5x5..21x21
+ int minDisparity; // minimum disparity (can be negative)
+ int numberOfDisparities; // maximum disparity - minimum disparity (> 0)
+
+ // post-filtering
+ int textureThreshold; // the disparity is only computed for pixels
+ // with textured enough neighborhood
+ int uniquenessRatio; // accept the computed disparity d* only if
+ // SAD(d) >= SAD(d*)*(1 + uniquenessRatio/100.)
+ // for any d != d*+/-1 within the search range.
+ int speckleWindowSize; // disparity variation window
+ int speckleRange; // acceptable range of variation in window
+
+ int trySmallerWindows; // if 1, the results may be more accurate,
+ // at the expense of slower processing
+ CvRect roi1, roi2;
+ int disp12MaxDiff;
+
+ // temporary buffers
+ CvMat* preFilteredImg0;
+ CvMat* preFilteredImg1;
+ CvMat* slidingSumBuf;
+ CvMat* cost;
+ CvMat* disp;
+} CvStereoBMState;
+
+#define CV_STEREO_BM_BASIC 0
+#define CV_STEREO_BM_FISH_EYE 1
+#define CV_STEREO_BM_NARROW 2
+
+CVAPI(CvStereoBMState*) cvCreateStereoBMState(int preset CV_DEFAULT(CV_STEREO_BM_BASIC),
+ int numberOfDisparities CV_DEFAULT(0));
+
+CVAPI(void) cvReleaseStereoBMState( CvStereoBMState** state );
+
+CVAPI(void) cvFindStereoCorrespondenceBM( const CvArr* left, const CvArr* right,
+ CvArr* disparity, CvStereoBMState* state );
+
+CVAPI(CvRect) cvGetValidDisparityROI( CvRect roi1, CvRect roi2, int minDisparity,
+ int numberOfDisparities, int SADWindowSize );
+
+CVAPI(void) cvValidateDisparity( CvArr* disparity, const CvArr* cost,
+ int minDisparity, int numberOfDisparities,
+ int disp12MaxDiff CV_DEFAULT(1) );
+
+/* Reprojects the computed disparity image to the 3D space using the specified 4x4 matrix */
+CVAPI(void) cvReprojectImageTo3D( const CvArr* disparityImage,
+ CvArr* _3dImage, const CvMat* Q,
+ int handleMissingValues CV_DEFAULT(0) );
+
+/** @} calib3d_c */
+
+#ifdef __cplusplus
+} // extern "C"
+
+//////////////////////////////////////////////////////////////////////////////////////////
+class CV_EXPORTS CvLevMarq
+{
+public:
+ CvLevMarq();
+ CvLevMarq( int nparams, int nerrs, CvTermCriteria criteria=
+ cvTermCriteria(CV_TERMCRIT_EPS+CV_TERMCRIT_ITER,30,DBL_EPSILON),
+ bool completeSymmFlag=false );
+ ~CvLevMarq();
+ void init( int nparams, int nerrs, CvTermCriteria criteria=
+ cvTermCriteria(CV_TERMCRIT_EPS+CV_TERMCRIT_ITER,30,DBL_EPSILON),
+ bool completeSymmFlag=false );
+ bool update( const CvMat*& param, CvMat*& J, CvMat*& err );
+ bool updateAlt( const CvMat*& param, CvMat*& JtJ, CvMat*& JtErr, double*& errNorm );
+
+ void clear();
+ void step();
+ enum { DONE=0, STARTED=1, CALC_J=2, CHECK_ERR=3 };
+
+ cv::Ptr<CvMat> mask;
+ cv::Ptr<CvMat> prevParam;
+ cv::Ptr<CvMat> param;
+ cv::Ptr<CvMat> J;
+ cv::Ptr<CvMat> err;
+ cv::Ptr<CvMat> JtJ;
+ cv::Ptr<CvMat> JtJN;
+ cv::Ptr<CvMat> JtErr;
+ cv::Ptr<CvMat> JtJV;
+ cv::Ptr<CvMat> JtJW;
+ double prevErrNorm, errNorm;
+ int lambdaLg10;
+ CvTermCriteria criteria;
+ int state;
+ int iters;
+ bool completeSymmFlag;
+ int solveMethod;
+};
+
+#endif
+
+#endif /* OPENCV_CALIB3D_C_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/core.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,3220 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2015, Intel Corporation, all rights reserved.
+// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
+// Copyright (C) 2015, OpenCV Foundation, all rights reserved.
+// Copyright (C) 2015, Itseez Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_CORE_HPP
+#define OPENCV_CORE_HPP
+
+#ifndef __cplusplus
+# error core.hpp header must be compiled as C++
+#endif
+
+#include "opencv2/core/cvdef.h"
+#include "opencv2/core/version.hpp"
+#include "opencv2/core/base.hpp"
+#include "opencv2/core/cvstd.hpp"
+#include "opencv2/core/traits.hpp"
+#include "opencv2/core/matx.hpp"
+#include "opencv2/core/types.hpp"
+#include "opencv2/core/mat.hpp"
+#include "opencv2/core/persistence.hpp"
+
+/**
+@defgroup core Core functionality
+@{
+ @defgroup core_basic Basic structures
+ @defgroup core_c C structures and operations
+ @{
+ @defgroup core_c_glue Connections with C++
+ @}
+ @defgroup core_array Operations on arrays
+ @defgroup core_xml XML/YAML Persistence
+ @defgroup core_cluster Clustering
+ @defgroup core_utils Utility and system functions and macros
+ @{
+ @defgroup core_utils_sse SSE utilities
+ @defgroup core_utils_neon NEON utilities
+ @}
+ @defgroup core_opengl OpenGL interoperability
+ @defgroup core_ipp Intel IPP Asynchronous C/C++ Converters
+ @defgroup core_optim Optimization Algorithms
+ @defgroup core_directx DirectX interoperability
+ @defgroup core_eigen Eigen support
+ @defgroup core_opencl OpenCL support
+ @defgroup core_va_intel Intel VA-API/OpenCL (CL-VA) interoperability
+ @defgroup core_hal Hardware Acceleration Layer
+ @{
+ @defgroup core_hal_functions Functions
+ @defgroup core_hal_interface Interface
+ @defgroup core_hal_intrin Universal intrinsics
+ @{
+ @defgroup core_hal_intrin_impl Private implementation helpers
+ @}
+ @}
+@}
+ */
+
+namespace cv {
+
+//! @addtogroup core_utils
+//! @{
+
+/*! @brief Class passed to an error.
+
+This class encapsulates all or almost all necessary
+information about the error happened in the program. The exception is
+usually constructed and thrown implicitly via CV_Error and CV_Error_ macros.
+@see error
+ */
+class CV_EXPORTS Exception : public std::exception
+{
+public:
+ /*!
+ Default constructor
+ */
+ Exception();
+ /*!
+ Full constructor. Normally the constuctor is not called explicitly.
+ Instead, the macros CV_Error(), CV_Error_() and CV_Assert() are used.
+ */
+ Exception(int _code, const String& _err, const String& _func, const String& _file, int _line);
+ virtual ~Exception() throw();
+
+ /*!
+ \return the error description and the context as a text string.
+ */
+ virtual const char *what() const throw();
+ void formatMessage();
+
+ String msg; ///< the formatted error message
+
+ int code; ///< error code @see CVStatus
+ String err; ///< error description
+ String func; ///< function name. Available only when the compiler supports getting it
+ String file; ///< source file name where the error has occured
+ int line; ///< line number in the source file where the error has occured
+};
+
+/*! @brief Signals an error and raises the exception.
+
+By default the function prints information about the error to stderr,
+then it either stops if cv::setBreakOnError() had been called before or raises the exception.
+It is possible to alternate error processing by using cv::redirectError().
+@param exc the exception raisen.
+@deprecated drop this version
+ */
+CV_EXPORTS void error( const Exception& exc );
+
+enum SortFlags { SORT_EVERY_ROW = 0, //!< each matrix row is sorted independently
+ SORT_EVERY_COLUMN = 1, //!< each matrix column is sorted
+ //!< independently; this flag and the previous one are
+ //!< mutually exclusive.
+ SORT_ASCENDING = 0, //!< each matrix row is sorted in the ascending
+ //!< order.
+ SORT_DESCENDING = 16 //!< each matrix row is sorted in the
+ //!< descending order; this flag and the previous one are also
+ //!< mutually exclusive.
+ };
+
+//! @} core_utils
+
+//! @addtogroup core
+//! @{
+
+//! Covariation flags
+enum CovarFlags {
+ /** The output covariance matrix is calculated as:
+ \f[\texttt{scale} \cdot [ \texttt{vects} [0]- \texttt{mean} , \texttt{vects} [1]- \texttt{mean} ,...]^T \cdot [ \texttt{vects} [0]- \texttt{mean} , \texttt{vects} [1]- \texttt{mean} ,...],\f]
+ The covariance matrix will be nsamples x nsamples. Such an unusual covariance matrix is used
+ for fast PCA of a set of very large vectors (see, for example, the EigenFaces technique for
+ face recognition). Eigenvalues of this "scrambled" matrix match the eigenvalues of the true
+ covariance matrix. The "true" eigenvectors can be easily calculated from the eigenvectors of
+ the "scrambled" covariance matrix. */
+ COVAR_SCRAMBLED = 0,
+ /**The output covariance matrix is calculated as:
+ \f[\texttt{scale} \cdot [ \texttt{vects} [0]- \texttt{mean} , \texttt{vects} [1]- \texttt{mean} ,...] \cdot [ \texttt{vects} [0]- \texttt{mean} , \texttt{vects} [1]- \texttt{mean} ,...]^T,\f]
+ covar will be a square matrix of the same size as the total number of elements in each input
+ vector. One and only one of COVAR_SCRAMBLED and COVAR_NORMAL must be specified.*/
+ COVAR_NORMAL = 1,
+ /** If the flag is specified, the function does not calculate mean from
+ the input vectors but, instead, uses the passed mean vector. This is useful if mean has been
+ pre-calculated or known in advance, or if the covariance matrix is calculated by parts. In
+ this case, mean is not a mean vector of the input sub-set of vectors but rather the mean
+ vector of the whole set.*/
+ COVAR_USE_AVG = 2,
+ /** If the flag is specified, the covariance matrix is scaled. In the
+ "normal" mode, scale is 1./nsamples . In the "scrambled" mode, scale is the reciprocal of the
+ total number of elements in each input vector. By default (if the flag is not specified), the
+ covariance matrix is not scaled ( scale=1 ).*/
+ COVAR_SCALE = 4,
+ /** If the flag is
+ specified, all the input vectors are stored as rows of the samples matrix. mean should be a
+ single-row vector in this case.*/
+ COVAR_ROWS = 8,
+ /** If the flag is
+ specified, all the input vectors are stored as columns of the samples matrix. mean should be a
+ single-column vector in this case.*/
+ COVAR_COLS = 16
+};
+
+//! k-Means flags
+enum KmeansFlags {
+ /** Select random initial centers in each attempt.*/
+ KMEANS_RANDOM_CENTERS = 0,
+ /** Use kmeans++ center initialization by Arthur and Vassilvitskii [Arthur2007].*/
+ KMEANS_PP_CENTERS = 2,
+ /** During the first (and possibly the only) attempt, use the
+ user-supplied labels instead of computing them from the initial centers. For the second and
+ further attempts, use the random or semi-random centers. Use one of KMEANS_\*_CENTERS flag
+ to specify the exact method.*/
+ KMEANS_USE_INITIAL_LABELS = 1
+};
+
+//! type of line
+enum LineTypes {
+ FILLED = -1,
+ LINE_4 = 4, //!< 4-connected line
+ LINE_8 = 8, //!< 8-connected line
+ LINE_AA = 16 //!< antialiased line
+};
+
+//! Only a subset of Hershey fonts
+//! <http://sources.isc.org/utils/misc/hershey-font.txt> are supported
+enum HersheyFonts {
+ FONT_HERSHEY_SIMPLEX = 0, //!< normal size sans-serif font
+ FONT_HERSHEY_PLAIN = 1, //!< small size sans-serif font
+ FONT_HERSHEY_DUPLEX = 2, //!< normal size sans-serif font (more complex than FONT_HERSHEY_SIMPLEX)
+ FONT_HERSHEY_COMPLEX = 3, //!< normal size serif font
+ FONT_HERSHEY_TRIPLEX = 4, //!< normal size serif font (more complex than FONT_HERSHEY_COMPLEX)
+ FONT_HERSHEY_COMPLEX_SMALL = 5, //!< smaller version of FONT_HERSHEY_COMPLEX
+ FONT_HERSHEY_SCRIPT_SIMPLEX = 6, //!< hand-writing style font
+ FONT_HERSHEY_SCRIPT_COMPLEX = 7, //!< more complex variant of FONT_HERSHEY_SCRIPT_SIMPLEX
+ FONT_ITALIC = 16 //!< flag for italic font
+};
+
+enum ReduceTypes { REDUCE_SUM = 0, //!< the output is the sum of all rows/columns of the matrix.
+ REDUCE_AVG = 1, //!< the output is the mean vector of all rows/columns of the matrix.
+ REDUCE_MAX = 2, //!< the output is the maximum (column/row-wise) of all rows/columns of the matrix.
+ REDUCE_MIN = 3 //!< the output is the minimum (column/row-wise) of all rows/columns of the matrix.
+ };
+
+
+/** @brief Swaps two matrices
+*/
+CV_EXPORTS void swap(Mat& a, Mat& b);
+/** @overload */
+CV_EXPORTS void swap( UMat& a, UMat& b );
+
+//! @} core
+
+//! @addtogroup core_array
+//! @{
+
+/** @brief Computes the source location of an extrapolated pixel.
+
+The function computes and returns the coordinate of a donor pixel corresponding to the specified
+extrapolated pixel when using the specified extrapolation border mode. For example, if you use
+cv::BORDER_WRAP mode in the horizontal direction, cv::BORDER_REFLECT_101 in the vertical direction and
+want to compute value of the "virtual" pixel Point(-5, 100) in a floating-point image img , it
+looks like:
+@code{.cpp}
+ float val = img.at<float>(borderInterpolate(100, img.rows, cv::BORDER_REFLECT_101),
+ borderInterpolate(-5, img.cols, cv::BORDER_WRAP));
+@endcode
+Normally, the function is not called directly. It is used inside filtering functions and also in
+copyMakeBorder.
+@param p 0-based coordinate of the extrapolated pixel along one of the axes, likely \<0 or \>= len
+@param len Length of the array along the corresponding axis.
+@param borderType Border type, one of the cv::BorderTypes, except for cv::BORDER_TRANSPARENT and
+cv::BORDER_ISOLATED . When borderType==cv::BORDER_CONSTANT , the function always returns -1, regardless
+of p and len.
+
+@sa copyMakeBorder
+*/
+CV_EXPORTS_W int borderInterpolate(int p, int len, int borderType);
+
+/** @brief Forms a border around an image.
+
+The function copies the source image into the middle of the destination image. The areas to the
+left, to the right, above and below the copied source image will be filled with extrapolated
+pixels. This is not what filtering functions based on it do (they extrapolate pixels on-fly), but
+what other more complex functions, including your own, may do to simplify image boundary handling.
+
+The function supports the mode when src is already in the middle of dst . In this case, the
+function does not copy src itself but simply constructs the border, for example:
+
+@code{.cpp}
+ // let border be the same in all directions
+ int border=2;
+ // constructs a larger image to fit both the image and the border
+ Mat gray_buf(rgb.rows + border*2, rgb.cols + border*2, rgb.depth());
+ // select the middle part of it w/o copying data
+ Mat gray(gray_canvas, Rect(border, border, rgb.cols, rgb.rows));
+ // convert image from RGB to grayscale
+ cvtColor(rgb, gray, COLOR_RGB2GRAY);
+ // form a border in-place
+ copyMakeBorder(gray, gray_buf, border, border,
+ border, border, BORDER_REPLICATE);
+ // now do some custom filtering ...
+ ...
+@endcode
+@note When the source image is a part (ROI) of a bigger image, the function will try to use the
+pixels outside of the ROI to form a border. To disable this feature and always do extrapolation, as
+if src was not a ROI, use borderType | BORDER_ISOLATED.
+
+@param src Source image.
+@param dst Destination image of the same type as src and the size Size(src.cols+left+right,
+src.rows+top+bottom) .
+@param top
+@param bottom
+@param left
+@param right Parameter specifying how many pixels in each direction from the source image rectangle
+to extrapolate. For example, top=1, bottom=1, left=1, right=1 mean that 1 pixel-wide border needs
+to be built.
+@param borderType Border type. See borderInterpolate for details.
+@param value Border value if borderType==BORDER_CONSTANT .
+
+@sa borderInterpolate
+*/
+CV_EXPORTS_W void copyMakeBorder(InputArray src, OutputArray dst,
+ int top, int bottom, int left, int right,
+ int borderType, const Scalar& value = Scalar() );
+
+/** @brief Calculates the per-element sum of two arrays or an array and a scalar.
+
+The function add calculates:
+- Sum of two arrays when both input arrays have the same size and the same number of channels:
+\f[\texttt{dst}(I) = \texttt{saturate} ( \texttt{src1}(I) + \texttt{src2}(I)) \quad \texttt{if mask}(I) \ne0\f]
+- Sum of an array and a scalar when src2 is constructed from Scalar or has the same number of
+elements as `src1.channels()`:
+\f[\texttt{dst}(I) = \texttt{saturate} ( \texttt{src1}(I) + \texttt{src2} ) \quad \texttt{if mask}(I) \ne0\f]
+- Sum of a scalar and an array when src1 is constructed from Scalar or has the same number of
+elements as `src2.channels()`:
+\f[\texttt{dst}(I) = \texttt{saturate} ( \texttt{src1} + \texttt{src2}(I) ) \quad \texttt{if mask}(I) \ne0\f]
+where `I` is a multi-dimensional index of array elements. In case of multi-channel arrays, each
+channel is processed independently.
+
+The first function in the list above can be replaced with matrix expressions:
+@code{.cpp}
+ dst = src1 + src2;
+ dst += src1; // equivalent to add(dst, src1, dst);
+@endcode
+The input arrays and the output array can all have the same or different depths. For example, you
+can add a 16-bit unsigned array to a 8-bit signed array and store the sum as a 32-bit
+floating-point array. Depth of the output array is determined by the dtype parameter. In the second
+and third cases above, as well as in the first case, when src1.depth() == src2.depth(), dtype can
+be set to the default -1. In this case, the output array will have the same depth as the input
+array, be it src1, src2 or both.
+@note Saturation is not applied when the output array has the depth CV_32S. You may even get
+result of an incorrect sign in the case of overflow.
+@param src1 first input array or a scalar.
+@param src2 second input array or a scalar.
+@param dst output array that has the same size and number of channels as the input array(s); the
+depth is defined by dtype or src1/src2.
+@param mask optional operation mask - 8-bit single channel array, that specifies elements of the
+output array to be changed.
+@param dtype optional depth of the output array (see the discussion below).
+@sa subtract, addWeighted, scaleAdd, Mat::convertTo
+*/
+CV_EXPORTS_W void add(InputArray src1, InputArray src2, OutputArray dst,
+ InputArray mask = noArray(), int dtype = -1);
+
+/** @brief Calculates the per-element difference between two arrays or array and a scalar.
+
+The function subtract calculates:
+- Difference between two arrays, when both input arrays have the same size and the same number of
+channels:
+ \f[\texttt{dst}(I) = \texttt{saturate} ( \texttt{src1}(I) - \texttt{src2}(I)) \quad \texttt{if mask}(I) \ne0\f]
+- Difference between an array and a scalar, when src2 is constructed from Scalar or has the same
+number of elements as `src1.channels()`:
+ \f[\texttt{dst}(I) = \texttt{saturate} ( \texttt{src1}(I) - \texttt{src2} ) \quad \texttt{if mask}(I) \ne0\f]
+- Difference between a scalar and an array, when src1 is constructed from Scalar or has the same
+number of elements as `src2.channels()`:
+ \f[\texttt{dst}(I) = \texttt{saturate} ( \texttt{src1} - \texttt{src2}(I) ) \quad \texttt{if mask}(I) \ne0\f]
+- The reverse difference between a scalar and an array in the case of `SubRS`:
+ \f[\texttt{dst}(I) = \texttt{saturate} ( \texttt{src2} - \texttt{src1}(I) ) \quad \texttt{if mask}(I) \ne0\f]
+where I is a multi-dimensional index of array elements. In case of multi-channel arrays, each
+channel is processed independently.
+
+The first function in the list above can be replaced with matrix expressions:
+@code{.cpp}
+ dst = src1 - src2;
+ dst -= src1; // equivalent to subtract(dst, src1, dst);
+@endcode
+The input arrays and the output array can all have the same or different depths. For example, you
+can subtract to 8-bit unsigned arrays and store the difference in a 16-bit signed array. Depth of
+the output array is determined by dtype parameter. In the second and third cases above, as well as
+in the first case, when src1.depth() == src2.depth(), dtype can be set to the default -1. In this
+case the output array will have the same depth as the input array, be it src1, src2 or both.
+@note Saturation is not applied when the output array has the depth CV_32S. You may even get
+result of an incorrect sign in the case of overflow.
+@param src1 first input array or a scalar.
+@param src2 second input array or a scalar.
+@param dst output array of the same size and the same number of channels as the input array.
+@param mask optional operation mask; this is an 8-bit single channel array that specifies elements
+of the output array to be changed.
+@param dtype optional depth of the output array
+@sa add, addWeighted, scaleAdd, Mat::convertTo
+ */
+CV_EXPORTS_W void subtract(InputArray src1, InputArray src2, OutputArray dst,
+ InputArray mask = noArray(), int dtype = -1);
+
+
+/** @brief Calculates the per-element scaled product of two arrays.
+
+The function multiply calculates the per-element product of two arrays:
+
+\f[\texttt{dst} (I)= \texttt{saturate} ( \texttt{scale} \cdot \texttt{src1} (I) \cdot \texttt{src2} (I))\f]
+
+There is also a @ref MatrixExpressions -friendly variant of the first function. See Mat::mul .
+
+For a not-per-element matrix product, see gemm .
+
+@note Saturation is not applied when the output array has the depth
+CV_32S. You may even get result of an incorrect sign in the case of
+overflow.
+@param src1 first input array.
+@param src2 second input array of the same size and the same type as src1.
+@param dst output array of the same size and type as src1.
+@param scale optional scale factor.
+@param dtype optional depth of the output array
+@sa add, subtract, divide, scaleAdd, addWeighted, accumulate, accumulateProduct, accumulateSquare,
+Mat::convertTo
+*/
+CV_EXPORTS_W void multiply(InputArray src1, InputArray src2,
+ OutputArray dst, double scale = 1, int dtype = -1);
+
+/** @brief Performs per-element division of two arrays or a scalar by an array.
+
+The function cv::divide divides one array by another:
+\f[\texttt{dst(I) = saturate(src1(I)*scale/src2(I))}\f]
+or a scalar by an array when there is no src1 :
+\f[\texttt{dst(I) = saturate(scale/src2(I))}\f]
+
+When src2(I) is zero, dst(I) will also be zero. Different channels of
+multi-channel arrays are processed independently.
+
+@note Saturation is not applied when the output array has the depth CV_32S. You may even get
+result of an incorrect sign in the case of overflow.
+@param src1 first input array.
+@param src2 second input array of the same size and type as src1.
+@param scale scalar factor.
+@param dst output array of the same size and type as src2.
+@param dtype optional depth of the output array; if -1, dst will have depth src2.depth(), but in
+case of an array-by-array division, you can only pass -1 when src1.depth()==src2.depth().
+@sa multiply, add, subtract
+*/
+CV_EXPORTS_W void divide(InputArray src1, InputArray src2, OutputArray dst,
+ double scale = 1, int dtype = -1);
+
+/** @overload */
+CV_EXPORTS_W void divide(double scale, InputArray src2,
+ OutputArray dst, int dtype = -1);
+
+/** @brief Calculates the sum of a scaled array and another array.
+
+The function scaleAdd is one of the classical primitive linear algebra operations, known as DAXPY
+or SAXPY in [BLAS](http://en.wikipedia.org/wiki/Basic_Linear_Algebra_Subprograms). It calculates
+the sum of a scaled array and another array:
+\f[\texttt{dst} (I)= \texttt{scale} \cdot \texttt{src1} (I) + \texttt{src2} (I)\f]
+The function can also be emulated with a matrix expression, for example:
+@code{.cpp}
+ Mat A(3, 3, CV_64F);
+ ...
+ A.row(0) = A.row(1)*2 + A.row(2);
+@endcode
+@param src1 first input array.
+@param alpha scale factor for the first array.
+@param src2 second input array of the same size and type as src1.
+@param dst output array of the same size and type as src1.
+@sa add, addWeighted, subtract, Mat::dot, Mat::convertTo
+*/
+CV_EXPORTS_W void scaleAdd(InputArray src1, double alpha, InputArray src2, OutputArray dst);
+
+/** @brief Calculates the weighted sum of two arrays.
+
+The function addWeighted calculates the weighted sum of two arrays as follows:
+\f[\texttt{dst} (I)= \texttt{saturate} ( \texttt{src1} (I)* \texttt{alpha} + \texttt{src2} (I)* \texttt{beta} + \texttt{gamma} )\f]
+where I is a multi-dimensional index of array elements. In case of multi-channel arrays, each
+channel is processed independently.
+The function can be replaced with a matrix expression:
+@code{.cpp}
+ dst = src1*alpha + src2*beta + gamma;
+@endcode
+@note Saturation is not applied when the output array has the depth CV_32S. You may even get
+result of an incorrect sign in the case of overflow.
+@param src1 first input array.
+@param alpha weight of the first array elements.
+@param src2 second input array of the same size and channel number as src1.
+@param beta weight of the second array elements.
+@param gamma scalar added to each sum.
+@param dst output array that has the same size and number of channels as the input arrays.
+@param dtype optional depth of the output array; when both input arrays have the same depth, dtype
+can be set to -1, which will be equivalent to src1.depth().
+@sa add, subtract, scaleAdd, Mat::convertTo
+*/
+CV_EXPORTS_W void addWeighted(InputArray src1, double alpha, InputArray src2,
+ double beta, double gamma, OutputArray dst, int dtype = -1);
+
+/** @brief Scales, calculates absolute values, and converts the result to 8-bit.
+
+On each element of the input array, the function convertScaleAbs
+performs three operations sequentially: scaling, taking an absolute
+value, conversion to an unsigned 8-bit type:
+\f[\texttt{dst} (I)= \texttt{saturate\_cast<uchar>} (| \texttt{src} (I)* \texttt{alpha} + \texttt{beta} |)\f]
+In case of multi-channel arrays, the function processes each channel
+independently. When the output is not 8-bit, the operation can be
+emulated by calling the Mat::convertTo method (or by using matrix
+expressions) and then by calculating an absolute value of the result.
+For example:
+@code{.cpp}
+ Mat_<float> A(30,30);
+ randu(A, Scalar(-100), Scalar(100));
+ Mat_<float> B = A*5 + 3;
+ B = abs(B);
+ // Mat_<float> B = abs(A*5+3) will also do the job,
+ // but it will allocate a temporary matrix
+@endcode
+@param src input array.
+@param dst output array.
+@param alpha optional scale factor.
+@param beta optional delta added to the scaled values.
+@sa Mat::convertTo, cv::abs(const Mat&)
+*/
+CV_EXPORTS_W void convertScaleAbs(InputArray src, OutputArray dst,
+ double alpha = 1, double beta = 0);
+
+/** @brief Converts an array to half precision floating number.
+
+This function converts FP32 (single precision floating point) from/to FP16 (half precision floating point). The input array has to have type of CV_32F or
+CV_16S to represent the bit depth. If the input array is neither of them, the function will raise an error.
+The format of half precision floating point is defined in IEEE 754-2008.
+
+@param src input array.
+@param dst output array.
+*/
+CV_EXPORTS_W void convertFp16(InputArray src, OutputArray dst);
+
+/** @brief Performs a look-up table transform of an array.
+
+The function LUT fills the output array with values from the look-up table. Indices of the entries
+are taken from the input array. That is, the function processes each element of src as follows:
+\f[\texttt{dst} (I) \leftarrow \texttt{lut(src(I) + d)}\f]
+where
+\f[d = \fork{0}{if \(\texttt{src}\) has depth \(\texttt{CV_8U}\)}{128}{if \(\texttt{src}\) has depth \(\texttt{CV_8S}\)}\f]
+@param src input array of 8-bit elements.
+@param lut look-up table of 256 elements; in case of multi-channel input array, the table should
+either have a single channel (in this case the same table is used for all channels) or the same
+number of channels as in the input array.
+@param dst output array of the same size and number of channels as src, and the same depth as lut.
+@sa convertScaleAbs, Mat::convertTo
+*/
+CV_EXPORTS_W void LUT(InputArray src, InputArray lut, OutputArray dst);
+
+/** @brief Calculates the sum of array elements.
+
+The function cv::sum calculates and returns the sum of array elements,
+independently for each channel.
+@param src input array that must have from 1 to 4 channels.
+@sa countNonZero, mean, meanStdDev, norm, minMaxLoc, reduce
+*/
+CV_EXPORTS_AS(sumElems) Scalar sum(InputArray src);
+
+/** @brief Counts non-zero array elements.
+
+The function returns the number of non-zero elements in src :
+\f[\sum _{I: \; \texttt{src} (I) \ne0 } 1\f]
+@param src single-channel array.
+@sa mean, meanStdDev, norm, minMaxLoc, calcCovarMatrix
+*/
+CV_EXPORTS_W int countNonZero( InputArray src );
+
+/** @brief Returns the list of locations of non-zero pixels
+
+Given a binary matrix (likely returned from an operation such
+as threshold(), compare(), >, ==, etc, return all of
+the non-zero indices as a cv::Mat or std::vector<cv::Point> (x,y)
+For example:
+@code{.cpp}
+ cv::Mat binaryImage; // input, binary image
+ cv::Mat locations; // output, locations of non-zero pixels
+ cv::findNonZero(binaryImage, locations);
+
+ // access pixel coordinates
+ Point pnt = locations.at<Point>(i);
+@endcode
+or
+@code{.cpp}
+ cv::Mat binaryImage; // input, binary image
+ vector<Point> locations; // output, locations of non-zero pixels
+ cv::findNonZero(binaryImage, locations);
+
+ // access pixel coordinates
+ Point pnt = locations[i];
+@endcode
+@param src single-channel array (type CV_8UC1)
+@param idx the output array, type of cv::Mat or std::vector<Point>, corresponding to non-zero indices in the input
+*/
+CV_EXPORTS_W void findNonZero( InputArray src, OutputArray idx );
+
+/** @brief Calculates an average (mean) of array elements.
+
+The function cv::mean calculates the mean value M of array elements,
+independently for each channel, and return it:
+\f[\begin{array}{l} N = \sum _{I: \; \texttt{mask} (I) \ne 0} 1 \\ M_c = \left ( \sum _{I: \; \texttt{mask} (I) \ne 0}{ \texttt{mtx} (I)_c} \right )/N \end{array}\f]
+When all the mask elements are 0's, the function returns Scalar::all(0)
+@param src input array that should have from 1 to 4 channels so that the result can be stored in
+Scalar_ .
+@param mask optional operation mask.
+@sa countNonZero, meanStdDev, norm, minMaxLoc
+*/
+CV_EXPORTS_W Scalar mean(InputArray src, InputArray mask = noArray());
+
+/** Calculates a mean and standard deviation of array elements.
+
+The function cv::meanStdDev calculates the mean and the standard deviation M
+of array elements independently for each channel and returns it via the
+output parameters:
+\f[\begin{array}{l} N = \sum _{I, \texttt{mask} (I) \ne 0} 1 \\ \texttt{mean} _c = \frac{\sum_{ I: \; \texttt{mask}(I) \ne 0} \texttt{src} (I)_c}{N} \\ \texttt{stddev} _c = \sqrt{\frac{\sum_{ I: \; \texttt{mask}(I) \ne 0} \left ( \texttt{src} (I)_c - \texttt{mean} _c \right )^2}{N}} \end{array}\f]
+When all the mask elements are 0's, the function returns
+mean=stddev=Scalar::all(0).
+@note The calculated standard deviation is only the diagonal of the
+complete normalized covariance matrix. If the full matrix is needed, you
+can reshape the multi-channel array M x N to the single-channel array
+M\*N x mtx.channels() (only possible when the matrix is continuous) and
+then pass the matrix to calcCovarMatrix .
+@param src input array that should have from 1 to 4 channels so that the results can be stored in
+Scalar_ 's.
+@param mean output parameter: calculated mean value.
+@param stddev output parameter: calculateded standard deviation.
+@param mask optional operation mask.
+@sa countNonZero, mean, norm, minMaxLoc, calcCovarMatrix
+*/
+CV_EXPORTS_W void meanStdDev(InputArray src, OutputArray mean, OutputArray stddev,
+ InputArray mask=noArray());
+
+/** @brief Calculates an absolute array norm, an absolute difference norm, or a
+relative difference norm.
+
+The function cv::norm calculates an absolute norm of src1 (when there is no
+src2 ):
+
+\f[norm = \forkthree{\|\texttt{src1}\|_{L_{\infty}} = \max _I | \texttt{src1} (I)|}{if \(\texttt{normType} = \texttt{NORM_INF}\) }
+{ \| \texttt{src1} \| _{L_1} = \sum _I | \texttt{src1} (I)|}{if \(\texttt{normType} = \texttt{NORM_L1}\) }
+{ \| \texttt{src1} \| _{L_2} = \sqrt{\sum_I \texttt{src1}(I)^2} }{if \(\texttt{normType} = \texttt{NORM_L2}\) }\f]
+
+or an absolute or relative difference norm if src2 is there:
+
+\f[norm = \forkthree{\|\texttt{src1}-\texttt{src2}\|_{L_{\infty}} = \max _I | \texttt{src1} (I) - \texttt{src2} (I)|}{if \(\texttt{normType} = \texttt{NORM_INF}\) }
+{ \| \texttt{src1} - \texttt{src2} \| _{L_1} = \sum _I | \texttt{src1} (I) - \texttt{src2} (I)|}{if \(\texttt{normType} = \texttt{NORM_L1}\) }
+{ \| \texttt{src1} - \texttt{src2} \| _{L_2} = \sqrt{\sum_I (\texttt{src1}(I) - \texttt{src2}(I))^2} }{if \(\texttt{normType} = \texttt{NORM_L2}\) }\f]
+
+or
+
+\f[norm = \forkthree{\frac{\|\texttt{src1}-\texttt{src2}\|_{L_{\infty}} }{\|\texttt{src2}\|_{L_{\infty}} }}{if \(\texttt{normType} = \texttt{NORM_RELATIVE_INF}\) }
+{ \frac{\|\texttt{src1}-\texttt{src2}\|_{L_1} }{\|\texttt{src2}\|_{L_1}} }{if \(\texttt{normType} = \texttt{NORM_RELATIVE_L1}\) }
+{ \frac{\|\texttt{src1}-\texttt{src2}\|_{L_2} }{\|\texttt{src2}\|_{L_2}} }{if \(\texttt{normType} = \texttt{NORM_RELATIVE_L2}\) }\f]
+
+The function cv::norm returns the calculated norm.
+
+When the mask parameter is specified and it is not empty, the norm is
+calculated only over the region specified by the mask.
+
+A multi-channel input arrays are treated as a single-channel, that is,
+the results for all channels are combined.
+
+@param src1 first input array.
+@param normType type of the norm (see cv::NormTypes).
+@param mask optional operation mask; it must have the same size as src1 and CV_8UC1 type.
+*/
+CV_EXPORTS_W double norm(InputArray src1, int normType = NORM_L2, InputArray mask = noArray());
+
+/** @overload
+@param src1 first input array.
+@param src2 second input array of the same size and the same type as src1.
+@param normType type of the norm (cv::NormTypes).
+@param mask optional operation mask; it must have the same size as src1 and CV_8UC1 type.
+*/
+CV_EXPORTS_W double norm(InputArray src1, InputArray src2,
+ int normType = NORM_L2, InputArray mask = noArray());
+/** @overload
+@param src first input array.
+@param normType type of the norm (see cv::NormTypes).
+*/
+CV_EXPORTS double norm( const SparseMat& src, int normType );
+
+/** @brief computes PSNR image/video quality metric
+
+see http://en.wikipedia.org/wiki/Peak_signal-to-noise_ratio for details
+@todo document
+ */
+CV_EXPORTS_W double PSNR(InputArray src1, InputArray src2);
+
+/** @brief naive nearest neighbor finder
+
+see http://en.wikipedia.org/wiki/Nearest_neighbor_search
+@todo document
+ */
+CV_EXPORTS_W void batchDistance(InputArray src1, InputArray src2,
+ OutputArray dist, int dtype, OutputArray nidx,
+ int normType = NORM_L2, int K = 0,
+ InputArray mask = noArray(), int update = 0,
+ bool crosscheck = false);
+
+/** @brief Normalizes the norm or value range of an array.
+
+The function cv::normalize normalizes scale and shift the input array elements so that
+\f[\| \texttt{dst} \| _{L_p}= \texttt{alpha}\f]
+(where p=Inf, 1 or 2) when normType=NORM_INF, NORM_L1, or NORM_L2, respectively; or so that
+\f[\min _I \texttt{dst} (I)= \texttt{alpha} , \, \, \max _I \texttt{dst} (I)= \texttt{beta}\f]
+
+when normType=NORM_MINMAX (for dense arrays only). The optional mask specifies a sub-array to be
+normalized. This means that the norm or min-n-max are calculated over the sub-array, and then this
+sub-array is modified to be normalized. If you want to only use the mask to calculate the norm or
+min-max but modify the whole array, you can use norm and Mat::convertTo.
+
+In case of sparse matrices, only the non-zero values are analyzed and transformed. Because of this,
+the range transformation for sparse matrices is not allowed since it can shift the zero level.
+
+Possible usage with some positive example data:
+@code{.cpp}
+ vector<double> positiveData = { 2.0, 8.0, 10.0 };
+ vector<double> normalizedData_l1, normalizedData_l2, normalizedData_inf, normalizedData_minmax;
+
+ // Norm to probability (total count)
+ // sum(numbers) = 20.0
+ // 2.0 0.1 (2.0/20.0)
+ // 8.0 0.4 (8.0/20.0)
+ // 10.0 0.5 (10.0/20.0)
+ normalize(positiveData, normalizedData_l1, 1.0, 0.0, NORM_L1);
+
+ // Norm to unit vector: ||positiveData|| = 1.0
+ // 2.0 0.15
+ // 8.0 0.62
+ // 10.0 0.77
+ normalize(positiveData, normalizedData_l2, 1.0, 0.0, NORM_L2);
+
+ // Norm to max element
+ // 2.0 0.2 (2.0/10.0)
+ // 8.0 0.8 (8.0/10.0)
+ // 10.0 1.0 (10.0/10.0)
+ normalize(positiveData, normalizedData_inf, 1.0, 0.0, NORM_INF);
+
+ // Norm to range [0.0;1.0]
+ // 2.0 0.0 (shift to left border)
+ // 8.0 0.75 (6.0/8.0)
+ // 10.0 1.0 (shift to right border)
+ normalize(positiveData, normalizedData_minmax, 1.0, 0.0, NORM_MINMAX);
+@endcode
+
+@param src input array.
+@param dst output array of the same size as src .
+@param alpha norm value to normalize to or the lower range boundary in case of the range
+normalization.
+@param beta upper range boundary in case of the range normalization; it is not used for the norm
+normalization.
+@param norm_type normalization type (see cv::NormTypes).
+@param dtype when negative, the output array has the same type as src; otherwise, it has the same
+number of channels as src and the depth =CV_MAT_DEPTH(dtype).
+@param mask optional operation mask.
+@sa norm, Mat::convertTo, SparseMat::convertTo
+*/
+CV_EXPORTS_W void normalize( InputArray src, InputOutputArray dst, double alpha = 1, double beta = 0,
+ int norm_type = NORM_L2, int dtype = -1, InputArray mask = noArray());
+
+/** @overload
+@param src input array.
+@param dst output array of the same size as src .
+@param alpha norm value to normalize to or the lower range boundary in case of the range
+normalization.
+@param normType normalization type (see cv::NormTypes).
+*/
+CV_EXPORTS void normalize( const SparseMat& src, SparseMat& dst, double alpha, int normType );
+
+/** @brief Finds the global minimum and maximum in an array.
+
+The function cv::minMaxLoc finds the minimum and maximum element values and their positions. The
+extremums are searched across the whole array or, if mask is not an empty array, in the specified
+array region.
+
+The function do not work with multi-channel arrays. If you need to find minimum or maximum
+elements across all the channels, use Mat::reshape first to reinterpret the array as
+single-channel. Or you may extract the particular channel using either extractImageCOI , or
+mixChannels , or split .
+@param src input single-channel array.
+@param minVal pointer to the returned minimum value; NULL is used if not required.
+@param maxVal pointer to the returned maximum value; NULL is used if not required.
+@param minLoc pointer to the returned minimum location (in 2D case); NULL is used if not required.
+@param maxLoc pointer to the returned maximum location (in 2D case); NULL is used if not required.
+@param mask optional mask used to select a sub-array.
+@sa max, min, compare, inRange, extractImageCOI, mixChannels, split, Mat::reshape
+*/
+CV_EXPORTS_W void minMaxLoc(InputArray src, CV_OUT double* minVal,
+ CV_OUT double* maxVal = 0, CV_OUT Point* minLoc = 0,
+ CV_OUT Point* maxLoc = 0, InputArray mask = noArray());
+
+
+/** @brief Finds the global minimum and maximum in an array
+
+The function cv::minMaxIdx finds the minimum and maximum element values and their positions. The
+extremums are searched across the whole array or, if mask is not an empty array, in the specified
+array region. The function does not work with multi-channel arrays. If you need to find minimum or
+maximum elements across all the channels, use Mat::reshape first to reinterpret the array as
+single-channel. Or you may extract the particular channel using either extractImageCOI , or
+mixChannels , or split . In case of a sparse matrix, the minimum is found among non-zero elements
+only.
+@note When minIdx is not NULL, it must have at least 2 elements (as well as maxIdx), even if src is
+a single-row or single-column matrix. In OpenCV (following MATLAB) each array has at least 2
+dimensions, i.e. single-column matrix is Mx1 matrix (and therefore minIdx/maxIdx will be
+(i1,0)/(i2,0)) and single-row matrix is 1xN matrix (and therefore minIdx/maxIdx will be
+(0,j1)/(0,j2)).
+@param src input single-channel array.
+@param minVal pointer to the returned minimum value; NULL is used if not required.
+@param maxVal pointer to the returned maximum value; NULL is used if not required.
+@param minIdx pointer to the returned minimum location (in nD case); NULL is used if not required;
+Otherwise, it must point to an array of src.dims elements, the coordinates of the minimum element
+in each dimension are stored there sequentially.
+@param maxIdx pointer to the returned maximum location (in nD case). NULL is used if not required.
+@param mask specified array region
+*/
+CV_EXPORTS void minMaxIdx(InputArray src, double* minVal, double* maxVal = 0,
+ int* minIdx = 0, int* maxIdx = 0, InputArray mask = noArray());
+
+/** @overload
+@param a input single-channel array.
+@param minVal pointer to the returned minimum value; NULL is used if not required.
+@param maxVal pointer to the returned maximum value; NULL is used if not required.
+@param minIdx pointer to the returned minimum location (in nD case); NULL is used if not required;
+Otherwise, it must point to an array of src.dims elements, the coordinates of the minimum element
+in each dimension are stored there sequentially.
+@param maxIdx pointer to the returned maximum location (in nD case). NULL is used if not required.
+*/
+CV_EXPORTS void minMaxLoc(const SparseMat& a, double* minVal,
+ double* maxVal, int* minIdx = 0, int* maxIdx = 0);
+
+/** @brief Reduces a matrix to a vector.
+
+The function cv::reduce reduces the matrix to a vector by treating the matrix rows/columns as a set of
+1D vectors and performing the specified operation on the vectors until a single row/column is
+obtained. For example, the function can be used to compute horizontal and vertical projections of a
+raster image. In case of REDUCE_MAX and REDUCE_MIN , the output image should have the same type as the source one.
+In case of REDUCE_SUM and REDUCE_AVG , the output may have a larger element bit-depth to preserve accuracy.
+And multi-channel arrays are also supported in these two reduction modes.
+@param src input 2D matrix.
+@param dst output vector. Its size and type is defined by dim and dtype parameters.
+@param dim dimension index along which the matrix is reduced. 0 means that the matrix is reduced to
+a single row. 1 means that the matrix is reduced to a single column.
+@param rtype reduction operation that could be one of cv::ReduceTypes
+@param dtype when negative, the output vector will have the same type as the input matrix,
+otherwise, its type will be CV_MAKE_TYPE(CV_MAT_DEPTH(dtype), src.channels()).
+@sa repeat
+*/
+CV_EXPORTS_W void reduce(InputArray src, OutputArray dst, int dim, int rtype, int dtype = -1);
+
+/** @brief Creates one multi-channel array out of several single-channel ones.
+
+The function cv::merge merges several arrays to make a single multi-channel array. That is, each
+element of the output array will be a concatenation of the elements of the input arrays, where
+elements of i-th input array are treated as mv[i].channels()-element vectors.
+
+The function cv::split does the reverse operation. If you need to shuffle channels in some other
+advanced way, use cv::mixChannels.
+@param mv input array of matrices to be merged; all the matrices in mv must have the same
+size and the same depth.
+@param count number of input matrices when mv is a plain C array; it must be greater than zero.
+@param dst output array of the same size and the same depth as mv[0]; The number of channels will
+be equal to the parameter count.
+@sa mixChannels, split, Mat::reshape
+*/
+CV_EXPORTS void merge(const Mat* mv, size_t count, OutputArray dst);
+
+/** @overload
+@param mv input vector of matrices to be merged; all the matrices in mv must have the same
+size and the same depth.
+@param dst output array of the same size and the same depth as mv[0]; The number of channels will
+be the total number of channels in the matrix array.
+ */
+CV_EXPORTS_W void merge(InputArrayOfArrays mv, OutputArray dst);
+
+/** @brief Divides a multi-channel array into several single-channel arrays.
+
+The function cv::split splits a multi-channel array into separate single-channel arrays:
+\f[\texttt{mv} [c](I) = \texttt{src} (I)_c\f]
+If you need to extract a single channel or do some other sophisticated channel permutation, use
+mixChannels .
+@param src input multi-channel array.
+@param mvbegin output array; the number of arrays must match src.channels(); the arrays themselves are
+reallocated, if needed.
+@sa merge, mixChannels, cvtColor
+*/
+CV_EXPORTS void split(const Mat& src, Mat* mvbegin);
+
+/** @overload
+@param m input multi-channel array.
+@param mv output vector of arrays; the arrays themselves are reallocated, if needed.
+*/
+CV_EXPORTS_W void split(InputArray m, OutputArrayOfArrays mv);
+
+/** @brief Copies specified channels from input arrays to the specified channels of
+output arrays.
+
+The function cv::mixChannels provides an advanced mechanism for shuffling image channels.
+
+cv::split,cv::merge,cv::extractChannel,cv::insertChannel and some forms of cv::cvtColor are partial cases of cv::mixChannels.
+
+In the example below, the code splits a 4-channel BGRA image into a 3-channel BGR (with B and R
+channels swapped) and a separate alpha-channel image:
+@code{.cpp}
+ Mat bgra( 100, 100, CV_8UC4, Scalar(255,0,0,255) );
+ Mat bgr( bgra.rows, bgra.cols, CV_8UC3 );
+ Mat alpha( bgra.rows, bgra.cols, CV_8UC1 );
+
+ // forming an array of matrices is a quite efficient operation,
+ // because the matrix data is not copied, only the headers
+ Mat out[] = { bgr, alpha };
+ // bgra[0] -> bgr[2], bgra[1] -> bgr[1],
+ // bgra[2] -> bgr[0], bgra[3] -> alpha[0]
+ int from_to[] = { 0,2, 1,1, 2,0, 3,3 };
+ mixChannels( &bgra, 1, out, 2, from_to, 4 );
+@endcode
+@note Unlike many other new-style C++ functions in OpenCV (see the introduction section and
+Mat::create ), cv::mixChannels requires the output arrays to be pre-allocated before calling the
+function.
+@param src input array or vector of matrices; all of the matrices must have the same size and the
+same depth.
+@param nsrcs number of matrices in `src`.
+@param dst output array or vector of matrices; all the matrices **must be allocated**; their size and
+depth must be the same as in `src[0]`.
+@param ndsts number of matrices in `dst`.
+@param fromTo array of index pairs specifying which channels are copied and where; fromTo[k\*2] is
+a 0-based index of the input channel in src, fromTo[k\*2+1] is an index of the output channel in
+dst; the continuous channel numbering is used: the first input image channels are indexed from 0 to
+src[0].channels()-1, the second input image channels are indexed from src[0].channels() to
+src[0].channels() + src[1].channels()-1, and so on, the same scheme is used for the output image
+channels; as a special case, when fromTo[k\*2] is negative, the corresponding output channel is
+filled with zero .
+@param npairs number of index pairs in `fromTo`.
+@sa split, merge, extractChannel, insertChannel, cvtColor
+*/
+CV_EXPORTS void mixChannels(const Mat* src, size_t nsrcs, Mat* dst, size_t ndsts,
+ const int* fromTo, size_t npairs);
+
+/** @overload
+@param src input array or vector of matrices; all of the matrices must have the same size and the
+same depth.
+@param dst output array or vector of matrices; all the matrices **must be allocated**; their size and
+depth must be the same as in src[0].
+@param fromTo array of index pairs specifying which channels are copied and where; fromTo[k\*2] is
+a 0-based index of the input channel in src, fromTo[k\*2+1] is an index of the output channel in
+dst; the continuous channel numbering is used: the first input image channels are indexed from 0 to
+src[0].channels()-1, the second input image channels are indexed from src[0].channels() to
+src[0].channels() + src[1].channels()-1, and so on, the same scheme is used for the output image
+channels; as a special case, when fromTo[k\*2] is negative, the corresponding output channel is
+filled with zero .
+@param npairs number of index pairs in fromTo.
+*/
+CV_EXPORTS void mixChannels(InputArrayOfArrays src, InputOutputArrayOfArrays dst,
+ const int* fromTo, size_t npairs);
+
+/** @overload
+@param src input array or vector of matrices; all of the matrices must have the same size and the
+same depth.
+@param dst output array or vector of matrices; all the matrices **must be allocated**; their size and
+depth must be the same as in src[0].
+@param fromTo array of index pairs specifying which channels are copied and where; fromTo[k\*2] is
+a 0-based index of the input channel in src, fromTo[k\*2+1] is an index of the output channel in
+dst; the continuous channel numbering is used: the first input image channels are indexed from 0 to
+src[0].channels()-1, the second input image channels are indexed from src[0].channels() to
+src[0].channels() + src[1].channels()-1, and so on, the same scheme is used for the output image
+channels; as a special case, when fromTo[k\*2] is negative, the corresponding output channel is
+filled with zero .
+*/
+CV_EXPORTS_W void mixChannels(InputArrayOfArrays src, InputOutputArrayOfArrays dst,
+ const std::vector<int>& fromTo);
+
+/** @brief Extracts a single channel from src (coi is 0-based index)
+@param src input array
+@param dst output array
+@param coi index of channel to extract
+@sa mixChannels, split
+*/
+CV_EXPORTS_W void extractChannel(InputArray src, OutputArray dst, int coi);
+
+/** @brief Inserts a single channel to dst (coi is 0-based index)
+@param src input array
+@param dst output array
+@param coi index of channel for insertion
+@sa mixChannels, merge
+*/
+CV_EXPORTS_W void insertChannel(InputArray src, InputOutputArray dst, int coi);
+
+/** @brief Flips a 2D array around vertical, horizontal, or both axes.
+
+The function cv::flip flips the array in one of three different ways (row
+and column indices are 0-based):
+\f[\texttt{dst} _{ij} =
+\left\{
+\begin{array}{l l}
+\texttt{src} _{\texttt{src.rows}-i-1,j} & if\; \texttt{flipCode} = 0 \\
+\texttt{src} _{i, \texttt{src.cols} -j-1} & if\; \texttt{flipCode} > 0 \\
+\texttt{src} _{ \texttt{src.rows} -i-1, \texttt{src.cols} -j-1} & if\; \texttt{flipCode} < 0 \\
+\end{array}
+\right.\f]
+The example scenarios of using the function are the following:
+* Vertical flipping of the image (flipCode == 0) to switch between
+ top-left and bottom-left image origin. This is a typical operation
+ in video processing on Microsoft Windows\* OS.
+* Horizontal flipping of the image with the subsequent horizontal
+ shift and absolute difference calculation to check for a
+ vertical-axis symmetry (flipCode \> 0).
+* Simultaneous horizontal and vertical flipping of the image with
+ the subsequent shift and absolute difference calculation to check
+ for a central symmetry (flipCode \< 0).
+* Reversing the order of point arrays (flipCode \> 0 or
+ flipCode == 0).
+@param src input array.
+@param dst output array of the same size and type as src.
+@param flipCode a flag to specify how to flip the array; 0 means
+flipping around the x-axis and positive value (for example, 1) means
+flipping around y-axis. Negative value (for example, -1) means flipping
+around both axes.
+@sa transpose , repeat , completeSymm
+*/
+CV_EXPORTS_W void flip(InputArray src, OutputArray dst, int flipCode);
+
+enum RotateFlags {
+ ROTATE_90_CLOCKWISE = 0, //Rotate 90 degrees clockwise
+ ROTATE_180 = 1, //Rotate 180 degrees clockwise
+ ROTATE_90_COUNTERCLOCKWISE = 2, //Rotate 270 degrees clockwise
+};
+/** @brief Rotates a 2D array in multiples of 90 degrees.
+The function rotate rotates the array in one of three different ways:
+* Rotate by 90 degrees clockwise (rotateCode = ROTATE_90).
+* Rotate by 180 degrees clockwise (rotateCode = ROTATE_180).
+* Rotate by 270 degrees clockwise (rotateCode = ROTATE_270).
+@param src input array.
+@param dst output array of the same type as src. The size is the same with ROTATE_180,
+and the rows and cols are switched for ROTATE_90 and ROTATE_270.
+@param rotateCode an enum to specify how to rotate the array; see the enum RotateFlags
+@sa transpose , repeat , completeSymm, flip, RotateFlags
+*/
+CV_EXPORTS_W void rotate(InputArray src, OutputArray dst, int rotateCode);
+
+/** @brief Fills the output array with repeated copies of the input array.
+
+The function cv::repeat duplicates the input array one or more times along each of the two axes:
+\f[\texttt{dst} _{ij}= \texttt{src} _{i\mod src.rows, \; j\mod src.cols }\f]
+The second variant of the function is more convenient to use with @ref MatrixExpressions.
+@param src input array to replicate.
+@param ny Flag to specify how many times the `src` is repeated along the
+vertical axis.
+@param nx Flag to specify how many times the `src` is repeated along the
+horizontal axis.
+@param dst output array of the same type as `src`.
+@sa cv::reduce
+*/
+CV_EXPORTS_W void repeat(InputArray src, int ny, int nx, OutputArray dst);
+
+/** @overload
+@param src input array to replicate.
+@param ny Flag to specify how many times the `src` is repeated along the
+vertical axis.
+@param nx Flag to specify how many times the `src` is repeated along the
+horizontal axis.
+ */
+CV_EXPORTS Mat repeat(const Mat& src, int ny, int nx);
+
+/** @brief Applies horizontal concatenation to given matrices.
+
+The function horizontally concatenates two or more cv::Mat matrices (with the same number of rows).
+@code{.cpp}
+ cv::Mat matArray[] = { cv::Mat(4, 1, CV_8UC1, cv::Scalar(1)),
+ cv::Mat(4, 1, CV_8UC1, cv::Scalar(2)),
+ cv::Mat(4, 1, CV_8UC1, cv::Scalar(3)),};
+
+ cv::Mat out;
+ cv::hconcat( matArray, 3, out );
+ //out:
+ //[1, 2, 3;
+ // 1, 2, 3;
+ // 1, 2, 3;
+ // 1, 2, 3]
+@endcode
+@param src input array or vector of matrices. all of the matrices must have the same number of rows and the same depth.
+@param nsrc number of matrices in src.
+@param dst output array. It has the same number of rows and depth as the src, and the sum of cols of the src.
+@sa cv::vconcat(const Mat*, size_t, OutputArray), @sa cv::vconcat(InputArrayOfArrays, OutputArray) and @sa cv::vconcat(InputArray, InputArray, OutputArray)
+*/
+CV_EXPORTS void hconcat(const Mat* src, size_t nsrc, OutputArray dst);
+/** @overload
+ @code{.cpp}
+ cv::Mat_<float> A = (cv::Mat_<float>(3, 2) << 1, 4,
+ 2, 5,
+ 3, 6);
+ cv::Mat_<float> B = (cv::Mat_<float>(3, 2) << 7, 10,
+ 8, 11,
+ 9, 12);
+
+ cv::Mat C;
+ cv::hconcat(A, B, C);
+ //C:
+ //[1, 4, 7, 10;
+ // 2, 5, 8, 11;
+ // 3, 6, 9, 12]
+ @endcode
+ @param src1 first input array to be considered for horizontal concatenation.
+ @param src2 second input array to be considered for horizontal concatenation.
+ @param dst output array. It has the same number of rows and depth as the src1 and src2, and the sum of cols of the src1 and src2.
+ */
+CV_EXPORTS void hconcat(InputArray src1, InputArray src2, OutputArray dst);
+/** @overload
+ @code{.cpp}
+ std::vector<cv::Mat> matrices = { cv::Mat(4, 1, CV_8UC1, cv::Scalar(1)),
+ cv::Mat(4, 1, CV_8UC1, cv::Scalar(2)),
+ cv::Mat(4, 1, CV_8UC1, cv::Scalar(3)),};
+
+ cv::Mat out;
+ cv::hconcat( matrices, out );
+ //out:
+ //[1, 2, 3;
+ // 1, 2, 3;
+ // 1, 2, 3;
+ // 1, 2, 3]
+ @endcode
+ @param src input array or vector of matrices. all of the matrices must have the same number of rows and the same depth.
+ @param dst output array. It has the same number of rows and depth as the src, and the sum of cols of the src.
+same depth.
+ */
+CV_EXPORTS_W void hconcat(InputArrayOfArrays src, OutputArray dst);
+
+/** @brief Applies vertical concatenation to given matrices.
+
+The function vertically concatenates two or more cv::Mat matrices (with the same number of cols).
+@code{.cpp}
+ cv::Mat matArray[] = { cv::Mat(1, 4, CV_8UC1, cv::Scalar(1)),
+ cv::Mat(1, 4, CV_8UC1, cv::Scalar(2)),
+ cv::Mat(1, 4, CV_8UC1, cv::Scalar(3)),};
+
+ cv::Mat out;
+ cv::vconcat( matArray, 3, out );
+ //out:
+ //[1, 1, 1, 1;
+ // 2, 2, 2, 2;
+ // 3, 3, 3, 3]
+@endcode
+@param src input array or vector of matrices. all of the matrices must have the same number of cols and the same depth.
+@param nsrc number of matrices in src.
+@param dst output array. It has the same number of cols and depth as the src, and the sum of rows of the src.
+@sa cv::hconcat(const Mat*, size_t, OutputArray), @sa cv::hconcat(InputArrayOfArrays, OutputArray) and @sa cv::hconcat(InputArray, InputArray, OutputArray)
+*/
+CV_EXPORTS void vconcat(const Mat* src, size_t nsrc, OutputArray dst);
+/** @overload
+ @code{.cpp}
+ cv::Mat_<float> A = (cv::Mat_<float>(3, 2) << 1, 7,
+ 2, 8,
+ 3, 9);
+ cv::Mat_<float> B = (cv::Mat_<float>(3, 2) << 4, 10,
+ 5, 11,
+ 6, 12);
+
+ cv::Mat C;
+ cv::vconcat(A, B, C);
+ //C:
+ //[1, 7;
+ // 2, 8;
+ // 3, 9;
+ // 4, 10;
+ // 5, 11;
+ // 6, 12]
+ @endcode
+ @param src1 first input array to be considered for vertical concatenation.
+ @param src2 second input array to be considered for vertical concatenation.
+ @param dst output array. It has the same number of cols and depth as the src1 and src2, and the sum of rows of the src1 and src2.
+ */
+CV_EXPORTS void vconcat(InputArray src1, InputArray src2, OutputArray dst);
+/** @overload
+ @code{.cpp}
+ std::vector<cv::Mat> matrices = { cv::Mat(1, 4, CV_8UC1, cv::Scalar(1)),
+ cv::Mat(1, 4, CV_8UC1, cv::Scalar(2)),
+ cv::Mat(1, 4, CV_8UC1, cv::Scalar(3)),};
+
+ cv::Mat out;
+ cv::vconcat( matrices, out );
+ //out:
+ //[1, 1, 1, 1;
+ // 2, 2, 2, 2;
+ // 3, 3, 3, 3]
+ @endcode
+ @param src input array or vector of matrices. all of the matrices must have the same number of cols and the same depth
+ @param dst output array. It has the same number of cols and depth as the src, and the sum of rows of the src.
+same depth.
+ */
+CV_EXPORTS_W void vconcat(InputArrayOfArrays src, OutputArray dst);
+
+/** @brief computes bitwise conjunction of the two arrays (dst = src1 & src2)
+Calculates the per-element bit-wise conjunction of two arrays or an
+array and a scalar.
+
+The function cv::bitwise_and calculates the per-element bit-wise logical conjunction for:
+* Two arrays when src1 and src2 have the same size:
+ \f[\texttt{dst} (I) = \texttt{src1} (I) \wedge \texttt{src2} (I) \quad \texttt{if mask} (I) \ne0\f]
+* An array and a scalar when src2 is constructed from Scalar or has
+ the same number of elements as `src1.channels()`:
+ \f[\texttt{dst} (I) = \texttt{src1} (I) \wedge \texttt{src2} \quad \texttt{if mask} (I) \ne0\f]
+* A scalar and an array when src1 is constructed from Scalar or has
+ the same number of elements as `src2.channels()`:
+ \f[\texttt{dst} (I) = \texttt{src1} \wedge \texttt{src2} (I) \quad \texttt{if mask} (I) \ne0\f]
+In case of floating-point arrays, their machine-specific bit
+representations (usually IEEE754-compliant) are used for the operation.
+In case of multi-channel arrays, each channel is processed
+independently. In the second and third cases above, the scalar is first
+converted to the array type.
+@param src1 first input array or a scalar.
+@param src2 second input array or a scalar.
+@param dst output array that has the same size and type as the input
+arrays.
+@param mask optional operation mask, 8-bit single channel array, that
+specifies elements of the output array to be changed.
+*/
+CV_EXPORTS_W void bitwise_and(InputArray src1, InputArray src2,
+ OutputArray dst, InputArray mask = noArray());
+
+/** @brief Calculates the per-element bit-wise disjunction of two arrays or an
+array and a scalar.
+
+The function cv::bitwise_or calculates the per-element bit-wise logical disjunction for:
+* Two arrays when src1 and src2 have the same size:
+ \f[\texttt{dst} (I) = \texttt{src1} (I) \vee \texttt{src2} (I) \quad \texttt{if mask} (I) \ne0\f]
+* An array and a scalar when src2 is constructed from Scalar or has
+ the same number of elements as `src1.channels()`:
+ \f[\texttt{dst} (I) = \texttt{src1} (I) \vee \texttt{src2} \quad \texttt{if mask} (I) \ne0\f]
+* A scalar and an array when src1 is constructed from Scalar or has
+ the same number of elements as `src2.channels()`:
+ \f[\texttt{dst} (I) = \texttt{src1} \vee \texttt{src2} (I) \quad \texttt{if mask} (I) \ne0\f]
+In case of floating-point arrays, their machine-specific bit
+representations (usually IEEE754-compliant) are used for the operation.
+In case of multi-channel arrays, each channel is processed
+independently. In the second and third cases above, the scalar is first
+converted to the array type.
+@param src1 first input array or a scalar.
+@param src2 second input array or a scalar.
+@param dst output array that has the same size and type as the input
+arrays.
+@param mask optional operation mask, 8-bit single channel array, that
+specifies elements of the output array to be changed.
+*/
+CV_EXPORTS_W void bitwise_or(InputArray src1, InputArray src2,
+ OutputArray dst, InputArray mask = noArray());
+
+/** @brief Calculates the per-element bit-wise "exclusive or" operation on two
+arrays or an array and a scalar.
+
+The function cv::bitwise_xor calculates the per-element bit-wise logical "exclusive-or"
+operation for:
+* Two arrays when src1 and src2 have the same size:
+ \f[\texttt{dst} (I) = \texttt{src1} (I) \oplus \texttt{src2} (I) \quad \texttt{if mask} (I) \ne0\f]
+* An array and a scalar when src2 is constructed from Scalar or has
+ the same number of elements as `src1.channels()`:
+ \f[\texttt{dst} (I) = \texttt{src1} (I) \oplus \texttt{src2} \quad \texttt{if mask} (I) \ne0\f]
+* A scalar and an array when src1 is constructed from Scalar or has
+ the same number of elements as `src2.channels()`:
+ \f[\texttt{dst} (I) = \texttt{src1} \oplus \texttt{src2} (I) \quad \texttt{if mask} (I) \ne0\f]
+In case of floating-point arrays, their machine-specific bit
+representations (usually IEEE754-compliant) are used for the operation.
+In case of multi-channel arrays, each channel is processed
+independently. In the 2nd and 3rd cases above, the scalar is first
+converted to the array type.
+@param src1 first input array or a scalar.
+@param src2 second input array or a scalar.
+@param dst output array that has the same size and type as the input
+arrays.
+@param mask optional operation mask, 8-bit single channel array, that
+specifies elements of the output array to be changed.
+*/
+CV_EXPORTS_W void bitwise_xor(InputArray src1, InputArray src2,
+ OutputArray dst, InputArray mask = noArray());
+
+/** @brief Inverts every bit of an array.
+
+The function cv::bitwise_not calculates per-element bit-wise inversion of the input
+array:
+\f[\texttt{dst} (I) = \neg \texttt{src} (I)\f]
+In case of a floating-point input array, its machine-specific bit
+representation (usually IEEE754-compliant) is used for the operation. In
+case of multi-channel arrays, each channel is processed independently.
+@param src input array.
+@param dst output array that has the same size and type as the input
+array.
+@param mask optional operation mask, 8-bit single channel array, that
+specifies elements of the output array to be changed.
+*/
+CV_EXPORTS_W void bitwise_not(InputArray src, OutputArray dst,
+ InputArray mask = noArray());
+
+/** @brief Calculates the per-element absolute difference between two arrays or between an array and a scalar.
+
+The function cv::absdiff calculates:
+* Absolute difference between two arrays when they have the same
+ size and type:
+ \f[\texttt{dst}(I) = \texttt{saturate} (| \texttt{src1}(I) - \texttt{src2}(I)|)\f]
+* Absolute difference between an array and a scalar when the second
+ array is constructed from Scalar or has as many elements as the
+ number of channels in `src1`:
+ \f[\texttt{dst}(I) = \texttt{saturate} (| \texttt{src1}(I) - \texttt{src2} |)\f]
+* Absolute difference between a scalar and an array when the first
+ array is constructed from Scalar or has as many elements as the
+ number of channels in `src2`:
+ \f[\texttt{dst}(I) = \texttt{saturate} (| \texttt{src1} - \texttt{src2}(I) |)\f]
+ where I is a multi-dimensional index of array elements. In case of
+ multi-channel arrays, each channel is processed independently.
+@note Saturation is not applied when the arrays have the depth CV_32S.
+You may even get a negative value in the case of overflow.
+@param src1 first input array or a scalar.
+@param src2 second input array or a scalar.
+@param dst output array that has the same size and type as input arrays.
+@sa cv::abs(const Mat&)
+*/
+CV_EXPORTS_W void absdiff(InputArray src1, InputArray src2, OutputArray dst);
+
+/** @brief Checks if array elements lie between the elements of two other arrays.
+
+The function checks the range as follows:
+- For every element of a single-channel input array:
+ \f[\texttt{dst} (I)= \texttt{lowerb} (I)_0 \leq \texttt{src} (I)_0 \leq \texttt{upperb} (I)_0\f]
+- For two-channel arrays:
+ \f[\texttt{dst} (I)= \texttt{lowerb} (I)_0 \leq \texttt{src} (I)_0 \leq \texttt{upperb} (I)_0 \land \texttt{lowerb} (I)_1 \leq \texttt{src} (I)_1 \leq \texttt{upperb} (I)_1\f]
+- and so forth.
+
+That is, dst (I) is set to 255 (all 1 -bits) if src (I) is within the
+specified 1D, 2D, 3D, ... box and 0 otherwise.
+
+When the lower and/or upper boundary parameters are scalars, the indexes
+(I) at lowerb and upperb in the above formulas should be omitted.
+@param src first input array.
+@param lowerb inclusive lower boundary array or a scalar.
+@param upperb inclusive upper boundary array or a scalar.
+@param dst output array of the same size as src and CV_8U type.
+*/
+CV_EXPORTS_W void inRange(InputArray src, InputArray lowerb,
+ InputArray upperb, OutputArray dst);
+
+/** @brief Performs the per-element comparison of two arrays or an array and scalar value.
+
+The function compares:
+* Elements of two arrays when src1 and src2 have the same size:
+ \f[\texttt{dst} (I) = \texttt{src1} (I) \,\texttt{cmpop}\, \texttt{src2} (I)\f]
+* Elements of src1 with a scalar src2 when src2 is constructed from
+ Scalar or has a single element:
+ \f[\texttt{dst} (I) = \texttt{src1}(I) \,\texttt{cmpop}\, \texttt{src2}\f]
+* src1 with elements of src2 when src1 is constructed from Scalar or
+ has a single element:
+ \f[\texttt{dst} (I) = \texttt{src1} \,\texttt{cmpop}\, \texttt{src2} (I)\f]
+When the comparison result is true, the corresponding element of output
+array is set to 255. The comparison operations can be replaced with the
+equivalent matrix expressions:
+@code{.cpp}
+ Mat dst1 = src1 >= src2;
+ Mat dst2 = src1 < 8;
+ ...
+@endcode
+@param src1 first input array or a scalar; when it is an array, it must have a single channel.
+@param src2 second input array or a scalar; when it is an array, it must have a single channel.
+@param dst output array of type ref CV_8U that has the same size and the same number of channels as
+ the input arrays.
+@param cmpop a flag, that specifies correspondence between the arrays (cv::CmpTypes)
+@sa checkRange, min, max, threshold
+*/
+CV_EXPORTS_W void compare(InputArray src1, InputArray src2, OutputArray dst, int cmpop);
+
+/** @brief Calculates per-element minimum of two arrays or an array and a scalar.
+
+The function cv::min calculates the per-element minimum of two arrays:
+\f[\texttt{dst} (I)= \min ( \texttt{src1} (I), \texttt{src2} (I))\f]
+or array and a scalar:
+\f[\texttt{dst} (I)= \min ( \texttt{src1} (I), \texttt{value} )\f]
+@param src1 first input array.
+@param src2 second input array of the same size and type as src1.
+@param dst output array of the same size and type as src1.
+@sa max, compare, inRange, minMaxLoc
+*/
+CV_EXPORTS_W void min(InputArray src1, InputArray src2, OutputArray dst);
+/** @overload
+needed to avoid conflicts with const _Tp& std::min(const _Tp&, const _Tp&, _Compare)
+*/
+CV_EXPORTS void min(const Mat& src1, const Mat& src2, Mat& dst);
+/** @overload
+needed to avoid conflicts with const _Tp& std::min(const _Tp&, const _Tp&, _Compare)
+*/
+CV_EXPORTS void min(const UMat& src1, const UMat& src2, UMat& dst);
+
+/** @brief Calculates per-element maximum of two arrays or an array and a scalar.
+
+The function cv::max calculates the per-element maximum of two arrays:
+\f[\texttt{dst} (I)= \max ( \texttt{src1} (I), \texttt{src2} (I))\f]
+or array and a scalar:
+\f[\texttt{dst} (I)= \max ( \texttt{src1} (I), \texttt{value} )\f]
+@param src1 first input array.
+@param src2 second input array of the same size and type as src1 .
+@param dst output array of the same size and type as src1.
+@sa min, compare, inRange, minMaxLoc, @ref MatrixExpressions
+*/
+CV_EXPORTS_W void max(InputArray src1, InputArray src2, OutputArray dst);
+/** @overload
+needed to avoid conflicts with const _Tp& std::min(const _Tp&, const _Tp&, _Compare)
+*/
+CV_EXPORTS void max(const Mat& src1, const Mat& src2, Mat& dst);
+/** @overload
+needed to avoid conflicts with const _Tp& std::min(const _Tp&, const _Tp&, _Compare)
+*/
+CV_EXPORTS void max(const UMat& src1, const UMat& src2, UMat& dst);
+
+/** @brief Calculates a square root of array elements.
+
+The function cv::sqrt calculates a square root of each input array element.
+In case of multi-channel arrays, each channel is processed
+independently. The accuracy is approximately the same as of the built-in
+std::sqrt .
+@param src input floating-point array.
+@param dst output array of the same size and type as src.
+*/
+CV_EXPORTS_W void sqrt(InputArray src, OutputArray dst);
+
+/** @brief Raises every array element to a power.
+
+The function cv::pow raises every element of the input array to power :
+\f[\texttt{dst} (I) = \fork{\texttt{src}(I)^{power}}{if \(\texttt{power}\) is integer}{|\texttt{src}(I)|^{power}}{otherwise}\f]
+
+So, for a non-integer power exponent, the absolute values of input array
+elements are used. However, it is possible to get true values for
+negative values using some extra operations. In the example below,
+computing the 5th root of array src shows:
+@code{.cpp}
+ Mat mask = src < 0;
+ pow(src, 1./5, dst);
+ subtract(Scalar::all(0), dst, dst, mask);
+@endcode
+For some values of power, such as integer values, 0.5 and -0.5,
+specialized faster algorithms are used.
+
+Special values (NaN, Inf) are not handled.
+@param src input array.
+@param power exponent of power.
+@param dst output array of the same size and type as src.
+@sa sqrt, exp, log, cartToPolar, polarToCart
+*/
+CV_EXPORTS_W void pow(InputArray src, double power, OutputArray dst);
+
+/** @brief Calculates the exponent of every array element.
+
+The function cv::exp calculates the exponent of every element of the input
+array:
+\f[\texttt{dst} [I] = e^{ src(I) }\f]
+
+The maximum relative error is about 7e-6 for single-precision input and
+less than 1e-10 for double-precision input. Currently, the function
+converts denormalized values to zeros on output. Special values (NaN,
+Inf) are not handled.
+@param src input array.
+@param dst output array of the same size and type as src.
+@sa log , cartToPolar , polarToCart , phase , pow , sqrt , magnitude
+*/
+CV_EXPORTS_W void exp(InputArray src, OutputArray dst);
+
+/** @brief Calculates the natural logarithm of every array element.
+
+The function cv::log calculates the natural logarithm of every element of the input array:
+\f[\texttt{dst} (I) = \log (\texttt{src}(I)) \f]
+
+Output on zero, negative and special (NaN, Inf) values is undefined.
+
+@param src input array.
+@param dst output array of the same size and type as src .
+@sa exp, cartToPolar, polarToCart, phase, pow, sqrt, magnitude
+*/
+CV_EXPORTS_W void log(InputArray src, OutputArray dst);
+
+/** @brief Calculates x and y coordinates of 2D vectors from their magnitude and angle.
+
+The function cv::polarToCart calculates the Cartesian coordinates of each 2D
+vector represented by the corresponding elements of magnitude and angle:
+\f[\begin{array}{l} \texttt{x} (I) = \texttt{magnitude} (I) \cos ( \texttt{angle} (I)) \\ \texttt{y} (I) = \texttt{magnitude} (I) \sin ( \texttt{angle} (I)) \\ \end{array}\f]
+
+The relative accuracy of the estimated coordinates is about 1e-6.
+@param magnitude input floating-point array of magnitudes of 2D vectors;
+it can be an empty matrix (=Mat()), in this case, the function assumes
+that all the magnitudes are =1; if it is not empty, it must have the
+same size and type as angle.
+@param angle input floating-point array of angles of 2D vectors.
+@param x output array of x-coordinates of 2D vectors; it has the same
+size and type as angle.
+@param y output array of y-coordinates of 2D vectors; it has the same
+size and type as angle.
+@param angleInDegrees when true, the input angles are measured in
+degrees, otherwise, they are measured in radians.
+@sa cartToPolar, magnitude, phase, exp, log, pow, sqrt
+*/
+CV_EXPORTS_W void polarToCart(InputArray magnitude, InputArray angle,
+ OutputArray x, OutputArray y, bool angleInDegrees = false);
+
+/** @brief Calculates the magnitude and angle of 2D vectors.
+
+The function cv::cartToPolar calculates either the magnitude, angle, or both
+for every 2D vector (x(I),y(I)):
+\f[\begin{array}{l} \texttt{magnitude} (I)= \sqrt{\texttt{x}(I)^2+\texttt{y}(I)^2} , \\ \texttt{angle} (I)= \texttt{atan2} ( \texttt{y} (I), \texttt{x} (I))[ \cdot180 / \pi ] \end{array}\f]
+
+The angles are calculated with accuracy about 0.3 degrees. For the point
+(0,0), the angle is set to 0.
+@param x array of x-coordinates; this must be a single-precision or
+double-precision floating-point array.
+@param y array of y-coordinates, that must have the same size and same type as x.
+@param magnitude output array of magnitudes of the same size and type as x.
+@param angle output array of angles that has the same size and type as
+x; the angles are measured in radians (from 0 to 2\*Pi) or in degrees (0 to 360 degrees).
+@param angleInDegrees a flag, indicating whether the angles are measured
+in radians (which is by default), or in degrees.
+@sa Sobel, Scharr
+*/
+CV_EXPORTS_W void cartToPolar(InputArray x, InputArray y,
+ OutputArray magnitude, OutputArray angle,
+ bool angleInDegrees = false);
+
+/** @brief Calculates the rotation angle of 2D vectors.
+
+The function cv::phase calculates the rotation angle of each 2D vector that
+is formed from the corresponding elements of x and y :
+\f[\texttt{angle} (I) = \texttt{atan2} ( \texttt{y} (I), \texttt{x} (I))\f]
+
+The angle estimation accuracy is about 0.3 degrees. When x(I)=y(I)=0 ,
+the corresponding angle(I) is set to 0.
+@param x input floating-point array of x-coordinates of 2D vectors.
+@param y input array of y-coordinates of 2D vectors; it must have the
+same size and the same type as x.
+@param angle output array of vector angles; it has the same size and
+same type as x .
+@param angleInDegrees when true, the function calculates the angle in
+degrees, otherwise, they are measured in radians.
+*/
+CV_EXPORTS_W void phase(InputArray x, InputArray y, OutputArray angle,
+ bool angleInDegrees = false);
+
+/** @brief Calculates the magnitude of 2D vectors.
+
+The function cv::magnitude calculates the magnitude of 2D vectors formed
+from the corresponding elements of x and y arrays:
+\f[\texttt{dst} (I) = \sqrt{\texttt{x}(I)^2 + \texttt{y}(I)^2}\f]
+@param x floating-point array of x-coordinates of the vectors.
+@param y floating-point array of y-coordinates of the vectors; it must
+have the same size as x.
+@param magnitude output array of the same size and type as x.
+@sa cartToPolar, polarToCart, phase, sqrt
+*/
+CV_EXPORTS_W void magnitude(InputArray x, InputArray y, OutputArray magnitude);
+
+/** @brief Checks every element of an input array for invalid values.
+
+The function cv::checkRange checks that every array element is neither NaN nor infinite. When minVal \>
+-DBL_MAX and maxVal \< DBL_MAX, the function also checks that each value is between minVal and
+maxVal. In case of multi-channel arrays, each channel is processed independently. If some values
+are out of range, position of the first outlier is stored in pos (when pos != NULL). Then, the
+function either returns false (when quiet=true) or throws an exception.
+@param a input array.
+@param quiet a flag, indicating whether the functions quietly return false when the array elements
+are out of range or they throw an exception.
+@param pos optional output parameter, when not NULL, must be a pointer to array of src.dims
+elements.
+@param minVal inclusive lower boundary of valid values range.
+@param maxVal exclusive upper boundary of valid values range.
+*/
+CV_EXPORTS_W bool checkRange(InputArray a, bool quiet = true, CV_OUT Point* pos = 0,
+ double minVal = -DBL_MAX, double maxVal = DBL_MAX);
+
+/** @brief converts NaN's to the given number
+*/
+CV_EXPORTS_W void patchNaNs(InputOutputArray a, double val = 0);
+
+/** @brief Performs generalized matrix multiplication.
+
+The function cv::gemm performs generalized matrix multiplication similar to the
+gemm functions in BLAS level 3. For example,
+`gemm(src1, src2, alpha, src3, beta, dst, GEMM_1_T + GEMM_3_T)`
+corresponds to
+\f[\texttt{dst} = \texttt{alpha} \cdot \texttt{src1} ^T \cdot \texttt{src2} + \texttt{beta} \cdot \texttt{src3} ^T\f]
+
+In case of complex (two-channel) data, performed a complex matrix
+multiplication.
+
+The function can be replaced with a matrix expression. For example, the
+above call can be replaced with:
+@code{.cpp}
+ dst = alpha*src1.t()*src2 + beta*src3.t();
+@endcode
+@param src1 first multiplied input matrix that could be real(CV_32FC1,
+CV_64FC1) or complex(CV_32FC2, CV_64FC2).
+@param src2 second multiplied input matrix of the same type as src1.
+@param alpha weight of the matrix product.
+@param src3 third optional delta matrix added to the matrix product; it
+should have the same type as src1 and src2.
+@param beta weight of src3.
+@param dst output matrix; it has the proper size and the same type as
+input matrices.
+@param flags operation flags (cv::GemmFlags)
+@sa mulTransposed , transform
+*/
+CV_EXPORTS_W void gemm(InputArray src1, InputArray src2, double alpha,
+ InputArray src3, double beta, OutputArray dst, int flags = 0);
+
+/** @brief Calculates the product of a matrix and its transposition.
+
+The function cv::mulTransposed calculates the product of src and its
+transposition:
+\f[\texttt{dst} = \texttt{scale} ( \texttt{src} - \texttt{delta} )^T ( \texttt{src} - \texttt{delta} )\f]
+if aTa=true , and
+\f[\texttt{dst} = \texttt{scale} ( \texttt{src} - \texttt{delta} ) ( \texttt{src} - \texttt{delta} )^T\f]
+otherwise. The function is used to calculate the covariance matrix. With
+zero delta, it can be used as a faster substitute for general matrix
+product A\*B when B=A'
+@param src input single-channel matrix. Note that unlike gemm, the
+function can multiply not only floating-point matrices.
+@param dst output square matrix.
+@param aTa Flag specifying the multiplication ordering. See the
+description below.
+@param delta Optional delta matrix subtracted from src before the
+multiplication. When the matrix is empty ( delta=noArray() ), it is
+assumed to be zero, that is, nothing is subtracted. If it has the same
+size as src , it is simply subtracted. Otherwise, it is "repeated" (see
+repeat ) to cover the full src and then subtracted. Type of the delta
+matrix, when it is not empty, must be the same as the type of created
+output matrix. See the dtype parameter description below.
+@param scale Optional scale factor for the matrix product.
+@param dtype Optional type of the output matrix. When it is negative,
+the output matrix will have the same type as src . Otherwise, it will be
+type=CV_MAT_DEPTH(dtype) that should be either CV_32F or CV_64F .
+@sa calcCovarMatrix, gemm, repeat, reduce
+*/
+CV_EXPORTS_W void mulTransposed( InputArray src, OutputArray dst, bool aTa,
+ InputArray delta = noArray(),
+ double scale = 1, int dtype = -1 );
+
+/** @brief Transposes a matrix.
+
+The function cv::transpose transposes the matrix src :
+\f[\texttt{dst} (i,j) = \texttt{src} (j,i)\f]
+@note No complex conjugation is done in case of a complex matrix. It it
+should be done separately if needed.
+@param src input array.
+@param dst output array of the same type as src.
+*/
+CV_EXPORTS_W void transpose(InputArray src, OutputArray dst);
+
+/** @brief Performs the matrix transformation of every array element.
+
+The function cv::transform performs the matrix transformation of every
+element of the array src and stores the results in dst :
+\f[\texttt{dst} (I) = \texttt{m} \cdot \texttt{src} (I)\f]
+(when m.cols=src.channels() ), or
+\f[\texttt{dst} (I) = \texttt{m} \cdot [ \texttt{src} (I); 1]\f]
+(when m.cols=src.channels()+1 )
+
+Every element of the N -channel array src is interpreted as N -element
+vector that is transformed using the M x N or M x (N+1) matrix m to
+M-element vector - the corresponding element of the output array dst .
+
+The function may be used for geometrical transformation of
+N -dimensional points, arbitrary linear color space transformation (such
+as various kinds of RGB to YUV transforms), shuffling the image
+channels, and so forth.
+@param src input array that must have as many channels (1 to 4) as
+m.cols or m.cols-1.
+@param dst output array of the same size and depth as src; it has as
+many channels as m.rows.
+@param m transformation 2x2 or 2x3 floating-point matrix.
+@sa perspectiveTransform, getAffineTransform, estimateAffine2D, warpAffine, warpPerspective
+*/
+CV_EXPORTS_W void transform(InputArray src, OutputArray dst, InputArray m );
+
+/** @brief Performs the perspective matrix transformation of vectors.
+
+The function cv::perspectiveTransform transforms every element of src by
+treating it as a 2D or 3D vector, in the following way:
+\f[(x, y, z) \rightarrow (x'/w, y'/w, z'/w)\f]
+where
+\f[(x', y', z', w') = \texttt{mat} \cdot \begin{bmatrix} x & y & z & 1 \end{bmatrix}\f]
+and
+\f[w = \fork{w'}{if \(w' \ne 0\)}{\infty}{otherwise}\f]
+
+Here a 3D vector transformation is shown. In case of a 2D vector
+transformation, the z component is omitted.
+
+@note The function transforms a sparse set of 2D or 3D vectors. If you
+want to transform an image using perspective transformation, use
+warpPerspective . If you have an inverse problem, that is, you want to
+compute the most probable perspective transformation out of several
+pairs of corresponding points, you can use getPerspectiveTransform or
+findHomography .
+@param src input two-channel or three-channel floating-point array; each
+element is a 2D/3D vector to be transformed.
+@param dst output array of the same size and type as src.
+@param m 3x3 or 4x4 floating-point transformation matrix.
+@sa transform, warpPerspective, getPerspectiveTransform, findHomography
+*/
+CV_EXPORTS_W void perspectiveTransform(InputArray src, OutputArray dst, InputArray m );
+
+/** @brief Copies the lower or the upper half of a square matrix to another half.
+
+The function cv::completeSymm copies the lower half of a square matrix to
+its another half. The matrix diagonal remains unchanged:
+* \f$\texttt{mtx}_{ij}=\texttt{mtx}_{ji}\f$ for \f$i > j\f$ if
+ lowerToUpper=false
+* \f$\texttt{mtx}_{ij}=\texttt{mtx}_{ji}\f$ for \f$i < j\f$ if
+ lowerToUpper=true
+@param mtx input-output floating-point square matrix.
+@param lowerToUpper operation flag; if true, the lower half is copied to
+the upper half. Otherwise, the upper half is copied to the lower half.
+@sa flip, transpose
+*/
+CV_EXPORTS_W void completeSymm(InputOutputArray mtx, bool lowerToUpper = false);
+
+/** @brief Initializes a scaled identity matrix.
+
+The function cv::setIdentity initializes a scaled identity matrix:
+\f[\texttt{mtx} (i,j)= \fork{\texttt{value}}{ if \(i=j\)}{0}{otherwise}\f]
+
+The function can also be emulated using the matrix initializers and the
+matrix expressions:
+@code
+ Mat A = Mat::eye(4, 3, CV_32F)*5;
+ // A will be set to [[5, 0, 0], [0, 5, 0], [0, 0, 5], [0, 0, 0]]
+@endcode
+@param mtx matrix to initialize (not necessarily square).
+@param s value to assign to diagonal elements.
+@sa Mat::zeros, Mat::ones, Mat::setTo, Mat::operator=
+*/
+CV_EXPORTS_W void setIdentity(InputOutputArray mtx, const Scalar& s = Scalar(1));
+
+/** @brief Returns the determinant of a square floating-point matrix.
+
+The function cv::determinant calculates and returns the determinant of the
+specified matrix. For small matrices ( mtx.cols=mtx.rows\<=3 ), the
+direct method is used. For larger matrices, the function uses LU
+factorization with partial pivoting.
+
+For symmetric positively-determined matrices, it is also possible to use
+eigen decomposition to calculate the determinant.
+@param mtx input matrix that must have CV_32FC1 or CV_64FC1 type and
+square size.
+@sa trace, invert, solve, eigen, @ref MatrixExpressions
+*/
+CV_EXPORTS_W double determinant(InputArray mtx);
+
+/** @brief Returns the trace of a matrix.
+
+The function cv::trace returns the sum of the diagonal elements of the
+matrix mtx .
+\f[\mathrm{tr} ( \texttt{mtx} ) = \sum _i \texttt{mtx} (i,i)\f]
+@param mtx input matrix.
+*/
+CV_EXPORTS_W Scalar trace(InputArray mtx);
+
+/** @brief Finds the inverse or pseudo-inverse of a matrix.
+
+The function cv::invert inverts the matrix src and stores the result in dst
+. When the matrix src is singular or non-square, the function calculates
+the pseudo-inverse matrix (the dst matrix) so that norm(src\*dst - I) is
+minimal, where I is an identity matrix.
+
+In case of the DECOMP_LU method, the function returns non-zero value if
+the inverse has been successfully calculated and 0 if src is singular.
+
+In case of the DECOMP_SVD method, the function returns the inverse
+condition number of src (the ratio of the smallest singular value to the
+largest singular value) and 0 if src is singular. The SVD method
+calculates a pseudo-inverse matrix if src is singular.
+
+Similarly to DECOMP_LU, the method DECOMP_CHOLESKY works only with
+non-singular square matrices that should also be symmetrical and
+positively defined. In this case, the function stores the inverted
+matrix in dst and returns non-zero. Otherwise, it returns 0.
+
+@param src input floating-point M x N matrix.
+@param dst output matrix of N x M size and the same type as src.
+@param flags inversion method (cv::DecompTypes)
+@sa solve, SVD
+*/
+CV_EXPORTS_W double invert(InputArray src, OutputArray dst, int flags = DECOMP_LU);
+
+/** @brief Solves one or more linear systems or least-squares problems.
+
+The function cv::solve solves a linear system or least-squares problem (the
+latter is possible with SVD or QR methods, or by specifying the flag
+DECOMP_NORMAL ):
+\f[\texttt{dst} = \arg \min _X \| \texttt{src1} \cdot \texttt{X} - \texttt{src2} \|\f]
+
+If DECOMP_LU or DECOMP_CHOLESKY method is used, the function returns 1
+if src1 (or \f$\texttt{src1}^T\texttt{src1}\f$ ) is non-singular. Otherwise,
+it returns 0. In the latter case, dst is not valid. Other methods find a
+pseudo-solution in case of a singular left-hand side part.
+
+@note If you want to find a unity-norm solution of an under-defined
+singular system \f$\texttt{src1}\cdot\texttt{dst}=0\f$ , the function solve
+will not do the work. Use SVD::solveZ instead.
+
+@param src1 input matrix on the left-hand side of the system.
+@param src2 input matrix on the right-hand side of the system.
+@param dst output solution.
+@param flags solution (matrix inversion) method (cv::DecompTypes)
+@sa invert, SVD, eigen
+*/
+CV_EXPORTS_W bool solve(InputArray src1, InputArray src2,
+ OutputArray dst, int flags = DECOMP_LU);
+
+/** @brief Sorts each row or each column of a matrix.
+
+The function cv::sort sorts each matrix row or each matrix column in
+ascending or descending order. So you should pass two operation flags to
+get desired behaviour. If you want to sort matrix rows or columns
+lexicographically, you can use STL std::sort generic function with the
+proper comparison predicate.
+
+@param src input single-channel array.
+@param dst output array of the same size and type as src.
+@param flags operation flags, a combination of cv::SortFlags
+@sa sortIdx, randShuffle
+*/
+CV_EXPORTS_W void sort(InputArray src, OutputArray dst, int flags);
+
+/** @brief Sorts each row or each column of a matrix.
+
+The function cv::sortIdx sorts each matrix row or each matrix column in the
+ascending or descending order. So you should pass two operation flags to
+get desired behaviour. Instead of reordering the elements themselves, it
+stores the indices of sorted elements in the output array. For example:
+@code
+ Mat A = Mat::eye(3,3,CV_32F), B;
+ sortIdx(A, B, SORT_EVERY_ROW + SORT_ASCENDING);
+ // B will probably contain
+ // (because of equal elements in A some permutations are possible):
+ // [[1, 2, 0], [0, 2, 1], [0, 1, 2]]
+@endcode
+@param src input single-channel array.
+@param dst output integer array of the same size as src.
+@param flags operation flags that could be a combination of cv::SortFlags
+@sa sort, randShuffle
+*/
+CV_EXPORTS_W void sortIdx(InputArray src, OutputArray dst, int flags);
+
+/** @brief Finds the real roots of a cubic equation.
+
+The function solveCubic finds the real roots of a cubic equation:
+- if coeffs is a 4-element vector:
+\f[\texttt{coeffs} [0] x^3 + \texttt{coeffs} [1] x^2 + \texttt{coeffs} [2] x + \texttt{coeffs} [3] = 0\f]
+- if coeffs is a 3-element vector:
+\f[x^3 + \texttt{coeffs} [0] x^2 + \texttt{coeffs} [1] x + \texttt{coeffs} [2] = 0\f]
+
+The roots are stored in the roots array.
+@param coeffs equation coefficients, an array of 3 or 4 elements.
+@param roots output array of real roots that has 1 or 3 elements.
+*/
+CV_EXPORTS_W int solveCubic(InputArray coeffs, OutputArray roots);
+
+/** @brief Finds the real or complex roots of a polynomial equation.
+
+The function cv::solvePoly finds real and complex roots of a polynomial equation:
+\f[\texttt{coeffs} [n] x^{n} + \texttt{coeffs} [n-1] x^{n-1} + ... + \texttt{coeffs} [1] x + \texttt{coeffs} [0] = 0\f]
+@param coeffs array of polynomial coefficients.
+@param roots output (complex) array of roots.
+@param maxIters maximum number of iterations the algorithm does.
+*/
+CV_EXPORTS_W double solvePoly(InputArray coeffs, OutputArray roots, int maxIters = 300);
+
+/** @brief Calculates eigenvalues and eigenvectors of a symmetric matrix.
+
+The function cv::eigen calculates just eigenvalues, or eigenvalues and eigenvectors of the symmetric
+matrix src:
+@code
+ src*eigenvectors.row(i).t() = eigenvalues.at<srcType>(i)*eigenvectors.row(i).t()
+@endcode
+@note in the new and the old interfaces different ordering of eigenvalues and eigenvectors
+parameters is used.
+@param src input matrix that must have CV_32FC1 or CV_64FC1 type, square size and be symmetrical
+(src ^T^ == src).
+@param eigenvalues output vector of eigenvalues of the same type as src; the eigenvalues are stored
+in the descending order.
+@param eigenvectors output matrix of eigenvectors; it has the same size and type as src; the
+eigenvectors are stored as subsequent matrix rows, in the same order as the corresponding
+eigenvalues.
+@sa completeSymm , PCA
+*/
+CV_EXPORTS_W bool eigen(InputArray src, OutputArray eigenvalues,
+ OutputArray eigenvectors = noArray());
+
+/** @brief Calculates the covariance matrix of a set of vectors.
+
+The function cv::calcCovarMatrix calculates the covariance matrix and, optionally, the mean vector of
+the set of input vectors.
+@param samples samples stored as separate matrices
+@param nsamples number of samples
+@param covar output covariance matrix of the type ctype and square size.
+@param mean input or output (depending on the flags) array as the average value of the input vectors.
+@param flags operation flags as a combination of cv::CovarFlags
+@param ctype type of the matrixl; it equals 'CV_64F' by default.
+@sa PCA, mulTransposed, Mahalanobis
+@todo InputArrayOfArrays
+*/
+CV_EXPORTS void calcCovarMatrix( const Mat* samples, int nsamples, Mat& covar, Mat& mean,
+ int flags, int ctype = CV_64F);
+
+/** @overload
+@note use cv::COVAR_ROWS or cv::COVAR_COLS flag
+@param samples samples stored as rows/columns of a single matrix.
+@param covar output covariance matrix of the type ctype and square size.
+@param mean input or output (depending on the flags) array as the average value of the input vectors.
+@param flags operation flags as a combination of cv::CovarFlags
+@param ctype type of the matrixl; it equals 'CV_64F' by default.
+*/
+CV_EXPORTS_W void calcCovarMatrix( InputArray samples, OutputArray covar,
+ InputOutputArray mean, int flags, int ctype = CV_64F);
+
+/** wrap PCA::operator() */
+CV_EXPORTS_W void PCACompute(InputArray data, InputOutputArray mean,
+ OutputArray eigenvectors, int maxComponents = 0);
+
+/** wrap PCA::operator() */
+CV_EXPORTS_W void PCACompute(InputArray data, InputOutputArray mean,
+ OutputArray eigenvectors, double retainedVariance);
+
+/** wrap PCA::project */
+CV_EXPORTS_W void PCAProject(InputArray data, InputArray mean,
+ InputArray eigenvectors, OutputArray result);
+
+/** wrap PCA::backProject */
+CV_EXPORTS_W void PCABackProject(InputArray data, InputArray mean,
+ InputArray eigenvectors, OutputArray result);
+
+/** wrap SVD::compute */
+CV_EXPORTS_W void SVDecomp( InputArray src, OutputArray w, OutputArray u, OutputArray vt, int flags = 0 );
+
+/** wrap SVD::backSubst */
+CV_EXPORTS_W void SVBackSubst( InputArray w, InputArray u, InputArray vt,
+ InputArray rhs, OutputArray dst );
+
+/** @brief Calculates the Mahalanobis distance between two vectors.
+
+The function cv::Mahalanobis calculates and returns the weighted distance between two vectors:
+\f[d( \texttt{vec1} , \texttt{vec2} )= \sqrt{\sum_{i,j}{\texttt{icovar(i,j)}\cdot(\texttt{vec1}(I)-\texttt{vec2}(I))\cdot(\texttt{vec1(j)}-\texttt{vec2(j)})} }\f]
+The covariance matrix may be calculated using the cv::calcCovarMatrix function and then inverted using
+the invert function (preferably using the cv::DECOMP_SVD method, as the most accurate).
+@param v1 first 1D input vector.
+@param v2 second 1D input vector.
+@param icovar inverse covariance matrix.
+*/
+CV_EXPORTS_W double Mahalanobis(InputArray v1, InputArray v2, InputArray icovar);
+
+/** @brief Performs a forward or inverse Discrete Fourier transform of a 1D or 2D floating-point array.
+
+The function cv::dft performs one of the following:
+- Forward the Fourier transform of a 1D vector of N elements:
+ \f[Y = F^{(N)} \cdot X,\f]
+ where \f$F^{(N)}_{jk}=\exp(-2\pi i j k/N)\f$ and \f$i=\sqrt{-1}\f$
+- Inverse the Fourier transform of a 1D vector of N elements:
+ \f[\begin{array}{l} X'= \left (F^{(N)} \right )^{-1} \cdot Y = \left (F^{(N)} \right )^* \cdot y \\ X = (1/N) \cdot X, \end{array}\f]
+ where \f$F^*=\left(\textrm{Re}(F^{(N)})-\textrm{Im}(F^{(N)})\right)^T\f$
+- Forward the 2D Fourier transform of a M x N matrix:
+ \f[Y = F^{(M)} \cdot X \cdot F^{(N)}\f]
+- Inverse the 2D Fourier transform of a M x N matrix:
+ \f[\begin{array}{l} X'= \left (F^{(M)} \right )^* \cdot Y \cdot \left (F^{(N)} \right )^* \\ X = \frac{1}{M \cdot N} \cdot X' \end{array}\f]
+
+In case of real (single-channel) data, the output spectrum of the forward Fourier transform or input
+spectrum of the inverse Fourier transform can be represented in a packed format called *CCS*
+(complex-conjugate-symmetrical). It was borrowed from IPL (Intel\* Image Processing Library). Here
+is how 2D *CCS* spectrum looks:
+\f[\begin{bmatrix} Re Y_{0,0} & Re Y_{0,1} & Im Y_{0,1} & Re Y_{0,2} & Im Y_{0,2} & \cdots & Re Y_{0,N/2-1} & Im Y_{0,N/2-1} & Re Y_{0,N/2} \\ Re Y_{1,0} & Re Y_{1,1} & Im Y_{1,1} & Re Y_{1,2} & Im Y_{1,2} & \cdots & Re Y_{1,N/2-1} & Im Y_{1,N/2-1} & Re Y_{1,N/2} \\ Im Y_{1,0} & Re Y_{2,1} & Im Y_{2,1} & Re Y_{2,2} & Im Y_{2,2} & \cdots & Re Y_{2,N/2-1} & Im Y_{2,N/2-1} & Im Y_{1,N/2} \\ \hdotsfor{9} \\ Re Y_{M/2-1,0} & Re Y_{M-3,1} & Im Y_{M-3,1} & \hdotsfor{3} & Re Y_{M-3,N/2-1} & Im Y_{M-3,N/2-1}& Re Y_{M/2-1,N/2} \\ Im Y_{M/2-1,0} & Re Y_{M-2,1} & Im Y_{M-2,1} & \hdotsfor{3} & Re Y_{M-2,N/2-1} & Im Y_{M-2,N/2-1}& Im Y_{M/2-1,N/2} \\ Re Y_{M/2,0} & Re Y_{M-1,1} & Im Y_{M-1,1} & \hdotsfor{3} & Re Y_{M-1,N/2-1} & Im Y_{M-1,N/2-1}& Re Y_{M/2,N/2} \end{bmatrix}\f]
+
+In case of 1D transform of a real vector, the output looks like the first row of the matrix above.
+
+So, the function chooses an operation mode depending on the flags and size of the input array:
+- If DFT_ROWS is set or the input array has a single row or single column, the function
+ performs a 1D forward or inverse transform of each row of a matrix when DFT_ROWS is set.
+ Otherwise, it performs a 2D transform.
+- If the input array is real and DFT_INVERSE is not set, the function performs a forward 1D or
+ 2D transform:
+ - When DFT_COMPLEX_OUTPUT is set, the output is a complex matrix of the same size as
+ input.
+ - When DFT_COMPLEX_OUTPUT is not set, the output is a real matrix of the same size as
+ input. In case of 2D transform, it uses the packed format as shown above. In case of a
+ single 1D transform, it looks like the first row of the matrix above. In case of
+ multiple 1D transforms (when using the DFT_ROWS flag), each row of the output matrix
+ looks like the first row of the matrix above.
+- If the input array is complex and either DFT_INVERSE or DFT_REAL_OUTPUT are not set, the
+ output is a complex array of the same size as input. The function performs a forward or
+ inverse 1D or 2D transform of the whole input array or each row of the input array
+ independently, depending on the flags DFT_INVERSE and DFT_ROWS.
+- When DFT_INVERSE is set and the input array is real, or it is complex but DFT_REAL_OUTPUT
+ is set, the output is a real array of the same size as input. The function performs a 1D or 2D
+ inverse transformation of the whole input array or each individual row, depending on the flags
+ DFT_INVERSE and DFT_ROWS.
+
+If DFT_SCALE is set, the scaling is done after the transformation.
+
+Unlike dct , the function supports arrays of arbitrary size. But only those arrays are processed
+efficiently, whose sizes can be factorized in a product of small prime numbers (2, 3, and 5 in the
+current implementation). Such an efficient DFT size can be calculated using the getOptimalDFTSize
+method.
+
+The sample below illustrates how to calculate a DFT-based convolution of two 2D real arrays:
+@code
+ void convolveDFT(InputArray A, InputArray B, OutputArray C)
+ {
+ // reallocate the output array if needed
+ C.create(abs(A.rows - B.rows)+1, abs(A.cols - B.cols)+1, A.type());
+ Size dftSize;
+ // calculate the size of DFT transform
+ dftSize.width = getOptimalDFTSize(A.cols + B.cols - 1);
+ dftSize.height = getOptimalDFTSize(A.rows + B.rows - 1);
+
+ // allocate temporary buffers and initialize them with 0's
+ Mat tempA(dftSize, A.type(), Scalar::all(0));
+ Mat tempB(dftSize, B.type(), Scalar::all(0));
+
+ // copy A and B to the top-left corners of tempA and tempB, respectively
+ Mat roiA(tempA, Rect(0,0,A.cols,A.rows));
+ A.copyTo(roiA);
+ Mat roiB(tempB, Rect(0,0,B.cols,B.rows));
+ B.copyTo(roiB);
+
+ // now transform the padded A & B in-place;
+ // use "nonzeroRows" hint for faster processing
+ dft(tempA, tempA, 0, A.rows);
+ dft(tempB, tempB, 0, B.rows);
+
+ // multiply the spectrums;
+ // the function handles packed spectrum representations well
+ mulSpectrums(tempA, tempB, tempA);
+
+ // transform the product back from the frequency domain.
+ // Even though all the result rows will be non-zero,
+ // you need only the first C.rows of them, and thus you
+ // pass nonzeroRows == C.rows
+ dft(tempA, tempA, DFT_INVERSE + DFT_SCALE, C.rows);
+
+ // now copy the result back to C.
+ tempA(Rect(0, 0, C.cols, C.rows)).copyTo(C);
+
+ // all the temporary buffers will be deallocated automatically
+ }
+@endcode
+To optimize this sample, consider the following approaches:
+- Since nonzeroRows != 0 is passed to the forward transform calls and since A and B are copied to
+ the top-left corners of tempA and tempB, respectively, it is not necessary to clear the whole
+ tempA and tempB. It is only necessary to clear the tempA.cols - A.cols ( tempB.cols - B.cols)
+ rightmost columns of the matrices.
+- This DFT-based convolution does not have to be applied to the whole big arrays, especially if B
+ is significantly smaller than A or vice versa. Instead, you can calculate convolution by parts.
+ To do this, you need to split the output array C into multiple tiles. For each tile, estimate
+ which parts of A and B are required to calculate convolution in this tile. If the tiles in C are
+ too small, the speed will decrease a lot because of repeated work. In the ultimate case, when
+ each tile in C is a single pixel, the algorithm becomes equivalent to the naive convolution
+ algorithm. If the tiles are too big, the temporary arrays tempA and tempB become too big and
+ there is also a slowdown because of bad cache locality. So, there is an optimal tile size
+ somewhere in the middle.
+- If different tiles in C can be calculated in parallel and, thus, the convolution is done by
+ parts, the loop can be threaded.
+
+All of the above improvements have been implemented in matchTemplate and filter2D . Therefore, by
+using them, you can get the performance even better than with the above theoretically optimal
+implementation. Though, those two functions actually calculate cross-correlation, not convolution,
+so you need to "flip" the second convolution operand B vertically and horizontally using flip .
+@note
+- An example using the discrete fourier transform can be found at
+ opencv_source_code/samples/cpp/dft.cpp
+- (Python) An example using the dft functionality to perform Wiener deconvolution can be found
+ at opencv_source/samples/python/deconvolution.py
+- (Python) An example rearranging the quadrants of a Fourier image can be found at
+ opencv_source/samples/python/dft.py
+@param src input array that could be real or complex.
+@param dst output array whose size and type depends on the flags .
+@param flags transformation flags, representing a combination of the cv::DftFlags
+@param nonzeroRows when the parameter is not zero, the function assumes that only the first
+nonzeroRows rows of the input array (DFT_INVERSE is not set) or only the first nonzeroRows of the
+output array (DFT_INVERSE is set) contain non-zeros, thus, the function can handle the rest of the
+rows more efficiently and save some time; this technique is very useful for calculating array
+cross-correlation or convolution using DFT.
+@sa dct , getOptimalDFTSize , mulSpectrums, filter2D , matchTemplate , flip , cartToPolar ,
+magnitude , phase
+*/
+CV_EXPORTS_W void dft(InputArray src, OutputArray dst, int flags = 0, int nonzeroRows = 0);
+
+/** @brief Calculates the inverse Discrete Fourier Transform of a 1D or 2D array.
+
+idft(src, dst, flags) is equivalent to dft(src, dst, flags | DFT_INVERSE) .
+@note None of dft and idft scales the result by default. So, you should pass DFT_SCALE to one of
+dft or idft explicitly to make these transforms mutually inverse.
+@sa dft, dct, idct, mulSpectrums, getOptimalDFTSize
+@param src input floating-point real or complex array.
+@param dst output array whose size and type depend on the flags.
+@param flags operation flags (see dft and cv::DftFlags).
+@param nonzeroRows number of dst rows to process; the rest of the rows have undefined content (see
+the convolution sample in dft description.
+*/
+CV_EXPORTS_W void idft(InputArray src, OutputArray dst, int flags = 0, int nonzeroRows = 0);
+
+/** @brief Performs a forward or inverse discrete Cosine transform of 1D or 2D array.
+
+The function cv::dct performs a forward or inverse discrete Cosine transform (DCT) of a 1D or 2D
+floating-point array:
+- Forward Cosine transform of a 1D vector of N elements:
+ \f[Y = C^{(N)} \cdot X\f]
+ where
+ \f[C^{(N)}_{jk}= \sqrt{\alpha_j/N} \cos \left ( \frac{\pi(2k+1)j}{2N} \right )\f]
+ and
+ \f$\alpha_0=1\f$, \f$\alpha_j=2\f$ for *j \> 0*.
+- Inverse Cosine transform of a 1D vector of N elements:
+ \f[X = \left (C^{(N)} \right )^{-1} \cdot Y = \left (C^{(N)} \right )^T \cdot Y\f]
+ (since \f$C^{(N)}\f$ is an orthogonal matrix, \f$C^{(N)} \cdot \left(C^{(N)}\right)^T = I\f$ )
+- Forward 2D Cosine transform of M x N matrix:
+ \f[Y = C^{(N)} \cdot X \cdot \left (C^{(N)} \right )^T\f]
+- Inverse 2D Cosine transform of M x N matrix:
+ \f[X = \left (C^{(N)} \right )^T \cdot X \cdot C^{(N)}\f]
+
+The function chooses the mode of operation by looking at the flags and size of the input array:
+- If (flags & DCT_INVERSE) == 0 , the function does a forward 1D or 2D transform. Otherwise, it
+ is an inverse 1D or 2D transform.
+- If (flags & DCT_ROWS) != 0 , the function performs a 1D transform of each row.
+- If the array is a single column or a single row, the function performs a 1D transform.
+- If none of the above is true, the function performs a 2D transform.
+
+@note Currently dct supports even-size arrays (2, 4, 6 ...). For data analysis and approximation, you
+can pad the array when necessary.
+Also, the function performance depends very much, and not monotonically, on the array size (see
+getOptimalDFTSize ). In the current implementation DCT of a vector of size N is calculated via DFT
+of a vector of size N/2 . Thus, the optimal DCT size N1 \>= N can be calculated as:
+@code
+ size_t getOptimalDCTSize(size_t N) { return 2*getOptimalDFTSize((N+1)/2); }
+ N1 = getOptimalDCTSize(N);
+@endcode
+@param src input floating-point array.
+@param dst output array of the same size and type as src .
+@param flags transformation flags as a combination of cv::DftFlags (DCT_*)
+@sa dft , getOptimalDFTSize , idct
+*/
+CV_EXPORTS_W void dct(InputArray src, OutputArray dst, int flags = 0);
+
+/** @brief Calculates the inverse Discrete Cosine Transform of a 1D or 2D array.
+
+idct(src, dst, flags) is equivalent to dct(src, dst, flags | DCT_INVERSE).
+@param src input floating-point single-channel array.
+@param dst output array of the same size and type as src.
+@param flags operation flags.
+@sa dct, dft, idft, getOptimalDFTSize
+*/
+CV_EXPORTS_W void idct(InputArray src, OutputArray dst, int flags = 0);
+
+/** @brief Performs the per-element multiplication of two Fourier spectrums.
+
+The function cv::mulSpectrums performs the per-element multiplication of the two CCS-packed or complex
+matrices that are results of a real or complex Fourier transform.
+
+The function, together with dft and idft , may be used to calculate convolution (pass conjB=false )
+or correlation (pass conjB=true ) of two arrays rapidly. When the arrays are complex, they are
+simply multiplied (per element) with an optional conjugation of the second-array elements. When the
+arrays are real, they are assumed to be CCS-packed (see dft for details).
+@param a first input array.
+@param b second input array of the same size and type as src1 .
+@param c output array of the same size and type as src1 .
+@param flags operation flags; currently, the only supported flag is cv::DFT_ROWS, which indicates that
+each row of src1 and src2 is an independent 1D Fourier spectrum. If you do not want to use this flag, then simply add a `0` as value.
+@param conjB optional flag that conjugates the second input array before the multiplication (true)
+or not (false).
+*/
+CV_EXPORTS_W void mulSpectrums(InputArray a, InputArray b, OutputArray c,
+ int flags, bool conjB = false);
+
+/** @brief Returns the optimal DFT size for a given vector size.
+
+DFT performance is not a monotonic function of a vector size. Therefore, when you calculate
+convolution of two arrays or perform the spectral analysis of an array, it usually makes sense to
+pad the input data with zeros to get a bit larger array that can be transformed much faster than the
+original one. Arrays whose size is a power-of-two (2, 4, 8, 16, 32, ...) are the fastest to process.
+Though, the arrays whose size is a product of 2's, 3's, and 5's (for example, 300 = 5\*5\*3\*2\*2)
+are also processed quite efficiently.
+
+The function cv::getOptimalDFTSize returns the minimum number N that is greater than or equal to vecsize
+so that the DFT of a vector of size N can be processed efficiently. In the current implementation N
+= 2 ^p^ \* 3 ^q^ \* 5 ^r^ for some integer p, q, r.
+
+The function returns a negative number if vecsize is too large (very close to INT_MAX ).
+
+While the function cannot be used directly to estimate the optimal vector size for DCT transform
+(since the current DCT implementation supports only even-size vectors), it can be easily processed
+as getOptimalDFTSize((vecsize+1)/2)\*2.
+@param vecsize vector size.
+@sa dft , dct , idft , idct , mulSpectrums
+*/
+CV_EXPORTS_W int getOptimalDFTSize(int vecsize);
+
+/** @brief Returns the default random number generator.
+
+The function cv::theRNG returns the default random number generator. For each thread, there is a
+separate random number generator, so you can use the function safely in multi-thread environments.
+If you just need to get a single random number using this generator or initialize an array, you can
+use randu or randn instead. But if you are going to generate many random numbers inside a loop, it
+is much faster to use this function to retrieve the generator and then use RNG::operator _Tp() .
+@sa RNG, randu, randn
+*/
+CV_EXPORTS RNG& theRNG();
+
+/** @brief Sets state of default random number generator.
+
+The function cv::setRNGSeed sets state of default random number generator to custom value.
+@param seed new state for default random number generator
+@sa RNG, randu, randn
+*/
+CV_EXPORTS_W void setRNGSeed(int seed);
+
+/** @brief Generates a single uniformly-distributed random number or an array of random numbers.
+
+Non-template variant of the function fills the matrix dst with uniformly-distributed
+random numbers from the specified range:
+\f[\texttt{low} _c \leq \texttt{dst} (I)_c < \texttt{high} _c\f]
+@param dst output array of random numbers; the array must be pre-allocated.
+@param low inclusive lower boundary of the generated random numbers.
+@param high exclusive upper boundary of the generated random numbers.
+@sa RNG, randn, theRNG
+*/
+CV_EXPORTS_W void randu(InputOutputArray dst, InputArray low, InputArray high);
+
+/** @brief Fills the array with normally distributed random numbers.
+
+The function cv::randn fills the matrix dst with normally distributed random numbers with the specified
+mean vector and the standard deviation matrix. The generated random numbers are clipped to fit the
+value range of the output array data type.
+@param dst output array of random numbers; the array must be pre-allocated and have 1 to 4 channels.
+@param mean mean value (expectation) of the generated random numbers.
+@param stddev standard deviation of the generated random numbers; it can be either a vector (in
+which case a diagonal standard deviation matrix is assumed) or a square matrix.
+@sa RNG, randu
+*/
+CV_EXPORTS_W void randn(InputOutputArray dst, InputArray mean, InputArray stddev);
+
+/** @brief Shuffles the array elements randomly.
+
+The function cv::randShuffle shuffles the specified 1D array by randomly choosing pairs of elements and
+swapping them. The number of such swap operations will be dst.rows\*dst.cols\*iterFactor .
+@param dst input/output numerical 1D array.
+@param iterFactor scale factor that determines the number of random swap operations (see the details
+below).
+@param rng optional random number generator used for shuffling; if it is zero, theRNG () is used
+instead.
+@sa RNG, sort
+*/
+CV_EXPORTS_W void randShuffle(InputOutputArray dst, double iterFactor = 1., RNG* rng = 0);
+
+/** @brief Principal Component Analysis
+
+The class is used to calculate a special basis for a set of vectors. The
+basis will consist of eigenvectors of the covariance matrix calculated
+from the input set of vectors. The class %PCA can also transform
+vectors to/from the new coordinate space defined by the basis. Usually,
+in this new coordinate system, each vector from the original set (and
+any linear combination of such vectors) can be quite accurately
+approximated by taking its first few components, corresponding to the
+eigenvectors of the largest eigenvalues of the covariance matrix.
+Geometrically it means that you calculate a projection of the vector to
+a subspace formed by a few eigenvectors corresponding to the dominant
+eigenvalues of the covariance matrix. And usually such a projection is
+very close to the original vector. So, you can represent the original
+vector from a high-dimensional space with a much shorter vector
+consisting of the projected vector's coordinates in the subspace. Such a
+transformation is also known as Karhunen-Loeve Transform, or KLT.
+See http://en.wikipedia.org/wiki/Principal_component_analysis
+
+The sample below is the function that takes two matrices. The first
+function stores a set of vectors (a row per vector) that is used to
+calculate PCA. The second function stores another "test" set of vectors
+(a row per vector). First, these vectors are compressed with PCA, then
+reconstructed back, and then the reconstruction error norm is computed
+and printed for each vector. :
+
+@code{.cpp}
+using namespace cv;
+
+PCA compressPCA(const Mat& pcaset, int maxComponents,
+ const Mat& testset, Mat& compressed)
+{
+ PCA pca(pcaset, // pass the data
+ Mat(), // we do not have a pre-computed mean vector,
+ // so let the PCA engine to compute it
+ PCA::DATA_AS_ROW, // indicate that the vectors
+ // are stored as matrix rows
+ // (use PCA::DATA_AS_COL if the vectors are
+ // the matrix columns)
+ maxComponents // specify, how many principal components to retain
+ );
+ // if there is no test data, just return the computed basis, ready-to-use
+ if( !testset.data )
+ return pca;
+ CV_Assert( testset.cols == pcaset.cols );
+
+ compressed.create(testset.rows, maxComponents, testset.type());
+
+ Mat reconstructed;
+ for( int i = 0; i < testset.rows; i++ )
+ {
+ Mat vec = testset.row(i), coeffs = compressed.row(i), reconstructed;
+ // compress the vector, the result will be stored
+ // in the i-th row of the output matrix
+ pca.project(vec, coeffs);
+ // and then reconstruct it
+ pca.backProject(coeffs, reconstructed);
+ // and measure the error
+ printf("%d. diff = %g\n", i, norm(vec, reconstructed, NORM_L2));
+ }
+ return pca;
+}
+@endcode
+@sa calcCovarMatrix, mulTransposed, SVD, dft, dct
+*/
+class CV_EXPORTS PCA
+{
+public:
+ enum Flags { DATA_AS_ROW = 0, //!< indicates that the input samples are stored as matrix rows
+ DATA_AS_COL = 1, //!< indicates that the input samples are stored as matrix columns
+ USE_AVG = 2 //!
+ };
+
+ /** @brief default constructor
+
+ The default constructor initializes an empty %PCA structure. The other
+ constructors initialize the structure and call PCA::operator()().
+ */
+ PCA();
+
+ /** @overload
+ @param data input samples stored as matrix rows or matrix columns.
+ @param mean optional mean value; if the matrix is empty (@c noArray()),
+ the mean is computed from the data.
+ @param flags operation flags; currently the parameter is only used to
+ specify the data layout (PCA::Flags)
+ @param maxComponents maximum number of components that %PCA should
+ retain; by default, all the components are retained.
+ */
+ PCA(InputArray data, InputArray mean, int flags, int maxComponents = 0);
+
+ /** @overload
+ @param data input samples stored as matrix rows or matrix columns.
+ @param mean optional mean value; if the matrix is empty (noArray()),
+ the mean is computed from the data.
+ @param flags operation flags; currently the parameter is only used to
+ specify the data layout (PCA::Flags)
+ @param retainedVariance Percentage of variance that PCA should retain.
+ Using this parameter will let the PCA decided how many components to
+ retain but it will always keep at least 2.
+ */
+ PCA(InputArray data, InputArray mean, int flags, double retainedVariance);
+
+ /** @brief performs %PCA
+
+ The operator performs %PCA of the supplied dataset. It is safe to reuse
+ the same PCA structure for multiple datasets. That is, if the structure
+ has been previously used with another dataset, the existing internal
+ data is reclaimed and the new @ref eigenvalues, @ref eigenvectors and @ref
+ mean are allocated and computed.
+
+ The computed @ref eigenvalues are sorted from the largest to the smallest and
+ the corresponding @ref eigenvectors are stored as eigenvectors rows.
+
+ @param data input samples stored as the matrix rows or as the matrix
+ columns.
+ @param mean optional mean value; if the matrix is empty (noArray()),
+ the mean is computed from the data.
+ @param flags operation flags; currently the parameter is only used to
+ specify the data layout. (Flags)
+ @param maxComponents maximum number of components that PCA should
+ retain; by default, all the components are retained.
+ */
+ PCA& operator()(InputArray data, InputArray mean, int flags, int maxComponents = 0);
+
+ /** @overload
+ @param data input samples stored as the matrix rows or as the matrix
+ columns.
+ @param mean optional mean value; if the matrix is empty (noArray()),
+ the mean is computed from the data.
+ @param flags operation flags; currently the parameter is only used to
+ specify the data layout. (PCA::Flags)
+ @param retainedVariance Percentage of variance that %PCA should retain.
+ Using this parameter will let the %PCA decided how many components to
+ retain but it will always keep at least 2.
+ */
+ PCA& operator()(InputArray data, InputArray mean, int flags, double retainedVariance);
+
+ /** @brief Projects vector(s) to the principal component subspace.
+
+ The methods project one or more vectors to the principal component
+ subspace, where each vector projection is represented by coefficients in
+ the principal component basis. The first form of the method returns the
+ matrix that the second form writes to the result. So the first form can
+ be used as a part of expression while the second form can be more
+ efficient in a processing loop.
+ @param vec input vector(s); must have the same dimensionality and the
+ same layout as the input data used at %PCA phase, that is, if
+ DATA_AS_ROW are specified, then `vec.cols==data.cols`
+ (vector dimensionality) and `vec.rows` is the number of vectors to
+ project, and the same is true for the PCA::DATA_AS_COL case.
+ */
+ Mat project(InputArray vec) const;
+
+ /** @overload
+ @param vec input vector(s); must have the same dimensionality and the
+ same layout as the input data used at PCA phase, that is, if
+ DATA_AS_ROW are specified, then `vec.cols==data.cols`
+ (vector dimensionality) and `vec.rows` is the number of vectors to
+ project, and the same is true for the PCA::DATA_AS_COL case.
+ @param result output vectors; in case of PCA::DATA_AS_COL, the
+ output matrix has as many columns as the number of input vectors, this
+ means that `result.cols==vec.cols` and the number of rows match the
+ number of principal components (for example, `maxComponents` parameter
+ passed to the constructor).
+ */
+ void project(InputArray vec, OutputArray result) const;
+
+ /** @brief Reconstructs vectors from their PC projections.
+
+ The methods are inverse operations to PCA::project. They take PC
+ coordinates of projected vectors and reconstruct the original vectors.
+ Unless all the principal components have been retained, the
+ reconstructed vectors are different from the originals. But typically,
+ the difference is small if the number of components is large enough (but
+ still much smaller than the original vector dimensionality). As a
+ result, PCA is used.
+ @param vec coordinates of the vectors in the principal component
+ subspace, the layout and size are the same as of PCA::project output
+ vectors.
+ */
+ Mat backProject(InputArray vec) const;
+
+ /** @overload
+ @param vec coordinates of the vectors in the principal component
+ subspace, the layout and size are the same as of PCA::project output
+ vectors.
+ @param result reconstructed vectors; the layout and size are the same as
+ of PCA::project input vectors.
+ */
+ void backProject(InputArray vec, OutputArray result) const;
+
+ /** @brief write PCA objects
+
+ Writes @ref eigenvalues @ref eigenvectors and @ref mean to specified FileStorage
+ */
+ void write(FileStorage& fs) const;
+
+ /** @brief load PCA objects
+
+ Loads @ref eigenvalues @ref eigenvectors and @ref mean from specified FileNode
+ */
+ void read(const FileNode& fn);
+
+ Mat eigenvectors; //!< eigenvectors of the covariation matrix
+ Mat eigenvalues; //!< eigenvalues of the covariation matrix
+ Mat mean; //!< mean value subtracted before the projection and added after the back projection
+};
+
+/** @example pca.cpp
+ An example using %PCA for dimensionality reduction while maintaining an amount of variance
+ */
+
+/**
+ @brief Linear Discriminant Analysis
+ @todo document this class
+ */
+class CV_EXPORTS LDA
+{
+public:
+ /** @brief constructor
+ Initializes a LDA with num_components (default 0).
+ */
+ explicit LDA(int num_components = 0);
+
+ /** Initializes and performs a Discriminant Analysis with Fisher's
+ Optimization Criterion on given data in src and corresponding labels
+ in labels. If 0 (or less) number of components are given, they are
+ automatically determined for given data in computation.
+ */
+ LDA(InputArrayOfArrays src, InputArray labels, int num_components = 0);
+
+ /** Serializes this object to a given filename.
+ */
+ void save(const String& filename) const;
+
+ /** Deserializes this object from a given filename.
+ */
+ void load(const String& filename);
+
+ /** Serializes this object to a given cv::FileStorage.
+ */
+ void save(FileStorage& fs) const;
+
+ /** Deserializes this object from a given cv::FileStorage.
+ */
+ void load(const FileStorage& node);
+
+ /** destructor
+ */
+ ~LDA();
+
+ /** Compute the discriminants for data in src (row aligned) and labels.
+ */
+ void compute(InputArrayOfArrays src, InputArray labels);
+
+ /** Projects samples into the LDA subspace.
+ src may be one or more row aligned samples.
+ */
+ Mat project(InputArray src);
+
+ /** Reconstructs projections from the LDA subspace.
+ src may be one or more row aligned projections.
+ */
+ Mat reconstruct(InputArray src);
+
+ /** Returns the eigenvectors of this LDA.
+ */
+ Mat eigenvectors() const { return _eigenvectors; }
+
+ /** Returns the eigenvalues of this LDA.
+ */
+ Mat eigenvalues() const { return _eigenvalues; }
+
+ static Mat subspaceProject(InputArray W, InputArray mean, InputArray src);
+ static Mat subspaceReconstruct(InputArray W, InputArray mean, InputArray src);
+
+protected:
+ bool _dataAsRow; // unused, but needed for 3.0 ABI compatibility.
+ int _num_components;
+ Mat _eigenvectors;
+ Mat _eigenvalues;
+ void lda(InputArrayOfArrays src, InputArray labels);
+};
+
+/** @brief Singular Value Decomposition
+
+Class for computing Singular Value Decomposition of a floating-point
+matrix. The Singular Value Decomposition is used to solve least-square
+problems, under-determined linear systems, invert matrices, compute
+condition numbers, and so on.
+
+If you want to compute a condition number of a matrix or an absolute value of
+its determinant, you do not need `u` and `vt`. You can pass
+flags=SVD::NO_UV|... . Another flag SVD::FULL_UV indicates that full-size u
+and vt must be computed, which is not necessary most of the time.
+
+@sa invert, solve, eigen, determinant
+*/
+class CV_EXPORTS SVD
+{
+public:
+ enum Flags {
+ /** allow the algorithm to modify the decomposed matrix; it can save space and speed up
+ processing. currently ignored. */
+ MODIFY_A = 1,
+ /** indicates that only a vector of singular values `w` is to be processed, while u and vt
+ will be set to empty matrices */
+ NO_UV = 2,
+ /** when the matrix is not square, by default the algorithm produces u and vt matrices of
+ sufficiently large size for the further A reconstruction; if, however, FULL_UV flag is
+ specified, u and vt will be full-size square orthogonal matrices.*/
+ FULL_UV = 4
+ };
+
+ /** @brief the default constructor
+
+ initializes an empty SVD structure
+ */
+ SVD();
+
+ /** @overload
+ initializes an empty SVD structure and then calls SVD::operator()
+ @param src decomposed matrix.
+ @param flags operation flags (SVD::Flags)
+ */
+ SVD( InputArray src, int flags = 0 );
+
+ /** @brief the operator that performs SVD. The previously allocated u, w and vt are released.
+
+ The operator performs the singular value decomposition of the supplied
+ matrix. The u,`vt` , and the vector of singular values w are stored in
+ the structure. The same SVD structure can be reused many times with
+ different matrices. Each time, if needed, the previous u,`vt` , and w
+ are reclaimed and the new matrices are created, which is all handled by
+ Mat::create.
+ @param src decomposed matrix.
+ @param flags operation flags (SVD::Flags)
+ */
+ SVD& operator ()( InputArray src, int flags = 0 );
+
+ /** @brief decomposes matrix and stores the results to user-provided matrices
+
+ The methods/functions perform SVD of matrix. Unlike SVD::SVD constructor
+ and SVD::operator(), they store the results to the user-provided
+ matrices:
+
+ @code{.cpp}
+ Mat A, w, u, vt;
+ SVD::compute(A, w, u, vt);
+ @endcode
+
+ @param src decomposed matrix
+ @param w calculated singular values
+ @param u calculated left singular vectors
+ @param vt transposed matrix of right singular values
+ @param flags operation flags - see SVD::SVD.
+ */
+ static void compute( InputArray src, OutputArray w,
+ OutputArray u, OutputArray vt, int flags = 0 );
+
+ /** @overload
+ computes singular values of a matrix
+ @param src decomposed matrix
+ @param w calculated singular values
+ @param flags operation flags - see SVD::Flags.
+ */
+ static void compute( InputArray src, OutputArray w, int flags = 0 );
+
+ /** @brief performs back substitution
+ */
+ static void backSubst( InputArray w, InputArray u,
+ InputArray vt, InputArray rhs,
+ OutputArray dst );
+
+ /** @brief solves an under-determined singular linear system
+
+ The method finds a unit-length solution x of a singular linear system
+ A\*x = 0. Depending on the rank of A, there can be no solutions, a
+ single solution or an infinite number of solutions. In general, the
+ algorithm solves the following problem:
+ \f[dst = \arg \min _{x: \| x \| =1} \| src \cdot x \|\f]
+ @param src left-hand-side matrix.
+ @param dst found solution.
+ */
+ static void solveZ( InputArray src, OutputArray dst );
+
+ /** @brief performs a singular value back substitution.
+
+ The method calculates a back substitution for the specified right-hand
+ side:
+
+ \f[\texttt{x} = \texttt{vt} ^T \cdot diag( \texttt{w} )^{-1} \cdot \texttt{u} ^T \cdot \texttt{rhs} \sim \texttt{A} ^{-1} \cdot \texttt{rhs}\f]
+
+ Using this technique you can either get a very accurate solution of the
+ convenient linear system, or the best (in the least-squares terms)
+ pseudo-solution of an overdetermined linear system.
+
+ @param rhs right-hand side of a linear system (u\*w\*v')\*dst = rhs to
+ be solved, where A has been previously decomposed.
+
+ @param dst found solution of the system.
+
+ @note Explicit SVD with the further back substitution only makes sense
+ if you need to solve many linear systems with the same left-hand side
+ (for example, src ). If all you need is to solve a single system
+ (possibly with multiple rhs immediately available), simply call solve
+ add pass DECOMP_SVD there. It does absolutely the same thing.
+ */
+ void backSubst( InputArray rhs, OutputArray dst ) const;
+
+ /** @todo document */
+ template<typename _Tp, int m, int n, int nm> static
+ void compute( const Matx<_Tp, m, n>& a, Matx<_Tp, nm, 1>& w, Matx<_Tp, m, nm>& u, Matx<_Tp, n, nm>& vt );
+
+ /** @todo document */
+ template<typename _Tp, int m, int n, int nm> static
+ void compute( const Matx<_Tp, m, n>& a, Matx<_Tp, nm, 1>& w );
+
+ /** @todo document */
+ template<typename _Tp, int m, int n, int nm, int nb> static
+ void backSubst( const Matx<_Tp, nm, 1>& w, const Matx<_Tp, m, nm>& u, const Matx<_Tp, n, nm>& vt, const Matx<_Tp, m, nb>& rhs, Matx<_Tp, n, nb>& dst );
+
+ Mat u, w, vt;
+};
+
+/** @brief Random Number Generator
+
+Random number generator. It encapsulates the state (currently, a 64-bit
+integer) and has methods to return scalar random values and to fill
+arrays with random values. Currently it supports uniform and Gaussian
+(normal) distributions. The generator uses Multiply-With-Carry
+algorithm, introduced by G. Marsaglia (
+<http://en.wikipedia.org/wiki/Multiply-with-carry> ).
+Gaussian-distribution random numbers are generated using the Ziggurat
+algorithm ( <http://en.wikipedia.org/wiki/Ziggurat_algorithm> ),
+introduced by G. Marsaglia and W. W. Tsang.
+*/
+class CV_EXPORTS RNG
+{
+public:
+ enum { UNIFORM = 0,
+ NORMAL = 1
+ };
+
+ /** @brief constructor
+
+ These are the RNG constructors. The first form sets the state to some
+ pre-defined value, equal to 2\*\*32-1 in the current implementation. The
+ second form sets the state to the specified value. If you passed state=0
+ , the constructor uses the above default value instead to avoid the
+ singular random number sequence, consisting of all zeros.
+ */
+ RNG();
+ /** @overload
+ @param state 64-bit value used to initialize the RNG.
+ */
+ RNG(uint64 state);
+ /**The method updates the state using the MWC algorithm and returns the
+ next 32-bit random number.*/
+ unsigned next();
+
+ /**Each of the methods updates the state using the MWC algorithm and
+ returns the next random number of the specified type. In case of integer
+ types, the returned number is from the available value range for the
+ specified type. In case of floating-point types, the returned value is
+ from [0,1) range.
+ */
+ operator uchar();
+ /** @overload */
+ operator schar();
+ /** @overload */
+ operator ushort();
+ /** @overload */
+ operator short();
+ /** @overload */
+ operator unsigned();
+ /** @overload */
+ operator int();
+ /** @overload */
+ operator float();
+ /** @overload */
+ operator double();
+
+ /** @brief returns a random integer sampled uniformly from [0, N).
+
+ The methods transform the state using the MWC algorithm and return the
+ next random number. The first form is equivalent to RNG::next . The
+ second form returns the random number modulo N , which means that the
+ result is in the range [0, N) .
+ */
+ unsigned operator ()();
+ /** @overload
+ @param N upper non-inclusive boundary of the returned random number.
+ */
+ unsigned operator ()(unsigned N);
+
+ /** @brief returns uniformly distributed integer random number from [a,b) range
+
+ The methods transform the state using the MWC algorithm and return the
+ next uniformly-distributed random number of the specified type, deduced
+ from the input parameter type, from the range [a, b) . There is a nuance
+ illustrated by the following sample:
+
+ @code{.cpp}
+ RNG rng;
+
+ // always produces 0
+ double a = rng.uniform(0, 1);
+
+ // produces double from [0, 1)
+ double a1 = rng.uniform((double)0, (double)1);
+
+ // produces float from [0, 1)
+ double b = rng.uniform(0.f, 1.f);
+
+ // produces double from [0, 1)
+ double c = rng.uniform(0., 1.);
+
+ // may cause compiler error because of ambiguity:
+ // RNG::uniform(0, (int)0.999999)? or RNG::uniform((double)0, 0.99999)?
+ double d = rng.uniform(0, 0.999999);
+ @endcode
+
+ The compiler does not take into account the type of the variable to
+ which you assign the result of RNG::uniform . The only thing that
+ matters to the compiler is the type of a and b parameters. So, if you
+ want a floating-point random number, but the range boundaries are
+ integer numbers, either put dots in the end, if they are constants, or
+ use explicit type cast operators, as in the a1 initialization above.
+ @param a lower inclusive boundary of the returned random numbers.
+ @param b upper non-inclusive boundary of the returned random numbers.
+ */
+ int uniform(int a, int b);
+ /** @overload */
+ float uniform(float a, float b);
+ /** @overload */
+ double uniform(double a, double b);
+
+ /** @brief Fills arrays with random numbers.
+
+ @param mat 2D or N-dimensional matrix; currently matrices with more than
+ 4 channels are not supported by the methods, use Mat::reshape as a
+ possible workaround.
+ @param distType distribution type, RNG::UNIFORM or RNG::NORMAL.
+ @param a first distribution parameter; in case of the uniform
+ distribution, this is an inclusive lower boundary, in case of the normal
+ distribution, this is a mean value.
+ @param b second distribution parameter; in case of the uniform
+ distribution, this is a non-inclusive upper boundary, in case of the
+ normal distribution, this is a standard deviation (diagonal of the
+ standard deviation matrix or the full standard deviation matrix).
+ @param saturateRange pre-saturation flag; for uniform distribution only;
+ if true, the method will first convert a and b to the acceptable value
+ range (according to the mat datatype) and then will generate uniformly
+ distributed random numbers within the range [saturate(a), saturate(b)),
+ if saturateRange=false, the method will generate uniformly distributed
+ random numbers in the original range [a, b) and then will saturate them,
+ it means, for example, that
+ <tt>theRNG().fill(mat_8u, RNG::UNIFORM, -DBL_MAX, DBL_MAX)</tt> will likely
+ produce array mostly filled with 0's and 255's, since the range (0, 255)
+ is significantly smaller than [-DBL_MAX, DBL_MAX).
+
+ Each of the methods fills the matrix with the random values from the
+ specified distribution. As the new numbers are generated, the RNG state
+ is updated accordingly. In case of multiple-channel images, every
+ channel is filled independently, which means that RNG cannot generate
+ samples from the multi-dimensional Gaussian distribution with
+ non-diagonal covariance matrix directly. To do that, the method
+ generates samples from multi-dimensional standard Gaussian distribution
+ with zero mean and identity covariation matrix, and then transforms them
+ using transform to get samples from the specified Gaussian distribution.
+ */
+ void fill( InputOutputArray mat, int distType, InputArray a, InputArray b, bool saturateRange = false );
+
+ /** @brief Returns the next random number sampled from the Gaussian distribution
+ @param sigma standard deviation of the distribution.
+
+ The method transforms the state using the MWC algorithm and returns the
+ next random number from the Gaussian distribution N(0,sigma) . That is,
+ the mean value of the returned random numbers is zero and the standard
+ deviation is the specified sigma .
+ */
+ double gaussian(double sigma);
+
+ uint64 state;
+};
+
+/** @brief Mersenne Twister random number generator
+
+Inspired by http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/CODES/mt19937ar.c
+@todo document
+ */
+class CV_EXPORTS RNG_MT19937
+{
+public:
+ RNG_MT19937();
+ RNG_MT19937(unsigned s);
+ void seed(unsigned s);
+
+ unsigned next();
+
+ operator int();
+ operator unsigned();
+ operator float();
+ operator double();
+
+ unsigned operator ()(unsigned N);
+ unsigned operator ()();
+
+ /** @brief returns uniformly distributed integer random number from [a,b) range
+
+*/
+ int uniform(int a, int b);
+ /** @brief returns uniformly distributed floating-point random number from [a,b) range
+
+*/
+ float uniform(float a, float b);
+ /** @brief returns uniformly distributed double-precision floating-point random number from [a,b) range
+
+*/
+ double uniform(double a, double b);
+
+private:
+ enum PeriodParameters {N = 624, M = 397};
+ unsigned state[N];
+ int mti;
+};
+
+//! @} core_array
+
+//! @addtogroup core_cluster
+//! @{
+
+/** @example kmeans.cpp
+ An example on K-means clustering
+*/
+
+/** @brief Finds centers of clusters and groups input samples around the clusters.
+
+The function kmeans implements a k-means algorithm that finds the centers of cluster_count clusters
+and groups the input samples around the clusters. As an output, \f$\texttt{labels}_i\f$ contains a
+0-based cluster index for the sample stored in the \f$i^{th}\f$ row of the samples matrix.
+
+@note
+- (Python) An example on K-means clustering can be found at
+ opencv_source_code/samples/python/kmeans.py
+@param data Data for clustering. An array of N-Dimensional points with float coordinates is needed.
+Examples of this array can be:
+- Mat points(count, 2, CV_32F);
+- Mat points(count, 1, CV_32FC2);
+- Mat points(1, count, CV_32FC2);
+- std::vector\<cv::Point2f\> points(sampleCount);
+@param K Number of clusters to split the set by.
+@param bestLabels Input/output integer array that stores the cluster indices for every sample.
+@param criteria The algorithm termination criteria, that is, the maximum number of iterations and/or
+the desired accuracy. The accuracy is specified as criteria.epsilon. As soon as each of the cluster
+centers moves by less than criteria.epsilon on some iteration, the algorithm stops.
+@param attempts Flag to specify the number of times the algorithm is executed using different
+initial labellings. The algorithm returns the labels that yield the best compactness (see the last
+function parameter).
+@param flags Flag that can take values of cv::KmeansFlags
+@param centers Output matrix of the cluster centers, one row per each cluster center.
+@return The function returns the compactness measure that is computed as
+\f[\sum _i \| \texttt{samples} _i - \texttt{centers} _{ \texttt{labels} _i} \| ^2\f]
+after every attempt. The best (minimum) value is chosen and the corresponding labels and the
+compactness value are returned by the function. Basically, you can use only the core of the
+function, set the number of attempts to 1, initialize labels each time using a custom algorithm,
+pass them with the ( flags = KMEANS_USE_INITIAL_LABELS ) flag, and then choose the best
+(most-compact) clustering.
+*/
+CV_EXPORTS_W double kmeans( InputArray data, int K, InputOutputArray bestLabels,
+ TermCriteria criteria, int attempts,
+ int flags, OutputArray centers = noArray() );
+
+//! @} core_cluster
+
+//! @addtogroup core_basic
+//! @{
+
+/////////////////////////////// Formatted output of cv::Mat ///////////////////////////
+
+/** @todo document */
+class CV_EXPORTS Formatted
+{
+public:
+ virtual const char* next() = 0;
+ virtual void reset() = 0;
+ virtual ~Formatted();
+};
+
+/** @todo document */
+class CV_EXPORTS Formatter
+{
+public:
+ enum { FMT_DEFAULT = 0,
+ FMT_MATLAB = 1,
+ FMT_CSV = 2,
+ FMT_PYTHON = 3,
+ FMT_NUMPY = 4,
+ FMT_C = 5
+ };
+
+ virtual ~Formatter();
+
+ virtual Ptr<Formatted> format(const Mat& mtx) const = 0;
+
+ virtual void set32fPrecision(int p = 8) = 0;
+ virtual void set64fPrecision(int p = 16) = 0;
+ virtual void setMultiline(bool ml = true) = 0;
+
+ static Ptr<Formatter> get(int fmt = FMT_DEFAULT);
+
+};
+
+static inline
+String& operator << (String& out, Ptr<Formatted> fmtd)
+{
+ fmtd->reset();
+ for(const char* str = fmtd->next(); str; str = fmtd->next())
+ out += cv::String(str);
+ return out;
+}
+
+static inline
+String& operator << (String& out, const Mat& mtx)
+{
+ return out << Formatter::get()->format(mtx);
+}
+
+//////////////////////////////////////// Algorithm ////////////////////////////////////
+
+class CV_EXPORTS Algorithm;
+
+template<typename _Tp> struct ParamType {};
+
+
+/** @brief This is a base class for all more or less complex algorithms in OpenCV
+
+especially for classes of algorithms, for which there can be multiple implementations. The examples
+are stereo correspondence (for which there are algorithms like block matching, semi-global block
+matching, graph-cut etc.), background subtraction (which can be done using mixture-of-gaussians
+models, codebook-based algorithm etc.), optical flow (block matching, Lucas-Kanade, Horn-Schunck
+etc.).
+
+Here is example of SIFT use in your application via Algorithm interface:
+@code
+ #include "opencv2/opencv.hpp"
+ #include "opencv2/xfeatures2d.hpp"
+ using namespace cv::xfeatures2d;
+
+ Ptr<Feature2D> sift = SIFT::create();
+ FileStorage fs("sift_params.xml", FileStorage::READ);
+ if( fs.isOpened() ) // if we have file with parameters, read them
+ {
+ sift->read(fs["sift_params"]);
+ fs.release();
+ }
+ else // else modify the parameters and store them; user can later edit the file to use different parameters
+ {
+ sift->setContrastThreshold(0.01f); // lower the contrast threshold, compared to the default value
+ {
+ WriteStructContext ws(fs, "sift_params", CV_NODE_MAP);
+ sift->write(fs);
+ }
+ }
+ Mat image = imread("myimage.png", 0), descriptors;
+ vector<KeyPoint> keypoints;
+ sift->detectAndCompute(image, noArray(), keypoints, descriptors);
+@endcode
+ */
+class CV_EXPORTS_W Algorithm
+{
+public:
+ Algorithm();
+ virtual ~Algorithm();
+
+ /** @brief Clears the algorithm state
+ */
+ CV_WRAP virtual void clear() {}
+
+ /** @brief Stores algorithm parameters in a file storage
+ */
+ virtual void write(FileStorage& fs) const { (void)fs; }
+
+ /** @brief Reads algorithm parameters from a file storage
+ */
+ virtual void read(const FileNode& fn) { (void)fn; }
+
+ /** @brief Returns true if the Algorithm is empty (e.g. in the very beginning or after unsuccessful read
+ */
+ virtual bool empty() const { return false; }
+
+ /** @brief Reads algorithm from the file node
+
+ This is static template method of Algorithm. It's usage is following (in the case of SVM):
+ @code
+ cv::FileStorage fsRead("example.xml", FileStorage::READ);
+ Ptr<SVM> svm = Algorithm::read<SVM>(fsRead.root());
+ @endcode
+ In order to make this method work, the derived class must overwrite Algorithm::read(const
+ FileNode& fn) and also have static create() method without parameters
+ (or with all the optional parameters)
+ */
+ template<typename _Tp> static Ptr<_Tp> read(const FileNode& fn)
+ {
+ Ptr<_Tp> obj = _Tp::create();
+ obj->read(fn);
+ return !obj->empty() ? obj : Ptr<_Tp>();
+ }
+
+ /** @brief Loads algorithm from the file
+
+ @param filename Name of the file to read.
+ @param objname The optional name of the node to read (if empty, the first top-level node will be used)
+
+ This is static template method of Algorithm. It's usage is following (in the case of SVM):
+ @code
+ Ptr<SVM> svm = Algorithm::load<SVM>("my_svm_model.xml");
+ @endcode
+ In order to make this method work, the derived class must overwrite Algorithm::read(const
+ FileNode& fn).
+ */
+ template<typename _Tp> static Ptr<_Tp> load(const String& filename, const String& objname=String())
+ {
+ FileStorage fs(filename, FileStorage::READ);
+ FileNode fn = objname.empty() ? fs.getFirstTopLevelNode() : fs[objname];
+ if (fn.empty()) return Ptr<_Tp>();
+ Ptr<_Tp> obj = _Tp::create();
+ obj->read(fn);
+ return !obj->empty() ? obj : Ptr<_Tp>();
+ }
+
+ /** @brief Loads algorithm from a String
+
+ @param strModel The string variable containing the model you want to load.
+ @param objname The optional name of the node to read (if empty, the first top-level node will be used)
+
+ This is static template method of Algorithm. It's usage is following (in the case of SVM):
+ @code
+ Ptr<SVM> svm = Algorithm::loadFromString<SVM>(myStringModel);
+ @endcode
+ */
+ template<typename _Tp> static Ptr<_Tp> loadFromString(const String& strModel, const String& objname=String())
+ {
+ FileStorage fs(strModel, FileStorage::READ + FileStorage::MEMORY);
+ FileNode fn = objname.empty() ? fs.getFirstTopLevelNode() : fs[objname];
+ Ptr<_Tp> obj = _Tp::create();
+ obj->read(fn);
+ return !obj->empty() ? obj : Ptr<_Tp>();
+ }
+
+ /** Saves the algorithm to a file.
+ In order to make this method work, the derived class must implement Algorithm::write(FileStorage& fs). */
+ CV_WRAP virtual void save(const String& filename) const;
+
+ /** Returns the algorithm string identifier.
+ This string is used as top level xml/yml node tag when the object is saved to a file or string. */
+ CV_WRAP virtual String getDefaultName() const;
+
+protected:
+ void writeFormat(FileStorage& fs) const;
+};
+
+struct Param {
+ enum { INT=0, BOOLEAN=1, REAL=2, STRING=3, MAT=4, MAT_VECTOR=5, ALGORITHM=6, FLOAT=7,
+ UNSIGNED_INT=8, UINT64=9, UCHAR=11 };
+};
+
+
+
+template<> struct ParamType<bool>
+{
+ typedef bool const_param_type;
+ typedef bool member_type;
+
+ enum { type = Param::BOOLEAN };
+};
+
+template<> struct ParamType<int>
+{
+ typedef int const_param_type;
+ typedef int member_type;
+
+ enum { type = Param::INT };
+};
+
+template<> struct ParamType<double>
+{
+ typedef double const_param_type;
+ typedef double member_type;
+
+ enum { type = Param::REAL };
+};
+
+template<> struct ParamType<String>
+{
+ typedef const String& const_param_type;
+ typedef String member_type;
+
+ enum { type = Param::STRING };
+};
+
+template<> struct ParamType<Mat>
+{
+ typedef const Mat& const_param_type;
+ typedef Mat member_type;
+
+ enum { type = Param::MAT };
+};
+
+template<> struct ParamType<std::vector<Mat> >
+{
+ typedef const std::vector<Mat>& const_param_type;
+ typedef std::vector<Mat> member_type;
+
+ enum { type = Param::MAT_VECTOR };
+};
+
+template<> struct ParamType<Algorithm>
+{
+ typedef const Ptr<Algorithm>& const_param_type;
+ typedef Ptr<Algorithm> member_type;
+
+ enum { type = Param::ALGORITHM };
+};
+
+template<> struct ParamType<float>
+{
+ typedef float const_param_type;
+ typedef float member_type;
+
+ enum { type = Param::FLOAT };
+};
+
+template<> struct ParamType<unsigned>
+{
+ typedef unsigned const_param_type;
+ typedef unsigned member_type;
+
+ enum { type = Param::UNSIGNED_INT };
+};
+
+template<> struct ParamType<uint64>
+{
+ typedef uint64 const_param_type;
+ typedef uint64 member_type;
+
+ enum { type = Param::UINT64 };
+};
+
+template<> struct ParamType<uchar>
+{
+ typedef uchar const_param_type;
+ typedef uchar member_type;
+
+ enum { type = Param::UCHAR };
+};
+
+//! @} core_basic
+
+} //namespace cv
+
+#include "opencv2/core/operations.hpp"
+#include "opencv2/core/cvstd.inl.hpp"
+#include "opencv2/core/utility.hpp"
+#include "opencv2/core/optim.hpp"
+#include "opencv2/core/ovx.hpp"
+
+#endif /*OPENCV_CORE_HPP*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/core/affine.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,517 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_CORE_AFFINE3_HPP
+#define OPENCV_CORE_AFFINE3_HPP
+
+#ifdef __cplusplus
+
+#include <opencv2/core.hpp>
+
+namespace cv
+{
+
+//! @addtogroup core
+//! @{
+
+ /** @brief Affine transform
+ @todo document
+ */
+ template<typename T>
+ class Affine3
+ {
+ public:
+ typedef T float_type;
+ typedef Matx<float_type, 3, 3> Mat3;
+ typedef Matx<float_type, 4, 4> Mat4;
+ typedef Vec<float_type, 3> Vec3;
+
+ Affine3();
+
+ //! Augmented affine matrix
+ Affine3(const Mat4& affine);
+
+ //! Rotation matrix
+ Affine3(const Mat3& R, const Vec3& t = Vec3::all(0));
+
+ //! Rodrigues vector
+ Affine3(const Vec3& rvec, const Vec3& t = Vec3::all(0));
+
+ //! Combines all contructors above. Supports 4x4, 4x3, 3x3, 1x3, 3x1 sizes of data matrix
+ explicit Affine3(const Mat& data, const Vec3& t = Vec3::all(0));
+
+ //! From 16th element array
+ explicit Affine3(const float_type* vals);
+
+ //! Create identity transform
+ static Affine3 Identity();
+
+ //! Rotation matrix
+ void rotation(const Mat3& R);
+
+ //! Rodrigues vector
+ void rotation(const Vec3& rvec);
+
+ //! Combines rotation methods above. Suports 3x3, 1x3, 3x1 sizes of data matrix;
+ void rotation(const Mat& data);
+
+ void linear(const Mat3& L);
+ void translation(const Vec3& t);
+
+ Mat3 rotation() const;
+ Mat3 linear() const;
+ Vec3 translation() const;
+
+ //! Rodrigues vector
+ Vec3 rvec() const;
+
+ Affine3 inv(int method = cv::DECOMP_SVD) const;
+
+ //! a.rotate(R) is equivalent to Affine(R, 0) * a;
+ Affine3 rotate(const Mat3& R) const;
+
+ //! a.rotate(rvec) is equivalent to Affine(rvec, 0) * a;
+ Affine3 rotate(const Vec3& rvec) const;
+
+ //! a.translate(t) is equivalent to Affine(E, t) * a;
+ Affine3 translate(const Vec3& t) const;
+
+ //! a.concatenate(affine) is equivalent to affine * a;
+ Affine3 concatenate(const Affine3& affine) const;
+
+ template <typename Y> operator Affine3<Y>() const;
+
+ template <typename Y> Affine3<Y> cast() const;
+
+ Mat4 matrix;
+
+#if defined EIGEN_WORLD_VERSION && defined EIGEN_GEOMETRY_MODULE_H
+ Affine3(const Eigen::Transform<T, 3, Eigen::Affine, (Eigen::RowMajor)>& affine);
+ Affine3(const Eigen::Transform<T, 3, Eigen::Affine>& affine);
+ operator Eigen::Transform<T, 3, Eigen::Affine, (Eigen::RowMajor)>() const;
+ operator Eigen::Transform<T, 3, Eigen::Affine>() const;
+#endif
+ };
+
+ template<typename T> static
+ Affine3<T> operator*(const Affine3<T>& affine1, const Affine3<T>& affine2);
+
+ template<typename T, typename V> static
+ V operator*(const Affine3<T>& affine, const V& vector);
+
+ typedef Affine3<float> Affine3f;
+ typedef Affine3<double> Affine3d;
+
+ static Vec3f operator*(const Affine3f& affine, const Vec3f& vector);
+ static Vec3d operator*(const Affine3d& affine, const Vec3d& vector);
+
+ template<typename _Tp> class DataType< Affine3<_Tp> >
+ {
+ public:
+ typedef Affine3<_Tp> value_type;
+ typedef Affine3<typename DataType<_Tp>::work_type> work_type;
+ typedef _Tp channel_type;
+
+ enum { generic_type = 0,
+ depth = DataType<channel_type>::depth,
+ channels = 16,
+ fmt = DataType<channel_type>::fmt + ((channels - 1) << 8),
+ type = CV_MAKETYPE(depth, channels)
+ };
+
+ typedef Vec<channel_type, channels> vec_type;
+ };
+
+//! @} core
+
+}
+
+//! @cond IGNORED
+
+///////////////////////////////////////////////////////////////////////////////////
+// Implementaiton
+
+template<typename T> inline
+cv::Affine3<T>::Affine3()
+ : matrix(Mat4::eye())
+{}
+
+template<typename T> inline
+cv::Affine3<T>::Affine3(const Mat4& affine)
+ : matrix(affine)
+{}
+
+template<typename T> inline
+cv::Affine3<T>::Affine3(const Mat3& R, const Vec3& t)
+{
+ rotation(R);
+ translation(t);
+ matrix.val[12] = matrix.val[13] = matrix.val[14] = 0;
+ matrix.val[15] = 1;
+}
+
+template<typename T> inline
+cv::Affine3<T>::Affine3(const Vec3& _rvec, const Vec3& t)
+{
+ rotation(_rvec);
+ translation(t);
+ matrix.val[12] = matrix.val[13] = matrix.val[14] = 0;
+ matrix.val[15] = 1;
+}
+
+template<typename T> inline
+cv::Affine3<T>::Affine3(const cv::Mat& data, const Vec3& t)
+{
+ CV_Assert(data.type() == cv::DataType<T>::type);
+
+ if (data.cols == 4 && data.rows == 4)
+ {
+ data.copyTo(matrix);
+ return;
+ }
+ else if (data.cols == 4 && data.rows == 3)
+ {
+ rotation(data(Rect(0, 0, 3, 3)));
+ translation(data(Rect(3, 0, 1, 3)));
+ return;
+ }
+
+ rotation(data);
+ translation(t);
+ matrix.val[12] = matrix.val[13] = matrix.val[14] = 0;
+ matrix.val[15] = 1;
+}
+
+template<typename T> inline
+cv::Affine3<T>::Affine3(const float_type* vals) : matrix(vals)
+{}
+
+template<typename T> inline
+cv::Affine3<T> cv::Affine3<T>::Identity()
+{
+ return Affine3<T>(cv::Affine3<T>::Mat4::eye());
+}
+
+template<typename T> inline
+void cv::Affine3<T>::rotation(const Mat3& R)
+{
+ linear(R);
+}
+
+template<typename T> inline
+void cv::Affine3<T>::rotation(const Vec3& _rvec)
+{
+ double theta = norm(_rvec);
+
+ if (theta < DBL_EPSILON)
+ rotation(Mat3::eye());
+ else
+ {
+ double c = std::cos(theta);
+ double s = std::sin(theta);
+ double c1 = 1. - c;
+ double itheta = (theta != 0) ? 1./theta : 0.;
+
+ Point3_<T> r = _rvec*itheta;
+
+ Mat3 rrt( r.x*r.x, r.x*r.y, r.x*r.z, r.x*r.y, r.y*r.y, r.y*r.z, r.x*r.z, r.y*r.z, r.z*r.z );
+ Mat3 r_x( 0, -r.z, r.y, r.z, 0, -r.x, -r.y, r.x, 0 );
+
+ // R = cos(theta)*I + (1 - cos(theta))*r*rT + sin(theta)*[r_x]
+ // where [r_x] is [0 -rz ry; rz 0 -rx; -ry rx 0]
+ Mat3 R = c*Mat3::eye() + c1*rrt + s*r_x;
+
+ rotation(R);
+ }
+}
+
+//Combines rotation methods above. Suports 3x3, 1x3, 3x1 sizes of data matrix;
+template<typename T> inline
+void cv::Affine3<T>::rotation(const cv::Mat& data)
+{
+ CV_Assert(data.type() == cv::DataType<T>::type);
+
+ if (data.cols == 3 && data.rows == 3)
+ {
+ Mat3 R;
+ data.copyTo(R);
+ rotation(R);
+ }
+ else if ((data.cols == 3 && data.rows == 1) || (data.cols == 1 && data.rows == 3))
+ {
+ Vec3 _rvec;
+ data.reshape(1, 3).copyTo(_rvec);
+ rotation(_rvec);
+ }
+ else
+ CV_Assert(!"Input marix can be 3x3, 1x3 or 3x1");
+}
+
+template<typename T> inline
+void cv::Affine3<T>::linear(const Mat3& L)
+{
+ matrix.val[0] = L.val[0]; matrix.val[1] = L.val[1]; matrix.val[ 2] = L.val[2];
+ matrix.val[4] = L.val[3]; matrix.val[5] = L.val[4]; matrix.val[ 6] = L.val[5];
+ matrix.val[8] = L.val[6]; matrix.val[9] = L.val[7]; matrix.val[10] = L.val[8];
+}
+
+template<typename T> inline
+void cv::Affine3<T>::translation(const Vec3& t)
+{
+ matrix.val[3] = t[0]; matrix.val[7] = t[1]; matrix.val[11] = t[2];
+}
+
+template<typename T> inline
+typename cv::Affine3<T>::Mat3 cv::Affine3<T>::rotation() const
+{
+ return linear();
+}
+
+template<typename T> inline
+typename cv::Affine3<T>::Mat3 cv::Affine3<T>::linear() const
+{
+ typename cv::Affine3<T>::Mat3 R;
+ R.val[0] = matrix.val[0]; R.val[1] = matrix.val[1]; R.val[2] = matrix.val[ 2];
+ R.val[3] = matrix.val[4]; R.val[4] = matrix.val[5]; R.val[5] = matrix.val[ 6];
+ R.val[6] = matrix.val[8]; R.val[7] = matrix.val[9]; R.val[8] = matrix.val[10];
+ return R;
+}
+
+template<typename T> inline
+typename cv::Affine3<T>::Vec3 cv::Affine3<T>::translation() const
+{
+ return Vec3(matrix.val[3], matrix.val[7], matrix.val[11]);
+}
+
+template<typename T> inline
+typename cv::Affine3<T>::Vec3 cv::Affine3<T>::rvec() const
+{
+ cv::Vec3d w;
+ cv::Matx33d u, vt, R = rotation();
+ cv::SVD::compute(R, w, u, vt, cv::SVD::FULL_UV + cv::SVD::MODIFY_A);
+ R = u * vt;
+
+ double rx = R.val[7] - R.val[5];
+ double ry = R.val[2] - R.val[6];
+ double rz = R.val[3] - R.val[1];
+
+ double s = std::sqrt((rx*rx + ry*ry + rz*rz)*0.25);
+ double c = (R.val[0] + R.val[4] + R.val[8] - 1) * 0.5;
+ c = c > 1.0 ? 1.0 : c < -1.0 ? -1.0 : c;
+ double theta = acos(c);
+
+ if( s < 1e-5 )
+ {
+ if( c > 0 )
+ rx = ry = rz = 0;
+ else
+ {
+ double t;
+ t = (R.val[0] + 1) * 0.5;
+ rx = std::sqrt(std::max(t, 0.0));
+ t = (R.val[4] + 1) * 0.5;
+ ry = std::sqrt(std::max(t, 0.0)) * (R.val[1] < 0 ? -1.0 : 1.0);
+ t = (R.val[8] + 1) * 0.5;
+ rz = std::sqrt(std::max(t, 0.0)) * (R.val[2] < 0 ? -1.0 : 1.0);
+
+ if( fabs(rx) < fabs(ry) && fabs(rx) < fabs(rz) && (R.val[5] > 0) != (ry*rz > 0) )
+ rz = -rz;
+ theta /= std::sqrt(rx*rx + ry*ry + rz*rz);
+ rx *= theta;
+ ry *= theta;
+ rz *= theta;
+ }
+ }
+ else
+ {
+ double vth = 1/(2*s);
+ vth *= theta;
+ rx *= vth; ry *= vth; rz *= vth;
+ }
+
+ return cv::Vec3d(rx, ry, rz);
+}
+
+template<typename T> inline
+cv::Affine3<T> cv::Affine3<T>::inv(int method) const
+{
+ return matrix.inv(method);
+}
+
+template<typename T> inline
+cv::Affine3<T> cv::Affine3<T>::rotate(const Mat3& R) const
+{
+ Mat3 Lc = linear();
+ Vec3 tc = translation();
+ Mat4 result;
+ result.val[12] = result.val[13] = result.val[14] = 0;
+ result.val[15] = 1;
+
+ for(int j = 0; j < 3; ++j)
+ {
+ for(int i = 0; i < 3; ++i)
+ {
+ float_type value = 0;
+ for(int k = 0; k < 3; ++k)
+ value += R(j, k) * Lc(k, i);
+ result(j, i) = value;
+ }
+
+ result(j, 3) = R.row(j).dot(tc.t());
+ }
+ return result;
+}
+
+template<typename T> inline
+cv::Affine3<T> cv::Affine3<T>::rotate(const Vec3& _rvec) const
+{
+ return rotate(Affine3f(_rvec).rotation());
+}
+
+template<typename T> inline
+cv::Affine3<T> cv::Affine3<T>::translate(const Vec3& t) const
+{
+ Mat4 m = matrix;
+ m.val[ 3] += t[0];
+ m.val[ 7] += t[1];
+ m.val[11] += t[2];
+ return m;
+}
+
+template<typename T> inline
+cv::Affine3<T> cv::Affine3<T>::concatenate(const Affine3<T>& affine) const
+{
+ return (*this).rotate(affine.rotation()).translate(affine.translation());
+}
+
+template<typename T> template <typename Y> inline
+cv::Affine3<T>::operator Affine3<Y>() const
+{
+ return Affine3<Y>(matrix);
+}
+
+template<typename T> template <typename Y> inline
+cv::Affine3<Y> cv::Affine3<T>::cast() const
+{
+ return Affine3<Y>(matrix);
+}
+
+template<typename T> inline
+cv::Affine3<T> cv::operator*(const cv::Affine3<T>& affine1, const cv::Affine3<T>& affine2)
+{
+ return affine2.concatenate(affine1);
+}
+
+template<typename T, typename V> inline
+V cv::operator*(const cv::Affine3<T>& affine, const V& v)
+{
+ const typename Affine3<T>::Mat4& m = affine.matrix;
+
+ V r;
+ r.x = m.val[0] * v.x + m.val[1] * v.y + m.val[ 2] * v.z + m.val[ 3];
+ r.y = m.val[4] * v.x + m.val[5] * v.y + m.val[ 6] * v.z + m.val[ 7];
+ r.z = m.val[8] * v.x + m.val[9] * v.y + m.val[10] * v.z + m.val[11];
+ return r;
+}
+
+static inline
+cv::Vec3f cv::operator*(const cv::Affine3f& affine, const cv::Vec3f& v)
+{
+ const cv::Matx44f& m = affine.matrix;
+ cv::Vec3f r;
+ r.val[0] = m.val[0] * v[0] + m.val[1] * v[1] + m.val[ 2] * v[2] + m.val[ 3];
+ r.val[1] = m.val[4] * v[0] + m.val[5] * v[1] + m.val[ 6] * v[2] + m.val[ 7];
+ r.val[2] = m.val[8] * v[0] + m.val[9] * v[1] + m.val[10] * v[2] + m.val[11];
+ return r;
+}
+
+static inline
+cv::Vec3d cv::operator*(const cv::Affine3d& affine, const cv::Vec3d& v)
+{
+ const cv::Matx44d& m = affine.matrix;
+ cv::Vec3d r;
+ r.val[0] = m.val[0] * v[0] + m.val[1] * v[1] + m.val[ 2] * v[2] + m.val[ 3];
+ r.val[1] = m.val[4] * v[0] + m.val[5] * v[1] + m.val[ 6] * v[2] + m.val[ 7];
+ r.val[2] = m.val[8] * v[0] + m.val[9] * v[1] + m.val[10] * v[2] + m.val[11];
+ return r;
+}
+
+
+
+#if defined EIGEN_WORLD_VERSION && defined EIGEN_GEOMETRY_MODULE_H
+
+template<typename T> inline
+cv::Affine3<T>::Affine3(const Eigen::Transform<T, 3, Eigen::Affine, (Eigen::RowMajor)>& affine)
+{
+ cv::Mat(4, 4, cv::DataType<T>::type, affine.matrix().data()).copyTo(matrix);
+}
+
+template<typename T> inline
+cv::Affine3<T>::Affine3(const Eigen::Transform<T, 3, Eigen::Affine>& affine)
+{
+ Eigen::Transform<T, 3, Eigen::Affine, (Eigen::RowMajor)> a = affine;
+ cv::Mat(4, 4, cv::DataType<T>::type, a.matrix().data()).copyTo(matrix);
+}
+
+template<typename T> inline
+cv::Affine3<T>::operator Eigen::Transform<T, 3, Eigen::Affine, (Eigen::RowMajor)>() const
+{
+ Eigen::Transform<T, 3, Eigen::Affine, (Eigen::RowMajor)> r;
+ cv::Mat hdr(4, 4, cv::DataType<T>::type, r.matrix().data());
+ cv::Mat(matrix, false).copyTo(hdr);
+ return r;
+}
+
+template<typename T> inline
+cv::Affine3<T>::operator Eigen::Transform<T, 3, Eigen::Affine>() const
+{
+ return this->operator Eigen::Transform<T, 3, Eigen::Affine, (Eigen::RowMajor)>();
+}
+
+#endif /* defined EIGEN_WORLD_VERSION && defined EIGEN_GEOMETRY_MODULE_H */
+
+//! @endcond
+
+#endif /* __cplusplus */
+
+#endif /* OPENCV_CORE_AFFINE3_HPP */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/core/base.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,691 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
+// Copyright (C) 2014, Itseez Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_CORE_BASE_HPP
+#define OPENCV_CORE_BASE_HPP
+
+#ifndef __cplusplus
+# error base.hpp header must be compiled as C++
+#endif
+
+#include "opencv2/opencv_modules.hpp"
+
+#include <climits>
+#include <algorithm>
+
+#include "opencv2/core/cvdef.h"
+#include "opencv2/core/cvstd.hpp"
+
+namespace cv
+{
+
+//! @addtogroup core_utils
+//! @{
+
+namespace Error {
+//! error codes
+enum Code {
+ StsOk= 0, //!< everithing is ok
+ StsBackTrace= -1, //!< pseudo error for back trace
+ StsError= -2, //!< unknown /unspecified error
+ StsInternal= -3, //!< internal error (bad state)
+ StsNoMem= -4, //!< insufficient memory
+ StsBadArg= -5, //!< function arg/param is bad
+ StsBadFunc= -6, //!< unsupported function
+ StsNoConv= -7, //!< iter. didn't converge
+ StsAutoTrace= -8, //!< tracing
+ HeaderIsNull= -9, //!< image header is NULL
+ BadImageSize= -10, //!< image size is invalid
+ BadOffset= -11, //!< offset is invalid
+ BadDataPtr= -12, //!<
+ BadStep= -13, //!<
+ BadModelOrChSeq= -14, //!<
+ BadNumChannels= -15, //!<
+ BadNumChannel1U= -16, //!<
+ BadDepth= -17, //!<
+ BadAlphaChannel= -18, //!<
+ BadOrder= -19, //!<
+ BadOrigin= -20, //!<
+ BadAlign= -21, //!<
+ BadCallBack= -22, //!<
+ BadTileSize= -23, //!<
+ BadCOI= -24, //!<
+ BadROISize= -25, //!<
+ MaskIsTiled= -26, //!<
+ StsNullPtr= -27, //!< null pointer
+ StsVecLengthErr= -28, //!< incorrect vector length
+ StsFilterStructContentErr= -29, //!< incorr. filter structure content
+ StsKernelStructContentErr= -30, //!< incorr. transform kernel content
+ StsFilterOffsetErr= -31, //!< incorrect filter ofset value
+ StsBadSize= -201, //!< the input/output structure size is incorrect
+ StsDivByZero= -202, //!< division by zero
+ StsInplaceNotSupported= -203, //!< in-place operation is not supported
+ StsObjectNotFound= -204, //!< request can't be completed
+ StsUnmatchedFormats= -205, //!< formats of input/output arrays differ
+ StsBadFlag= -206, //!< flag is wrong or not supported
+ StsBadPoint= -207, //!< bad CvPoint
+ StsBadMask= -208, //!< bad format of mask (neither 8uC1 nor 8sC1)
+ StsUnmatchedSizes= -209, //!< sizes of input/output structures do not match
+ StsUnsupportedFormat= -210, //!< the data format/type is not supported by the function
+ StsOutOfRange= -211, //!< some of parameters are out of range
+ StsParseError= -212, //!< invalid syntax/structure of the parsed file
+ StsNotImplemented= -213, //!< the requested function/feature is not implemented
+ StsBadMemBlock= -214, //!< an allocated block has been corrupted
+ StsAssert= -215, //!< assertion failed
+ GpuNotSupported= -216,
+ GpuApiCallError= -217,
+ OpenGlNotSupported= -218,
+ OpenGlApiCallError= -219,
+ OpenCLApiCallError= -220,
+ OpenCLDoubleNotSupported= -221,
+ OpenCLInitError= -222,
+ OpenCLNoAMDBlasFft= -223
+};
+} //Error
+
+//! @} core_utils
+
+//! @addtogroup core_array
+//! @{
+
+//! matrix decomposition types
+enum DecompTypes {
+ /** Gaussian elimination with the optimal pivot element chosen. */
+ DECOMP_LU = 0,
+ /** singular value decomposition (SVD) method; the system can be over-defined and/or the matrix
+ src1 can be singular */
+ DECOMP_SVD = 1,
+ /** eigenvalue decomposition; the matrix src1 must be symmetrical */
+ DECOMP_EIG = 2,
+ /** Cholesky \f$LL^T\f$ factorization; the matrix src1 must be symmetrical and positively
+ defined */
+ DECOMP_CHOLESKY = 3,
+ /** QR factorization; the system can be over-defined and/or the matrix src1 can be singular */
+ DECOMP_QR = 4,
+ /** while all the previous flags are mutually exclusive, this flag can be used together with
+ any of the previous; it means that the normal equations
+ \f$\texttt{src1}^T\cdot\texttt{src1}\cdot\texttt{dst}=\texttt{src1}^T\texttt{src2}\f$ are
+ solved instead of the original system
+ \f$\texttt{src1}\cdot\texttt{dst}=\texttt{src2}\f$ */
+ DECOMP_NORMAL = 16
+};
+
+/** norm types
+- For one array:
+\f[norm = \forkthree{\|\texttt{src1}\|_{L_{\infty}} = \max _I | \texttt{src1} (I)|}{if \(\texttt{normType} = \texttt{NORM_INF}\) }
+{ \| \texttt{src1} \| _{L_1} = \sum _I | \texttt{src1} (I)|}{if \(\texttt{normType} = \texttt{NORM_L1}\) }
+{ \| \texttt{src1} \| _{L_2} = \sqrt{\sum_I \texttt{src1}(I)^2} }{if \(\texttt{normType} = \texttt{NORM_L2}\) }\f]
+
+- Absolute norm for two arrays
+\f[norm = \forkthree{\|\texttt{src1}-\texttt{src2}\|_{L_{\infty}} = \max _I | \texttt{src1} (I) - \texttt{src2} (I)|}{if \(\texttt{normType} = \texttt{NORM_INF}\) }
+{ \| \texttt{src1} - \texttt{src2} \| _{L_1} = \sum _I | \texttt{src1} (I) - \texttt{src2} (I)|}{if \(\texttt{normType} = \texttt{NORM_L1}\) }
+{ \| \texttt{src1} - \texttt{src2} \| _{L_2} = \sqrt{\sum_I (\texttt{src1}(I) - \texttt{src2}(I))^2} }{if \(\texttt{normType} = \texttt{NORM_L2}\) }\f]
+
+- Relative norm for two arrays
+\f[norm = \forkthree{\frac{\|\texttt{src1}-\texttt{src2}\|_{L_{\infty}} }{\|\texttt{src2}\|_{L_{\infty}} }}{if \(\texttt{normType} = \texttt{NORM_RELATIVE_INF}\) }
+{ \frac{\|\texttt{src1}-\texttt{src2}\|_{L_1} }{\|\texttt{src2}\|_{L_1}} }{if \(\texttt{normType} = \texttt{NORM_RELATIVE_L1}\) }
+{ \frac{\|\texttt{src1}-\texttt{src2}\|_{L_2} }{\|\texttt{src2}\|_{L_2}} }{if \(\texttt{normType} = \texttt{NORM_RELATIVE_L2}\) }\f]
+
+As example for one array consider the function \f$r(x)= \begin{pmatrix} x \\ 1-x \end{pmatrix}, x \in [-1;1]\f$.
+The \f$ L_{1}, L_{2} \f$ and \f$ L_{\infty} \f$ norm for the sample value \f$r(-1) = \begin{pmatrix} -1 \\ 2 \end{pmatrix}\f$
+is calculated as follows
+\f{align*}
+ \| r(-1) \|_{L_1} &= |-1| + |2| = 3 \\
+ \| r(-1) \|_{L_2} &= \sqrt{(-1)^{2} + (2)^{2}} = \sqrt{5} \\
+ \| r(-1) \|_{L_\infty} &= \max(|-1|,|2|) = 2
+\f}
+and for \f$r(0.5) = \begin{pmatrix} 0.5 \\ 0.5 \end{pmatrix}\f$ the calculation is
+\f{align*}
+ \| r(0.5) \|_{L_1} &= |0.5| + |0.5| = 1 \\
+ \| r(0.5) \|_{L_2} &= \sqrt{(0.5)^{2} + (0.5)^{2}} = \sqrt{0.5} \\
+ \| r(0.5) \|_{L_\infty} &= \max(|0.5|,|0.5|) = 0.5.
+\f}
+The following graphic shows all values for the three norm functions \f$\| r(x) \|_{L_1}, \| r(x) \|_{L_2}\f$ and \f$\| r(x) \|_{L_\infty}\f$.
+It is notable that the \f$ L_{1} \f$ norm forms the upper and the \f$ L_{\infty} \f$ norm forms the lower border for the example function \f$ r(x) \f$.
+
+ */
+enum NormTypes { NORM_INF = 1,
+ NORM_L1 = 2,
+ NORM_L2 = 4,
+ NORM_L2SQR = 5,
+ NORM_HAMMING = 6,
+ NORM_HAMMING2 = 7,
+ NORM_TYPE_MASK = 7,
+ NORM_RELATIVE = 8, //!< flag
+ NORM_MINMAX = 32 //!< flag
+ };
+
+//! comparison types
+enum CmpTypes { CMP_EQ = 0, //!< src1 is equal to src2.
+ CMP_GT = 1, //!< src1 is greater than src2.
+ CMP_GE = 2, //!< src1 is greater than or equal to src2.
+ CMP_LT = 3, //!< src1 is less than src2.
+ CMP_LE = 4, //!< src1 is less than or equal to src2.
+ CMP_NE = 5 //!< src1 is unequal to src2.
+ };
+
+//! generalized matrix multiplication flags
+enum GemmFlags { GEMM_1_T = 1, //!< transposes src1
+ GEMM_2_T = 2, //!< transposes src2
+ GEMM_3_T = 4 //!< transposes src3
+ };
+
+enum DftFlags {
+ /** performs an inverse 1D or 2D transform instead of the default forward
+ transform. */
+ DFT_INVERSE = 1,
+ /** scales the result: divide it by the number of array elements. Normally, it is
+ combined with DFT_INVERSE. */
+ DFT_SCALE = 2,
+ /** performs a forward or inverse transform of every individual row of the input
+ matrix; this flag enables you to transform multiple vectors simultaneously and can be used to
+ decrease the overhead (which is sometimes several times larger than the processing itself) to
+ perform 3D and higher-dimensional transformations and so forth.*/
+ DFT_ROWS = 4,
+ /** performs a forward transformation of 1D or 2D real array; the result,
+ though being a complex array, has complex-conjugate symmetry (*CCS*, see the function
+ description below for details), and such an array can be packed into a real array of the same
+ size as input, which is the fastest option and which is what the function does by default;
+ however, you may wish to get a full complex array (for simpler spectrum analysis, and so on) -
+ pass the flag to enable the function to produce a full-size complex output array. */
+ DFT_COMPLEX_OUTPUT = 16,
+ /** performs an inverse transformation of a 1D or 2D complex array; the
+ result is normally a complex array of the same size, however, if the input array has
+ conjugate-complex symmetry (for example, it is a result of forward transformation with
+ DFT_COMPLEX_OUTPUT flag), the output is a real array; while the function itself does not
+ check whether the input is symmetrical or not, you can pass the flag and then the function
+ will assume the symmetry and produce the real output array (note that when the input is packed
+ into a real array and inverse transformation is executed, the function treats the input as a
+ packed complex-conjugate symmetrical array, and the output will also be a real array). */
+ DFT_REAL_OUTPUT = 32,
+ /** performs an inverse 1D or 2D transform instead of the default forward transform. */
+ DCT_INVERSE = DFT_INVERSE,
+ /** performs a forward or inverse transform of every individual row of the input
+ matrix. This flag enables you to transform multiple vectors simultaneously and can be used to
+ decrease the overhead (which is sometimes several times larger than the processing itself) to
+ perform 3D and higher-dimensional transforms and so forth.*/
+ DCT_ROWS = DFT_ROWS
+};
+
+//! Various border types, image boundaries are denoted with `|`
+//! @see borderInterpolate, copyMakeBorder
+enum BorderTypes {
+ BORDER_CONSTANT = 0, //!< `iiiiii|abcdefgh|iiiiiii` with some specified `i`
+ BORDER_REPLICATE = 1, //!< `aaaaaa|abcdefgh|hhhhhhh`
+ BORDER_REFLECT = 2, //!< `fedcba|abcdefgh|hgfedcb`
+ BORDER_WRAP = 3, //!< `cdefgh|abcdefgh|abcdefg`
+ BORDER_REFLECT_101 = 4, //!< `gfedcb|abcdefgh|gfedcba`
+ BORDER_TRANSPARENT = 5, //!< `uvwxyz|absdefgh|ijklmno`
+
+ BORDER_REFLECT101 = BORDER_REFLECT_101, //!< same as BORDER_REFLECT_101
+ BORDER_DEFAULT = BORDER_REFLECT_101, //!< same as BORDER_REFLECT_101
+ BORDER_ISOLATED = 16 //!< do not look outside of ROI
+};
+
+//! @} core_array
+
+//! @addtogroup core_utils
+//! @{
+
+//! @cond IGNORED
+
+//////////////// static assert /////////////////
+#define CVAUX_CONCAT_EXP(a, b) a##b
+#define CVAUX_CONCAT(a, b) CVAUX_CONCAT_EXP(a,b)
+
+#if defined(__clang__)
+# ifndef __has_extension
+# define __has_extension __has_feature /* compatibility, for older versions of clang */
+# endif
+# if __has_extension(cxx_static_assert)
+# define CV_StaticAssert(condition, reason) static_assert((condition), reason " " #condition)
+# elif __has_extension(c_static_assert)
+# define CV_StaticAssert(condition, reason) _Static_assert((condition), reason " " #condition)
+# endif
+#elif defined(__GNUC__)
+# if (defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L)
+# define CV_StaticAssert(condition, reason) static_assert((condition), reason " " #condition)
+# endif
+#elif defined(_MSC_VER)
+# if _MSC_VER >= 1600 /* MSVC 10 */
+# define CV_StaticAssert(condition, reason) static_assert((condition), reason " " #condition)
+# endif
+#endif
+#ifndef CV_StaticAssert
+# if !defined(__clang__) && defined(__GNUC__) && (__GNUC__*100 + __GNUC_MINOR__ > 302)
+# define CV_StaticAssert(condition, reason) ({ extern int __attribute__((error("CV_StaticAssert: " reason " " #condition))) CV_StaticAssert(); ((condition) ? 0 : CV_StaticAssert()); })
+# else
+ template <bool x> struct CV_StaticAssert_failed;
+ template <> struct CV_StaticAssert_failed<true> { enum { val = 1 }; };
+ template<int x> struct CV_StaticAssert_test {};
+# define CV_StaticAssert(condition, reason)\
+ typedef cv::CV_StaticAssert_test< sizeof(cv::CV_StaticAssert_failed< static_cast<bool>(condition) >) > CVAUX_CONCAT(CV_StaticAssert_failed_at_, __LINE__)
+# endif
+#endif
+
+// Suppress warning "-Wdeprecated-declarations" / C4996
+#if defined(_MSC_VER)
+ #define CV_DO_PRAGMA(x) __pragma(x)
+#elif defined(__GNUC__)
+ #define CV_DO_PRAGMA(x) _Pragma (#x)
+#else
+ #define CV_DO_PRAGMA(x)
+#endif
+
+#ifdef _MSC_VER
+#define CV_SUPPRESS_DEPRECATED_START \
+ CV_DO_PRAGMA(warning(push)) \
+ CV_DO_PRAGMA(warning(disable: 4996))
+#define CV_SUPPRESS_DEPRECATED_END CV_DO_PRAGMA(warning(pop))
+#elif defined (__clang__) || ((__GNUC__) && (__GNUC__*100 + __GNUC_MINOR__ > 405))
+#define CV_SUPPRESS_DEPRECATED_START \
+ CV_DO_PRAGMA(GCC diagnostic push) \
+ CV_DO_PRAGMA(GCC diagnostic ignored "-Wdeprecated-declarations")
+#define CV_SUPPRESS_DEPRECATED_END CV_DO_PRAGMA(GCC diagnostic pop)
+#else
+#define CV_SUPPRESS_DEPRECATED_START
+#define CV_SUPPRESS_DEPRECATED_END
+#endif
+#define CV_UNUSED(name) (void)name
+//! @endcond
+
+/*! @brief Signals an error and raises the exception.
+
+By default the function prints information about the error to stderr,
+then it either stops if setBreakOnError() had been called before or raises the exception.
+It is possible to alternate error processing by using redirectError().
+@param _code - error code (Error::Code)
+@param _err - error description
+@param _func - function name. Available only when the compiler supports getting it
+@param _file - source file name where the error has occured
+@param _line - line number in the source file where the error has occured
+@see CV_Error, CV_Error_, CV_ErrorNoReturn, CV_ErrorNoReturn_, CV_Assert, CV_DbgAssert
+ */
+CV_EXPORTS void error(int _code, const String& _err, const char* _func, const char* _file, int _line);
+
+#ifdef __GNUC__
+# if defined __clang__ || defined __APPLE__
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Winvalid-noreturn"
+# endif
+#endif
+
+/** same as cv::error, but does not return */
+CV_INLINE CV_NORETURN void errorNoReturn(int _code, const String& _err, const char* _func, const char* _file, int _line)
+{
+ error(_code, _err, _func, _file, _line);
+#ifdef __GNUC__
+# if !defined __clang__ && !defined __APPLE__
+ // this suppresses this warning: "noreturn" function does return [enabled by default]
+ __builtin_trap();
+ // or use infinite loop: for (;;) {}
+# endif
+#endif
+}
+#ifdef __GNUC__
+# if defined __clang__ || defined __APPLE__
+# pragma GCC diagnostic pop
+# endif
+#endif
+
+#if defined __GNUC__
+#define CV_Func __func__
+#elif defined _MSC_VER
+#define CV_Func __FUNCTION__
+#else
+#define CV_Func ""
+#endif
+
+/** @brief Call the error handler.
+
+Currently, the error handler prints the error code and the error message to the standard
+error stream `stderr`. In the Debug configuration, it then provokes memory access violation, so that
+the execution stack and all the parameters can be analyzed by the debugger. In the Release
+configuration, the exception is thrown.
+
+@param code one of Error::Code
+@param msg error message
+*/
+#define CV_Error( code, msg ) cv::error( code, msg, CV_Func, __FILE__, __LINE__ )
+
+/** @brief Call the error handler.
+
+This macro can be used to construct an error message on-fly to include some dynamic information,
+for example:
+@code
+ // note the extra parentheses around the formatted text message
+ CV_Error_( CV_StsOutOfRange,
+ ("the value at (%d, %d)=%g is out of range", badPt.x, badPt.y, badValue));
+@endcode
+@param code one of Error::Code
+@param args printf-like formatted error message in parentheses
+*/
+#define CV_Error_( code, args ) cv::error( code, cv::format args, CV_Func, __FILE__, __LINE__ )
+
+/** @brief Checks a condition at runtime and throws exception if it fails
+
+The macros CV_Assert (and CV_DbgAssert(expr)) evaluate the specified expression. If it is 0, the macros
+raise an error (see cv::error). The macro CV_Assert checks the condition in both Debug and Release
+configurations while CV_DbgAssert is only retained in the Debug configuration.
+*/
+#define CV_Assert( expr ) if(!!(expr)) ; else cv::error( cv::Error::StsAssert, #expr, CV_Func, __FILE__, __LINE__ )
+
+/** same as CV_Error(code,msg), but does not return */
+#define CV_ErrorNoReturn( code, msg ) cv::errorNoReturn( code, msg, CV_Func, __FILE__, __LINE__ )
+
+/** same as CV_Error_(code,args), but does not return */
+#define CV_ErrorNoReturn_( code, args ) cv::errorNoReturn( code, cv::format args, CV_Func, __FILE__, __LINE__ )
+
+/** replaced with CV_Assert(expr) in Debug configuration */
+#ifdef _DEBUG
+# define CV_DbgAssert(expr) CV_Assert(expr)
+#else
+# define CV_DbgAssert(expr)
+#endif
+
+/*
+ * Hamming distance functor - counts the bit differences between two strings - useful for the Brief descriptor
+ * bit count of A exclusive XOR'ed with B
+ */
+struct CV_EXPORTS Hamming
+{
+ enum { normType = NORM_HAMMING };
+ typedef unsigned char ValueType;
+ typedef int ResultType;
+
+ /** this will count the bits in a ^ b
+ */
+ ResultType operator()( const unsigned char* a, const unsigned char* b, int size ) const;
+};
+
+typedef Hamming HammingLUT;
+
+/////////////////////////////////// inline norms ////////////////////////////////////
+
+template<typename _Tp> inline _Tp cv_abs(_Tp x) { return std::abs(x); }
+inline int cv_abs(uchar x) { return x; }
+inline int cv_abs(schar x) { return std::abs(x); }
+inline int cv_abs(ushort x) { return x; }
+inline int cv_abs(short x) { return std::abs(x); }
+
+template<typename _Tp, typename _AccTp> static inline
+_AccTp normL2Sqr(const _Tp* a, int n)
+{
+ _AccTp s = 0;
+ int i=0;
+#if CV_ENABLE_UNROLLED
+ for( ; i <= n - 4; i += 4 )
+ {
+ _AccTp v0 = a[i], v1 = a[i+1], v2 = a[i+2], v3 = a[i+3];
+ s += v0*v0 + v1*v1 + v2*v2 + v3*v3;
+ }
+#endif
+ for( ; i < n; i++ )
+ {
+ _AccTp v = a[i];
+ s += v*v;
+ }
+ return s;
+}
+
+template<typename _Tp, typename _AccTp> static inline
+_AccTp normL1(const _Tp* a, int n)
+{
+ _AccTp s = 0;
+ int i = 0;
+#if CV_ENABLE_UNROLLED
+ for(; i <= n - 4; i += 4 )
+ {
+ s += (_AccTp)cv_abs(a[i]) + (_AccTp)cv_abs(a[i+1]) +
+ (_AccTp)cv_abs(a[i+2]) + (_AccTp)cv_abs(a[i+3]);
+ }
+#endif
+ for( ; i < n; i++ )
+ s += cv_abs(a[i]);
+ return s;
+}
+
+template<typename _Tp, typename _AccTp> static inline
+_AccTp normInf(const _Tp* a, int n)
+{
+ _AccTp s = 0;
+ for( int i = 0; i < n; i++ )
+ s = std::max(s, (_AccTp)cv_abs(a[i]));
+ return s;
+}
+
+template<typename _Tp, typename _AccTp> static inline
+_AccTp normL2Sqr(const _Tp* a, const _Tp* b, int n)
+{
+ _AccTp s = 0;
+ int i= 0;
+#if CV_ENABLE_UNROLLED
+ for(; i <= n - 4; i += 4 )
+ {
+ _AccTp v0 = _AccTp(a[i] - b[i]), v1 = _AccTp(a[i+1] - b[i+1]), v2 = _AccTp(a[i+2] - b[i+2]), v3 = _AccTp(a[i+3] - b[i+3]);
+ s += v0*v0 + v1*v1 + v2*v2 + v3*v3;
+ }
+#endif
+ for( ; i < n; i++ )
+ {
+ _AccTp v = _AccTp(a[i] - b[i]);
+ s += v*v;
+ }
+ return s;
+}
+
+static inline float normL2Sqr(const float* a, const float* b, int n)
+{
+ float s = 0.f;
+ for( int i = 0; i < n; i++ )
+ {
+ float v = a[i] - b[i];
+ s += v*v;
+ }
+ return s;
+}
+
+template<typename _Tp, typename _AccTp> static inline
+_AccTp normL1(const _Tp* a, const _Tp* b, int n)
+{
+ _AccTp s = 0;
+ int i= 0;
+#if CV_ENABLE_UNROLLED
+ for(; i <= n - 4; i += 4 )
+ {
+ _AccTp v0 = _AccTp(a[i] - b[i]), v1 = _AccTp(a[i+1] - b[i+1]), v2 = _AccTp(a[i+2] - b[i+2]), v3 = _AccTp(a[i+3] - b[i+3]);
+ s += std::abs(v0) + std::abs(v1) + std::abs(v2) + std::abs(v3);
+ }
+#endif
+ for( ; i < n; i++ )
+ {
+ _AccTp v = _AccTp(a[i] - b[i]);
+ s += std::abs(v);
+ }
+ return s;
+}
+
+inline float normL1(const float* a, const float* b, int n)
+{
+ float s = 0.f;
+ for( int i = 0; i < n; i++ )
+ {
+ s += std::abs(a[i] - b[i]);
+ }
+ return s;
+}
+
+inline int normL1(const uchar* a, const uchar* b, int n)
+{
+ int s = 0;
+ for( int i = 0; i < n; i++ )
+ {
+ s += std::abs(a[i] - b[i]);
+ }
+ return s;
+}
+
+template<typename _Tp, typename _AccTp> static inline
+_AccTp normInf(const _Tp* a, const _Tp* b, int n)
+{
+ _AccTp s = 0;
+ for( int i = 0; i < n; i++ )
+ {
+ _AccTp v0 = a[i] - b[i];
+ s = std::max(s, std::abs(v0));
+ }
+ return s;
+}
+
+/** @brief Computes the cube root of an argument.
+
+ The function cubeRoot computes \f$\sqrt[3]{\texttt{val}}\f$. Negative arguments are handled correctly.
+ NaN and Inf are not handled. The accuracy approaches the maximum possible accuracy for
+ single-precision data.
+ @param val A function argument.
+ */
+CV_EXPORTS_W float cubeRoot(float val);
+
+/** @brief Calculates the angle of a 2D vector in degrees.
+
+ The function fastAtan2 calculates the full-range angle of an input 2D vector. The angle is measured
+ in degrees and varies from 0 to 360 degrees. The accuracy is about 0.3 degrees.
+ @param x x-coordinate of the vector.
+ @param y y-coordinate of the vector.
+ */
+CV_EXPORTS_W float fastAtan2(float y, float x);
+
+/** proxy for hal::LU */
+CV_EXPORTS int LU(float* A, size_t astep, int m, float* b, size_t bstep, int n);
+/** proxy for hal::LU */
+CV_EXPORTS int LU(double* A, size_t astep, int m, double* b, size_t bstep, int n);
+/** proxy for hal::Cholesky */
+CV_EXPORTS bool Cholesky(float* A, size_t astep, int m, float* b, size_t bstep, int n);
+/** proxy for hal::Cholesky */
+CV_EXPORTS bool Cholesky(double* A, size_t astep, int m, double* b, size_t bstep, int n);
+
+////////////////// forward declarations for important OpenCV types //////////////////
+
+//! @cond IGNORED
+
+template<typename _Tp, int cn> class Vec;
+template<typename _Tp, int m, int n> class Matx;
+
+template<typename _Tp> class Complex;
+template<typename _Tp> class Point_;
+template<typename _Tp> class Point3_;
+template<typename _Tp> class Size_;
+template<typename _Tp> class Rect_;
+template<typename _Tp> class Scalar_;
+
+class CV_EXPORTS RotatedRect;
+class CV_EXPORTS Range;
+class CV_EXPORTS TermCriteria;
+class CV_EXPORTS KeyPoint;
+class CV_EXPORTS DMatch;
+class CV_EXPORTS RNG;
+
+class CV_EXPORTS Mat;
+class CV_EXPORTS MatExpr;
+
+class CV_EXPORTS UMat;
+
+class CV_EXPORTS SparseMat;
+typedef Mat MatND;
+
+template<typename _Tp> class Mat_;
+template<typename _Tp> class SparseMat_;
+
+class CV_EXPORTS MatConstIterator;
+class CV_EXPORTS SparseMatIterator;
+class CV_EXPORTS SparseMatConstIterator;
+template<typename _Tp> class MatIterator_;
+template<typename _Tp> class MatConstIterator_;
+template<typename _Tp> class SparseMatIterator_;
+template<typename _Tp> class SparseMatConstIterator_;
+
+namespace ogl
+{
+ class CV_EXPORTS Buffer;
+ class CV_EXPORTS Texture2D;
+ class CV_EXPORTS Arrays;
+}
+
+namespace cuda
+{
+ class CV_EXPORTS GpuMat;
+ class CV_EXPORTS HostMem;
+ class CV_EXPORTS Stream;
+ class CV_EXPORTS Event;
+}
+
+namespace cudev
+{
+ template <typename _Tp> class GpuMat_;
+}
+
+namespace ipp
+{
+CV_EXPORTS int getIppFeatures();
+CV_EXPORTS void setIppStatus(int status, const char * const funcname = NULL, const char * const filename = NULL,
+ int line = 0);
+CV_EXPORTS int getIppStatus();
+CV_EXPORTS String getIppErrorLocation();
+CV_EXPORTS bool useIPP();
+CV_EXPORTS void setUseIPP(bool flag);
+
+} // ipp
+
+//! @endcond
+
+//! @} core_utils
+
+
+
+
+} // cv
+
+#include "opencv2/core/neon_utils.hpp"
+
+#endif //OPENCV_CORE_BASE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/core/bufferpool.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,31 @@
+// This file is part of OpenCV project.
+// It is subject to the license terms in the LICENSE file found in the top-level directory
+// of this distribution and at http://opencv.org/license.html.
+//
+// Copyright (C) 2014, Advanced Micro Devices, Inc., all rights reserved.
+
+#ifndef OPENCV_CORE_BUFFER_POOL_HPP
+#define OPENCV_CORE_BUFFER_POOL_HPP
+
+namespace cv
+{
+
+//! @addtogroup core
+//! @{
+
+class BufferPoolController
+{
+protected:
+ ~BufferPoolController() { }
+public:
+ virtual size_t getReservedSize() const = 0;
+ virtual size_t getMaxReservedSize() const = 0;
+ virtual void setMaxReservedSize(size_t size) = 0;
+ virtual void freeAllReservedBuffers() = 0;
+};
+
+//! @}
+
+}
+
+#endif // OPENCV_CORE_BUFFER_POOL_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/opencv2/core/core.hpp Fri Jan 29 04:53:38 2021 +0000 @@ -0,0 +1,48 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifdef __OPENCV_BUILD +#error this is a compatibility header which should not be used inside the OpenCV library +#endif + +#include "opencv2/core.hpp"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/core/core_c.h Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,3184 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+
+#ifndef OPENCV_CORE_C_H
+#define OPENCV_CORE_C_H
+
+#include "opencv2/core/types_c.h"
+
+#ifdef __cplusplus
+# ifdef _MSC_VER
+/* disable warning C4190: 'function' has C-linkage specified, but returns UDT 'typename'
+ which is incompatible with C
+
+ It is OK to disable it because we only extend few plain structures with
+ C++ construrtors for simpler interoperability with C++ API of the library
+*/
+# pragma warning(disable:4190)
+# elif defined __clang__ && __clang_major__ >= 3
+# pragma GCC diagnostic ignored "-Wreturn-type-c-linkage"
+# endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @addtogroup core_c
+ @{
+*/
+
+/****************************************************************************************\
+* Array allocation, deallocation, initialization and access to elements *
+\****************************************************************************************/
+
+/** `malloc` wrapper.
+ If there is no enough memory, the function
+ (as well as other OpenCV functions that call cvAlloc)
+ raises an error. */
+CVAPI(void*) cvAlloc( size_t size );
+
+/** `free` wrapper.
+ Here and further all the memory releasing functions
+ (that all call cvFree) take double pointer in order to
+ to clear pointer to the data after releasing it.
+ Passing pointer to NULL pointer is Ok: nothing happens in this case
+*/
+CVAPI(void) cvFree_( void* ptr );
+#define cvFree(ptr) (cvFree_(*(ptr)), *(ptr)=0)
+
+/** @brief Creates an image header but does not allocate the image data.
+
+@param size Image width and height
+@param depth Image depth (see cvCreateImage )
+@param channels Number of channels (see cvCreateImage )
+ */
+CVAPI(IplImage*) cvCreateImageHeader( CvSize size, int depth, int channels );
+
+/** @brief Initializes an image header that was previously allocated.
+
+The returned IplImage\* points to the initialized header.
+@param image Image header to initialize
+@param size Image width and height
+@param depth Image depth (see cvCreateImage )
+@param channels Number of channels (see cvCreateImage )
+@param origin Top-left IPL_ORIGIN_TL or bottom-left IPL_ORIGIN_BL
+@param align Alignment for image rows, typically 4 or 8 bytes
+ */
+CVAPI(IplImage*) cvInitImageHeader( IplImage* image, CvSize size, int depth,
+ int channels, int origin CV_DEFAULT(0),
+ int align CV_DEFAULT(4));
+
+/** @brief Creates an image header and allocates the image data.
+
+This function call is equivalent to the following code:
+@code
+ header = cvCreateImageHeader(size, depth, channels);
+ cvCreateData(header);
+@endcode
+@param size Image width and height
+@param depth Bit depth of image elements. See IplImage for valid depths.
+@param channels Number of channels per pixel. See IplImage for details. This function only creates
+images with interleaved channels.
+ */
+CVAPI(IplImage*) cvCreateImage( CvSize size, int depth, int channels );
+
+/** @brief Deallocates an image header.
+
+This call is an analogue of :
+@code
+ if(image )
+ {
+ iplDeallocate(*image, IPL_IMAGE_HEADER | IPL_IMAGE_ROI);
+ *image = 0;
+ }
+@endcode
+but it does not use IPL functions by default (see the CV_TURN_ON_IPL_COMPATIBILITY macro).
+@param image Double pointer to the image header
+ */
+CVAPI(void) cvReleaseImageHeader( IplImage** image );
+
+/** @brief Deallocates the image header and the image data.
+
+This call is a shortened form of :
+@code
+ if(*image )
+ {
+ cvReleaseData(*image);
+ cvReleaseImageHeader(image);
+ }
+@endcode
+@param image Double pointer to the image header
+*/
+CVAPI(void) cvReleaseImage( IplImage** image );
+
+/** Creates a copy of IPL image (widthStep may differ) */
+CVAPI(IplImage*) cvCloneImage( const IplImage* image );
+
+/** @brief Sets the channel of interest in an IplImage.
+
+If the ROI is set to NULL and the coi is *not* 0, the ROI is allocated. Most OpenCV functions do
+*not* support the COI setting, so to process an individual image/matrix channel one may copy (via
+cvCopy or cvSplit) the channel to a separate image/matrix, process it and then copy the result
+back (via cvCopy or cvMerge) if needed.
+@param image A pointer to the image header
+@param coi The channel of interest. 0 - all channels are selected, 1 - first channel is selected,
+etc. Note that the channel indices become 1-based.
+ */
+CVAPI(void) cvSetImageCOI( IplImage* image, int coi );
+
+/** @brief Returns the index of the channel of interest.
+
+Returns the channel of interest of in an IplImage. Returned values correspond to the coi in
+cvSetImageCOI.
+@param image A pointer to the image header
+ */
+CVAPI(int) cvGetImageCOI( const IplImage* image );
+
+/** @brief Sets an image Region Of Interest (ROI) for a given rectangle.
+
+If the original image ROI was NULL and the rect is not the whole image, the ROI structure is
+allocated.
+
+Most OpenCV functions support the use of ROI and treat the image rectangle as a separate image. For
+example, all of the pixel coordinates are counted from the top-left (or bottom-left) corner of the
+ROI, not the original image.
+@param image A pointer to the image header
+@param rect The ROI rectangle
+ */
+CVAPI(void) cvSetImageROI( IplImage* image, CvRect rect );
+
+/** @brief Resets the image ROI to include the entire image and releases the ROI structure.
+
+This produces a similar result to the following, but in addition it releases the ROI structure. :
+@code
+ cvSetImageROI(image, cvRect(0, 0, image->width, image->height ));
+ cvSetImageCOI(image, 0);
+@endcode
+@param image A pointer to the image header
+ */
+CVAPI(void) cvResetImageROI( IplImage* image );
+
+/** @brief Returns the image ROI.
+
+If there is no ROI set, cvRect(0,0,image-\>width,image-\>height) is returned.
+@param image A pointer to the image header
+ */
+CVAPI(CvRect) cvGetImageROI( const IplImage* image );
+
+/** @brief Creates a matrix header but does not allocate the matrix data.
+
+The function allocates a new matrix header and returns a pointer to it. The matrix data can then be
+allocated using cvCreateData or set explicitly to user-allocated data via cvSetData.
+@param rows Number of rows in the matrix
+@param cols Number of columns in the matrix
+@param type Type of the matrix elements, see cvCreateMat
+ */
+CVAPI(CvMat*) cvCreateMatHeader( int rows, int cols, int type );
+
+#define CV_AUTOSTEP 0x7fffffff
+
+/** @brief Initializes a pre-allocated matrix header.
+
+This function is often used to process raw data with OpenCV matrix functions. For example, the
+following code computes the matrix product of two matrices, stored as ordinary arrays:
+@code
+ double a[] = { 1, 2, 3, 4,
+ 5, 6, 7, 8,
+ 9, 10, 11, 12 };
+
+ double b[] = { 1, 5, 9,
+ 2, 6, 10,
+ 3, 7, 11,
+ 4, 8, 12 };
+
+ double c[9];
+ CvMat Ma, Mb, Mc ;
+
+ cvInitMatHeader(&Ma, 3, 4, CV_64FC1, a);
+ cvInitMatHeader(&Mb, 4, 3, CV_64FC1, b);
+ cvInitMatHeader(&Mc, 3, 3, CV_64FC1, c);
+
+ cvMatMulAdd(&Ma, &Mb, 0, &Mc);
+ // the c array now contains the product of a (3x4) and b (4x3)
+@endcode
+@param mat A pointer to the matrix header to be initialized
+@param rows Number of rows in the matrix
+@param cols Number of columns in the matrix
+@param type Type of the matrix elements, see cvCreateMat .
+@param data Optional: data pointer assigned to the matrix header
+@param step Optional: full row width in bytes of the assigned data. By default, the minimal
+possible step is used which assumes there are no gaps between subsequent rows of the matrix.
+ */
+CVAPI(CvMat*) cvInitMatHeader( CvMat* mat, int rows, int cols,
+ int type, void* data CV_DEFAULT(NULL),
+ int step CV_DEFAULT(CV_AUTOSTEP) );
+
+/** @brief Creates a matrix header and allocates the matrix data.
+
+The function call is equivalent to the following code:
+@code
+ CvMat* mat = cvCreateMatHeader(rows, cols, type);
+ cvCreateData(mat);
+@endcode
+@param rows Number of rows in the matrix
+@param cols Number of columns in the matrix
+@param type The type of the matrix elements in the form
+CV_\<bit depth\>\<S|U|F\>C\<number of channels\> , where S=signed, U=unsigned, F=float. For
+example, CV _ 8UC1 means the elements are 8-bit unsigned and the there is 1 channel, and CV _
+32SC2 means the elements are 32-bit signed and there are 2 channels.
+ */
+CVAPI(CvMat*) cvCreateMat( int rows, int cols, int type );
+
+/** @brief Deallocates a matrix.
+
+The function decrements the matrix data reference counter and deallocates matrix header. If the data
+reference counter is 0, it also deallocates the data. :
+@code
+ if(*mat )
+ cvDecRefData(*mat);
+ cvFree((void**)mat);
+@endcode
+@param mat Double pointer to the matrix
+ */
+CVAPI(void) cvReleaseMat( CvMat** mat );
+
+/** @brief Decrements an array data reference counter.
+
+The function decrements the data reference counter in a CvMat or CvMatND if the reference counter
+
+pointer is not NULL. If the counter reaches zero, the data is deallocated. In the current
+implementation the reference counter is not NULL only if the data was allocated using the
+cvCreateData function. The counter will be NULL in other cases such as: external data was assigned
+to the header using cvSetData, header is part of a larger matrix or image, or the header was
+converted from an image or n-dimensional matrix header.
+@param arr Pointer to an array header
+ */
+CV_INLINE void cvDecRefData( CvArr* arr )
+{
+ if( CV_IS_MAT( arr ))
+ {
+ CvMat* mat = (CvMat*)arr;
+ mat->data.ptr = NULL;
+ if( mat->refcount != NULL && --*mat->refcount == 0 )
+ cvFree( &mat->refcount );
+ mat->refcount = NULL;
+ }
+ else if( CV_IS_MATND( arr ))
+ {
+ CvMatND* mat = (CvMatND*)arr;
+ mat->data.ptr = NULL;
+ if( mat->refcount != NULL && --*mat->refcount == 0 )
+ cvFree( &mat->refcount );
+ mat->refcount = NULL;
+ }
+}
+
+/** @brief Increments array data reference counter.
+
+The function increments CvMat or CvMatND data reference counter and returns the new counter value if
+the reference counter pointer is not NULL, otherwise it returns zero.
+@param arr Array header
+ */
+CV_INLINE int cvIncRefData( CvArr* arr )
+{
+ int refcount = 0;
+ if( CV_IS_MAT( arr ))
+ {
+ CvMat* mat = (CvMat*)arr;
+ if( mat->refcount != NULL )
+ refcount = ++*mat->refcount;
+ }
+ else if( CV_IS_MATND( arr ))
+ {
+ CvMatND* mat = (CvMatND*)arr;
+ if( mat->refcount != NULL )
+ refcount = ++*mat->refcount;
+ }
+ return refcount;
+}
+
+
+/** Creates an exact copy of the input matrix (except, may be, step value) */
+CVAPI(CvMat*) cvCloneMat( const CvMat* mat );
+
+
+/** @brief Returns matrix header corresponding to the rectangular sub-array of input image or matrix.
+
+The function returns header, corresponding to a specified rectangle of the input array. In other
+
+words, it allows the user to treat a rectangular part of input array as a stand-alone array. ROI is
+taken into account by the function so the sub-array of ROI is actually extracted.
+@param arr Input array
+@param submat Pointer to the resultant sub-array header
+@param rect Zero-based coordinates of the rectangle of interest
+ */
+CVAPI(CvMat*) cvGetSubRect( const CvArr* arr, CvMat* submat, CvRect rect );
+#define cvGetSubArr cvGetSubRect
+
+/** @brief Returns array row or row span.
+
+The functions return the header, corresponding to a specified row/row span of the input array.
+cvGetRow(arr, submat, row) is a shortcut for cvGetRows(arr, submat, row, row+1).
+@param arr Input array
+@param submat Pointer to the resulting sub-array header
+@param start_row Zero-based index of the starting row (inclusive) of the span
+@param end_row Zero-based index of the ending row (exclusive) of the span
+@param delta_row Index step in the row span. That is, the function extracts every delta_row -th
+row from start_row and up to (but not including) end_row .
+ */
+CVAPI(CvMat*) cvGetRows( const CvArr* arr, CvMat* submat,
+ int start_row, int end_row,
+ int delta_row CV_DEFAULT(1));
+
+/** @overload
+@param arr Input array
+@param submat Pointer to the resulting sub-array header
+@param row Zero-based index of the selected row
+*/
+CV_INLINE CvMat* cvGetRow( const CvArr* arr, CvMat* submat, int row )
+{
+ return cvGetRows( arr, submat, row, row + 1, 1 );
+}
+
+
+/** @brief Returns one of more array columns.
+
+The functions return the header, corresponding to a specified column span of the input array. That
+
+is, no data is copied. Therefore, any modifications of the submatrix will affect the original array.
+If you need to copy the columns, use cvCloneMat. cvGetCol(arr, submat, col) is a shortcut for
+cvGetCols(arr, submat, col, col+1).
+@param arr Input array
+@param submat Pointer to the resulting sub-array header
+@param start_col Zero-based index of the starting column (inclusive) of the span
+@param end_col Zero-based index of the ending column (exclusive) of the span
+ */
+CVAPI(CvMat*) cvGetCols( const CvArr* arr, CvMat* submat,
+ int start_col, int end_col );
+
+/** @overload
+@param arr Input array
+@param submat Pointer to the resulting sub-array header
+@param col Zero-based index of the selected column
+*/
+CV_INLINE CvMat* cvGetCol( const CvArr* arr, CvMat* submat, int col )
+{
+ return cvGetCols( arr, submat, col, col + 1 );
+}
+
+/** @brief Returns one of array diagonals.
+
+The function returns the header, corresponding to a specified diagonal of the input array.
+@param arr Input array
+@param submat Pointer to the resulting sub-array header
+@param diag Index of the array diagonal. Zero value corresponds to the main diagonal, -1
+corresponds to the diagonal above the main, 1 corresponds to the diagonal below the main, and so
+forth.
+ */
+CVAPI(CvMat*) cvGetDiag( const CvArr* arr, CvMat* submat,
+ int diag CV_DEFAULT(0));
+
+/** low-level scalar <-> raw data conversion functions */
+CVAPI(void) cvScalarToRawData( const CvScalar* scalar, void* data, int type,
+ int extend_to_12 CV_DEFAULT(0) );
+
+CVAPI(void) cvRawDataToScalar( const void* data, int type, CvScalar* scalar );
+
+/** @brief Creates a new matrix header but does not allocate the matrix data.
+
+The function allocates a header for a multi-dimensional dense array. The array data can further be
+allocated using cvCreateData or set explicitly to user-allocated data via cvSetData.
+@param dims Number of array dimensions
+@param sizes Array of dimension sizes
+@param type Type of array elements, see cvCreateMat
+ */
+CVAPI(CvMatND*) cvCreateMatNDHeader( int dims, const int* sizes, int type );
+
+/** @brief Creates the header and allocates the data for a multi-dimensional dense array.
+
+This function call is equivalent to the following code:
+@code
+ CvMatND* mat = cvCreateMatNDHeader(dims, sizes, type);
+ cvCreateData(mat);
+@endcode
+@param dims Number of array dimensions. This must not exceed CV_MAX_DIM (32 by default, but can be
+changed at build time).
+@param sizes Array of dimension sizes.
+@param type Type of array elements, see cvCreateMat .
+ */
+CVAPI(CvMatND*) cvCreateMatND( int dims, const int* sizes, int type );
+
+/** @brief Initializes a pre-allocated multi-dimensional array header.
+
+@param mat A pointer to the array header to be initialized
+@param dims The number of array dimensions
+@param sizes An array of dimension sizes
+@param type Type of array elements, see cvCreateMat
+@param data Optional data pointer assigned to the matrix header
+ */
+CVAPI(CvMatND*) cvInitMatNDHeader( CvMatND* mat, int dims, const int* sizes,
+ int type, void* data CV_DEFAULT(NULL) );
+
+/** @brief Deallocates a multi-dimensional array.
+
+The function decrements the array data reference counter and releases the array header. If the
+reference counter reaches 0, it also deallocates the data. :
+@code
+ if(*mat )
+ cvDecRefData(*mat);
+ cvFree((void**)mat);
+@endcode
+@param mat Double pointer to the array
+ */
+CV_INLINE void cvReleaseMatND( CvMatND** mat )
+{
+ cvReleaseMat( (CvMat**)mat );
+}
+
+/** Creates a copy of CvMatND (except, may be, steps) */
+CVAPI(CvMatND*) cvCloneMatND( const CvMatND* mat );
+
+/** @brief Creates sparse array.
+
+The function allocates a multi-dimensional sparse array. Initially the array contain no elements,
+that is PtrND and other related functions will return 0 for every index.
+@param dims Number of array dimensions. In contrast to the dense matrix, the number of dimensions is
+practically unlimited (up to \f$2^{16}\f$ ).
+@param sizes Array of dimension sizes
+@param type Type of array elements. The same as for CvMat
+ */
+CVAPI(CvSparseMat*) cvCreateSparseMat( int dims, const int* sizes, int type );
+
+/** @brief Deallocates sparse array.
+
+The function releases the sparse array and clears the array pointer upon exit.
+@param mat Double pointer to the array
+ */
+CVAPI(void) cvReleaseSparseMat( CvSparseMat** mat );
+
+/** Creates a copy of CvSparseMat (except, may be, zero items) */
+CVAPI(CvSparseMat*) cvCloneSparseMat( const CvSparseMat* mat );
+
+/** @brief Initializes sparse array elements iterator.
+
+The function initializes iterator of sparse array elements and returns pointer to the first element,
+or NULL if the array is empty.
+@param mat Input array
+@param mat_iterator Initialized iterator
+ */
+CVAPI(CvSparseNode*) cvInitSparseMatIterator( const CvSparseMat* mat,
+ CvSparseMatIterator* mat_iterator );
+
+/** @brief Returns the next sparse matrix element
+
+The function moves iterator to the next sparse matrix element and returns pointer to it. In the
+current version there is no any particular order of the elements, because they are stored in the
+hash table. The sample below demonstrates how to iterate through the sparse matrix:
+@code
+ // print all the non-zero sparse matrix elements and compute their sum
+ double sum = 0;
+ int i, dims = cvGetDims(sparsemat);
+ CvSparseMatIterator it;
+ CvSparseNode* node = cvInitSparseMatIterator(sparsemat, &it);
+
+ for(; node != 0; node = cvGetNextSparseNode(&it))
+ {
+ int* idx = CV_NODE_IDX(array, node);
+ float val = *(float*)CV_NODE_VAL(array, node);
+ printf("M");
+ for(i = 0; i < dims; i++ )
+ printf("[%d]", idx[i]);
+ printf("=%g\n", val);
+
+ sum += val;
+ }
+
+ printf("nTotal sum = %g\n", sum);
+@endcode
+@param mat_iterator Sparse array iterator
+ */
+CV_INLINE CvSparseNode* cvGetNextSparseNode( CvSparseMatIterator* mat_iterator )
+{
+ if( mat_iterator->node->next )
+ return mat_iterator->node = mat_iterator->node->next;
+ else
+ {
+ int idx;
+ for( idx = ++mat_iterator->curidx; idx < mat_iterator->mat->hashsize; idx++ )
+ {
+ CvSparseNode* node = (CvSparseNode*)mat_iterator->mat->hashtable[idx];
+ if( node )
+ {
+ mat_iterator->curidx = idx;
+ return mat_iterator->node = node;
+ }
+ }
+ return NULL;
+ }
+}
+
+
+#define CV_MAX_ARR 10
+
+/** matrix iterator: used for n-ary operations on dense arrays */
+typedef struct CvNArrayIterator
+{
+ int count; /**< number of arrays */
+ int dims; /**< number of dimensions to iterate */
+ CvSize size; /**< maximal common linear size: { width = size, height = 1 } */
+ uchar* ptr[CV_MAX_ARR]; /**< pointers to the array slices */
+ int stack[CV_MAX_DIM]; /**< for internal use */
+ CvMatND* hdr[CV_MAX_ARR]; /**< pointers to the headers of the
+ matrices that are processed */
+}
+CvNArrayIterator;
+
+#define CV_NO_DEPTH_CHECK 1
+#define CV_NO_CN_CHECK 2
+#define CV_NO_SIZE_CHECK 4
+
+/** initializes iterator that traverses through several arrays simulteneously
+ (the function together with cvNextArraySlice is used for
+ N-ari element-wise operations) */
+CVAPI(int) cvInitNArrayIterator( int count, CvArr** arrs,
+ const CvArr* mask, CvMatND* stubs,
+ CvNArrayIterator* array_iterator,
+ int flags CV_DEFAULT(0) );
+
+/** returns zero value if iteration is finished, non-zero (slice length) otherwise */
+CVAPI(int) cvNextNArraySlice( CvNArrayIterator* array_iterator );
+
+
+/** @brief Returns type of array elements.
+
+The function returns type of the array elements. In the case of IplImage the type is converted to
+CvMat-like representation. For example, if the image has been created as:
+@code
+ IplImage* img = cvCreateImage(cvSize(640, 480), IPL_DEPTH_8U, 3);
+@endcode
+The code cvGetElemType(img) will return CV_8UC3.
+@param arr Input array
+ */
+CVAPI(int) cvGetElemType( const CvArr* arr );
+
+/** @brief Return number of array dimensions
+
+The function returns the array dimensionality and the array of dimension sizes. In the case of
+IplImage or CvMat it always returns 2 regardless of number of image/matrix rows. For example, the
+following code calculates total number of array elements:
+@code
+ int sizes[CV_MAX_DIM];
+ int i, total = 1;
+ int dims = cvGetDims(arr, size);
+ for(i = 0; i < dims; i++ )
+ total *= sizes[i];
+@endcode
+@param arr Input array
+@param sizes Optional output vector of the array dimension sizes. For 2d arrays the number of rows
+(height) goes first, number of columns (width) next.
+ */
+CVAPI(int) cvGetDims( const CvArr* arr, int* sizes CV_DEFAULT(NULL) );
+
+
+/** @brief Returns array size along the specified dimension.
+
+@param arr Input array
+@param index Zero-based dimension index (for matrices 0 means number of rows, 1 means number of
+columns; for images 0 means height, 1 means width)
+ */
+CVAPI(int) cvGetDimSize( const CvArr* arr, int index );
+
+
+/** @brief Return pointer to a particular array element.
+
+The functions return a pointer to a specific array element. Number of array dimension should match
+to the number of indices passed to the function except for cvPtr1D function that can be used for
+sequential access to 1D, 2D or nD dense arrays.
+
+The functions can be used for sparse arrays as well - if the requested node does not exist they
+create it and set it to zero.
+
+All these as well as other functions accessing array elements ( cvGetND , cvGetRealND , cvSet
+, cvSetND , cvSetRealND ) raise an error in case if the element index is out of range.
+@param arr Input array
+@param idx0 The first zero-based component of the element index
+@param type Optional output parameter: type of matrix elements
+ */
+CVAPI(uchar*) cvPtr1D( const CvArr* arr, int idx0, int* type CV_DEFAULT(NULL));
+/** @overload */
+CVAPI(uchar*) cvPtr2D( const CvArr* arr, int idx0, int idx1, int* type CV_DEFAULT(NULL) );
+/** @overload */
+CVAPI(uchar*) cvPtr3D( const CvArr* arr, int idx0, int idx1, int idx2,
+ int* type CV_DEFAULT(NULL));
+/** @overload
+@param arr Input array
+@param idx Array of the element indices
+@param type Optional output parameter: type of matrix elements
+@param create_node Optional input parameter for sparse matrices. Non-zero value of the parameter
+means that the requested element is created if it does not exist already.
+@param precalc_hashval Optional input parameter for sparse matrices. If the pointer is not NULL,
+the function does not recalculate the node hash value, but takes it from the specified location.
+It is useful for speeding up pair-wise operations (TODO: provide an example)
+*/
+CVAPI(uchar*) cvPtrND( const CvArr* arr, const int* idx, int* type CV_DEFAULT(NULL),
+ int create_node CV_DEFAULT(1),
+ unsigned* precalc_hashval CV_DEFAULT(NULL));
+
+/** @brief Return a specific array element.
+
+The functions return a specific array element. In the case of a sparse array the functions return 0
+if the requested node does not exist (no new node is created by the functions).
+@param arr Input array
+@param idx0 The first zero-based component of the element index
+ */
+CVAPI(CvScalar) cvGet1D( const CvArr* arr, int idx0 );
+/** @overload */
+CVAPI(CvScalar) cvGet2D( const CvArr* arr, int idx0, int idx1 );
+/** @overload */
+CVAPI(CvScalar) cvGet3D( const CvArr* arr, int idx0, int idx1, int idx2 );
+/** @overload
+@param arr Input array
+@param idx Array of the element indices
+*/
+CVAPI(CvScalar) cvGetND( const CvArr* arr, const int* idx );
+
+/** @brief Return a specific element of single-channel 1D, 2D, 3D or nD array.
+
+Returns a specific element of a single-channel array. If the array has multiple channels, a runtime
+error is raised. Note that Get?D functions can be used safely for both single-channel and
+multiple-channel arrays though they are a bit slower.
+
+In the case of a sparse array the functions return 0 if the requested node does not exist (no new
+node is created by the functions).
+@param arr Input array. Must have a single channel.
+@param idx0 The first zero-based component of the element index
+ */
+CVAPI(double) cvGetReal1D( const CvArr* arr, int idx0 );
+/** @overload */
+CVAPI(double) cvGetReal2D( const CvArr* arr, int idx0, int idx1 );
+/** @overload */
+CVAPI(double) cvGetReal3D( const CvArr* arr, int idx0, int idx1, int idx2 );
+/** @overload
+@param arr Input array. Must have a single channel.
+@param idx Array of the element indices
+*/
+CVAPI(double) cvGetRealND( const CvArr* arr, const int* idx );
+
+/** @brief Change the particular array element.
+
+The functions assign the new value to a particular array element. In the case of a sparse array the
+functions create the node if it does not exist yet.
+@param arr Input array
+@param idx0 The first zero-based component of the element index
+@param value The assigned value
+ */
+CVAPI(void) cvSet1D( CvArr* arr, int idx0, CvScalar value );
+/** @overload */
+CVAPI(void) cvSet2D( CvArr* arr, int idx0, int idx1, CvScalar value );
+/** @overload */
+CVAPI(void) cvSet3D( CvArr* arr, int idx0, int idx1, int idx2, CvScalar value );
+/** @overload
+@param arr Input array
+@param idx Array of the element indices
+@param value The assigned value
+*/
+CVAPI(void) cvSetND( CvArr* arr, const int* idx, CvScalar value );
+
+/** @brief Change a specific array element.
+
+The functions assign a new value to a specific element of a single-channel array. If the array has
+multiple channels, a runtime error is raised. Note that the Set\*D function can be used safely for
+both single-channel and multiple-channel arrays, though they are a bit slower.
+
+In the case of a sparse array the functions create the node if it does not yet exist.
+@param arr Input array
+@param idx0 The first zero-based component of the element index
+@param value The assigned value
+ */
+CVAPI(void) cvSetReal1D( CvArr* arr, int idx0, double value );
+/** @overload */
+CVAPI(void) cvSetReal2D( CvArr* arr, int idx0, int idx1, double value );
+/** @overload */
+CVAPI(void) cvSetReal3D( CvArr* arr, int idx0,
+ int idx1, int idx2, double value );
+/** @overload
+@param arr Input array
+@param idx Array of the element indices
+@param value The assigned value
+*/
+CVAPI(void) cvSetRealND( CvArr* arr, const int* idx, double value );
+
+/** clears element of ND dense array,
+ in case of sparse arrays it deletes the specified node */
+CVAPI(void) cvClearND( CvArr* arr, const int* idx );
+
+/** @brief Returns matrix header for arbitrary array.
+
+The function returns a matrix header for the input array that can be a matrix - CvMat, an image -
+IplImage, or a multi-dimensional dense array - CvMatND (the third option is allowed only if
+allowND != 0) . In the case of matrix the function simply returns the input pointer. In the case of
+IplImage\* or CvMatND it initializes the header structure with parameters of the current image ROI
+and returns &header. Because COI is not supported by CvMat, it is returned separately.
+
+The function provides an easy way to handle both types of arrays - IplImage and CvMat using the same
+code. Input array must have non-zero data pointer, otherwise the function will report an error.
+
+@note If the input array is IplImage with planar data layout and COI set, the function returns the
+pointer to the selected plane and COI == 0. This feature allows user to process IplImage structures
+with planar data layout, even though OpenCV does not support such images.
+@param arr Input array
+@param header Pointer to CvMat structure used as a temporary buffer
+@param coi Optional output parameter for storing COI
+@param allowND If non-zero, the function accepts multi-dimensional dense arrays (CvMatND\*) and
+returns 2D matrix (if CvMatND has two dimensions) or 1D matrix (when CvMatND has 1 dimension or
+more than 2 dimensions). The CvMatND array must be continuous.
+@sa cvGetImage, cvarrToMat.
+ */
+CVAPI(CvMat*) cvGetMat( const CvArr* arr, CvMat* header,
+ int* coi CV_DEFAULT(NULL),
+ int allowND CV_DEFAULT(0));
+
+/** @brief Returns image header for arbitrary array.
+
+The function returns the image header for the input array that can be a matrix (CvMat) or image
+(IplImage). In the case of an image the function simply returns the input pointer. In the case of
+CvMat it initializes an image_header structure with the parameters of the input matrix. Note that
+if we transform IplImage to CvMat using cvGetMat and then transform CvMat back to IplImage using
+this function, we will get different headers if the ROI is set in the original image.
+@param arr Input array
+@param image_header Pointer to IplImage structure used as a temporary buffer
+ */
+CVAPI(IplImage*) cvGetImage( const CvArr* arr, IplImage* image_header );
+
+
+/** @brief Changes the shape of a multi-dimensional array without copying the data.
+
+The function is an advanced version of cvReshape that can work with multi-dimensional arrays as
+well (though it can work with ordinary images and matrices) and change the number of dimensions.
+
+Below are the two samples from the cvReshape description rewritten using cvReshapeMatND:
+@code
+ IplImage* color_img = cvCreateImage(cvSize(320,240), IPL_DEPTH_8U, 3);
+ IplImage gray_img_hdr, *gray_img;
+ gray_img = (IplImage*)cvReshapeMatND(color_img, sizeof(gray_img_hdr), &gray_img_hdr, 1, 0, 0);
+ ...
+ int size[] = { 2, 2, 2 };
+ CvMatND* mat = cvCreateMatND(3, size, CV_32F);
+ CvMat row_header, *row;
+ row = (CvMat*)cvReshapeMatND(mat, sizeof(row_header), &row_header, 0, 1, 0);
+@endcode
+In C, the header file for this function includes a convenient macro cvReshapeND that does away with
+the sizeof_header parameter. So, the lines containing the call to cvReshapeMatND in the examples
+may be replaced as follow:
+@code
+ gray_img = (IplImage*)cvReshapeND(color_img, &gray_img_hdr, 1, 0, 0);
+ ...
+ row = (CvMat*)cvReshapeND(mat, &row_header, 0, 1, 0);
+@endcode
+@param arr Input array
+@param sizeof_header Size of output header to distinguish between IplImage, CvMat and CvMatND
+output headers
+@param header Output header to be filled
+@param new_cn New number of channels. new_cn = 0 means that the number of channels remains
+unchanged.
+@param new_dims New number of dimensions. new_dims = 0 means that the number of dimensions
+remains the same.
+@param new_sizes Array of new dimension sizes. Only new_dims-1 values are used, because the
+total number of elements must remain the same. Thus, if new_dims = 1, new_sizes array is not
+used.
+ */
+CVAPI(CvArr*) cvReshapeMatND( const CvArr* arr,
+ int sizeof_header, CvArr* header,
+ int new_cn, int new_dims, int* new_sizes );
+
+#define cvReshapeND( arr, header, new_cn, new_dims, new_sizes ) \
+ cvReshapeMatND( (arr), sizeof(*(header)), (header), \
+ (new_cn), (new_dims), (new_sizes))
+
+/** @brief Changes shape of matrix/image without copying data.
+
+The function initializes the CvMat header so that it points to the same data as the original array
+but has a different shape - different number of channels, different number of rows, or both.
+
+The following example code creates one image buffer and two image headers, the first is for a
+320x240x3 image and the second is for a 960x240x1 image:
+@code
+ IplImage* color_img = cvCreateImage(cvSize(320,240), IPL_DEPTH_8U, 3);
+ CvMat gray_mat_hdr;
+ IplImage gray_img_hdr, *gray_img;
+ cvReshape(color_img, &gray_mat_hdr, 1);
+ gray_img = cvGetImage(&gray_mat_hdr, &gray_img_hdr);
+@endcode
+And the next example converts a 3x3 matrix to a single 1x9 vector:
+@code
+ CvMat* mat = cvCreateMat(3, 3, CV_32F);
+ CvMat row_header, *row;
+ row = cvReshape(mat, &row_header, 0, 1);
+@endcode
+@param arr Input array
+@param header Output header to be filled
+@param new_cn New number of channels. 'new_cn = 0' means that the number of channels remains
+unchanged.
+@param new_rows New number of rows. 'new_rows = 0' means that the number of rows remains
+unchanged unless it needs to be changed according to new_cn value.
+*/
+CVAPI(CvMat*) cvReshape( const CvArr* arr, CvMat* header,
+ int new_cn, int new_rows CV_DEFAULT(0) );
+
+/** Repeats source 2d array several times in both horizontal and
+ vertical direction to fill destination array */
+CVAPI(void) cvRepeat( const CvArr* src, CvArr* dst );
+
+/** @brief Allocates array data
+
+The function allocates image, matrix or multi-dimensional dense array data. Note that in the case of
+matrix types OpenCV allocation functions are used. In the case of IplImage they are used unless
+CV_TURN_ON_IPL_COMPATIBILITY() has been called before. In the latter case IPL functions are used
+to allocate the data.
+@param arr Array header
+ */
+CVAPI(void) cvCreateData( CvArr* arr );
+
+/** @brief Releases array data.
+
+The function releases the array data. In the case of CvMat or CvMatND it simply calls
+cvDecRefData(), that is the function can not deallocate external data. See also the note to
+cvCreateData .
+@param arr Array header
+ */
+CVAPI(void) cvReleaseData( CvArr* arr );
+
+/** @brief Assigns user data to the array header.
+
+The function assigns user data to the array header. Header should be initialized before using
+cvCreateMatHeader, cvCreateImageHeader, cvCreateMatNDHeader, cvInitMatHeader,
+cvInitImageHeader or cvInitMatNDHeader.
+@param arr Array header
+@param data User data
+@param step Full row length in bytes
+ */
+CVAPI(void) cvSetData( CvArr* arr, void* data, int step );
+
+/** @brief Retrieves low-level information about the array.
+
+The function fills output variables with low-level information about the array data. All output
+
+parameters are optional, so some of the pointers may be set to NULL. If the array is IplImage with
+ROI set, the parameters of ROI are returned.
+
+The following example shows how to get access to array elements. It computes absolute values of the
+array elements :
+@code
+ float* data;
+ int step;
+ CvSize size;
+
+ cvGetRawData(array, (uchar**)&data, &step, &size);
+ step /= sizeof(data[0]);
+
+ for(int y = 0; y < size.height; y++, data += step )
+ for(int x = 0; x < size.width; x++ )
+ data[x] = (float)fabs(data[x]);
+@endcode
+@param arr Array header
+@param data Output pointer to the whole image origin or ROI origin if ROI is set
+@param step Output full row length in bytes
+@param roi_size Output ROI size
+ */
+CVAPI(void) cvGetRawData( const CvArr* arr, uchar** data,
+ int* step CV_DEFAULT(NULL),
+ CvSize* roi_size CV_DEFAULT(NULL));
+
+/** @brief Returns size of matrix or image ROI.
+
+The function returns number of rows (CvSize::height) and number of columns (CvSize::width) of the
+input matrix or image. In the case of image the size of ROI is returned.
+@param arr array header
+ */
+CVAPI(CvSize) cvGetSize( const CvArr* arr );
+
+/** @brief Copies one array to another.
+
+The function copies selected elements from an input array to an output array:
+
+\f[\texttt{dst} (I)= \texttt{src} (I) \quad \text{if} \quad \texttt{mask} (I) \ne 0.\f]
+
+If any of the passed arrays is of IplImage type, then its ROI and COI fields are used. Both arrays
+must have the same type, the same number of dimensions, and the same size. The function can also
+copy sparse arrays (mask is not supported in this case).
+@param src The source array
+@param dst The destination array
+@param mask Operation mask, 8-bit single channel array; specifies elements of the destination array
+to be changed
+ */
+CVAPI(void) cvCopy( const CvArr* src, CvArr* dst,
+ const CvArr* mask CV_DEFAULT(NULL) );
+
+/** @brief Sets every element of an array to a given value.
+
+The function copies the scalar value to every selected element of the destination array:
+\f[\texttt{arr} (I)= \texttt{value} \quad \text{if} \quad \texttt{mask} (I) \ne 0\f]
+If array arr is of IplImage type, then is ROI used, but COI must not be set.
+@param arr The destination array
+@param value Fill value
+@param mask Operation mask, 8-bit single channel array; specifies elements of the destination
+array to be changed
+ */
+CVAPI(void) cvSet( CvArr* arr, CvScalar value,
+ const CvArr* mask CV_DEFAULT(NULL) );
+
+/** @brief Clears the array.
+
+The function clears the array. In the case of dense arrays (CvMat, CvMatND or IplImage),
+cvZero(array) is equivalent to cvSet(array,cvScalarAll(0),0). In the case of sparse arrays all the
+elements are removed.
+@param arr Array to be cleared
+ */
+CVAPI(void) cvSetZero( CvArr* arr );
+#define cvZero cvSetZero
+
+
+/** Splits a multi-channel array into the set of single-channel arrays or
+ extracts particular [color] plane */
+CVAPI(void) cvSplit( const CvArr* src, CvArr* dst0, CvArr* dst1,
+ CvArr* dst2, CvArr* dst3 );
+
+/** Merges a set of single-channel arrays into the single multi-channel array
+ or inserts one particular [color] plane to the array */
+CVAPI(void) cvMerge( const CvArr* src0, const CvArr* src1,
+ const CvArr* src2, const CvArr* src3,
+ CvArr* dst );
+
+/** Copies several channels from input arrays to
+ certain channels of output arrays */
+CVAPI(void) cvMixChannels( const CvArr** src, int src_count,
+ CvArr** dst, int dst_count,
+ const int* from_to, int pair_count );
+
+/** @brief Converts one array to another with optional linear transformation.
+
+The function has several different purposes, and thus has several different names. It copies one
+array to another with optional scaling, which is performed first, and/or optional type conversion,
+performed after:
+
+\f[\texttt{dst} (I) = \texttt{scale} \texttt{src} (I) + ( \texttt{shift} _0, \texttt{shift} _1,...)\f]
+
+All the channels of multi-channel arrays are processed independently.
+
+The type of conversion is done with rounding and saturation, that is if the result of scaling +
+conversion can not be represented exactly by a value of the destination array element type, it is
+set to the nearest representable value on the real axis.
+@param src Source array
+@param dst Destination array
+@param scale Scale factor
+@param shift Value added to the scaled source array elements
+ */
+CVAPI(void) cvConvertScale( const CvArr* src, CvArr* dst,
+ double scale CV_DEFAULT(1),
+ double shift CV_DEFAULT(0) );
+#define cvCvtScale cvConvertScale
+#define cvScale cvConvertScale
+#define cvConvert( src, dst ) cvConvertScale( (src), (dst), 1, 0 )
+
+
+/** Performs linear transformation on every source array element,
+ stores absolute value of the result:
+ dst(x,y,c) = abs(scale*src(x,y,c)+shift).
+ destination array must have 8u type.
+ In other cases one may use cvConvertScale + cvAbsDiffS */
+CVAPI(void) cvConvertScaleAbs( const CvArr* src, CvArr* dst,
+ double scale CV_DEFAULT(1),
+ double shift CV_DEFAULT(0) );
+#define cvCvtScaleAbs cvConvertScaleAbs
+
+
+/** checks termination criteria validity and
+ sets eps to default_eps (if it is not set),
+ max_iter to default_max_iters (if it is not set)
+*/
+CVAPI(CvTermCriteria) cvCheckTermCriteria( CvTermCriteria criteria,
+ double default_eps,
+ int default_max_iters );
+
+/****************************************************************************************\
+* Arithmetic, logic and comparison operations *
+\****************************************************************************************/
+
+/** dst(mask) = src1(mask) + src2(mask) */
+CVAPI(void) cvAdd( const CvArr* src1, const CvArr* src2, CvArr* dst,
+ const CvArr* mask CV_DEFAULT(NULL));
+
+/** dst(mask) = src(mask) + value */
+CVAPI(void) cvAddS( const CvArr* src, CvScalar value, CvArr* dst,
+ const CvArr* mask CV_DEFAULT(NULL));
+
+/** dst(mask) = src1(mask) - src2(mask) */
+CVAPI(void) cvSub( const CvArr* src1, const CvArr* src2, CvArr* dst,
+ const CvArr* mask CV_DEFAULT(NULL));
+
+/** dst(mask) = src(mask) - value = src(mask) + (-value) */
+CV_INLINE void cvSubS( const CvArr* src, CvScalar value, CvArr* dst,
+ const CvArr* mask CV_DEFAULT(NULL))
+{
+ cvAddS( src, cvScalar( -value.val[0], -value.val[1], -value.val[2], -value.val[3]),
+ dst, mask );
+}
+
+/** dst(mask) = value - src(mask) */
+CVAPI(void) cvSubRS( const CvArr* src, CvScalar value, CvArr* dst,
+ const CvArr* mask CV_DEFAULT(NULL));
+
+/** dst(idx) = src1(idx) * src2(idx) * scale
+ (scaled element-wise multiplication of 2 arrays) */
+CVAPI(void) cvMul( const CvArr* src1, const CvArr* src2,
+ CvArr* dst, double scale CV_DEFAULT(1) );
+
+/** element-wise division/inversion with scaling:
+ dst(idx) = src1(idx) * scale / src2(idx)
+ or dst(idx) = scale / src2(idx) if src1 == 0 */
+CVAPI(void) cvDiv( const CvArr* src1, const CvArr* src2,
+ CvArr* dst, double scale CV_DEFAULT(1));
+
+/** dst = src1 * scale + src2 */
+CVAPI(void) cvScaleAdd( const CvArr* src1, CvScalar scale,
+ const CvArr* src2, CvArr* dst );
+#define cvAXPY( A, real_scalar, B, C ) cvScaleAdd(A, cvRealScalar(real_scalar), B, C)
+
+/** dst = src1 * alpha + src2 * beta + gamma */
+CVAPI(void) cvAddWeighted( const CvArr* src1, double alpha,
+ const CvArr* src2, double beta,
+ double gamma, CvArr* dst );
+
+/** @brief Calculates the dot product of two arrays in Euclidean metrics.
+
+The function calculates and returns the Euclidean dot product of two arrays.
+
+\f[src1 \bullet src2 = \sum _I ( \texttt{src1} (I) \texttt{src2} (I))\f]
+
+In the case of multiple channel arrays, the results for all channels are accumulated. In particular,
+cvDotProduct(a,a) where a is a complex vector, will return \f$||\texttt{a}||^2\f$. The function can
+process multi-dimensional arrays, row by row, layer by layer, and so on.
+@param src1 The first source array
+@param src2 The second source array
+ */
+CVAPI(double) cvDotProduct( const CvArr* src1, const CvArr* src2 );
+
+/** dst(idx) = src1(idx) & src2(idx) */
+CVAPI(void) cvAnd( const CvArr* src1, const CvArr* src2,
+ CvArr* dst, const CvArr* mask CV_DEFAULT(NULL));
+
+/** dst(idx) = src(idx) & value */
+CVAPI(void) cvAndS( const CvArr* src, CvScalar value,
+ CvArr* dst, const CvArr* mask CV_DEFAULT(NULL));
+
+/** dst(idx) = src1(idx) | src2(idx) */
+CVAPI(void) cvOr( const CvArr* src1, const CvArr* src2,
+ CvArr* dst, const CvArr* mask CV_DEFAULT(NULL));
+
+/** dst(idx) = src(idx) | value */
+CVAPI(void) cvOrS( const CvArr* src, CvScalar value,
+ CvArr* dst, const CvArr* mask CV_DEFAULT(NULL));
+
+/** dst(idx) = src1(idx) ^ src2(idx) */
+CVAPI(void) cvXor( const CvArr* src1, const CvArr* src2,
+ CvArr* dst, const CvArr* mask CV_DEFAULT(NULL));
+
+/** dst(idx) = src(idx) ^ value */
+CVAPI(void) cvXorS( const CvArr* src, CvScalar value,
+ CvArr* dst, const CvArr* mask CV_DEFAULT(NULL));
+
+/** dst(idx) = ~src(idx) */
+CVAPI(void) cvNot( const CvArr* src, CvArr* dst );
+
+/** dst(idx) = lower(idx) <= src(idx) < upper(idx) */
+CVAPI(void) cvInRange( const CvArr* src, const CvArr* lower,
+ const CvArr* upper, CvArr* dst );
+
+/** dst(idx) = lower <= src(idx) < upper */
+CVAPI(void) cvInRangeS( const CvArr* src, CvScalar lower,
+ CvScalar upper, CvArr* dst );
+
+#define CV_CMP_EQ 0
+#define CV_CMP_GT 1
+#define CV_CMP_GE 2
+#define CV_CMP_LT 3
+#define CV_CMP_LE 4
+#define CV_CMP_NE 5
+
+/** The comparison operation support single-channel arrays only.
+ Destination image should be 8uC1 or 8sC1 */
+
+/** dst(idx) = src1(idx) _cmp_op_ src2(idx) */
+CVAPI(void) cvCmp( const CvArr* src1, const CvArr* src2, CvArr* dst, int cmp_op );
+
+/** dst(idx) = src1(idx) _cmp_op_ value */
+CVAPI(void) cvCmpS( const CvArr* src, double value, CvArr* dst, int cmp_op );
+
+/** dst(idx) = min(src1(idx),src2(idx)) */
+CVAPI(void) cvMin( const CvArr* src1, const CvArr* src2, CvArr* dst );
+
+/** dst(idx) = max(src1(idx),src2(idx)) */
+CVAPI(void) cvMax( const CvArr* src1, const CvArr* src2, CvArr* dst );
+
+/** dst(idx) = min(src(idx),value) */
+CVAPI(void) cvMinS( const CvArr* src, double value, CvArr* dst );
+
+/** dst(idx) = max(src(idx),value) */
+CVAPI(void) cvMaxS( const CvArr* src, double value, CvArr* dst );
+
+/** dst(x,y,c) = abs(src1(x,y,c) - src2(x,y,c)) */
+CVAPI(void) cvAbsDiff( const CvArr* src1, const CvArr* src2, CvArr* dst );
+
+/** dst(x,y,c) = abs(src(x,y,c) - value(c)) */
+CVAPI(void) cvAbsDiffS( const CvArr* src, CvArr* dst, CvScalar value );
+#define cvAbs( src, dst ) cvAbsDiffS( (src), (dst), cvScalarAll(0))
+
+/****************************************************************************************\
+* Math operations *
+\****************************************************************************************/
+
+/** Does cartesian->polar coordinates conversion.
+ Either of output components (magnitude or angle) is optional */
+CVAPI(void) cvCartToPolar( const CvArr* x, const CvArr* y,
+ CvArr* magnitude, CvArr* angle CV_DEFAULT(NULL),
+ int angle_in_degrees CV_DEFAULT(0));
+
+/** Does polar->cartesian coordinates conversion.
+ Either of output components (magnitude or angle) is optional.
+ If magnitude is missing it is assumed to be all 1's */
+CVAPI(void) cvPolarToCart( const CvArr* magnitude, const CvArr* angle,
+ CvArr* x, CvArr* y,
+ int angle_in_degrees CV_DEFAULT(0));
+
+/** Does powering: dst(idx) = src(idx)^power */
+CVAPI(void) cvPow( const CvArr* src, CvArr* dst, double power );
+
+/** Does exponention: dst(idx) = exp(src(idx)).
+ Overflow is not handled yet. Underflow is handled.
+ Maximal relative error is ~7e-6 for single-precision input */
+CVAPI(void) cvExp( const CvArr* src, CvArr* dst );
+
+/** Calculates natural logarithms: dst(idx) = log(abs(src(idx))).
+ Logarithm of 0 gives large negative number(~-700)
+ Maximal relative error is ~3e-7 for single-precision output
+*/
+CVAPI(void) cvLog( const CvArr* src, CvArr* dst );
+
+/** Fast arctangent calculation */
+CVAPI(float) cvFastArctan( float y, float x );
+
+/** Fast cubic root calculation */
+CVAPI(float) cvCbrt( float value );
+
+#define CV_CHECK_RANGE 1
+#define CV_CHECK_QUIET 2
+/** Checks array values for NaNs, Infs or simply for too large numbers
+ (if CV_CHECK_RANGE is set). If CV_CHECK_QUIET is set,
+ no runtime errors is raised (function returns zero value in case of "bad" values).
+ Otherwise cvError is called */
+CVAPI(int) cvCheckArr( const CvArr* arr, int flags CV_DEFAULT(0),
+ double min_val CV_DEFAULT(0), double max_val CV_DEFAULT(0));
+#define cvCheckArray cvCheckArr
+
+#define CV_RAND_UNI 0
+#define CV_RAND_NORMAL 1
+
+/** @brief Fills an array with random numbers and updates the RNG state.
+
+The function fills the destination array with uniformly or normally distributed random numbers.
+@param rng CvRNG state initialized by cvRNG
+@param arr The destination array
+@param dist_type Distribution type
+> - **CV_RAND_UNI** uniform distribution
+> - **CV_RAND_NORMAL** normal or Gaussian distribution
+@param param1 The first parameter of the distribution. In the case of a uniform distribution it is
+the inclusive lower boundary of the random numbers range. In the case of a normal distribution it
+is the mean value of the random numbers.
+@param param2 The second parameter of the distribution. In the case of a uniform distribution it
+is the exclusive upper boundary of the random numbers range. In the case of a normal distribution
+it is the standard deviation of the random numbers.
+@sa randu, randn, RNG::fill.
+ */
+CVAPI(void) cvRandArr( CvRNG* rng, CvArr* arr, int dist_type,
+ CvScalar param1, CvScalar param2 );
+
+CVAPI(void) cvRandShuffle( CvArr* mat, CvRNG* rng,
+ double iter_factor CV_DEFAULT(1.));
+
+#define CV_SORT_EVERY_ROW 0
+#define CV_SORT_EVERY_COLUMN 1
+#define CV_SORT_ASCENDING 0
+#define CV_SORT_DESCENDING 16
+
+CVAPI(void) cvSort( const CvArr* src, CvArr* dst CV_DEFAULT(NULL),
+ CvArr* idxmat CV_DEFAULT(NULL),
+ int flags CV_DEFAULT(0));
+
+/** Finds real roots of a cubic equation */
+CVAPI(int) cvSolveCubic( const CvMat* coeffs, CvMat* roots );
+
+/** Finds all real and complex roots of a polynomial equation */
+CVAPI(void) cvSolvePoly(const CvMat* coeffs, CvMat *roots2,
+ int maxiter CV_DEFAULT(20), int fig CV_DEFAULT(100));
+
+/****************************************************************************************\
+* Matrix operations *
+\****************************************************************************************/
+
+/** @brief Calculates the cross product of two 3D vectors.
+
+The function calculates the cross product of two 3D vectors:
+\f[\texttt{dst} = \texttt{src1} \times \texttt{src2}\f]
+or:
+\f[\begin{array}{l} \texttt{dst} _1 = \texttt{src1} _2 \texttt{src2} _3 - \texttt{src1} _3 \texttt{src2} _2 \\ \texttt{dst} _2 = \texttt{src1} _3 \texttt{src2} _1 - \texttt{src1} _1 \texttt{src2} _3 \\ \texttt{dst} _3 = \texttt{src1} _1 \texttt{src2} _2 - \texttt{src1} _2 \texttt{src2} _1 \end{array}\f]
+@param src1 The first source vector
+@param src2 The second source vector
+@param dst The destination vector
+ */
+CVAPI(void) cvCrossProduct( const CvArr* src1, const CvArr* src2, CvArr* dst );
+
+/** Matrix transform: dst = A*B + C, C is optional */
+#define cvMatMulAdd( src1, src2, src3, dst ) cvGEMM( (src1), (src2), 1., (src3), 1., (dst), 0 )
+#define cvMatMul( src1, src2, dst ) cvMatMulAdd( (src1), (src2), NULL, (dst))
+
+#define CV_GEMM_A_T 1
+#define CV_GEMM_B_T 2
+#define CV_GEMM_C_T 4
+/** Extended matrix transform:
+ dst = alpha*op(A)*op(B) + beta*op(C), where op(X) is X or X^T */
+CVAPI(void) cvGEMM( const CvArr* src1, const CvArr* src2, double alpha,
+ const CvArr* src3, double beta, CvArr* dst,
+ int tABC CV_DEFAULT(0));
+#define cvMatMulAddEx cvGEMM
+
+/** Transforms each element of source array and stores
+ resultant vectors in destination array */
+CVAPI(void) cvTransform( const CvArr* src, CvArr* dst,
+ const CvMat* transmat,
+ const CvMat* shiftvec CV_DEFAULT(NULL));
+#define cvMatMulAddS cvTransform
+
+/** Does perspective transform on every element of input array */
+CVAPI(void) cvPerspectiveTransform( const CvArr* src, CvArr* dst,
+ const CvMat* mat );
+
+/** Calculates (A-delta)*(A-delta)^T (order=0) or (A-delta)^T*(A-delta) (order=1) */
+CVAPI(void) cvMulTransposed( const CvArr* src, CvArr* dst, int order,
+ const CvArr* delta CV_DEFAULT(NULL),
+ double scale CV_DEFAULT(1.) );
+
+/** Tranposes matrix. Square matrices can be transposed in-place */
+CVAPI(void) cvTranspose( const CvArr* src, CvArr* dst );
+#define cvT cvTranspose
+
+/** Completes the symmetric matrix from the lower (LtoR=0) or from the upper (LtoR!=0) part */
+CVAPI(void) cvCompleteSymm( CvMat* matrix, int LtoR CV_DEFAULT(0) );
+
+/** Mirror array data around horizontal (flip=0),
+ vertical (flip=1) or both(flip=-1) axises:
+ cvFlip(src) flips images vertically and sequences horizontally (inplace) */
+CVAPI(void) cvFlip( const CvArr* src, CvArr* dst CV_DEFAULT(NULL),
+ int flip_mode CV_DEFAULT(0));
+#define cvMirror cvFlip
+
+
+#define CV_SVD_MODIFY_A 1
+#define CV_SVD_U_T 2
+#define CV_SVD_V_T 4
+
+/** Performs Singular Value Decomposition of a matrix */
+CVAPI(void) cvSVD( CvArr* A, CvArr* W, CvArr* U CV_DEFAULT(NULL),
+ CvArr* V CV_DEFAULT(NULL), int flags CV_DEFAULT(0));
+
+/** Performs Singular Value Back Substitution (solves A*X = B):
+ flags must be the same as in cvSVD */
+CVAPI(void) cvSVBkSb( const CvArr* W, const CvArr* U,
+ const CvArr* V, const CvArr* B,
+ CvArr* X, int flags );
+
+#define CV_LU 0
+#define CV_SVD 1
+#define CV_SVD_SYM 2
+#define CV_CHOLESKY 3
+#define CV_QR 4
+#define CV_NORMAL 16
+
+/** Inverts matrix */
+CVAPI(double) cvInvert( const CvArr* src, CvArr* dst,
+ int method CV_DEFAULT(CV_LU));
+#define cvInv cvInvert
+
+/** Solves linear system (src1)*(dst) = (src2)
+ (returns 0 if src1 is a singular and CV_LU method is used) */
+CVAPI(int) cvSolve( const CvArr* src1, const CvArr* src2, CvArr* dst,
+ int method CV_DEFAULT(CV_LU));
+
+/** Calculates determinant of input matrix */
+CVAPI(double) cvDet( const CvArr* mat );
+
+/** Calculates trace of the matrix (sum of elements on the main diagonal) */
+CVAPI(CvScalar) cvTrace( const CvArr* mat );
+
+/** Finds eigen values and vectors of a symmetric matrix */
+CVAPI(void) cvEigenVV( CvArr* mat, CvArr* evects, CvArr* evals,
+ double eps CV_DEFAULT(0),
+ int lowindex CV_DEFAULT(-1),
+ int highindex CV_DEFAULT(-1));
+
+///* Finds selected eigen values and vectors of a symmetric matrix */
+//CVAPI(void) cvSelectedEigenVV( CvArr* mat, CvArr* evects, CvArr* evals,
+// int lowindex, int highindex );
+
+/** Makes an identity matrix (mat_ij = i == j) */
+CVAPI(void) cvSetIdentity( CvArr* mat, CvScalar value CV_DEFAULT(cvRealScalar(1)) );
+
+/** Fills matrix with given range of numbers */
+CVAPI(CvArr*) cvRange( CvArr* mat, double start, double end );
+
+/** @anchor core_c_CovarFlags
+@name Flags for cvCalcCovarMatrix
+@see cvCalcCovarMatrix
+ @{
+*/
+
+/** flag for cvCalcCovarMatrix, transpose([v1-avg, v2-avg,...]) * [v1-avg,v2-avg,...] */
+#define CV_COVAR_SCRAMBLED 0
+
+/** flag for cvCalcCovarMatrix, [v1-avg, v2-avg,...] * transpose([v1-avg,v2-avg,...]) */
+#define CV_COVAR_NORMAL 1
+
+/** flag for cvCalcCovarMatrix, do not calc average (i.e. mean vector) - use the input vector instead
+ (useful for calculating covariance matrix by parts) */
+#define CV_COVAR_USE_AVG 2
+
+/** flag for cvCalcCovarMatrix, scale the covariance matrix coefficients by number of the vectors */
+#define CV_COVAR_SCALE 4
+
+/** flag for cvCalcCovarMatrix, all the input vectors are stored in a single matrix, as its rows */
+#define CV_COVAR_ROWS 8
+
+/** flag for cvCalcCovarMatrix, all the input vectors are stored in a single matrix, as its columns */
+#define CV_COVAR_COLS 16
+
+/** @} */
+
+/** Calculates covariation matrix for a set of vectors
+@see @ref core_c_CovarFlags "flags"
+*/
+CVAPI(void) cvCalcCovarMatrix( const CvArr** vects, int count,
+ CvArr* cov_mat, CvArr* avg, int flags );
+
+#define CV_PCA_DATA_AS_ROW 0
+#define CV_PCA_DATA_AS_COL 1
+#define CV_PCA_USE_AVG 2
+CVAPI(void) cvCalcPCA( const CvArr* data, CvArr* mean,
+ CvArr* eigenvals, CvArr* eigenvects, int flags );
+
+CVAPI(void) cvProjectPCA( const CvArr* data, const CvArr* mean,
+ const CvArr* eigenvects, CvArr* result );
+
+CVAPI(void) cvBackProjectPCA( const CvArr* proj, const CvArr* mean,
+ const CvArr* eigenvects, CvArr* result );
+
+/** Calculates Mahalanobis(weighted) distance */
+CVAPI(double) cvMahalanobis( const CvArr* vec1, const CvArr* vec2, const CvArr* mat );
+#define cvMahalonobis cvMahalanobis
+
+/****************************************************************************************\
+* Array Statistics *
+\****************************************************************************************/
+
+/** Finds sum of array elements */
+CVAPI(CvScalar) cvSum( const CvArr* arr );
+
+/** Calculates number of non-zero pixels */
+CVAPI(int) cvCountNonZero( const CvArr* arr );
+
+/** Calculates mean value of array elements */
+CVAPI(CvScalar) cvAvg( const CvArr* arr, const CvArr* mask CV_DEFAULT(NULL) );
+
+/** Calculates mean and standard deviation of pixel values */
+CVAPI(void) cvAvgSdv( const CvArr* arr, CvScalar* mean, CvScalar* std_dev,
+ const CvArr* mask CV_DEFAULT(NULL) );
+
+/** Finds global minimum, maximum and their positions */
+CVAPI(void) cvMinMaxLoc( const CvArr* arr, double* min_val, double* max_val,
+ CvPoint* min_loc CV_DEFAULT(NULL),
+ CvPoint* max_loc CV_DEFAULT(NULL),
+ const CvArr* mask CV_DEFAULT(NULL) );
+
+/** @anchor core_c_NormFlags
+ @name Flags for cvNorm and cvNormalize
+ @{
+*/
+#define CV_C 1
+#define CV_L1 2
+#define CV_L2 4
+#define CV_NORM_MASK 7
+#define CV_RELATIVE 8
+#define CV_DIFF 16
+#define CV_MINMAX 32
+
+#define CV_DIFF_C (CV_DIFF | CV_C)
+#define CV_DIFF_L1 (CV_DIFF | CV_L1)
+#define CV_DIFF_L2 (CV_DIFF | CV_L2)
+#define CV_RELATIVE_C (CV_RELATIVE | CV_C)
+#define CV_RELATIVE_L1 (CV_RELATIVE | CV_L1)
+#define CV_RELATIVE_L2 (CV_RELATIVE | CV_L2)
+/** @} */
+
+/** Finds norm, difference norm or relative difference norm for an array (or two arrays)
+@see ref core_c_NormFlags "flags"
+*/
+CVAPI(double) cvNorm( const CvArr* arr1, const CvArr* arr2 CV_DEFAULT(NULL),
+ int norm_type CV_DEFAULT(CV_L2),
+ const CvArr* mask CV_DEFAULT(NULL) );
+
+/** @see ref core_c_NormFlags "flags" */
+CVAPI(void) cvNormalize( const CvArr* src, CvArr* dst,
+ double a CV_DEFAULT(1.), double b CV_DEFAULT(0.),
+ int norm_type CV_DEFAULT(CV_L2),
+ const CvArr* mask CV_DEFAULT(NULL) );
+
+/** @anchor core_c_ReduceFlags
+ @name Flags for cvReduce
+ @{
+*/
+#define CV_REDUCE_SUM 0
+#define CV_REDUCE_AVG 1
+#define CV_REDUCE_MAX 2
+#define CV_REDUCE_MIN 3
+/** @} */
+
+/** @see @ref core_c_ReduceFlags "flags" */
+CVAPI(void) cvReduce( const CvArr* src, CvArr* dst, int dim CV_DEFAULT(-1),
+ int op CV_DEFAULT(CV_REDUCE_SUM) );
+
+/****************************************************************************************\
+* Discrete Linear Transforms and Related Functions *
+\****************************************************************************************/
+
+/** @anchor core_c_DftFlags
+ @name Flags for cvDFT, cvDCT and cvMulSpectrums
+ @{
+ */
+#define CV_DXT_FORWARD 0
+#define CV_DXT_INVERSE 1
+#define CV_DXT_SCALE 2 /**< divide result by size of array */
+#define CV_DXT_INV_SCALE (CV_DXT_INVERSE + CV_DXT_SCALE)
+#define CV_DXT_INVERSE_SCALE CV_DXT_INV_SCALE
+#define CV_DXT_ROWS 4 /**< transform each row individually */
+#define CV_DXT_MUL_CONJ 8 /**< conjugate the second argument of cvMulSpectrums */
+/** @} */
+
+/** Discrete Fourier Transform:
+ complex->complex,
+ real->ccs (forward),
+ ccs->real (inverse)
+@see core_c_DftFlags "flags"
+*/
+CVAPI(void) cvDFT( const CvArr* src, CvArr* dst, int flags,
+ int nonzero_rows CV_DEFAULT(0) );
+#define cvFFT cvDFT
+
+/** Multiply results of DFTs: DFT(X)*DFT(Y) or DFT(X)*conj(DFT(Y))
+@see core_c_DftFlags "flags"
+*/
+CVAPI(void) cvMulSpectrums( const CvArr* src1, const CvArr* src2,
+ CvArr* dst, int flags );
+
+/** Finds optimal DFT vector size >= size0 */
+CVAPI(int) cvGetOptimalDFTSize( int size0 );
+
+/** Discrete Cosine Transform
+@see core_c_DftFlags "flags"
+*/
+CVAPI(void) cvDCT( const CvArr* src, CvArr* dst, int flags );
+
+/****************************************************************************************\
+* Dynamic data structures *
+\****************************************************************************************/
+
+/** Calculates length of sequence slice (with support of negative indices). */
+CVAPI(int) cvSliceLength( CvSlice slice, const CvSeq* seq );
+
+
+/** Creates new memory storage.
+ block_size == 0 means that default,
+ somewhat optimal size, is used (currently, it is 64K) */
+CVAPI(CvMemStorage*) cvCreateMemStorage( int block_size CV_DEFAULT(0));
+
+
+/** Creates a memory storage that will borrow memory blocks from parent storage */
+CVAPI(CvMemStorage*) cvCreateChildMemStorage( CvMemStorage* parent );
+
+
+/** Releases memory storage. All the children of a parent must be released before
+ the parent. A child storage returns all the blocks to parent when it is released */
+CVAPI(void) cvReleaseMemStorage( CvMemStorage** storage );
+
+
+/** Clears memory storage. This is the only way(!!!) (besides cvRestoreMemStoragePos)
+ to reuse memory allocated for the storage - cvClearSeq,cvClearSet ...
+ do not free any memory.
+ A child storage returns all the blocks to the parent when it is cleared */
+CVAPI(void) cvClearMemStorage( CvMemStorage* storage );
+
+/** Remember a storage "free memory" position */
+CVAPI(void) cvSaveMemStoragePos( const CvMemStorage* storage, CvMemStoragePos* pos );
+
+/** Restore a storage "free memory" position */
+CVAPI(void) cvRestoreMemStoragePos( CvMemStorage* storage, CvMemStoragePos* pos );
+
+/** Allocates continuous buffer of the specified size in the storage */
+CVAPI(void*) cvMemStorageAlloc( CvMemStorage* storage, size_t size );
+
+/** Allocates string in memory storage */
+CVAPI(CvString) cvMemStorageAllocString( CvMemStorage* storage, const char* ptr,
+ int len CV_DEFAULT(-1) );
+
+/** Creates new empty sequence that will reside in the specified storage */
+CVAPI(CvSeq*) cvCreateSeq( int seq_flags, size_t header_size,
+ size_t elem_size, CvMemStorage* storage );
+
+/** Changes default size (granularity) of sequence blocks.
+ The default size is ~1Kbyte */
+CVAPI(void) cvSetSeqBlockSize( CvSeq* seq, int delta_elems );
+
+
+/** Adds new element to the end of sequence. Returns pointer to the element */
+CVAPI(schar*) cvSeqPush( CvSeq* seq, const void* element CV_DEFAULT(NULL));
+
+
+/** Adds new element to the beginning of sequence. Returns pointer to it */
+CVAPI(schar*) cvSeqPushFront( CvSeq* seq, const void* element CV_DEFAULT(NULL));
+
+
+/** Removes the last element from sequence and optionally saves it */
+CVAPI(void) cvSeqPop( CvSeq* seq, void* element CV_DEFAULT(NULL));
+
+
+/** Removes the first element from sequence and optioanally saves it */
+CVAPI(void) cvSeqPopFront( CvSeq* seq, void* element CV_DEFAULT(NULL));
+
+
+#define CV_FRONT 1
+#define CV_BACK 0
+/** Adds several new elements to the end of sequence */
+CVAPI(void) cvSeqPushMulti( CvSeq* seq, const void* elements,
+ int count, int in_front CV_DEFAULT(0) );
+
+/** Removes several elements from the end of sequence and optionally saves them */
+CVAPI(void) cvSeqPopMulti( CvSeq* seq, void* elements,
+ int count, int in_front CV_DEFAULT(0) );
+
+/** Inserts a new element in the middle of sequence.
+ cvSeqInsert(seq,0,elem) == cvSeqPushFront(seq,elem) */
+CVAPI(schar*) cvSeqInsert( CvSeq* seq, int before_index,
+ const void* element CV_DEFAULT(NULL));
+
+/** Removes specified sequence element */
+CVAPI(void) cvSeqRemove( CvSeq* seq, int index );
+
+
+/** Removes all the elements from the sequence. The freed memory
+ can be reused later only by the same sequence unless cvClearMemStorage
+ or cvRestoreMemStoragePos is called */
+CVAPI(void) cvClearSeq( CvSeq* seq );
+
+
+/** Retrieves pointer to specified sequence element.
+ Negative indices are supported and mean counting from the end
+ (e.g -1 means the last sequence element) */
+CVAPI(schar*) cvGetSeqElem( const CvSeq* seq, int index );
+
+/** Calculates index of the specified sequence element.
+ Returns -1 if element does not belong to the sequence */
+CVAPI(int) cvSeqElemIdx( const CvSeq* seq, const void* element,
+ CvSeqBlock** block CV_DEFAULT(NULL) );
+
+/** Initializes sequence writer. The new elements will be added to the end of sequence */
+CVAPI(void) cvStartAppendToSeq( CvSeq* seq, CvSeqWriter* writer );
+
+
+/** Combination of cvCreateSeq and cvStartAppendToSeq */
+CVAPI(void) cvStartWriteSeq( int seq_flags, int header_size,
+ int elem_size, CvMemStorage* storage,
+ CvSeqWriter* writer );
+
+/** Closes sequence writer, updates sequence header and returns pointer
+ to the resultant sequence
+ (which may be useful if the sequence was created using cvStartWriteSeq))
+*/
+CVAPI(CvSeq*) cvEndWriteSeq( CvSeqWriter* writer );
+
+
+/** Updates sequence header. May be useful to get access to some of previously
+ written elements via cvGetSeqElem or sequence reader */
+CVAPI(void) cvFlushSeqWriter( CvSeqWriter* writer );
+
+
+/** Initializes sequence reader.
+ The sequence can be read in forward or backward direction */
+CVAPI(void) cvStartReadSeq( const CvSeq* seq, CvSeqReader* reader,
+ int reverse CV_DEFAULT(0) );
+
+
+/** Returns current sequence reader position (currently observed sequence element) */
+CVAPI(int) cvGetSeqReaderPos( CvSeqReader* reader );
+
+
+/** Changes sequence reader position. It may seek to an absolute or
+ to relative to the current position */
+CVAPI(void) cvSetSeqReaderPos( CvSeqReader* reader, int index,
+ int is_relative CV_DEFAULT(0));
+
+/** Copies sequence content to a continuous piece of memory */
+CVAPI(void*) cvCvtSeqToArray( const CvSeq* seq, void* elements,
+ CvSlice slice CV_DEFAULT(CV_WHOLE_SEQ) );
+
+/** Creates sequence header for array.
+ After that all the operations on sequences that do not alter the content
+ can be applied to the resultant sequence */
+CVAPI(CvSeq*) cvMakeSeqHeaderForArray( int seq_type, int header_size,
+ int elem_size, void* elements, int total,
+ CvSeq* seq, CvSeqBlock* block );
+
+/** Extracts sequence slice (with or without copying sequence elements) */
+CVAPI(CvSeq*) cvSeqSlice( const CvSeq* seq, CvSlice slice,
+ CvMemStorage* storage CV_DEFAULT(NULL),
+ int copy_data CV_DEFAULT(0));
+
+CV_INLINE CvSeq* cvCloneSeq( const CvSeq* seq, CvMemStorage* storage CV_DEFAULT(NULL))
+{
+ return cvSeqSlice( seq, CV_WHOLE_SEQ, storage, 1 );
+}
+
+/** Removes sequence slice */
+CVAPI(void) cvSeqRemoveSlice( CvSeq* seq, CvSlice slice );
+
+/** Inserts a sequence or array into another sequence */
+CVAPI(void) cvSeqInsertSlice( CvSeq* seq, int before_index, const CvArr* from_arr );
+
+/** a < b ? -1 : a > b ? 1 : 0 */
+typedef int (CV_CDECL* CvCmpFunc)(const void* a, const void* b, void* userdata );
+
+/** Sorts sequence in-place given element comparison function */
+CVAPI(void) cvSeqSort( CvSeq* seq, CvCmpFunc func, void* userdata CV_DEFAULT(NULL) );
+
+/** Finds element in a [sorted] sequence */
+CVAPI(schar*) cvSeqSearch( CvSeq* seq, const void* elem, CvCmpFunc func,
+ int is_sorted, int* elem_idx,
+ void* userdata CV_DEFAULT(NULL) );
+
+/** Reverses order of sequence elements in-place */
+CVAPI(void) cvSeqInvert( CvSeq* seq );
+
+/** Splits sequence into one or more equivalence classes using the specified criteria */
+CVAPI(int) cvSeqPartition( const CvSeq* seq, CvMemStorage* storage,
+ CvSeq** labels, CvCmpFunc is_equal, void* userdata );
+
+/************ Internal sequence functions ************/
+CVAPI(void) cvChangeSeqBlock( void* reader, int direction );
+CVAPI(void) cvCreateSeqBlock( CvSeqWriter* writer );
+
+
+/** Creates a new set */
+CVAPI(CvSet*) cvCreateSet( int set_flags, int header_size,
+ int elem_size, CvMemStorage* storage );
+
+/** Adds new element to the set and returns pointer to it */
+CVAPI(int) cvSetAdd( CvSet* set_header, CvSetElem* elem CV_DEFAULT(NULL),
+ CvSetElem** inserted_elem CV_DEFAULT(NULL) );
+
+/** Fast variant of cvSetAdd */
+CV_INLINE CvSetElem* cvSetNew( CvSet* set_header )
+{
+ CvSetElem* elem = set_header->free_elems;
+ if( elem )
+ {
+ set_header->free_elems = elem->next_free;
+ elem->flags = elem->flags & CV_SET_ELEM_IDX_MASK;
+ set_header->active_count++;
+ }
+ else
+ cvSetAdd( set_header, NULL, &elem );
+ return elem;
+}
+
+/** Removes set element given its pointer */
+CV_INLINE void cvSetRemoveByPtr( CvSet* set_header, void* elem )
+{
+ CvSetElem* _elem = (CvSetElem*)elem;
+ assert( _elem->flags >= 0 /*&& (elem->flags & CV_SET_ELEM_IDX_MASK) < set_header->total*/ );
+ _elem->next_free = set_header->free_elems;
+ _elem->flags = (_elem->flags & CV_SET_ELEM_IDX_MASK) | CV_SET_ELEM_FREE_FLAG;
+ set_header->free_elems = _elem;
+ set_header->active_count--;
+}
+
+/** Removes element from the set by its index */
+CVAPI(void) cvSetRemove( CvSet* set_header, int index );
+
+/** Returns a set element by index. If the element doesn't belong to the set,
+ NULL is returned */
+CV_INLINE CvSetElem* cvGetSetElem( const CvSet* set_header, int idx )
+{
+ CvSetElem* elem = (CvSetElem*)(void *)cvGetSeqElem( (CvSeq*)set_header, idx );
+ return elem && CV_IS_SET_ELEM( elem ) ? elem : 0;
+}
+
+/** Removes all the elements from the set */
+CVAPI(void) cvClearSet( CvSet* set_header );
+
+/** Creates new graph */
+CVAPI(CvGraph*) cvCreateGraph( int graph_flags, int header_size,
+ int vtx_size, int edge_size,
+ CvMemStorage* storage );
+
+/** Adds new vertex to the graph */
+CVAPI(int) cvGraphAddVtx( CvGraph* graph, const CvGraphVtx* vtx CV_DEFAULT(NULL),
+ CvGraphVtx** inserted_vtx CV_DEFAULT(NULL) );
+
+
+/** Removes vertex from the graph together with all incident edges */
+CVAPI(int) cvGraphRemoveVtx( CvGraph* graph, int index );
+CVAPI(int) cvGraphRemoveVtxByPtr( CvGraph* graph, CvGraphVtx* vtx );
+
+
+/** Link two vertices specifed by indices or pointers if they
+ are not connected or return pointer to already existing edge
+ connecting the vertices.
+ Functions return 1 if a new edge was created, 0 otherwise */
+CVAPI(int) cvGraphAddEdge( CvGraph* graph,
+ int start_idx, int end_idx,
+ const CvGraphEdge* edge CV_DEFAULT(NULL),
+ CvGraphEdge** inserted_edge CV_DEFAULT(NULL) );
+
+CVAPI(int) cvGraphAddEdgeByPtr( CvGraph* graph,
+ CvGraphVtx* start_vtx, CvGraphVtx* end_vtx,
+ const CvGraphEdge* edge CV_DEFAULT(NULL),
+ CvGraphEdge** inserted_edge CV_DEFAULT(NULL) );
+
+/** Remove edge connecting two vertices */
+CVAPI(void) cvGraphRemoveEdge( CvGraph* graph, int start_idx, int end_idx );
+CVAPI(void) cvGraphRemoveEdgeByPtr( CvGraph* graph, CvGraphVtx* start_vtx,
+ CvGraphVtx* end_vtx );
+
+/** Find edge connecting two vertices */
+CVAPI(CvGraphEdge*) cvFindGraphEdge( const CvGraph* graph, int start_idx, int end_idx );
+CVAPI(CvGraphEdge*) cvFindGraphEdgeByPtr( const CvGraph* graph,
+ const CvGraphVtx* start_vtx,
+ const CvGraphVtx* end_vtx );
+#define cvGraphFindEdge cvFindGraphEdge
+#define cvGraphFindEdgeByPtr cvFindGraphEdgeByPtr
+
+/** Remove all vertices and edges from the graph */
+CVAPI(void) cvClearGraph( CvGraph* graph );
+
+
+/** Count number of edges incident to the vertex */
+CVAPI(int) cvGraphVtxDegree( const CvGraph* graph, int vtx_idx );
+CVAPI(int) cvGraphVtxDegreeByPtr( const CvGraph* graph, const CvGraphVtx* vtx );
+
+
+/** Retrieves graph vertex by given index */
+#define cvGetGraphVtx( graph, idx ) (CvGraphVtx*)cvGetSetElem((CvSet*)(graph), (idx))
+
+/** Retrieves index of a graph vertex given its pointer */
+#define cvGraphVtxIdx( graph, vtx ) ((vtx)->flags & CV_SET_ELEM_IDX_MASK)
+
+/** Retrieves index of a graph edge given its pointer */
+#define cvGraphEdgeIdx( graph, edge ) ((edge)->flags & CV_SET_ELEM_IDX_MASK)
+
+#define cvGraphGetVtxCount( graph ) ((graph)->active_count)
+#define cvGraphGetEdgeCount( graph ) ((graph)->edges->active_count)
+
+#define CV_GRAPH_VERTEX 1
+#define CV_GRAPH_TREE_EDGE 2
+#define CV_GRAPH_BACK_EDGE 4
+#define CV_GRAPH_FORWARD_EDGE 8
+#define CV_GRAPH_CROSS_EDGE 16
+#define CV_GRAPH_ANY_EDGE 30
+#define CV_GRAPH_NEW_TREE 32
+#define CV_GRAPH_BACKTRACKING 64
+#define CV_GRAPH_OVER -1
+
+#define CV_GRAPH_ALL_ITEMS -1
+
+/** flags for graph vertices and edges */
+#define CV_GRAPH_ITEM_VISITED_FLAG (1 << 30)
+#define CV_IS_GRAPH_VERTEX_VISITED(vtx) \
+ (((CvGraphVtx*)(vtx))->flags & CV_GRAPH_ITEM_VISITED_FLAG)
+#define CV_IS_GRAPH_EDGE_VISITED(edge) \
+ (((CvGraphEdge*)(edge))->flags & CV_GRAPH_ITEM_VISITED_FLAG)
+#define CV_GRAPH_SEARCH_TREE_NODE_FLAG (1 << 29)
+#define CV_GRAPH_FORWARD_EDGE_FLAG (1 << 28)
+
+typedef struct CvGraphScanner
+{
+ CvGraphVtx* vtx; /* current graph vertex (or current edge origin) */
+ CvGraphVtx* dst; /* current graph edge destination vertex */
+ CvGraphEdge* edge; /* current edge */
+
+ CvGraph* graph; /* the graph */
+ CvSeq* stack; /* the graph vertex stack */
+ int index; /* the lower bound of certainly visited vertices */
+ int mask; /* event mask */
+}
+CvGraphScanner;
+
+/** Creates new graph scanner. */
+CVAPI(CvGraphScanner*) cvCreateGraphScanner( CvGraph* graph,
+ CvGraphVtx* vtx CV_DEFAULT(NULL),
+ int mask CV_DEFAULT(CV_GRAPH_ALL_ITEMS));
+
+/** Releases graph scanner. */
+CVAPI(void) cvReleaseGraphScanner( CvGraphScanner** scanner );
+
+/** Get next graph element */
+CVAPI(int) cvNextGraphItem( CvGraphScanner* scanner );
+
+/** Creates a copy of graph */
+CVAPI(CvGraph*) cvCloneGraph( const CvGraph* graph, CvMemStorage* storage );
+
+
+/** Does look-up transformation. Elements of the source array
+ (that should be 8uC1 or 8sC1) are used as indexes in lutarr 256-element table */
+CVAPI(void) cvLUT( const CvArr* src, CvArr* dst, const CvArr* lut );
+
+
+/******************* Iteration through the sequence tree *****************/
+typedef struct CvTreeNodeIterator
+{
+ const void* node;
+ int level;
+ int max_level;
+}
+CvTreeNodeIterator;
+
+CVAPI(void) cvInitTreeNodeIterator( CvTreeNodeIterator* tree_iterator,
+ const void* first, int max_level );
+CVAPI(void*) cvNextTreeNode( CvTreeNodeIterator* tree_iterator );
+CVAPI(void*) cvPrevTreeNode( CvTreeNodeIterator* tree_iterator );
+
+/** Inserts sequence into tree with specified "parent" sequence.
+ If parent is equal to frame (e.g. the most external contour),
+ then added contour will have null pointer to parent. */
+CVAPI(void) cvInsertNodeIntoTree( void* node, void* parent, void* frame );
+
+/** Removes contour from tree (together with the contour children). */
+CVAPI(void) cvRemoveNodeFromTree( void* node, void* frame );
+
+/** Gathers pointers to all the sequences,
+ accessible from the `first`, to the single sequence */
+CVAPI(CvSeq*) cvTreeToNodeSeq( const void* first, int header_size,
+ CvMemStorage* storage );
+
+/** The function implements the K-means algorithm for clustering an array of sample
+ vectors in a specified number of classes */
+#define CV_KMEANS_USE_INITIAL_LABELS 1
+CVAPI(int) cvKMeans2( const CvArr* samples, int cluster_count, CvArr* labels,
+ CvTermCriteria termcrit, int attempts CV_DEFAULT(1),
+ CvRNG* rng CV_DEFAULT(0), int flags CV_DEFAULT(0),
+ CvArr* _centers CV_DEFAULT(0), double* compactness CV_DEFAULT(0) );
+
+/****************************************************************************************\
+* System functions *
+\****************************************************************************************/
+
+/** Loads optimized functions from IPP, MKL etc. or switches back to pure C code */
+CVAPI(int) cvUseOptimized( int on_off );
+
+typedef IplImage* (CV_STDCALL* Cv_iplCreateImageHeader)
+ (int,int,int,char*,char*,int,int,int,int,int,
+ IplROI*,IplImage*,void*,IplTileInfo*);
+typedef void (CV_STDCALL* Cv_iplAllocateImageData)(IplImage*,int,int);
+typedef void (CV_STDCALL* Cv_iplDeallocate)(IplImage*,int);
+typedef IplROI* (CV_STDCALL* Cv_iplCreateROI)(int,int,int,int,int);
+typedef IplImage* (CV_STDCALL* Cv_iplCloneImage)(const IplImage*);
+
+/** @brief Makes OpenCV use IPL functions for allocating IplImage and IplROI structures.
+
+Normally, the function is not called directly. Instead, a simple macro
+CV_TURN_ON_IPL_COMPATIBILITY() is used that calls cvSetIPLAllocators and passes there pointers
+to IPL allocation functions. :
+@code
+ ...
+ CV_TURN_ON_IPL_COMPATIBILITY()
+ ...
+@endcode
+@param create_header pointer to a function, creating IPL image header.
+@param allocate_data pointer to a function, allocating IPL image data.
+@param deallocate pointer to a function, deallocating IPL image.
+@param create_roi pointer to a function, creating IPL image ROI (i.e. Region of Interest).
+@param clone_image pointer to a function, cloning an IPL image.
+ */
+CVAPI(void) cvSetIPLAllocators( Cv_iplCreateImageHeader create_header,
+ Cv_iplAllocateImageData allocate_data,
+ Cv_iplDeallocate deallocate,
+ Cv_iplCreateROI create_roi,
+ Cv_iplCloneImage clone_image );
+
+#define CV_TURN_ON_IPL_COMPATIBILITY() \
+ cvSetIPLAllocators( iplCreateImageHeader, iplAllocateImage, \
+ iplDeallocate, iplCreateROI, iplCloneImage )
+
+/****************************************************************************************\
+* Data Persistence *
+\****************************************************************************************/
+
+/********************************** High-level functions ********************************/
+
+/** @brief Opens file storage for reading or writing data.
+
+The function opens file storage for reading or writing data. In the latter case, a new file is
+created or an existing file is rewritten. The type of the read or written file is determined by the
+filename extension: .xml for XML, .yml or .yaml for YAML and .json for JSON.
+
+At the same time, it also supports adding parameters like "example.xml?base64". The three ways
+are the same:
+@snippet samples/cpp/filestorage_base64.cpp suffix_in_file_name
+@snippet samples/cpp/filestorage_base64.cpp flag_write_base64
+@snippet samples/cpp/filestorage_base64.cpp flag_write_and_flag_base64
+
+The function returns a pointer to the CvFileStorage structure.
+If the file cannot be opened then the function returns NULL.
+@param filename Name of the file associated with the storage
+@param memstorage Memory storage used for temporary data and for
+: storing dynamic structures, such as CvSeq or CvGraph . If it is NULL, a temporary memory
+ storage is created and used.
+@param flags Can be one of the following:
+> - **CV_STORAGE_READ** the storage is open for reading
+> - **CV_STORAGE_WRITE** the storage is open for writing
+ (use **CV_STORAGE_WRITE | CV_STORAGE_WRITE_BASE64** to write rawdata in Base64)
+@param encoding
+ */
+CVAPI(CvFileStorage*) cvOpenFileStorage( const char* filename, CvMemStorage* memstorage,
+ int flags, const char* encoding CV_DEFAULT(NULL) );
+
+/** @brief Releases file storage.
+
+The function closes the file associated with the storage and releases all the temporary structures.
+It must be called after all I/O operations with the storage are finished.
+@param fs Double pointer to the released file storage
+ */
+CVAPI(void) cvReleaseFileStorage( CvFileStorage** fs );
+
+/** returns attribute value or 0 (NULL) if there is no such attribute */
+CVAPI(const char*) cvAttrValue( const CvAttrList* attr, const char* attr_name );
+
+/** @brief Starts writing a new structure.
+
+The function starts writing a compound structure (collection) that can be a sequence or a map. After
+all the structure fields, which can be scalars or structures, are written, cvEndWriteStruct should
+be called. The function can be used to group some objects or to implement the write function for a
+some user object (see CvTypeInfo).
+@param fs File storage
+@param name Name of the written structure. The structure can be accessed by this name when the
+storage is read.
+@param struct_flags A combination one of the following values:
+- **CV_NODE_SEQ** the written structure is a sequence (see discussion of CvFileStorage ),
+ that is, its elements do not have a name.
+- **CV_NODE_MAP** the written structure is a map (see discussion of CvFileStorage ), that
+ is, all its elements have names.
+One and only one of the two above flags must be specified
+- **CV_NODE_FLOW** the optional flag that makes sense only for YAML streams. It means that
+ the structure is written as a flow (not as a block), which is more compact. It is
+ recommended to use this flag for structures or arrays whose elements are all scalars.
+@param type_name Optional parameter - the object type name. In
+ case of XML it is written as a type_id attribute of the structure opening tag. In the case of
+ YAML it is written after a colon following the structure name (see the example in
+ CvFileStorage description). In case of JSON it is written as a name/value pair.
+ Mainly it is used with user objects. When the storage is read, the
+ encoded type name is used to determine the object type (see CvTypeInfo and cvFindType ).
+@param attributes This parameter is not used in the current implementation
+ */
+CVAPI(void) cvStartWriteStruct( CvFileStorage* fs, const char* name,
+ int struct_flags, const char* type_name CV_DEFAULT(NULL),
+ CvAttrList attributes CV_DEFAULT(cvAttrList()));
+
+/** @brief Finishes writing to a file node collection.
+@param fs File storage
+@sa cvStartWriteStruct.
+ */
+CVAPI(void) cvEndWriteStruct( CvFileStorage* fs );
+
+/** @brief Writes an integer value.
+
+The function writes a single integer value (with or without a name) to the file storage.
+@param fs File storage
+@param name Name of the written value. Should be NULL if and only if the parent structure is a
+sequence.
+@param value The written value
+ */
+CVAPI(void) cvWriteInt( CvFileStorage* fs, const char* name, int value );
+
+/** @brief Writes a floating-point value.
+
+The function writes a single floating-point value (with or without a name) to file storage. Special
+values are encoded as follows: NaN (Not A Number) as .NaN, infinity as +.Inf or -.Inf.
+
+The following example shows how to use the low-level writing functions to store custom structures,
+such as termination criteria, without registering a new type. :
+@code
+ void write_termcriteria( CvFileStorage* fs, const char* struct_name,
+ CvTermCriteria* termcrit )
+ {
+ cvStartWriteStruct( fs, struct_name, CV_NODE_MAP, NULL, cvAttrList(0,0));
+ cvWriteComment( fs, "termination criteria", 1 ); // just a description
+ if( termcrit->type & CV_TERMCRIT_ITER )
+ cvWriteInteger( fs, "max_iterations", termcrit->max_iter );
+ if( termcrit->type & CV_TERMCRIT_EPS )
+ cvWriteReal( fs, "accuracy", termcrit->epsilon );
+ cvEndWriteStruct( fs );
+ }
+@endcode
+@param fs File storage
+@param name Name of the written value. Should be NULL if and only if the parent structure is a
+sequence.
+@param value The written value
+*/
+CVAPI(void) cvWriteReal( CvFileStorage* fs, const char* name, double value );
+
+/** @brief Writes a text string.
+
+The function writes a text string to file storage.
+@param fs File storage
+@param name Name of the written string . Should be NULL if and only if the parent structure is a
+sequence.
+@param str The written text string
+@param quote If non-zero, the written string is put in quotes, regardless of whether they are
+required. Otherwise, if the flag is zero, quotes are used only when they are required (e.g. when
+the string starts with a digit or contains spaces).
+ */
+CVAPI(void) cvWriteString( CvFileStorage* fs, const char* name,
+ const char* str, int quote CV_DEFAULT(0) );
+
+/** @brief Writes a comment.
+
+The function writes a comment into file storage. The comments are skipped when the storage is read.
+@param fs File storage
+@param comment The written comment, single-line or multi-line
+@param eol_comment If non-zero, the function tries to put the comment at the end of current line.
+If the flag is zero, if the comment is multi-line, or if it does not fit at the end of the current
+line, the comment starts a new line.
+ */
+CVAPI(void) cvWriteComment( CvFileStorage* fs, const char* comment,
+ int eol_comment );
+
+/** @brief Writes an object to file storage.
+
+The function writes an object to file storage. First, the appropriate type info is found using
+cvTypeOf. Then, the write method associated with the type info is called.
+
+Attributes are used to customize the writing procedure. The standard types support the following
+attributes (all the dt attributes have the same format as in cvWriteRawData):
+
+-# CvSeq
+ - **header_dt** description of user fields of the sequence header that follow CvSeq, or
+ CvChain (if the sequence is a Freeman chain) or CvContour (if the sequence is a contour or
+ point sequence)
+ - **dt** description of the sequence elements.
+ - **recursive** if the attribute is present and is not equal to "0" or "false", the whole
+ tree of sequences (contours) is stored.
+-# CvGraph
+ - **header_dt** description of user fields of the graph header that follows CvGraph;
+ - **vertex_dt** description of user fields of graph vertices
+ - **edge_dt** description of user fields of graph edges (note that the edge weight is
+ always written, so there is no need to specify it explicitly)
+
+Below is the code that creates the YAML file shown in the CvFileStorage description:
+@code
+ #include "cxcore.h"
+
+ int main( int argc, char** argv )
+ {
+ CvMat* mat = cvCreateMat( 3, 3, CV_32F );
+ CvFileStorage* fs = cvOpenFileStorage( "example.yml", 0, CV_STORAGE_WRITE );
+
+ cvSetIdentity( mat );
+ cvWrite( fs, "A", mat, cvAttrList(0,0) );
+
+ cvReleaseFileStorage( &fs );
+ cvReleaseMat( &mat );
+ return 0;
+ }
+@endcode
+@param fs File storage
+@param name Name of the written object. Should be NULL if and only if the parent structure is a
+sequence.
+@param ptr Pointer to the object
+@param attributes The attributes of the object. They are specific for each particular type (see
+the discussion below).
+ */
+CVAPI(void) cvWrite( CvFileStorage* fs, const char* name, const void* ptr,
+ CvAttrList attributes CV_DEFAULT(cvAttrList()));
+
+/** @brief Starts the next stream.
+
+The function finishes the currently written stream and starts the next stream. In the case of XML
+the file with multiple streams looks like this:
+@code{.xml}
+ <opencv_storage>
+ <!-- stream #1 data -->
+ </opencv_storage>
+ <opencv_storage>
+ <!-- stream #2 data -->
+ </opencv_storage>
+ ...
+@endcode
+The YAML file will look like this:
+@code{.yaml}
+ %YAML 1.0
+ # stream #1 data
+ ...
+ ---
+ # stream #2 data
+@endcode
+This is useful for concatenating files or for resuming the writing process.
+@param fs File storage
+ */
+CVAPI(void) cvStartNextStream( CvFileStorage* fs );
+
+/** @brief Writes multiple numbers.
+
+The function writes an array, whose elements consist of single or multiple numbers. The function
+call can be replaced with a loop containing a few cvWriteInt and cvWriteReal calls, but a single
+call is more efficient. Note that because none of the elements have a name, they should be written
+to a sequence rather than a map.
+@param fs File storage
+@param src Pointer to the written array
+@param len Number of the array elements to write
+@param dt Specification of each array element, see @ref format_spec "format specification"
+ */
+CVAPI(void) cvWriteRawData( CvFileStorage* fs, const void* src,
+ int len, const char* dt );
+
+/** @brief Writes multiple numbers in Base64.
+
+If either CV_STORAGE_WRITE_BASE64 or cv::FileStorage::WRITE_BASE64 is used,
+this function will be the same as cvWriteRawData. If neither, the main
+difference is that it outputs a sequence in Base64 encoding rather than
+in plain text.
+
+This function can only be used to write a sequence with a type "binary".
+
+Consider the following two examples where their output is the same:
+@snippet samples/cpp/filestorage_base64.cpp without_base64_flag
+and
+@snippet samples/cpp/filestorage_base64.cpp with_write_base64_flag
+
+@param fs File storage
+@param src Pointer to the written array
+@param len Number of the array elements to write
+@param dt Specification of each array element, see @ref format_spec "format specification"
+*/
+CVAPI(void) cvWriteRawDataBase64( CvFileStorage* fs, const void* src,
+ int len, const char* dt );
+
+/** @brief Returns a unique pointer for a given name.
+
+The function returns a unique pointer for each particular file node name. This pointer can be then
+passed to the cvGetFileNode function that is faster than cvGetFileNodeByName because it compares
+text strings by comparing pointers rather than the strings' content.
+
+Consider the following example where an array of points is encoded as a sequence of 2-entry maps:
+@code
+ points:
+ - { x: 10, y: 10 }
+ - { x: 20, y: 20 }
+ - { x: 30, y: 30 }
+ # ...
+@endcode
+Then, it is possible to get hashed "x" and "y" pointers to speed up decoding of the points. :
+@code
+ #include "cxcore.h"
+
+ int main( int argc, char** argv )
+ {
+ CvFileStorage* fs = cvOpenFileStorage( "points.yml", 0, CV_STORAGE_READ );
+ CvStringHashNode* x_key = cvGetHashedNode( fs, "x", -1, 1 );
+ CvStringHashNode* y_key = cvGetHashedNode( fs, "y", -1, 1 );
+ CvFileNode* points = cvGetFileNodeByName( fs, 0, "points" );
+
+ if( CV_NODE_IS_SEQ(points->tag) )
+ {
+ CvSeq* seq = points->data.seq;
+ int i, total = seq->total;
+ CvSeqReader reader;
+ cvStartReadSeq( seq, &reader, 0 );
+ for( i = 0; i < total; i++ )
+ {
+ CvFileNode* pt = (CvFileNode*)reader.ptr;
+ #if 1 // faster variant
+ CvFileNode* xnode = cvGetFileNode( fs, pt, x_key, 0 );
+ CvFileNode* ynode = cvGetFileNode( fs, pt, y_key, 0 );
+ assert( xnode && CV_NODE_IS_INT(xnode->tag) &&
+ ynode && CV_NODE_IS_INT(ynode->tag));
+ int x = xnode->data.i; // or x = cvReadInt( xnode, 0 );
+ int y = ynode->data.i; // or y = cvReadInt( ynode, 0 );
+ #elif 1 // slower variant; does not use x_key & y_key
+ CvFileNode* xnode = cvGetFileNodeByName( fs, pt, "x" );
+ CvFileNode* ynode = cvGetFileNodeByName( fs, pt, "y" );
+ assert( xnode && CV_NODE_IS_INT(xnode->tag) &&
+ ynode && CV_NODE_IS_INT(ynode->tag));
+ int x = xnode->data.i; // or x = cvReadInt( xnode, 0 );
+ int y = ynode->data.i; // or y = cvReadInt( ynode, 0 );
+ #else // the slowest yet the easiest to use variant
+ int x = cvReadIntByName( fs, pt, "x", 0 );
+ int y = cvReadIntByName( fs, pt, "y", 0 );
+ #endif
+ CV_NEXT_SEQ_ELEM( seq->elem_size, reader );
+ printf("
+ }
+ }
+ cvReleaseFileStorage( &fs );
+ return 0;
+ }
+@endcode
+Please note that whatever method of accessing a map you are using, it is still much slower than
+using plain sequences; for example, in the above example, it is more efficient to encode the points
+as pairs of integers in a single numeric sequence.
+@param fs File storage
+@param name Literal node name
+@param len Length of the name (if it is known apriori), or -1 if it needs to be calculated
+@param create_missing Flag that specifies, whether an absent key should be added into the hash table
+*/
+CVAPI(CvStringHashNode*) cvGetHashedKey( CvFileStorage* fs, const char* name,
+ int len CV_DEFAULT(-1),
+ int create_missing CV_DEFAULT(0));
+
+/** @brief Retrieves one of the top-level nodes of the file storage.
+
+The function returns one of the top-level file nodes. The top-level nodes do not have a name, they
+correspond to the streams that are stored one after another in the file storage. If the index is out
+of range, the function returns a NULL pointer, so all the top-level nodes can be iterated by
+subsequent calls to the function with stream_index=0,1,..., until the NULL pointer is returned.
+This function can be used as a base for recursive traversal of the file storage.
+@param fs File storage
+@param stream_index Zero-based index of the stream. See cvStartNextStream . In most cases,
+there is only one stream in the file; however, there can be several.
+ */
+CVAPI(CvFileNode*) cvGetRootFileNode( const CvFileStorage* fs,
+ int stream_index CV_DEFAULT(0) );
+
+/** @brief Finds a node in a map or file storage.
+
+The function finds a file node. It is a faster version of cvGetFileNodeByName (see
+cvGetHashedKey discussion). Also, the function can insert a new node, if it is not in the map yet.
+@param fs File storage
+@param map The parent map. If it is NULL, the function searches a top-level node. If both map and
+key are NULLs, the function returns the root file node - a map that contains top-level nodes.
+@param key Unique pointer to the node name, retrieved with cvGetHashedKey
+@param create_missing Flag that specifies whether an absent node should be added to the map
+ */
+CVAPI(CvFileNode*) cvGetFileNode( CvFileStorage* fs, CvFileNode* map,
+ const CvStringHashNode* key,
+ int create_missing CV_DEFAULT(0) );
+
+/** @brief Finds a node in a map or file storage.
+
+The function finds a file node by name. The node is searched either in map or, if the pointer is
+NULL, among the top-level file storage nodes. Using this function for maps and cvGetSeqElem (or
+sequence reader) for sequences, it is possible to navigate through the file storage. To speed up
+multiple queries for a certain key (e.g., in the case of an array of structures) one may use a
+combination of cvGetHashedKey and cvGetFileNode.
+@param fs File storage
+@param map The parent map. If it is NULL, the function searches in all the top-level nodes
+(streams), starting with the first one.
+@param name The file node name
+ */
+CVAPI(CvFileNode*) cvGetFileNodeByName( const CvFileStorage* fs,
+ const CvFileNode* map,
+ const char* name );
+
+/** @brief Retrieves an integer value from a file node.
+
+The function returns an integer that is represented by the file node. If the file node is NULL, the
+default_value is returned (thus, it is convenient to call the function right after cvGetFileNode
+without checking for a NULL pointer). If the file node has type CV_NODE_INT, then node-\>data.i is
+returned. If the file node has type CV_NODE_REAL, then node-\>data.f is converted to an integer
+and returned. Otherwise the error is reported.
+@param node File node
+@param default_value The value that is returned if node is NULL
+ */
+CV_INLINE int cvReadInt( const CvFileNode* node, int default_value CV_DEFAULT(0) )
+{
+ return !node ? default_value :
+ CV_NODE_IS_INT(node->tag) ? node->data.i :
+ CV_NODE_IS_REAL(node->tag) ? cvRound(node->data.f) : 0x7fffffff;
+}
+
+/** @brief Finds a file node and returns its value.
+
+The function is a simple superposition of cvGetFileNodeByName and cvReadInt.
+@param fs File storage
+@param map The parent map. If it is NULL, the function searches a top-level node.
+@param name The node name
+@param default_value The value that is returned if the file node is not found
+ */
+CV_INLINE int cvReadIntByName( const CvFileStorage* fs, const CvFileNode* map,
+ const char* name, int default_value CV_DEFAULT(0) )
+{
+ return cvReadInt( cvGetFileNodeByName( fs, map, name ), default_value );
+}
+
+/** @brief Retrieves a floating-point value from a file node.
+
+The function returns a floating-point value that is represented by the file node. If the file node
+is NULL, the default_value is returned (thus, it is convenient to call the function right after
+cvGetFileNode without checking for a NULL pointer). If the file node has type CV_NODE_REAL ,
+then node-\>data.f is returned. If the file node has type CV_NODE_INT , then node-:math:\>data.f
+is converted to floating-point and returned. Otherwise the result is not determined.
+@param node File node
+@param default_value The value that is returned if node is NULL
+ */
+CV_INLINE double cvReadReal( const CvFileNode* node, double default_value CV_DEFAULT(0.) )
+{
+ return !node ? default_value :
+ CV_NODE_IS_INT(node->tag) ? (double)node->data.i :
+ CV_NODE_IS_REAL(node->tag) ? node->data.f : 1e300;
+}
+
+/** @brief Finds a file node and returns its value.
+
+The function is a simple superposition of cvGetFileNodeByName and cvReadReal .
+@param fs File storage
+@param map The parent map. If it is NULL, the function searches a top-level node.
+@param name The node name
+@param default_value The value that is returned if the file node is not found
+ */
+CV_INLINE double cvReadRealByName( const CvFileStorage* fs, const CvFileNode* map,
+ const char* name, double default_value CV_DEFAULT(0.) )
+{
+ return cvReadReal( cvGetFileNodeByName( fs, map, name ), default_value );
+}
+
+/** @brief Retrieves a text string from a file node.
+
+The function returns a text string that is represented by the file node. If the file node is NULL,
+the default_value is returned (thus, it is convenient to call the function right after
+cvGetFileNode without checking for a NULL pointer). If the file node has type CV_NODE_STR , then
+node-:math:\>data.str.ptr is returned. Otherwise the result is not determined.
+@param node File node
+@param default_value The value that is returned if node is NULL
+ */
+CV_INLINE const char* cvReadString( const CvFileNode* node,
+ const char* default_value CV_DEFAULT(NULL) )
+{
+ return !node ? default_value : CV_NODE_IS_STRING(node->tag) ? node->data.str.ptr : 0;
+}
+
+/** @brief Finds a file node by its name and returns its value.
+
+The function is a simple superposition of cvGetFileNodeByName and cvReadString .
+@param fs File storage
+@param map The parent map. If it is NULL, the function searches a top-level node.
+@param name The node name
+@param default_value The value that is returned if the file node is not found
+ */
+CV_INLINE const char* cvReadStringByName( const CvFileStorage* fs, const CvFileNode* map,
+ const char* name, const char* default_value CV_DEFAULT(NULL) )
+{
+ return cvReadString( cvGetFileNodeByName( fs, map, name ), default_value );
+}
+
+
+/** @brief Decodes an object and returns a pointer to it.
+
+The function decodes a user object (creates an object in a native representation from the file
+storage subtree) and returns it. The object to be decoded must be an instance of a registered type
+that supports the read method (see CvTypeInfo). The type of the object is determined by the type
+name that is encoded in the file. If the object is a dynamic structure, it is created either in
+memory storage and passed to cvOpenFileStorage or, if a NULL pointer was passed, in temporary
+memory storage, which is released when cvReleaseFileStorage is called. Otherwise, if the object is
+not a dynamic structure, it is created in a heap and should be released with a specialized function
+or by using the generic cvRelease.
+@param fs File storage
+@param node The root object node
+@param attributes Unused parameter
+ */
+CVAPI(void*) cvRead( CvFileStorage* fs, CvFileNode* node,
+ CvAttrList* attributes CV_DEFAULT(NULL));
+
+/** @brief Finds an object by name and decodes it.
+
+The function is a simple superposition of cvGetFileNodeByName and cvRead.
+@param fs File storage
+@param map The parent map. If it is NULL, the function searches a top-level node.
+@param name The node name
+@param attributes Unused parameter
+ */
+CV_INLINE void* cvReadByName( CvFileStorage* fs, const CvFileNode* map,
+ const char* name, CvAttrList* attributes CV_DEFAULT(NULL) )
+{
+ return cvRead( fs, cvGetFileNodeByName( fs, map, name ), attributes );
+}
+
+
+/** @brief Initializes the file node sequence reader.
+
+The function initializes the sequence reader to read data from a file node. The initialized reader
+can be then passed to cvReadRawDataSlice.
+@param fs File storage
+@param src The file node (a sequence) to read numbers from
+@param reader Pointer to the sequence reader
+ */
+CVAPI(void) cvStartReadRawData( const CvFileStorage* fs, const CvFileNode* src,
+ CvSeqReader* reader );
+
+/** @brief Initializes file node sequence reader.
+
+The function reads one or more elements from the file node, representing a sequence, to a
+user-specified array. The total number of read sequence elements is a product of total and the
+number of components in each array element. For example, if dt=2if, the function will read total\*3
+sequence elements. As with any sequence, some parts of the file node sequence can be skipped or read
+repeatedly by repositioning the reader using cvSetSeqReaderPos.
+@param fs File storage
+@param reader The sequence reader. Initialize it with cvStartReadRawData .
+@param count The number of elements to read
+@param dst Pointer to the destination array
+@param dt Specification of each array element. It has the same format as in cvWriteRawData .
+ */
+CVAPI(void) cvReadRawDataSlice( const CvFileStorage* fs, CvSeqReader* reader,
+ int count, void* dst, const char* dt );
+
+/** @brief Reads multiple numbers.
+
+The function reads elements from a file node that represents a sequence of scalars.
+@param fs File storage
+@param src The file node (a sequence) to read numbers from
+@param dst Pointer to the destination array
+@param dt Specification of each array element. It has the same format as in cvWriteRawData .
+ */
+CVAPI(void) cvReadRawData( const CvFileStorage* fs, const CvFileNode* src,
+ void* dst, const char* dt );
+
+/** @brief Writes a file node to another file storage.
+
+The function writes a copy of a file node to file storage. Possible applications of the function are
+merging several file storages into one and conversion between XML, YAML and JSON formats.
+@param fs Destination file storage
+@param new_node_name New name of the file node in the destination file storage. To keep the
+existing name, use cvcvGetFileNodeName
+@param node The written node
+@param embed If the written node is a collection and this parameter is not zero, no extra level of
+hierarchy is created. Instead, all the elements of node are written into the currently written
+structure. Of course, map elements can only be embedded into another map, and sequence elements
+can only be embedded into another sequence.
+ */
+CVAPI(void) cvWriteFileNode( CvFileStorage* fs, const char* new_node_name,
+ const CvFileNode* node, int embed );
+
+/** @brief Returns the name of a file node.
+
+The function returns the name of a file node or NULL, if the file node does not have a name or if
+node is NULL.
+@param node File node
+ */
+CVAPI(const char*) cvGetFileNodeName( const CvFileNode* node );
+
+/*********************************** Adding own types ***********************************/
+
+/** @brief Registers a new type.
+
+The function registers a new type, which is described by info . The function creates a copy of the
+structure, so the user should delete it after calling the function.
+@param info Type info structure
+ */
+CVAPI(void) cvRegisterType( const CvTypeInfo* info );
+
+/** @brief Unregisters the type.
+
+The function unregisters a type with a specified name. If the name is unknown, it is possible to
+locate the type info by an instance of the type using cvTypeOf or by iterating the type list,
+starting from cvFirstType, and then calling cvUnregisterType(info-\>typeName).
+@param type_name Name of an unregistered type
+ */
+CVAPI(void) cvUnregisterType( const char* type_name );
+
+/** @brief Returns the beginning of a type list.
+
+The function returns the first type in the list of registered types. Navigation through the list can
+be done via the prev and next fields of the CvTypeInfo structure.
+ */
+CVAPI(CvTypeInfo*) cvFirstType(void);
+
+/** @brief Finds a type by its name.
+
+The function finds a registered type by its name. It returns NULL if there is no type with the
+specified name.
+@param type_name Type name
+ */
+CVAPI(CvTypeInfo*) cvFindType( const char* type_name );
+
+/** @brief Returns the type of an object.
+
+The function finds the type of a given object. It iterates through the list of registered types and
+calls the is_instance function/method for every type info structure with that object until one of
+them returns non-zero or until the whole list has been traversed. In the latter case, the function
+returns NULL.
+@param struct_ptr The object pointer
+ */
+CVAPI(CvTypeInfo*) cvTypeOf( const void* struct_ptr );
+
+/** @brief Releases an object.
+
+The function finds the type of a given object and calls release with the double pointer.
+@param struct_ptr Double pointer to the object
+ */
+CVAPI(void) cvRelease( void** struct_ptr );
+
+/** @brief Makes a clone of an object.
+
+The function finds the type of a given object and calls clone with the passed object. Of course, if
+you know the object type, for example, struct_ptr is CvMat\*, it is faster to call the specific
+function, like cvCloneMat.
+@param struct_ptr The object to clone
+ */
+CVAPI(void*) cvClone( const void* struct_ptr );
+
+/** @brief Saves an object to a file.
+
+The function saves an object to a file. It provides a simple interface to cvWrite .
+@param filename File name
+@param struct_ptr Object to save
+@param name Optional object name. If it is NULL, the name will be formed from filename .
+@param comment Optional comment to put in the beginning of the file
+@param attributes Optional attributes passed to cvWrite
+ */
+CVAPI(void) cvSave( const char* filename, const void* struct_ptr,
+ const char* name CV_DEFAULT(NULL),
+ const char* comment CV_DEFAULT(NULL),
+ CvAttrList attributes CV_DEFAULT(cvAttrList()));
+
+/** @brief Loads an object from a file.
+
+The function loads an object from a file. It basically reads the specified file, find the first
+top-level node and calls cvRead for that node. If the file node does not have type information or
+the type information can not be found by the type name, the function returns NULL. After the object
+is loaded, the file storage is closed and all the temporary buffers are deleted. Thus, to load a
+dynamic structure, such as a sequence, contour, or graph, one should pass a valid memory storage
+destination to the function.
+@param filename File name
+@param memstorage Memory storage for dynamic structures, such as CvSeq or CvGraph . It is not used
+for matrices or images.
+@param name Optional object name. If it is NULL, the first top-level object in the storage will be
+loaded.
+@param real_name Optional output parameter that will contain the name of the loaded object
+(useful if name=NULL )
+ */
+CVAPI(void*) cvLoad( const char* filename,
+ CvMemStorage* memstorage CV_DEFAULT(NULL),
+ const char* name CV_DEFAULT(NULL),
+ const char** real_name CV_DEFAULT(NULL) );
+
+/*********************************** Measuring Execution Time ***************************/
+
+/** helper functions for RNG initialization and accurate time measurement:
+ uses internal clock counter on x86 */
+CVAPI(int64) cvGetTickCount( void );
+CVAPI(double) cvGetTickFrequency( void );
+
+/*********************************** CPU capabilities ***********************************/
+
+CVAPI(int) cvCheckHardwareSupport(int feature);
+
+/*********************************** Multi-Threading ************************************/
+
+/** retrieve/set the number of threads used in OpenMP implementations */
+CVAPI(int) cvGetNumThreads( void );
+CVAPI(void) cvSetNumThreads( int threads CV_DEFAULT(0) );
+/** get index of the thread being executed */
+CVAPI(int) cvGetThreadNum( void );
+
+
+/********************************** Error Handling **************************************/
+
+/** Get current OpenCV error status */
+CVAPI(int) cvGetErrStatus( void );
+
+/** Sets error status silently */
+CVAPI(void) cvSetErrStatus( int status );
+
+#define CV_ErrModeLeaf 0 /* Print error and exit program */
+#define CV_ErrModeParent 1 /* Print error and continue */
+#define CV_ErrModeSilent 2 /* Don't print and continue */
+
+/** Retrives current error processing mode */
+CVAPI(int) cvGetErrMode( void );
+
+/** Sets error processing mode, returns previously used mode */
+CVAPI(int) cvSetErrMode( int mode );
+
+/** Sets error status and performs some additonal actions (displaying message box,
+ writing message to stderr, terminating application etc.)
+ depending on the current error mode */
+CVAPI(void) cvError( int status, const char* func_name,
+ const char* err_msg, const char* file_name, int line );
+
+/** Retrieves textual description of the error given its code */
+CVAPI(const char*) cvErrorStr( int status );
+
+/** Retrieves detailed information about the last error occured */
+CVAPI(int) cvGetErrInfo( const char** errcode_desc, const char** description,
+ const char** filename, int* line );
+
+/** Maps IPP error codes to the counterparts from OpenCV */
+CVAPI(int) cvErrorFromIppStatus( int ipp_status );
+
+typedef int (CV_CDECL *CvErrorCallback)( int status, const char* func_name,
+ const char* err_msg, const char* file_name, int line, void* userdata );
+
+/** Assigns a new error-handling function */
+CVAPI(CvErrorCallback) cvRedirectError( CvErrorCallback error_handler,
+ void* userdata CV_DEFAULT(NULL),
+ void** prev_userdata CV_DEFAULT(NULL) );
+
+/** Output nothing */
+CVAPI(int) cvNulDevReport( int status, const char* func_name, const char* err_msg,
+ const char* file_name, int line, void* userdata );
+
+/** Output to console(fprintf(stderr,...)) */
+CVAPI(int) cvStdErrReport( int status, const char* func_name, const char* err_msg,
+ const char* file_name, int line, void* userdata );
+
+/** Output to MessageBox(WIN32) */
+CVAPI(int) cvGuiBoxReport( int status, const char* func_name, const char* err_msg,
+ const char* file_name, int line, void* userdata );
+
+#define OPENCV_ERROR(status,func,context) \
+cvError((status),(func),(context),__FILE__,__LINE__)
+
+#define OPENCV_ASSERT(expr,func,context) \
+{if (! (expr)) \
+{OPENCV_ERROR(CV_StsInternal,(func),(context));}}
+
+#define OPENCV_CALL( Func ) \
+{ \
+Func; \
+}
+
+
+/** CV_FUNCNAME macro defines icvFuncName constant which is used by CV_ERROR macro */
+#ifdef CV_NO_FUNC_NAMES
+#define CV_FUNCNAME( Name )
+#define cvFuncName ""
+#else
+#define CV_FUNCNAME( Name ) \
+static char cvFuncName[] = Name
+#endif
+
+
+/**
+ CV_ERROR macro unconditionally raises error with passed code and message.
+ After raising error, control will be transferred to the exit label.
+ */
+#define CV_ERROR( Code, Msg ) \
+{ \
+ cvError( (Code), cvFuncName, Msg, __FILE__, __LINE__ ); \
+ __CV_EXIT__; \
+}
+
+/**
+ CV_CHECK macro checks error status after CV (or IPL)
+ function call. If error detected, control will be transferred to the exit
+ label.
+ */
+#define CV_CHECK() \
+{ \
+ if( cvGetErrStatus() < 0 ) \
+ CV_ERROR( CV_StsBackTrace, "Inner function failed." ); \
+}
+
+
+/**
+ CV_CALL macro calls CV (or IPL) function, checks error status and
+ signals a error if the function failed. Useful in "parent node"
+ error procesing mode
+ */
+#define CV_CALL( Func ) \
+{ \
+ Func; \
+ CV_CHECK(); \
+}
+
+
+/** Runtime assertion macro */
+#define CV_ASSERT( Condition ) \
+{ \
+ if( !(Condition) ) \
+ CV_ERROR( CV_StsInternal, "Assertion: " #Condition " failed" ); \
+}
+
+#define __CV_BEGIN__ {
+#define __CV_END__ goto exit; exit: ; }
+#define __CV_EXIT__ goto exit
+
+/** @} core_c */
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#ifdef __cplusplus
+
+//! @addtogroup core_c_glue
+//! @{
+
+//! class for automatic module/RTTI data registration/unregistration
+struct CV_EXPORTS CvType
+{
+ CvType( const char* type_name,
+ CvIsInstanceFunc is_instance, CvReleaseFunc release=0,
+ CvReadFunc read=0, CvWriteFunc write=0, CvCloneFunc clone=0 );
+ ~CvType();
+ CvTypeInfo* info;
+
+ static CvTypeInfo* first;
+ static CvTypeInfo* last;
+};
+
+//! @}
+
+#include "opencv2/core/utility.hpp"
+
+namespace cv
+{
+
+//! @addtogroup core_c_glue
+//! @{
+
+/////////////////////////////////////////// glue ///////////////////////////////////////////
+
+//! converts array (CvMat or IplImage) to cv::Mat
+CV_EXPORTS Mat cvarrToMat(const CvArr* arr, bool copyData=false,
+ bool allowND=true, int coiMode=0,
+ AutoBuffer<double>* buf=0);
+
+static inline Mat cvarrToMatND(const CvArr* arr, bool copyData=false, int coiMode=0)
+{
+ return cvarrToMat(arr, copyData, true, coiMode);
+}
+
+
+//! extracts Channel of Interest from CvMat or IplImage and makes cv::Mat out of it.
+CV_EXPORTS void extractImageCOI(const CvArr* arr, OutputArray coiimg, int coi=-1);
+//! inserts single-channel cv::Mat into a multi-channel CvMat or IplImage
+CV_EXPORTS void insertImageCOI(InputArray coiimg, CvArr* arr, int coi=-1);
+
+
+
+////// specialized implementations of DefaultDeleter::operator() for classic OpenCV types //////
+
+template<> CV_EXPORTS void DefaultDeleter<CvMat>::operator ()(CvMat* obj) const;
+template<> CV_EXPORTS void DefaultDeleter<IplImage>::operator ()(IplImage* obj) const;
+template<> CV_EXPORTS void DefaultDeleter<CvMatND>::operator ()(CvMatND* obj) const;
+template<> CV_EXPORTS void DefaultDeleter<CvSparseMat>::operator ()(CvSparseMat* obj) const;
+template<> CV_EXPORTS void DefaultDeleter<CvMemStorage>::operator ()(CvMemStorage* obj) const;
+
+////////////// convenient wrappers for operating old-style dynamic structures //////////////
+
+template<typename _Tp> class SeqIterator;
+
+typedef Ptr<CvMemStorage> MemStorage;
+
+/*!
+ Template Sequence Class derived from CvSeq
+
+ The class provides more convenient access to sequence elements,
+ STL-style operations and iterators.
+
+ \note The class is targeted for simple data types,
+ i.e. no constructors or destructors
+ are called for the sequence elements.
+*/
+template<typename _Tp> class Seq
+{
+public:
+ typedef SeqIterator<_Tp> iterator;
+ typedef SeqIterator<_Tp> const_iterator;
+
+ //! the default constructor
+ Seq();
+ //! the constructor for wrapping CvSeq structure. The real element type in CvSeq should match _Tp.
+ Seq(const CvSeq* seq);
+ //! creates the empty sequence that resides in the specified storage
+ Seq(MemStorage& storage, int headerSize = sizeof(CvSeq));
+ //! returns read-write reference to the specified element
+ _Tp& operator [](int idx);
+ //! returns read-only reference to the specified element
+ const _Tp& operator[](int idx) const;
+ //! returns iterator pointing to the beginning of the sequence
+ SeqIterator<_Tp> begin() const;
+ //! returns iterator pointing to the element following the last sequence element
+ SeqIterator<_Tp> end() const;
+ //! returns the number of elements in the sequence
+ size_t size() const;
+ //! returns the type of sequence elements (CV_8UC1 ... CV_64FC(CV_CN_MAX) ...)
+ int type() const;
+ //! returns the depth of sequence elements (CV_8U ... CV_64F)
+ int depth() const;
+ //! returns the number of channels in each sequence element
+ int channels() const;
+ //! returns the size of each sequence element
+ size_t elemSize() const;
+ //! returns index of the specified sequence element
+ size_t index(const _Tp& elem) const;
+ //! appends the specified element to the end of the sequence
+ void push_back(const _Tp& elem);
+ //! appends the specified element to the front of the sequence
+ void push_front(const _Tp& elem);
+ //! appends zero or more elements to the end of the sequence
+ void push_back(const _Tp* elems, size_t count);
+ //! appends zero or more elements to the front of the sequence
+ void push_front(const _Tp* elems, size_t count);
+ //! inserts the specified element to the specified position
+ void insert(int idx, const _Tp& elem);
+ //! inserts zero or more elements to the specified position
+ void insert(int idx, const _Tp* elems, size_t count);
+ //! removes element at the specified position
+ void remove(int idx);
+ //! removes the specified subsequence
+ void remove(const Range& r);
+
+ //! returns reference to the first sequence element
+ _Tp& front();
+ //! returns read-only reference to the first sequence element
+ const _Tp& front() const;
+ //! returns reference to the last sequence element
+ _Tp& back();
+ //! returns read-only reference to the last sequence element
+ const _Tp& back() const;
+ //! returns true iff the sequence contains no elements
+ bool empty() const;
+
+ //! removes all the elements from the sequence
+ void clear();
+ //! removes the first element from the sequence
+ void pop_front();
+ //! removes the last element from the sequence
+ void pop_back();
+ //! removes zero or more elements from the beginning of the sequence
+ void pop_front(_Tp* elems, size_t count);
+ //! removes zero or more elements from the end of the sequence
+ void pop_back(_Tp* elems, size_t count);
+
+ //! copies the whole sequence or the sequence slice to the specified vector
+ void copyTo(std::vector<_Tp>& vec, const Range& range=Range::all()) const;
+ //! returns the vector containing all the sequence elements
+ operator std::vector<_Tp>() const;
+
+ CvSeq* seq;
+};
+
+
+/*!
+ STL-style Sequence Iterator inherited from the CvSeqReader structure
+*/
+template<typename _Tp> class SeqIterator : public CvSeqReader
+{
+public:
+ //! the default constructor
+ SeqIterator();
+ //! the constructor setting the iterator to the beginning or to the end of the sequence
+ SeqIterator(const Seq<_Tp>& seq, bool seekEnd=false);
+ //! positions the iterator within the sequence
+ void seek(size_t pos);
+ //! reports the current iterator position
+ size_t tell() const;
+ //! returns reference to the current sequence element
+ _Tp& operator *();
+ //! returns read-only reference to the current sequence element
+ const _Tp& operator *() const;
+ //! moves iterator to the next sequence element
+ SeqIterator& operator ++();
+ //! moves iterator to the next sequence element
+ SeqIterator operator ++(int) const;
+ //! moves iterator to the previous sequence element
+ SeqIterator& operator --();
+ //! moves iterator to the previous sequence element
+ SeqIterator operator --(int) const;
+
+ //! moves iterator forward by the specified offset (possibly negative)
+ SeqIterator& operator +=(int);
+ //! moves iterator backward by the specified offset (possibly negative)
+ SeqIterator& operator -=(int);
+
+ // this is index of the current element module seq->total*2
+ // (to distinguish between 0 and seq->total)
+ int index;
+};
+
+
+
+// bridge C++ => C Seq API
+CV_EXPORTS schar* seqPush( CvSeq* seq, const void* element=0);
+CV_EXPORTS schar* seqPushFront( CvSeq* seq, const void* element=0);
+CV_EXPORTS void seqPop( CvSeq* seq, void* element=0);
+CV_EXPORTS void seqPopFront( CvSeq* seq, void* element=0);
+CV_EXPORTS void seqPopMulti( CvSeq* seq, void* elements,
+ int count, int in_front=0 );
+CV_EXPORTS void seqRemove( CvSeq* seq, int index );
+CV_EXPORTS void clearSeq( CvSeq* seq );
+CV_EXPORTS schar* getSeqElem( const CvSeq* seq, int index );
+CV_EXPORTS void seqRemoveSlice( CvSeq* seq, CvSlice slice );
+CV_EXPORTS void seqInsertSlice( CvSeq* seq, int before_index, const CvArr* from_arr );
+
+template<typename _Tp> inline Seq<_Tp>::Seq() : seq(0) {}
+template<typename _Tp> inline Seq<_Tp>::Seq( const CvSeq* _seq ) : seq((CvSeq*)_seq)
+{
+ CV_Assert(!_seq || _seq->elem_size == sizeof(_Tp));
+}
+
+template<typename _Tp> inline Seq<_Tp>::Seq( MemStorage& storage,
+ int headerSize )
+{
+ CV_Assert(headerSize >= (int)sizeof(CvSeq));
+ seq = cvCreateSeq(DataType<_Tp>::type, headerSize, sizeof(_Tp), storage);
+}
+
+template<typename _Tp> inline _Tp& Seq<_Tp>::operator [](int idx)
+{ return *(_Tp*)getSeqElem(seq, idx); }
+
+template<typename _Tp> inline const _Tp& Seq<_Tp>::operator [](int idx) const
+{ return *(_Tp*)getSeqElem(seq, idx); }
+
+template<typename _Tp> inline SeqIterator<_Tp> Seq<_Tp>::begin() const
+{ return SeqIterator<_Tp>(*this); }
+
+template<typename _Tp> inline SeqIterator<_Tp> Seq<_Tp>::end() const
+{ return SeqIterator<_Tp>(*this, true); }
+
+template<typename _Tp> inline size_t Seq<_Tp>::size() const
+{ return seq ? seq->total : 0; }
+
+template<typename _Tp> inline int Seq<_Tp>::type() const
+{ return seq ? CV_MAT_TYPE(seq->flags) : 0; }
+
+template<typename _Tp> inline int Seq<_Tp>::depth() const
+{ return seq ? CV_MAT_DEPTH(seq->flags) : 0; }
+
+template<typename _Tp> inline int Seq<_Tp>::channels() const
+{ return seq ? CV_MAT_CN(seq->flags) : 0; }
+
+template<typename _Tp> inline size_t Seq<_Tp>::elemSize() const
+{ return seq ? seq->elem_size : 0; }
+
+template<typename _Tp> inline size_t Seq<_Tp>::index(const _Tp& elem) const
+{ return cvSeqElemIdx(seq, &elem); }
+
+template<typename _Tp> inline void Seq<_Tp>::push_back(const _Tp& elem)
+{ cvSeqPush(seq, &elem); }
+
+template<typename _Tp> inline void Seq<_Tp>::push_front(const _Tp& elem)
+{ cvSeqPushFront(seq, &elem); }
+
+template<typename _Tp> inline void Seq<_Tp>::push_back(const _Tp* elem, size_t count)
+{ cvSeqPushMulti(seq, elem, (int)count, 0); }
+
+template<typename _Tp> inline void Seq<_Tp>::push_front(const _Tp* elem, size_t count)
+{ cvSeqPushMulti(seq, elem, (int)count, 1); }
+
+template<typename _Tp> inline _Tp& Seq<_Tp>::back()
+{ return *(_Tp*)getSeqElem(seq, -1); }
+
+template<typename _Tp> inline const _Tp& Seq<_Tp>::back() const
+{ return *(const _Tp*)getSeqElem(seq, -1); }
+
+template<typename _Tp> inline _Tp& Seq<_Tp>::front()
+{ return *(_Tp*)getSeqElem(seq, 0); }
+
+template<typename _Tp> inline const _Tp& Seq<_Tp>::front() const
+{ return *(const _Tp*)getSeqElem(seq, 0); }
+
+template<typename _Tp> inline bool Seq<_Tp>::empty() const
+{ return !seq || seq->total == 0; }
+
+template<typename _Tp> inline void Seq<_Tp>::clear()
+{ if(seq) clearSeq(seq); }
+
+template<typename _Tp> inline void Seq<_Tp>::pop_back()
+{ seqPop(seq); }
+
+template<typename _Tp> inline void Seq<_Tp>::pop_front()
+{ seqPopFront(seq); }
+
+template<typename _Tp> inline void Seq<_Tp>::pop_back(_Tp* elem, size_t count)
+{ seqPopMulti(seq, elem, (int)count, 0); }
+
+template<typename _Tp> inline void Seq<_Tp>::pop_front(_Tp* elem, size_t count)
+{ seqPopMulti(seq, elem, (int)count, 1); }
+
+template<typename _Tp> inline void Seq<_Tp>::insert(int idx, const _Tp& elem)
+{ seqInsert(seq, idx, &elem); }
+
+template<typename _Tp> inline void Seq<_Tp>::insert(int idx, const _Tp* elems, size_t count)
+{
+ CvMat m = cvMat(1, count, DataType<_Tp>::type, elems);
+ seqInsertSlice(seq, idx, &m);
+}
+
+template<typename _Tp> inline void Seq<_Tp>::remove(int idx)
+{ seqRemove(seq, idx); }
+
+template<typename _Tp> inline void Seq<_Tp>::remove(const Range& r)
+{ seqRemoveSlice(seq, cvSlice(r.start, r.end)); }
+
+template<typename _Tp> inline void Seq<_Tp>::copyTo(std::vector<_Tp>& vec, const Range& range) const
+{
+ size_t len = !seq ? 0 : range == Range::all() ? seq->total : range.end - range.start;
+ vec.resize(len);
+ if( seq && len )
+ cvCvtSeqToArray(seq, &vec[0], range);
+}
+
+template<typename _Tp> inline Seq<_Tp>::operator std::vector<_Tp>() const
+{
+ std::vector<_Tp> vec;
+ copyTo(vec);
+ return vec;
+}
+
+template<typename _Tp> inline SeqIterator<_Tp>::SeqIterator()
+{ memset(this, 0, sizeof(*this)); }
+
+template<typename _Tp> inline SeqIterator<_Tp>::SeqIterator(const Seq<_Tp>& _seq, bool seekEnd)
+{
+ cvStartReadSeq(_seq.seq, this);
+ index = seekEnd ? _seq.seq->total : 0;
+}
+
+template<typename _Tp> inline void SeqIterator<_Tp>::seek(size_t pos)
+{
+ cvSetSeqReaderPos(this, (int)pos, false);
+ index = pos;
+}
+
+template<typename _Tp> inline size_t SeqIterator<_Tp>::tell() const
+{ return index; }
+
+template<typename _Tp> inline _Tp& SeqIterator<_Tp>::operator *()
+{ return *(_Tp*)ptr; }
+
+template<typename _Tp> inline const _Tp& SeqIterator<_Tp>::operator *() const
+{ return *(const _Tp*)ptr; }
+
+template<typename _Tp> inline SeqIterator<_Tp>& SeqIterator<_Tp>::operator ++()
+{
+ CV_NEXT_SEQ_ELEM(sizeof(_Tp), *this);
+ if( ++index >= seq->total*2 )
+ index = 0;
+ return *this;
+}
+
+template<typename _Tp> inline SeqIterator<_Tp> SeqIterator<_Tp>::operator ++(int) const
+{
+ SeqIterator<_Tp> it = *this;
+ ++*this;
+ return it;
+}
+
+template<typename _Tp> inline SeqIterator<_Tp>& SeqIterator<_Tp>::operator --()
+{
+ CV_PREV_SEQ_ELEM(sizeof(_Tp), *this);
+ if( --index < 0 )
+ index = seq->total*2-1;
+ return *this;
+}
+
+template<typename _Tp> inline SeqIterator<_Tp> SeqIterator<_Tp>::operator --(int) const
+{
+ SeqIterator<_Tp> it = *this;
+ --*this;
+ return it;
+}
+
+template<typename _Tp> inline SeqIterator<_Tp>& SeqIterator<_Tp>::operator +=(int delta)
+{
+ cvSetSeqReaderPos(this, delta, 1);
+ index += delta;
+ int n = seq->total*2;
+ if( index < 0 )
+ index += n;
+ if( index >= n )
+ index -= n;
+ return *this;
+}
+
+template<typename _Tp> inline SeqIterator<_Tp>& SeqIterator<_Tp>::operator -=(int delta)
+{
+ return (*this += -delta);
+}
+
+template<typename _Tp> inline ptrdiff_t operator - (const SeqIterator<_Tp>& a,
+ const SeqIterator<_Tp>& b)
+{
+ ptrdiff_t delta = a.index - b.index, n = a.seq->total;
+ if( delta > n || delta < -n )
+ delta += delta < 0 ? n : -n;
+ return delta;
+}
+
+template<typename _Tp> inline bool operator == (const SeqIterator<_Tp>& a,
+ const SeqIterator<_Tp>& b)
+{
+ return a.seq == b.seq && a.index == b.index;
+}
+
+template<typename _Tp> inline bool operator != (const SeqIterator<_Tp>& a,
+ const SeqIterator<_Tp>& b)
+{
+ return !(a == b);
+}
+
+//! @}
+
+} // cv
+
+#endif
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/core/cuda.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,874 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_CORE_CUDA_HPP
+#define OPENCV_CORE_CUDA_HPP
+
+#ifndef __cplusplus
+# error cuda.hpp header must be compiled as C++
+#endif
+
+#include "opencv2/core.hpp"
+#include "opencv2/core/cuda_types.hpp"
+
+/**
+ @defgroup cuda CUDA-accelerated Computer Vision
+ @{
+ @defgroup cudacore Core part
+ @{
+ @defgroup cudacore_init Initalization and Information
+ @defgroup cudacore_struct Data Structures
+ @}
+ @}
+ */
+
+namespace cv { namespace cuda {
+
+//! @addtogroup cudacore_struct
+//! @{
+
+//===================================================================================
+// GpuMat
+//===================================================================================
+
+/** @brief Base storage class for GPU memory with reference counting.
+
+Its interface matches the Mat interface with the following limitations:
+
+- no arbitrary dimensions support (only 2D)
+- no functions that return references to their data (because references on GPU are not valid for
+ CPU)
+- no expression templates technique support
+
+Beware that the latter limitation may lead to overloaded matrix operators that cause memory
+allocations. The GpuMat class is convertible to cuda::PtrStepSz and cuda::PtrStep so it can be
+passed directly to the kernel.
+
+@note In contrast with Mat, in most cases GpuMat::isContinuous() == false . This means that rows are
+aligned to a size depending on the hardware. Single-row GpuMat is always a continuous matrix.
+
+@note You are not recommended to leave static or global GpuMat variables allocated, that is, to rely
+on its destructor. The destruction order of such variables and CUDA context is undefined. GPU memory
+release function returns error if the CUDA context has been destroyed before.
+
+@sa Mat
+ */
+class CV_EXPORTS GpuMat
+{
+public:
+ class CV_EXPORTS Allocator
+ {
+ public:
+ virtual ~Allocator() {}
+
+ // allocator must fill data, step and refcount fields
+ virtual bool allocate(GpuMat* mat, int rows, int cols, size_t elemSize) = 0;
+ virtual void free(GpuMat* mat) = 0;
+ };
+
+ //! default allocator
+ static Allocator* defaultAllocator();
+ static void setDefaultAllocator(Allocator* allocator);
+
+ //! default constructor
+ explicit GpuMat(Allocator* allocator = defaultAllocator());
+
+ //! constructs GpuMat of the specified size and type
+ GpuMat(int rows, int cols, int type, Allocator* allocator = defaultAllocator());
+ GpuMat(Size size, int type, Allocator* allocator = defaultAllocator());
+
+ //! constucts GpuMat and fills it with the specified value _s
+ GpuMat(int rows, int cols, int type, Scalar s, Allocator* allocator = defaultAllocator());
+ GpuMat(Size size, int type, Scalar s, Allocator* allocator = defaultAllocator());
+
+ //! copy constructor
+ GpuMat(const GpuMat& m);
+
+ //! constructor for GpuMat headers pointing to user-allocated data
+ GpuMat(int rows, int cols, int type, void* data, size_t step = Mat::AUTO_STEP);
+ GpuMat(Size size, int type, void* data, size_t step = Mat::AUTO_STEP);
+
+ //! creates a GpuMat header for a part of the bigger matrix
+ GpuMat(const GpuMat& m, Range rowRange, Range colRange);
+ GpuMat(const GpuMat& m, Rect roi);
+
+ //! builds GpuMat from host memory (Blocking call)
+ explicit GpuMat(InputArray arr, Allocator* allocator = defaultAllocator());
+
+ //! destructor - calls release()
+ ~GpuMat();
+
+ //! assignment operators
+ GpuMat& operator =(const GpuMat& m);
+
+ //! allocates new GpuMat data unless the GpuMat already has specified size and type
+ void create(int rows, int cols, int type);
+ void create(Size size, int type);
+
+ //! decreases reference counter, deallocate the data when reference counter reaches 0
+ void release();
+
+ //! swaps with other smart pointer
+ void swap(GpuMat& mat);
+
+ //! pefroms upload data to GpuMat (Blocking call)
+ void upload(InputArray arr);
+
+ //! pefroms upload data to GpuMat (Non-Blocking call)
+ void upload(InputArray arr, Stream& stream);
+
+ //! pefroms download data from device to host memory (Blocking call)
+ void download(OutputArray dst) const;
+
+ //! pefroms download data from device to host memory (Non-Blocking call)
+ void download(OutputArray dst, Stream& stream) const;
+
+ //! returns deep copy of the GpuMat, i.e. the data is copied
+ GpuMat clone() const;
+
+ //! copies the GpuMat content to device memory (Blocking call)
+ void copyTo(OutputArray dst) const;
+
+ //! copies the GpuMat content to device memory (Non-Blocking call)
+ void copyTo(OutputArray dst, Stream& stream) const;
+
+ //! copies those GpuMat elements to "m" that are marked with non-zero mask elements (Blocking call)
+ void copyTo(OutputArray dst, InputArray mask) const;
+
+ //! copies those GpuMat elements to "m" that are marked with non-zero mask elements (Non-Blocking call)
+ void copyTo(OutputArray dst, InputArray mask, Stream& stream) const;
+
+ //! sets some of the GpuMat elements to s (Blocking call)
+ GpuMat& setTo(Scalar s);
+
+ //! sets some of the GpuMat elements to s (Non-Blocking call)
+ GpuMat& setTo(Scalar s, Stream& stream);
+
+ //! sets some of the GpuMat elements to s, according to the mask (Blocking call)
+ GpuMat& setTo(Scalar s, InputArray mask);
+
+ //! sets some of the GpuMat elements to s, according to the mask (Non-Blocking call)
+ GpuMat& setTo(Scalar s, InputArray mask, Stream& stream);
+
+ //! converts GpuMat to another datatype (Blocking call)
+ void convertTo(OutputArray dst, int rtype) const;
+
+ //! converts GpuMat to another datatype (Non-Blocking call)
+ void convertTo(OutputArray dst, int rtype, Stream& stream) const;
+
+ //! converts GpuMat to another datatype with scaling (Blocking call)
+ void convertTo(OutputArray dst, int rtype, double alpha, double beta = 0.0) const;
+
+ //! converts GpuMat to another datatype with scaling (Non-Blocking call)
+ void convertTo(OutputArray dst, int rtype, double alpha, Stream& stream) const;
+
+ //! converts GpuMat to another datatype with scaling (Non-Blocking call)
+ void convertTo(OutputArray dst, int rtype, double alpha, double beta, Stream& stream) const;
+
+ void assignTo(GpuMat& m, int type=-1) const;
+
+ //! returns pointer to y-th row
+ uchar* ptr(int y = 0);
+ const uchar* ptr(int y = 0) const;
+
+ //! template version of the above method
+ template<typename _Tp> _Tp* ptr(int y = 0);
+ template<typename _Tp> const _Tp* ptr(int y = 0) const;
+
+ template <typename _Tp> operator PtrStepSz<_Tp>() const;
+ template <typename _Tp> operator PtrStep<_Tp>() const;
+
+ //! returns a new GpuMat header for the specified row
+ GpuMat row(int y) const;
+
+ //! returns a new GpuMat header for the specified column
+ GpuMat col(int x) const;
+
+ //! ... for the specified row span
+ GpuMat rowRange(int startrow, int endrow) const;
+ GpuMat rowRange(Range r) const;
+
+ //! ... for the specified column span
+ GpuMat colRange(int startcol, int endcol) const;
+ GpuMat colRange(Range r) const;
+
+ //! extracts a rectangular sub-GpuMat (this is a generalized form of row, rowRange etc.)
+ GpuMat operator ()(Range rowRange, Range colRange) const;
+ GpuMat operator ()(Rect roi) const;
+
+ //! creates alternative GpuMat header for the same data, with different
+ //! number of channels and/or different number of rows
+ GpuMat reshape(int cn, int rows = 0) const;
+
+ //! locates GpuMat header within a parent GpuMat
+ void locateROI(Size& wholeSize, Point& ofs) const;
+
+ //! moves/resizes the current GpuMat ROI inside the parent GpuMat
+ GpuMat& adjustROI(int dtop, int dbottom, int dleft, int dright);
+
+ //! returns true iff the GpuMat data is continuous
+ //! (i.e. when there are no gaps between successive rows)
+ bool isContinuous() const;
+
+ //! returns element size in bytes
+ size_t elemSize() const;
+
+ //! returns the size of element channel in bytes
+ size_t elemSize1() const;
+
+ //! returns element type
+ int type() const;
+
+ //! returns element type
+ int depth() const;
+
+ //! returns number of channels
+ int channels() const;
+
+ //! returns step/elemSize1()
+ size_t step1() const;
+
+ //! returns GpuMat size : width == number of columns, height == number of rows
+ Size size() const;
+
+ //! returns true if GpuMat data is NULL
+ bool empty() const;
+
+ /*! includes several bit-fields:
+ - the magic signature
+ - continuity flag
+ - depth
+ - number of channels
+ */
+ int flags;
+
+ //! the number of rows and columns
+ int rows, cols;
+
+ //! a distance between successive rows in bytes; includes the gap if any
+ size_t step;
+
+ //! pointer to the data
+ uchar* data;
+
+ //! pointer to the reference counter;
+ //! when GpuMat points to user-allocated data, the pointer is NULL
+ int* refcount;
+
+ //! helper fields used in locateROI and adjustROI
+ uchar* datastart;
+ const uchar* dataend;
+
+ //! allocator
+ Allocator* allocator;
+};
+
+/** @brief Creates a continuous matrix.
+
+@param rows Row count.
+@param cols Column count.
+@param type Type of the matrix.
+@param arr Destination matrix. This parameter changes only if it has a proper type and area (
+\f$\texttt{rows} \times \texttt{cols}\f$ ).
+
+Matrix is called continuous if its elements are stored continuously, that is, without gaps at the
+end of each row.
+ */
+CV_EXPORTS void createContinuous(int rows, int cols, int type, OutputArray arr);
+
+/** @brief Ensures that the size of a matrix is big enough and the matrix has a proper type.
+
+@param rows Minimum desired number of rows.
+@param cols Minimum desired number of columns.
+@param type Desired matrix type.
+@param arr Destination matrix.
+
+The function does not reallocate memory if the matrix has proper attributes already.
+ */
+CV_EXPORTS void ensureSizeIsEnough(int rows, int cols, int type, OutputArray arr);
+
+//! BufferPool management (must be called before Stream creation)
+CV_EXPORTS void setBufferPoolUsage(bool on);
+CV_EXPORTS void setBufferPoolConfig(int deviceId, size_t stackSize, int stackCount);
+
+//===================================================================================
+// HostMem
+//===================================================================================
+
+/** @brief Class with reference counting wrapping special memory type allocation functions from CUDA.
+
+Its interface is also Mat-like but with additional memory type parameters.
+
+- **PAGE_LOCKED** sets a page locked memory type used commonly for fast and asynchronous
+ uploading/downloading data from/to GPU.
+- **SHARED** specifies a zero copy memory allocation that enables mapping the host memory to GPU
+ address space, if supported.
+- **WRITE_COMBINED** sets the write combined buffer that is not cached by CPU. Such buffers are
+ used to supply GPU with data when GPU only reads it. The advantage is a better CPU cache
+ utilization.
+
+@note Allocation size of such memory types is usually limited. For more details, see *CUDA 2.2
+Pinned Memory APIs* document or *CUDA C Programming Guide*.
+ */
+class CV_EXPORTS HostMem
+{
+public:
+ enum AllocType { PAGE_LOCKED = 1, SHARED = 2, WRITE_COMBINED = 4 };
+
+ static MatAllocator* getAllocator(AllocType alloc_type = PAGE_LOCKED);
+
+ explicit HostMem(AllocType alloc_type = PAGE_LOCKED);
+
+ HostMem(const HostMem& m);
+
+ HostMem(int rows, int cols, int type, AllocType alloc_type = PAGE_LOCKED);
+ HostMem(Size size, int type, AllocType alloc_type = PAGE_LOCKED);
+
+ //! creates from host memory with coping data
+ explicit HostMem(InputArray arr, AllocType alloc_type = PAGE_LOCKED);
+
+ ~HostMem();
+
+ HostMem& operator =(const HostMem& m);
+
+ //! swaps with other smart pointer
+ void swap(HostMem& b);
+
+ //! returns deep copy of the matrix, i.e. the data is copied
+ HostMem clone() const;
+
+ //! allocates new matrix data unless the matrix already has specified size and type.
+ void create(int rows, int cols, int type);
+ void create(Size size, int type);
+
+ //! creates alternative HostMem header for the same data, with different
+ //! number of channels and/or different number of rows
+ HostMem reshape(int cn, int rows = 0) const;
+
+ //! decrements reference counter and released memory if needed.
+ void release();
+
+ //! returns matrix header with disabled reference counting for HostMem data.
+ Mat createMatHeader() const;
+
+ /** @brief Maps CPU memory to GPU address space and creates the cuda::GpuMat header without reference counting
+ for it.
+
+ This can be done only if memory was allocated with the SHARED flag and if it is supported by the
+ hardware. Laptops often share video and CPU memory, so address spaces can be mapped, which
+ eliminates an extra copy.
+ */
+ GpuMat createGpuMatHeader() const;
+
+ // Please see cv::Mat for descriptions
+ bool isContinuous() const;
+ size_t elemSize() const;
+ size_t elemSize1() const;
+ int type() const;
+ int depth() const;
+ int channels() const;
+ size_t step1() const;
+ Size size() const;
+ bool empty() const;
+
+ // Please see cv::Mat for descriptions
+ int flags;
+ int rows, cols;
+ size_t step;
+
+ uchar* data;
+ int* refcount;
+
+ uchar* datastart;
+ const uchar* dataend;
+
+ AllocType alloc_type;
+};
+
+/** @brief Page-locks the memory of matrix and maps it for the device(s).
+
+@param m Input matrix.
+ */
+CV_EXPORTS void registerPageLocked(Mat& m);
+
+/** @brief Unmaps the memory of matrix and makes it pageable again.
+
+@param m Input matrix.
+ */
+CV_EXPORTS void unregisterPageLocked(Mat& m);
+
+//===================================================================================
+// Stream
+//===================================================================================
+
+/** @brief This class encapsulates a queue of asynchronous calls.
+
+@note Currently, you may face problems if an operation is enqueued twice with different data. Some
+functions use the constant GPU memory, and next call may update the memory before the previous one
+has been finished. But calling different operations asynchronously is safe because each operation
+has its own constant buffer. Memory copy/upload/download/set operations to the buffers you hold are
+also safe.
+
+@note The Stream class is not thread-safe. Please use different Stream objects for different CPU threads.
+
+@code
+void thread1()
+{
+ cv::cuda::Stream stream1;
+ cv::cuda::func1(..., stream1);
+}
+
+void thread2()
+{
+ cv::cuda::Stream stream2;
+ cv::cuda::func2(..., stream2);
+}
+@endcode
+
+@note By default all CUDA routines are launched in Stream::Null() object, if the stream is not specified by user.
+In multi-threading environment the stream objects must be passed explicitly (see previous note).
+ */
+class CV_EXPORTS Stream
+{
+ typedef void (Stream::*bool_type)() const;
+ void this_type_does_not_support_comparisons() const {}
+
+public:
+ typedef void (*StreamCallback)(int status, void* userData);
+
+ //! creates a new asynchronous stream
+ Stream();
+
+ /** @brief Returns true if the current stream queue is finished. Otherwise, it returns false.
+ */
+ bool queryIfComplete() const;
+
+ /** @brief Blocks the current CPU thread until all operations in the stream are complete.
+ */
+ void waitForCompletion();
+
+ /** @brief Makes a compute stream wait on an event.
+ */
+ void waitEvent(const Event& event);
+
+ /** @brief Adds a callback to be called on the host after all currently enqueued items in the stream have
+ completed.
+
+ @note Callbacks must not make any CUDA API calls. Callbacks must not perform any synchronization
+ that may depend on outstanding device work or other callbacks that are not mandated to run earlier.
+ Callbacks without a mandated order (in independent streams) execute in undefined order and may be
+ serialized.
+ */
+ void enqueueHostCallback(StreamCallback callback, void* userData);
+
+ //! return Stream object for default CUDA stream
+ static Stream& Null();
+
+ //! returns true if stream object is not default (!= 0)
+ operator bool_type() const;
+
+ class Impl;
+
+private:
+ Ptr<Impl> impl_;
+ Stream(const Ptr<Impl>& impl);
+
+ friend struct StreamAccessor;
+ friend class BufferPool;
+ friend class DefaultDeviceInitializer;
+};
+
+class CV_EXPORTS Event
+{
+public:
+ enum CreateFlags
+ {
+ DEFAULT = 0x00, /**< Default event flag */
+ BLOCKING_SYNC = 0x01, /**< Event uses blocking synchronization */
+ DISABLE_TIMING = 0x02, /**< Event will not record timing data */
+ INTERPROCESS = 0x04 /**< Event is suitable for interprocess use. DisableTiming must be set */
+ };
+
+ explicit Event(CreateFlags flags = DEFAULT);
+
+ //! records an event
+ void record(Stream& stream = Stream::Null());
+
+ //! queries an event's status
+ bool queryIfComplete() const;
+
+ //! waits for an event to complete
+ void waitForCompletion();
+
+ //! computes the elapsed time between events
+ static float elapsedTime(const Event& start, const Event& end);
+
+ class Impl;
+
+private:
+ Ptr<Impl> impl_;
+ Event(const Ptr<Impl>& impl);
+
+ friend struct EventAccessor;
+};
+
+//! @} cudacore_struct
+
+//===================================================================================
+// Initialization & Info
+//===================================================================================
+
+//! @addtogroup cudacore_init
+//! @{
+
+/** @brief Returns the number of installed CUDA-enabled devices.
+
+Use this function before any other CUDA functions calls. If OpenCV is compiled without CUDA support,
+this function returns 0.
+ */
+CV_EXPORTS int getCudaEnabledDeviceCount();
+
+/** @brief Sets a device and initializes it for the current thread.
+
+@param device System index of a CUDA device starting with 0.
+
+If the call of this function is omitted, a default device is initialized at the fist CUDA usage.
+ */
+CV_EXPORTS void setDevice(int device);
+
+/** @brief Returns the current device index set by cuda::setDevice or initialized by default.
+ */
+CV_EXPORTS int getDevice();
+
+/** @brief Explicitly destroys and cleans up all resources associated with the current device in the current
+process.
+
+Any subsequent API call to this device will reinitialize the device.
+ */
+CV_EXPORTS void resetDevice();
+
+/** @brief Enumeration providing CUDA computing features.
+ */
+enum FeatureSet
+{
+ FEATURE_SET_COMPUTE_10 = 10,
+ FEATURE_SET_COMPUTE_11 = 11,
+ FEATURE_SET_COMPUTE_12 = 12,
+ FEATURE_SET_COMPUTE_13 = 13,
+ FEATURE_SET_COMPUTE_20 = 20,
+ FEATURE_SET_COMPUTE_21 = 21,
+ FEATURE_SET_COMPUTE_30 = 30,
+ FEATURE_SET_COMPUTE_32 = 32,
+ FEATURE_SET_COMPUTE_35 = 35,
+ FEATURE_SET_COMPUTE_50 = 50,
+
+ GLOBAL_ATOMICS = FEATURE_SET_COMPUTE_11,
+ SHARED_ATOMICS = FEATURE_SET_COMPUTE_12,
+ NATIVE_DOUBLE = FEATURE_SET_COMPUTE_13,
+ WARP_SHUFFLE_FUNCTIONS = FEATURE_SET_COMPUTE_30,
+ DYNAMIC_PARALLELISM = FEATURE_SET_COMPUTE_35
+};
+
+//! checks whether current device supports the given feature
+CV_EXPORTS bool deviceSupports(FeatureSet feature_set);
+
+/** @brief Class providing a set of static methods to check what NVIDIA\* card architecture the CUDA module was
+built for.
+
+According to the CUDA C Programming Guide Version 3.2: "PTX code produced for some specific compute
+capability can always be compiled to binary code of greater or equal compute capability".
+ */
+class CV_EXPORTS TargetArchs
+{
+public:
+ /** @brief The following method checks whether the module was built with the support of the given feature:
+
+ @param feature_set Features to be checked. See :ocvcuda::FeatureSet.
+ */
+ static bool builtWith(FeatureSet feature_set);
+
+ /** @brief There is a set of methods to check whether the module contains intermediate (PTX) or binary CUDA
+ code for the given architecture(s):
+
+ @param major Major compute capability version.
+ @param minor Minor compute capability version.
+ */
+ static bool has(int major, int minor);
+ static bool hasPtx(int major, int minor);
+ static bool hasBin(int major, int minor);
+
+ static bool hasEqualOrLessPtx(int major, int minor);
+ static bool hasEqualOrGreater(int major, int minor);
+ static bool hasEqualOrGreaterPtx(int major, int minor);
+ static bool hasEqualOrGreaterBin(int major, int minor);
+};
+
+/** @brief Class providing functionality for querying the specified GPU properties.
+ */
+class CV_EXPORTS DeviceInfo
+{
+public:
+ //! creates DeviceInfo object for the current GPU
+ DeviceInfo();
+
+ /** @brief The constructors.
+
+ @param device_id System index of the CUDA device starting with 0.
+
+ Constructs the DeviceInfo object for the specified device. If device_id parameter is missed, it
+ constructs an object for the current device.
+ */
+ DeviceInfo(int device_id);
+
+ /** @brief Returns system index of the CUDA device starting with 0.
+ */
+ int deviceID() const;
+
+ //! ASCII string identifying device
+ const char* name() const;
+
+ //! global memory available on device in bytes
+ size_t totalGlobalMem() const;
+
+ //! shared memory available per block in bytes
+ size_t sharedMemPerBlock() const;
+
+ //! 32-bit registers available per block
+ int regsPerBlock() const;
+
+ //! warp size in threads
+ int warpSize() const;
+
+ //! maximum pitch in bytes allowed by memory copies
+ size_t memPitch() const;
+
+ //! maximum number of threads per block
+ int maxThreadsPerBlock() const;
+
+ //! maximum size of each dimension of a block
+ Vec3i maxThreadsDim() const;
+
+ //! maximum size of each dimension of a grid
+ Vec3i maxGridSize() const;
+
+ //! clock frequency in kilohertz
+ int clockRate() const;
+
+ //! constant memory available on device in bytes
+ size_t totalConstMem() const;
+
+ //! major compute capability
+ int majorVersion() const;
+
+ //! minor compute capability
+ int minorVersion() const;
+
+ //! alignment requirement for textures
+ size_t textureAlignment() const;
+
+ //! pitch alignment requirement for texture references bound to pitched memory
+ size_t texturePitchAlignment() const;
+
+ //! number of multiprocessors on device
+ int multiProcessorCount() const;
+
+ //! specified whether there is a run time limit on kernels
+ bool kernelExecTimeoutEnabled() const;
+
+ //! device is integrated as opposed to discrete
+ bool integrated() const;
+
+ //! device can map host memory with cudaHostAlloc/cudaHostGetDevicePointer
+ bool canMapHostMemory() const;
+
+ enum ComputeMode
+ {
+ ComputeModeDefault, /**< default compute mode (Multiple threads can use cudaSetDevice with this device) */
+ ComputeModeExclusive, /**< compute-exclusive-thread mode (Only one thread in one process will be able to use cudaSetDevice with this device) */
+ ComputeModeProhibited, /**< compute-prohibited mode (No threads can use cudaSetDevice with this device) */
+ ComputeModeExclusiveProcess /**< compute-exclusive-process mode (Many threads in one process will be able to use cudaSetDevice with this device) */
+ };
+
+ //! compute mode
+ ComputeMode computeMode() const;
+
+ //! maximum 1D texture size
+ int maxTexture1D() const;
+
+ //! maximum 1D mipmapped texture size
+ int maxTexture1DMipmap() const;
+
+ //! maximum size for 1D textures bound to linear memory
+ int maxTexture1DLinear() const;
+
+ //! maximum 2D texture dimensions
+ Vec2i maxTexture2D() const;
+
+ //! maximum 2D mipmapped texture dimensions
+ Vec2i maxTexture2DMipmap() const;
+
+ //! maximum dimensions (width, height, pitch) for 2D textures bound to pitched memory
+ Vec3i maxTexture2DLinear() const;
+
+ //! maximum 2D texture dimensions if texture gather operations have to be performed
+ Vec2i maxTexture2DGather() const;
+
+ //! maximum 3D texture dimensions
+ Vec3i maxTexture3D() const;
+
+ //! maximum Cubemap texture dimensions
+ int maxTextureCubemap() const;
+
+ //! maximum 1D layered texture dimensions
+ Vec2i maxTexture1DLayered() const;
+
+ //! maximum 2D layered texture dimensions
+ Vec3i maxTexture2DLayered() const;
+
+ //! maximum Cubemap layered texture dimensions
+ Vec2i maxTextureCubemapLayered() const;
+
+ //! maximum 1D surface size
+ int maxSurface1D() const;
+
+ //! maximum 2D surface dimensions
+ Vec2i maxSurface2D() const;
+
+ //! maximum 3D surface dimensions
+ Vec3i maxSurface3D() const;
+
+ //! maximum 1D layered surface dimensions
+ Vec2i maxSurface1DLayered() const;
+
+ //! maximum 2D layered surface dimensions
+ Vec3i maxSurface2DLayered() const;
+
+ //! maximum Cubemap surface dimensions
+ int maxSurfaceCubemap() const;
+
+ //! maximum Cubemap layered surface dimensions
+ Vec2i maxSurfaceCubemapLayered() const;
+
+ //! alignment requirements for surfaces
+ size_t surfaceAlignment() const;
+
+ //! device can possibly execute multiple kernels concurrently
+ bool concurrentKernels() const;
+
+ //! device has ECC support enabled
+ bool ECCEnabled() const;
+
+ //! PCI bus ID of the device
+ int pciBusID() const;
+
+ //! PCI device ID of the device
+ int pciDeviceID() const;
+
+ //! PCI domain ID of the device
+ int pciDomainID() const;
+
+ //! true if device is a Tesla device using TCC driver, false otherwise
+ bool tccDriver() const;
+
+ //! number of asynchronous engines
+ int asyncEngineCount() const;
+
+ //! device shares a unified address space with the host
+ bool unifiedAddressing() const;
+
+ //! peak memory clock frequency in kilohertz
+ int memoryClockRate() const;
+
+ //! global memory bus width in bits
+ int memoryBusWidth() const;
+
+ //! size of L2 cache in bytes
+ int l2CacheSize() const;
+
+ //! maximum resident threads per multiprocessor
+ int maxThreadsPerMultiProcessor() const;
+
+ //! gets free and total device memory
+ void queryMemory(size_t& totalMemory, size_t& freeMemory) const;
+ size_t freeMemory() const;
+ size_t totalMemory() const;
+
+ /** @brief Provides information on CUDA feature support.
+
+ @param feature_set Features to be checked. See cuda::FeatureSet.
+
+ This function returns true if the device has the specified CUDA feature. Otherwise, it returns false
+ */
+ bool supports(FeatureSet feature_set) const;
+
+ /** @brief Checks the CUDA module and device compatibility.
+
+ This function returns true if the CUDA module can be run on the specified device. Otherwise, it
+ returns false .
+ */
+ bool isCompatible() const;
+
+private:
+ int device_id_;
+};
+
+CV_EXPORTS void printCudaDeviceInfo(int device);
+CV_EXPORTS void printShortCudaDeviceInfo(int device);
+
+/** @brief Converts an array to half precision floating number.
+
+@param _src input array.
+@param _dst output array.
+@param stream Stream for the asynchronous version.
+@sa convertFp16
+*/
+CV_EXPORTS void convertFp16(InputArray _src, OutputArray _dst, Stream& stream = Stream::Null());
+
+//! @} cudacore_init
+
+}} // namespace cv { namespace cuda {
+
+
+#include "opencv2/core/cuda.inl.hpp"
+
+#endif /* OPENCV_CORE_CUDA_HPP */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/core/cuda.inl.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,631 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_CORE_CUDAINL_HPP
+#define OPENCV_CORE_CUDAINL_HPP
+
+#include "opencv2/core/cuda.hpp"
+
+//! @cond IGNORED
+
+namespace cv { namespace cuda {
+
+//===================================================================================
+// GpuMat
+//===================================================================================
+
+inline
+GpuMat::GpuMat(Allocator* allocator_)
+ : flags(0), rows(0), cols(0), step(0), data(0), refcount(0), datastart(0), dataend(0), allocator(allocator_)
+{}
+
+inline
+GpuMat::GpuMat(int rows_, int cols_, int type_, Allocator* allocator_)
+ : flags(0), rows(0), cols(0), step(0), data(0), refcount(0), datastart(0), dataend(0), allocator(allocator_)
+{
+ if (rows_ > 0 && cols_ > 0)
+ create(rows_, cols_, type_);
+}
+
+inline
+GpuMat::GpuMat(Size size_, int type_, Allocator* allocator_)
+ : flags(0), rows(0), cols(0), step(0), data(0), refcount(0), datastart(0), dataend(0), allocator(allocator_)
+{
+ if (size_.height > 0 && size_.width > 0)
+ create(size_.height, size_.width, type_);
+}
+
+inline
+GpuMat::GpuMat(int rows_, int cols_, int type_, Scalar s_, Allocator* allocator_)
+ : flags(0), rows(0), cols(0), step(0), data(0), refcount(0), datastart(0), dataend(0), allocator(allocator_)
+{
+ if (rows_ > 0 && cols_ > 0)
+ {
+ create(rows_, cols_, type_);
+ setTo(s_);
+ }
+}
+
+inline
+GpuMat::GpuMat(Size size_, int type_, Scalar s_, Allocator* allocator_)
+ : flags(0), rows(0), cols(0), step(0), data(0), refcount(0), datastart(0), dataend(0), allocator(allocator_)
+{
+ if (size_.height > 0 && size_.width > 0)
+ {
+ create(size_.height, size_.width, type_);
+ setTo(s_);
+ }
+}
+
+inline
+GpuMat::GpuMat(const GpuMat& m)
+ : flags(m.flags), rows(m.rows), cols(m.cols), step(m.step), data(m.data), refcount(m.refcount), datastart(m.datastart), dataend(m.dataend), allocator(m.allocator)
+{
+ if (refcount)
+ CV_XADD(refcount, 1);
+}
+
+inline
+GpuMat::GpuMat(InputArray arr, Allocator* allocator_) :
+ flags(0), rows(0), cols(0), step(0), data(0), refcount(0), datastart(0), dataend(0), allocator(allocator_)
+{
+ upload(arr);
+}
+
+inline
+GpuMat::~GpuMat()
+{
+ release();
+}
+
+inline
+GpuMat& GpuMat::operator =(const GpuMat& m)
+{
+ if (this != &m)
+ {
+ GpuMat temp(m);
+ swap(temp);
+ }
+
+ return *this;
+}
+
+inline
+void GpuMat::create(Size size_, int type_)
+{
+ create(size_.height, size_.width, type_);
+}
+
+inline
+void GpuMat::swap(GpuMat& b)
+{
+ std::swap(flags, b.flags);
+ std::swap(rows, b.rows);
+ std::swap(cols, b.cols);
+ std::swap(step, b.step);
+ std::swap(data, b.data);
+ std::swap(datastart, b.datastart);
+ std::swap(dataend, b.dataend);
+ std::swap(refcount, b.refcount);
+ std::swap(allocator, b.allocator);
+}
+
+inline
+GpuMat GpuMat::clone() const
+{
+ GpuMat m;
+ copyTo(m);
+ return m;
+}
+
+inline
+void GpuMat::copyTo(OutputArray dst, InputArray mask) const
+{
+ copyTo(dst, mask, Stream::Null());
+}
+
+inline
+GpuMat& GpuMat::setTo(Scalar s)
+{
+ return setTo(s, Stream::Null());
+}
+
+inline
+GpuMat& GpuMat::setTo(Scalar s, InputArray mask)
+{
+ return setTo(s, mask, Stream::Null());
+}
+
+inline
+void GpuMat::convertTo(OutputArray dst, int rtype) const
+{
+ convertTo(dst, rtype, Stream::Null());
+}
+
+inline
+void GpuMat::convertTo(OutputArray dst, int rtype, double alpha, double beta) const
+{
+ convertTo(dst, rtype, alpha, beta, Stream::Null());
+}
+
+inline
+void GpuMat::convertTo(OutputArray dst, int rtype, double alpha, Stream& stream) const
+{
+ convertTo(dst, rtype, alpha, 0.0, stream);
+}
+
+inline
+void GpuMat::assignTo(GpuMat& m, int _type) const
+{
+ if (_type < 0)
+ m = *this;
+ else
+ convertTo(m, _type);
+}
+
+inline
+uchar* GpuMat::ptr(int y)
+{
+ CV_DbgAssert( (unsigned)y < (unsigned)rows );
+ return data + step * y;
+}
+
+inline
+const uchar* GpuMat::ptr(int y) const
+{
+ CV_DbgAssert( (unsigned)y < (unsigned)rows );
+ return data + step * y;
+}
+
+template<typename _Tp> inline
+_Tp* GpuMat::ptr(int y)
+{
+ return (_Tp*)ptr(y);
+}
+
+template<typename _Tp> inline
+const _Tp* GpuMat::ptr(int y) const
+{
+ return (const _Tp*)ptr(y);
+}
+
+template <class T> inline
+GpuMat::operator PtrStepSz<T>() const
+{
+ return PtrStepSz<T>(rows, cols, (T*)data, step);
+}
+
+template <class T> inline
+GpuMat::operator PtrStep<T>() const
+{
+ return PtrStep<T>((T*)data, step);
+}
+
+inline
+GpuMat GpuMat::row(int y) const
+{
+ return GpuMat(*this, Range(y, y+1), Range::all());
+}
+
+inline
+GpuMat GpuMat::col(int x) const
+{
+ return GpuMat(*this, Range::all(), Range(x, x+1));
+}
+
+inline
+GpuMat GpuMat::rowRange(int startrow, int endrow) const
+{
+ return GpuMat(*this, Range(startrow, endrow), Range::all());
+}
+
+inline
+GpuMat GpuMat::rowRange(Range r) const
+{
+ return GpuMat(*this, r, Range::all());
+}
+
+inline
+GpuMat GpuMat::colRange(int startcol, int endcol) const
+{
+ return GpuMat(*this, Range::all(), Range(startcol, endcol));
+}
+
+inline
+GpuMat GpuMat::colRange(Range r) const
+{
+ return GpuMat(*this, Range::all(), r);
+}
+
+inline
+GpuMat GpuMat::operator ()(Range rowRange_, Range colRange_) const
+{
+ return GpuMat(*this, rowRange_, colRange_);
+}
+
+inline
+GpuMat GpuMat::operator ()(Rect roi) const
+{
+ return GpuMat(*this, roi);
+}
+
+inline
+bool GpuMat::isContinuous() const
+{
+ return (flags & Mat::CONTINUOUS_FLAG) != 0;
+}
+
+inline
+size_t GpuMat::elemSize() const
+{
+ return CV_ELEM_SIZE(flags);
+}
+
+inline
+size_t GpuMat::elemSize1() const
+{
+ return CV_ELEM_SIZE1(flags);
+}
+
+inline
+int GpuMat::type() const
+{
+ return CV_MAT_TYPE(flags);
+}
+
+inline
+int GpuMat::depth() const
+{
+ return CV_MAT_DEPTH(flags);
+}
+
+inline
+int GpuMat::channels() const
+{
+ return CV_MAT_CN(flags);
+}
+
+inline
+size_t GpuMat::step1() const
+{
+ return step / elemSize1();
+}
+
+inline
+Size GpuMat::size() const
+{
+ return Size(cols, rows);
+}
+
+inline
+bool GpuMat::empty() const
+{
+ return data == 0;
+}
+
+static inline
+GpuMat createContinuous(int rows, int cols, int type)
+{
+ GpuMat m;
+ createContinuous(rows, cols, type, m);
+ return m;
+}
+
+static inline
+void createContinuous(Size size, int type, OutputArray arr)
+{
+ createContinuous(size.height, size.width, type, arr);
+}
+
+static inline
+GpuMat createContinuous(Size size, int type)
+{
+ GpuMat m;
+ createContinuous(size, type, m);
+ return m;
+}
+
+static inline
+void ensureSizeIsEnough(Size size, int type, OutputArray arr)
+{
+ ensureSizeIsEnough(size.height, size.width, type, arr);
+}
+
+static inline
+void swap(GpuMat& a, GpuMat& b)
+{
+ a.swap(b);
+}
+
+//===================================================================================
+// HostMem
+//===================================================================================
+
+inline
+HostMem::HostMem(AllocType alloc_type_)
+ : flags(0), rows(0), cols(0), step(0), data(0), refcount(0), datastart(0), dataend(0), alloc_type(alloc_type_)
+{
+}
+
+inline
+HostMem::HostMem(const HostMem& m)
+ : flags(m.flags), rows(m.rows), cols(m.cols), step(m.step), data(m.data), refcount(m.refcount), datastart(m.datastart), dataend(m.dataend), alloc_type(m.alloc_type)
+{
+ if( refcount )
+ CV_XADD(refcount, 1);
+}
+
+inline
+HostMem::HostMem(int rows_, int cols_, int type_, AllocType alloc_type_)
+ : flags(0), rows(0), cols(0), step(0), data(0), refcount(0), datastart(0), dataend(0), alloc_type(alloc_type_)
+{
+ if (rows_ > 0 && cols_ > 0)
+ create(rows_, cols_, type_);
+}
+
+inline
+HostMem::HostMem(Size size_, int type_, AllocType alloc_type_)
+ : flags(0), rows(0), cols(0), step(0), data(0), refcount(0), datastart(0), dataend(0), alloc_type(alloc_type_)
+{
+ if (size_.height > 0 && size_.width > 0)
+ create(size_.height, size_.width, type_);
+}
+
+inline
+HostMem::HostMem(InputArray arr, AllocType alloc_type_)
+ : flags(0), rows(0), cols(0), step(0), data(0), refcount(0), datastart(0), dataend(0), alloc_type(alloc_type_)
+{
+ arr.getMat().copyTo(*this);
+}
+
+inline
+HostMem::~HostMem()
+{
+ release();
+}
+
+inline
+HostMem& HostMem::operator =(const HostMem& m)
+{
+ if (this != &m)
+ {
+ HostMem temp(m);
+ swap(temp);
+ }
+
+ return *this;
+}
+
+inline
+void HostMem::swap(HostMem& b)
+{
+ std::swap(flags, b.flags);
+ std::swap(rows, b.rows);
+ std::swap(cols, b.cols);
+ std::swap(step, b.step);
+ std::swap(data, b.data);
+ std::swap(datastart, b.datastart);
+ std::swap(dataend, b.dataend);
+ std::swap(refcount, b.refcount);
+ std::swap(alloc_type, b.alloc_type);
+}
+
+inline
+HostMem HostMem::clone() const
+{
+ HostMem m(size(), type(), alloc_type);
+ createMatHeader().copyTo(m);
+ return m;
+}
+
+inline
+void HostMem::create(Size size_, int type_)
+{
+ create(size_.height, size_.width, type_);
+}
+
+inline
+Mat HostMem::createMatHeader() const
+{
+ return Mat(size(), type(), data, step);
+}
+
+inline
+bool HostMem::isContinuous() const
+{
+ return (flags & Mat::CONTINUOUS_FLAG) != 0;
+}
+
+inline
+size_t HostMem::elemSize() const
+{
+ return CV_ELEM_SIZE(flags);
+}
+
+inline
+size_t HostMem::elemSize1() const
+{
+ return CV_ELEM_SIZE1(flags);
+}
+
+inline
+int HostMem::type() const
+{
+ return CV_MAT_TYPE(flags);
+}
+
+inline
+int HostMem::depth() const
+{
+ return CV_MAT_DEPTH(flags);
+}
+
+inline
+int HostMem::channels() const
+{
+ return CV_MAT_CN(flags);
+}
+
+inline
+size_t HostMem::step1() const
+{
+ return step / elemSize1();
+}
+
+inline
+Size HostMem::size() const
+{
+ return Size(cols, rows);
+}
+
+inline
+bool HostMem::empty() const
+{
+ return data == 0;
+}
+
+static inline
+void swap(HostMem& a, HostMem& b)
+{
+ a.swap(b);
+}
+
+//===================================================================================
+// Stream
+//===================================================================================
+
+inline
+Stream::Stream(const Ptr<Impl>& impl)
+ : impl_(impl)
+{
+}
+
+//===================================================================================
+// Event
+//===================================================================================
+
+inline
+Event::Event(const Ptr<Impl>& impl)
+ : impl_(impl)
+{
+}
+
+//===================================================================================
+// Initialization & Info
+//===================================================================================
+
+inline
+bool TargetArchs::has(int major, int minor)
+{
+ return hasPtx(major, minor) || hasBin(major, minor);
+}
+
+inline
+bool TargetArchs::hasEqualOrGreater(int major, int minor)
+{
+ return hasEqualOrGreaterPtx(major, minor) || hasEqualOrGreaterBin(major, minor);
+}
+
+inline
+DeviceInfo::DeviceInfo()
+{
+ device_id_ = getDevice();
+}
+
+inline
+DeviceInfo::DeviceInfo(int device_id)
+{
+ CV_Assert( device_id >= 0 && device_id < getCudaEnabledDeviceCount() );
+ device_id_ = device_id;
+}
+
+inline
+int DeviceInfo::deviceID() const
+{
+ return device_id_;
+}
+
+inline
+size_t DeviceInfo::freeMemory() const
+{
+ size_t _totalMemory = 0, _freeMemory = 0;
+ queryMemory(_totalMemory, _freeMemory);
+ return _freeMemory;
+}
+
+inline
+size_t DeviceInfo::totalMemory() const
+{
+ size_t _totalMemory = 0, _freeMemory = 0;
+ queryMemory(_totalMemory, _freeMemory);
+ return _totalMemory;
+}
+
+inline
+bool DeviceInfo::supports(FeatureSet feature_set) const
+{
+ int version = majorVersion() * 10 + minorVersion();
+ return version >= feature_set;
+}
+
+
+}} // namespace cv { namespace cuda {
+
+//===================================================================================
+// Mat
+//===================================================================================
+
+namespace cv {
+
+inline
+Mat::Mat(const cuda::GpuMat& m)
+ : flags(0), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0), datalimit(0), allocator(0), u(0), size(&rows)
+{
+ m.download(*this);
+}
+
+}
+
+//! @endcond
+
+#endif // OPENCV_CORE_CUDAINL_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/core/cuda_stream_accessor.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,86 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_CORE_CUDA_STREAM_ACCESSOR_HPP
+#define OPENCV_CORE_CUDA_STREAM_ACCESSOR_HPP
+
+#ifndef __cplusplus
+# error cuda_stream_accessor.hpp header must be compiled as C++
+#endif
+
+/** @file cuda_stream_accessor.hpp
+ * This is only header file that depends on CUDA Runtime API. All other headers are independent.
+ */
+
+#include <cuda_runtime.h>
+#include "opencv2/core/cuda.hpp"
+
+namespace cv
+{
+ namespace cuda
+ {
+
+//! @addtogroup cudacore_struct
+//! @{
+
+ /** @brief Class that enables getting cudaStream_t from cuda::Stream
+ */
+ struct StreamAccessor
+ {
+ CV_EXPORTS static cudaStream_t getStream(const Stream& stream);
+ CV_EXPORTS static Stream wrapStream(cudaStream_t stream);
+ };
+
+ /** @brief Class that enables getting cudaEvent_t from cuda::Event
+ */
+ struct EventAccessor
+ {
+ CV_EXPORTS static cudaEvent_t getEvent(const Event& event);
+ CV_EXPORTS static Event wrapEvent(cudaEvent_t event);
+ };
+
+//! @}
+
+ }
+}
+
+#endif /* OPENCV_CORE_CUDA_STREAM_ACCESSOR_HPP */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/core/cuda_types.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,135 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_CORE_CUDA_TYPES_HPP
+#define OPENCV_CORE_CUDA_TYPES_HPP
+
+#ifndef __cplusplus
+# error cuda_types.hpp header must be compiled as C++
+#endif
+
+/** @file
+ * @deprecated Use @ref cudev instead.
+ */
+
+//! @cond IGNORED
+
+#ifdef __CUDACC__
+ #define __CV_CUDA_HOST_DEVICE__ __host__ __device__ __forceinline__
+#else
+ #define __CV_CUDA_HOST_DEVICE__
+#endif
+
+namespace cv
+{
+ namespace cuda
+ {
+
+ // Simple lightweight structures that encapsulates information about an image on device.
+ // It is intended to pass to nvcc-compiled code. GpuMat depends on headers that nvcc can't compile
+
+ template <typename T> struct DevPtr
+ {
+ typedef T elem_type;
+ typedef int index_type;
+
+ enum { elem_size = sizeof(elem_type) };
+
+ T* data;
+
+ __CV_CUDA_HOST_DEVICE__ DevPtr() : data(0) {}
+ __CV_CUDA_HOST_DEVICE__ DevPtr(T* data_) : data(data_) {}
+
+ __CV_CUDA_HOST_DEVICE__ size_t elemSize() const { return elem_size; }
+ __CV_CUDA_HOST_DEVICE__ operator T*() { return data; }
+ __CV_CUDA_HOST_DEVICE__ operator const T*() const { return data; }
+ };
+
+ template <typename T> struct PtrSz : public DevPtr<T>
+ {
+ __CV_CUDA_HOST_DEVICE__ PtrSz() : size(0) {}
+ __CV_CUDA_HOST_DEVICE__ PtrSz(T* data_, size_t size_) : DevPtr<T>(data_), size(size_) {}
+
+ size_t size;
+ };
+
+ template <typename T> struct PtrStep : public DevPtr<T>
+ {
+ __CV_CUDA_HOST_DEVICE__ PtrStep() : step(0) {}
+ __CV_CUDA_HOST_DEVICE__ PtrStep(T* data_, size_t step_) : DevPtr<T>(data_), step(step_) {}
+
+ size_t step;
+
+ __CV_CUDA_HOST_DEVICE__ T* ptr(int y = 0) { return ( T*)( ( char*)DevPtr<T>::data + y * step); }
+ __CV_CUDA_HOST_DEVICE__ const T* ptr(int y = 0) const { return (const T*)( (const char*)DevPtr<T>::data + y * step); }
+
+ __CV_CUDA_HOST_DEVICE__ T& operator ()(int y, int x) { return ptr(y)[x]; }
+ __CV_CUDA_HOST_DEVICE__ const T& operator ()(int y, int x) const { return ptr(y)[x]; }
+ };
+
+ template <typename T> struct PtrStepSz : public PtrStep<T>
+ {
+ __CV_CUDA_HOST_DEVICE__ PtrStepSz() : cols(0), rows(0) {}
+ __CV_CUDA_HOST_DEVICE__ PtrStepSz(int rows_, int cols_, T* data_, size_t step_)
+ : PtrStep<T>(data_, step_), cols(cols_), rows(rows_) {}
+
+ template <typename U>
+ explicit PtrStepSz(const PtrStepSz<U>& d) : PtrStep<T>((T*)d.data, d.step), cols(d.cols), rows(d.rows){}
+
+ int cols;
+ int rows;
+ };
+
+ typedef PtrStepSz<unsigned char> PtrStepSzb;
+ typedef PtrStepSz<float> PtrStepSzf;
+ typedef PtrStepSz<int> PtrStepSzi;
+
+ typedef PtrStep<unsigned char> PtrStepb;
+ typedef PtrStep<float> PtrStepf;
+ typedef PtrStep<int> PtrStepi;
+
+ }
+}
+
+//! @endcond
+
+#endif /* OPENCV_CORE_CUDA_TYPES_HPP */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/core/cvdef.h Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,481 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
+// Copyright (C) 2015, Itseez Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_CORE_CVDEF_H
+#define OPENCV_CORE_CVDEF_H
+
+//! @addtogroup core_utils
+//! @{
+
+#if !defined _CRT_SECURE_NO_DEPRECATE && defined _MSC_VER && _MSC_VER > 1300
+# define _CRT_SECURE_NO_DEPRECATE /* to avoid multiple Visual Studio warnings */
+#endif
+
+// undef problematic defines sometimes defined by system headers (windows.h in particular)
+#undef small
+#undef min
+#undef max
+#undef abs
+#undef Complex
+
+#if !defined _CRT_SECURE_NO_DEPRECATE && defined _MSC_VER && _MSC_VER > 1300
+# define _CRT_SECURE_NO_DEPRECATE /* to avoid multiple Visual Studio warnings */
+#endif
+
+#include <limits.h>
+#include "opencv2/core/hal/interface.h"
+
+#if defined __ICL
+# define CV_ICC __ICL
+#elif defined __ICC
+# define CV_ICC __ICC
+#elif defined __ECL
+# define CV_ICC __ECL
+#elif defined __ECC
+# define CV_ICC __ECC
+#elif defined __INTEL_COMPILER
+# define CV_ICC __INTEL_COMPILER
+#endif
+
+#ifndef CV_INLINE
+# if defined __cplusplus
+# define CV_INLINE static inline
+# elif defined _MSC_VER
+# define CV_INLINE __inline
+# else
+# define CV_INLINE static
+# endif
+#endif
+
+#if defined CV_ICC && !defined CV_ENABLE_UNROLLED
+# define CV_ENABLE_UNROLLED 0
+#else
+# define CV_ENABLE_UNROLLED 1
+#endif
+
+#ifdef __GNUC__
+# define CV_DECL_ALIGNED(x) __attribute__ ((aligned (x)))
+#elif defined _MSC_VER
+# define CV_DECL_ALIGNED(x) __declspec(align(x))
+#else
+# define CV_DECL_ALIGNED(x)
+#endif
+
+/* CPU features and intrinsics support */
+#define CV_CPU_NONE 0
+#define CV_CPU_MMX 1
+#define CV_CPU_SSE 2
+#define CV_CPU_SSE2 3
+#define CV_CPU_SSE3 4
+#define CV_CPU_SSSE3 5
+#define CV_CPU_SSE4_1 6
+#define CV_CPU_SSE4_2 7
+#define CV_CPU_POPCNT 8
+#define CV_CPU_FP16 9
+#define CV_CPU_AVX 10
+#define CV_CPU_AVX2 11
+#define CV_CPU_FMA3 12
+
+#define CV_CPU_AVX_512F 13
+#define CV_CPU_AVX_512BW 14
+#define CV_CPU_AVX_512CD 15
+#define CV_CPU_AVX_512DQ 16
+#define CV_CPU_AVX_512ER 17
+#define CV_CPU_AVX_512IFMA512 18
+#define CV_CPU_AVX_512PF 19
+#define CV_CPU_AVX_512VBMI 20
+#define CV_CPU_AVX_512VL 21
+
+#define CV_CPU_NEON 100
+
+// when adding to this list remember to update the following enum
+#define CV_HARDWARE_MAX_FEATURE 255
+
+/** @brief Available CPU features.
+*/
+enum CpuFeatures {
+ CPU_MMX = 1,
+ CPU_SSE = 2,
+ CPU_SSE2 = 3,
+ CPU_SSE3 = 4,
+ CPU_SSSE3 = 5,
+ CPU_SSE4_1 = 6,
+ CPU_SSE4_2 = 7,
+ CPU_POPCNT = 8,
+ CPU_FP16 = 9,
+ CPU_AVX = 10,
+ CPU_AVX2 = 11,
+ CPU_FMA3 = 12,
+
+ CPU_AVX_512F = 13,
+ CPU_AVX_512BW = 14,
+ CPU_AVX_512CD = 15,
+ CPU_AVX_512DQ = 16,
+ CPU_AVX_512ER = 17,
+ CPU_AVX_512IFMA512 = 18,
+ CPU_AVX_512PF = 19,
+ CPU_AVX_512VBMI = 20,
+ CPU_AVX_512VL = 21,
+
+ CPU_NEON = 100
+};
+
+// do not include SSE/AVX/NEON headers for NVCC compiler
+#ifndef __CUDACC__
+
+#if defined __SSE2__ || defined _M_X64 || (defined _M_IX86_FP && _M_IX86_FP >= 2)
+# include <emmintrin.h>
+# define CV_MMX 1
+# define CV_SSE 1
+# define CV_SSE2 1
+# if defined __SSE3__ || (defined _MSC_VER && _MSC_VER >= 1500)
+# include <pmmintrin.h>
+# define CV_SSE3 1
+# endif
+# if defined __SSSE3__ || (defined _MSC_VER && _MSC_VER >= 1500)
+# include <tmmintrin.h>
+# define CV_SSSE3 1
+# endif
+# if defined __SSE4_1__ || (defined _MSC_VER && _MSC_VER >= 1500)
+# include <smmintrin.h>
+# define CV_SSE4_1 1
+# endif
+# if defined __SSE4_2__ || (defined _MSC_VER && _MSC_VER >= 1500)
+# include <nmmintrin.h>
+# define CV_SSE4_2 1
+# endif
+# if defined __POPCNT__ || (defined _MSC_VER && _MSC_VER >= 1500)
+# ifdef _MSC_VER
+# include <nmmintrin.h>
+# else
+# include <popcntintrin.h>
+# endif
+# define CV_POPCNT 1
+# endif
+# if defined __AVX__ || (defined _MSC_VER && _MSC_VER >= 1600 && 0)
+// MS Visual Studio 2010 (2012?) has no macro pre-defined to identify the use of /arch:AVX
+// See: http://connect.microsoft.com/VisualStudio/feedback/details/605858/arch-avx-should-define-a-predefined-macro-in-x64-and-set-a-unique-value-for-m-ix86-fp-in-win32
+# include <immintrin.h>
+# define CV_AVX 1
+# if defined(_XCR_XFEATURE_ENABLED_MASK)
+# define __xgetbv() _xgetbv(_XCR_XFEATURE_ENABLED_MASK)
+# else
+# define __xgetbv() 0
+# endif
+# endif
+# if defined __AVX2__ || (defined _MSC_VER && _MSC_VER >= 1800 && 0)
+# include <immintrin.h>
+# define CV_AVX2 1
+# if defined __FMA__
+# define CV_FMA3 1
+# endif
+# endif
+#endif
+
+#if (defined WIN32 || defined _WIN32) && defined(_M_ARM)
+# include <Intrin.h>
+# include <arm_neon.h>
+# define CV_NEON 1
+# define CPU_HAS_NEON_FEATURE (true)
+#elif defined(__ARM_NEON__) || (defined (__ARM_NEON) && defined(__aarch64__))
+# include <arm_neon.h>
+# define CV_NEON 1
+#endif
+
+#if defined __GNUC__ && defined __arm__ && (defined __ARM_PCS_VFP || defined __ARM_VFPV3__ || defined __ARM_NEON__) && !defined __SOFTFP__
+# define CV_VFP 1
+#endif
+
+#endif // __CUDACC__
+
+#ifndef CV_POPCNT
+#define CV_POPCNT 0
+#endif
+#ifndef CV_MMX
+# define CV_MMX 0
+#endif
+#ifndef CV_SSE
+# define CV_SSE 0
+#endif
+#ifndef CV_SSE2
+# define CV_SSE2 0
+#endif
+#ifndef CV_SSE3
+# define CV_SSE3 0
+#endif
+#ifndef CV_SSSE3
+# define CV_SSSE3 0
+#endif
+#ifndef CV_SSE4_1
+# define CV_SSE4_1 0
+#endif
+#ifndef CV_SSE4_2
+# define CV_SSE4_2 0
+#endif
+#ifndef CV_AVX
+# define CV_AVX 0
+#endif
+#ifndef CV_AVX2
+# define CV_AVX2 0
+#endif
+#ifndef CV_FMA3
+# define CV_FMA3 0
+#endif
+#ifndef CV_AVX_512F
+# define CV_AVX_512F 0
+#endif
+#ifndef CV_AVX_512BW
+# define CV_AVX_512BW 0
+#endif
+#ifndef CV_AVX_512CD
+# define CV_AVX_512CD 0
+#endif
+#ifndef CV_AVX_512DQ
+# define CV_AVX_512DQ 0
+#endif
+#ifndef CV_AVX_512ER
+# define CV_AVX_512ER 0
+#endif
+#ifndef CV_AVX_512IFMA512
+# define CV_AVX_512IFMA512 0
+#endif
+#ifndef CV_AVX_512PF
+# define CV_AVX_512PF 0
+#endif
+#ifndef CV_AVX_512VBMI
+# define CV_AVX_512VBMI 0
+#endif
+#ifndef CV_AVX_512VL
+# define CV_AVX_512VL 0
+#endif
+
+#ifndef CV_NEON
+# define CV_NEON 0
+#endif
+
+#ifndef CV_VFP
+# define CV_VFP 0
+#endif
+
+/* fundamental constants */
+#define CV_PI 3.1415926535897932384626433832795
+#define CV_2PI 6.283185307179586476925286766559
+#define CV_LOG2 0.69314718055994530941723212145818
+
+#if defined __ARM_FP16_FORMAT_IEEE \
+ && !defined __CUDACC__
+# define CV_FP16_TYPE 1
+#else
+# define CV_FP16_TYPE 0
+#endif
+
+typedef union Cv16suf
+{
+ short i;
+#if CV_FP16_TYPE
+ __fp16 h;
+#endif
+ struct _fp16Format
+ {
+ unsigned int significand : 10;
+ unsigned int exponent : 5;
+ unsigned int sign : 1;
+ } fmt;
+}
+Cv16suf;
+
+typedef union Cv32suf
+{
+ int i;
+ unsigned u;
+ float f;
+ struct _fp32Format
+ {
+ unsigned int significand : 23;
+ unsigned int exponent : 8;
+ unsigned int sign : 1;
+ } fmt;
+}
+Cv32suf;
+
+typedef union Cv64suf
+{
+ int64 i;
+ uint64 u;
+ double f;
+}
+Cv64suf;
+
+#define OPENCV_ABI_COMPATIBILITY 300
+
+#ifdef __OPENCV_BUILD
+# define DISABLE_OPENCV_24_COMPATIBILITY
+#endif
+
+#if (defined WIN32 || defined _WIN32 || defined WINCE || defined __CYGWIN__) && defined CVAPI_EXPORTS
+# define CV_EXPORTS __declspec(dllexport)
+#elif defined __GNUC__ && __GNUC__ >= 4
+# define CV_EXPORTS __attribute__ ((visibility ("default")))
+#else
+# define CV_EXPORTS
+#endif
+
+#ifndef CV_EXTERN_C
+# ifdef __cplusplus
+# define CV_EXTERN_C extern "C"
+# else
+# define CV_EXTERN_C
+# endif
+#endif
+
+/* special informative macros for wrapper generators */
+#define CV_EXPORTS_W CV_EXPORTS
+#define CV_EXPORTS_W_SIMPLE CV_EXPORTS
+#define CV_EXPORTS_AS(synonym) CV_EXPORTS
+#define CV_EXPORTS_W_MAP CV_EXPORTS
+#define CV_IN_OUT
+#define CV_OUT
+#define CV_PROP
+#define CV_PROP_RW
+#define CV_WRAP
+#define CV_WRAP_AS(synonym)
+
+/****************************************************************************************\
+* Matrix type (Mat) *
+\****************************************************************************************/
+
+#define CV_MAT_CN_MASK ((CV_CN_MAX - 1) << CV_CN_SHIFT)
+#define CV_MAT_CN(flags) ((((flags) & CV_MAT_CN_MASK) >> CV_CN_SHIFT) + 1)
+#define CV_MAT_TYPE_MASK (CV_DEPTH_MAX*CV_CN_MAX - 1)
+#define CV_MAT_TYPE(flags) ((flags) & CV_MAT_TYPE_MASK)
+#define CV_MAT_CONT_FLAG_SHIFT 14
+#define CV_MAT_CONT_FLAG (1 << CV_MAT_CONT_FLAG_SHIFT)
+#define CV_IS_MAT_CONT(flags) ((flags) & CV_MAT_CONT_FLAG)
+#define CV_IS_CONT_MAT CV_IS_MAT_CONT
+#define CV_SUBMAT_FLAG_SHIFT 15
+#define CV_SUBMAT_FLAG (1 << CV_SUBMAT_FLAG_SHIFT)
+#define CV_IS_SUBMAT(flags) ((flags) & CV_MAT_SUBMAT_FLAG)
+
+/** Size of each channel item,
+ 0x124489 = 1000 0100 0100 0010 0010 0001 0001 ~ array of sizeof(arr_type_elem) */
+#define CV_ELEM_SIZE1(type) \
+ ((((sizeof(size_t)<<28)|0x8442211) >> CV_MAT_DEPTH(type)*4) & 15)
+
+/** 0x3a50 = 11 10 10 01 01 00 00 ~ array of log2(sizeof(arr_type_elem)) */
+#define CV_ELEM_SIZE(type) \
+ (CV_MAT_CN(type) << ((((sizeof(size_t)/4+1)*16384|0x3a50) >> CV_MAT_DEPTH(type)*2) & 3))
+
+#ifndef MIN
+# define MIN(a,b) ((a) > (b) ? (b) : (a))
+#endif
+
+#ifndef MAX
+# define MAX(a,b) ((a) < (b) ? (b) : (a))
+#endif
+
+/****************************************************************************************\
+* exchange-add operation for atomic operations on reference counters *
+\****************************************************************************************/
+
+#ifdef CV_XADD
+ // allow to use user-defined macro
+#elif defined __GNUC__
+# if defined __clang__ && __clang_major__ >= 3 && !defined __ANDROID__ && !defined __EMSCRIPTEN__ && !defined(__CUDACC__)
+# ifdef __ATOMIC_ACQ_REL
+# define CV_XADD(addr, delta) __c11_atomic_fetch_add((_Atomic(int)*)(addr), delta, __ATOMIC_ACQ_REL)
+# else
+# define CV_XADD(addr, delta) __atomic_fetch_add((_Atomic(int)*)(addr), delta, 4)
+# endif
+# else
+# if defined __ATOMIC_ACQ_REL && !defined __clang__
+ // version for gcc >= 4.7
+# define CV_XADD(addr, delta) (int)__atomic_fetch_add((unsigned*)(addr), (unsigned)(delta), __ATOMIC_ACQ_REL)
+# else
+# define CV_XADD(addr, delta) (int)__sync_fetch_and_add((unsigned*)(addr), (unsigned)(delta))
+# endif
+# endif
+#elif defined _MSC_VER && !defined RC_INVOKED
+# include <intrin.h>
+# define CV_XADD(addr, delta) (int)_InterlockedExchangeAdd((long volatile*)addr, delta)
+#else
+ CV_INLINE CV_XADD(int* addr, int delta) { int tmp = *addr; *addr += delta; return tmp; }
+#endif
+
+
+/****************************************************************************************\
+* CV_NORETURN attribute *
+\****************************************************************************************/
+
+#ifndef CV_NORETURN
+# if defined(__GNUC__)
+# define CV_NORETURN __attribute__((__noreturn__))
+# elif defined(_MSC_VER) && (_MSC_VER >= 1300)
+# define CV_NORETURN __declspec(noreturn)
+# else
+# define CV_NORETURN /* nothing by default */
+# endif
+#endif
+
+
+/****************************************************************************************\
+* C++ Move semantics *
+\****************************************************************************************/
+
+#ifndef CV_CXX_MOVE_SEMANTICS
+# if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) || defined(_MSC_VER) && _MSC_VER >= 1600
+# define CV_CXX_MOVE_SEMANTICS 1
+# elif defined(__clang)
+# if __has_feature(cxx_rvalue_references)
+# define CV_CXX_MOVE_SEMANTICS 1
+# endif
+# endif
+#else
+# if CV_CXX_MOVE_SEMANTICS == 0
+# undef CV_CXX_MOVE_SEMANTICS
+# endif
+#endif
+
+//! @}
+
+#endif // OPENCV_CORE_CVDEF_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/core/cvstd.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,1066 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_CORE_CVSTD_HPP
+#define OPENCV_CORE_CVSTD_HPP
+
+#ifndef __cplusplus
+# error cvstd.hpp header must be compiled as C++
+#endif
+
+#include "opencv2/core/cvdef.h"
+
+#include <cstddef>
+#include <cstring>
+#include <cctype>
+
+#ifndef OPENCV_NOSTL
+# include <string>
+#endif
+
+// import useful primitives from stl
+#ifndef OPENCV_NOSTL_TRANSITIONAL
+# include <algorithm>
+# include <utility>
+# include <cstdlib> //for abs(int)
+# include <cmath>
+
+namespace cv
+{
+ static inline uchar abs(uchar a) { return a; }
+ static inline ushort abs(ushort a) { return a; }
+ static inline unsigned abs(unsigned a) { return a; }
+ static inline uint64 abs(uint64 a) { return a; }
+
+ using std::min;
+ using std::max;
+ using std::abs;
+ using std::swap;
+ using std::sqrt;
+ using std::exp;
+ using std::pow;
+ using std::log;
+}
+
+#else
+namespace cv
+{
+ template<typename T> static inline T min(T a, T b) { return a < b ? a : b; }
+ template<typename T> static inline T max(T a, T b) { return a > b ? a : b; }
+ template<typename T> static inline T abs(T a) { return a < 0 ? -a : a; }
+ template<typename T> static inline void swap(T& a, T& b) { T tmp = a; a = b; b = tmp; }
+
+ template<> inline uchar abs(uchar a) { return a; }
+ template<> inline ushort abs(ushort a) { return a; }
+ template<> inline unsigned abs(unsigned a) { return a; }
+ template<> inline uint64 abs(uint64 a) { return a; }
+}
+#endif
+
+namespace cv {
+
+//! @addtogroup core_utils
+//! @{
+
+//////////////////////////// memory management functions ////////////////////////////
+
+/** @brief Allocates an aligned memory buffer.
+
+The function allocates the buffer of the specified size and returns it. When the buffer size is 16
+bytes or more, the returned buffer is aligned to 16 bytes.
+@param bufSize Allocated buffer size.
+ */
+CV_EXPORTS void* fastMalloc(size_t bufSize);
+
+/** @brief Deallocates a memory buffer.
+
+The function deallocates the buffer allocated with fastMalloc . If NULL pointer is passed, the
+function does nothing. C version of the function clears the pointer *pptr* to avoid problems with
+double memory deallocation.
+@param ptr Pointer to the allocated buffer.
+ */
+CV_EXPORTS void fastFree(void* ptr);
+
+/*!
+ The STL-compilant memory Allocator based on cv::fastMalloc() and cv::fastFree()
+*/
+template<typename _Tp> class Allocator
+{
+public:
+ typedef _Tp value_type;
+ typedef value_type* pointer;
+ typedef const value_type* const_pointer;
+ typedef value_type& reference;
+ typedef const value_type& const_reference;
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+ template<typename U> class rebind { typedef Allocator<U> other; };
+
+ explicit Allocator() {}
+ ~Allocator() {}
+ explicit Allocator(Allocator const&) {}
+ template<typename U>
+ explicit Allocator(Allocator<U> const&) {}
+
+ // address
+ pointer address(reference r) { return &r; }
+ const_pointer address(const_reference r) { return &r; }
+
+ pointer allocate(size_type count, const void* =0) { return reinterpret_cast<pointer>(fastMalloc(count * sizeof (_Tp))); }
+ void deallocate(pointer p, size_type) { fastFree(p); }
+
+ void construct(pointer p, const _Tp& v) { new(static_cast<void*>(p)) _Tp(v); }
+ void destroy(pointer p) { p->~_Tp(); }
+
+ size_type max_size() const { return cv::max(static_cast<_Tp>(-1)/sizeof(_Tp), 1); }
+};
+
+//! @} core_utils
+
+//! @cond IGNORED
+
+namespace detail
+{
+
+// Metafunction to avoid taking a reference to void.
+template<typename T>
+struct RefOrVoid { typedef T& type; };
+
+template<>
+struct RefOrVoid<void>{ typedef void type; };
+
+template<>
+struct RefOrVoid<const void>{ typedef const void type; };
+
+template<>
+struct RefOrVoid<volatile void>{ typedef volatile void type; };
+
+template<>
+struct RefOrVoid<const volatile void>{ typedef const volatile void type; };
+
+// This class would be private to Ptr, if it didn't have to be a non-template.
+struct PtrOwner;
+
+}
+
+template<typename Y>
+struct DefaultDeleter
+{
+ void operator () (Y* p) const;
+};
+
+//! @endcond
+
+//! @addtogroup core_basic
+//! @{
+
+/** @brief Template class for smart pointers with shared ownership
+
+A Ptr\<T\> pretends to be a pointer to an object of type T. Unlike an ordinary pointer, however, the
+object will be automatically cleaned up once all Ptr instances pointing to it are destroyed.
+
+Ptr is similar to boost::shared_ptr that is part of the Boost library
+(<http://www.boost.org/doc/libs/release/libs/smart_ptr/shared_ptr.htm>) and std::shared_ptr from
+the [C++11](http://en.wikipedia.org/wiki/C++11) standard.
+
+This class provides the following advantages:
+- Default constructor, copy constructor, and assignment operator for an arbitrary C++ class or C
+ structure. For some objects, like files, windows, mutexes, sockets, and others, a copy
+ constructor or an assignment operator are difficult to define. For some other objects, like
+ complex classifiers in OpenCV, copy constructors are absent and not easy to implement. Finally,
+ some of complex OpenCV and your own data structures may be written in C. However, copy
+ constructors and default constructors can simplify programming a lot. Besides, they are often
+ required (for example, by STL containers). By using a Ptr to such an object instead of the
+ object itself, you automatically get all of the necessary constructors and the assignment
+ operator.
+- *O(1)* complexity of the above-mentioned operations. While some structures, like std::vector,
+ provide a copy constructor and an assignment operator, the operations may take a considerable
+ amount of time if the data structures are large. But if the structures are put into a Ptr, the
+ overhead is small and independent of the data size.
+- Automatic and customizable cleanup, even for C structures. See the example below with FILE\*.
+- Heterogeneous collections of objects. The standard STL and most other C++ and OpenCV containers
+ can store only objects of the same type and the same size. The classical solution to store
+ objects of different types in the same container is to store pointers to the base class (Base\*)
+ instead but then you lose the automatic memory management. Again, by using Ptr\<Base\> instead
+ of raw pointers, you can solve the problem.
+
+A Ptr is said to *own* a pointer - that is, for each Ptr there is a pointer that will be deleted
+once all Ptr instances that own it are destroyed. The owned pointer may be null, in which case
+nothing is deleted. Each Ptr also *stores* a pointer. The stored pointer is the pointer the Ptr
+pretends to be; that is, the one you get when you use Ptr::get or the conversion to T\*. It's
+usually the same as the owned pointer, but if you use casts or the general shared-ownership
+constructor, the two may diverge: the Ptr will still own the original pointer, but will itself point
+to something else.
+
+The owned pointer is treated as a black box. The only thing Ptr needs to know about it is how to
+delete it. This knowledge is encapsulated in the *deleter* - an auxiliary object that is associated
+with the owned pointer and shared between all Ptr instances that own it. The default deleter is an
+instance of DefaultDeleter, which uses the standard C++ delete operator; as such it will work with
+any pointer allocated with the standard new operator.
+
+However, if the pointer must be deleted in a different way, you must specify a custom deleter upon
+Ptr construction. A deleter is simply a callable object that accepts the pointer as its sole
+argument. For example, if you want to wrap FILE, you may do so as follows:
+@code
+ Ptr<FILE> f(fopen("myfile.txt", "w"), fclose);
+ if(!f) throw ...;
+ fprintf(f, ....);
+ ...
+ // the file will be closed automatically by f's destructor.
+@endcode
+Alternatively, if you want all pointers of a particular type to be deleted the same way, you can
+specialize DefaultDeleter<T>::operator() for that type, like this:
+@code
+ namespace cv {
+ template<> void DefaultDeleter<FILE>::operator ()(FILE * obj) const
+ {
+ fclose(obj);
+ }
+ }
+@endcode
+For convenience, the following types from the OpenCV C API already have such a specialization that
+calls the appropriate release function:
+- CvCapture
+- CvFileStorage
+- CvHaarClassifierCascade
+- CvMat
+- CvMatND
+- CvMemStorage
+- CvSparseMat
+- CvVideoWriter
+- IplImage
+@note The shared ownership mechanism is implemented with reference counting. As such, cyclic
+ownership (e.g. when object a contains a Ptr to object b, which contains a Ptr to object a) will
+lead to all involved objects never being cleaned up. Avoid such situations.
+@note It is safe to concurrently read (but not write) a Ptr instance from multiple threads and
+therefore it is normally safe to use it in multi-threaded applications. The same is true for Mat and
+other C++ OpenCV classes that use internal reference counts.
+*/
+template<typename T>
+struct Ptr
+{
+ /** Generic programming support. */
+ typedef T element_type;
+
+ /** The default constructor creates a null Ptr - one that owns and stores a null pointer.
+ */
+ Ptr();
+
+ /**
+ If p is null, these are equivalent to the default constructor.
+ Otherwise, these constructors assume ownership of p - that is, the created Ptr owns and stores p
+ and assumes it is the sole owner of it. Don't use them if p is already owned by another Ptr, or
+ else p will get deleted twice.
+ With the first constructor, DefaultDeleter\<Y\>() becomes the associated deleter (so p will
+ eventually be deleted with the standard delete operator). Y must be a complete type at the point
+ of invocation.
+ With the second constructor, d becomes the associated deleter.
+ Y\* must be convertible to T\*.
+ @param p Pointer to own.
+ @note It is often easier to use makePtr instead.
+ */
+ template<typename Y>
+#ifdef DISABLE_OPENCV_24_COMPATIBILITY
+ explicit
+#endif
+ Ptr(Y* p);
+
+ /** @overload
+ @param d Deleter to use for the owned pointer.
+ @param p Pointer to own.
+ */
+ template<typename Y, typename D>
+ Ptr(Y* p, D d);
+
+ /**
+ These constructors create a Ptr that shares ownership with another Ptr - that is, own the same
+ pointer as o.
+ With the first two, the same pointer is stored, as well; for the second, Y\* must be convertible
+ to T\*.
+ With the third, p is stored, and Y may be any type. This constructor allows to have completely
+ unrelated owned and stored pointers, and should be used with care to avoid confusion. A relatively
+ benign use is to create a non-owning Ptr, like this:
+ @code
+ ptr = Ptr<T>(Ptr<T>(), dont_delete_me); // owns nothing; will not delete the pointer.
+ @endcode
+ @param o Ptr to share ownership with.
+ */
+ Ptr(const Ptr& o);
+
+ /** @overload
+ @param o Ptr to share ownership with.
+ */
+ template<typename Y>
+ Ptr(const Ptr<Y>& o);
+
+ /** @overload
+ @param o Ptr to share ownership with.
+ @param p Pointer to store.
+ */
+ template<typename Y>
+ Ptr(const Ptr<Y>& o, T* p);
+
+ /** The destructor is equivalent to calling Ptr::release. */
+ ~Ptr();
+
+ /**
+ Assignment replaces the current Ptr instance with one that owns and stores same pointers as o and
+ then destroys the old instance.
+ @param o Ptr to share ownership with.
+ */
+ Ptr& operator = (const Ptr& o);
+
+ /** @overload */
+ template<typename Y>
+ Ptr& operator = (const Ptr<Y>& o);
+
+ /** If no other Ptr instance owns the owned pointer, deletes it with the associated deleter. Then sets
+ both the owned and the stored pointers to NULL.
+ */
+ void release();
+
+ /**
+ `ptr.reset(...)` is equivalent to `ptr = Ptr<T>(...)`.
+ @param p Pointer to own.
+ */
+ template<typename Y>
+ void reset(Y* p);
+
+ /** @overload
+ @param d Deleter to use for the owned pointer.
+ @param p Pointer to own.
+ */
+ template<typename Y, typename D>
+ void reset(Y* p, D d);
+
+ /**
+ Swaps the owned and stored pointers (and deleters, if any) of this and o.
+ @param o Ptr to swap with.
+ */
+ void swap(Ptr& o);
+
+ /** Returns the stored pointer. */
+ T* get() const;
+
+ /** Ordinary pointer emulation. */
+ typename detail::RefOrVoid<T>::type operator * () const;
+
+ /** Ordinary pointer emulation. */
+ T* operator -> () const;
+
+ /** Equivalent to get(). */
+ operator T* () const;
+
+ /** ptr.empty() is equivalent to `!ptr.get()`. */
+ bool empty() const;
+
+ /** Returns a Ptr that owns the same pointer as this, and stores the same
+ pointer as this, except converted via static_cast to Y*.
+ */
+ template<typename Y>
+ Ptr<Y> staticCast() const;
+
+ /** Ditto for const_cast. */
+ template<typename Y>
+ Ptr<Y> constCast() const;
+
+ /** Ditto for dynamic_cast. */
+ template<typename Y>
+ Ptr<Y> dynamicCast() const;
+
+#ifdef CV_CXX_MOVE_SEMANTICS
+ Ptr(Ptr&& o);
+ Ptr& operator = (Ptr&& o);
+#endif
+
+private:
+ detail::PtrOwner* owner;
+ T* stored;
+
+ template<typename Y>
+ friend struct Ptr; // have to do this for the cross-type copy constructor
+};
+
+/** Equivalent to ptr1.swap(ptr2). Provided to help write generic algorithms. */
+template<typename T>
+void swap(Ptr<T>& ptr1, Ptr<T>& ptr2);
+
+/** Return whether ptr1.get() and ptr2.get() are equal and not equal, respectively. */
+template<typename T>
+bool operator == (const Ptr<T>& ptr1, const Ptr<T>& ptr2);
+template<typename T>
+bool operator != (const Ptr<T>& ptr1, const Ptr<T>& ptr2);
+
+/** `makePtr<T>(...)` is equivalent to `Ptr<T>(new T(...))`. It is shorter than the latter, and it's
+marginally safer than using a constructor or Ptr::reset, since it ensures that the owned pointer
+is new and thus not owned by any other Ptr instance.
+Unfortunately, perfect forwarding is impossible to implement in C++03, and so makePtr is limited
+to constructors of T that have up to 10 arguments, none of which are non-const references.
+ */
+template<typename T>
+Ptr<T> makePtr();
+/** @overload */
+template<typename T, typename A1>
+Ptr<T> makePtr(const A1& a1);
+/** @overload */
+template<typename T, typename A1, typename A2>
+Ptr<T> makePtr(const A1& a1, const A2& a2);
+/** @overload */
+template<typename T, typename A1, typename A2, typename A3>
+Ptr<T> makePtr(const A1& a1, const A2& a2, const A3& a3);
+/** @overload */
+template<typename T, typename A1, typename A2, typename A3, typename A4>
+Ptr<T> makePtr(const A1& a1, const A2& a2, const A3& a3, const A4& a4);
+/** @overload */
+template<typename T, typename A1, typename A2, typename A3, typename A4, typename A5>
+Ptr<T> makePtr(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5);
+/** @overload */
+template<typename T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>
+Ptr<T> makePtr(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6);
+/** @overload */
+template<typename T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>
+Ptr<T> makePtr(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7);
+/** @overload */
+template<typename T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8>
+Ptr<T> makePtr(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8);
+/** @overload */
+template<typename T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9>
+Ptr<T> makePtr(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9);
+/** @overload */
+template<typename T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10>
+Ptr<T> makePtr(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9, const A10& a10);
+
+//////////////////////////////// string class ////////////////////////////////
+
+class CV_EXPORTS FileNode; //for string constructor from FileNode
+
+class CV_EXPORTS String
+{
+public:
+ typedef char value_type;
+ typedef char& reference;
+ typedef const char& const_reference;
+ typedef char* pointer;
+ typedef const char* const_pointer;
+ typedef ptrdiff_t difference_type;
+ typedef size_t size_type;
+ typedef char* iterator;
+ typedef const char* const_iterator;
+
+ static const size_t npos = size_t(-1);
+
+ explicit String();
+ String(const String& str);
+ String(const String& str, size_t pos, size_t len = npos);
+ String(const char* s);
+ String(const char* s, size_t n);
+ String(size_t n, char c);
+ String(const char* first, const char* last);
+ template<typename Iterator> String(Iterator first, Iterator last);
+ explicit String(const FileNode& fn);
+ ~String();
+
+ String& operator=(const String& str);
+ String& operator=(const char* s);
+ String& operator=(char c);
+
+ String& operator+=(const String& str);
+ String& operator+=(const char* s);
+ String& operator+=(char c);
+
+ size_t size() const;
+ size_t length() const;
+
+ char operator[](size_t idx) const;
+ char operator[](int idx) const;
+
+ const char* begin() const;
+ const char* end() const;
+
+ const char* c_str() const;
+
+ bool empty() const;
+ void clear();
+
+ int compare(const char* s) const;
+ int compare(const String& str) const;
+
+ void swap(String& str);
+ String substr(size_t pos = 0, size_t len = npos) const;
+
+ size_t find(const char* s, size_t pos, size_t n) const;
+ size_t find(char c, size_t pos = 0) const;
+ size_t find(const String& str, size_t pos = 0) const;
+ size_t find(const char* s, size_t pos = 0) const;
+
+ size_t rfind(const char* s, size_t pos, size_t n) const;
+ size_t rfind(char c, size_t pos = npos) const;
+ size_t rfind(const String& str, size_t pos = npos) const;
+ size_t rfind(const char* s, size_t pos = npos) const;
+
+ size_t find_first_of(const char* s, size_t pos, size_t n) const;
+ size_t find_first_of(char c, size_t pos = 0) const;
+ size_t find_first_of(const String& str, size_t pos = 0) const;
+ size_t find_first_of(const char* s, size_t pos = 0) const;
+
+ size_t find_last_of(const char* s, size_t pos, size_t n) const;
+ size_t find_last_of(char c, size_t pos = npos) const;
+ size_t find_last_of(const String& str, size_t pos = npos) const;
+ size_t find_last_of(const char* s, size_t pos = npos) const;
+
+ friend String operator+ (const String& lhs, const String& rhs);
+ friend String operator+ (const String& lhs, const char* rhs);
+ friend String operator+ (const char* lhs, const String& rhs);
+ friend String operator+ (const String& lhs, char rhs);
+ friend String operator+ (char lhs, const String& rhs);
+
+ String toLowerCase() const;
+
+#ifndef OPENCV_NOSTL
+ String(const std::string& str);
+ String(const std::string& str, size_t pos, size_t len = npos);
+ String& operator=(const std::string& str);
+ String& operator+=(const std::string& str);
+ operator std::string() const;
+
+ friend String operator+ (const String& lhs, const std::string& rhs);
+ friend String operator+ (const std::string& lhs, const String& rhs);
+#endif
+
+private:
+ char* cstr_;
+ size_t len_;
+
+ char* allocate(size_t len); // len without trailing 0
+ void deallocate();
+
+ String(int); // disabled and invalid. Catch invalid usages like, commandLineParser.has(0) problem
+};
+
+//! @} core_basic
+
+////////////////////////// cv::String implementation /////////////////////////
+
+//! @cond IGNORED
+
+inline
+String::String()
+ : cstr_(0), len_(0)
+{}
+
+inline
+String::String(const String& str)
+ : cstr_(str.cstr_), len_(str.len_)
+{
+ if (cstr_)
+ CV_XADD(((int*)cstr_)-1, 1);
+}
+
+inline
+String::String(const String& str, size_t pos, size_t len)
+ : cstr_(0), len_(0)
+{
+ pos = min(pos, str.len_);
+ len = min(str.len_ - pos, len);
+ if (!len) return;
+ if (len == str.len_)
+ {
+ CV_XADD(((int*)str.cstr_)-1, 1);
+ cstr_ = str.cstr_;
+ len_ = str.len_;
+ return;
+ }
+ memcpy(allocate(len), str.cstr_ + pos, len);
+}
+
+inline
+String::String(const char* s)
+ : cstr_(0), len_(0)
+{
+ if (!s) return;
+ size_t len = strlen(s);
+ memcpy(allocate(len), s, len);
+}
+
+inline
+String::String(const char* s, size_t n)
+ : cstr_(0), len_(0)
+{
+ if (!n) return;
+ memcpy(allocate(n), s, n);
+}
+
+inline
+String::String(size_t n, char c)
+ : cstr_(0), len_(0)
+{
+ memset(allocate(n), c, n);
+}
+
+inline
+String::String(const char* first, const char* last)
+ : cstr_(0), len_(0)
+{
+ size_t len = (size_t)(last - first);
+ memcpy(allocate(len), first, len);
+}
+
+template<typename Iterator> inline
+String::String(Iterator first, Iterator last)
+ : cstr_(0), len_(0)
+{
+ size_t len = (size_t)(last - first);
+ char* str = allocate(len);
+ while (first != last)
+ {
+ *str++ = *first;
+ ++first;
+ }
+}
+
+inline
+String::~String()
+{
+ deallocate();
+}
+
+inline
+String& String::operator=(const String& str)
+{
+ if (&str == this) return *this;
+
+ deallocate();
+ if (str.cstr_) CV_XADD(((int*)str.cstr_)-1, 1);
+ cstr_ = str.cstr_;
+ len_ = str.len_;
+ return *this;
+}
+
+inline
+String& String::operator=(const char* s)
+{
+ deallocate();
+ if (!s) return *this;
+ size_t len = strlen(s);
+ memcpy(allocate(len), s, len);
+ return *this;
+}
+
+inline
+String& String::operator=(char c)
+{
+ deallocate();
+ allocate(1)[0] = c;
+ return *this;
+}
+
+inline
+String& String::operator+=(const String& str)
+{
+ *this = *this + str;
+ return *this;
+}
+
+inline
+String& String::operator+=(const char* s)
+{
+ *this = *this + s;
+ return *this;
+}
+
+inline
+String& String::operator+=(char c)
+{
+ *this = *this + c;
+ return *this;
+}
+
+inline
+size_t String::size() const
+{
+ return len_;
+}
+
+inline
+size_t String::length() const
+{
+ return len_;
+}
+
+inline
+char String::operator[](size_t idx) const
+{
+ return cstr_[idx];
+}
+
+inline
+char String::operator[](int idx) const
+{
+ return cstr_[idx];
+}
+
+inline
+const char* String::begin() const
+{
+ return cstr_;
+}
+
+inline
+const char* String::end() const
+{
+ return len_ ? cstr_ + 1 : 0;
+}
+
+inline
+bool String::empty() const
+{
+ return len_ == 0;
+}
+
+inline
+const char* String::c_str() const
+{
+ return cstr_ ? cstr_ : "";
+}
+
+inline
+void String::swap(String& str)
+{
+ cv::swap(cstr_, str.cstr_);
+ cv::swap(len_, str.len_);
+}
+
+inline
+void String::clear()
+{
+ deallocate();
+}
+
+inline
+int String::compare(const char* s) const
+{
+ if (cstr_ == s) return 0;
+ return strcmp(c_str(), s);
+}
+
+inline
+int String::compare(const String& str) const
+{
+ if (cstr_ == str.cstr_) return 0;
+ return strcmp(c_str(), str.c_str());
+}
+
+inline
+String String::substr(size_t pos, size_t len) const
+{
+ return String(*this, pos, len);
+}
+
+inline
+size_t String::find(const char* s, size_t pos, size_t n) const
+{
+ if (n == 0 || pos + n > len_) return npos;
+ const char* lmax = cstr_ + len_ - n;
+ for (const char* i = cstr_ + pos; i <= lmax; ++i)
+ {
+ size_t j = 0;
+ while (j < n && s[j] == i[j]) ++j;
+ if (j == n) return (size_t)(i - cstr_);
+ }
+ return npos;
+}
+
+inline
+size_t String::find(char c, size_t pos) const
+{
+ return find(&c, pos, 1);
+}
+
+inline
+size_t String::find(const String& str, size_t pos) const
+{
+ return find(str.c_str(), pos, str.len_);
+}
+
+inline
+size_t String::find(const char* s, size_t pos) const
+{
+ if (pos >= len_ || !s[0]) return npos;
+ const char* lmax = cstr_ + len_;
+ for (const char* i = cstr_ + pos; i < lmax; ++i)
+ {
+ size_t j = 0;
+ while (s[j] && s[j] == i[j])
+ { if(i + j >= lmax) return npos;
+ ++j;
+ }
+ if (!s[j]) return (size_t)(i - cstr_);
+ }
+ return npos;
+}
+
+inline
+size_t String::rfind(const char* s, size_t pos, size_t n) const
+{
+ if (n > len_) return npos;
+ if (pos > len_ - n) pos = len_ - n;
+ for (const char* i = cstr_ + pos; i >= cstr_; --i)
+ {
+ size_t j = 0;
+ while (j < n && s[j] == i[j]) ++j;
+ if (j == n) return (size_t)(i - cstr_);
+ }
+ return npos;
+}
+
+inline
+size_t String::rfind(char c, size_t pos) const
+{
+ return rfind(&c, pos, 1);
+}
+
+inline
+size_t String::rfind(const String& str, size_t pos) const
+{
+ return rfind(str.c_str(), pos, str.len_);
+}
+
+inline
+size_t String::rfind(const char* s, size_t pos) const
+{
+ return rfind(s, pos, strlen(s));
+}
+
+inline
+size_t String::find_first_of(const char* s, size_t pos, size_t n) const
+{
+ if (n == 0 || pos + n > len_) return npos;
+ const char* lmax = cstr_ + len_;
+ for (const char* i = cstr_ + pos; i < lmax; ++i)
+ {
+ for (size_t j = 0; j < n; ++j)
+ if (s[j] == *i)
+ return (size_t)(i - cstr_);
+ }
+ return npos;
+}
+
+inline
+size_t String::find_first_of(char c, size_t pos) const
+{
+ return find_first_of(&c, pos, 1);
+}
+
+inline
+size_t String::find_first_of(const String& str, size_t pos) const
+{
+ return find_first_of(str.c_str(), pos, str.len_);
+}
+
+inline
+size_t String::find_first_of(const char* s, size_t pos) const
+{
+ if (len_ == 0) return npos;
+ if (pos >= len_ || !s[0]) return npos;
+ const char* lmax = cstr_ + len_;
+ for (const char* i = cstr_ + pos; i < lmax; ++i)
+ {
+ for (size_t j = 0; s[j]; ++j)
+ if (s[j] == *i)
+ return (size_t)(i - cstr_);
+ }
+ return npos;
+}
+
+inline
+size_t String::find_last_of(const char* s, size_t pos, size_t n) const
+{
+ if (len_ == 0) return npos;
+ if (pos >= len_) pos = len_ - 1;
+ for (const char* i = cstr_ + pos; i >= cstr_; --i)
+ {
+ for (size_t j = 0; j < n; ++j)
+ if (s[j] == *i)
+ return (size_t)(i - cstr_);
+ }
+ return npos;
+}
+
+inline
+size_t String::find_last_of(char c, size_t pos) const
+{
+ return find_last_of(&c, pos, 1);
+}
+
+inline
+size_t String::find_last_of(const String& str, size_t pos) const
+{
+ return find_last_of(str.c_str(), pos, str.len_);
+}
+
+inline
+size_t String::find_last_of(const char* s, size_t pos) const
+{
+ if (len_ == 0) return npos;
+ if (pos >= len_) pos = len_ - 1;
+ for (const char* i = cstr_ + pos; i >= cstr_; --i)
+ {
+ for (size_t j = 0; s[j]; ++j)
+ if (s[j] == *i)
+ return (size_t)(i - cstr_);
+ }
+ return npos;
+}
+
+inline
+String String::toLowerCase() const
+{
+ String res(cstr_, len_);
+
+ for (size_t i = 0; i < len_; ++i)
+ res.cstr_[i] = (char) ::tolower(cstr_[i]);
+
+ return res;
+}
+
+//! @endcond
+
+// ************************* cv::String non-member functions *************************
+
+//! @relates cv::String
+//! @{
+
+inline
+String operator + (const String& lhs, const String& rhs)
+{
+ String s;
+ s.allocate(lhs.len_ + rhs.len_);
+ memcpy(s.cstr_, lhs.cstr_, lhs.len_);
+ memcpy(s.cstr_ + lhs.len_, rhs.cstr_, rhs.len_);
+ return s;
+}
+
+inline
+String operator + (const String& lhs, const char* rhs)
+{
+ String s;
+ size_t rhslen = strlen(rhs);
+ s.allocate(lhs.len_ + rhslen);
+ memcpy(s.cstr_, lhs.cstr_, lhs.len_);
+ memcpy(s.cstr_ + lhs.len_, rhs, rhslen);
+ return s;
+}
+
+inline
+String operator + (const char* lhs, const String& rhs)
+{
+ String s;
+ size_t lhslen = strlen(lhs);
+ s.allocate(lhslen + rhs.len_);
+ memcpy(s.cstr_, lhs, lhslen);
+ memcpy(s.cstr_ + lhslen, rhs.cstr_, rhs.len_);
+ return s;
+}
+
+inline
+String operator + (const String& lhs, char rhs)
+{
+ String s;
+ s.allocate(lhs.len_ + 1);
+ memcpy(s.cstr_, lhs.cstr_, lhs.len_);
+ s.cstr_[lhs.len_] = rhs;
+ return s;
+}
+
+inline
+String operator + (char lhs, const String& rhs)
+{
+ String s;
+ s.allocate(rhs.len_ + 1);
+ s.cstr_[0] = lhs;
+ memcpy(s.cstr_ + 1, rhs.cstr_, rhs.len_);
+ return s;
+}
+
+static inline bool operator== (const String& lhs, const String& rhs) { return 0 == lhs.compare(rhs); }
+static inline bool operator== (const char* lhs, const String& rhs) { return 0 == rhs.compare(lhs); }
+static inline bool operator== (const String& lhs, const char* rhs) { return 0 == lhs.compare(rhs); }
+static inline bool operator!= (const String& lhs, const String& rhs) { return 0 != lhs.compare(rhs); }
+static inline bool operator!= (const char* lhs, const String& rhs) { return 0 != rhs.compare(lhs); }
+static inline bool operator!= (const String& lhs, const char* rhs) { return 0 != lhs.compare(rhs); }
+static inline bool operator< (const String& lhs, const String& rhs) { return lhs.compare(rhs) < 0; }
+static inline bool operator< (const char* lhs, const String& rhs) { return rhs.compare(lhs) > 0; }
+static inline bool operator< (const String& lhs, const char* rhs) { return lhs.compare(rhs) < 0; }
+static inline bool operator<= (const String& lhs, const String& rhs) { return lhs.compare(rhs) <= 0; }
+static inline bool operator<= (const char* lhs, const String& rhs) { return rhs.compare(lhs) >= 0; }
+static inline bool operator<= (const String& lhs, const char* rhs) { return lhs.compare(rhs) <= 0; }
+static inline bool operator> (const String& lhs, const String& rhs) { return lhs.compare(rhs) > 0; }
+static inline bool operator> (const char* lhs, const String& rhs) { return rhs.compare(lhs) < 0; }
+static inline bool operator> (const String& lhs, const char* rhs) { return lhs.compare(rhs) > 0; }
+static inline bool operator>= (const String& lhs, const String& rhs) { return lhs.compare(rhs) >= 0; }
+static inline bool operator>= (const char* lhs, const String& rhs) { return rhs.compare(lhs) <= 0; }
+static inline bool operator>= (const String& lhs, const char* rhs) { return lhs.compare(rhs) >= 0; }
+
+//! @} relates cv::String
+
+} // cv
+
+#ifndef OPENCV_NOSTL_TRANSITIONAL
+namespace std
+{
+ static inline void swap(cv::String& a, cv::String& b) { a.swap(b); }
+}
+#else
+namespace cv
+{
+ template<> inline
+ void swap<cv::String>(cv::String& a, cv::String& b)
+ {
+ a.swap(b);
+ }
+}
+#endif
+
+#include "opencv2/core/ptr.inl.hpp"
+
+#endif //OPENCV_CORE_CVSTD_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/core/cvstd.inl.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,267 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_CORE_CVSTDINL_HPP
+#define OPENCV_CORE_CVSTDINL_HPP
+
+#ifndef OPENCV_NOSTL
+# include <complex>
+# include <ostream>
+#endif
+
+//! @cond IGNORED
+
+namespace cv
+{
+#ifndef OPENCV_NOSTL
+
+template<typename _Tp> class DataType< std::complex<_Tp> >
+{
+public:
+ typedef std::complex<_Tp> value_type;
+ typedef value_type work_type;
+ typedef _Tp channel_type;
+
+ enum { generic_type = 0,
+ depth = DataType<channel_type>::depth,
+ channels = 2,
+ fmt = DataType<channel_type>::fmt + ((channels - 1) << 8),
+ type = CV_MAKETYPE(depth, channels) };
+
+ typedef Vec<channel_type, channels> vec_type;
+};
+
+inline
+String::String(const std::string& str)
+ : cstr_(0), len_(0)
+{
+ if (!str.empty())
+ {
+ size_t len = str.size();
+ memcpy(allocate(len), str.c_str(), len);
+ }
+}
+
+inline
+String::String(const std::string& str, size_t pos, size_t len)
+ : cstr_(0), len_(0)
+{
+ size_t strlen = str.size();
+ pos = min(pos, strlen);
+ len = min(strlen - pos, len);
+ if (!len) return;
+ memcpy(allocate(len), str.c_str() + pos, len);
+}
+
+inline
+String& String::operator = (const std::string& str)
+{
+ deallocate();
+ if (!str.empty())
+ {
+ size_t len = str.size();
+ memcpy(allocate(len), str.c_str(), len);
+ }
+ return *this;
+}
+
+inline
+String& String::operator += (const std::string& str)
+{
+ *this = *this + str;
+ return *this;
+}
+
+inline
+String::operator std::string() const
+{
+ return std::string(cstr_, len_);
+}
+
+inline
+String operator + (const String& lhs, const std::string& rhs)
+{
+ String s;
+ size_t rhslen = rhs.size();
+ s.allocate(lhs.len_ + rhslen);
+ memcpy(s.cstr_, lhs.cstr_, lhs.len_);
+ memcpy(s.cstr_ + lhs.len_, rhs.c_str(), rhslen);
+ return s;
+}
+
+inline
+String operator + (const std::string& lhs, const String& rhs)
+{
+ String s;
+ size_t lhslen = lhs.size();
+ s.allocate(lhslen + rhs.len_);
+ memcpy(s.cstr_, lhs.c_str(), lhslen);
+ memcpy(s.cstr_ + lhslen, rhs.cstr_, rhs.len_);
+ return s;
+}
+
+inline
+FileNode::operator std::string() const
+{
+ String value;
+ read(*this, value, value);
+ return value;
+}
+
+template<> inline
+void operator >> (const FileNode& n, std::string& value)
+{
+ String val;
+ read(n, val, val);
+ value = val;
+}
+
+template<> inline
+FileStorage& operator << (FileStorage& fs, const std::string& value)
+{
+ return fs << cv::String(value);
+}
+
+static inline
+std::ostream& operator << (std::ostream& os, const String& str)
+{
+ return os << str.c_str();
+}
+
+static inline
+std::ostream& operator << (std::ostream& out, Ptr<Formatted> fmtd)
+{
+ fmtd->reset();
+ for(const char* str = fmtd->next(); str; str = fmtd->next())
+ out << str;
+ return out;
+}
+
+static inline
+std::ostream& operator << (std::ostream& out, const Mat& mtx)
+{
+ return out << Formatter::get()->format(mtx);
+}
+
+template<typename _Tp> static inline
+std::ostream& operator << (std::ostream& out, const std::vector<Point_<_Tp> >& vec)
+{
+ return out << Formatter::get()->format(Mat(vec));
+}
+
+
+template<typename _Tp> static inline
+std::ostream& operator << (std::ostream& out, const std::vector<Point3_<_Tp> >& vec)
+{
+ return out << Formatter::get()->format(Mat(vec));
+}
+
+
+template<typename _Tp, int m, int n> static inline
+std::ostream& operator << (std::ostream& out, const Matx<_Tp, m, n>& matx)
+{
+ return out << Formatter::get()->format(Mat(matx));
+}
+
+template<typename _Tp> static inline
+std::ostream& operator << (std::ostream& out, const Point_<_Tp>& p)
+{
+ out << "[" << p.x << ", " << p.y << "]";
+ return out;
+}
+
+template<typename _Tp> static inline
+std::ostream& operator << (std::ostream& out, const Point3_<_Tp>& p)
+{
+ out << "[" << p.x << ", " << p.y << ", " << p.z << "]";
+ return out;
+}
+
+template<typename _Tp, int n> static inline
+std::ostream& operator << (std::ostream& out, const Vec<_Tp, n>& vec)
+{
+ out << "[";
+#ifdef _MSC_VER
+#pragma warning( push )
+#pragma warning( disable: 4127 )
+#endif
+ if(Vec<_Tp, n>::depth < CV_32F)
+#ifdef _MSC_VER
+#pragma warning( pop )
+#endif
+ {
+ for (int i = 0; i < n - 1; ++i) {
+ out << (int)vec[i] << ", ";
+ }
+ out << (int)vec[n-1] << "]";
+ }
+ else
+ {
+ for (int i = 0; i < n - 1; ++i) {
+ out << vec[i] << ", ";
+ }
+ out << vec[n-1] << "]";
+ }
+
+ return out;
+}
+
+template<typename _Tp> static inline
+std::ostream& operator << (std::ostream& out, const Size_<_Tp>& size)
+{
+ return out << "[" << size.width << " x " << size.height << "]";
+}
+
+template<typename _Tp> static inline
+std::ostream& operator << (std::ostream& out, const Rect_<_Tp>& rect)
+{
+ return out << "[" << rect.width << " x " << rect.height << " from (" << rect.x << ", " << rect.y << ")]";
+}
+
+
+#endif // OPENCV_NOSTL
+} // cv
+
+//! @endcond
+
+#endif // OPENCV_CORE_CVSTDINL_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/core/directx.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,184 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2010-2013, Advanced Micro Devices, Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors as is and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the copyright holders or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_CORE_DIRECTX_HPP
+#define OPENCV_CORE_DIRECTX_HPP
+
+#include "mat.hpp"
+#include "ocl.hpp"
+
+#if !defined(__d3d11_h__)
+struct ID3D11Device;
+struct ID3D11Texture2D;
+#endif
+
+#if !defined(__d3d10_h__)
+struct ID3D10Device;
+struct ID3D10Texture2D;
+#endif
+
+#if !defined(_D3D9_H_)
+struct IDirect3DDevice9;
+struct IDirect3DDevice9Ex;
+struct IDirect3DSurface9;
+#endif
+
+
+namespace cv { namespace directx {
+
+namespace ocl {
+using namespace cv::ocl;
+
+//! @addtogroup core_directx
+// This section describes OpenCL and DirectX interoperability.
+//
+// To enable DirectX support, configure OpenCV using CMake with WITH_DIRECTX=ON . Note, DirectX is
+// supported only on Windows.
+//
+// To use OpenCL functionality you should first initialize OpenCL context from DirectX resource.
+//
+//! @{
+
+// TODO static functions in the Context class
+//! @brief Creates OpenCL context from D3D11 device
+//
+//! @param pD3D11Device - pointer to D3D11 device
+//! @return Returns reference to OpenCL Context
+CV_EXPORTS Context& initializeContextFromD3D11Device(ID3D11Device* pD3D11Device);
+
+//! @brief Creates OpenCL context from D3D10 device
+//
+//! @param pD3D10Device - pointer to D3D10 device
+//! @return Returns reference to OpenCL Context
+CV_EXPORTS Context& initializeContextFromD3D10Device(ID3D10Device* pD3D10Device);
+
+//! @brief Creates OpenCL context from Direct3DDevice9Ex device
+//
+//! @param pDirect3DDevice9Ex - pointer to Direct3DDevice9Ex device
+//! @return Returns reference to OpenCL Context
+CV_EXPORTS Context& initializeContextFromDirect3DDevice9Ex(IDirect3DDevice9Ex* pDirect3DDevice9Ex);
+
+//! @brief Creates OpenCL context from Direct3DDevice9 device
+//
+//! @param pDirect3DDevice9 - pointer to Direct3Device9 device
+//! @return Returns reference to OpenCL Context
+CV_EXPORTS Context& initializeContextFromDirect3DDevice9(IDirect3DDevice9* pDirect3DDevice9);
+
+//! @}
+
+} // namespace cv::directx::ocl
+
+//! @addtogroup core_directx
+//! @{
+
+//! @brief Converts InputArray to ID3D11Texture2D. If destination texture format is DXGI_FORMAT_NV12 then
+//! input UMat expected to be in BGR format and data will be downsampled and color-converted to NV12.
+//
+//! @note Note: Destination texture must be allocated by application. Function does memory copy from src to
+//! pD3D11Texture2D
+//
+//! @param src - source InputArray
+//! @param pD3D11Texture2D - destination D3D11 texture
+CV_EXPORTS void convertToD3D11Texture2D(InputArray src, ID3D11Texture2D* pD3D11Texture2D);
+
+//! @brief Converts ID3D11Texture2D to OutputArray. If input texture format is DXGI_FORMAT_NV12 then
+//! data will be upsampled and color-converted to BGR format.
+//
+//! @note Note: Destination matrix will be re-allocated if it has not enough memory to match texture size.
+//! function does memory copy from pD3D11Texture2D to dst
+//
+//! @param pD3D11Texture2D - source D3D11 texture
+//! @param dst - destination OutputArray
+CV_EXPORTS void convertFromD3D11Texture2D(ID3D11Texture2D* pD3D11Texture2D, OutputArray dst);
+
+//! @brief Converts InputArray to ID3D10Texture2D
+//
+//! @note Note: function does memory copy from src to
+//! pD3D10Texture2D
+//
+//! @param src - source InputArray
+//! @param pD3D10Texture2D - destination D3D10 texture
+CV_EXPORTS void convertToD3D10Texture2D(InputArray src, ID3D10Texture2D* pD3D10Texture2D);
+
+//! @brief Converts ID3D10Texture2D to OutputArray
+//
+//! @note Note: function does memory copy from pD3D10Texture2D
+//! to dst
+//
+//! @param pD3D10Texture2D - source D3D10 texture
+//! @param dst - destination OutputArray
+CV_EXPORTS void convertFromD3D10Texture2D(ID3D10Texture2D* pD3D10Texture2D, OutputArray dst);
+
+//! @brief Converts InputArray to IDirect3DSurface9
+//
+//! @note Note: function does memory copy from src to
+//! pDirect3DSurface9
+//
+//! @param src - source InputArray
+//! @param pDirect3DSurface9 - destination D3D10 texture
+//! @param surfaceSharedHandle - shared handle
+CV_EXPORTS void convertToDirect3DSurface9(InputArray src, IDirect3DSurface9* pDirect3DSurface9, void* surfaceSharedHandle = NULL);
+
+//! @brief Converts IDirect3DSurface9 to OutputArray
+//
+//! @note Note: function does memory copy from pDirect3DSurface9
+//! to dst
+//
+//! @param pDirect3DSurface9 - source D3D10 texture
+//! @param dst - destination OutputArray
+//! @param surfaceSharedHandle - shared handle
+CV_EXPORTS void convertFromDirect3DSurface9(IDirect3DSurface9* pDirect3DSurface9, OutputArray dst, void* surfaceSharedHandle = NULL);
+
+//! @brief Get OpenCV type from DirectX type
+//! @param iDXGI_FORMAT - enum DXGI_FORMAT for D3D10/D3D11
+//! @return OpenCV type or -1 if there is no equivalent
+CV_EXPORTS int getTypeFromDXGI_FORMAT(const int iDXGI_FORMAT); // enum DXGI_FORMAT for D3D10/D3D11
+
+//! @brief Get OpenCV type from DirectX type
+//! @param iD3DFORMAT - enum D3DTYPE for D3D9
+//! @return OpenCV type or -1 if there is no equivalent
+CV_EXPORTS int getTypeFromD3DFORMAT(const int iD3DFORMAT); // enum D3DTYPE for D3D9
+
+//! @}
+
+} } // namespace cv::directx
+
+#endif // OPENCV_CORE_DIRECTX_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/core/eigen.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,280 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+
+#ifndef OPENCV_CORE_EIGEN_HPP
+#define OPENCV_CORE_EIGEN_HPP
+
+#include "opencv2/core.hpp"
+
+#if defined _MSC_VER && _MSC_VER >= 1200
+#pragma warning( disable: 4714 ) //__forceinline is not inlined
+#pragma warning( disable: 4127 ) //conditional expression is constant
+#pragma warning( disable: 4244 ) //conversion from '__int64' to 'int', possible loss of data
+#endif
+
+namespace cv
+{
+
+//! @addtogroup core_eigen
+//! @{
+
+template<typename _Tp, int _rows, int _cols, int _options, int _maxRows, int _maxCols> static inline
+void eigen2cv( const Eigen::Matrix<_Tp, _rows, _cols, _options, _maxRows, _maxCols>& src, Mat& dst )
+{
+ if( !(src.Flags & Eigen::RowMajorBit) )
+ {
+ Mat _src(src.cols(), src.rows(), DataType<_Tp>::type,
+ (void*)src.data(), src.stride()*sizeof(_Tp));
+ transpose(_src, dst);
+ }
+ else
+ {
+ Mat _src(src.rows(), src.cols(), DataType<_Tp>::type,
+ (void*)src.data(), src.stride()*sizeof(_Tp));
+ _src.copyTo(dst);
+ }
+}
+
+// Matx case
+template<typename _Tp, int _rows, int _cols, int _options, int _maxRows, int _maxCols> static inline
+void eigen2cv( const Eigen::Matrix<_Tp, _rows, _cols, _options, _maxRows, _maxCols>& src,
+ Matx<_Tp, _rows, _cols>& dst )
+{
+ if( !(src.Flags & Eigen::RowMajorBit) )
+ {
+ dst = Matx<_Tp, _cols, _rows>(static_cast<const _Tp*>(src.data())).t();
+ }
+ else
+ {
+ dst = Matx<_Tp, _rows, _cols>(static_cast<const _Tp*>(src.data()));
+ }
+}
+
+template<typename _Tp, int _rows, int _cols, int _options, int _maxRows, int _maxCols> static inline
+void cv2eigen( const Mat& src,
+ Eigen::Matrix<_Tp, _rows, _cols, _options, _maxRows, _maxCols>& dst )
+{
+ CV_DbgAssert(src.rows == _rows && src.cols == _cols);
+ if( !(dst.Flags & Eigen::RowMajorBit) )
+ {
+ const Mat _dst(src.cols, src.rows, DataType<_Tp>::type,
+ dst.data(), (size_t)(dst.stride()*sizeof(_Tp)));
+ if( src.type() == _dst.type() )
+ transpose(src, _dst);
+ else if( src.cols == src.rows )
+ {
+ src.convertTo(_dst, _dst.type());
+ transpose(_dst, _dst);
+ }
+ else
+ Mat(src.t()).convertTo(_dst, _dst.type());
+ }
+ else
+ {
+ const Mat _dst(src.rows, src.cols, DataType<_Tp>::type,
+ dst.data(), (size_t)(dst.stride()*sizeof(_Tp)));
+ src.convertTo(_dst, _dst.type());
+ }
+}
+
+// Matx case
+template<typename _Tp, int _rows, int _cols, int _options, int _maxRows, int _maxCols> static inline
+void cv2eigen( const Matx<_Tp, _rows, _cols>& src,
+ Eigen::Matrix<_Tp, _rows, _cols, _options, _maxRows, _maxCols>& dst )
+{
+ if( !(dst.Flags & Eigen::RowMajorBit) )
+ {
+ const Mat _dst(_cols, _rows, DataType<_Tp>::type,
+ dst.data(), (size_t)(dst.stride()*sizeof(_Tp)));
+ transpose(src, _dst);
+ }
+ else
+ {
+ const Mat _dst(_rows, _cols, DataType<_Tp>::type,
+ dst.data(), (size_t)(dst.stride()*sizeof(_Tp)));
+ Mat(src).copyTo(_dst);
+ }
+}
+
+template<typename _Tp> static inline
+void cv2eigen( const Mat& src,
+ Eigen::Matrix<_Tp, Eigen::Dynamic, Eigen::Dynamic>& dst )
+{
+ dst.resize(src.rows, src.cols);
+ if( !(dst.Flags & Eigen::RowMajorBit) )
+ {
+ const Mat _dst(src.cols, src.rows, DataType<_Tp>::type,
+ dst.data(), (size_t)(dst.stride()*sizeof(_Tp)));
+ if( src.type() == _dst.type() )
+ transpose(src, _dst);
+ else if( src.cols == src.rows )
+ {
+ src.convertTo(_dst, _dst.type());
+ transpose(_dst, _dst);
+ }
+ else
+ Mat(src.t()).convertTo(_dst, _dst.type());
+ }
+ else
+ {
+ const Mat _dst(src.rows, src.cols, DataType<_Tp>::type,
+ dst.data(), (size_t)(dst.stride()*sizeof(_Tp)));
+ src.convertTo(_dst, _dst.type());
+ }
+}
+
+// Matx case
+template<typename _Tp, int _rows, int _cols> static inline
+void cv2eigen( const Matx<_Tp, _rows, _cols>& src,
+ Eigen::Matrix<_Tp, Eigen::Dynamic, Eigen::Dynamic>& dst )
+{
+ dst.resize(_rows, _cols);
+ if( !(dst.Flags & Eigen::RowMajorBit) )
+ {
+ const Mat _dst(_cols, _rows, DataType<_Tp>::type,
+ dst.data(), (size_t)(dst.stride()*sizeof(_Tp)));
+ transpose(src, _dst);
+ }
+ else
+ {
+ const Mat _dst(_rows, _cols, DataType<_Tp>::type,
+ dst.data(), (size_t)(dst.stride()*sizeof(_Tp)));
+ Mat(src).copyTo(_dst);
+ }
+}
+
+template<typename _Tp> static inline
+void cv2eigen( const Mat& src,
+ Eigen::Matrix<_Tp, Eigen::Dynamic, 1>& dst )
+{
+ CV_Assert(src.cols == 1);
+ dst.resize(src.rows);
+
+ if( !(dst.Flags & Eigen::RowMajorBit) )
+ {
+ const Mat _dst(src.cols, src.rows, DataType<_Tp>::type,
+ dst.data(), (size_t)(dst.stride()*sizeof(_Tp)));
+ if( src.type() == _dst.type() )
+ transpose(src, _dst);
+ else
+ Mat(src.t()).convertTo(_dst, _dst.type());
+ }
+ else
+ {
+ const Mat _dst(src.rows, src.cols, DataType<_Tp>::type,
+ dst.data(), (size_t)(dst.stride()*sizeof(_Tp)));
+ src.convertTo(_dst, _dst.type());
+ }
+}
+
+// Matx case
+template<typename _Tp, int _rows> static inline
+void cv2eigen( const Matx<_Tp, _rows, 1>& src,
+ Eigen::Matrix<_Tp, Eigen::Dynamic, 1>& dst )
+{
+ dst.resize(_rows);
+
+ if( !(dst.Flags & Eigen::RowMajorBit) )
+ {
+ const Mat _dst(1, _rows, DataType<_Tp>::type,
+ dst.data(), (size_t)(dst.stride()*sizeof(_Tp)));
+ transpose(src, _dst);
+ }
+ else
+ {
+ const Mat _dst(_rows, 1, DataType<_Tp>::type,
+ dst.data(), (size_t)(dst.stride()*sizeof(_Tp)));
+ src.copyTo(_dst);
+ }
+}
+
+
+template<typename _Tp> static inline
+void cv2eigen( const Mat& src,
+ Eigen::Matrix<_Tp, 1, Eigen::Dynamic>& dst )
+{
+ CV_Assert(src.rows == 1);
+ dst.resize(src.cols);
+ if( !(dst.Flags & Eigen::RowMajorBit) )
+ {
+ const Mat _dst(src.cols, src.rows, DataType<_Tp>::type,
+ dst.data(), (size_t)(dst.stride()*sizeof(_Tp)));
+ if( src.type() == _dst.type() )
+ transpose(src, _dst);
+ else
+ Mat(src.t()).convertTo(_dst, _dst.type());
+ }
+ else
+ {
+ const Mat _dst(src.rows, src.cols, DataType<_Tp>::type,
+ dst.data(), (size_t)(dst.stride()*sizeof(_Tp)));
+ src.convertTo(_dst, _dst.type());
+ }
+}
+
+//Matx
+template<typename _Tp, int _cols> static inline
+void cv2eigen( const Matx<_Tp, 1, _cols>& src,
+ Eigen::Matrix<_Tp, 1, Eigen::Dynamic>& dst )
+{
+ dst.resize(_cols);
+ if( !(dst.Flags & Eigen::RowMajorBit) )
+ {
+ const Mat _dst(_cols, 1, DataType<_Tp>::type,
+ dst.data(), (size_t)(dst.stride()*sizeof(_Tp)));
+ transpose(src, _dst);
+ }
+ else
+ {
+ const Mat _dst(1, _cols, DataType<_Tp>::type,
+ dst.data(), (size_t)(dst.stride()*sizeof(_Tp)));
+ Mat(src).copyTo(_dst);
+ }
+}
+
+//! @}
+
+} // cv
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/core/fast_math.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,303 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
+// Copyright (C) 2015, Itseez Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_CORE_FAST_MATH_HPP
+#define OPENCV_CORE_FAST_MATH_HPP
+
+#include "opencv2/core/cvdef.h"
+
+//! @addtogroup core_utils
+//! @{
+
+/****************************************************************************************\
+* fast math *
+\****************************************************************************************/
+
+#if defined __BORLANDC__
+# include <fastmath.h>
+#elif defined __cplusplus
+# include <cmath>
+#else
+# include <math.h>
+#endif
+
+#ifdef HAVE_TEGRA_OPTIMIZATION
+# include "tegra_round.hpp"
+#endif
+
+#if CV_VFP
+ // 1. general scheme
+ #define ARM_ROUND(_value, _asm_string) \
+ int res; \
+ float temp; \
+ (void)temp; \
+ asm(_asm_string : [res] "=r" (res), [temp] "=w" (temp) : [value] "w" (_value)); \
+ return res
+ // 2. version for double
+ #ifdef __clang__
+ #define ARM_ROUND_DBL(value) ARM_ROUND(value, "vcvtr.s32.f64 %[temp], %[value] \n vmov %[res], %[temp]")
+ #else
+ #define ARM_ROUND_DBL(value) ARM_ROUND(value, "vcvtr.s32.f64 %[temp], %P[value] \n vmov %[res], %[temp]")
+ #endif
+ // 3. version for float
+ #define ARM_ROUND_FLT(value) ARM_ROUND(value, "vcvtr.s32.f32 %[temp], %[value]\n vmov %[res], %[temp]")
+#endif // CV_VFP
+
+/** @brief Rounds floating-point number to the nearest integer
+
+ @param value floating-point number. If the value is outside of INT_MIN ... INT_MAX range, the
+ result is not defined.
+ */
+CV_INLINE int
+cvRound( double value )
+{
+#if ((defined _MSC_VER && defined _M_X64) || (defined __GNUC__ && defined __x86_64__ \
+ && defined __SSE2__ && !defined __APPLE__)) && !defined(__CUDACC__)
+ __m128d t = _mm_set_sd( value );
+ return _mm_cvtsd_si32(t);
+#elif defined _MSC_VER && defined _M_IX86
+ int t;
+ __asm
+ {
+ fld value;
+ fistp t;
+ }
+ return t;
+#elif ((defined _MSC_VER && defined _M_ARM) || defined CV_ICC || \
+ defined __GNUC__) && defined HAVE_TEGRA_OPTIMIZATION
+ TEGRA_ROUND_DBL(value);
+#elif defined CV_ICC || defined __GNUC__
+# if CV_VFP
+ ARM_ROUND_DBL(value);
+# else
+ return (int)lrint(value);
+# endif
+#else
+ /* it's ok if round does not comply with IEEE754 standard;
+ the tests should allow +/-1 difference when the tested functions use round */
+ return (int)(value + (value >= 0 ? 0.5 : -0.5));
+#endif
+}
+
+
+/** @brief Rounds floating-point number to the nearest integer not larger than the original.
+
+ The function computes an integer i such that:
+ \f[i \le \texttt{value} < i+1\f]
+ @param value floating-point number. If the value is outside of INT_MIN ... INT_MAX range, the
+ result is not defined.
+ */
+CV_INLINE int cvFloor( double value )
+{
+#if (defined _MSC_VER && defined _M_X64 || (defined __GNUC__ && defined __SSE2__ && !defined __APPLE__)) && !defined(__CUDACC__)
+ __m128d t = _mm_set_sd( value );
+ int i = _mm_cvtsd_si32(t);
+ return i - _mm_movemask_pd(_mm_cmplt_sd(t, _mm_cvtsi32_sd(t,i)));
+#elif defined __GNUC__
+ int i = (int)value;
+ return i - (i > value);
+#else
+ int i = cvRound(value);
+ float diff = (float)(value - i);
+ return i - (diff < 0);
+#endif
+}
+
+/** @brief Rounds floating-point number to the nearest integer not smaller than the original.
+
+ The function computes an integer i such that:
+ \f[i \le \texttt{value} < i+1\f]
+ @param value floating-point number. If the value is outside of INT_MIN ... INT_MAX range, the
+ result is not defined.
+ */
+CV_INLINE int cvCeil( double value )
+{
+#if (defined _MSC_VER && defined _M_X64 || (defined __GNUC__ && defined __SSE2__&& !defined __APPLE__)) && !defined(__CUDACC__)
+ __m128d t = _mm_set_sd( value );
+ int i = _mm_cvtsd_si32(t);
+ return i + _mm_movemask_pd(_mm_cmplt_sd(_mm_cvtsi32_sd(t,i), t));
+#elif defined __GNUC__
+ int i = (int)value;
+ return i + (i < value);
+#else
+ int i = cvRound(value);
+ float diff = (float)(i - value);
+ return i + (diff < 0);
+#endif
+}
+
+/** @brief Determines if the argument is Not A Number.
+
+ @param value The input floating-point value
+
+ The function returns 1 if the argument is Not A Number (as defined by IEEE754 standard), 0
+ otherwise. */
+CV_INLINE int cvIsNaN( double value )
+{
+ Cv64suf ieee754;
+ ieee754.f = value;
+ return ((unsigned)(ieee754.u >> 32) & 0x7fffffff) +
+ ((unsigned)ieee754.u != 0) > 0x7ff00000;
+}
+
+/** @brief Determines if the argument is Infinity.
+
+ @param value The input floating-point value
+
+ The function returns 1 if the argument is a plus or minus infinity (as defined by IEEE754 standard)
+ and 0 otherwise. */
+CV_INLINE int cvIsInf( double value )
+{
+ Cv64suf ieee754;
+ ieee754.f = value;
+ return ((unsigned)(ieee754.u >> 32) & 0x7fffffff) == 0x7ff00000 &&
+ (unsigned)ieee754.u == 0;
+}
+
+#ifdef __cplusplus
+
+/** @overload */
+CV_INLINE int cvRound(float value)
+{
+#if ((defined _MSC_VER && defined _M_X64) || (defined __GNUC__ && defined __x86_64__ && \
+ defined __SSE2__ && !defined __APPLE__)) && !defined(__CUDACC__)
+ __m128 t = _mm_set_ss( value );
+ return _mm_cvtss_si32(t);
+#elif defined _MSC_VER && defined _M_IX86
+ int t;
+ __asm
+ {
+ fld value;
+ fistp t;
+ }
+ return t;
+#elif ((defined _MSC_VER && defined _M_ARM) || defined CV_ICC || \
+ defined __GNUC__) && defined HAVE_TEGRA_OPTIMIZATION
+ TEGRA_ROUND_FLT(value);
+#elif defined CV_ICC || defined __GNUC__
+# if CV_VFP
+ ARM_ROUND_FLT(value);
+# else
+ return (int)lrintf(value);
+# endif
+#else
+ /* it's ok if round does not comply with IEEE754 standard;
+ the tests should allow +/-1 difference when the tested functions use round */
+ return (int)(value + (value >= 0 ? 0.5f : -0.5f));
+#endif
+}
+
+/** @overload */
+CV_INLINE int cvRound( int value )
+{
+ return value;
+}
+
+/** @overload */
+CV_INLINE int cvFloor( float value )
+{
+#if (defined _MSC_VER && defined _M_X64 || (defined __GNUC__ && defined __SSE2__ && !defined __APPLE__)) && !defined(__CUDACC__)
+ __m128 t = _mm_set_ss( value );
+ int i = _mm_cvtss_si32(t);
+ return i - _mm_movemask_ps(_mm_cmplt_ss(t, _mm_cvtsi32_ss(t,i)));
+#elif defined __GNUC__
+ int i = (int)value;
+ return i - (i > value);
+#else
+ int i = cvRound(value);
+ float diff = (float)(value - i);
+ return i - (diff < 0);
+#endif
+}
+
+/** @overload */
+CV_INLINE int cvFloor( int value )
+{
+ return value;
+}
+
+/** @overload */
+CV_INLINE int cvCeil( float value )
+{
+#if (defined _MSC_VER && defined _M_X64 || (defined __GNUC__ && defined __SSE2__&& !defined __APPLE__)) && !defined(__CUDACC__)
+ __m128 t = _mm_set_ss( value );
+ int i = _mm_cvtss_si32(t);
+ return i + _mm_movemask_ps(_mm_cmplt_ss(_mm_cvtsi32_ss(t,i), t));
+#elif defined __GNUC__
+ int i = (int)value;
+ return i + (i < value);
+#else
+ int i = cvRound(value);
+ float diff = (float)(i - value);
+ return i + (diff < 0);
+#endif
+}
+
+/** @overload */
+CV_INLINE int cvCeil( int value )
+{
+ return value;
+}
+
+/** @overload */
+CV_INLINE int cvIsNaN( float value )
+{
+ Cv32suf ieee754;
+ ieee754.f = value;
+ return (ieee754.u & 0x7fffffff) > 0x7f800000;
+}
+
+/** @overload */
+CV_INLINE int cvIsInf( float value )
+{
+ Cv32suf ieee754;
+ ieee754.f = value;
+ return (ieee754.u & 0x7fffffff) == 0x7f800000;
+}
+
+#endif // __cplusplus
+
+//! @} core_utils
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/core/hal/hal.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,250 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
+// Copyright (C) 2015, Itseez Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_HAL_HPP
+#define OPENCV_HAL_HPP
+
+#include "opencv2/core/cvdef.h"
+#include "opencv2/core/cvstd.hpp"
+#include "opencv2/core/hal/interface.h"
+
+namespace cv { namespace hal {
+
+//! @addtogroup core_hal_functions
+//! @{
+
+CV_EXPORTS int normHamming(const uchar* a, int n);
+CV_EXPORTS int normHamming(const uchar* a, const uchar* b, int n);
+
+CV_EXPORTS int normHamming(const uchar* a, int n, int cellSize);
+CV_EXPORTS int normHamming(const uchar* a, const uchar* b, int n, int cellSize);
+
+CV_EXPORTS int LU32f(float* A, size_t astep, int m, float* b, size_t bstep, int n);
+CV_EXPORTS int LU64f(double* A, size_t astep, int m, double* b, size_t bstep, int n);
+CV_EXPORTS bool Cholesky32f(float* A, size_t astep, int m, float* b, size_t bstep, int n);
+CV_EXPORTS bool Cholesky64f(double* A, size_t astep, int m, double* b, size_t bstep, int n);
+CV_EXPORTS void SVD32f(float* At, size_t astep, float* W, float* U, size_t ustep, float* Vt, size_t vstep, int m, int n, int flags);
+CV_EXPORTS void SVD64f(double* At, size_t astep, double* W, double* U, size_t ustep, double* Vt, size_t vstep, int m, int n, int flags);
+CV_EXPORTS int QR32f(float* A, size_t astep, int m, int n, int k, float* b, size_t bstep, float* hFactors);
+CV_EXPORTS int QR64f(double* A, size_t astep, int m, int n, int k, double* b, size_t bstep, double* hFactors);
+
+CV_EXPORTS void gemm32f(const float* src1, size_t src1_step, const float* src2, size_t src2_step,
+ float alpha, const float* src3, size_t src3_step, float beta, float* dst, size_t dst_step,
+ int m_a, int n_a, int n_d, int flags);
+CV_EXPORTS void gemm64f(const double* src1, size_t src1_step, const double* src2, size_t src2_step,
+ double alpha, const double* src3, size_t src3_step, double beta, double* dst, size_t dst_step,
+ int m_a, int n_a, int n_d, int flags);
+CV_EXPORTS void gemm32fc(const float* src1, size_t src1_step, const float* src2, size_t src2_step,
+ float alpha, const float* src3, size_t src3_step, float beta, float* dst, size_t dst_step,
+ int m_a, int n_a, int n_d, int flags);
+CV_EXPORTS void gemm64fc(const double* src1, size_t src1_step, const double* src2, size_t src2_step,
+ double alpha, const double* src3, size_t src3_step, double beta, double* dst, size_t dst_step,
+ int m_a, int n_a, int n_d, int flags);
+
+CV_EXPORTS int normL1_(const uchar* a, const uchar* b, int n);
+CV_EXPORTS float normL1_(const float* a, const float* b, int n);
+CV_EXPORTS float normL2Sqr_(const float* a, const float* b, int n);
+
+CV_EXPORTS void exp32f(const float* src, float* dst, int n);
+CV_EXPORTS void exp64f(const double* src, double* dst, int n);
+CV_EXPORTS void log32f(const float* src, float* dst, int n);
+CV_EXPORTS void log64f(const double* src, double* dst, int n);
+
+CV_EXPORTS void fastAtan32f(const float* y, const float* x, float* dst, int n, bool angleInDegrees);
+CV_EXPORTS void fastAtan64f(const double* y, const double* x, double* dst, int n, bool angleInDegrees);
+CV_EXPORTS void magnitude32f(const float* x, const float* y, float* dst, int n);
+CV_EXPORTS void magnitude64f(const double* x, const double* y, double* dst, int n);
+CV_EXPORTS void sqrt32f(const float* src, float* dst, int len);
+CV_EXPORTS void sqrt64f(const double* src, double* dst, int len);
+CV_EXPORTS void invSqrt32f(const float* src, float* dst, int len);
+CV_EXPORTS void invSqrt64f(const double* src, double* dst, int len);
+
+CV_EXPORTS void split8u(const uchar* src, uchar** dst, int len, int cn );
+CV_EXPORTS void split16u(const ushort* src, ushort** dst, int len, int cn );
+CV_EXPORTS void split32s(const int* src, int** dst, int len, int cn );
+CV_EXPORTS void split64s(const int64* src, int64** dst, int len, int cn );
+
+CV_EXPORTS void merge8u(const uchar** src, uchar* dst, int len, int cn );
+CV_EXPORTS void merge16u(const ushort** src, ushort* dst, int len, int cn );
+CV_EXPORTS void merge32s(const int** src, int* dst, int len, int cn );
+CV_EXPORTS void merge64s(const int64** src, int64* dst, int len, int cn );
+
+CV_EXPORTS void add8u( const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height, void* );
+CV_EXPORTS void add8s( const schar* src1, size_t step1, const schar* src2, size_t step2, schar* dst, size_t step, int width, int height, void* );
+CV_EXPORTS void add16u( const ushort* src1, size_t step1, const ushort* src2, size_t step2, ushort* dst, size_t step, int width, int height, void* );
+CV_EXPORTS void add16s( const short* src1, size_t step1, const short* src2, size_t step2, short* dst, size_t step, int width, int height, void* );
+CV_EXPORTS void add32s( const int* src1, size_t step1, const int* src2, size_t step2, int* dst, size_t step, int width, int height, void* );
+CV_EXPORTS void add32f( const float* src1, size_t step1, const float* src2, size_t step2, float* dst, size_t step, int width, int height, void* );
+CV_EXPORTS void add64f( const double* src1, size_t step1, const double* src2, size_t step2, double* dst, size_t step, int width, int height, void* );
+
+CV_EXPORTS void sub8u( const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height, void* );
+CV_EXPORTS void sub8s( const schar* src1, size_t step1, const schar* src2, size_t step2, schar* dst, size_t step, int width, int height, void* );
+CV_EXPORTS void sub16u( const ushort* src1, size_t step1, const ushort* src2, size_t step2, ushort* dst, size_t step, int width, int height, void* );
+CV_EXPORTS void sub16s( const short* src1, size_t step1, const short* src2, size_t step2, short* dst, size_t step, int width, int height, void* );
+CV_EXPORTS void sub32s( const int* src1, size_t step1, const int* src2, size_t step2, int* dst, size_t step, int width, int height, void* );
+CV_EXPORTS void sub32f( const float* src1, size_t step1, const float* src2, size_t step2, float* dst, size_t step, int width, int height, void* );
+CV_EXPORTS void sub64f( const double* src1, size_t step1, const double* src2, size_t step2, double* dst, size_t step, int width, int height, void* );
+
+CV_EXPORTS void max8u( const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height, void* );
+CV_EXPORTS void max8s( const schar* src1, size_t step1, const schar* src2, size_t step2, schar* dst, size_t step, int width, int height, void* );
+CV_EXPORTS void max16u( const ushort* src1, size_t step1, const ushort* src2, size_t step2, ushort* dst, size_t step, int width, int height, void* );
+CV_EXPORTS void max16s( const short* src1, size_t step1, const short* src2, size_t step2, short* dst, size_t step, int width, int height, void* );
+CV_EXPORTS void max32s( const int* src1, size_t step1, const int* src2, size_t step2, int* dst, size_t step, int width, int height, void* );
+CV_EXPORTS void max32f( const float* src1, size_t step1, const float* src2, size_t step2, float* dst, size_t step, int width, int height, void* );
+CV_EXPORTS void max64f( const double* src1, size_t step1, const double* src2, size_t step2, double* dst, size_t step, int width, int height, void* );
+
+CV_EXPORTS void min8u( const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height, void* );
+CV_EXPORTS void min8s( const schar* src1, size_t step1, const schar* src2, size_t step2, schar* dst, size_t step, int width, int height, void* );
+CV_EXPORTS void min16u( const ushort* src1, size_t step1, const ushort* src2, size_t step2, ushort* dst, size_t step, int width, int height, void* );
+CV_EXPORTS void min16s( const short* src1, size_t step1, const short* src2, size_t step2, short* dst, size_t step, int width, int height, void* );
+CV_EXPORTS void min32s( const int* src1, size_t step1, const int* src2, size_t step2, int* dst, size_t step, int width, int height, void* );
+CV_EXPORTS void min32f( const float* src1, size_t step1, const float* src2, size_t step2, float* dst, size_t step, int width, int height, void* );
+CV_EXPORTS void min64f( const double* src1, size_t step1, const double* src2, size_t step2, double* dst, size_t step, int width, int height, void* );
+
+CV_EXPORTS void absdiff8u( const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height, void* );
+CV_EXPORTS void absdiff8s( const schar* src1, size_t step1, const schar* src2, size_t step2, schar* dst, size_t step, int width, int height, void* );
+CV_EXPORTS void absdiff16u( const ushort* src1, size_t step1, const ushort* src2, size_t step2, ushort* dst, size_t step, int width, int height, void* );
+CV_EXPORTS void absdiff16s( const short* src1, size_t step1, const short* src2, size_t step2, short* dst, size_t step, int width, int height, void* );
+CV_EXPORTS void absdiff32s( const int* src1, size_t step1, const int* src2, size_t step2, int* dst, size_t step, int width, int height, void* );
+CV_EXPORTS void absdiff32f( const float* src1, size_t step1, const float* src2, size_t step2, float* dst, size_t step, int width, int height, void* );
+CV_EXPORTS void absdiff64f( const double* src1, size_t step1, const double* src2, size_t step2, double* dst, size_t step, int width, int height, void* );
+
+CV_EXPORTS void and8u( const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height, void* );
+CV_EXPORTS void or8u( const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height, void* );
+CV_EXPORTS void xor8u( const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height, void* );
+CV_EXPORTS void not8u( const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height, void* );
+
+CV_EXPORTS void cmp8u(const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height, void* _cmpop);
+CV_EXPORTS void cmp8s(const schar* src1, size_t step1, const schar* src2, size_t step2, uchar* dst, size_t step, int width, int height, void* _cmpop);
+CV_EXPORTS void cmp16u(const ushort* src1, size_t step1, const ushort* src2, size_t step2, uchar* dst, size_t step, int width, int height, void* _cmpop);
+CV_EXPORTS void cmp16s(const short* src1, size_t step1, const short* src2, size_t step2, uchar* dst, size_t step, int width, int height, void* _cmpop);
+CV_EXPORTS void cmp32s(const int* src1, size_t step1, const int* src2, size_t step2, uchar* dst, size_t step, int width, int height, void* _cmpop);
+CV_EXPORTS void cmp32f(const float* src1, size_t step1, const float* src2, size_t step2, uchar* dst, size_t step, int width, int height, void* _cmpop);
+CV_EXPORTS void cmp64f(const double* src1, size_t step1, const double* src2, size_t step2, uchar* dst, size_t step, int width, int height, void* _cmpop);
+
+CV_EXPORTS void mul8u( const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height, void* scale);
+CV_EXPORTS void mul8s( const schar* src1, size_t step1, const schar* src2, size_t step2, schar* dst, size_t step, int width, int height, void* scale);
+CV_EXPORTS void mul16u( const ushort* src1, size_t step1, const ushort* src2, size_t step2, ushort* dst, size_t step, int width, int height, void* scale);
+CV_EXPORTS void mul16s( const short* src1, size_t step1, const short* src2, size_t step2, short* dst, size_t step, int width, int height, void* scale);
+CV_EXPORTS void mul32s( const int* src1, size_t step1, const int* src2, size_t step2, int* dst, size_t step, int width, int height, void* scale);
+CV_EXPORTS void mul32f( const float* src1, size_t step1, const float* src2, size_t step2, float* dst, size_t step, int width, int height, void* scale);
+CV_EXPORTS void mul64f( const double* src1, size_t step1, const double* src2, size_t step2, double* dst, size_t step, int width, int height, void* scale);
+
+CV_EXPORTS void div8u( const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height, void* scale);
+CV_EXPORTS void div8s( const schar* src1, size_t step1, const schar* src2, size_t step2, schar* dst, size_t step, int width, int height, void* scale);
+CV_EXPORTS void div16u( const ushort* src1, size_t step1, const ushort* src2, size_t step2, ushort* dst, size_t step, int width, int height, void* scale);
+CV_EXPORTS void div16s( const short* src1, size_t step1, const short* src2, size_t step2, short* dst, size_t step, int width, int height, void* scale);
+CV_EXPORTS void div32s( const int* src1, size_t step1, const int* src2, size_t step2, int* dst, size_t step, int width, int height, void* scale);
+CV_EXPORTS void div32f( const float* src1, size_t step1, const float* src2, size_t step2, float* dst, size_t step, int width, int height, void* scale);
+CV_EXPORTS void div64f( const double* src1, size_t step1, const double* src2, size_t step2, double* dst, size_t step, int width, int height, void* scale);
+
+CV_EXPORTS void recip8u( const uchar *, size_t, const uchar * src2, size_t step2, uchar* dst, size_t step, int width, int height, void* scale);
+CV_EXPORTS void recip8s( const schar *, size_t, const schar * src2, size_t step2, schar* dst, size_t step, int width, int height, void* scale);
+CV_EXPORTS void recip16u( const ushort *, size_t, const ushort * src2, size_t step2, ushort* dst, size_t step, int width, int height, void* scale);
+CV_EXPORTS void recip16s( const short *, size_t, const short * src2, size_t step2, short* dst, size_t step, int width, int height, void* scale);
+CV_EXPORTS void recip32s( const int *, size_t, const int * src2, size_t step2, int* dst, size_t step, int width, int height, void* scale);
+CV_EXPORTS void recip32f( const float *, size_t, const float * src2, size_t step2, float* dst, size_t step, int width, int height, void* scale);
+CV_EXPORTS void recip64f( const double *, size_t, const double * src2, size_t step2, double* dst, size_t step, int width, int height, void* scale);
+
+CV_EXPORTS void addWeighted8u( const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height, void* _scalars );
+CV_EXPORTS void addWeighted8s( const schar* src1, size_t step1, const schar* src2, size_t step2, schar* dst, size_t step, int width, int height, void* scalars );
+CV_EXPORTS void addWeighted16u( const ushort* src1, size_t step1, const ushort* src2, size_t step2, ushort* dst, size_t step, int width, int height, void* scalars );
+CV_EXPORTS void addWeighted16s( const short* src1, size_t step1, const short* src2, size_t step2, short* dst, size_t step, int width, int height, void* scalars );
+CV_EXPORTS void addWeighted32s( const int* src1, size_t step1, const int* src2, size_t step2, int* dst, size_t step, int width, int height, void* scalars );
+CV_EXPORTS void addWeighted32f( const float* src1, size_t step1, const float* src2, size_t step2, float* dst, size_t step, int width, int height, void* scalars );
+CV_EXPORTS void addWeighted64f( const double* src1, size_t step1, const double* src2, size_t step2, double* dst, size_t step, int width, int height, void* scalars );
+
+struct CV_EXPORTS DFT1D
+{
+ static Ptr<DFT1D> create(int len, int count, int depth, int flags, bool * useBuffer = 0);
+ virtual void apply(const uchar *src, uchar *dst) = 0;
+ virtual ~DFT1D() {}
+};
+
+struct CV_EXPORTS DFT2D
+{
+ static Ptr<DFT2D> create(int width, int height, int depth,
+ int src_channels, int dst_channels,
+ int flags, int nonzero_rows = 0);
+ virtual void apply(const uchar *src_data, size_t src_step, uchar *dst_data, size_t dst_step) = 0;
+ virtual ~DFT2D() {}
+};
+
+struct CV_EXPORTS DCT2D
+{
+ static Ptr<DCT2D> create(int width, int height, int depth, int flags);
+ virtual void apply(const uchar *src_data, size_t src_step, uchar *dst_data, size_t dst_step) = 0;
+ virtual ~DCT2D() {}
+};
+
+//! @} core_hal
+
+//=============================================================================
+// for binary compatibility with 3.0
+
+//! @cond IGNORED
+
+CV_EXPORTS int LU(float* A, size_t astep, int m, float* b, size_t bstep, int n);
+CV_EXPORTS int LU(double* A, size_t astep, int m, double* b, size_t bstep, int n);
+CV_EXPORTS bool Cholesky(float* A, size_t astep, int m, float* b, size_t bstep, int n);
+CV_EXPORTS bool Cholesky(double* A, size_t astep, int m, double* b, size_t bstep, int n);
+
+CV_EXPORTS void exp(const float* src, float* dst, int n);
+CV_EXPORTS void exp(const double* src, double* dst, int n);
+CV_EXPORTS void log(const float* src, float* dst, int n);
+CV_EXPORTS void log(const double* src, double* dst, int n);
+
+CV_EXPORTS void fastAtan2(const float* y, const float* x, float* dst, int n, bool angleInDegrees);
+CV_EXPORTS void magnitude(const float* x, const float* y, float* dst, int n);
+CV_EXPORTS void magnitude(const double* x, const double* y, double* dst, int n);
+CV_EXPORTS void sqrt(const float* src, float* dst, int len);
+CV_EXPORTS void sqrt(const double* src, double* dst, int len);
+CV_EXPORTS void invSqrt(const float* src, float* dst, int len);
+CV_EXPORTS void invSqrt(const double* src, double* dst, int len);
+
+//! @endcond
+
+}} //cv::hal
+
+#endif //OPENCV_HAL_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/core/hal/interface.h Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,182 @@
+#ifndef OPENCV_CORE_HAL_INTERFACE_H
+#define OPENCV_CORE_HAL_INTERFACE_H
+
+//! @addtogroup core_hal_interface
+//! @{
+
+//! @name Return codes
+//! @{
+#define CV_HAL_ERROR_OK 0
+#define CV_HAL_ERROR_NOT_IMPLEMENTED 1
+#define CV_HAL_ERROR_UNKNOWN -1
+//! @}
+
+#ifdef __cplusplus
+#include <cstddef>
+#else
+#include <stddef.h>
+#include <stdbool.h>
+#endif
+
+//! @name Data types
+//! primitive types
+//! - schar - signed 1 byte integer
+//! - uchar - unsigned 1 byte integer
+//! - short - signed 2 byte integer
+//! - ushort - unsigned 2 byte integer
+//! - int - signed 4 byte integer
+//! - uint - unsigned 4 byte integer
+//! - int64 - signed 8 byte integer
+//! - uint64 - unsigned 8 byte integer
+//! @{
+#if !defined _MSC_VER && !defined __BORLANDC__
+# if defined __cplusplus && __cplusplus >= 201103L && !defined __APPLE__
+# include <cstdint>
+ #ifndef __MBED__
+ typedef std::uint32_t uint;
+ # endif
+# else
+# include <stdint.h>
+ #ifndef __MBED__
+ typedef uint32_t uint;
+ # endif
+# endif
+#else
+ typedef unsigned uint;
+#endif
+
+typedef signed char schar;
+
+#ifndef __IPL_H__
+ typedef unsigned char uchar;
+ typedef unsigned short ushort;
+#endif
+
+#if defined _MSC_VER || defined __BORLANDC__
+ typedef __int64 int64;
+ typedef unsigned __int64 uint64;
+# define CV_BIG_INT(n) n##I64
+# define CV_BIG_UINT(n) n##UI64
+#else
+ typedef int64_t int64;
+ typedef uint64_t uint64;
+# define CV_BIG_INT(n) n##LL
+# define CV_BIG_UINT(n) n##ULL
+#endif
+
+#define CV_CN_MAX 512
+#define CV_CN_SHIFT 3
+#define CV_DEPTH_MAX (1 << CV_CN_SHIFT)
+
+#define CV_8U 0
+#define CV_8S 1
+#define CV_16U 2
+#define CV_16S 3
+#define CV_32S 4
+#define CV_32F 5
+#define CV_64F 6
+#define CV_USRTYPE1 7
+
+#define CV_MAT_DEPTH_MASK (CV_DEPTH_MAX - 1)
+#define CV_MAT_DEPTH(flags) ((flags) & CV_MAT_DEPTH_MASK)
+
+#define CV_MAKETYPE(depth,cn) (CV_MAT_DEPTH(depth) + (((cn)-1) << CV_CN_SHIFT))
+#define CV_MAKE_TYPE CV_MAKETYPE
+
+#define CV_8UC1 CV_MAKETYPE(CV_8U,1)
+#define CV_8UC2 CV_MAKETYPE(CV_8U,2)
+#define CV_8UC3 CV_MAKETYPE(CV_8U,3)
+#define CV_8UC4 CV_MAKETYPE(CV_8U,4)
+#define CV_8UC(n) CV_MAKETYPE(CV_8U,(n))
+
+#define CV_8SC1 CV_MAKETYPE(CV_8S,1)
+#define CV_8SC2 CV_MAKETYPE(CV_8S,2)
+#define CV_8SC3 CV_MAKETYPE(CV_8S,3)
+#define CV_8SC4 CV_MAKETYPE(CV_8S,4)
+#define CV_8SC(n) CV_MAKETYPE(CV_8S,(n))
+
+#define CV_16UC1 CV_MAKETYPE(CV_16U,1)
+#define CV_16UC2 CV_MAKETYPE(CV_16U,2)
+#define CV_16UC3 CV_MAKETYPE(CV_16U,3)
+#define CV_16UC4 CV_MAKETYPE(CV_16U,4)
+#define CV_16UC(n) CV_MAKETYPE(CV_16U,(n))
+
+#define CV_16SC1 CV_MAKETYPE(CV_16S,1)
+#define CV_16SC2 CV_MAKETYPE(CV_16S,2)
+#define CV_16SC3 CV_MAKETYPE(CV_16S,3)
+#define CV_16SC4 CV_MAKETYPE(CV_16S,4)
+#define CV_16SC(n) CV_MAKETYPE(CV_16S,(n))
+
+#define CV_32SC1 CV_MAKETYPE(CV_32S,1)
+#define CV_32SC2 CV_MAKETYPE(CV_32S,2)
+#define CV_32SC3 CV_MAKETYPE(CV_32S,3)
+#define CV_32SC4 CV_MAKETYPE(CV_32S,4)
+#define CV_32SC(n) CV_MAKETYPE(CV_32S,(n))
+
+#define CV_32FC1 CV_MAKETYPE(CV_32F,1)
+#define CV_32FC2 CV_MAKETYPE(CV_32F,2)
+#define CV_32FC3 CV_MAKETYPE(CV_32F,3)
+#define CV_32FC4 CV_MAKETYPE(CV_32F,4)
+#define CV_32FC(n) CV_MAKETYPE(CV_32F,(n))
+
+#define CV_64FC1 CV_MAKETYPE(CV_64F,1)
+#define CV_64FC2 CV_MAKETYPE(CV_64F,2)
+#define CV_64FC3 CV_MAKETYPE(CV_64F,3)
+#define CV_64FC4 CV_MAKETYPE(CV_64F,4)
+#define CV_64FC(n) CV_MAKETYPE(CV_64F,(n))
+//! @}
+
+//! @name Comparison operation
+//! @sa cv::CmpTypes
+//! @{
+#define CV_HAL_CMP_EQ 0
+#define CV_HAL_CMP_GT 1
+#define CV_HAL_CMP_GE 2
+#define CV_HAL_CMP_LT 3
+#define CV_HAL_CMP_LE 4
+#define CV_HAL_CMP_NE 5
+//! @}
+
+//! @name Border processing modes
+//! @sa cv::BorderTypes
+//! @{
+#define CV_HAL_BORDER_CONSTANT 0
+#define CV_HAL_BORDER_REPLICATE 1
+#define CV_HAL_BORDER_REFLECT 2
+#define CV_HAL_BORDER_WRAP 3
+#define CV_HAL_BORDER_REFLECT_101 4
+#define CV_HAL_BORDER_TRANSPARENT 5
+#define CV_HAL_BORDER_ISOLATED 16
+//! @}
+
+//! @name DFT flags
+//! @{
+#define CV_HAL_DFT_INVERSE 1
+#define CV_HAL_DFT_SCALE 2
+#define CV_HAL_DFT_ROWS 4
+#define CV_HAL_DFT_COMPLEX_OUTPUT 16
+#define CV_HAL_DFT_REAL_OUTPUT 32
+#define CV_HAL_DFT_TWO_STAGE 64
+#define CV_HAL_DFT_STAGE_COLS 128
+#define CV_HAL_DFT_IS_CONTINUOUS 512
+#define CV_HAL_DFT_IS_INPLACE 1024
+//! @}
+
+//! @name SVD flags
+//! @{
+#define CV_HAL_SVD_NO_UV 1
+#define CV_HAL_SVD_SHORT_UV 2
+#define CV_HAL_SVD_MODIFY_A 4
+#define CV_HAL_SVD_FULL_UV 8
+//! @}
+
+//! @name Gemm flags
+//! @{
+#define CV_HAL_GEMM_1_T 1
+#define CV_HAL_GEMM_2_T 2
+#define CV_HAL_GEMM_3_T 4
+//! @}
+
+//! @}
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/core/hal/intrin.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,414 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
+// Copyright (C) 2015, Itseez Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_HAL_INTRIN_HPP
+#define OPENCV_HAL_INTRIN_HPP
+
+#include <cmath>
+#include <float.h>
+#include <stdlib.h>
+#include "opencv2/core/cvdef.h"
+
+#define OPENCV_HAL_ADD(a, b) ((a) + (b))
+#define OPENCV_HAL_AND(a, b) ((a) & (b))
+#define OPENCV_HAL_NOP(a) (a)
+#define OPENCV_HAL_1ST(a, b) (a)
+
+// unlike HAL API, which is in cv::hal,
+// we put intrinsics into cv namespace to make its
+// access from within opencv code more accessible
+namespace cv {
+
+//! @addtogroup core_hal_intrin
+//! @{
+
+//! @cond IGNORED
+template<typename _Tp> struct V_TypeTraits
+{
+ typedef _Tp int_type;
+ typedef _Tp uint_type;
+ typedef _Tp abs_type;
+ typedef _Tp sum_type;
+
+ enum { delta = 0, shift = 0 };
+
+ static int_type reinterpret_int(_Tp x) { return x; }
+ static uint_type reinterpet_uint(_Tp x) { return x; }
+ static _Tp reinterpret_from_int(int_type x) { return (_Tp)x; }
+};
+
+template<> struct V_TypeTraits<uchar>
+{
+ typedef uchar value_type;
+ typedef schar int_type;
+ typedef uchar uint_type;
+ typedef uchar abs_type;
+ typedef int sum_type;
+
+ typedef ushort w_type;
+ typedef unsigned q_type;
+
+ enum { delta = 128, shift = 8 };
+
+ static int_type reinterpret_int(value_type x) { return (int_type)x; }
+ static uint_type reinterpret_uint(value_type x) { return (uint_type)x; }
+ static value_type reinterpret_from_int(int_type x) { return (value_type)x; }
+};
+
+template<> struct V_TypeTraits<schar>
+{
+ typedef schar value_type;
+ typedef schar int_type;
+ typedef uchar uint_type;
+ typedef uchar abs_type;
+ typedef int sum_type;
+
+ typedef short w_type;
+ typedef int q_type;
+
+ enum { delta = 128, shift = 8 };
+
+ static int_type reinterpret_int(value_type x) { return (int_type)x; }
+ static uint_type reinterpret_uint(value_type x) { return (uint_type)x; }
+ static value_type reinterpret_from_int(int_type x) { return (value_type)x; }
+};
+
+template<> struct V_TypeTraits<ushort>
+{
+ typedef ushort value_type;
+ typedef short int_type;
+ typedef ushort uint_type;
+ typedef ushort abs_type;
+ typedef int sum_type;
+
+ typedef unsigned w_type;
+ typedef uchar nu_type;
+
+ enum { delta = 32768, shift = 16 };
+
+ static int_type reinterpret_int(value_type x) { return (int_type)x; }
+ static uint_type reinterpret_uint(value_type x) { return (uint_type)x; }
+ static value_type reinterpret_from_int(int_type x) { return (value_type)x; }
+};
+
+template<> struct V_TypeTraits<short>
+{
+ typedef short value_type;
+ typedef short int_type;
+ typedef ushort uint_type;
+ typedef ushort abs_type;
+ typedef int sum_type;
+
+ typedef int w_type;
+ typedef uchar nu_type;
+ typedef schar n_type;
+
+ enum { delta = 128, shift = 8 };
+
+ static int_type reinterpret_int(value_type x) { return (int_type)x; }
+ static uint_type reinterpret_uint(value_type x) { return (uint_type)x; }
+ static value_type reinterpret_from_int(int_type x) { return (value_type)x; }
+};
+
+template<> struct V_TypeTraits<unsigned>
+{
+ typedef unsigned value_type;
+ typedef int int_type;
+ typedef unsigned uint_type;
+ typedef unsigned abs_type;
+ typedef unsigned sum_type;
+
+ typedef uint64 w_type;
+ typedef ushort nu_type;
+
+ static int_type reinterpret_int(value_type x) { return (int_type)x; }
+ static uint_type reinterpret_uint(value_type x) { return (uint_type)x; }
+ static value_type reinterpret_from_int(int_type x) { return (value_type)x; }
+};
+
+template<> struct V_TypeTraits<int>
+{
+ typedef int value_type;
+ typedef int int_type;
+ typedef unsigned uint_type;
+ typedef unsigned abs_type;
+ typedef int sum_type;
+
+ typedef int64 w_type;
+ typedef short n_type;
+ typedef ushort nu_type;
+
+ static int_type reinterpret_int(value_type x) { return (int_type)x; }
+ static uint_type reinterpret_uint(value_type x) { return (uint_type)x; }
+ static value_type reinterpret_from_int(int_type x) { return (value_type)x; }
+};
+
+template<> struct V_TypeTraits<uint64>
+{
+ typedef uint64 value_type;
+ typedef int64 int_type;
+ typedef uint64 uint_type;
+ typedef uint64 abs_type;
+ typedef uint64 sum_type;
+
+ typedef unsigned nu_type;
+
+ static int_type reinterpret_int(value_type x) { return (int_type)x; }
+ static uint_type reinterpret_uint(value_type x) { return (uint_type)x; }
+ static value_type reinterpret_from_int(int_type x) { return (value_type)x; }
+};
+
+template<> struct V_TypeTraits<int64>
+{
+ typedef int64 value_type;
+ typedef int64 int_type;
+ typedef uint64 uint_type;
+ typedef uint64 abs_type;
+ typedef int64 sum_type;
+
+ typedef int nu_type;
+
+ static int_type reinterpret_int(value_type x) { return (int_type)x; }
+ static uint_type reinterpret_uint(value_type x) { return (uint_type)x; }
+ static value_type reinterpret_from_int(int_type x) { return (value_type)x; }
+};
+
+
+template<> struct V_TypeTraits<float>
+{
+ typedef float value_type;
+ typedef int int_type;
+ typedef unsigned uint_type;
+ typedef float abs_type;
+ typedef float sum_type;
+
+ typedef double w_type;
+
+ static int_type reinterpret_int(value_type x)
+ {
+ Cv32suf u;
+ u.f = x;
+ return u.i;
+ }
+ static uint_type reinterpet_uint(value_type x)
+ {
+ Cv32suf u;
+ u.f = x;
+ return u.u;
+ }
+ static value_type reinterpret_from_int(int_type x)
+ {
+ Cv32suf u;
+ u.i = x;
+ return u.f;
+ }
+};
+
+template<> struct V_TypeTraits<double>
+{
+ typedef double value_type;
+ typedef int64 int_type;
+ typedef uint64 uint_type;
+ typedef double abs_type;
+ typedef double sum_type;
+ static int_type reinterpret_int(value_type x)
+ {
+ Cv64suf u;
+ u.f = x;
+ return u.i;
+ }
+ static uint_type reinterpet_uint(value_type x)
+ {
+ Cv64suf u;
+ u.f = x;
+ return u.u;
+ }
+ static value_type reinterpret_from_int(int_type x)
+ {
+ Cv64suf u;
+ u.i = x;
+ return u.f;
+ }
+};
+
+template <typename T> struct V_SIMD128Traits
+{
+ enum { nlanes = 16 / sizeof(T) };
+};
+
+//! @endcond
+
+//! @}
+
+}
+
+#ifdef CV_DOXYGEN
+# undef CV_SSE2
+# undef CV_NEON
+#endif
+
+#if CV_SSE2
+
+#include "opencv2/core/hal/intrin_sse.hpp"
+
+#elif CV_NEON
+
+#include "opencv2/core/hal/intrin_neon.hpp"
+
+#else
+
+#include "opencv2/core/hal/intrin_cpp.hpp"
+
+#endif
+
+//! @addtogroup core_hal_intrin
+//! @{
+
+#ifndef CV_SIMD128
+//! Set to 1 if current compiler supports vector extensions (NEON or SSE is enabled)
+#define CV_SIMD128 0
+#endif
+
+#ifndef CV_SIMD128_64F
+//! Set to 1 if current intrinsics implementation supports 64-bit float vectors
+#define CV_SIMD128_64F 0
+#endif
+
+//! @}
+
+//==================================================================================================
+
+//! @cond IGNORED
+
+namespace cv {
+
+template <typename R> struct V_RegTrait128;
+
+template <> struct V_RegTrait128<uchar> {
+ typedef v_uint8x16 reg;
+ typedef v_uint16x8 w_reg;
+ typedef v_uint32x4 q_reg;
+ typedef v_uint8x16 u_reg;
+ static v_uint8x16 zero() { return v_setzero_u8(); }
+ static v_uint8x16 all(uchar val) { return v_setall_u8(val); }
+};
+
+template <> struct V_RegTrait128<schar> {
+ typedef v_int8x16 reg;
+ typedef v_int16x8 w_reg;
+ typedef v_int32x4 q_reg;
+ typedef v_uint8x16 u_reg;
+ static v_int8x16 zero() { return v_setzero_s8(); }
+ static v_int8x16 all(schar val) { return v_setall_s8(val); }
+};
+
+template <> struct V_RegTrait128<ushort> {
+ typedef v_uint16x8 reg;
+ typedef v_uint32x4 w_reg;
+ typedef v_int16x8 int_reg;
+ typedef v_uint16x8 u_reg;
+ static v_uint16x8 zero() { return v_setzero_u16(); }
+ static v_uint16x8 all(ushort val) { return v_setall_u16(val); }
+};
+
+template <> struct V_RegTrait128<short> {
+ typedef v_int16x8 reg;
+ typedef v_int32x4 w_reg;
+ typedef v_uint16x8 u_reg;
+ static v_int16x8 zero() { return v_setzero_s16(); }
+ static v_int16x8 all(short val) { return v_setall_s16(val); }
+};
+
+template <> struct V_RegTrait128<unsigned> {
+ typedef v_uint32x4 reg;
+ typedef v_uint64x2 w_reg;
+ typedef v_int32x4 int_reg;
+ typedef v_uint32x4 u_reg;
+ static v_uint32x4 zero() { return v_setzero_u32(); }
+ static v_uint32x4 all(unsigned val) { return v_setall_u32(val); }
+};
+
+template <> struct V_RegTrait128<int> {
+ typedef v_int32x4 reg;
+ typedef v_int64x2 w_reg;
+ typedef v_uint32x4 u_reg;
+ static v_int32x4 zero() { return v_setzero_s32(); }
+ static v_int32x4 all(int val) { return v_setall_s32(val); }
+};
+
+template <> struct V_RegTrait128<uint64> {
+ typedef v_uint64x2 reg;
+ static v_uint64x2 zero() { return v_setzero_u64(); }
+ static v_uint64x2 all(uint64 val) { return v_setall_u64(val); }
+};
+
+template <> struct V_RegTrait128<int64> {
+ typedef v_int64x2 reg;
+ static v_int64x2 zero() { return v_setzero_s64(); }
+ static v_int64x2 all(int64 val) { return v_setall_s64(val); }
+};
+
+template <> struct V_RegTrait128<float> {
+ typedef v_float32x4 reg;
+ typedef v_int32x4 int_reg;
+ typedef v_float32x4 u_reg;
+ static v_float32x4 zero() { return v_setzero_f32(); }
+ static v_float32x4 all(float val) { return v_setall_f32(val); }
+};
+
+#if CV_SIMD128_64F
+template <> struct V_RegTrait128<double> {
+ typedef v_float64x2 reg;
+ typedef v_int32x4 int_reg;
+ typedef v_float64x2 u_reg;
+ static v_float64x2 zero() { return v_setzero_f64(); }
+ static v_float64x2 all(double val) { return v_setall_f64(val); }
+};
+#endif
+
+} // cv::
+
+//! @endcond
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/core/hal/intrin_cpp.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,1790 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
+// Copyright (C) 2015, Itseez Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_HAL_INTRIN_CPP_HPP
+#define OPENCV_HAL_INTRIN_CPP_HPP
+
+#include <limits>
+#include <cstring>
+#include <algorithm>
+#include "opencv2/core/saturate.hpp"
+
+namespace cv
+{
+
+/** @addtogroup core_hal_intrin
+
+"Universal intrinsics" is a types and functions set intended to simplify vectorization of code on
+different platforms. Currently there are two supported SIMD extensions: __SSE/SSE2__ on x86
+architectures and __NEON__ on ARM architectures, both allow working with 128 bit registers
+containing packed values of different types. In case when there is no SIMD extension available
+during compilation, fallback C++ implementation of intrinsics will be chosen and code will work as
+expected although it could be slower.
+
+### Types
+
+There are several types representing 128-bit register as a vector of packed values, each type is
+implemented as a structure based on a one SIMD register.
+
+- cv::v_uint8x16 and cv::v_int8x16: sixteen 8-bit integer values (unsigned/signed) - char
+- cv::v_uint16x8 and cv::v_int16x8: eight 16-bit integer values (unsigned/signed) - short
+- cv::v_uint32x4 and cv::v_int32x4: four 32-bit integer values (unsgined/signed) - int
+- cv::v_uint64x2 and cv::v_int64x2: two 64-bit integer values (unsigned/signed) - int64
+- cv::v_float32x4: four 32-bit floating point values (signed) - float
+- cv::v_float64x2: two 64-bit floating point valies (signed) - double
+
+@note
+cv::v_float64x2 is not implemented in NEON variant, if you want to use this type, don't forget to
+check the CV_SIMD128_64F preprocessor definition:
+@code
+#if CV_SIMD128_64F
+//...
+#endif
+@endcode
+
+### Load and store operations
+
+These operations allow to set contents of the register explicitly or by loading it from some memory
+block and to save contents of the register to memory block.
+
+- Constructors:
+@ref v_reg::v_reg(const _Tp *ptr) "from memory",
+@ref v_reg::v_reg(_Tp s0, _Tp s1) "from two values", ...
+- Other create methods:
+@ref v_setall_s8, @ref v_setall_u8, ...,
+@ref v_setzero_u8, @ref v_setzero_s8, ...
+- Memory operations:
+@ref v_load, @ref v_load_aligned, @ref v_load_halves,
+@ref v_store, @ref v_store_aligned,
+@ref v_store_high, @ref v_store_low
+
+### Value reordering
+
+These operations allow to reorder or recombine elements in one or multiple vectors.
+
+- Interleave, deinterleave (2, 3 and 4 channels): @ref v_load_deinterleave, @ref v_store_interleave
+- Expand: @ref v_load_expand, @ref v_load_expand_q, @ref v_expand
+- Pack: @ref v_pack, @ref v_pack_u, @ref v_rshr_pack, @ref v_rshr_pack_u,
+@ref v_pack_store, @ref v_pack_u_store, @ref v_rshr_pack_store, @ref v_rshr_pack_u_store
+- Recombine: @ref v_zip, @ref v_recombine, @ref v_combine_low, @ref v_combine_high
+- Extract: @ref v_extract
+
+
+### Arithmetic, bitwise and comparison operations
+
+Element-wise binary and unary operations.
+
+- Arithmetics:
+@ref operator +(const v_reg &a, const v_reg &b) "+",
+@ref operator -(const v_reg &a, const v_reg &b) "-",
+@ref operator *(const v_reg &a, const v_reg &b) "*",
+@ref operator /(const v_reg &a, const v_reg &b) "/",
+@ref v_mul_expand
+
+- Non-saturating arithmetics: @ref v_add_wrap, @ref v_sub_wrap
+
+- Bitwise shifts:
+@ref operator <<(const v_reg &a, int s) "<<",
+@ref operator >>(const v_reg &a, int s) ">>",
+@ref v_shl, @ref v_shr
+
+- Bitwise logic:
+@ref operator&(const v_reg &a, const v_reg &b) "&",
+@ref operator |(const v_reg &a, const v_reg &b) "|",
+@ref operator ^(const v_reg &a, const v_reg &b) "^",
+@ref operator ~(const v_reg &a) "~"
+
+- Comparison:
+@ref operator >(const v_reg &a, const v_reg &b) ">",
+@ref operator >=(const v_reg &a, const v_reg &b) ">=",
+@ref operator <(const v_reg &a, const v_reg &b) "<",
+@ref operator <=(const v_reg &a, const v_reg &b) "<=",
+@ref operator==(const v_reg &a, const v_reg &b) "==",
+@ref operator !=(const v_reg &a, const v_reg &b) "!="
+
+- min/max: @ref v_min, @ref v_max
+
+### Reduce and mask
+
+Most of these operations return only one value.
+
+- Reduce: @ref v_reduce_min, @ref v_reduce_max, @ref v_reduce_sum
+- Mask: @ref v_signmask, @ref v_check_all, @ref v_check_any, @ref v_select
+
+### Other math
+
+- Some frequent operations: @ref v_sqrt, @ref v_invsqrt, @ref v_magnitude, @ref v_sqr_magnitude
+- Absolute values: @ref v_abs, @ref v_absdiff
+
+### Conversions
+
+Different type conversions and casts:
+
+- Rounding: @ref v_round, @ref v_floor, @ref v_ceil, @ref v_trunc,
+- To float: @ref v_cvt_f32, @ref v_cvt_f64
+- Reinterpret: @ref v_reinterpret_as_u8, @ref v_reinterpret_as_s8, ...
+
+### Matrix operations
+
+In these operations vectors represent matrix rows/columns: @ref v_dotprod, @ref v_matmul, @ref v_transpose4x4
+
+### Usability
+
+Most operations are implemented only for some subset of the available types, following matrices
+shows the applicability of different operations to the types.
+
+Regular integers:
+
+| Operations\\Types | uint 8x16 | int 8x16 | uint 16x8 | int 16x8 | uint 32x4 | int 32x4 |
+|-------------------|:-:|:-:|:-:|:-:|:-:|:-:|
+|load, store | x | x | x | x | x | x |
+|interleave | x | x | x | x | x | x |
+|expand | x | x | x | x | x | x |
+|expand_q | x | x | | | | |
+|add, sub | x | x | x | x | x | x |
+|add_wrap, sub_wrap | x | x | x | x | | |
+|mul | | | x | x | x | x |
+|mul_expand | | | x | x | x | |
+|compare | x | x | x | x | x | x |
+|shift | | | x | x | x | x |
+|dotprod | | | | x | | |
+|logical | x | x | x | x | x | x |
+|min, max | x | x | x | x | x | x |
+|absdiff | x | x | x | x | x | x |
+|reduce | | | | | x | x |
+|mask | x | x | x | x | x | x |
+|pack | x | x | x | x | x | x |
+|pack_u | x | | x | | | |
+|unpack | x | x | x | x | x | x |
+|extract | x | x | x | x | x | x |
+|cvt_flt32 | | | | | | x |
+|cvt_flt64 | | | | | | x |
+|transpose4x4 | | | | | x | x |
+
+Big integers:
+
+| Operations\\Types | uint 64x2 | int 64x2 |
+|-------------------|:-:|:-:|
+|load, store | x | x |
+|add, sub | x | x |
+|shift | x | x |
+|logical | x | x |
+|extract | x | x |
+
+Floating point:
+
+| Operations\\Types | float 32x4 | float 64x2 |
+|-------------------|:-:|:-:|
+|load, store | x | x |
+|interleave | x | |
+|add, sub | x | x |
+|mul | x | x |
+|div | x | x |
+|compare | x | x |
+|min, max | x | x |
+|absdiff | x | x |
+|reduce | x | |
+|mask | x | x |
+|unpack | x | x |
+|cvt_flt32 | | x |
+|cvt_flt64 | x | |
+|sqrt, abs | x | x |
+|float math | x | x |
+|transpose4x4 | x | |
+
+
+ @{ */
+
+template<typename _Tp, int n> struct v_reg
+{
+//! @cond IGNORED
+ typedef _Tp lane_type;
+ typedef v_reg<typename V_TypeTraits<_Tp>::int_type, n> int_vec;
+ typedef v_reg<typename V_TypeTraits<_Tp>::abs_type, n> abs_vec;
+ enum { nlanes = n };
+// !@endcond
+
+ /** @brief Constructor
+
+ Initializes register with data from memory
+ @param ptr pointer to memory block with data for register */
+ explicit v_reg(const _Tp* ptr) { for( int i = 0; i < n; i++ ) s[i] = ptr[i]; }
+
+ /** @brief Constructor
+
+ Initializes register with two 64-bit values */
+ v_reg(_Tp s0, _Tp s1) { s[0] = s0; s[1] = s1; }
+
+ /** @brief Constructor
+
+ Initializes register with four 32-bit values */
+ v_reg(_Tp s0, _Tp s1, _Tp s2, _Tp s3) { s[0] = s0; s[1] = s1; s[2] = s2; s[3] = s3; }
+
+ /** @brief Constructor
+
+ Initializes register with eight 16-bit values */
+ v_reg(_Tp s0, _Tp s1, _Tp s2, _Tp s3,
+ _Tp s4, _Tp s5, _Tp s6, _Tp s7)
+ {
+ s[0] = s0; s[1] = s1; s[2] = s2; s[3] = s3;
+ s[4] = s4; s[5] = s5; s[6] = s6; s[7] = s7;
+ }
+
+ /** @brief Constructor
+
+ Initializes register with sixteen 8-bit values */
+ v_reg(_Tp s0, _Tp s1, _Tp s2, _Tp s3,
+ _Tp s4, _Tp s5, _Tp s6, _Tp s7,
+ _Tp s8, _Tp s9, _Tp s10, _Tp s11,
+ _Tp s12, _Tp s13, _Tp s14, _Tp s15)
+ {
+ s[0] = s0; s[1] = s1; s[2] = s2; s[3] = s3;
+ s[4] = s4; s[5] = s5; s[6] = s6; s[7] = s7;
+ s[8] = s8; s[9] = s9; s[10] = s10; s[11] = s11;
+ s[12] = s12; s[13] = s13; s[14] = s14; s[15] = s15;
+ }
+
+ /** @brief Default constructor
+
+ Does not initialize anything*/
+ v_reg() {}
+
+ /** @brief Copy constructor */
+ v_reg(const v_reg<_Tp, n> & r)
+ {
+ for( int i = 0; i < n; i++ )
+ s[i] = r.s[i];
+ }
+ /** @brief Access first value
+
+ Returns value of the first lane according to register type, for example:
+ @code{.cpp}
+ v_int32x4 r(1, 2, 3, 4);
+ int v = r.get0(); // returns 1
+ v_uint64x2 r(1, 2);
+ uint64_t v = r.get0(); // returns 1
+ @endcode
+ */
+ _Tp get0() const { return s[0]; }
+
+//! @cond IGNORED
+ _Tp get(const int i) const { return s[i]; }
+ v_reg<_Tp, n> high() const
+ {
+ v_reg<_Tp, n> c;
+ int i;
+ for( i = 0; i < n/2; i++ )
+ {
+ c.s[i] = s[i+(n/2)];
+ c.s[i+(n/2)] = 0;
+ }
+ return c;
+ }
+
+ static v_reg<_Tp, n> zero()
+ {
+ v_reg<_Tp, n> c;
+ for( int i = 0; i < n; i++ )
+ c.s[i] = (_Tp)0;
+ return c;
+ }
+
+ static v_reg<_Tp, n> all(_Tp s)
+ {
+ v_reg<_Tp, n> c;
+ for( int i = 0; i < n; i++ )
+ c.s[i] = s;
+ return c;
+ }
+
+ template<typename _Tp2, int n2> v_reg<_Tp2, n2> reinterpret_as() const
+ {
+ size_t bytes = std::min(sizeof(_Tp2)*n2, sizeof(_Tp)*n);
+ v_reg<_Tp2, n2> c;
+ std::memcpy(&c.s[0], &s[0], bytes);
+ return c;
+ }
+
+ _Tp s[n];
+//! @endcond
+};
+
+/** @brief Sixteen 8-bit unsigned integer values */
+typedef v_reg<uchar, 16> v_uint8x16;
+/** @brief Sixteen 8-bit signed integer values */
+typedef v_reg<schar, 16> v_int8x16;
+/** @brief Eight 16-bit unsigned integer values */
+typedef v_reg<ushort, 8> v_uint16x8;
+/** @brief Eight 16-bit signed integer values */
+typedef v_reg<short, 8> v_int16x8;
+/** @brief Four 32-bit unsigned integer values */
+typedef v_reg<unsigned, 4> v_uint32x4;
+/** @brief Four 32-bit signed integer values */
+typedef v_reg<int, 4> v_int32x4;
+/** @brief Four 32-bit floating point values (single precision) */
+typedef v_reg<float, 4> v_float32x4;
+/** @brief Two 64-bit floating point values (double precision) */
+typedef v_reg<double, 2> v_float64x2;
+/** @brief Two 64-bit unsigned integer values */
+typedef v_reg<uint64, 2> v_uint64x2;
+/** @brief Two 64-bit signed integer values */
+typedef v_reg<int64, 2> v_int64x2;
+
+//! @brief Helper macro
+//! @ingroup core_hal_intrin_impl
+#define OPENCV_HAL_IMPL_BIN_OP(bin_op) \
+template<typename _Tp, int n> inline v_reg<_Tp, n> \
+ operator bin_op (const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b) \
+{ \
+ v_reg<_Tp, n> c; \
+ for( int i = 0; i < n; i++ ) \
+ c.s[i] = saturate_cast<_Tp>(a.s[i] bin_op b.s[i]); \
+ return c; \
+} \
+template<typename _Tp, int n> inline v_reg<_Tp, n>& \
+ operator bin_op##= (v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b) \
+{ \
+ for( int i = 0; i < n; i++ ) \
+ a.s[i] = saturate_cast<_Tp>(a.s[i] bin_op b.s[i]); \
+ return a; \
+}
+
+/** @brief Add values
+
+For all types. */
+OPENCV_HAL_IMPL_BIN_OP(+)
+
+/** @brief Subtract values
+
+For all types. */
+OPENCV_HAL_IMPL_BIN_OP(-)
+
+/** @brief Multiply values
+
+For 16- and 32-bit integer types and floating types. */
+OPENCV_HAL_IMPL_BIN_OP(*)
+
+/** @brief Divide values
+
+For floating types only. */
+OPENCV_HAL_IMPL_BIN_OP(/)
+
+//! @brief Helper macro
+//! @ingroup core_hal_intrin_impl
+#define OPENCV_HAL_IMPL_BIT_OP(bit_op) \
+template<typename _Tp, int n> inline v_reg<_Tp, n> operator bit_op \
+ (const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b) \
+{ \
+ v_reg<_Tp, n> c; \
+ typedef typename V_TypeTraits<_Tp>::int_type itype; \
+ for( int i = 0; i < n; i++ ) \
+ c.s[i] = V_TypeTraits<_Tp>::reinterpret_from_int((itype)(V_TypeTraits<_Tp>::reinterpret_int(a.s[i]) bit_op \
+ V_TypeTraits<_Tp>::reinterpret_int(b.s[i]))); \
+ return c; \
+} \
+template<typename _Tp, int n> inline v_reg<_Tp, n>& operator \
+ bit_op##= (v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b) \
+{ \
+ typedef typename V_TypeTraits<_Tp>::int_type itype; \
+ for( int i = 0; i < n; i++ ) \
+ a.s[i] = V_TypeTraits<_Tp>::reinterpret_from_int((itype)(V_TypeTraits<_Tp>::reinterpret_int(a.s[i]) bit_op \
+ V_TypeTraits<_Tp>::reinterpret_int(b.s[i]))); \
+ return a; \
+}
+
+/** @brief Bitwise AND
+
+Only for integer types. */
+OPENCV_HAL_IMPL_BIT_OP(&)
+
+/** @brief Bitwise OR
+
+Only for integer types. */
+OPENCV_HAL_IMPL_BIT_OP(|)
+
+/** @brief Bitwise XOR
+
+Only for integer types.*/
+OPENCV_HAL_IMPL_BIT_OP(^)
+
+/** @brief Bitwise NOT
+
+Only for integer types.*/
+template<typename _Tp, int n> inline v_reg<_Tp, n> operator ~ (const v_reg<_Tp, n>& a)
+{
+ v_reg<_Tp, n> c;
+ for( int i = 0; i < n; i++ )
+ {
+ c.s[i] = V_TypeTraits<_Tp>::reinterpret_from_int(~V_TypeTraits<_Tp>::reinterpret_int(a.s[i]));
+ }
+ return c;
+}
+
+//! @brief Helper macro
+//! @ingroup core_hal_intrin_impl
+#define OPENCV_HAL_IMPL_MATH_FUNC(func, cfunc, _Tp2) \
+template<typename _Tp, int n> inline v_reg<_Tp2, n> func(const v_reg<_Tp, n>& a) \
+{ \
+ v_reg<_Tp2, n> c; \
+ for( int i = 0; i < n; i++ ) \
+ c.s[i] = cfunc(a.s[i]); \
+ return c; \
+}
+
+/** @brief Square root of elements
+
+Only for floating point types.*/
+OPENCV_HAL_IMPL_MATH_FUNC(v_sqrt, std::sqrt, _Tp)
+
+//! @cond IGNORED
+OPENCV_HAL_IMPL_MATH_FUNC(v_sin, std::sin, _Tp)
+OPENCV_HAL_IMPL_MATH_FUNC(v_cos, std::cos, _Tp)
+OPENCV_HAL_IMPL_MATH_FUNC(v_exp, std::exp, _Tp)
+OPENCV_HAL_IMPL_MATH_FUNC(v_log, std::log, _Tp)
+//! @endcond
+
+/** @brief Absolute value of elements
+
+Only for floating point types.*/
+OPENCV_HAL_IMPL_MATH_FUNC(v_abs, (typename V_TypeTraits<_Tp>::abs_type)std::abs,
+ typename V_TypeTraits<_Tp>::abs_type)
+
+/** @brief Round elements
+
+Only for floating point types.*/
+OPENCV_HAL_IMPL_MATH_FUNC(v_round, cvRound, int)
+
+/** @brief Floor elements
+
+Only for floating point types.*/
+OPENCV_HAL_IMPL_MATH_FUNC(v_floor, cvFloor, int)
+
+/** @brief Ceil elements
+
+Only for floating point types.*/
+OPENCV_HAL_IMPL_MATH_FUNC(v_ceil, cvCeil, int)
+
+/** @brief Truncate elements
+
+Only for floating point types.*/
+OPENCV_HAL_IMPL_MATH_FUNC(v_trunc, int, int)
+
+//! @brief Helper macro
+//! @ingroup core_hal_intrin_impl
+#define OPENCV_HAL_IMPL_MINMAX_FUNC(func, cfunc) \
+template<typename _Tp, int n> inline v_reg<_Tp, n> func(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b) \
+{ \
+ v_reg<_Tp, n> c; \
+ for( int i = 0; i < n; i++ ) \
+ c.s[i] = cfunc(a.s[i], b.s[i]); \
+ return c; \
+}
+
+//! @brief Helper macro
+//! @ingroup core_hal_intrin_impl
+#define OPENCV_HAL_IMPL_REDUCE_MINMAX_FUNC(func, cfunc) \
+template<typename _Tp, int n> inline _Tp func(const v_reg<_Tp, n>& a) \
+{ \
+ _Tp c = a.s[0]; \
+ for( int i = 1; i < n; i++ ) \
+ c = cfunc(c, a.s[i]); \
+ return c; \
+}
+
+/** @brief Choose min values for each pair
+
+Scheme:
+@code
+{A1 A2 ...}
+{B1 B2 ...}
+--------------
+{min(A1,B1) min(A2,B2) ...}
+@endcode
+For all types except 64-bit integer. */
+OPENCV_HAL_IMPL_MINMAX_FUNC(v_min, std::min)
+
+/** @brief Choose max values for each pair
+
+Scheme:
+@code
+{A1 A2 ...}
+{B1 B2 ...}
+--------------
+{max(A1,B1) max(A2,B2) ...}
+@endcode
+For all types except 64-bit integer. */
+OPENCV_HAL_IMPL_MINMAX_FUNC(v_max, std::max)
+
+/** @brief Find one min value
+
+Scheme:
+@code
+{A1 A2 A3 ...} => min(A1,A2,A3,...)
+@endcode
+For 32-bit integer and 32-bit floating point types. */
+OPENCV_HAL_IMPL_REDUCE_MINMAX_FUNC(v_reduce_min, std::min)
+
+/** @brief Find one max value
+
+Scheme:
+@code
+{A1 A2 A3 ...} => max(A1,A2,A3,...)
+@endcode
+For 32-bit integer and 32-bit floating point types. */
+OPENCV_HAL_IMPL_REDUCE_MINMAX_FUNC(v_reduce_max, std::max)
+
+//! @cond IGNORED
+template<typename _Tp, int n>
+inline void v_minmax( const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b,
+ v_reg<_Tp, n>& minval, v_reg<_Tp, n>& maxval )
+{
+ for( int i = 0; i < n; i++ )
+ {
+ minval.s[i] = std::min(a.s[i], b.s[i]);
+ maxval.s[i] = std::max(a.s[i], b.s[i]);
+ }
+}
+//! @endcond
+
+//! @brief Helper macro
+//! @ingroup core_hal_intrin_impl
+#define OPENCV_HAL_IMPL_CMP_OP(cmp_op) \
+template<typename _Tp, int n> \
+inline v_reg<_Tp, n> operator cmp_op(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b) \
+{ \
+ typedef typename V_TypeTraits<_Tp>::int_type itype; \
+ v_reg<_Tp, n> c; \
+ for( int i = 0; i < n; i++ ) \
+ c.s[i] = V_TypeTraits<_Tp>::reinterpret_from_int((itype)-(int)(a.s[i] cmp_op b.s[i])); \
+ return c; \
+}
+
+/** @brief Less-than comparison
+
+For all types except 64-bit integer values. */
+OPENCV_HAL_IMPL_CMP_OP(<)
+
+/** @brief Greater-than comparison
+
+For all types except 64-bit integer values. */
+OPENCV_HAL_IMPL_CMP_OP(>)
+
+/** @brief Less-than or equal comparison
+
+For all types except 64-bit integer values. */
+OPENCV_HAL_IMPL_CMP_OP(<=)
+
+/** @brief Greater-than or equal comparison
+
+For all types except 64-bit integer values. */
+OPENCV_HAL_IMPL_CMP_OP(>=)
+
+/** @brief Equal comparison
+
+For all types except 64-bit integer values. */
+OPENCV_HAL_IMPL_CMP_OP(==)
+
+/** @brief Not equal comparison
+
+For all types except 64-bit integer values. */
+OPENCV_HAL_IMPL_CMP_OP(!=)
+
+//! @brief Helper macro
+//! @ingroup core_hal_intrin_impl
+#define OPENCV_HAL_IMPL_ADD_SUB_OP(func, bin_op, cast_op, _Tp2) \
+template<typename _Tp, int n> \
+inline v_reg<_Tp2, n> func(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b) \
+{ \
+ typedef _Tp2 rtype; \
+ v_reg<rtype, n> c; \
+ for( int i = 0; i < n; i++ ) \
+ c.s[i] = cast_op(a.s[i] bin_op b.s[i]); \
+ return c; \
+}
+
+/** @brief Add values without saturation
+
+For 8- and 16-bit integer values. */
+OPENCV_HAL_IMPL_ADD_SUB_OP(v_add_wrap, +, (_Tp), _Tp)
+
+/** @brief Subtract values without saturation
+
+For 8- and 16-bit integer values. */
+OPENCV_HAL_IMPL_ADD_SUB_OP(v_sub_wrap, -, (_Tp), _Tp)
+
+//! @cond IGNORED
+template<typename T> inline T _absdiff(T a, T b)
+{
+ return a > b ? a - b : b - a;
+}
+//! @endcond
+
+/** @brief Absolute difference
+
+Returns \f$ |a - b| \f$ converted to corresponding unsigned type.
+Example:
+@code{.cpp}
+v_int32x4 a, b; // {1, 2, 3, 4} and {4, 3, 2, 1}
+v_uint32x4 c = v_absdiff(a, b); // result is {3, 1, 1, 3}
+@endcode
+For 8-, 16-, 32-bit integer source types. */
+template<typename _Tp, int n>
+inline v_reg<typename V_TypeTraits<_Tp>::abs_type, n> v_absdiff(const v_reg<_Tp, n>& a, const v_reg<_Tp, n> & b)
+{
+ typedef typename V_TypeTraits<_Tp>::abs_type rtype;
+ v_reg<rtype, n> c;
+ const rtype mask = std::numeric_limits<_Tp>::is_signed ? (1 << (sizeof(rtype)*8 - 1)) : 0;
+ for( int i = 0; i < n; i++ )
+ {
+ rtype ua = a.s[i] ^ mask;
+ rtype ub = b.s[i] ^ mask;
+ c.s[i] = _absdiff(ua, ub);
+ }
+ return c;
+}
+
+/** @overload
+
+For 32-bit floating point values */
+inline v_float32x4 v_absdiff(const v_float32x4& a, const v_float32x4& b)
+{
+ v_float32x4 c;
+ for( int i = 0; i < c.nlanes; i++ )
+ c.s[i] = _absdiff(a.s[i], b.s[i]);
+ return c;
+}
+
+/** @overload
+
+For 64-bit floating point values */
+inline v_float64x2 v_absdiff(const v_float64x2& a, const v_float64x2& b)
+{
+ v_float64x2 c;
+ for( int i = 0; i < c.nlanes; i++ )
+ c.s[i] = _absdiff(a.s[i], b.s[i]);
+ return c;
+}
+
+/** @brief Inversed square root
+
+Returns \f$ 1/sqrt(a) \f$
+For floating point types only. */
+template<typename _Tp, int n>
+inline v_reg<_Tp, n> v_invsqrt(const v_reg<_Tp, n>& a)
+{
+ v_reg<_Tp, n> c;
+ for( int i = 0; i < n; i++ )
+ c.s[i] = 1.f/std::sqrt(a.s[i]);
+ return c;
+}
+
+/** @brief Magnitude
+
+Returns \f$ sqrt(a^2 + b^2) \f$
+For floating point types only. */
+template<typename _Tp, int n>
+inline v_reg<_Tp, n> v_magnitude(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b)
+{
+ v_reg<_Tp, n> c;
+ for( int i = 0; i < n; i++ )
+ c.s[i] = std::sqrt(a.s[i]*a.s[i] + b.s[i]*b.s[i]);
+ return c;
+}
+
+/** @brief Square of the magnitude
+
+Returns \f$ a^2 + b^2 \f$
+For floating point types only. */
+template<typename _Tp, int n>
+inline v_reg<_Tp, n> v_sqr_magnitude(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b)
+{
+ v_reg<_Tp, n> c;
+ for( int i = 0; i < n; i++ )
+ c.s[i] = a.s[i]*a.s[i] + b.s[i]*b.s[i];
+ return c;
+}
+
+/** @brief Multiply and add
+
+Returns \f$ a*b + c \f$
+For floating point types only. */
+template<typename _Tp, int n>
+inline v_reg<_Tp, n> v_muladd(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b,
+ const v_reg<_Tp, n>& c)
+{
+ v_reg<_Tp, n> d;
+ for( int i = 0; i < n; i++ )
+ d.s[i] = a.s[i]*b.s[i] + c.s[i];
+ return d;
+}
+
+/** @brief Dot product of elements
+
+Multiply values in two registers and sum adjacent result pairs.
+Scheme:
+@code
+ {A1 A2 ...} // 16-bit
+x {B1 B2 ...} // 16-bit
+-------------
+{A1B1+A2B2 ...} // 32-bit
+@endcode
+Implemented only for 16-bit signed source type (v_int16x8).
+*/
+template<typename _Tp, int n> inline v_reg<typename V_TypeTraits<_Tp>::w_type, n/2>
+ v_dotprod(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b)
+{
+ typedef typename V_TypeTraits<_Tp>::w_type w_type;
+ v_reg<w_type, n/2> c;
+ for( int i = 0; i < (n/2); i++ )
+ c.s[i] = (w_type)a.s[i*2]*b.s[i*2] + (w_type)a.s[i*2+1]*b.s[i*2+1];
+ return c;
+}
+
+/** @brief Multiply and expand
+
+Multiply values two registers and store results in two registers with wider pack type.
+Scheme:
+@code
+ {A B C D} // 32-bit
+x {E F G H} // 32-bit
+---------------
+{AE BF} // 64-bit
+ {CG DH} // 64-bit
+@endcode
+Example:
+@code{.cpp}
+v_uint32x4 a, b; // {1,2,3,4} and {2,2,2,2}
+v_uint64x2 c, d; // results
+v_mul_expand(a, b, c, d); // c, d = {2,4}, {6, 8}
+@endcode
+Implemented only for 16- and unsigned 32-bit source types (v_int16x8, v_uint16x8, v_uint32x4).
+*/
+template<typename _Tp, int n> inline void v_mul_expand(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b,
+ v_reg<typename V_TypeTraits<_Tp>::w_type, n/2>& c,
+ v_reg<typename V_TypeTraits<_Tp>::w_type, n/2>& d)
+{
+ typedef typename V_TypeTraits<_Tp>::w_type w_type;
+ for( int i = 0; i < (n/2); i++ )
+ {
+ c.s[i] = (w_type)a.s[i]*b.s[i];
+ d.s[i] = (w_type)a.s[i+(n/2)]*b.s[i+(n/2)];
+ }
+}
+
+//! @cond IGNORED
+template<typename _Tp, int n> inline void v_hsum(const v_reg<_Tp, n>& a,
+ v_reg<typename V_TypeTraits<_Tp>::w_type, n/2>& c)
+{
+ typedef typename V_TypeTraits<_Tp>::w_type w_type;
+ for( int i = 0; i < (n/2); i++ )
+ {
+ c.s[i] = (w_type)a.s[i*2] + a.s[i*2+1];
+ }
+}
+//! @endcond
+
+//! @brief Helper macro
+//! @ingroup core_hal_intrin_impl
+#define OPENCV_HAL_IMPL_SHIFT_OP(shift_op) \
+template<typename _Tp, int n> inline v_reg<_Tp, n> operator shift_op(const v_reg<_Tp, n>& a, int imm) \
+{ \
+ v_reg<_Tp, n> c; \
+ for( int i = 0; i < n; i++ ) \
+ c.s[i] = (_Tp)(a.s[i] shift_op imm); \
+ return c; \
+}
+
+/** @brief Bitwise shift left
+
+For 16-, 32- and 64-bit integer values. */
+OPENCV_HAL_IMPL_SHIFT_OP(<<)
+
+/** @brief Bitwise shift right
+
+For 16-, 32- and 64-bit integer values. */
+OPENCV_HAL_IMPL_SHIFT_OP(>>)
+
+/** @brief Sum packed values
+
+Scheme:
+@code
+{A1 A2 A3 ...} => sum{A1,A2,A3,...}
+@endcode
+For 32-bit integer and 32-bit floating point types.*/
+template<typename _Tp, int n> inline typename V_TypeTraits<_Tp>::sum_type v_reduce_sum(const v_reg<_Tp, n>& a)
+{
+ typename V_TypeTraits<_Tp>::sum_type c = a.s[0];
+ for( int i = 1; i < n; i++ )
+ c += a.s[i];
+ return c;
+}
+
+/** @brief Get negative values mask
+
+Returned value is a bit mask with bits set to 1 on places corresponding to negative packed values indexes.
+Example:
+@code{.cpp}
+v_int32x4 r; // set to {-1, -1, 1, 1}
+int mask = v_signmask(r); // mask = 3 <== 00000000 00000000 00000000 00000011
+@endcode
+For all types except 64-bit. */
+template<typename _Tp, int n> inline int v_signmask(const v_reg<_Tp, n>& a)
+{
+ int mask = 0;
+ for( int i = 0; i < n; i++ )
+ mask |= (V_TypeTraits<_Tp>::reinterpret_int(a.s[i]) < 0) << i;
+ return mask;
+}
+
+/** @brief Check if all packed values are less than zero
+
+Unsigned values will be casted to signed: `uchar 254 => char -2`.
+For all types except 64-bit. */
+template<typename _Tp, int n> inline bool v_check_all(const v_reg<_Tp, n>& a)
+{
+ for( int i = 0; i < n; i++ )
+ if( V_TypeTraits<_Tp>::reinterpret_int(a.s[i]) >= 0 )
+ return false;
+ return true;
+}
+
+/** @brief Check if any of packed values is less than zero
+
+Unsigned values will be casted to signed: `uchar 254 => char -2`.
+For all types except 64-bit. */
+template<typename _Tp, int n> inline bool v_check_any(const v_reg<_Tp, n>& a)
+{
+ for( int i = 0; i < n; i++ )
+ if( V_TypeTraits<_Tp>::reinterpret_int(a.s[i]) < 0 )
+ return true;
+ return false;
+}
+
+/** @brief Bitwise select
+
+Return value will be built by combining values a and b using the following scheme:
+If the i-th bit in _mask_ is 1
+ select i-th bit from _a_
+else
+ select i-th bit from _b_ */
+template<typename _Tp, int n> inline v_reg<_Tp, n> v_select(const v_reg<_Tp, n>& mask,
+ const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b)
+{
+ typedef V_TypeTraits<_Tp> Traits;
+ typedef typename Traits::int_type int_type;
+ v_reg<_Tp, n> c;
+ for( int i = 0; i < n; i++ )
+ {
+ int_type m = Traits::reinterpret_int(mask.s[i]);
+ c.s[i] = Traits::reinterpret_from_int((Traits::reinterpret_int(a.s[i]) & m)
+ | (Traits::reinterpret_int(b.s[i]) & ~m));
+ }
+ return c;
+}
+
+/** @brief Expand values to the wider pack type
+
+Copy contents of register to two registers with 2x wider pack type.
+Scheme:
+@code
+ int32x4 int64x2 int64x2
+{A B C D} ==> {A B} , {C D}
+@endcode */
+template<typename _Tp, int n> inline void v_expand(const v_reg<_Tp, n>& a,
+ v_reg<typename V_TypeTraits<_Tp>::w_type, n/2>& b0,
+ v_reg<typename V_TypeTraits<_Tp>::w_type, n/2>& b1)
+{
+ for( int i = 0; i < (n/2); i++ )
+ {
+ b0.s[i] = a.s[i];
+ b1.s[i] = a.s[i+(n/2)];
+ }
+}
+
+//! @cond IGNORED
+template<typename _Tp, int n> inline v_reg<typename V_TypeTraits<_Tp>::int_type, n>
+ v_reinterpret_as_int(const v_reg<_Tp, n>& a)
+{
+ v_reg<typename V_TypeTraits<_Tp>::int_type, n> c;
+ for( int i = 0; i < n; i++ )
+ c.s[i] = V_TypeTraits<_Tp>::reinterpret_int(a.s[i]);
+ return c;
+}
+
+template<typename _Tp, int n> inline v_reg<typename V_TypeTraits<_Tp>::uint_type, n>
+ v_reinterpret_as_uint(const v_reg<_Tp, n>& a)
+{
+ v_reg<typename V_TypeTraits<_Tp>::uint_type, n> c;
+ for( int i = 0; i < n; i++ )
+ c.s[i] = V_TypeTraits<_Tp>::reinterpret_uint(a.s[i]);
+ return c;
+}
+//! @endcond
+
+/** @brief Interleave two vectors
+
+Scheme:
+@code
+ {A1 A2 A3 A4}
+ {B1 B2 B3 B4}
+---------------
+ {A1 B1 A2 B2} and {A3 B3 A4 B4}
+@endcode
+For all types except 64-bit.
+*/
+template<typename _Tp, int n> inline void v_zip( const v_reg<_Tp, n>& a0, const v_reg<_Tp, n>& a1,
+ v_reg<_Tp, n>& b0, v_reg<_Tp, n>& b1 )
+{
+ int i;
+ for( i = 0; i < n/2; i++ )
+ {
+ b0.s[i*2] = a0.s[i];
+ b0.s[i*2+1] = a1.s[i];
+ }
+ for( ; i < n; i++ )
+ {
+ b1.s[i*2-n] = a0.s[i];
+ b1.s[i*2-n+1] = a1.s[i];
+ }
+}
+
+/** @brief Load register contents from memory
+
+@param ptr pointer to memory block with data
+@return register object
+
+@note Returned type will be detected from passed pointer type, for example uchar ==> cv::v_uint8x16, int ==> cv::v_int32x4, etc.
+ */
+template<typename _Tp>
+inline v_reg<_Tp, V_SIMD128Traits<_Tp>::nlanes> v_load(const _Tp* ptr)
+{
+ return v_reg<_Tp, V_SIMD128Traits<_Tp>::nlanes>(ptr);
+}
+
+/** @brief Load register contents from memory (aligned)
+
+similar to cv::v_load, but source memory block should be aligned (to 16-byte boundary)
+ */
+template<typename _Tp>
+inline v_reg<_Tp, V_SIMD128Traits<_Tp>::nlanes> v_load_aligned(const _Tp* ptr)
+{
+ return v_reg<_Tp, V_SIMD128Traits<_Tp>::nlanes>(ptr);
+}
+
+/** @brief Load register contents from two memory blocks
+
+@param loptr memory block containing data for first half (0..n/2)
+@param hiptr memory block containing data for second half (n/2..n)
+
+@code{.cpp}
+int lo[2] = { 1, 2 }, hi[2] = { 3, 4 };
+v_int32x4 r = v_load_halves(lo, hi);
+@endcode
+ */
+template<typename _Tp>
+inline v_reg<_Tp, V_SIMD128Traits<_Tp>::nlanes> v_load_halves(const _Tp* loptr, const _Tp* hiptr)
+{
+ v_reg<_Tp, V_SIMD128Traits<_Tp>::nlanes> c;
+ for( int i = 0; i < c.nlanes/2; i++ )
+ {
+ c.s[i] = loptr[i];
+ c.s[i+c.nlanes/2] = hiptr[i];
+ }
+ return c;
+}
+
+/** @brief Load register contents from memory with double expand
+
+Same as cv::v_load, but result pack type will be 2x wider than memory type.
+
+@code{.cpp}
+short buf[4] = {1, 2, 3, 4}; // type is int16
+v_int32x4 r = v_load_expand(buf); // r = {1, 2, 3, 4} - type is int32
+@endcode
+For 8-, 16-, 32-bit integer source types. */
+template<typename _Tp>
+inline v_reg<typename V_TypeTraits<_Tp>::w_type, V_SIMD128Traits<_Tp>::nlanes / 2>
+v_load_expand(const _Tp* ptr)
+{
+ typedef typename V_TypeTraits<_Tp>::w_type w_type;
+ v_reg<w_type, V_SIMD128Traits<w_type>::nlanes> c;
+ for( int i = 0; i < c.nlanes; i++ )
+ {
+ c.s[i] = ptr[i];
+ }
+ return c;
+}
+
+/** @brief Load register contents from memory with quad expand
+
+Same as cv::v_load_expand, but result type is 4 times wider than source.
+@code{.cpp}
+char buf[4] = {1, 2, 3, 4}; // type is int8
+v_int32x4 r = v_load_q(buf); // r = {1, 2, 3, 4} - type is int32
+@endcode
+For 8-bit integer source types. */
+template<typename _Tp>
+inline v_reg<typename V_TypeTraits<_Tp>::q_type, V_SIMD128Traits<_Tp>::nlanes / 4>
+v_load_expand_q(const _Tp* ptr)
+{
+ typedef typename V_TypeTraits<_Tp>::q_type q_type;
+ v_reg<q_type, V_SIMD128Traits<q_type>::nlanes> c;
+ for( int i = 0; i < c.nlanes; i++ )
+ {
+ c.s[i] = ptr[i];
+ }
+ return c;
+}
+
+/** @brief Load and deinterleave (2 channels)
+
+Load data from memory deinterleave and store to 2 registers.
+Scheme:
+@code
+{A1 B1 A2 B2 ...} ==> {A1 A2 ...}, {B1 B2 ...}
+@endcode
+For all types except 64-bit. */
+template<typename _Tp, int n> inline void v_load_deinterleave(const _Tp* ptr, v_reg<_Tp, n>& a,
+ v_reg<_Tp, n>& b)
+{
+ int i, i2;
+ for( i = i2 = 0; i < n; i++, i2 += 2 )
+ {
+ a.s[i] = ptr[i2];
+ b.s[i] = ptr[i2+1];
+ }
+}
+
+/** @brief Load and deinterleave (3 channels)
+
+Load data from memory deinterleave and store to 3 registers.
+Scheme:
+@code
+{A1 B1 C1 A2 B2 C2 ...} ==> {A1 A2 ...}, {B1 B2 ...}, {C1 C2 ...}
+@endcode
+For all types except 64-bit. */
+template<typename _Tp, int n> inline void v_load_deinterleave(const _Tp* ptr, v_reg<_Tp, n>& a,
+ v_reg<_Tp, n>& b, v_reg<_Tp, n>& c)
+{
+ int i, i3;
+ for( i = i3 = 0; i < n; i++, i3 += 3 )
+ {
+ a.s[i] = ptr[i3];
+ b.s[i] = ptr[i3+1];
+ c.s[i] = ptr[i3+2];
+ }
+}
+
+/** @brief Load and deinterleave (4 channels)
+
+Load data from memory deinterleave and store to 4 registers.
+Scheme:
+@code
+{A1 B1 C1 D1 A2 B2 C2 D2 ...} ==> {A1 A2 ...}, {B1 B2 ...}, {C1 C2 ...}, {D1 D2 ...}
+@endcode
+For all types except 64-bit. */
+template<typename _Tp, int n>
+inline void v_load_deinterleave(const _Tp* ptr, v_reg<_Tp, n>& a,
+ v_reg<_Tp, n>& b, v_reg<_Tp, n>& c,
+ v_reg<_Tp, n>& d)
+{
+ int i, i4;
+ for( i = i4 = 0; i < n; i++, i4 += 4 )
+ {
+ a.s[i] = ptr[i4];
+ b.s[i] = ptr[i4+1];
+ c.s[i] = ptr[i4+2];
+ d.s[i] = ptr[i4+3];
+ }
+}
+
+/** @brief Interleave and store (2 channels)
+
+Interleave and store data from 2 registers to memory.
+Scheme:
+@code
+{A1 A2 ...}, {B1 B2 ...} ==> {A1 B1 A2 B2 ...}
+@endcode
+For all types except 64-bit. */
+template<typename _Tp, int n>
+inline void v_store_interleave( _Tp* ptr, const v_reg<_Tp, n>& a,
+ const v_reg<_Tp, n>& b)
+{
+ int i, i2;
+ for( i = i2 = 0; i < n; i++, i2 += 2 )
+ {
+ ptr[i2] = a.s[i];
+ ptr[i2+1] = b.s[i];
+ }
+}
+
+/** @brief Interleave and store (3 channels)
+
+Interleave and store data from 3 registers to memory.
+Scheme:
+@code
+{A1 A2 ...}, {B1 B2 ...}, {C1 C2 ...} ==> {A1 B1 C1 A2 B2 C2 ...}
+@endcode
+For all types except 64-bit. */
+template<typename _Tp, int n>
+inline void v_store_interleave( _Tp* ptr, const v_reg<_Tp, n>& a,
+ const v_reg<_Tp, n>& b, const v_reg<_Tp, n>& c)
+{
+ int i, i3;
+ for( i = i3 = 0; i < n; i++, i3 += 3 )
+ {
+ ptr[i3] = a.s[i];
+ ptr[i3+1] = b.s[i];
+ ptr[i3+2] = c.s[i];
+ }
+}
+
+/** @brief Interleave and store (4 channels)
+
+Interleave and store data from 4 registers to memory.
+Scheme:
+@code
+{A1 A2 ...}, {B1 B2 ...}, {C1 C2 ...}, {D1 D2 ...} ==> {A1 B1 C1 D1 A2 B2 C2 D2 ...}
+@endcode
+For all types except 64-bit. */
+template<typename _Tp, int n> inline void v_store_interleave( _Tp* ptr, const v_reg<_Tp, n>& a,
+ const v_reg<_Tp, n>& b, const v_reg<_Tp, n>& c,
+ const v_reg<_Tp, n>& d)
+{
+ int i, i4;
+ for( i = i4 = 0; i < n; i++, i4 += 4 )
+ {
+ ptr[i4] = a.s[i];
+ ptr[i4+1] = b.s[i];
+ ptr[i4+2] = c.s[i];
+ ptr[i4+3] = d.s[i];
+ }
+}
+
+/** @brief Store data to memory
+
+Store register contents to memory.
+Scheme:
+@code
+ REG {A B C D} ==> MEM {A B C D}
+@endcode
+Pointer can be unaligned. */
+template<typename _Tp, int n>
+inline void v_store(_Tp* ptr, const v_reg<_Tp, n>& a)
+{
+ for( int i = 0; i < n; i++ )
+ ptr[i] = a.s[i];
+}
+
+/** @brief Store data to memory (lower half)
+
+Store lower half of register contents to memory.
+Scheme:
+@code
+ REG {A B C D} ==> MEM {A B}
+@endcode */
+template<typename _Tp, int n>
+inline void v_store_low(_Tp* ptr, const v_reg<_Tp, n>& a)
+{
+ for( int i = 0; i < (n/2); i++ )
+ ptr[i] = a.s[i];
+}
+
+/** @brief Store data to memory (higher half)
+
+Store higher half of register contents to memory.
+Scheme:
+@code
+ REG {A B C D} ==> MEM {C D}
+@endcode */
+template<typename _Tp, int n>
+inline void v_store_high(_Tp* ptr, const v_reg<_Tp, n>& a)
+{
+ for( int i = 0; i < (n/2); i++ )
+ ptr[i] = a.s[i+(n/2)];
+}
+
+/** @brief Store data to memory (aligned)
+
+Store register contents to memory.
+Scheme:
+@code
+ REG {A B C D} ==> MEM {A B C D}
+@endcode
+Pointer __should__ be aligned by 16-byte boundary. */
+template<typename _Tp, int n>
+inline void v_store_aligned(_Tp* ptr, const v_reg<_Tp, n>& a)
+{
+ for( int i = 0; i < n; i++ )
+ ptr[i] = a.s[i];
+}
+
+/** @brief Combine vector from first elements of two vectors
+
+Scheme:
+@code
+ {A1 A2 A3 A4}
+ {B1 B2 B3 B4}
+---------------
+ {A1 A2 B1 B2}
+@endcode
+For all types except 64-bit. */
+template<typename _Tp, int n>
+inline v_reg<_Tp, n> v_combine_low(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b)
+{
+ v_reg<_Tp, n> c;
+ for( int i = 0; i < (n/2); i++ )
+ {
+ c.s[i] = a.s[i];
+ c.s[i+(n/2)] = b.s[i];
+ }
+ return c;
+}
+
+/** @brief Combine vector from last elements of two vectors
+
+Scheme:
+@code
+ {A1 A2 A3 A4}
+ {B1 B2 B3 B4}
+---------------
+ {A3 A4 B3 B4}
+@endcode
+For all types except 64-bit. */
+template<typename _Tp, int n>
+inline v_reg<_Tp, n> v_combine_high(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b)
+{
+ v_reg<_Tp, n> c;
+ for( int i = 0; i < (n/2); i++ )
+ {
+ c.s[i] = a.s[i+(n/2)];
+ c.s[i+(n/2)] = b.s[i+(n/2)];
+ }
+ return c;
+}
+
+/** @brief Combine two vectors from lower and higher parts of two other vectors
+
+@code{.cpp}
+low = cv::v_combine_low(a, b);
+high = cv::v_combine_high(a, b);
+@endcode */
+template<typename _Tp, int n>
+inline void v_recombine(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b,
+ v_reg<_Tp, n>& low, v_reg<_Tp, n>& high)
+{
+ for( int i = 0; i < (n/2); i++ )
+ {
+ low.s[i] = a.s[i];
+ low.s[i+(n/2)] = b.s[i];
+ high.s[i] = a.s[i+(n/2)];
+ high.s[i+(n/2)] = b.s[i+(n/2)];
+ }
+}
+
+/** @brief Vector extract
+
+Scheme:
+@code
+ {A1 A2 A3 A4}
+ {B1 B2 B3 B4}
+========================
+shift = 1 {A2 A3 A4 B1}
+shift = 2 {A3 A4 B1 B2}
+shift = 3 {A4 B1 B2 B3}
+@endcode
+Restriction: 0 <= shift < nlanes
+
+Usage:
+@code
+v_int32x4 a, b, c;
+c = v_extract<2>(a, b);
+@endcode
+For integer types only. */
+template<int s, typename _Tp, int n>
+inline v_reg<_Tp, n> v_extract(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b)
+{
+ v_reg<_Tp, n> r;
+ const int shift = n - s;
+ int i = 0;
+ for (; i < shift; ++i)
+ r.s[i] = a.s[i+s];
+ for (; i < n; ++i)
+ r.s[i] = b.s[i-shift];
+ return r;
+}
+
+/** @brief Round
+
+Rounds each value. Input type is float vector ==> output type is int vector.*/
+template<int n> inline v_reg<int, n> v_round(const v_reg<float, n>& a)
+{
+ v_reg<int, n> c;
+ for( int i = 0; i < n; i++ )
+ c.s[i] = cvRound(a.s[i]);
+ return c;
+}
+
+/** @brief Floor
+
+Floor each value. Input type is float vector ==> output type is int vector.*/
+template<int n> inline v_reg<int, n> v_floor(const v_reg<float, n>& a)
+{
+ v_reg<int, n> c;
+ for( int i = 0; i < n; i++ )
+ c.s[i] = cvFloor(a.s[i]);
+ return c;
+}
+
+/** @brief Ceil
+
+Ceil each value. Input type is float vector ==> output type is int vector.*/
+template<int n> inline v_reg<int, n> v_ceil(const v_reg<float, n>& a)
+{
+ v_reg<int, n> c;
+ for( int i = 0; i < n; i++ )
+ c.s[i] = cvCeil(a.s[i]);
+ return c;
+}
+
+/** @brief Trunc
+
+Truncate each value. Input type is float vector ==> output type is int vector.*/
+template<int n> inline v_reg<int, n> v_trunc(const v_reg<float, n>& a)
+{
+ v_reg<int, n> c;
+ for( int i = 0; i < n; i++ )
+ c.s[i] = (int)(a.s[i]);
+ return c;
+}
+
+/** @overload */
+template<int n> inline v_reg<int, n*2> v_round(const v_reg<double, n>& a)
+{
+ v_reg<int, n*2> c;
+ for( int i = 0; i < n; i++ )
+ {
+ c.s[i] = cvRound(a.s[i]);
+ c.s[i+n] = 0;
+ }
+ return c;
+}
+
+/** @overload */
+template<int n> inline v_reg<int, n*2> v_floor(const v_reg<double, n>& a)
+{
+ v_reg<int, n> c;
+ for( int i = 0; i < n; i++ )
+ {
+ c.s[i] = cvFloor(a.s[i]);
+ c.s[i+n] = 0;
+ }
+ return c;
+}
+
+/** @overload */
+template<int n> inline v_reg<int, n*2> v_ceil(const v_reg<double, n>& a)
+{
+ v_reg<int, n> c;
+ for( int i = 0; i < n; i++ )
+ {
+ c.s[i] = cvCeil(a.s[i]);
+ c.s[i+n] = 0;
+ }
+ return c;
+}
+
+/** @overload */
+template<int n> inline v_reg<int, n*2> v_trunc(const v_reg<double, n>& a)
+{
+ v_reg<int, n> c;
+ for( int i = 0; i < n; i++ )
+ {
+ c.s[i] = cvCeil(a.s[i]);
+ c.s[i+n] = 0;
+ }
+ return c;
+}
+
+/** @brief Convert to float
+
+Supported input type is cv::v_int32x4. */
+template<int n> inline v_reg<float, n> v_cvt_f32(const v_reg<int, n>& a)
+{
+ v_reg<float, n> c;
+ for( int i = 0; i < n; i++ )
+ c.s[i] = (float)a.s[i];
+ return c;
+}
+
+/** @brief Convert to double
+
+Supported input type is cv::v_int32x4. */
+template<int n> inline v_reg<double, n> v_cvt_f64(const v_reg<int, n*2>& a)
+{
+ v_reg<double, n> c;
+ for( int i = 0; i < n; i++ )
+ c.s[i] = (double)a.s[i];
+ return c;
+}
+
+/** @brief Convert to double
+
+Supported input type is cv::v_float32x4. */
+template<int n> inline v_reg<double, n> v_cvt_f64(const v_reg<float, n*2>& a)
+{
+ v_reg<double, n> c;
+ for( int i = 0; i < n; i++ )
+ c.s[i] = (double)a.s[i];
+ return c;
+}
+
+/** @brief Transpose 4x4 matrix
+
+Scheme:
+@code
+a0 {A1 A2 A3 A4}
+a1 {B1 B2 B3 B4}
+a2 {C1 C2 C3 C4}
+a3 {D1 D2 D3 D4}
+===============
+b0 {A1 B1 C1 D1}
+b1 {A2 B2 C2 D2}
+b2 {A3 B3 C3 D3}
+b3 {A4 B4 C4 D4}
+@endcode
+*/
+template<typename _Tp>
+inline void v_transpose4x4( v_reg<_Tp, 4>& a0, const v_reg<_Tp, 4>& a1,
+ const v_reg<_Tp, 4>& a2, const v_reg<_Tp, 4>& a3,
+ v_reg<_Tp, 4>& b0, v_reg<_Tp, 4>& b1,
+ v_reg<_Tp, 4>& b2, v_reg<_Tp, 4>& b3 )
+{
+ b0 = v_reg<_Tp, 4>(a0.s[0], a1.s[0], a2.s[0], a3.s[0]);
+ b1 = v_reg<_Tp, 4>(a0.s[1], a1.s[1], a2.s[1], a3.s[1]);
+ b2 = v_reg<_Tp, 4>(a0.s[2], a1.s[2], a2.s[2], a3.s[2]);
+ b3 = v_reg<_Tp, 4>(a0.s[3], a1.s[3], a2.s[3], a3.s[3]);
+}
+
+//! @brief Helper macro
+//! @ingroup core_hal_intrin_impl
+#define OPENCV_HAL_IMPL_C_INIT_ZERO(_Tpvec, _Tp, suffix) \
+inline _Tpvec v_setzero_##suffix() { return _Tpvec::zero(); }
+
+//! @name Init with zero
+//! @{
+//! @brief Create new vector with zero elements
+OPENCV_HAL_IMPL_C_INIT_ZERO(v_uint8x16, uchar, u8)
+OPENCV_HAL_IMPL_C_INIT_ZERO(v_int8x16, schar, s8)
+OPENCV_HAL_IMPL_C_INIT_ZERO(v_uint16x8, ushort, u16)
+OPENCV_HAL_IMPL_C_INIT_ZERO(v_int16x8, short, s16)
+OPENCV_HAL_IMPL_C_INIT_ZERO(v_uint32x4, unsigned, u32)
+OPENCV_HAL_IMPL_C_INIT_ZERO(v_int32x4, int, s32)
+OPENCV_HAL_IMPL_C_INIT_ZERO(v_float32x4, float, f32)
+OPENCV_HAL_IMPL_C_INIT_ZERO(v_float64x2, double, f64)
+OPENCV_HAL_IMPL_C_INIT_ZERO(v_uint64x2, uint64, u64)
+OPENCV_HAL_IMPL_C_INIT_ZERO(v_int64x2, int64, s64)
+//! @}
+
+//! @brief Helper macro
+//! @ingroup core_hal_intrin_impl
+#define OPENCV_HAL_IMPL_C_INIT_VAL(_Tpvec, _Tp, suffix) \
+inline _Tpvec v_setall_##suffix(_Tp val) { return _Tpvec::all(val); }
+
+//! @name Init with value
+//! @{
+//! @brief Create new vector with elements set to a specific value
+OPENCV_HAL_IMPL_C_INIT_VAL(v_uint8x16, uchar, u8)
+OPENCV_HAL_IMPL_C_INIT_VAL(v_int8x16, schar, s8)
+OPENCV_HAL_IMPL_C_INIT_VAL(v_uint16x8, ushort, u16)
+OPENCV_HAL_IMPL_C_INIT_VAL(v_int16x8, short, s16)
+OPENCV_HAL_IMPL_C_INIT_VAL(v_uint32x4, unsigned, u32)
+OPENCV_HAL_IMPL_C_INIT_VAL(v_int32x4, int, s32)
+OPENCV_HAL_IMPL_C_INIT_VAL(v_float32x4, float, f32)
+OPENCV_HAL_IMPL_C_INIT_VAL(v_float64x2, double, f64)
+OPENCV_HAL_IMPL_C_INIT_VAL(v_uint64x2, uint64, u64)
+OPENCV_HAL_IMPL_C_INIT_VAL(v_int64x2, int64, s64)
+//! @}
+
+//! @brief Helper macro
+//! @ingroup core_hal_intrin_impl
+#define OPENCV_HAL_IMPL_C_REINTERPRET(_Tpvec, _Tp, suffix) \
+template<typename _Tp0, int n0> inline _Tpvec \
+ v_reinterpret_as_##suffix(const v_reg<_Tp0, n0>& a) \
+{ return a.template reinterpret_as<_Tp, _Tpvec::nlanes>(); }
+
+//! @name Reinterpret
+//! @{
+//! @brief Convert vector to different type without modifying underlying data.
+OPENCV_HAL_IMPL_C_REINTERPRET(v_uint8x16, uchar, u8)
+OPENCV_HAL_IMPL_C_REINTERPRET(v_int8x16, schar, s8)
+OPENCV_HAL_IMPL_C_REINTERPRET(v_uint16x8, ushort, u16)
+OPENCV_HAL_IMPL_C_REINTERPRET(v_int16x8, short, s16)
+OPENCV_HAL_IMPL_C_REINTERPRET(v_uint32x4, unsigned, u32)
+OPENCV_HAL_IMPL_C_REINTERPRET(v_int32x4, int, s32)
+OPENCV_HAL_IMPL_C_REINTERPRET(v_float32x4, float, f32)
+OPENCV_HAL_IMPL_C_REINTERPRET(v_float64x2, double, f64)
+OPENCV_HAL_IMPL_C_REINTERPRET(v_uint64x2, uint64, u64)
+OPENCV_HAL_IMPL_C_REINTERPRET(v_int64x2, int64, s64)
+//! @}
+
+//! @brief Helper macro
+//! @ingroup core_hal_intrin_impl
+#define OPENCV_HAL_IMPL_C_SHIFTL(_Tpvec, _Tp) \
+template<int n> inline _Tpvec v_shl(const _Tpvec& a) \
+{ return a << n; }
+
+//! @name Left shift
+//! @{
+//! @brief Shift left
+OPENCV_HAL_IMPL_C_SHIFTL(v_uint16x8, ushort)
+OPENCV_HAL_IMPL_C_SHIFTL(v_int16x8, short)
+OPENCV_HAL_IMPL_C_SHIFTL(v_uint32x4, unsigned)
+OPENCV_HAL_IMPL_C_SHIFTL(v_int32x4, int)
+OPENCV_HAL_IMPL_C_SHIFTL(v_uint64x2, uint64)
+OPENCV_HAL_IMPL_C_SHIFTL(v_int64x2, int64)
+//! @}
+
+//! @brief Helper macro
+//! @ingroup core_hal_intrin_impl
+#define OPENCV_HAL_IMPL_C_SHIFTR(_Tpvec, _Tp) \
+template<int n> inline _Tpvec v_shr(const _Tpvec& a) \
+{ return a >> n; }
+
+//! @name Right shift
+//! @{
+//! @brief Shift right
+OPENCV_HAL_IMPL_C_SHIFTR(v_uint16x8, ushort)
+OPENCV_HAL_IMPL_C_SHIFTR(v_int16x8, short)
+OPENCV_HAL_IMPL_C_SHIFTR(v_uint32x4, unsigned)
+OPENCV_HAL_IMPL_C_SHIFTR(v_int32x4, int)
+OPENCV_HAL_IMPL_C_SHIFTR(v_uint64x2, uint64)
+OPENCV_HAL_IMPL_C_SHIFTR(v_int64x2, int64)
+//! @}
+
+//! @brief Helper macro
+//! @ingroup core_hal_intrin_impl
+#define OPENCV_HAL_IMPL_C_RSHIFTR(_Tpvec, _Tp) \
+template<int n> inline _Tpvec v_rshr(const _Tpvec& a) \
+{ \
+ _Tpvec c; \
+ for( int i = 0; i < _Tpvec::nlanes; i++ ) \
+ c.s[i] = (_Tp)((a.s[i] + ((_Tp)1 << (n - 1))) >> n); \
+ return c; \
+}
+
+//! @name Rounding shift
+//! @{
+//! @brief Rounding shift right
+OPENCV_HAL_IMPL_C_RSHIFTR(v_uint16x8, ushort)
+OPENCV_HAL_IMPL_C_RSHIFTR(v_int16x8, short)
+OPENCV_HAL_IMPL_C_RSHIFTR(v_uint32x4, unsigned)
+OPENCV_HAL_IMPL_C_RSHIFTR(v_int32x4, int)
+OPENCV_HAL_IMPL_C_RSHIFTR(v_uint64x2, uint64)
+OPENCV_HAL_IMPL_C_RSHIFTR(v_int64x2, int64)
+//! @}
+
+//! @brief Helper macro
+//! @ingroup core_hal_intrin_impl
+#define OPENCV_HAL_IMPL_C_PACK(_Tpvec, _Tpnvec, _Tpn, pack_suffix) \
+inline _Tpnvec v_##pack_suffix(const _Tpvec& a, const _Tpvec& b) \
+{ \
+ _Tpnvec c; \
+ for( int i = 0; i < _Tpvec::nlanes; i++ ) \
+ { \
+ c.s[i] = saturate_cast<_Tpn>(a.s[i]); \
+ c.s[i+_Tpvec::nlanes] = saturate_cast<_Tpn>(b.s[i]); \
+ } \
+ return c; \
+}
+
+//! @name Pack
+//! @{
+//! @brief Pack values from two vectors to one
+//!
+//! Return vector type have twice more elements than input vector types. Variant with _u_ suffix also
+//! converts to corresponding unsigned type.
+//!
+//! - pack: for 16-, 32- and 64-bit integer input types
+//! - pack_u: for 16- and 32-bit signed integer input types
+OPENCV_HAL_IMPL_C_PACK(v_uint16x8, v_uint8x16, uchar, pack)
+OPENCV_HAL_IMPL_C_PACK(v_int16x8, v_int8x16, schar, pack)
+OPENCV_HAL_IMPL_C_PACK(v_uint32x4, v_uint16x8, ushort, pack)
+OPENCV_HAL_IMPL_C_PACK(v_int32x4, v_int16x8, short, pack)
+OPENCV_HAL_IMPL_C_PACK(v_uint64x2, v_uint32x4, unsigned, pack)
+OPENCV_HAL_IMPL_C_PACK(v_int64x2, v_int32x4, int, pack)
+OPENCV_HAL_IMPL_C_PACK(v_int16x8, v_uint8x16, uchar, pack_u)
+OPENCV_HAL_IMPL_C_PACK(v_int32x4, v_uint16x8, ushort, pack_u)
+//! @}
+
+//! @brief Helper macro
+//! @ingroup core_hal_intrin_impl
+#define OPENCV_HAL_IMPL_C_RSHR_PACK(_Tpvec, _Tp, _Tpnvec, _Tpn, pack_suffix) \
+template<int n> inline _Tpnvec v_rshr_##pack_suffix(const _Tpvec& a, const _Tpvec& b) \
+{ \
+ _Tpnvec c; \
+ for( int i = 0; i < _Tpvec::nlanes; i++ ) \
+ { \
+ c.s[i] = saturate_cast<_Tpn>((a.s[i] + ((_Tp)1 << (n - 1))) >> n); \
+ c.s[i+_Tpvec::nlanes] = saturate_cast<_Tpn>((b.s[i] + ((_Tp)1 << (n - 1))) >> n); \
+ } \
+ return c; \
+}
+
+//! @name Pack with rounding shift
+//! @{
+//! @brief Pack values from two vectors to one with rounding shift
+//!
+//! Values from the input vectors will be shifted right by _n_ bits with rounding, converted to narrower
+//! type and returned in the result vector. Variant with _u_ suffix converts to unsigned type.
+//!
+//! - pack: for 16-, 32- and 64-bit integer input types
+//! - pack_u: for 16- and 32-bit signed integer input types
+OPENCV_HAL_IMPL_C_RSHR_PACK(v_uint16x8, ushort, v_uint8x16, uchar, pack)
+OPENCV_HAL_IMPL_C_RSHR_PACK(v_int16x8, short, v_int8x16, schar, pack)
+OPENCV_HAL_IMPL_C_RSHR_PACK(v_uint32x4, unsigned, v_uint16x8, ushort, pack)
+OPENCV_HAL_IMPL_C_RSHR_PACK(v_int32x4, int, v_int16x8, short, pack)
+OPENCV_HAL_IMPL_C_RSHR_PACK(v_uint64x2, uint64, v_uint32x4, unsigned, pack)
+OPENCV_HAL_IMPL_C_RSHR_PACK(v_int64x2, int64, v_int32x4, int, pack)
+OPENCV_HAL_IMPL_C_RSHR_PACK(v_int16x8, short, v_uint8x16, uchar, pack_u)
+OPENCV_HAL_IMPL_C_RSHR_PACK(v_int32x4, int, v_uint16x8, ushort, pack_u)
+//! @}
+
+//! @brief Helper macro
+//! @ingroup core_hal_intrin_impl
+#define OPENCV_HAL_IMPL_C_PACK_STORE(_Tpvec, _Tp, _Tpnvec, _Tpn, pack_suffix) \
+inline void v_##pack_suffix##_store(_Tpn* ptr, const _Tpvec& a) \
+{ \
+ for( int i = 0; i < _Tpvec::nlanes; i++ ) \
+ ptr[i] = saturate_cast<_Tpn>(a.s[i]); \
+}
+
+//! @name Pack and store
+//! @{
+//! @brief Store values from the input vector into memory with pack
+//!
+//! Values will be stored into memory with saturating conversion to narrower type.
+//! Variant with _u_ suffix converts to corresponding unsigned type.
+//!
+//! - pack: for 16-, 32- and 64-bit integer input types
+//! - pack_u: for 16- and 32-bit signed integer input types
+OPENCV_HAL_IMPL_C_PACK_STORE(v_uint16x8, ushort, v_uint8x16, uchar, pack)
+OPENCV_HAL_IMPL_C_PACK_STORE(v_int16x8, short, v_int8x16, schar, pack)
+OPENCV_HAL_IMPL_C_PACK_STORE(v_uint32x4, unsigned, v_uint16x8, ushort, pack)
+OPENCV_HAL_IMPL_C_PACK_STORE(v_int32x4, int, v_int16x8, short, pack)
+OPENCV_HAL_IMPL_C_PACK_STORE(v_uint64x2, uint64, v_uint32x4, unsigned, pack)
+OPENCV_HAL_IMPL_C_PACK_STORE(v_int64x2, int64, v_int32x4, int, pack)
+OPENCV_HAL_IMPL_C_PACK_STORE(v_int16x8, short, v_uint8x16, uchar, pack_u)
+OPENCV_HAL_IMPL_C_PACK_STORE(v_int32x4, int, v_uint16x8, ushort, pack_u)
+//! @}
+
+//! @brief Helper macro
+//! @ingroup core_hal_intrin_impl
+#define OPENCV_HAL_IMPL_C_RSHR_PACK_STORE(_Tpvec, _Tp, _Tpnvec, _Tpn, pack_suffix) \
+template<int n> inline void v_rshr_##pack_suffix##_store(_Tpn* ptr, const _Tpvec& a) \
+{ \
+ for( int i = 0; i < _Tpvec::nlanes; i++ ) \
+ ptr[i] = saturate_cast<_Tpn>((a.s[i] + ((_Tp)1 << (n - 1))) >> n); \
+}
+
+//! @name Pack and store with rounding shift
+//! @{
+//! @brief Store values from the input vector into memory with pack
+//!
+//! Values will be shifted _n_ bits right with rounding, converted to narrower type and stored into
+//! memory. Variant with _u_ suffix converts to unsigned type.
+//!
+//! - pack: for 16-, 32- and 64-bit integer input types
+//! - pack_u: for 16- and 32-bit signed integer input types
+OPENCV_HAL_IMPL_C_RSHR_PACK_STORE(v_uint16x8, ushort, v_uint8x16, uchar, pack)
+OPENCV_HAL_IMPL_C_RSHR_PACK_STORE(v_int16x8, short, v_int8x16, schar, pack)
+OPENCV_HAL_IMPL_C_RSHR_PACK_STORE(v_uint32x4, unsigned, v_uint16x8, ushort, pack)
+OPENCV_HAL_IMPL_C_RSHR_PACK_STORE(v_int32x4, int, v_int16x8, short, pack)
+OPENCV_HAL_IMPL_C_RSHR_PACK_STORE(v_uint64x2, uint64, v_uint32x4, unsigned, pack)
+OPENCV_HAL_IMPL_C_RSHR_PACK_STORE(v_int64x2, int64, v_int32x4, int, pack)
+OPENCV_HAL_IMPL_C_RSHR_PACK_STORE(v_int16x8, short, v_uint8x16, uchar, pack_u)
+OPENCV_HAL_IMPL_C_RSHR_PACK_STORE(v_int32x4, int, v_uint16x8, ushort, pack_u)
+//! @}
+
+/** @brief Matrix multiplication
+
+Scheme:
+@code
+{A0 A1 A2 A3} |V0|
+{B0 B1 B2 B3} |V1|
+{C0 C1 C2 C3} |V2|
+{D0 D1 D2 D3} x |V3|
+====================
+{R0 R1 R2 R3}, where:
+R0 = A0V0 + A1V1 + A2V2 + A3V3,
+R1 = B0V0 + B1V1 + B2V2 + B3V3
+...
+@endcode
+*/
+inline v_float32x4 v_matmul(const v_float32x4& v, const v_float32x4& m0,
+ const v_float32x4& m1, const v_float32x4& m2,
+ const v_float32x4& m3)
+{
+ return v_float32x4(v.s[0]*m0.s[0] + v.s[1]*m1.s[0] + v.s[2]*m2.s[0] + v.s[3]*m3.s[0],
+ v.s[0]*m0.s[1] + v.s[1]*m1.s[1] + v.s[2]*m2.s[1] + v.s[3]*m3.s[1],
+ v.s[0]*m0.s[2] + v.s[1]*m1.s[2] + v.s[2]*m2.s[2] + v.s[3]*m3.s[2],
+ v.s[0]*m0.s[3] + v.s[1]*m1.s[3] + v.s[2]*m2.s[3] + v.s[3]*m3.s[3]);
+}
+
+//! @}
+
+//! @name Check SIMD support
+//! @{
+//! @brief Check CPU capability of SIMD operation
+static inline bool hasSIMD128()
+{
+ return false;
+}
+
+//! @}
+
+
+}
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/core/hal/intrin_neon.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,1234 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
+// Copyright (C) 2015, Itseez Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_HAL_INTRIN_NEON_HPP
+#define OPENCV_HAL_INTRIN_NEON_HPP
+
+#include <algorithm>
+#include "opencv2/core/utility.hpp"
+
+namespace cv
+{
+
+//! @cond IGNORED
+
+#define CV_SIMD128 1
+#if defined(__aarch64__)
+#define CV_SIMD128_64F 1
+#else
+#define CV_SIMD128_64F 0
+#endif
+
+#if CV_SIMD128_64F
+#define OPENCV_HAL_IMPL_NEON_REINTERPRET(_Tpv, suffix) \
+template <typename T> static inline \
+_Tpv vreinterpretq_##suffix##_f64(T a) { return (_Tpv) a; } \
+template <typename T> static inline \
+float64x2_t vreinterpretq_f64_##suffix(T a) { return (float64x2_t) a; }
+OPENCV_HAL_IMPL_NEON_REINTERPRET(uint8x16_t, u8)
+OPENCV_HAL_IMPL_NEON_REINTERPRET(int8x16_t, s8)
+OPENCV_HAL_IMPL_NEON_REINTERPRET(uint16x8_t, u16)
+OPENCV_HAL_IMPL_NEON_REINTERPRET(int16x8_t, s16)
+OPENCV_HAL_IMPL_NEON_REINTERPRET(uint32x4_t, u32)
+OPENCV_HAL_IMPL_NEON_REINTERPRET(int32x4_t, s32)
+OPENCV_HAL_IMPL_NEON_REINTERPRET(uint64x2_t, u64)
+OPENCV_HAL_IMPL_NEON_REINTERPRET(int64x2_t, s64)
+OPENCV_HAL_IMPL_NEON_REINTERPRET(float32x4_t, f32)
+#endif
+
+struct v_uint8x16
+{
+ typedef uchar lane_type;
+ enum { nlanes = 16 };
+
+ v_uint8x16() {}
+ explicit v_uint8x16(uint8x16_t v) : val(v) {}
+ v_uint8x16(uchar v0, uchar v1, uchar v2, uchar v3, uchar v4, uchar v5, uchar v6, uchar v7,
+ uchar v8, uchar v9, uchar v10, uchar v11, uchar v12, uchar v13, uchar v14, uchar v15)
+ {
+ uchar v[] = {v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15};
+ val = vld1q_u8(v);
+ }
+ uchar get0() const
+ {
+ return vgetq_lane_u8(val, 0);
+ }
+
+ uint8x16_t val;
+};
+
+struct v_int8x16
+{
+ typedef schar lane_type;
+ enum { nlanes = 16 };
+
+ v_int8x16() {}
+ explicit v_int8x16(int8x16_t v) : val(v) {}
+ v_int8x16(schar v0, schar v1, schar v2, schar v3, schar v4, schar v5, schar v6, schar v7,
+ schar v8, schar v9, schar v10, schar v11, schar v12, schar v13, schar v14, schar v15)
+ {
+ schar v[] = {v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15};
+ val = vld1q_s8(v);
+ }
+ schar get0() const
+ {
+ return vgetq_lane_s8(val, 0);
+ }
+
+ int8x16_t val;
+};
+
+struct v_uint16x8
+{
+ typedef ushort lane_type;
+ enum { nlanes = 8 };
+
+ v_uint16x8() {}
+ explicit v_uint16x8(uint16x8_t v) : val(v) {}
+ v_uint16x8(ushort v0, ushort v1, ushort v2, ushort v3, ushort v4, ushort v5, ushort v6, ushort v7)
+ {
+ ushort v[] = {v0, v1, v2, v3, v4, v5, v6, v7};
+ val = vld1q_u16(v);
+ }
+ ushort get0() const
+ {
+ return vgetq_lane_u16(val, 0);
+ }
+
+ uint16x8_t val;
+};
+
+struct v_int16x8
+{
+ typedef short lane_type;
+ enum { nlanes = 8 };
+
+ v_int16x8() {}
+ explicit v_int16x8(int16x8_t v) : val(v) {}
+ v_int16x8(short v0, short v1, short v2, short v3, short v4, short v5, short v6, short v7)
+ {
+ short v[] = {v0, v1, v2, v3, v4, v5, v6, v7};
+ val = vld1q_s16(v);
+ }
+ short get0() const
+ {
+ return vgetq_lane_s16(val, 0);
+ }
+
+ int16x8_t val;
+};
+
+struct v_uint32x4
+{
+ typedef unsigned lane_type;
+ enum { nlanes = 4 };
+
+ v_uint32x4() {}
+ explicit v_uint32x4(uint32x4_t v) : val(v) {}
+ v_uint32x4(unsigned v0, unsigned v1, unsigned v2, unsigned v3)
+ {
+ unsigned v[] = {v0, v1, v2, v3};
+ val = vld1q_u32(v);
+ }
+ unsigned get0() const
+ {
+ return vgetq_lane_u32(val, 0);
+ }
+
+ uint32x4_t val;
+};
+
+struct v_int32x4
+{
+ typedef int lane_type;
+ enum { nlanes = 4 };
+
+ v_int32x4() {}
+ explicit v_int32x4(int32x4_t v) : val(v) {}
+ v_int32x4(int v0, int v1, int v2, int v3)
+ {
+ int v[] = {v0, v1, v2, v3};
+ val = vld1q_s32(v);
+ }
+ int get0() const
+ {
+ return vgetq_lane_s32(val, 0);
+ }
+ int32x4_t val;
+};
+
+struct v_float32x4
+{
+ typedef float lane_type;
+ enum { nlanes = 4 };
+
+ v_float32x4() {}
+ explicit v_float32x4(float32x4_t v) : val(v) {}
+ v_float32x4(float v0, float v1, float v2, float v3)
+ {
+ float v[] = {v0, v1, v2, v3};
+ val = vld1q_f32(v);
+ }
+ float get0() const
+ {
+ return vgetq_lane_f32(val, 0);
+ }
+ float32x4_t val;
+};
+
+struct v_uint64x2
+{
+ typedef uint64 lane_type;
+ enum { nlanes = 2 };
+
+ v_uint64x2() {}
+ explicit v_uint64x2(uint64x2_t v) : val(v) {}
+ v_uint64x2(unsigned v0, unsigned v1)
+ {
+ uint64 v[] = {v0, v1};
+ val = vld1q_u64(v);
+ }
+ uint64 get0() const
+ {
+ return vgetq_lane_u64(val, 0);
+ }
+ uint64x2_t val;
+};
+
+struct v_int64x2
+{
+ typedef int64 lane_type;
+ enum { nlanes = 2 };
+
+ v_int64x2() {}
+ explicit v_int64x2(int64x2_t v) : val(v) {}
+ v_int64x2(int v0, int v1)
+ {
+ int64 v[] = {v0, v1};
+ val = vld1q_s64(v);
+ }
+ int64 get0() const
+ {
+ return vgetq_lane_s64(val, 0);
+ }
+ int64x2_t val;
+};
+
+#if CV_SIMD128_64F
+struct v_float64x2
+{
+ typedef double lane_type;
+ enum { nlanes = 2 };
+
+ v_float64x2() {}
+ explicit v_float64x2(float64x2_t v) : val(v) {}
+ v_float64x2(double v0, double v1)
+ {
+ double v[] = {v0, v1};
+ val = vld1q_f64(v);
+ }
+ double get0() const
+ {
+ return vgetq_lane_f64(val, 0);
+ }
+ float64x2_t val;
+};
+#endif
+
+#if defined (HAVE_FP16)
+// Workaround for old comiplers
+template <typename T> static inline int16x4_t vreinterpret_s16_f16(T a)
+{ return (int16x4_t)a; }
+template <typename T> static inline float16x4_t vreinterpret_f16_s16(T a)
+{ return (float16x4_t)a; }
+template <typename T> static inline float16x4_t vld1_f16(const T* ptr)
+{ return vreinterpret_f16_s16(vld1_s16((const short*)ptr)); }
+template <typename T> static inline void vst1_f16(T* ptr, float16x4_t a)
+{ vst1_s16((short*)ptr, vreinterpret_s16_f16(a)); }
+
+struct v_float16x4
+{
+ typedef short lane_type;
+ enum { nlanes = 4 };
+
+ v_float16x4() {}
+ explicit v_float16x4(float16x4_t v) : val(v) {}
+ v_float16x4(short v0, short v1, short v2, short v3)
+ {
+ short v[] = {v0, v1, v2, v3};
+ val = vld1_f16(v);
+ }
+ short get0() const
+ {
+ return vget_lane_s16(vreinterpret_s16_f16(val), 0);
+ }
+ float16x4_t val;
+};
+#endif
+
+#define OPENCV_HAL_IMPL_NEON_INIT(_Tpv, _Tp, suffix) \
+inline v_##_Tpv v_setzero_##suffix() { return v_##_Tpv(vdupq_n_##suffix((_Tp)0)); } \
+inline v_##_Tpv v_setall_##suffix(_Tp v) { return v_##_Tpv(vdupq_n_##suffix(v)); } \
+inline _Tpv##_t vreinterpretq_##suffix##_##suffix(_Tpv##_t v) { return v; } \
+inline v_uint8x16 v_reinterpret_as_u8(const v_##_Tpv& v) { return v_uint8x16(vreinterpretq_u8_##suffix(v.val)); } \
+inline v_int8x16 v_reinterpret_as_s8(const v_##_Tpv& v) { return v_int8x16(vreinterpretq_s8_##suffix(v.val)); } \
+inline v_uint16x8 v_reinterpret_as_u16(const v_##_Tpv& v) { return v_uint16x8(vreinterpretq_u16_##suffix(v.val)); } \
+inline v_int16x8 v_reinterpret_as_s16(const v_##_Tpv& v) { return v_int16x8(vreinterpretq_s16_##suffix(v.val)); } \
+inline v_uint32x4 v_reinterpret_as_u32(const v_##_Tpv& v) { return v_uint32x4(vreinterpretq_u32_##suffix(v.val)); } \
+inline v_int32x4 v_reinterpret_as_s32(const v_##_Tpv& v) { return v_int32x4(vreinterpretq_s32_##suffix(v.val)); } \
+inline v_uint64x2 v_reinterpret_as_u64(const v_##_Tpv& v) { return v_uint64x2(vreinterpretq_u64_##suffix(v.val)); } \
+inline v_int64x2 v_reinterpret_as_s64(const v_##_Tpv& v) { return v_int64x2(vreinterpretq_s64_##suffix(v.val)); } \
+inline v_float32x4 v_reinterpret_as_f32(const v_##_Tpv& v) { return v_float32x4(vreinterpretq_f32_##suffix(v.val)); }
+
+OPENCV_HAL_IMPL_NEON_INIT(uint8x16, uchar, u8)
+OPENCV_HAL_IMPL_NEON_INIT(int8x16, schar, s8)
+OPENCV_HAL_IMPL_NEON_INIT(uint16x8, ushort, u16)
+OPENCV_HAL_IMPL_NEON_INIT(int16x8, short, s16)
+OPENCV_HAL_IMPL_NEON_INIT(uint32x4, unsigned, u32)
+OPENCV_HAL_IMPL_NEON_INIT(int32x4, int, s32)
+OPENCV_HAL_IMPL_NEON_INIT(uint64x2, uint64, u64)
+OPENCV_HAL_IMPL_NEON_INIT(int64x2, int64, s64)
+OPENCV_HAL_IMPL_NEON_INIT(float32x4, float, f32)
+#if CV_SIMD128_64F
+#define OPENCV_HAL_IMPL_NEON_INIT_64(_Tpv, suffix) \
+inline v_float64x2 v_reinterpret_as_f64(const v_##_Tpv& v) { return v_float64x2(vreinterpretq_f64_##suffix(v.val)); }
+OPENCV_HAL_IMPL_NEON_INIT(float64x2, double, f64)
+OPENCV_HAL_IMPL_NEON_INIT_64(uint8x16, u8)
+OPENCV_HAL_IMPL_NEON_INIT_64(int8x16, s8)
+OPENCV_HAL_IMPL_NEON_INIT_64(uint16x8, u16)
+OPENCV_HAL_IMPL_NEON_INIT_64(int16x8, s16)
+OPENCV_HAL_IMPL_NEON_INIT_64(uint32x4, u32)
+OPENCV_HAL_IMPL_NEON_INIT_64(int32x4, s32)
+OPENCV_HAL_IMPL_NEON_INIT_64(uint64x2, u64)
+OPENCV_HAL_IMPL_NEON_INIT_64(int64x2, s64)
+OPENCV_HAL_IMPL_NEON_INIT_64(float32x4, f32)
+OPENCV_HAL_IMPL_NEON_INIT_64(float64x2, f64)
+#endif
+
+#define OPENCV_HAL_IMPL_NEON_PACK(_Tpvec, _Tp, hreg, suffix, _Tpwvec, wsuffix, pack, op) \
+inline _Tpvec v_##pack(const _Tpwvec& a, const _Tpwvec& b) \
+{ \
+ hreg a1 = vqmov##op##_##wsuffix(a.val), b1 = vqmov##op##_##wsuffix(b.val); \
+ return _Tpvec(vcombine_##suffix(a1, b1)); \
+} \
+inline void v_##pack##_store(_Tp* ptr, const _Tpwvec& a) \
+{ \
+ hreg a1 = vqmov##op##_##wsuffix(a.val); \
+ vst1_##suffix(ptr, a1); \
+} \
+template<int n> inline \
+_Tpvec v_rshr_##pack(const _Tpwvec& a, const _Tpwvec& b) \
+{ \
+ hreg a1 = vqrshr##op##_n_##wsuffix(a.val, n); \
+ hreg b1 = vqrshr##op##_n_##wsuffix(b.val, n); \
+ return _Tpvec(vcombine_##suffix(a1, b1)); \
+} \
+template<int n> inline \
+void v_rshr_##pack##_store(_Tp* ptr, const _Tpwvec& a) \
+{ \
+ hreg a1 = vqrshr##op##_n_##wsuffix(a.val, n); \
+ vst1_##suffix(ptr, a1); \
+}
+
+OPENCV_HAL_IMPL_NEON_PACK(v_uint8x16, uchar, uint8x8_t, u8, v_uint16x8, u16, pack, n)
+OPENCV_HAL_IMPL_NEON_PACK(v_int8x16, schar, int8x8_t, s8, v_int16x8, s16, pack, n)
+OPENCV_HAL_IMPL_NEON_PACK(v_uint16x8, ushort, uint16x4_t, u16, v_uint32x4, u32, pack, n)
+OPENCV_HAL_IMPL_NEON_PACK(v_int16x8, short, int16x4_t, s16, v_int32x4, s32, pack, n)
+OPENCV_HAL_IMPL_NEON_PACK(v_uint32x4, unsigned, uint32x2_t, u32, v_uint64x2, u64, pack, n)
+OPENCV_HAL_IMPL_NEON_PACK(v_int32x4, int, int32x2_t, s32, v_int64x2, s64, pack, n)
+
+OPENCV_HAL_IMPL_NEON_PACK(v_uint8x16, uchar, uint8x8_t, u8, v_int16x8, s16, pack_u, un)
+OPENCV_HAL_IMPL_NEON_PACK(v_uint16x8, ushort, uint16x4_t, u16, v_int32x4, s32, pack_u, un)
+
+inline v_float32x4 v_matmul(const v_float32x4& v, const v_float32x4& m0,
+ const v_float32x4& m1, const v_float32x4& m2,
+ const v_float32x4& m3)
+{
+ float32x2_t vl = vget_low_f32(v.val), vh = vget_high_f32(v.val);
+ float32x4_t res = vmulq_lane_f32(m0.val, vl, 0);
+ res = vmlaq_lane_f32(res, m1.val, vl, 1);
+ res = vmlaq_lane_f32(res, m2.val, vh, 0);
+ res = vmlaq_lane_f32(res, m3.val, vh, 1);
+ return v_float32x4(res);
+}
+
+#define OPENCV_HAL_IMPL_NEON_BIN_OP(bin_op, _Tpvec, intrin) \
+inline _Tpvec operator bin_op (const _Tpvec& a, const _Tpvec& b) \
+{ \
+ return _Tpvec(intrin(a.val, b.val)); \
+} \
+inline _Tpvec& operator bin_op##= (_Tpvec& a, const _Tpvec& b) \
+{ \
+ a.val = intrin(a.val, b.val); \
+ return a; \
+}
+
+OPENCV_HAL_IMPL_NEON_BIN_OP(+, v_uint8x16, vqaddq_u8)
+OPENCV_HAL_IMPL_NEON_BIN_OP(-, v_uint8x16, vqsubq_u8)
+OPENCV_HAL_IMPL_NEON_BIN_OP(+, v_int8x16, vqaddq_s8)
+OPENCV_HAL_IMPL_NEON_BIN_OP(-, v_int8x16, vqsubq_s8)
+OPENCV_HAL_IMPL_NEON_BIN_OP(+, v_uint16x8, vqaddq_u16)
+OPENCV_HAL_IMPL_NEON_BIN_OP(-, v_uint16x8, vqsubq_u16)
+OPENCV_HAL_IMPL_NEON_BIN_OP(*, v_uint16x8, vmulq_u16)
+OPENCV_HAL_IMPL_NEON_BIN_OP(+, v_int16x8, vqaddq_s16)
+OPENCV_HAL_IMPL_NEON_BIN_OP(-, v_int16x8, vqsubq_s16)
+OPENCV_HAL_IMPL_NEON_BIN_OP(*, v_int16x8, vmulq_s16)
+OPENCV_HAL_IMPL_NEON_BIN_OP(+, v_int32x4, vaddq_s32)
+OPENCV_HAL_IMPL_NEON_BIN_OP(-, v_int32x4, vsubq_s32)
+OPENCV_HAL_IMPL_NEON_BIN_OP(*, v_int32x4, vmulq_s32)
+OPENCV_HAL_IMPL_NEON_BIN_OP(+, v_uint32x4, vaddq_u32)
+OPENCV_HAL_IMPL_NEON_BIN_OP(-, v_uint32x4, vsubq_u32)
+OPENCV_HAL_IMPL_NEON_BIN_OP(*, v_uint32x4, vmulq_u32)
+OPENCV_HAL_IMPL_NEON_BIN_OP(+, v_float32x4, vaddq_f32)
+OPENCV_HAL_IMPL_NEON_BIN_OP(-, v_float32x4, vsubq_f32)
+OPENCV_HAL_IMPL_NEON_BIN_OP(*, v_float32x4, vmulq_f32)
+OPENCV_HAL_IMPL_NEON_BIN_OP(+, v_int64x2, vaddq_s64)
+OPENCV_HAL_IMPL_NEON_BIN_OP(-, v_int64x2, vsubq_s64)
+OPENCV_HAL_IMPL_NEON_BIN_OP(+, v_uint64x2, vaddq_u64)
+OPENCV_HAL_IMPL_NEON_BIN_OP(-, v_uint64x2, vsubq_u64)
+#if CV_SIMD128_64F
+OPENCV_HAL_IMPL_NEON_BIN_OP(/, v_float32x4, vdivq_f32)
+OPENCV_HAL_IMPL_NEON_BIN_OP(+, v_float64x2, vaddq_f64)
+OPENCV_HAL_IMPL_NEON_BIN_OP(-, v_float64x2, vsubq_f64)
+OPENCV_HAL_IMPL_NEON_BIN_OP(*, v_float64x2, vmulq_f64)
+OPENCV_HAL_IMPL_NEON_BIN_OP(/, v_float64x2, vdivq_f64)
+#else
+inline v_float32x4 operator / (const v_float32x4& a, const v_float32x4& b)
+{
+ float32x4_t reciprocal = vrecpeq_f32(b.val);
+ reciprocal = vmulq_f32(vrecpsq_f32(b.val, reciprocal), reciprocal);
+ reciprocal = vmulq_f32(vrecpsq_f32(b.val, reciprocal), reciprocal);
+ return v_float32x4(vmulq_f32(a.val, reciprocal));
+}
+inline v_float32x4& operator /= (v_float32x4& a, const v_float32x4& b)
+{
+ float32x4_t reciprocal = vrecpeq_f32(b.val);
+ reciprocal = vmulq_f32(vrecpsq_f32(b.val, reciprocal), reciprocal);
+ reciprocal = vmulq_f32(vrecpsq_f32(b.val, reciprocal), reciprocal);
+ a.val = vmulq_f32(a.val, reciprocal);
+ return a;
+}
+#endif
+
+inline void v_mul_expand(const v_int16x8& a, const v_int16x8& b,
+ v_int32x4& c, v_int32x4& d)
+{
+ c.val = vmull_s16(vget_low_s16(a.val), vget_low_s16(b.val));
+ d.val = vmull_s16(vget_high_s16(a.val), vget_high_s16(b.val));
+}
+
+inline void v_mul_expand(const v_uint16x8& a, const v_uint16x8& b,
+ v_uint32x4& c, v_uint32x4& d)
+{
+ c.val = vmull_u16(vget_low_u16(a.val), vget_low_u16(b.val));
+ d.val = vmull_u16(vget_high_u16(a.val), vget_high_u16(b.val));
+}
+
+inline void v_mul_expand(const v_uint32x4& a, const v_uint32x4& b,
+ v_uint64x2& c, v_uint64x2& d)
+{
+ c.val = vmull_u32(vget_low_u32(a.val), vget_low_u32(b.val));
+ d.val = vmull_u32(vget_high_u32(a.val), vget_high_u32(b.val));
+}
+
+inline v_int32x4 v_dotprod(const v_int16x8& a, const v_int16x8& b)
+{
+ int32x4_t c = vmull_s16(vget_low_s16(a.val), vget_low_s16(b.val));
+ int32x4_t d = vmull_s16(vget_high_s16(a.val), vget_high_s16(b.val));
+ int32x4x2_t cd = vuzpq_s32(c, d);
+ return v_int32x4(vaddq_s32(cd.val[0], cd.val[1]));
+}
+
+#define OPENCV_HAL_IMPL_NEON_LOGIC_OP(_Tpvec, suffix) \
+ OPENCV_HAL_IMPL_NEON_BIN_OP(&, _Tpvec, vandq_##suffix) \
+ OPENCV_HAL_IMPL_NEON_BIN_OP(|, _Tpvec, vorrq_##suffix) \
+ OPENCV_HAL_IMPL_NEON_BIN_OP(^, _Tpvec, veorq_##suffix) \
+ inline _Tpvec operator ~ (const _Tpvec& a) \
+ { \
+ return _Tpvec(vreinterpretq_##suffix##_u8(vmvnq_u8(vreinterpretq_u8_##suffix(a.val)))); \
+ }
+
+OPENCV_HAL_IMPL_NEON_LOGIC_OP(v_uint8x16, u8)
+OPENCV_HAL_IMPL_NEON_LOGIC_OP(v_int8x16, s8)
+OPENCV_HAL_IMPL_NEON_LOGIC_OP(v_uint16x8, u16)
+OPENCV_HAL_IMPL_NEON_LOGIC_OP(v_int16x8, s16)
+OPENCV_HAL_IMPL_NEON_LOGIC_OP(v_uint32x4, u32)
+OPENCV_HAL_IMPL_NEON_LOGIC_OP(v_int32x4, s32)
+OPENCV_HAL_IMPL_NEON_LOGIC_OP(v_uint64x2, u64)
+OPENCV_HAL_IMPL_NEON_LOGIC_OP(v_int64x2, s64)
+
+#define OPENCV_HAL_IMPL_NEON_FLT_BIT_OP(bin_op, intrin) \
+inline v_float32x4 operator bin_op (const v_float32x4& a, const v_float32x4& b) \
+{ \
+ return v_float32x4(vreinterpretq_f32_s32(intrin(vreinterpretq_s32_f32(a.val), vreinterpretq_s32_f32(b.val)))); \
+} \
+inline v_float32x4& operator bin_op##= (v_float32x4& a, const v_float32x4& b) \
+{ \
+ a.val = vreinterpretq_f32_s32(intrin(vreinterpretq_s32_f32(a.val), vreinterpretq_s32_f32(b.val))); \
+ return a; \
+}
+
+OPENCV_HAL_IMPL_NEON_FLT_BIT_OP(&, vandq_s32)
+OPENCV_HAL_IMPL_NEON_FLT_BIT_OP(|, vorrq_s32)
+OPENCV_HAL_IMPL_NEON_FLT_BIT_OP(^, veorq_s32)
+
+inline v_float32x4 operator ~ (const v_float32x4& a)
+{
+ return v_float32x4(vreinterpretq_f32_s32(vmvnq_s32(vreinterpretq_s32_f32(a.val))));
+}
+
+#if CV_SIMD128_64F
+inline v_float32x4 v_sqrt(const v_float32x4& x)
+{
+ return v_float32x4(vsqrtq_f32(x.val));
+}
+
+inline v_float32x4 v_invsqrt(const v_float32x4& x)
+{
+ v_float32x4 one = v_setall_f32(1.0f);
+ return one / v_sqrt(x);
+}
+#else
+inline v_float32x4 v_sqrt(const v_float32x4& x)
+{
+ float32x4_t x1 = vmaxq_f32(x.val, vdupq_n_f32(FLT_MIN));
+ float32x4_t e = vrsqrteq_f32(x1);
+ e = vmulq_f32(vrsqrtsq_f32(vmulq_f32(x1, e), e), e);
+ e = vmulq_f32(vrsqrtsq_f32(vmulq_f32(x1, e), e), e);
+ return v_float32x4(vmulq_f32(x.val, e));
+}
+
+inline v_float32x4 v_invsqrt(const v_float32x4& x)
+{
+ float32x4_t e = vrsqrteq_f32(x.val);
+ e = vmulq_f32(vrsqrtsq_f32(vmulq_f32(x.val, e), e), e);
+ e = vmulq_f32(vrsqrtsq_f32(vmulq_f32(x.val, e), e), e);
+ return v_float32x4(e);
+}
+#endif
+
+#define OPENCV_HAL_IMPL_NEON_ABS(_Tpuvec, _Tpsvec, usuffix, ssuffix) \
+inline _Tpuvec v_abs(const _Tpsvec& a) { return v_reinterpret_as_##usuffix(_Tpsvec(vabsq_##ssuffix(a.val))); }
+
+OPENCV_HAL_IMPL_NEON_ABS(v_uint8x16, v_int8x16, u8, s8)
+OPENCV_HAL_IMPL_NEON_ABS(v_uint16x8, v_int16x8, u16, s16)
+OPENCV_HAL_IMPL_NEON_ABS(v_uint32x4, v_int32x4, u32, s32)
+
+inline v_float32x4 v_abs(v_float32x4 x)
+{ return v_float32x4(vabsq_f32(x.val)); }
+
+#if CV_SIMD128_64F
+#define OPENCV_HAL_IMPL_NEON_DBL_BIT_OP(bin_op, intrin) \
+inline v_float64x2 operator bin_op (const v_float64x2& a, const v_float64x2& b) \
+{ \
+ return v_float64x2(vreinterpretq_f64_s64(intrin(vreinterpretq_s64_f64(a.val), vreinterpretq_s64_f64(b.val)))); \
+} \
+inline v_float64x2& operator bin_op##= (v_float64x2& a, const v_float64x2& b) \
+{ \
+ a.val = vreinterpretq_f64_s64(intrin(vreinterpretq_s64_f64(a.val), vreinterpretq_s64_f64(b.val))); \
+ return a; \
+}
+
+OPENCV_HAL_IMPL_NEON_DBL_BIT_OP(&, vandq_s64)
+OPENCV_HAL_IMPL_NEON_DBL_BIT_OP(|, vorrq_s64)
+OPENCV_HAL_IMPL_NEON_DBL_BIT_OP(^, veorq_s64)
+
+inline v_float64x2 operator ~ (const v_float64x2& a)
+{
+ return v_float64x2(vreinterpretq_f64_s32(vmvnq_s32(vreinterpretq_s32_f64(a.val))));
+}
+
+inline v_float64x2 v_sqrt(const v_float64x2& x)
+{
+ return v_float64x2(vsqrtq_f64(x.val));
+}
+
+inline v_float64x2 v_invsqrt(const v_float64x2& x)
+{
+ v_float64x2 one = v_setall_f64(1.0f);
+ return one / v_sqrt(x);
+}
+
+inline v_float64x2 v_abs(v_float64x2 x)
+{ return v_float64x2(vabsq_f64(x.val)); }
+#endif
+
+// TODO: exp, log, sin, cos
+
+#define OPENCV_HAL_IMPL_NEON_BIN_FUNC(_Tpvec, func, intrin) \
+inline _Tpvec func(const _Tpvec& a, const _Tpvec& b) \
+{ \
+ return _Tpvec(intrin(a.val, b.val)); \
+}
+
+OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_uint8x16, v_min, vminq_u8)
+OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_uint8x16, v_max, vmaxq_u8)
+OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_int8x16, v_min, vminq_s8)
+OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_int8x16, v_max, vmaxq_s8)
+OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_uint16x8, v_min, vminq_u16)
+OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_uint16x8, v_max, vmaxq_u16)
+OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_int16x8, v_min, vminq_s16)
+OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_int16x8, v_max, vmaxq_s16)
+OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_uint32x4, v_min, vminq_u32)
+OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_uint32x4, v_max, vmaxq_u32)
+OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_int32x4, v_min, vminq_s32)
+OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_int32x4, v_max, vmaxq_s32)
+OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_float32x4, v_min, vminq_f32)
+OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_float32x4, v_max, vmaxq_f32)
+#if CV_SIMD128_64F
+OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_float64x2, v_min, vminq_f64)
+OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_float64x2, v_max, vmaxq_f64)
+#endif
+
+#if CV_SIMD128_64F
+inline int64x2_t vmvnq_s64(int64x2_t a)
+{
+ int64x2_t vx = vreinterpretq_s64_u32(vdupq_n_u32(0xFFFFFFFF));
+ return veorq_s64(a, vx);
+}
+inline uint64x2_t vmvnq_u64(uint64x2_t a)
+{
+ uint64x2_t vx = vreinterpretq_u64_u32(vdupq_n_u32(0xFFFFFFFF));
+ return veorq_u64(a, vx);
+}
+#endif
+#define OPENCV_HAL_IMPL_NEON_INT_CMP_OP(_Tpvec, cast, suffix, not_suffix) \
+inline _Tpvec operator == (const _Tpvec& a, const _Tpvec& b) \
+{ return _Tpvec(cast(vceqq_##suffix(a.val, b.val))); } \
+inline _Tpvec operator != (const _Tpvec& a, const _Tpvec& b) \
+{ return _Tpvec(cast(vmvnq_##not_suffix(vceqq_##suffix(a.val, b.val)))); } \
+inline _Tpvec operator < (const _Tpvec& a, const _Tpvec& b) \
+{ return _Tpvec(cast(vcltq_##suffix(a.val, b.val))); } \
+inline _Tpvec operator > (const _Tpvec& a, const _Tpvec& b) \
+{ return _Tpvec(cast(vcgtq_##suffix(a.val, b.val))); } \
+inline _Tpvec operator <= (const _Tpvec& a, const _Tpvec& b) \
+{ return _Tpvec(cast(vcleq_##suffix(a.val, b.val))); } \
+inline _Tpvec operator >= (const _Tpvec& a, const _Tpvec& b) \
+{ return _Tpvec(cast(vcgeq_##suffix(a.val, b.val))); }
+
+OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_uint8x16, OPENCV_HAL_NOP, u8, u8)
+OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_int8x16, vreinterpretq_s8_u8, s8, u8)
+OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_uint16x8, OPENCV_HAL_NOP, u16, u16)
+OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_int16x8, vreinterpretq_s16_u16, s16, u16)
+OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_uint32x4, OPENCV_HAL_NOP, u32, u32)
+OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_int32x4, vreinterpretq_s32_u32, s32, u32)
+OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_float32x4, vreinterpretq_f32_u32, f32, u32)
+#if CV_SIMD128_64F
+OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_uint64x2, OPENCV_HAL_NOP, u64, u64)
+OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_int64x2, vreinterpretq_s64_u64, s64, u64)
+OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_float64x2, vreinterpretq_f64_u64, f64, u64)
+#endif
+
+OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_uint8x16, v_add_wrap, vaddq_u8)
+OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_int8x16, v_add_wrap, vaddq_s8)
+OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_uint16x8, v_add_wrap, vaddq_u16)
+OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_int16x8, v_add_wrap, vaddq_s16)
+OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_uint8x16, v_sub_wrap, vsubq_u8)
+OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_int8x16, v_sub_wrap, vsubq_s8)
+OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_uint16x8, v_sub_wrap, vsubq_u16)
+OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_int16x8, v_sub_wrap, vsubq_s16)
+
+// TODO: absdiff for signed integers
+OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_uint8x16, v_absdiff, vabdq_u8)
+OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_uint16x8, v_absdiff, vabdq_u16)
+OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_uint32x4, v_absdiff, vabdq_u32)
+OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_float32x4, v_absdiff, vabdq_f32)
+#if CV_SIMD128_64F
+OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_float64x2, v_absdiff, vabdq_f64)
+#endif
+
+#define OPENCV_HAL_IMPL_NEON_BIN_FUNC2(_Tpvec, _Tpvec2, cast, func, intrin) \
+inline _Tpvec2 func(const _Tpvec& a, const _Tpvec& b) \
+{ \
+ return _Tpvec2(cast(intrin(a.val, b.val))); \
+}
+
+OPENCV_HAL_IMPL_NEON_BIN_FUNC2(v_int8x16, v_uint8x16, vreinterpretq_u8_s8, v_absdiff, vabdq_s8)
+OPENCV_HAL_IMPL_NEON_BIN_FUNC2(v_int16x8, v_uint16x8, vreinterpretq_u16_s16, v_absdiff, vabdq_s16)
+OPENCV_HAL_IMPL_NEON_BIN_FUNC2(v_int32x4, v_uint32x4, vreinterpretq_u32_s32, v_absdiff, vabdq_s32)
+
+inline v_float32x4 v_magnitude(const v_float32x4& a, const v_float32x4& b)
+{
+ v_float32x4 x(vmlaq_f32(vmulq_f32(a.val, a.val), b.val, b.val));
+ return v_sqrt(x);
+}
+
+inline v_float32x4 v_sqr_magnitude(const v_float32x4& a, const v_float32x4& b)
+{
+ return v_float32x4(vmlaq_f32(vmulq_f32(a.val, a.val), b.val, b.val));
+}
+
+inline v_float32x4 v_muladd(const v_float32x4& a, const v_float32x4& b, const v_float32x4& c)
+{
+ return v_float32x4(vmlaq_f32(c.val, a.val, b.val));
+}
+
+#if CV_SIMD128_64F
+inline v_float64x2 v_magnitude(const v_float64x2& a, const v_float64x2& b)
+{
+ v_float64x2 x(vaddq_f64(vmulq_f64(a.val, a.val), vmulq_f64(b.val, b.val)));
+ return v_sqrt(x);
+}
+
+inline v_float64x2 v_sqr_magnitude(const v_float64x2& a, const v_float64x2& b)
+{
+ return v_float64x2(vaddq_f64(vmulq_f64(a.val, a.val), vmulq_f64(b.val, b.val)));
+}
+
+inline v_float64x2 v_muladd(const v_float64x2& a, const v_float64x2& b, const v_float64x2& c)
+{
+ return v_float64x2(vaddq_f64(c.val, vmulq_f64(a.val, b.val)));
+}
+#endif
+
+// trade efficiency for convenience
+#define OPENCV_HAL_IMPL_NEON_SHIFT_OP(_Tpvec, suffix, _Tps, ssuffix) \
+inline _Tpvec operator << (const _Tpvec& a, int n) \
+{ return _Tpvec(vshlq_##suffix(a.val, vdupq_n_##ssuffix((_Tps)n))); } \
+inline _Tpvec operator >> (const _Tpvec& a, int n) \
+{ return _Tpvec(vshlq_##suffix(a.val, vdupq_n_##ssuffix((_Tps)-n))); } \
+template<int n> inline _Tpvec v_shl(const _Tpvec& a) \
+{ return _Tpvec(vshlq_n_##suffix(a.val, n)); } \
+template<int n> inline _Tpvec v_shr(const _Tpvec& a) \
+{ return _Tpvec(vshrq_n_##suffix(a.val, n)); } \
+template<int n> inline _Tpvec v_rshr(const _Tpvec& a) \
+{ return _Tpvec(vrshrq_n_##suffix(a.val, n)); }
+
+OPENCV_HAL_IMPL_NEON_SHIFT_OP(v_uint8x16, u8, schar, s8)
+OPENCV_HAL_IMPL_NEON_SHIFT_OP(v_int8x16, s8, schar, s8)
+OPENCV_HAL_IMPL_NEON_SHIFT_OP(v_uint16x8, u16, short, s16)
+OPENCV_HAL_IMPL_NEON_SHIFT_OP(v_int16x8, s16, short, s16)
+OPENCV_HAL_IMPL_NEON_SHIFT_OP(v_uint32x4, u32, int, s32)
+OPENCV_HAL_IMPL_NEON_SHIFT_OP(v_int32x4, s32, int, s32)
+OPENCV_HAL_IMPL_NEON_SHIFT_OP(v_uint64x2, u64, int64, s64)
+OPENCV_HAL_IMPL_NEON_SHIFT_OP(v_int64x2, s64, int64, s64)
+
+#define OPENCV_HAL_IMPL_NEON_LOADSTORE_OP(_Tpvec, _Tp, suffix) \
+inline _Tpvec v_load(const _Tp* ptr) \
+{ return _Tpvec(vld1q_##suffix(ptr)); } \
+inline _Tpvec v_load_aligned(const _Tp* ptr) \
+{ return _Tpvec(vld1q_##suffix(ptr)); } \
+inline _Tpvec v_load_halves(const _Tp* ptr0, const _Tp* ptr1) \
+{ return _Tpvec(vcombine_##suffix(vld1_##suffix(ptr0), vld1_##suffix(ptr1))); } \
+inline void v_store(_Tp* ptr, const _Tpvec& a) \
+{ vst1q_##suffix(ptr, a.val); } \
+inline void v_store_aligned(_Tp* ptr, const _Tpvec& a) \
+{ vst1q_##suffix(ptr, a.val); } \
+inline void v_store_low(_Tp* ptr, const _Tpvec& a) \
+{ vst1_##suffix(ptr, vget_low_##suffix(a.val)); } \
+inline void v_store_high(_Tp* ptr, const _Tpvec& a) \
+{ vst1_##suffix(ptr, vget_high_##suffix(a.val)); }
+
+OPENCV_HAL_IMPL_NEON_LOADSTORE_OP(v_uint8x16, uchar, u8)
+OPENCV_HAL_IMPL_NEON_LOADSTORE_OP(v_int8x16, schar, s8)
+OPENCV_HAL_IMPL_NEON_LOADSTORE_OP(v_uint16x8, ushort, u16)
+OPENCV_HAL_IMPL_NEON_LOADSTORE_OP(v_int16x8, short, s16)
+OPENCV_HAL_IMPL_NEON_LOADSTORE_OP(v_uint32x4, unsigned, u32)
+OPENCV_HAL_IMPL_NEON_LOADSTORE_OP(v_int32x4, int, s32)
+OPENCV_HAL_IMPL_NEON_LOADSTORE_OP(v_uint64x2, uint64, u64)
+OPENCV_HAL_IMPL_NEON_LOADSTORE_OP(v_int64x2, int64, s64)
+OPENCV_HAL_IMPL_NEON_LOADSTORE_OP(v_float32x4, float, f32)
+#if CV_SIMD128_64F
+OPENCV_HAL_IMPL_NEON_LOADSTORE_OP(v_float64x2, double, f64)
+#endif
+
+#if defined (HAVE_FP16)
+// Workaround for old comiplers
+inline v_float16x4 v_load_f16(const short* ptr)
+{ return v_float16x4(vld1_f16(ptr)); }
+inline void v_store_f16(short* ptr, v_float16x4& a)
+{ vst1_f16(ptr, a.val); }
+#endif
+
+#define OPENCV_HAL_IMPL_NEON_REDUCE_OP_8(_Tpvec, _Tpnvec, scalartype, func, vectorfunc, suffix) \
+inline scalartype v_reduce_##func(const _Tpvec& a) \
+{ \
+ _Tpnvec##_t a0 = vp##vectorfunc##_##suffix(vget_low_##suffix(a.val), vget_high_##suffix(a.val)); \
+ a0 = vp##vectorfunc##_##suffix(a0, a0); \
+ return (scalartype)vget_lane_##suffix(vp##vectorfunc##_##suffix(a0, a0),0); \
+}
+
+OPENCV_HAL_IMPL_NEON_REDUCE_OP_8(v_uint16x8, uint16x4, unsigned short, sum, add, u16)
+OPENCV_HAL_IMPL_NEON_REDUCE_OP_8(v_uint16x8, uint16x4, unsigned short, max, max, u16)
+OPENCV_HAL_IMPL_NEON_REDUCE_OP_8(v_uint16x8, uint16x4, unsigned short, min, min, u16)
+OPENCV_HAL_IMPL_NEON_REDUCE_OP_8(v_int16x8, int16x4, short, sum, add, s16)
+OPENCV_HAL_IMPL_NEON_REDUCE_OP_8(v_int16x8, int16x4, short, max, max, s16)
+OPENCV_HAL_IMPL_NEON_REDUCE_OP_8(v_int16x8, int16x4, short, min, min, s16)
+
+#define OPENCV_HAL_IMPL_NEON_REDUCE_OP_4(_Tpvec, _Tpnvec, scalartype, func, vectorfunc, suffix) \
+inline scalartype v_reduce_##func(const _Tpvec& a) \
+{ \
+ _Tpnvec##_t a0 = vp##vectorfunc##_##suffix(vget_low_##suffix(a.val), vget_high_##suffix(a.val)); \
+ return (scalartype)vget_lane_##suffix(vp##vectorfunc##_##suffix(a0, vget_high_##suffix(a.val)),0); \
+}
+
+OPENCV_HAL_IMPL_NEON_REDUCE_OP_4(v_uint32x4, uint32x2, unsigned, sum, add, u32)
+OPENCV_HAL_IMPL_NEON_REDUCE_OP_4(v_uint32x4, uint32x2, unsigned, max, max, u32)
+OPENCV_HAL_IMPL_NEON_REDUCE_OP_4(v_uint32x4, uint32x2, unsigned, min, min, u32)
+OPENCV_HAL_IMPL_NEON_REDUCE_OP_4(v_int32x4, int32x2, int, sum, add, s32)
+OPENCV_HAL_IMPL_NEON_REDUCE_OP_4(v_int32x4, int32x2, int, max, max, s32)
+OPENCV_HAL_IMPL_NEON_REDUCE_OP_4(v_int32x4, int32x2, int, min, min, s32)
+OPENCV_HAL_IMPL_NEON_REDUCE_OP_4(v_float32x4, float32x2, float, sum, add, f32)
+OPENCV_HAL_IMPL_NEON_REDUCE_OP_4(v_float32x4, float32x2, float, max, max, f32)
+OPENCV_HAL_IMPL_NEON_REDUCE_OP_4(v_float32x4, float32x2, float, min, min, f32)
+
+inline int v_signmask(const v_uint8x16& a)
+{
+ int8x8_t m0 = vcreate_s8(CV_BIG_UINT(0x0706050403020100));
+ uint8x16_t v0 = vshlq_u8(vshrq_n_u8(a.val, 7), vcombine_s8(m0, m0));
+ uint64x2_t v1 = vpaddlq_u32(vpaddlq_u16(vpaddlq_u8(v0)));
+ return (int)vgetq_lane_u64(v1, 0) + ((int)vgetq_lane_u64(v1, 1) << 8);
+}
+inline int v_signmask(const v_int8x16& a)
+{ return v_signmask(v_reinterpret_as_u8(a)); }
+
+inline int v_signmask(const v_uint16x8& a)
+{
+ int16x4_t m0 = vcreate_s16(CV_BIG_UINT(0x0003000200010000));
+ uint16x8_t v0 = vshlq_u16(vshrq_n_u16(a.val, 15), vcombine_s16(m0, m0));
+ uint64x2_t v1 = vpaddlq_u32(vpaddlq_u16(v0));
+ return (int)vgetq_lane_u64(v1, 0) + ((int)vgetq_lane_u64(v1, 1) << 4);
+}
+inline int v_signmask(const v_int16x8& a)
+{ return v_signmask(v_reinterpret_as_u16(a)); }
+
+inline int v_signmask(const v_uint32x4& a)
+{
+ int32x2_t m0 = vcreate_s32(CV_BIG_UINT(0x0000000100000000));
+ uint32x4_t v0 = vshlq_u32(vshrq_n_u32(a.val, 31), vcombine_s32(m0, m0));
+ uint64x2_t v1 = vpaddlq_u32(v0);
+ return (int)vgetq_lane_u64(v1, 0) + ((int)vgetq_lane_u64(v1, 1) << 2);
+}
+inline int v_signmask(const v_int32x4& a)
+{ return v_signmask(v_reinterpret_as_u32(a)); }
+inline int v_signmask(const v_float32x4& a)
+{ return v_signmask(v_reinterpret_as_u32(a)); }
+#if CV_SIMD128_64F
+inline int v_signmask(const v_uint64x2& a)
+{
+ int64x1_t m0 = vdup_n_s64(0);
+ uint64x2_t v0 = vshlq_u64(vshrq_n_u64(a.val, 63), vcombine_s64(m0, m0));
+ return (int)vgetq_lane_u64(v0, 0) + ((int)vgetq_lane_u64(v0, 1) << 1);
+}
+inline int v_signmask(const v_float64x2& a)
+{ return v_signmask(v_reinterpret_as_u64(a)); }
+#endif
+
+#define OPENCV_HAL_IMPL_NEON_CHECK_ALLANY(_Tpvec, suffix, shift) \
+inline bool v_check_all(const v_##_Tpvec& a) \
+{ \
+ _Tpvec##_t v0 = vshrq_n_##suffix(vmvnq_##suffix(a.val), shift); \
+ uint64x2_t v1 = vreinterpretq_u64_##suffix(v0); \
+ return (vgetq_lane_u64(v1, 0) | vgetq_lane_u64(v1, 1)) == 0; \
+} \
+inline bool v_check_any(const v_##_Tpvec& a) \
+{ \
+ _Tpvec##_t v0 = vshrq_n_##suffix(a.val, shift); \
+ uint64x2_t v1 = vreinterpretq_u64_##suffix(v0); \
+ return (vgetq_lane_u64(v1, 0) | vgetq_lane_u64(v1, 1)) != 0; \
+}
+
+OPENCV_HAL_IMPL_NEON_CHECK_ALLANY(uint8x16, u8, 7)
+OPENCV_HAL_IMPL_NEON_CHECK_ALLANY(uint16x8, u16, 15)
+OPENCV_HAL_IMPL_NEON_CHECK_ALLANY(uint32x4, u32, 31)
+#if CV_SIMD128_64F
+OPENCV_HAL_IMPL_NEON_CHECK_ALLANY(uint64x2, u64, 63)
+#endif
+
+inline bool v_check_all(const v_int8x16& a)
+{ return v_check_all(v_reinterpret_as_u8(a)); }
+inline bool v_check_all(const v_int16x8& a)
+{ return v_check_all(v_reinterpret_as_u16(a)); }
+inline bool v_check_all(const v_int32x4& a)
+{ return v_check_all(v_reinterpret_as_u32(a)); }
+inline bool v_check_all(const v_float32x4& a)
+{ return v_check_all(v_reinterpret_as_u32(a)); }
+
+inline bool v_check_any(const v_int8x16& a)
+{ return v_check_any(v_reinterpret_as_u8(a)); }
+inline bool v_check_any(const v_int16x8& a)
+{ return v_check_any(v_reinterpret_as_u16(a)); }
+inline bool v_check_any(const v_int32x4& a)
+{ return v_check_any(v_reinterpret_as_u32(a)); }
+inline bool v_check_any(const v_float32x4& a)
+{ return v_check_any(v_reinterpret_as_u32(a)); }
+
+#if CV_SIMD128_64F
+inline bool v_check_all(const v_int64x2& a)
+{ return v_check_all(v_reinterpret_as_u64(a)); }
+inline bool v_check_all(const v_float64x2& a)
+{ return v_check_all(v_reinterpret_as_u64(a)); }
+inline bool v_check_any(const v_int64x2& a)
+{ return v_check_any(v_reinterpret_as_u64(a)); }
+inline bool v_check_any(const v_float64x2& a)
+{ return v_check_any(v_reinterpret_as_u64(a)); }
+#endif
+
+#define OPENCV_HAL_IMPL_NEON_SELECT(_Tpvec, suffix, usuffix) \
+inline _Tpvec v_select(const _Tpvec& mask, const _Tpvec& a, const _Tpvec& b) \
+{ \
+ return _Tpvec(vbslq_##suffix(vreinterpretq_##usuffix##_##suffix(mask.val), a.val, b.val)); \
+}
+
+OPENCV_HAL_IMPL_NEON_SELECT(v_uint8x16, u8, u8)
+OPENCV_HAL_IMPL_NEON_SELECT(v_int8x16, s8, u8)
+OPENCV_HAL_IMPL_NEON_SELECT(v_uint16x8, u16, u16)
+OPENCV_HAL_IMPL_NEON_SELECT(v_int16x8, s16, u16)
+OPENCV_HAL_IMPL_NEON_SELECT(v_uint32x4, u32, u32)
+OPENCV_HAL_IMPL_NEON_SELECT(v_int32x4, s32, u32)
+OPENCV_HAL_IMPL_NEON_SELECT(v_float32x4, f32, u32)
+#if CV_SIMD128_64F
+OPENCV_HAL_IMPL_NEON_SELECT(v_float64x2, f64, u64)
+#endif
+
+#define OPENCV_HAL_IMPL_NEON_EXPAND(_Tpvec, _Tpwvec, _Tp, suffix) \
+inline void v_expand(const _Tpvec& a, _Tpwvec& b0, _Tpwvec& b1) \
+{ \
+ b0.val = vmovl_##suffix(vget_low_##suffix(a.val)); \
+ b1.val = vmovl_##suffix(vget_high_##suffix(a.val)); \
+} \
+inline _Tpwvec v_load_expand(const _Tp* ptr) \
+{ \
+ return _Tpwvec(vmovl_##suffix(vld1_##suffix(ptr))); \
+}
+
+OPENCV_HAL_IMPL_NEON_EXPAND(v_uint8x16, v_uint16x8, uchar, u8)
+OPENCV_HAL_IMPL_NEON_EXPAND(v_int8x16, v_int16x8, schar, s8)
+OPENCV_HAL_IMPL_NEON_EXPAND(v_uint16x8, v_uint32x4, ushort, u16)
+OPENCV_HAL_IMPL_NEON_EXPAND(v_int16x8, v_int32x4, short, s16)
+OPENCV_HAL_IMPL_NEON_EXPAND(v_uint32x4, v_uint64x2, uint, u32)
+OPENCV_HAL_IMPL_NEON_EXPAND(v_int32x4, v_int64x2, int, s32)
+
+inline v_uint32x4 v_load_expand_q(const uchar* ptr)
+{
+ uint8x8_t v0 = vcreate_u8(*(unsigned*)ptr);
+ uint16x4_t v1 = vget_low_u16(vmovl_u8(v0));
+ return v_uint32x4(vmovl_u16(v1));
+}
+
+inline v_int32x4 v_load_expand_q(const schar* ptr)
+{
+ int8x8_t v0 = vcreate_s8(*(unsigned*)ptr);
+ int16x4_t v1 = vget_low_s16(vmovl_s8(v0));
+ return v_int32x4(vmovl_s16(v1));
+}
+
+#if defined(__aarch64__)
+#define OPENCV_HAL_IMPL_NEON_UNPACKS(_Tpvec, suffix) \
+inline void v_zip(const v_##_Tpvec& a0, const v_##_Tpvec& a1, v_##_Tpvec& b0, v_##_Tpvec& b1) \
+{ \
+ b0.val = vzip1q_##suffix(a0.val, a1.val); \
+ b1.val = vzip2q_##suffix(a0.val, a1.val); \
+} \
+inline v_##_Tpvec v_combine_low(const v_##_Tpvec& a, const v_##_Tpvec& b) \
+{ \
+ return v_##_Tpvec(vcombine_##suffix(vget_low_##suffix(a.val), vget_low_##suffix(b.val))); \
+} \
+inline v_##_Tpvec v_combine_high(const v_##_Tpvec& a, const v_##_Tpvec& b) \
+{ \
+ return v_##_Tpvec(vcombine_##suffix(vget_high_##suffix(a.val), vget_high_##suffix(b.val))); \
+} \
+inline void v_recombine(const v_##_Tpvec& a, const v_##_Tpvec& b, v_##_Tpvec& c, v_##_Tpvec& d) \
+{ \
+ c.val = vcombine_##suffix(vget_low_##suffix(a.val), vget_low_##suffix(b.val)); \
+ d.val = vcombine_##suffix(vget_high_##suffix(a.val), vget_high_##suffix(b.val)); \
+}
+#else
+#define OPENCV_HAL_IMPL_NEON_UNPACKS(_Tpvec, suffix) \
+inline void v_zip(const v_##_Tpvec& a0, const v_##_Tpvec& a1, v_##_Tpvec& b0, v_##_Tpvec& b1) \
+{ \
+ _Tpvec##x2_t p = vzipq_##suffix(a0.val, a1.val); \
+ b0.val = p.val[0]; \
+ b1.val = p.val[1]; \
+} \
+inline v_##_Tpvec v_combine_low(const v_##_Tpvec& a, const v_##_Tpvec& b) \
+{ \
+ return v_##_Tpvec(vcombine_##suffix(vget_low_##suffix(a.val), vget_low_##suffix(b.val))); \
+} \
+inline v_##_Tpvec v_combine_high(const v_##_Tpvec& a, const v_##_Tpvec& b) \
+{ \
+ return v_##_Tpvec(vcombine_##suffix(vget_high_##suffix(a.val), vget_high_##suffix(b.val))); \
+} \
+inline void v_recombine(const v_##_Tpvec& a, const v_##_Tpvec& b, v_##_Tpvec& c, v_##_Tpvec& d) \
+{ \
+ c.val = vcombine_##suffix(vget_low_##suffix(a.val), vget_low_##suffix(b.val)); \
+ d.val = vcombine_##suffix(vget_high_##suffix(a.val), vget_high_##suffix(b.val)); \
+}
+#endif
+
+OPENCV_HAL_IMPL_NEON_UNPACKS(uint8x16, u8)
+OPENCV_HAL_IMPL_NEON_UNPACKS(int8x16, s8)
+OPENCV_HAL_IMPL_NEON_UNPACKS(uint16x8, u16)
+OPENCV_HAL_IMPL_NEON_UNPACKS(int16x8, s16)
+OPENCV_HAL_IMPL_NEON_UNPACKS(uint32x4, u32)
+OPENCV_HAL_IMPL_NEON_UNPACKS(int32x4, s32)
+OPENCV_HAL_IMPL_NEON_UNPACKS(float32x4, f32)
+#if CV_SIMD128_64F
+OPENCV_HAL_IMPL_NEON_UNPACKS(float64x2, f64)
+#endif
+
+#define OPENCV_HAL_IMPL_NEON_EXTRACT(_Tpvec, suffix) \
+template <int s> \
+inline v_##_Tpvec v_extract(const v_##_Tpvec& a, const v_##_Tpvec& b) \
+{ \
+ return v_##_Tpvec(vextq_##suffix(a.val, b.val, s)); \
+}
+
+OPENCV_HAL_IMPL_NEON_EXTRACT(uint8x16, u8)
+OPENCV_HAL_IMPL_NEON_EXTRACT(int8x16, s8)
+OPENCV_HAL_IMPL_NEON_EXTRACT(uint16x8, u16)
+OPENCV_HAL_IMPL_NEON_EXTRACT(int16x8, s16)
+OPENCV_HAL_IMPL_NEON_EXTRACT(uint32x4, u32)
+OPENCV_HAL_IMPL_NEON_EXTRACT(int32x4, s32)
+OPENCV_HAL_IMPL_NEON_EXTRACT(uint64x2, u64)
+OPENCV_HAL_IMPL_NEON_EXTRACT(int64x2, s64)
+OPENCV_HAL_IMPL_NEON_EXTRACT(float32x4, f32)
+#if CV_SIMD128_64F
+OPENCV_HAL_IMPL_NEON_EXTRACT(float64x2, f64)
+#endif
+
+inline v_int32x4 v_round(const v_float32x4& a)
+{
+ static const int32x4_t v_sign = vdupq_n_s32(1 << 31),
+ v_05 = vreinterpretq_s32_f32(vdupq_n_f32(0.5f));
+
+ int32x4_t v_addition = vorrq_s32(v_05, vandq_s32(v_sign, vreinterpretq_s32_f32(a.val)));
+ return v_int32x4(vcvtq_s32_f32(vaddq_f32(a.val, vreinterpretq_f32_s32(v_addition))));
+}
+
+inline v_int32x4 v_floor(const v_float32x4& a)
+{
+ int32x4_t a1 = vcvtq_s32_f32(a.val);
+ uint32x4_t mask = vcgtq_f32(vcvtq_f32_s32(a1), a.val);
+ return v_int32x4(vaddq_s32(a1, vreinterpretq_s32_u32(mask)));
+}
+
+inline v_int32x4 v_ceil(const v_float32x4& a)
+{
+ int32x4_t a1 = vcvtq_s32_f32(a.val);
+ uint32x4_t mask = vcgtq_f32(a.val, vcvtq_f32_s32(a1));
+ return v_int32x4(vsubq_s32(a1, vreinterpretq_s32_u32(mask)));
+}
+
+inline v_int32x4 v_trunc(const v_float32x4& a)
+{ return v_int32x4(vcvtq_s32_f32(a.val)); }
+
+#if CV_SIMD128_64F
+inline v_int32x4 v_round(const v_float64x2& a)
+{
+ static const int32x2_t zero = vdup_n_s32(0);
+ return v_int32x4(vcombine_s32(vmovn_s64(vcvtaq_s64_f64(a.val)), zero));
+}
+
+inline v_int32x4 v_floor(const v_float64x2& a)
+{
+ static const int32x2_t zero = vdup_n_s32(0);
+ int64x2_t a1 = vcvtq_s64_f64(a.val);
+ uint64x2_t mask = vcgtq_f64(vcvtq_f64_s64(a1), a.val);
+ a1 = vaddq_s64(a1, vreinterpretq_s64_u64(mask));
+ return v_int32x4(vcombine_s32(vmovn_s64(a1), zero));
+}
+
+inline v_int32x4 v_ceil(const v_float64x2& a)
+{
+ static const int32x2_t zero = vdup_n_s32(0);
+ int64x2_t a1 = vcvtq_s64_f64(a.val);
+ uint64x2_t mask = vcgtq_f64(a.val, vcvtq_f64_s64(a1));
+ a1 = vsubq_s64(a1, vreinterpretq_s64_u64(mask));
+ return v_int32x4(vcombine_s32(vmovn_s64(a1), zero));
+}
+
+inline v_int32x4 v_trunc(const v_float64x2& a)
+{
+ static const int32x2_t zero = vdup_n_s32(0);
+ return v_int32x4(vcombine_s32(vmovn_s64(vcvtaq_s64_f64(a.val)), zero));
+}
+#endif
+
+#define OPENCV_HAL_IMPL_NEON_TRANSPOSE4x4(_Tpvec, suffix) \
+inline void v_transpose4x4(const v_##_Tpvec& a0, const v_##_Tpvec& a1, \
+ const v_##_Tpvec& a2, const v_##_Tpvec& a3, \
+ v_##_Tpvec& b0, v_##_Tpvec& b1, \
+ v_##_Tpvec& b2, v_##_Tpvec& b3) \
+{ \
+ /* m00 m01 m02 m03 */ \
+ /* m10 m11 m12 m13 */ \
+ /* m20 m21 m22 m23 */ \
+ /* m30 m31 m32 m33 */ \
+ _Tpvec##x2_t t0 = vtrnq_##suffix(a0.val, a1.val); \
+ _Tpvec##x2_t t1 = vtrnq_##suffix(a2.val, a3.val); \
+ /* m00 m10 m02 m12 */ \
+ /* m01 m11 m03 m13 */ \
+ /* m20 m30 m22 m32 */ \
+ /* m21 m31 m23 m33 */ \
+ b0.val = vcombine_##suffix(vget_low_##suffix(t0.val[0]), vget_low_##suffix(t1.val[0])); \
+ b1.val = vcombine_##suffix(vget_low_##suffix(t0.val[1]), vget_low_##suffix(t1.val[1])); \
+ b2.val = vcombine_##suffix(vget_high_##suffix(t0.val[0]), vget_high_##suffix(t1.val[0])); \
+ b3.val = vcombine_##suffix(vget_high_##suffix(t0.val[1]), vget_high_##suffix(t1.val[1])); \
+}
+
+OPENCV_HAL_IMPL_NEON_TRANSPOSE4x4(uint32x4, u32)
+OPENCV_HAL_IMPL_NEON_TRANSPOSE4x4(int32x4, s32)
+OPENCV_HAL_IMPL_NEON_TRANSPOSE4x4(float32x4, f32)
+
+#define OPENCV_HAL_IMPL_NEON_INTERLEAVED(_Tpvec, _Tp, suffix) \
+inline void v_load_deinterleave(const _Tp* ptr, v_##_Tpvec& a, v_##_Tpvec& b) \
+{ \
+ _Tpvec##x2_t v = vld2q_##suffix(ptr); \
+ a.val = v.val[0]; \
+ b.val = v.val[1]; \
+} \
+inline void v_load_deinterleave(const _Tp* ptr, v_##_Tpvec& a, v_##_Tpvec& b, v_##_Tpvec& c) \
+{ \
+ _Tpvec##x3_t v = vld3q_##suffix(ptr); \
+ a.val = v.val[0]; \
+ b.val = v.val[1]; \
+ c.val = v.val[2]; \
+} \
+inline void v_load_deinterleave(const _Tp* ptr, v_##_Tpvec& a, v_##_Tpvec& b, \
+ v_##_Tpvec& c, v_##_Tpvec& d) \
+{ \
+ _Tpvec##x4_t v = vld4q_##suffix(ptr); \
+ a.val = v.val[0]; \
+ b.val = v.val[1]; \
+ c.val = v.val[2]; \
+ d.val = v.val[3]; \
+} \
+inline void v_store_interleave( _Tp* ptr, const v_##_Tpvec& a, const v_##_Tpvec& b) \
+{ \
+ _Tpvec##x2_t v; \
+ v.val[0] = a.val; \
+ v.val[1] = b.val; \
+ vst2q_##suffix(ptr, v); \
+} \
+inline void v_store_interleave( _Tp* ptr, const v_##_Tpvec& a, const v_##_Tpvec& b, const v_##_Tpvec& c) \
+{ \
+ _Tpvec##x3_t v; \
+ v.val[0] = a.val; \
+ v.val[1] = b.val; \
+ v.val[2] = c.val; \
+ vst3q_##suffix(ptr, v); \
+} \
+inline void v_store_interleave( _Tp* ptr, const v_##_Tpvec& a, const v_##_Tpvec& b, \
+ const v_##_Tpvec& c, const v_##_Tpvec& d) \
+{ \
+ _Tpvec##x4_t v; \
+ v.val[0] = a.val; \
+ v.val[1] = b.val; \
+ v.val[2] = c.val; \
+ v.val[3] = d.val; \
+ vst4q_##suffix(ptr, v); \
+}
+
+OPENCV_HAL_IMPL_NEON_INTERLEAVED(uint8x16, uchar, u8)
+OPENCV_HAL_IMPL_NEON_INTERLEAVED(int8x16, schar, s8)
+OPENCV_HAL_IMPL_NEON_INTERLEAVED(uint16x8, ushort, u16)
+OPENCV_HAL_IMPL_NEON_INTERLEAVED(int16x8, short, s16)
+OPENCV_HAL_IMPL_NEON_INTERLEAVED(uint32x4, unsigned, u32)
+OPENCV_HAL_IMPL_NEON_INTERLEAVED(int32x4, int, s32)
+OPENCV_HAL_IMPL_NEON_INTERLEAVED(float32x4, float, f32)
+#if CV_SIMD128_64F
+OPENCV_HAL_IMPL_NEON_INTERLEAVED(float64x2, double, f64)
+#endif
+
+inline v_float32x4 v_cvt_f32(const v_int32x4& a)
+{
+ return v_float32x4(vcvtq_f32_s32(a.val));
+}
+
+#if CV_SIMD128_64F
+inline v_float32x4 v_cvt_f32(const v_float64x2& a)
+{
+ float32x2_t zero = vdup_n_f32(0.0f);
+ return v_float32x4(vcombine_f32(vcvt_f32_f64(a.val), zero));
+}
+
+inline v_float64x2 v_cvt_f64(const v_int32x4& a)
+{
+ return v_float64x2(vcvt_f64_f32(vcvt_f32_s32(vget_low_s32(a.val))));
+}
+
+inline v_float64x2 v_cvt_f64_high(const v_int32x4& a)
+{
+ return v_float64x2(vcvt_f64_f32(vcvt_f32_s32(vget_high_s32(a.val))));
+}
+
+inline v_float64x2 v_cvt_f64(const v_float32x4& a)
+{
+ return v_float64x2(vcvt_f64_f32(vget_low_f32(a.val)));
+}
+
+inline v_float64x2 v_cvt_f64_high(const v_float32x4& a)
+{
+ return v_float64x2(vcvt_f64_f32(vget_high_f32(a.val)));
+}
+#endif
+
+#if defined (HAVE_FP16)
+inline v_float32x4 v_cvt_f32(const v_float16x4& a)
+{
+ return v_float32x4(vcvt_f32_f16(a.val));
+}
+
+inline v_float16x4 v_cvt_f16(const v_float32x4& a)
+{
+ return v_float16x4(vcvt_f16_f32(a.val));
+}
+#endif
+
+//! @name Check SIMD support
+//! @{
+//! @brief Check CPU capability of SIMD operation
+static inline bool hasSIMD128()
+{
+ return checkHardwareSupport(CV_CPU_NEON);
+}
+
+//! @}
+
+//! @endcond
+
+}
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/core/hal/intrin_sse.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,1744 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
+// Copyright (C) 2015, Itseez Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_HAL_SSE_HPP
+#define OPENCV_HAL_SSE_HPP
+
+#include <algorithm>
+#include "opencv2/core/utility.hpp"
+
+#define CV_SIMD128 1
+#define CV_SIMD128_64F 1
+
+namespace cv
+{
+
+//! @cond IGNORED
+
+struct v_uint8x16
+{
+ typedef uchar lane_type;
+ enum { nlanes = 16 };
+
+ v_uint8x16() {}
+ explicit v_uint8x16(__m128i v) : val(v) {}
+ v_uint8x16(uchar v0, uchar v1, uchar v2, uchar v3, uchar v4, uchar v5, uchar v6, uchar v7,
+ uchar v8, uchar v9, uchar v10, uchar v11, uchar v12, uchar v13, uchar v14, uchar v15)
+ {
+ val = _mm_setr_epi8((char)v0, (char)v1, (char)v2, (char)v3,
+ (char)v4, (char)v5, (char)v6, (char)v7,
+ (char)v8, (char)v9, (char)v10, (char)v11,
+ (char)v12, (char)v13, (char)v14, (char)v15);
+ }
+ uchar get0() const
+ {
+ return (uchar)_mm_cvtsi128_si32(val);
+ }
+
+ __m128i val;
+};
+
+struct v_int8x16
+{
+ typedef schar lane_type;
+ enum { nlanes = 16 };
+
+ v_int8x16() {}
+ explicit v_int8x16(__m128i v) : val(v) {}
+ v_int8x16(schar v0, schar v1, schar v2, schar v3, schar v4, schar v5, schar v6, schar v7,
+ schar v8, schar v9, schar v10, schar v11, schar v12, schar v13, schar v14, schar v15)
+ {
+ val = _mm_setr_epi8((char)v0, (char)v1, (char)v2, (char)v3,
+ (char)v4, (char)v5, (char)v6, (char)v7,
+ (char)v8, (char)v9, (char)v10, (char)v11,
+ (char)v12, (char)v13, (char)v14, (char)v15);
+ }
+ schar get0() const
+ {
+ return (schar)_mm_cvtsi128_si32(val);
+ }
+
+ __m128i val;
+};
+
+struct v_uint16x8
+{
+ typedef ushort lane_type;
+ enum { nlanes = 8 };
+
+ v_uint16x8() {}
+ explicit v_uint16x8(__m128i v) : val(v) {}
+ v_uint16x8(ushort v0, ushort v1, ushort v2, ushort v3, ushort v4, ushort v5, ushort v6, ushort v7)
+ {
+ val = _mm_setr_epi16((short)v0, (short)v1, (short)v2, (short)v3,
+ (short)v4, (short)v5, (short)v6, (short)v7);
+ }
+ ushort get0() const
+ {
+ return (ushort)_mm_cvtsi128_si32(val);
+ }
+
+ __m128i val;
+};
+
+struct v_int16x8
+{
+ typedef short lane_type;
+ enum { nlanes = 8 };
+
+ v_int16x8() {}
+ explicit v_int16x8(__m128i v) : val(v) {}
+ v_int16x8(short v0, short v1, short v2, short v3, short v4, short v5, short v6, short v7)
+ {
+ val = _mm_setr_epi16((short)v0, (short)v1, (short)v2, (short)v3,
+ (short)v4, (short)v5, (short)v6, (short)v7);
+ }
+ short get0() const
+ {
+ return (short)_mm_cvtsi128_si32(val);
+ }
+ __m128i val;
+};
+
+struct v_uint32x4
+{
+ typedef unsigned lane_type;
+ enum { nlanes = 4 };
+
+ v_uint32x4() {}
+ explicit v_uint32x4(__m128i v) : val(v) {}
+ v_uint32x4(unsigned v0, unsigned v1, unsigned v2, unsigned v3)
+ {
+ val = _mm_setr_epi32((int)v0, (int)v1, (int)v2, (int)v3);
+ }
+ unsigned get0() const
+ {
+ return (unsigned)_mm_cvtsi128_si32(val);
+ }
+ __m128i val;
+};
+
+struct v_int32x4
+{
+ typedef int lane_type;
+ enum { nlanes = 4 };
+
+ v_int32x4() {}
+ explicit v_int32x4(__m128i v) : val(v) {}
+ v_int32x4(int v0, int v1, int v2, int v3)
+ {
+ val = _mm_setr_epi32(v0, v1, v2, v3);
+ }
+ int get0() const
+ {
+ return _mm_cvtsi128_si32(val);
+ }
+ __m128i val;
+};
+
+struct v_float32x4
+{
+ typedef float lane_type;
+ enum { nlanes = 4 };
+
+ v_float32x4() {}
+ explicit v_float32x4(__m128 v) : val(v) {}
+ v_float32x4(float v0, float v1, float v2, float v3)
+ {
+ val = _mm_setr_ps(v0, v1, v2, v3);
+ }
+ float get0() const
+ {
+ return _mm_cvtss_f32(val);
+ }
+ __m128 val;
+};
+
+struct v_uint64x2
+{
+ typedef uint64 lane_type;
+ enum { nlanes = 2 };
+
+ v_uint64x2() {}
+ explicit v_uint64x2(__m128i v) : val(v) {}
+ v_uint64x2(uint64 v0, uint64 v1)
+ {
+ val = _mm_setr_epi32((int)v0, (int)(v0 >> 32), (int)v1, (int)(v1 >> 32));
+ }
+ uint64 get0() const
+ {
+ int a = _mm_cvtsi128_si32(val);
+ int b = _mm_cvtsi128_si32(_mm_srli_epi64(val, 32));
+ return (unsigned)a | ((uint64)(unsigned)b << 32);
+ }
+ __m128i val;
+};
+
+struct v_int64x2
+{
+ typedef int64 lane_type;
+ enum { nlanes = 2 };
+
+ v_int64x2() {}
+ explicit v_int64x2(__m128i v) : val(v) {}
+ v_int64x2(int64 v0, int64 v1)
+ {
+ val = _mm_setr_epi32((int)v0, (int)(v0 >> 32), (int)v1, (int)(v1 >> 32));
+ }
+ int64 get0() const
+ {
+ int a = _mm_cvtsi128_si32(val);
+ int b = _mm_cvtsi128_si32(_mm_srli_epi64(val, 32));
+ return (int64)((unsigned)a | ((uint64)(unsigned)b << 32));
+ }
+ __m128i val;
+};
+
+struct v_float64x2
+{
+ typedef double lane_type;
+ enum { nlanes = 2 };
+
+ v_float64x2() {}
+ explicit v_float64x2(__m128d v) : val(v) {}
+ v_float64x2(double v0, double v1)
+ {
+ val = _mm_setr_pd(v0, v1);
+ }
+ double get0() const
+ {
+ return _mm_cvtsd_f64(val);
+ }
+ __m128d val;
+};
+
+#if defined(HAVE_FP16)
+struct v_float16x4
+{
+ typedef short lane_type;
+ enum { nlanes = 4 };
+
+ v_float16x4() {}
+ explicit v_float16x4(__m128i v) : val(v) {}
+ v_float16x4(short v0, short v1, short v2, short v3)
+ {
+ val = _mm_setr_epi16(v0, v1, v2, v3, 0, 0, 0, 0);
+ }
+ short get0() const
+ {
+ return (short)_mm_cvtsi128_si32(val);
+ }
+ __m128i val;
+};
+#endif
+
+#define OPENCV_HAL_IMPL_SSE_INITVEC(_Tpvec, _Tp, suffix, zsuffix, ssuffix, _Tps, cast) \
+inline _Tpvec v_setzero_##suffix() { return _Tpvec(_mm_setzero_##zsuffix()); } \
+inline _Tpvec v_setall_##suffix(_Tp v) { return _Tpvec(_mm_set1_##ssuffix((_Tps)v)); } \
+template<typename _Tpvec0> inline _Tpvec v_reinterpret_as_##suffix(const _Tpvec0& a) \
+{ return _Tpvec(cast(a.val)); }
+
+OPENCV_HAL_IMPL_SSE_INITVEC(v_uint8x16, uchar, u8, si128, epi8, char, OPENCV_HAL_NOP)
+OPENCV_HAL_IMPL_SSE_INITVEC(v_int8x16, schar, s8, si128, epi8, char, OPENCV_HAL_NOP)
+OPENCV_HAL_IMPL_SSE_INITVEC(v_uint16x8, ushort, u16, si128, epi16, short, OPENCV_HAL_NOP)
+OPENCV_HAL_IMPL_SSE_INITVEC(v_int16x8, short, s16, si128, epi16, short, OPENCV_HAL_NOP)
+OPENCV_HAL_IMPL_SSE_INITVEC(v_uint32x4, unsigned, u32, si128, epi32, int, OPENCV_HAL_NOP)
+OPENCV_HAL_IMPL_SSE_INITVEC(v_int32x4, int, s32, si128, epi32, int, OPENCV_HAL_NOP)
+OPENCV_HAL_IMPL_SSE_INITVEC(v_float32x4, float, f32, ps, ps, float, _mm_castsi128_ps)
+OPENCV_HAL_IMPL_SSE_INITVEC(v_float64x2, double, f64, pd, pd, double, _mm_castsi128_pd)
+
+inline v_uint64x2 v_setzero_u64() { return v_uint64x2(_mm_setzero_si128()); }
+inline v_int64x2 v_setzero_s64() { return v_int64x2(_mm_setzero_si128()); }
+inline v_uint64x2 v_setall_u64(uint64 val) { return v_uint64x2(val, val); }
+inline v_int64x2 v_setall_s64(int64 val) { return v_int64x2(val, val); }
+
+template<typename _Tpvec> inline
+v_uint64x2 v_reinterpret_as_u64(const _Tpvec& a) { return v_uint64x2(a.val); }
+template<typename _Tpvec> inline
+v_int64x2 v_reinterpret_as_s64(const _Tpvec& a) { return v_int64x2(a.val); }
+inline v_float32x4 v_reinterpret_as_f32(const v_uint64x2& a)
+{ return v_float32x4(_mm_castsi128_ps(a.val)); }
+inline v_float32x4 v_reinterpret_as_f32(const v_int64x2& a)
+{ return v_float32x4(_mm_castsi128_ps(a.val)); }
+inline v_float64x2 v_reinterpret_as_f64(const v_uint64x2& a)
+{ return v_float64x2(_mm_castsi128_pd(a.val)); }
+inline v_float64x2 v_reinterpret_as_f64(const v_int64x2& a)
+{ return v_float64x2(_mm_castsi128_pd(a.val)); }
+
+#define OPENCV_HAL_IMPL_SSE_INIT_FROM_FLT(_Tpvec, suffix) \
+inline _Tpvec v_reinterpret_as_##suffix(const v_float32x4& a) \
+{ return _Tpvec(_mm_castps_si128(a.val)); } \
+inline _Tpvec v_reinterpret_as_##suffix(const v_float64x2& a) \
+{ return _Tpvec(_mm_castpd_si128(a.val)); }
+
+OPENCV_HAL_IMPL_SSE_INIT_FROM_FLT(v_uint8x16, u8)
+OPENCV_HAL_IMPL_SSE_INIT_FROM_FLT(v_int8x16, s8)
+OPENCV_HAL_IMPL_SSE_INIT_FROM_FLT(v_uint16x8, u16)
+OPENCV_HAL_IMPL_SSE_INIT_FROM_FLT(v_int16x8, s16)
+OPENCV_HAL_IMPL_SSE_INIT_FROM_FLT(v_uint32x4, u32)
+OPENCV_HAL_IMPL_SSE_INIT_FROM_FLT(v_int32x4, s32)
+OPENCV_HAL_IMPL_SSE_INIT_FROM_FLT(v_uint64x2, u64)
+OPENCV_HAL_IMPL_SSE_INIT_FROM_FLT(v_int64x2, s64)
+
+inline v_float32x4 v_reinterpret_as_f32(const v_float32x4& a) {return a; }
+inline v_float64x2 v_reinterpret_as_f64(const v_float64x2& a) {return a; }
+inline v_float32x4 v_reinterpret_as_f32(const v_float64x2& a) {return v_float32x4(_mm_castpd_ps(a.val)); }
+inline v_float64x2 v_reinterpret_as_f64(const v_float32x4& a) {return v_float64x2(_mm_castps_pd(a.val)); }
+
+//////////////// PACK ///////////////
+inline v_uint8x16 v_pack(const v_uint16x8& a, const v_uint16x8& b)
+{
+ __m128i delta = _mm_set1_epi16(255);
+ return v_uint8x16(_mm_packus_epi16(_mm_subs_epu16(a.val, _mm_subs_epu16(a.val, delta)),
+ _mm_subs_epu16(b.val, _mm_subs_epu16(b.val, delta))));
+}
+
+inline void v_pack_store(uchar* ptr, const v_uint16x8& a)
+{
+ __m128i delta = _mm_set1_epi16(255);
+ __m128i a1 = _mm_subs_epu16(a.val, _mm_subs_epu16(a.val, delta));
+ _mm_storel_epi64((__m128i*)ptr, _mm_packus_epi16(a1, a1));
+}
+
+inline v_uint8x16 v_pack_u(const v_int16x8& a, const v_int16x8& b)
+{ return v_uint8x16(_mm_packus_epi16(a.val, b.val)); }
+
+inline void v_pack_u_store(uchar* ptr, const v_int16x8& a)
+{ _mm_storel_epi64((__m128i*)ptr, _mm_packus_epi16(a.val, a.val)); }
+
+template<int n> inline
+v_uint8x16 v_rshr_pack(const v_uint16x8& a, const v_uint16x8& b)
+{
+ // we assume that n > 0, and so the shifted 16-bit values can be treated as signed numbers.
+ __m128i delta = _mm_set1_epi16((short)(1 << (n-1)));
+ return v_uint8x16(_mm_packus_epi16(_mm_srli_epi16(_mm_adds_epu16(a.val, delta), n),
+ _mm_srli_epi16(_mm_adds_epu16(b.val, delta), n)));
+}
+
+template<int n> inline
+void v_rshr_pack_store(uchar* ptr, const v_uint16x8& a)
+{
+ __m128i delta = _mm_set1_epi16((short)(1 << (n-1)));
+ __m128i a1 = _mm_srli_epi16(_mm_adds_epu16(a.val, delta), n);
+ _mm_storel_epi64((__m128i*)ptr, _mm_packus_epi16(a1, a1));
+}
+
+template<int n> inline
+v_uint8x16 v_rshr_pack_u(const v_int16x8& a, const v_int16x8& b)
+{
+ __m128i delta = _mm_set1_epi16((short)(1 << (n-1)));
+ return v_uint8x16(_mm_packus_epi16(_mm_srai_epi16(_mm_adds_epi16(a.val, delta), n),
+ _mm_srai_epi16(_mm_adds_epi16(b.val, delta), n)));
+}
+
+template<int n> inline
+void v_rshr_pack_u_store(uchar* ptr, const v_int16x8& a)
+{
+ __m128i delta = _mm_set1_epi16((short)(1 << (n-1)));
+ __m128i a1 = _mm_srai_epi16(_mm_adds_epi16(a.val, delta), n);
+ _mm_storel_epi64((__m128i*)ptr, _mm_packus_epi16(a1, a1));
+}
+
+inline v_int8x16 v_pack(const v_int16x8& a, const v_int16x8& b)
+{ return v_int8x16(_mm_packs_epi16(a.val, b.val)); }
+
+inline void v_pack_store(schar* ptr, v_int16x8& a)
+{ _mm_storel_epi64((__m128i*)ptr, _mm_packs_epi16(a.val, a.val)); }
+
+template<int n> inline
+v_int8x16 v_rshr_pack(const v_int16x8& a, const v_int16x8& b)
+{
+ // we assume that n > 0, and so the shifted 16-bit values can be treated as signed numbers.
+ __m128i delta = _mm_set1_epi16((short)(1 << (n-1)));
+ return v_int8x16(_mm_packs_epi16(_mm_srai_epi16(_mm_adds_epi16(a.val, delta), n),
+ _mm_srai_epi16(_mm_adds_epi16(b.val, delta), n)));
+}
+template<int n> inline
+void v_rshr_pack_store(schar* ptr, const v_int16x8& a)
+{
+ // we assume that n > 0, and so the shifted 16-bit values can be treated as signed numbers.
+ __m128i delta = _mm_set1_epi16((short)(1 << (n-1)));
+ __m128i a1 = _mm_srai_epi16(_mm_adds_epi16(a.val, delta), n);
+ _mm_storel_epi64((__m128i*)ptr, _mm_packs_epi16(a1, a1));
+}
+
+
+// bit-wise "mask ? a : b"
+inline __m128i v_select_si128(__m128i mask, __m128i a, __m128i b)
+{
+ return _mm_xor_si128(b, _mm_and_si128(_mm_xor_si128(a, b), mask));
+}
+
+inline v_uint16x8 v_pack(const v_uint32x4& a, const v_uint32x4& b)
+{
+ __m128i z = _mm_setzero_si128(), maxval32 = _mm_set1_epi32(65535), delta32 = _mm_set1_epi32(32768);
+ __m128i a1 = _mm_sub_epi32(v_select_si128(_mm_cmpgt_epi32(z, a.val), maxval32, a.val), delta32);
+ __m128i b1 = _mm_sub_epi32(v_select_si128(_mm_cmpgt_epi32(z, b.val), maxval32, b.val), delta32);
+ __m128i r = _mm_packs_epi32(a1, b1);
+ return v_uint16x8(_mm_sub_epi16(r, _mm_set1_epi16(-32768)));
+}
+
+inline void v_pack_store(ushort* ptr, const v_uint32x4& a)
+{
+ __m128i z = _mm_setzero_si128(), maxval32 = _mm_set1_epi32(65535), delta32 = _mm_set1_epi32(32768);
+ __m128i a1 = _mm_sub_epi32(v_select_si128(_mm_cmpgt_epi32(z, a.val), maxval32, a.val), delta32);
+ __m128i r = _mm_packs_epi32(a1, a1);
+ _mm_storel_epi64((__m128i*)ptr, _mm_sub_epi16(r, _mm_set1_epi16(-32768)));
+}
+
+template<int n> inline
+v_uint16x8 v_rshr_pack(const v_uint32x4& a, const v_uint32x4& b)
+{
+ __m128i delta = _mm_set1_epi32(1 << (n-1)), delta32 = _mm_set1_epi32(32768);
+ __m128i a1 = _mm_sub_epi32(_mm_srli_epi32(_mm_add_epi32(a.val, delta), n), delta32);
+ __m128i b1 = _mm_sub_epi32(_mm_srli_epi32(_mm_add_epi32(b.val, delta), n), delta32);
+ return v_uint16x8(_mm_sub_epi16(_mm_packs_epi32(a1, b1), _mm_set1_epi16(-32768)));
+}
+
+template<int n> inline
+void v_rshr_pack_store(ushort* ptr, const v_uint32x4& a)
+{
+ __m128i delta = _mm_set1_epi32(1 << (n-1)), delta32 = _mm_set1_epi32(32768);
+ __m128i a1 = _mm_sub_epi32(_mm_srli_epi32(_mm_add_epi32(a.val, delta), n), delta32);
+ __m128i a2 = _mm_sub_epi16(_mm_packs_epi32(a1, a1), _mm_set1_epi16(-32768));
+ _mm_storel_epi64((__m128i*)ptr, a2);
+}
+
+inline v_uint16x8 v_pack_u(const v_int32x4& a, const v_int32x4& b)
+{
+ __m128i delta32 = _mm_set1_epi32(32768);
+ __m128i r = _mm_packs_epi32(_mm_sub_epi32(a.val, delta32), _mm_sub_epi32(b.val, delta32));
+ return v_uint16x8(_mm_sub_epi16(r, _mm_set1_epi16(-32768)));
+}
+
+inline void v_pack_u_store(ushort* ptr, const v_int32x4& a)
+{
+ __m128i delta32 = _mm_set1_epi32(32768);
+ __m128i a1 = _mm_sub_epi32(a.val, delta32);
+ __m128i r = _mm_sub_epi16(_mm_packs_epi32(a1, a1), _mm_set1_epi16(-32768));
+ _mm_storel_epi64((__m128i*)ptr, r);
+}
+
+template<int n> inline
+v_uint16x8 v_rshr_pack_u(const v_int32x4& a, const v_int32x4& b)
+{
+ __m128i delta = _mm_set1_epi32(1 << (n-1)), delta32 = _mm_set1_epi32(32768);
+ __m128i a1 = _mm_sub_epi32(_mm_srai_epi32(_mm_add_epi32(a.val, delta), n), delta32);
+ __m128i a2 = _mm_sub_epi16(_mm_packs_epi32(a1, a1), _mm_set1_epi16(-32768));
+ __m128i b1 = _mm_sub_epi32(_mm_srai_epi32(_mm_add_epi32(b.val, delta), n), delta32);
+ __m128i b2 = _mm_sub_epi16(_mm_packs_epi32(b1, b1), _mm_set1_epi16(-32768));
+ return v_uint16x8(_mm_unpacklo_epi64(a2, b2));
+}
+
+template<int n> inline
+void v_rshr_pack_u_store(ushort* ptr, const v_int32x4& a)
+{
+ __m128i delta = _mm_set1_epi32(1 << (n-1)), delta32 = _mm_set1_epi32(32768);
+ __m128i a1 = _mm_sub_epi32(_mm_srai_epi32(_mm_add_epi32(a.val, delta), n), delta32);
+ __m128i a2 = _mm_sub_epi16(_mm_packs_epi32(a1, a1), _mm_set1_epi16(-32768));
+ _mm_storel_epi64((__m128i*)ptr, a2);
+}
+
+inline v_int16x8 v_pack(const v_int32x4& a, const v_int32x4& b)
+{ return v_int16x8(_mm_packs_epi32(a.val, b.val)); }
+
+inline void v_pack_store(short* ptr, const v_int32x4& a)
+{
+ _mm_storel_epi64((__m128i*)ptr, _mm_packs_epi32(a.val, a.val));
+}
+
+template<int n> inline
+v_int16x8 v_rshr_pack(const v_int32x4& a, const v_int32x4& b)
+{
+ __m128i delta = _mm_set1_epi32(1 << (n-1));
+ return v_int16x8(_mm_packs_epi32(_mm_srai_epi32(_mm_add_epi32(a.val, delta), n),
+ _mm_srai_epi32(_mm_add_epi32(b.val, delta), n)));
+}
+
+template<int n> inline
+void v_rshr_pack_store(short* ptr, const v_int32x4& a)
+{
+ __m128i delta = _mm_set1_epi32(1 << (n-1));
+ __m128i a1 = _mm_srai_epi32(_mm_add_epi32(a.val, delta), n);
+ _mm_storel_epi64((__m128i*)ptr, _mm_packs_epi32(a1, a1));
+}
+
+
+// [a0 0 | b0 0] [a1 0 | b1 0]
+inline v_uint32x4 v_pack(const v_uint64x2& a, const v_uint64x2& b)
+{
+ __m128i v0 = _mm_unpacklo_epi32(a.val, b.val); // a0 a1 0 0
+ __m128i v1 = _mm_unpackhi_epi32(a.val, b.val); // b0 b1 0 0
+ return v_uint32x4(_mm_unpacklo_epi32(v0, v1));
+}
+
+inline void v_pack_store(unsigned* ptr, const v_uint64x2& a)
+{
+ __m128i a1 = _mm_shuffle_epi32(a.val, _MM_SHUFFLE(0, 2, 2, 0));
+ _mm_storel_epi64((__m128i*)ptr, a1);
+}
+
+// [a0 0 | b0 0] [a1 0 | b1 0]
+inline v_int32x4 v_pack(const v_int64x2& a, const v_int64x2& b)
+{
+ __m128i v0 = _mm_unpacklo_epi32(a.val, b.val); // a0 a1 0 0
+ __m128i v1 = _mm_unpackhi_epi32(a.val, b.val); // b0 b1 0 0
+ return v_int32x4(_mm_unpacklo_epi32(v0, v1));
+}
+
+inline void v_pack_store(int* ptr, const v_int64x2& a)
+{
+ __m128i a1 = _mm_shuffle_epi32(a.val, _MM_SHUFFLE(0, 2, 2, 0));
+ _mm_storel_epi64((__m128i*)ptr, a1);
+}
+
+template<int n> inline
+v_uint32x4 v_rshr_pack(const v_uint64x2& a, const v_uint64x2& b)
+{
+ uint64 delta = (uint64)1 << (n-1);
+ v_uint64x2 delta2(delta, delta);
+ __m128i a1 = _mm_srli_epi64(_mm_add_epi64(a.val, delta2.val), n);
+ __m128i b1 = _mm_srli_epi64(_mm_add_epi64(b.val, delta2.val), n);
+ __m128i v0 = _mm_unpacklo_epi32(a1, b1); // a0 a1 0 0
+ __m128i v1 = _mm_unpackhi_epi32(a1, b1); // b0 b1 0 0
+ return v_uint32x4(_mm_unpacklo_epi32(v0, v1));
+}
+
+template<int n> inline
+void v_rshr_pack_store(unsigned* ptr, const v_uint64x2& a)
+{
+ uint64 delta = (uint64)1 << (n-1);
+ v_uint64x2 delta2(delta, delta);
+ __m128i a1 = _mm_srli_epi64(_mm_add_epi64(a.val, delta2.val), n);
+ __m128i a2 = _mm_shuffle_epi32(a1, _MM_SHUFFLE(0, 2, 2, 0));
+ _mm_storel_epi64((__m128i*)ptr, a2);
+}
+
+inline __m128i v_sign_epi64(__m128i a)
+{
+ return _mm_shuffle_epi32(_mm_srai_epi32(a, 31), _MM_SHUFFLE(3, 3, 1, 1)); // x m0 | x m1
+}
+
+inline __m128i v_srai_epi64(__m128i a, int imm)
+{
+ __m128i smask = v_sign_epi64(a);
+ return _mm_xor_si128(_mm_srli_epi64(_mm_xor_si128(a, smask), imm), smask);
+}
+
+template<int n> inline
+v_int32x4 v_rshr_pack(const v_int64x2& a, const v_int64x2& b)
+{
+ int64 delta = (int64)1 << (n-1);
+ v_int64x2 delta2(delta, delta);
+ __m128i a1 = v_srai_epi64(_mm_add_epi64(a.val, delta2.val), n);
+ __m128i b1 = v_srai_epi64(_mm_add_epi64(b.val, delta2.val), n);
+ __m128i v0 = _mm_unpacklo_epi32(a1, b1); // a0 a1 0 0
+ __m128i v1 = _mm_unpackhi_epi32(a1, b1); // b0 b1 0 0
+ return v_int32x4(_mm_unpacklo_epi32(v0, v1));
+}
+
+template<int n> inline
+void v_rshr_pack_store(int* ptr, const v_int64x2& a)
+{
+ int64 delta = (int64)1 << (n-1);
+ v_int64x2 delta2(delta, delta);
+ __m128i a1 = v_srai_epi64(_mm_add_epi64(a.val, delta2.val), n);
+ __m128i a2 = _mm_shuffle_epi32(a1, _MM_SHUFFLE(0, 2, 2, 0));
+ _mm_storel_epi64((__m128i*)ptr, a2);
+}
+
+inline v_float32x4 v_matmul(const v_float32x4& v, const v_float32x4& m0,
+ const v_float32x4& m1, const v_float32x4& m2,
+ const v_float32x4& m3)
+{
+ __m128 v0 = _mm_mul_ps(_mm_shuffle_ps(v.val, v.val, _MM_SHUFFLE(0, 0, 0, 0)), m0.val);
+ __m128 v1 = _mm_mul_ps(_mm_shuffle_ps(v.val, v.val, _MM_SHUFFLE(1, 1, 1, 1)), m1.val);
+ __m128 v2 = _mm_mul_ps(_mm_shuffle_ps(v.val, v.val, _MM_SHUFFLE(2, 2, 2, 2)), m2.val);
+ __m128 v3 = _mm_mul_ps(_mm_shuffle_ps(v.val, v.val, _MM_SHUFFLE(3, 3, 3, 3)), m3.val);
+
+ return v_float32x4(_mm_add_ps(_mm_add_ps(v0, v1), _mm_add_ps(v2, v3)));
+}
+
+
+#define OPENCV_HAL_IMPL_SSE_BIN_OP(bin_op, _Tpvec, intrin) \
+ inline _Tpvec operator bin_op (const _Tpvec& a, const _Tpvec& b) \
+ { \
+ return _Tpvec(intrin(a.val, b.val)); \
+ } \
+ inline _Tpvec& operator bin_op##= (_Tpvec& a, const _Tpvec& b) \
+ { \
+ a.val = intrin(a.val, b.val); \
+ return a; \
+ }
+
+OPENCV_HAL_IMPL_SSE_BIN_OP(+, v_uint8x16, _mm_adds_epu8)
+OPENCV_HAL_IMPL_SSE_BIN_OP(-, v_uint8x16, _mm_subs_epu8)
+OPENCV_HAL_IMPL_SSE_BIN_OP(+, v_int8x16, _mm_adds_epi8)
+OPENCV_HAL_IMPL_SSE_BIN_OP(-, v_int8x16, _mm_subs_epi8)
+OPENCV_HAL_IMPL_SSE_BIN_OP(+, v_uint16x8, _mm_adds_epu16)
+OPENCV_HAL_IMPL_SSE_BIN_OP(-, v_uint16x8, _mm_subs_epu16)
+OPENCV_HAL_IMPL_SSE_BIN_OP(*, v_uint16x8, _mm_mullo_epi16)
+OPENCV_HAL_IMPL_SSE_BIN_OP(+, v_int16x8, _mm_adds_epi16)
+OPENCV_HAL_IMPL_SSE_BIN_OP(-, v_int16x8, _mm_subs_epi16)
+OPENCV_HAL_IMPL_SSE_BIN_OP(*, v_int16x8, _mm_mullo_epi16)
+OPENCV_HAL_IMPL_SSE_BIN_OP(+, v_uint32x4, _mm_add_epi32)
+OPENCV_HAL_IMPL_SSE_BIN_OP(-, v_uint32x4, _mm_sub_epi32)
+OPENCV_HAL_IMPL_SSE_BIN_OP(+, v_int32x4, _mm_add_epi32)
+OPENCV_HAL_IMPL_SSE_BIN_OP(-, v_int32x4, _mm_sub_epi32)
+OPENCV_HAL_IMPL_SSE_BIN_OP(+, v_float32x4, _mm_add_ps)
+OPENCV_HAL_IMPL_SSE_BIN_OP(-, v_float32x4, _mm_sub_ps)
+OPENCV_HAL_IMPL_SSE_BIN_OP(*, v_float32x4, _mm_mul_ps)
+OPENCV_HAL_IMPL_SSE_BIN_OP(/, v_float32x4, _mm_div_ps)
+OPENCV_HAL_IMPL_SSE_BIN_OP(+, v_float64x2, _mm_add_pd)
+OPENCV_HAL_IMPL_SSE_BIN_OP(-, v_float64x2, _mm_sub_pd)
+OPENCV_HAL_IMPL_SSE_BIN_OP(*, v_float64x2, _mm_mul_pd)
+OPENCV_HAL_IMPL_SSE_BIN_OP(/, v_float64x2, _mm_div_pd)
+OPENCV_HAL_IMPL_SSE_BIN_OP(+, v_uint64x2, _mm_add_epi64)
+OPENCV_HAL_IMPL_SSE_BIN_OP(-, v_uint64x2, _mm_sub_epi64)
+OPENCV_HAL_IMPL_SSE_BIN_OP(+, v_int64x2, _mm_add_epi64)
+OPENCV_HAL_IMPL_SSE_BIN_OP(-, v_int64x2, _mm_sub_epi64)
+
+inline v_uint32x4 operator * (const v_uint32x4& a, const v_uint32x4& b)
+{
+ __m128i c0 = _mm_mul_epu32(a.val, b.val);
+ __m128i c1 = _mm_mul_epu32(_mm_srli_epi64(a.val, 32), _mm_srli_epi64(b.val, 32));
+ __m128i d0 = _mm_unpacklo_epi32(c0, c1);
+ __m128i d1 = _mm_unpackhi_epi32(c0, c1);
+ return v_uint32x4(_mm_unpacklo_epi64(d0, d1));
+}
+inline v_int32x4 operator * (const v_int32x4& a, const v_int32x4& b)
+{
+ __m128i c0 = _mm_mul_epu32(a.val, b.val);
+ __m128i c1 = _mm_mul_epu32(_mm_srli_epi64(a.val, 32), _mm_srli_epi64(b.val, 32));
+ __m128i d0 = _mm_unpacklo_epi32(c0, c1);
+ __m128i d1 = _mm_unpackhi_epi32(c0, c1);
+ return v_int32x4(_mm_unpacklo_epi64(d0, d1));
+}
+inline v_uint32x4& operator *= (v_uint32x4& a, const v_uint32x4& b)
+{
+ a = a * b;
+ return a;
+}
+inline v_int32x4& operator *= (v_int32x4& a, const v_int32x4& b)
+{
+ a = a * b;
+ return a;
+}
+
+inline void v_mul_expand(const v_int16x8& a, const v_int16x8& b,
+ v_int32x4& c, v_int32x4& d)
+{
+ __m128i v0 = _mm_mullo_epi16(a.val, b.val);
+ __m128i v1 = _mm_mulhi_epi16(a.val, b.val);
+ c.val = _mm_unpacklo_epi16(v0, v1);
+ d.val = _mm_unpackhi_epi16(v0, v1);
+}
+
+inline void v_mul_expand(const v_uint16x8& a, const v_uint16x8& b,
+ v_uint32x4& c, v_uint32x4& d)
+{
+ __m128i v0 = _mm_mullo_epi16(a.val, b.val);
+ __m128i v1 = _mm_mulhi_epu16(a.val, b.val);
+ c.val = _mm_unpacklo_epi16(v0, v1);
+ d.val = _mm_unpackhi_epi16(v0, v1);
+}
+
+inline void v_mul_expand(const v_uint32x4& a, const v_uint32x4& b,
+ v_uint64x2& c, v_uint64x2& d)
+{
+ __m128i c0 = _mm_mul_epu32(a.val, b.val);
+ __m128i c1 = _mm_mul_epu32(_mm_srli_epi64(a.val, 32), _mm_srli_epi64(b.val, 32));
+ c.val = _mm_unpacklo_epi64(c0, c1);
+ d.val = _mm_unpackhi_epi64(c0, c1);
+}
+
+inline v_int32x4 v_dotprod(const v_int16x8& a, const v_int16x8& b)
+{
+ return v_int32x4(_mm_madd_epi16(a.val, b.val));
+}
+
+#define OPENCV_HAL_IMPL_SSE_LOGIC_OP(_Tpvec, suffix, not_const) \
+ OPENCV_HAL_IMPL_SSE_BIN_OP(&, _Tpvec, _mm_and_##suffix) \
+ OPENCV_HAL_IMPL_SSE_BIN_OP(|, _Tpvec, _mm_or_##suffix) \
+ OPENCV_HAL_IMPL_SSE_BIN_OP(^, _Tpvec, _mm_xor_##suffix) \
+ inline _Tpvec operator ~ (const _Tpvec& a) \
+ { \
+ return _Tpvec(_mm_xor_##suffix(a.val, not_const)); \
+ }
+
+OPENCV_HAL_IMPL_SSE_LOGIC_OP(v_uint8x16, si128, _mm_set1_epi32(-1))
+OPENCV_HAL_IMPL_SSE_LOGIC_OP(v_int8x16, si128, _mm_set1_epi32(-1))
+OPENCV_HAL_IMPL_SSE_LOGIC_OP(v_uint16x8, si128, _mm_set1_epi32(-1))
+OPENCV_HAL_IMPL_SSE_LOGIC_OP(v_int16x8, si128, _mm_set1_epi32(-1))
+OPENCV_HAL_IMPL_SSE_LOGIC_OP(v_uint32x4, si128, _mm_set1_epi32(-1))
+OPENCV_HAL_IMPL_SSE_LOGIC_OP(v_int32x4, si128, _mm_set1_epi32(-1))
+OPENCV_HAL_IMPL_SSE_LOGIC_OP(v_uint64x2, si128, _mm_set1_epi32(-1))
+OPENCV_HAL_IMPL_SSE_LOGIC_OP(v_int64x2, si128, _mm_set1_epi32(-1))
+OPENCV_HAL_IMPL_SSE_LOGIC_OP(v_float32x4, ps, _mm_castsi128_ps(_mm_set1_epi32(-1)))
+OPENCV_HAL_IMPL_SSE_LOGIC_OP(v_float64x2, pd, _mm_castsi128_pd(_mm_set1_epi32(-1)))
+
+inline v_float32x4 v_sqrt(const v_float32x4& x)
+{ return v_float32x4(_mm_sqrt_ps(x.val)); }
+
+inline v_float32x4 v_invsqrt(const v_float32x4& x)
+{
+ static const __m128 _0_5 = _mm_set1_ps(0.5f), _1_5 = _mm_set1_ps(1.5f);
+ __m128 t = x.val;
+ __m128 h = _mm_mul_ps(t, _0_5);
+ t = _mm_rsqrt_ps(t);
+ t = _mm_mul_ps(t, _mm_sub_ps(_1_5, _mm_mul_ps(_mm_mul_ps(t, t), h)));
+ return v_float32x4(t);
+}
+
+inline v_float64x2 v_sqrt(const v_float64x2& x)
+{ return v_float64x2(_mm_sqrt_pd(x.val)); }
+
+inline v_float64x2 v_invsqrt(const v_float64x2& x)
+{
+ static const __m128d v_1 = _mm_set1_pd(1.);
+ return v_float64x2(_mm_div_pd(v_1, _mm_sqrt_pd(x.val)));
+}
+
+#define OPENCV_HAL_IMPL_SSE_ABS_INT_FUNC(_Tpuvec, _Tpsvec, func, suffix, subWidth) \
+inline _Tpuvec v_abs(const _Tpsvec& x) \
+{ return _Tpuvec(_mm_##func##_ep##suffix(x.val, _mm_sub_ep##subWidth(_mm_setzero_si128(), x.val))); }
+
+OPENCV_HAL_IMPL_SSE_ABS_INT_FUNC(v_uint8x16, v_int8x16, min, u8, i8)
+OPENCV_HAL_IMPL_SSE_ABS_INT_FUNC(v_uint16x8, v_int16x8, max, i16, i16)
+inline v_uint32x4 v_abs(const v_int32x4& x)
+{
+ __m128i s = _mm_srli_epi32(x.val, 31);
+ __m128i f = _mm_srai_epi32(x.val, 31);
+ return v_uint32x4(_mm_add_epi32(_mm_xor_si128(x.val, f), s));
+}
+inline v_float32x4 v_abs(const v_float32x4& x)
+{ return v_float32x4(_mm_and_ps(x.val, _mm_castsi128_ps(_mm_set1_epi32(0x7fffffff)))); }
+inline v_float64x2 v_abs(const v_float64x2& x)
+{
+ return v_float64x2(_mm_and_pd(x.val,
+ _mm_castsi128_pd(_mm_srli_epi64(_mm_set1_epi32(-1), 1))));
+}
+
+// TODO: exp, log, sin, cos
+
+#define OPENCV_HAL_IMPL_SSE_BIN_FUNC(_Tpvec, func, intrin) \
+inline _Tpvec func(const _Tpvec& a, const _Tpvec& b) \
+{ \
+ return _Tpvec(intrin(a.val, b.val)); \
+}
+
+OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_uint8x16, v_min, _mm_min_epu8)
+OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_uint8x16, v_max, _mm_max_epu8)
+OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_int16x8, v_min, _mm_min_epi16)
+OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_int16x8, v_max, _mm_max_epi16)
+OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_float32x4, v_min, _mm_min_ps)
+OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_float32x4, v_max, _mm_max_ps)
+OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_float64x2, v_min, _mm_min_pd)
+OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_float64x2, v_max, _mm_max_pd)
+
+inline v_int8x16 v_min(const v_int8x16& a, const v_int8x16& b)
+{
+ __m128i delta = _mm_set1_epi8((char)-128);
+ return v_int8x16(_mm_xor_si128(delta, _mm_min_epu8(_mm_xor_si128(a.val, delta),
+ _mm_xor_si128(b.val, delta))));
+}
+inline v_int8x16 v_max(const v_int8x16& a, const v_int8x16& b)
+{
+ __m128i delta = _mm_set1_epi8((char)-128);
+ return v_int8x16(_mm_xor_si128(delta, _mm_max_epu8(_mm_xor_si128(a.val, delta),
+ _mm_xor_si128(b.val, delta))));
+}
+inline v_uint16x8 v_min(const v_uint16x8& a, const v_uint16x8& b)
+{
+ return v_uint16x8(_mm_subs_epu16(a.val, _mm_subs_epu16(a.val, b.val)));
+}
+inline v_uint16x8 v_max(const v_uint16x8& a, const v_uint16x8& b)
+{
+ return v_uint16x8(_mm_adds_epu16(_mm_subs_epu16(a.val, b.val), b.val));
+}
+inline v_uint32x4 v_min(const v_uint32x4& a, const v_uint32x4& b)
+{
+ __m128i delta = _mm_set1_epi32((int)0x80000000);
+ __m128i mask = _mm_cmpgt_epi32(_mm_xor_si128(a.val, delta), _mm_xor_si128(b.val, delta));
+ return v_uint32x4(v_select_si128(mask, b.val, a.val));
+}
+inline v_uint32x4 v_max(const v_uint32x4& a, const v_uint32x4& b)
+{
+ __m128i delta = _mm_set1_epi32((int)0x80000000);
+ __m128i mask = _mm_cmpgt_epi32(_mm_xor_si128(a.val, delta), _mm_xor_si128(b.val, delta));
+ return v_uint32x4(v_select_si128(mask, a.val, b.val));
+}
+inline v_int32x4 v_min(const v_int32x4& a, const v_int32x4& b)
+{
+ return v_int32x4(v_select_si128(_mm_cmpgt_epi32(a.val, b.val), b.val, a.val));
+}
+inline v_int32x4 v_max(const v_int32x4& a, const v_int32x4& b)
+{
+ return v_int32x4(v_select_si128(_mm_cmpgt_epi32(a.val, b.val), a.val, b.val));
+}
+
+#define OPENCV_HAL_IMPL_SSE_INT_CMP_OP(_Tpuvec, _Tpsvec, suffix, sbit) \
+inline _Tpuvec operator == (const _Tpuvec& a, const _Tpuvec& b) \
+{ return _Tpuvec(_mm_cmpeq_##suffix(a.val, b.val)); } \
+inline _Tpuvec operator != (const _Tpuvec& a, const _Tpuvec& b) \
+{ \
+ __m128i not_mask = _mm_set1_epi32(-1); \
+ return _Tpuvec(_mm_xor_si128(_mm_cmpeq_##suffix(a.val, b.val), not_mask)); \
+} \
+inline _Tpsvec operator == (const _Tpsvec& a, const _Tpsvec& b) \
+{ return _Tpsvec(_mm_cmpeq_##suffix(a.val, b.val)); } \
+inline _Tpsvec operator != (const _Tpsvec& a, const _Tpsvec& b) \
+{ \
+ __m128i not_mask = _mm_set1_epi32(-1); \
+ return _Tpsvec(_mm_xor_si128(_mm_cmpeq_##suffix(a.val, b.val), not_mask)); \
+} \
+inline _Tpuvec operator < (const _Tpuvec& a, const _Tpuvec& b) \
+{ \
+ __m128i smask = _mm_set1_##suffix(sbit); \
+ return _Tpuvec(_mm_cmpgt_##suffix(_mm_xor_si128(b.val, smask), _mm_xor_si128(a.val, smask))); \
+} \
+inline _Tpuvec operator > (const _Tpuvec& a, const _Tpuvec& b) \
+{ \
+ __m128i smask = _mm_set1_##suffix(sbit); \
+ return _Tpuvec(_mm_cmpgt_##suffix(_mm_xor_si128(a.val, smask), _mm_xor_si128(b.val, smask))); \
+} \
+inline _Tpuvec operator <= (const _Tpuvec& a, const _Tpuvec& b) \
+{ \
+ __m128i smask = _mm_set1_##suffix(sbit); \
+ __m128i not_mask = _mm_set1_epi32(-1); \
+ __m128i res = _mm_cmpgt_##suffix(_mm_xor_si128(a.val, smask), _mm_xor_si128(b.val, smask)); \
+ return _Tpuvec(_mm_xor_si128(res, not_mask)); \
+} \
+inline _Tpuvec operator >= (const _Tpuvec& a, const _Tpuvec& b) \
+{ \
+ __m128i smask = _mm_set1_##suffix(sbit); \
+ __m128i not_mask = _mm_set1_epi32(-1); \
+ __m128i res = _mm_cmpgt_##suffix(_mm_xor_si128(b.val, smask), _mm_xor_si128(a.val, smask)); \
+ return _Tpuvec(_mm_xor_si128(res, not_mask)); \
+} \
+inline _Tpsvec operator < (const _Tpsvec& a, const _Tpsvec& b) \
+{ \
+ return _Tpsvec(_mm_cmpgt_##suffix(b.val, a.val)); \
+} \
+inline _Tpsvec operator > (const _Tpsvec& a, const _Tpsvec& b) \
+{ \
+ return _Tpsvec(_mm_cmpgt_##suffix(a.val, b.val)); \
+} \
+inline _Tpsvec operator <= (const _Tpsvec& a, const _Tpsvec& b) \
+{ \
+ __m128i not_mask = _mm_set1_epi32(-1); \
+ return _Tpsvec(_mm_xor_si128(_mm_cmpgt_##suffix(a.val, b.val), not_mask)); \
+} \
+inline _Tpsvec operator >= (const _Tpsvec& a, const _Tpsvec& b) \
+{ \
+ __m128i not_mask = _mm_set1_epi32(-1); \
+ return _Tpsvec(_mm_xor_si128(_mm_cmpgt_##suffix(b.val, a.val), not_mask)); \
+}
+
+OPENCV_HAL_IMPL_SSE_INT_CMP_OP(v_uint8x16, v_int8x16, epi8, (char)-128)
+OPENCV_HAL_IMPL_SSE_INT_CMP_OP(v_uint16x8, v_int16x8, epi16, (short)-32768)
+OPENCV_HAL_IMPL_SSE_INT_CMP_OP(v_uint32x4, v_int32x4, epi32, (int)0x80000000)
+
+#define OPENCV_HAL_IMPL_SSE_FLT_CMP_OP(_Tpvec, suffix) \
+inline _Tpvec operator == (const _Tpvec& a, const _Tpvec& b) \
+{ return _Tpvec(_mm_cmpeq_##suffix(a.val, b.val)); } \
+inline _Tpvec operator != (const _Tpvec& a, const _Tpvec& b) \
+{ return _Tpvec(_mm_cmpneq_##suffix(a.val, b.val)); } \
+inline _Tpvec operator < (const _Tpvec& a, const _Tpvec& b) \
+{ return _Tpvec(_mm_cmplt_##suffix(a.val, b.val)); } \
+inline _Tpvec operator > (const _Tpvec& a, const _Tpvec& b) \
+{ return _Tpvec(_mm_cmpgt_##suffix(a.val, b.val)); } \
+inline _Tpvec operator <= (const _Tpvec& a, const _Tpvec& b) \
+{ return _Tpvec(_mm_cmple_##suffix(a.val, b.val)); } \
+inline _Tpvec operator >= (const _Tpvec& a, const _Tpvec& b) \
+{ return _Tpvec(_mm_cmpge_##suffix(a.val, b.val)); }
+
+OPENCV_HAL_IMPL_SSE_FLT_CMP_OP(v_float32x4, ps)
+OPENCV_HAL_IMPL_SSE_FLT_CMP_OP(v_float64x2, pd)
+
+OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_uint8x16, v_add_wrap, _mm_add_epi8)
+OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_int8x16, v_add_wrap, _mm_add_epi8)
+OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_uint16x8, v_add_wrap, _mm_add_epi16)
+OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_int16x8, v_add_wrap, _mm_add_epi16)
+OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_uint8x16, v_sub_wrap, _mm_sub_epi8)
+OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_int8x16, v_sub_wrap, _mm_sub_epi8)
+OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_uint16x8, v_sub_wrap, _mm_sub_epi16)
+OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_int16x8, v_sub_wrap, _mm_sub_epi16)
+
+#define OPENCV_HAL_IMPL_SSE_ABSDIFF_8_16(_Tpuvec, _Tpsvec, bits, smask32) \
+inline _Tpuvec v_absdiff(const _Tpuvec& a, const _Tpuvec& b) \
+{ \
+ return _Tpuvec(_mm_add_epi##bits(_mm_subs_epu##bits(a.val, b.val), _mm_subs_epu##bits(b.val, a.val))); \
+} \
+inline _Tpuvec v_absdiff(const _Tpsvec& a, const _Tpsvec& b) \
+{ \
+ __m128i smask = _mm_set1_epi32(smask32); \
+ __m128i a1 = _mm_xor_si128(a.val, smask); \
+ __m128i b1 = _mm_xor_si128(b.val, smask); \
+ return _Tpuvec(_mm_add_epi##bits(_mm_subs_epu##bits(a1, b1), _mm_subs_epu##bits(b1, a1))); \
+}
+
+OPENCV_HAL_IMPL_SSE_ABSDIFF_8_16(v_uint8x16, v_int8x16, 8, (int)0x80808080)
+OPENCV_HAL_IMPL_SSE_ABSDIFF_8_16(v_uint16x8, v_int16x8, 16, (int)0x80008000)
+
+inline v_uint32x4 v_absdiff(const v_uint32x4& a, const v_uint32x4& b)
+{
+ return v_max(a, b) - v_min(a, b);
+}
+
+inline v_uint32x4 v_absdiff(const v_int32x4& a, const v_int32x4& b)
+{
+ __m128i d = _mm_sub_epi32(a.val, b.val);
+ __m128i m = _mm_cmpgt_epi32(b.val, a.val);
+ return v_uint32x4(_mm_sub_epi32(_mm_xor_si128(d, m), m));
+}
+
+#define OPENCV_HAL_IMPL_SSE_MISC_FLT_OP(_Tpvec, _Tp, _Tpreg, suffix, absmask_vec) \
+inline _Tpvec v_absdiff(const _Tpvec& a, const _Tpvec& b) \
+{ \
+ _Tpreg absmask = _mm_castsi128_##suffix(absmask_vec); \
+ return _Tpvec(_mm_and_##suffix(_mm_sub_##suffix(a.val, b.val), absmask)); \
+} \
+inline _Tpvec v_magnitude(const _Tpvec& a, const _Tpvec& b) \
+{ \
+ _Tpreg res = _mm_add_##suffix(_mm_mul_##suffix(a.val, a.val), _mm_mul_##suffix(b.val, b.val)); \
+ return _Tpvec(_mm_sqrt_##suffix(res)); \
+} \
+inline _Tpvec v_sqr_magnitude(const _Tpvec& a, const _Tpvec& b) \
+{ \
+ _Tpreg res = _mm_add_##suffix(_mm_mul_##suffix(a.val, a.val), _mm_mul_##suffix(b.val, b.val)); \
+ return _Tpvec(res); \
+} \
+inline _Tpvec v_muladd(const _Tpvec& a, const _Tpvec& b, const _Tpvec& c) \
+{ \
+ return _Tpvec(_mm_add_##suffix(_mm_mul_##suffix(a.val, b.val), c.val)); \
+}
+
+OPENCV_HAL_IMPL_SSE_MISC_FLT_OP(v_float32x4, float, __m128, ps, _mm_set1_epi32((int)0x7fffffff))
+OPENCV_HAL_IMPL_SSE_MISC_FLT_OP(v_float64x2, double, __m128d, pd, _mm_srli_epi64(_mm_set1_epi32(-1), 1))
+
+#define OPENCV_HAL_IMPL_SSE_SHIFT_OP(_Tpuvec, _Tpsvec, suffix, srai) \
+inline _Tpuvec operator << (const _Tpuvec& a, int imm) \
+{ \
+ return _Tpuvec(_mm_slli_##suffix(a.val, imm)); \
+} \
+inline _Tpsvec operator << (const _Tpsvec& a, int imm) \
+{ \
+ return _Tpsvec(_mm_slli_##suffix(a.val, imm)); \
+} \
+inline _Tpuvec operator >> (const _Tpuvec& a, int imm) \
+{ \
+ return _Tpuvec(_mm_srli_##suffix(a.val, imm)); \
+} \
+inline _Tpsvec operator >> (const _Tpsvec& a, int imm) \
+{ \
+ return _Tpsvec(srai(a.val, imm)); \
+} \
+template<int imm> \
+inline _Tpuvec v_shl(const _Tpuvec& a) \
+{ \
+ return _Tpuvec(_mm_slli_##suffix(a.val, imm)); \
+} \
+template<int imm> \
+inline _Tpsvec v_shl(const _Tpsvec& a) \
+{ \
+ return _Tpsvec(_mm_slli_##suffix(a.val, imm)); \
+} \
+template<int imm> \
+inline _Tpuvec v_shr(const _Tpuvec& a) \
+{ \
+ return _Tpuvec(_mm_srli_##suffix(a.val, imm)); \
+} \
+template<int imm> \
+inline _Tpsvec v_shr(const _Tpsvec& a) \
+{ \
+ return _Tpsvec(srai(a.val, imm)); \
+}
+
+OPENCV_HAL_IMPL_SSE_SHIFT_OP(v_uint16x8, v_int16x8, epi16, _mm_srai_epi16)
+OPENCV_HAL_IMPL_SSE_SHIFT_OP(v_uint32x4, v_int32x4, epi32, _mm_srai_epi32)
+OPENCV_HAL_IMPL_SSE_SHIFT_OP(v_uint64x2, v_int64x2, epi64, v_srai_epi64)
+
+#define OPENCV_HAL_IMPL_SSE_LOADSTORE_INT_OP(_Tpvec, _Tp) \
+inline _Tpvec v_load(const _Tp* ptr) \
+{ return _Tpvec(_mm_loadu_si128((const __m128i*)ptr)); } \
+inline _Tpvec v_load_aligned(const _Tp* ptr) \
+{ return _Tpvec(_mm_load_si128((const __m128i*)ptr)); } \
+inline _Tpvec v_load_halves(const _Tp* ptr0, const _Tp* ptr1) \
+{ \
+ return _Tpvec(_mm_unpacklo_epi64(_mm_loadl_epi64((const __m128i*)ptr0), \
+ _mm_loadl_epi64((const __m128i*)ptr1))); \
+} \
+inline void v_store(_Tp* ptr, const _Tpvec& a) \
+{ _mm_storeu_si128((__m128i*)ptr, a.val); } \
+inline void v_store_aligned(_Tp* ptr, const _Tpvec& a) \
+{ _mm_store_si128((__m128i*)ptr, a.val); } \
+inline void v_store_low(_Tp* ptr, const _Tpvec& a) \
+{ _mm_storel_epi64((__m128i*)ptr, a.val); } \
+inline void v_store_high(_Tp* ptr, const _Tpvec& a) \
+{ _mm_storel_epi64((__m128i*)ptr, _mm_unpackhi_epi64(a.val, a.val)); }
+
+OPENCV_HAL_IMPL_SSE_LOADSTORE_INT_OP(v_uint8x16, uchar)
+OPENCV_HAL_IMPL_SSE_LOADSTORE_INT_OP(v_int8x16, schar)
+OPENCV_HAL_IMPL_SSE_LOADSTORE_INT_OP(v_uint16x8, ushort)
+OPENCV_HAL_IMPL_SSE_LOADSTORE_INT_OP(v_int16x8, short)
+OPENCV_HAL_IMPL_SSE_LOADSTORE_INT_OP(v_uint32x4, unsigned)
+OPENCV_HAL_IMPL_SSE_LOADSTORE_INT_OP(v_int32x4, int)
+OPENCV_HAL_IMPL_SSE_LOADSTORE_INT_OP(v_uint64x2, uint64)
+OPENCV_HAL_IMPL_SSE_LOADSTORE_INT_OP(v_int64x2, int64)
+
+#define OPENCV_HAL_IMPL_SSE_LOADSTORE_FLT_OP(_Tpvec, _Tp, suffix) \
+inline _Tpvec v_load(const _Tp* ptr) \
+{ return _Tpvec(_mm_loadu_##suffix(ptr)); } \
+inline _Tpvec v_load_aligned(const _Tp* ptr) \
+{ return _Tpvec(_mm_load_##suffix(ptr)); } \
+inline _Tpvec v_load_halves(const _Tp* ptr0, const _Tp* ptr1) \
+{ \
+ return _Tpvec(_mm_castsi128_##suffix( \
+ _mm_unpacklo_epi64(_mm_loadl_epi64((const __m128i*)ptr0), \
+ _mm_loadl_epi64((const __m128i*)ptr1)))); \
+} \
+inline void v_store(_Tp* ptr, const _Tpvec& a) \
+{ _mm_storeu_##suffix(ptr, a.val); } \
+inline void v_store_aligned(_Tp* ptr, const _Tpvec& a) \
+{ _mm_store_##suffix(ptr, a.val); } \
+inline void v_store_low(_Tp* ptr, const _Tpvec& a) \
+{ _mm_storel_epi64((__m128i*)ptr, _mm_cast##suffix##_si128(a.val)); } \
+inline void v_store_high(_Tp* ptr, const _Tpvec& a) \
+{ \
+ __m128i a1 = _mm_cast##suffix##_si128(a.val); \
+ _mm_storel_epi64((__m128i*)ptr, _mm_unpackhi_epi64(a1, a1)); \
+}
+
+OPENCV_HAL_IMPL_SSE_LOADSTORE_FLT_OP(v_float32x4, float, ps)
+OPENCV_HAL_IMPL_SSE_LOADSTORE_FLT_OP(v_float64x2, double, pd)
+
+#if defined(HAVE_FP16)
+inline v_float16x4 v_load_f16(const short* ptr)
+{ return v_float16x4(_mm_loadl_epi64((const __m128i*)ptr)); }
+inline void v_store_f16(short* ptr, v_float16x4& a)
+{ _mm_storel_epi64((__m128i*)ptr, a.val); }
+#endif
+
+#define OPENCV_HAL_IMPL_SSE_REDUCE_OP_8(_Tpvec, scalartype, func, suffix, sbit) \
+inline scalartype v_reduce_##func(const v_##_Tpvec& a) \
+{ \
+ __m128i val = a.val; \
+ val = _mm_##func##_##suffix(val, _mm_srli_si128(val,8)); \
+ val = _mm_##func##_##suffix(val, _mm_srli_si128(val,4)); \
+ val = _mm_##func##_##suffix(val, _mm_srli_si128(val,2)); \
+ return (scalartype)_mm_cvtsi128_si32(val); \
+} \
+inline unsigned scalartype v_reduce_##func(const v_u##_Tpvec& a) \
+{ \
+ __m128i val = a.val; \
+ __m128i smask = _mm_set1_epi16(sbit); \
+ val = _mm_xor_si128(val, smask); \
+ val = _mm_##func##_##suffix(val, _mm_srli_si128(val,8)); \
+ val = _mm_##func##_##suffix(val, _mm_srli_si128(val,4)); \
+ val = _mm_##func##_##suffix(val, _mm_srli_si128(val,2)); \
+ return (unsigned scalartype)(_mm_cvtsi128_si32(val) ^ sbit); \
+}
+#define OPENCV_HAL_IMPL_SSE_REDUCE_OP_8_SUM(_Tpvec, scalartype, suffix) \
+inline scalartype v_reduce_sum(const v_##_Tpvec& a) \
+{ \
+ __m128i val = a.val; \
+ val = _mm_adds_epi##suffix(val, _mm_srli_si128(val, 8)); \
+ val = _mm_adds_epi##suffix(val, _mm_srli_si128(val, 4)); \
+ val = _mm_adds_epi##suffix(val, _mm_srli_si128(val, 2)); \
+ return (scalartype)_mm_cvtsi128_si32(val); \
+} \
+inline unsigned scalartype v_reduce_sum(const v_u##_Tpvec& a) \
+{ \
+ __m128i val = a.val; \
+ val = _mm_adds_epu##suffix(val, _mm_srli_si128(val, 8)); \
+ val = _mm_adds_epu##suffix(val, _mm_srli_si128(val, 4)); \
+ val = _mm_adds_epu##suffix(val, _mm_srli_si128(val, 2)); \
+ return (unsigned scalartype)_mm_cvtsi128_si32(val); \
+}
+OPENCV_HAL_IMPL_SSE_REDUCE_OP_8(int16x8, short, max, epi16, (short)-32768)
+OPENCV_HAL_IMPL_SSE_REDUCE_OP_8(int16x8, short, min, epi16, (short)-32768)
+OPENCV_HAL_IMPL_SSE_REDUCE_OP_8_SUM(int16x8, short, 16)
+
+#define OPENCV_HAL_IMPL_SSE_REDUCE_OP_4(_Tpvec, scalartype, func, scalar_func) \
+inline scalartype v_reduce_##func(const _Tpvec& a) \
+{ \
+ scalartype CV_DECL_ALIGNED(16) buf[4]; \
+ v_store_aligned(buf, a); \
+ scalartype s0 = scalar_func(buf[0], buf[1]); \
+ scalartype s1 = scalar_func(buf[2], buf[3]); \
+ return scalar_func(s0, s1); \
+}
+
+OPENCV_HAL_IMPL_SSE_REDUCE_OP_4(v_uint32x4, unsigned, sum, OPENCV_HAL_ADD)
+OPENCV_HAL_IMPL_SSE_REDUCE_OP_4(v_uint32x4, unsigned, max, std::max)
+OPENCV_HAL_IMPL_SSE_REDUCE_OP_4(v_uint32x4, unsigned, min, std::min)
+OPENCV_HAL_IMPL_SSE_REDUCE_OP_4(v_int32x4, int, sum, OPENCV_HAL_ADD)
+OPENCV_HAL_IMPL_SSE_REDUCE_OP_4(v_int32x4, int, max, std::max)
+OPENCV_HAL_IMPL_SSE_REDUCE_OP_4(v_int32x4, int, min, std::min)
+OPENCV_HAL_IMPL_SSE_REDUCE_OP_4(v_float32x4, float, sum, OPENCV_HAL_ADD)
+OPENCV_HAL_IMPL_SSE_REDUCE_OP_4(v_float32x4, float, max, std::max)
+OPENCV_HAL_IMPL_SSE_REDUCE_OP_4(v_float32x4, float, min, std::min)
+
+#define OPENCV_HAL_IMPL_SSE_CHECK_SIGNS(_Tpvec, suffix, pack_op, and_op, signmask, allmask) \
+inline int v_signmask(const _Tpvec& a) \
+{ \
+ return and_op(_mm_movemask_##suffix(pack_op(a.val)), signmask); \
+} \
+inline bool v_check_all(const _Tpvec& a) \
+{ return and_op(_mm_movemask_##suffix(a.val), allmask) == allmask; } \
+inline bool v_check_any(const _Tpvec& a) \
+{ return and_op(_mm_movemask_##suffix(a.val), allmask) != 0; }
+
+#define OPENCV_HAL_PACKS(a) _mm_packs_epi16(a, a)
+inline __m128i v_packq_epi32(__m128i a)
+{
+ __m128i b = _mm_packs_epi32(a, a);
+ return _mm_packs_epi16(b, b);
+}
+
+OPENCV_HAL_IMPL_SSE_CHECK_SIGNS(v_uint8x16, epi8, OPENCV_HAL_NOP, OPENCV_HAL_1ST, 65535, 65535)
+OPENCV_HAL_IMPL_SSE_CHECK_SIGNS(v_int8x16, epi8, OPENCV_HAL_NOP, OPENCV_HAL_1ST, 65535, 65535)
+OPENCV_HAL_IMPL_SSE_CHECK_SIGNS(v_uint16x8, epi8, OPENCV_HAL_PACKS, OPENCV_HAL_AND, 255, (int)0xaaaa)
+OPENCV_HAL_IMPL_SSE_CHECK_SIGNS(v_int16x8, epi8, OPENCV_HAL_PACKS, OPENCV_HAL_AND, 255, (int)0xaaaa)
+OPENCV_HAL_IMPL_SSE_CHECK_SIGNS(v_uint32x4, epi8, v_packq_epi32, OPENCV_HAL_AND, 15, (int)0x8888)
+OPENCV_HAL_IMPL_SSE_CHECK_SIGNS(v_int32x4, epi8, v_packq_epi32, OPENCV_HAL_AND, 15, (int)0x8888)
+OPENCV_HAL_IMPL_SSE_CHECK_SIGNS(v_float32x4, ps, OPENCV_HAL_NOP, OPENCV_HAL_1ST, 15, 15)
+OPENCV_HAL_IMPL_SSE_CHECK_SIGNS(v_float64x2, pd, OPENCV_HAL_NOP, OPENCV_HAL_1ST, 3, 3)
+
+#define OPENCV_HAL_IMPL_SSE_SELECT(_Tpvec, suffix) \
+inline _Tpvec v_select(const _Tpvec& mask, const _Tpvec& a, const _Tpvec& b) \
+{ \
+ return _Tpvec(_mm_xor_##suffix(b.val, _mm_and_##suffix(_mm_xor_##suffix(b.val, a.val), mask.val))); \
+}
+
+OPENCV_HAL_IMPL_SSE_SELECT(v_uint8x16, si128)
+OPENCV_HAL_IMPL_SSE_SELECT(v_int8x16, si128)
+OPENCV_HAL_IMPL_SSE_SELECT(v_uint16x8, si128)
+OPENCV_HAL_IMPL_SSE_SELECT(v_int16x8, si128)
+OPENCV_HAL_IMPL_SSE_SELECT(v_uint32x4, si128)
+OPENCV_HAL_IMPL_SSE_SELECT(v_int32x4, si128)
+// OPENCV_HAL_IMPL_SSE_SELECT(v_uint64x2, si128)
+// OPENCV_HAL_IMPL_SSE_SELECT(v_int64x2, si128)
+OPENCV_HAL_IMPL_SSE_SELECT(v_float32x4, ps)
+OPENCV_HAL_IMPL_SSE_SELECT(v_float64x2, pd)
+
+#define OPENCV_HAL_IMPL_SSE_EXPAND(_Tpuvec, _Tpwuvec, _Tpu, _Tpsvec, _Tpwsvec, _Tps, suffix, wsuffix, shift) \
+inline void v_expand(const _Tpuvec& a, _Tpwuvec& b0, _Tpwuvec& b1) \
+{ \
+ __m128i z = _mm_setzero_si128(); \
+ b0.val = _mm_unpacklo_##suffix(a.val, z); \
+ b1.val = _mm_unpackhi_##suffix(a.val, z); \
+} \
+inline _Tpwuvec v_load_expand(const _Tpu* ptr) \
+{ \
+ __m128i z = _mm_setzero_si128(); \
+ return _Tpwuvec(_mm_unpacklo_##suffix(_mm_loadl_epi64((const __m128i*)ptr), z)); \
+} \
+inline void v_expand(const _Tpsvec& a, _Tpwsvec& b0, _Tpwsvec& b1) \
+{ \
+ b0.val = _mm_srai_##wsuffix(_mm_unpacklo_##suffix(a.val, a.val), shift); \
+ b1.val = _mm_srai_##wsuffix(_mm_unpackhi_##suffix(a.val, a.val), shift); \
+} \
+inline _Tpwsvec v_load_expand(const _Tps* ptr) \
+{ \
+ __m128i a = _mm_loadl_epi64((const __m128i*)ptr); \
+ return _Tpwsvec(_mm_srai_##wsuffix(_mm_unpacklo_##suffix(a, a), shift)); \
+}
+
+OPENCV_HAL_IMPL_SSE_EXPAND(v_uint8x16, v_uint16x8, uchar, v_int8x16, v_int16x8, schar, epi8, epi16, 8)
+OPENCV_HAL_IMPL_SSE_EXPAND(v_uint16x8, v_uint32x4, ushort, v_int16x8, v_int32x4, short, epi16, epi32, 16)
+
+inline void v_expand(const v_uint32x4& a, v_uint64x2& b0, v_uint64x2& b1)
+{
+ __m128i z = _mm_setzero_si128();
+ b0.val = _mm_unpacklo_epi32(a.val, z);
+ b1.val = _mm_unpackhi_epi32(a.val, z);
+}
+inline v_uint64x2 v_load_expand(const unsigned* ptr)
+{
+ __m128i z = _mm_setzero_si128();
+ return v_uint64x2(_mm_unpacklo_epi32(_mm_loadl_epi64((const __m128i*)ptr), z));
+}
+inline void v_expand(const v_int32x4& a, v_int64x2& b0, v_int64x2& b1)
+{
+ __m128i s = _mm_srai_epi32(a.val, 31);
+ b0.val = _mm_unpacklo_epi32(a.val, s);
+ b1.val = _mm_unpackhi_epi32(a.val, s);
+}
+inline v_int64x2 v_load_expand(const int* ptr)
+{
+ __m128i a = _mm_loadl_epi64((const __m128i*)ptr);
+ __m128i s = _mm_srai_epi32(a, 31);
+ return v_int64x2(_mm_unpacklo_epi32(a, s));
+}
+
+inline v_uint32x4 v_load_expand_q(const uchar* ptr)
+{
+ __m128i z = _mm_setzero_si128();
+ __m128i a = _mm_cvtsi32_si128(*(const int*)ptr);
+ return v_uint32x4(_mm_unpacklo_epi16(_mm_unpacklo_epi8(a, z), z));
+}
+
+inline v_int32x4 v_load_expand_q(const schar* ptr)
+{
+ __m128i a = _mm_cvtsi32_si128(*(const int*)ptr);
+ a = _mm_unpacklo_epi8(a, a);
+ a = _mm_unpacklo_epi8(a, a);
+ return v_int32x4(_mm_srai_epi32(a, 24));
+}
+
+#define OPENCV_HAL_IMPL_SSE_UNPACKS(_Tpvec, suffix, cast_from, cast_to) \
+inline void v_zip(const _Tpvec& a0, const _Tpvec& a1, _Tpvec& b0, _Tpvec& b1) \
+{ \
+ b0.val = _mm_unpacklo_##suffix(a0.val, a1.val); \
+ b1.val = _mm_unpackhi_##suffix(a0.val, a1.val); \
+} \
+inline _Tpvec v_combine_low(const _Tpvec& a, const _Tpvec& b) \
+{ \
+ __m128i a1 = cast_from(a.val), b1 = cast_from(b.val); \
+ return _Tpvec(cast_to(_mm_unpacklo_epi64(a1, b1))); \
+} \
+inline _Tpvec v_combine_high(const _Tpvec& a, const _Tpvec& b) \
+{ \
+ __m128i a1 = cast_from(a.val), b1 = cast_from(b.val); \
+ return _Tpvec(cast_to(_mm_unpackhi_epi64(a1, b1))); \
+} \
+inline void v_recombine(const _Tpvec& a, const _Tpvec& b, _Tpvec& c, _Tpvec& d) \
+{ \
+ __m128i a1 = cast_from(a.val), b1 = cast_from(b.val); \
+ c.val = cast_to(_mm_unpacklo_epi64(a1, b1)); \
+ d.val = cast_to(_mm_unpackhi_epi64(a1, b1)); \
+}
+
+OPENCV_HAL_IMPL_SSE_UNPACKS(v_uint8x16, epi8, OPENCV_HAL_NOP, OPENCV_HAL_NOP)
+OPENCV_HAL_IMPL_SSE_UNPACKS(v_int8x16, epi8, OPENCV_HAL_NOP, OPENCV_HAL_NOP)
+OPENCV_HAL_IMPL_SSE_UNPACKS(v_uint16x8, epi16, OPENCV_HAL_NOP, OPENCV_HAL_NOP)
+OPENCV_HAL_IMPL_SSE_UNPACKS(v_int16x8, epi16, OPENCV_HAL_NOP, OPENCV_HAL_NOP)
+OPENCV_HAL_IMPL_SSE_UNPACKS(v_uint32x4, epi32, OPENCV_HAL_NOP, OPENCV_HAL_NOP)
+OPENCV_HAL_IMPL_SSE_UNPACKS(v_int32x4, epi32, OPENCV_HAL_NOP, OPENCV_HAL_NOP)
+OPENCV_HAL_IMPL_SSE_UNPACKS(v_float32x4, ps, _mm_castps_si128, _mm_castsi128_ps)
+OPENCV_HAL_IMPL_SSE_UNPACKS(v_float64x2, pd, _mm_castpd_si128, _mm_castsi128_pd)
+
+template<int s, typename _Tpvec>
+inline _Tpvec v_extract(const _Tpvec& a, const _Tpvec& b)
+{
+ const int w = sizeof(typename _Tpvec::lane_type);
+ const int n = _Tpvec::nlanes;
+ __m128i ra, rb;
+ ra = _mm_srli_si128(a.val, s*w);
+ rb = _mm_slli_si128(b.val, (n-s)*w);
+ return _Tpvec(_mm_or_si128(ra, rb));
+}
+
+inline v_int32x4 v_round(const v_float32x4& a)
+{ return v_int32x4(_mm_cvtps_epi32(a.val)); }
+
+inline v_int32x4 v_floor(const v_float32x4& a)
+{
+ __m128i a1 = _mm_cvtps_epi32(a.val);
+ __m128i mask = _mm_castps_si128(_mm_cmpgt_ps(_mm_cvtepi32_ps(a1), a.val));
+ return v_int32x4(_mm_add_epi32(a1, mask));
+}
+
+inline v_int32x4 v_ceil(const v_float32x4& a)
+{
+ __m128i a1 = _mm_cvtps_epi32(a.val);
+ __m128i mask = _mm_castps_si128(_mm_cmpgt_ps(a.val, _mm_cvtepi32_ps(a1)));
+ return v_int32x4(_mm_sub_epi32(a1, mask));
+}
+
+inline v_int32x4 v_trunc(const v_float32x4& a)
+{ return v_int32x4(_mm_cvttps_epi32(a.val)); }
+
+inline v_int32x4 v_round(const v_float64x2& a)
+{ return v_int32x4(_mm_cvtpd_epi32(a.val)); }
+
+inline v_int32x4 v_floor(const v_float64x2& a)
+{
+ __m128i a1 = _mm_cvtpd_epi32(a.val);
+ __m128i mask = _mm_castpd_si128(_mm_cmpgt_pd(_mm_cvtepi32_pd(a1), a.val));
+ mask = _mm_srli_si128(_mm_slli_si128(mask, 4), 8); // m0 m0 m1 m1 => m0 m1 0 0
+ return v_int32x4(_mm_add_epi32(a1, mask));
+}
+
+inline v_int32x4 v_ceil(const v_float64x2& a)
+{
+ __m128i a1 = _mm_cvtpd_epi32(a.val);
+ __m128i mask = _mm_castpd_si128(_mm_cmpgt_pd(a.val, _mm_cvtepi32_pd(a1)));
+ mask = _mm_srli_si128(_mm_slli_si128(mask, 4), 8); // m0 m0 m1 m1 => m0 m1 0 0
+ return v_int32x4(_mm_sub_epi32(a1, mask));
+}
+
+inline v_int32x4 v_trunc(const v_float64x2& a)
+{ return v_int32x4(_mm_cvttpd_epi32(a.val)); }
+
+#define OPENCV_HAL_IMPL_SSE_TRANSPOSE4x4(_Tpvec, suffix, cast_from, cast_to) \
+inline void v_transpose4x4(const _Tpvec& a0, const _Tpvec& a1, \
+ const _Tpvec& a2, const _Tpvec& a3, \
+ _Tpvec& b0, _Tpvec& b1, \
+ _Tpvec& b2, _Tpvec& b3) \
+{ \
+ __m128i t0 = cast_from(_mm_unpacklo_##suffix(a0.val, a1.val)); \
+ __m128i t1 = cast_from(_mm_unpacklo_##suffix(a2.val, a3.val)); \
+ __m128i t2 = cast_from(_mm_unpackhi_##suffix(a0.val, a1.val)); \
+ __m128i t3 = cast_from(_mm_unpackhi_##suffix(a2.val, a3.val)); \
+\
+ b0.val = cast_to(_mm_unpacklo_epi64(t0, t1)); \
+ b1.val = cast_to(_mm_unpackhi_epi64(t0, t1)); \
+ b2.val = cast_to(_mm_unpacklo_epi64(t2, t3)); \
+ b3.val = cast_to(_mm_unpackhi_epi64(t2, t3)); \
+}
+
+OPENCV_HAL_IMPL_SSE_TRANSPOSE4x4(v_uint32x4, epi32, OPENCV_HAL_NOP, OPENCV_HAL_NOP)
+OPENCV_HAL_IMPL_SSE_TRANSPOSE4x4(v_int32x4, epi32, OPENCV_HAL_NOP, OPENCV_HAL_NOP)
+OPENCV_HAL_IMPL_SSE_TRANSPOSE4x4(v_float32x4, ps, _mm_castps_si128, _mm_castsi128_ps)
+
+// adopted from sse_utils.hpp
+inline void v_load_deinterleave(const uchar* ptr, v_uint8x16& a, v_uint8x16& b, v_uint8x16& c)
+{
+ __m128i t00 = _mm_loadu_si128((const __m128i*)ptr);
+ __m128i t01 = _mm_loadu_si128((const __m128i*)(ptr + 16));
+ __m128i t02 = _mm_loadu_si128((const __m128i*)(ptr + 32));
+
+ __m128i t10 = _mm_unpacklo_epi8(t00, _mm_unpackhi_epi64(t01, t01));
+ __m128i t11 = _mm_unpacklo_epi8(_mm_unpackhi_epi64(t00, t00), t02);
+ __m128i t12 = _mm_unpacklo_epi8(t01, _mm_unpackhi_epi64(t02, t02));
+
+ __m128i t20 = _mm_unpacklo_epi8(t10, _mm_unpackhi_epi64(t11, t11));
+ __m128i t21 = _mm_unpacklo_epi8(_mm_unpackhi_epi64(t10, t10), t12);
+ __m128i t22 = _mm_unpacklo_epi8(t11, _mm_unpackhi_epi64(t12, t12));
+
+ __m128i t30 = _mm_unpacklo_epi8(t20, _mm_unpackhi_epi64(t21, t21));
+ __m128i t31 = _mm_unpacklo_epi8(_mm_unpackhi_epi64(t20, t20), t22);
+ __m128i t32 = _mm_unpacklo_epi8(t21, _mm_unpackhi_epi64(t22, t22));
+
+ a.val = _mm_unpacklo_epi8(t30, _mm_unpackhi_epi64(t31, t31));
+ b.val = _mm_unpacklo_epi8(_mm_unpackhi_epi64(t30, t30), t32);
+ c.val = _mm_unpacklo_epi8(t31, _mm_unpackhi_epi64(t32, t32));
+}
+
+inline void v_load_deinterleave(const uchar* ptr, v_uint8x16& a, v_uint8x16& b, v_uint8x16& c, v_uint8x16& d)
+{
+ __m128i u0 = _mm_loadu_si128((const __m128i*)ptr); // a0 b0 c0 d0 a1 b1 c1 d1 ...
+ __m128i u1 = _mm_loadu_si128((const __m128i*)(ptr + 16)); // a4 b4 c4 d4 ...
+ __m128i u2 = _mm_loadu_si128((const __m128i*)(ptr + 32)); // a8 b8 c8 d8 ...
+ __m128i u3 = _mm_loadu_si128((const __m128i*)(ptr + 48)); // a12 b12 c12 d12 ...
+
+ __m128i v0 = _mm_unpacklo_epi8(u0, u2); // a0 a8 b0 b8 ...
+ __m128i v1 = _mm_unpackhi_epi8(u0, u2); // a2 a10 b2 b10 ...
+ __m128i v2 = _mm_unpacklo_epi8(u1, u3); // a4 a12 b4 b12 ...
+ __m128i v3 = _mm_unpackhi_epi8(u1, u3); // a6 a14 b6 b14 ...
+
+ u0 = _mm_unpacklo_epi8(v0, v2); // a0 a4 a8 a12 ...
+ u1 = _mm_unpacklo_epi8(v1, v3); // a2 a6 a10 a14 ...
+ u2 = _mm_unpackhi_epi8(v0, v2); // a1 a5 a9 a13 ...
+ u3 = _mm_unpackhi_epi8(v1, v3); // a3 a7 a11 a15 ...
+
+ v0 = _mm_unpacklo_epi8(u0, u1); // a0 a2 a4 a6 ...
+ v1 = _mm_unpacklo_epi8(u2, u3); // a1 a3 a5 a7 ...
+ v2 = _mm_unpackhi_epi8(u0, u1); // c0 c2 c4 c6 ...
+ v3 = _mm_unpackhi_epi8(u2, u3); // c1 c3 c5 c7 ...
+
+ a.val = _mm_unpacklo_epi8(v0, v1);
+ b.val = _mm_unpackhi_epi8(v0, v1);
+ c.val = _mm_unpacklo_epi8(v2, v3);
+ d.val = _mm_unpackhi_epi8(v2, v3);
+}
+
+inline void v_load_deinterleave(const ushort* ptr, v_uint16x8& a, v_uint16x8& b, v_uint16x8& c)
+{
+ __m128i t00 = _mm_loadu_si128((const __m128i*)ptr);
+ __m128i t01 = _mm_loadu_si128((const __m128i*)(ptr + 8));
+ __m128i t02 = _mm_loadu_si128((const __m128i*)(ptr + 16));
+
+ __m128i t10 = _mm_unpacklo_epi16(t00, _mm_unpackhi_epi64(t01, t01));
+ __m128i t11 = _mm_unpacklo_epi16(_mm_unpackhi_epi64(t00, t00), t02);
+ __m128i t12 = _mm_unpacklo_epi16(t01, _mm_unpackhi_epi64(t02, t02));
+
+ __m128i t20 = _mm_unpacklo_epi16(t10, _mm_unpackhi_epi64(t11, t11));
+ __m128i t21 = _mm_unpacklo_epi16(_mm_unpackhi_epi64(t10, t10), t12);
+ __m128i t22 = _mm_unpacklo_epi16(t11, _mm_unpackhi_epi64(t12, t12));
+
+ a.val = _mm_unpacklo_epi16(t20, _mm_unpackhi_epi64(t21, t21));
+ b.val = _mm_unpacklo_epi16(_mm_unpackhi_epi64(t20, t20), t22);
+ c.val = _mm_unpacklo_epi16(t21, _mm_unpackhi_epi64(t22, t22));
+}
+
+inline void v_load_deinterleave(const ushort* ptr, v_uint16x8& a, v_uint16x8& b, v_uint16x8& c, v_uint16x8& d)
+{
+ __m128i u0 = _mm_loadu_si128((const __m128i*)ptr); // a0 b0 c0 d0 a1 b1 c1 d1
+ __m128i u1 = _mm_loadu_si128((const __m128i*)(ptr + 8)); // a2 b2 c2 d2 ...
+ __m128i u2 = _mm_loadu_si128((const __m128i*)(ptr + 16)); // a4 b4 c4 d4 ...
+ __m128i u3 = _mm_loadu_si128((const __m128i*)(ptr + 24)); // a6 b6 c6 d6 ...
+
+ __m128i v0 = _mm_unpacklo_epi16(u0, u2); // a0 a4 b0 b4 ...
+ __m128i v1 = _mm_unpackhi_epi16(u0, u2); // a1 a5 b1 b5 ...
+ __m128i v2 = _mm_unpacklo_epi16(u1, u3); // a2 a6 b2 b6 ...
+ __m128i v3 = _mm_unpackhi_epi16(u1, u3); // a3 a7 b3 b7 ...
+
+ u0 = _mm_unpacklo_epi16(v0, v2); // a0 a2 a4 a6 ...
+ u1 = _mm_unpacklo_epi16(v1, v3); // a1 a3 a5 a7 ...
+ u2 = _mm_unpackhi_epi16(v0, v2); // c0 c2 c4 c6 ...
+ u3 = _mm_unpackhi_epi16(v1, v3); // c1 c3 c5 c7 ...
+
+ a.val = _mm_unpacklo_epi16(u0, u1);
+ b.val = _mm_unpackhi_epi16(u0, u1);
+ c.val = _mm_unpacklo_epi16(u2, u3);
+ d.val = _mm_unpackhi_epi16(u2, u3);
+}
+
+inline void v_load_deinterleave(const unsigned* ptr, v_uint32x4& a, v_uint32x4& b, v_uint32x4& c)
+{
+ __m128i t00 = _mm_loadu_si128((const __m128i*)ptr);
+ __m128i t01 = _mm_loadu_si128((const __m128i*)(ptr + 4));
+ __m128i t02 = _mm_loadu_si128((const __m128i*)(ptr + 8));
+
+ __m128i t10 = _mm_unpacklo_epi32(t00, _mm_unpackhi_epi64(t01, t01));
+ __m128i t11 = _mm_unpacklo_epi32(_mm_unpackhi_epi64(t00, t00), t02);
+ __m128i t12 = _mm_unpacklo_epi32(t01, _mm_unpackhi_epi64(t02, t02));
+
+ a.val = _mm_unpacklo_epi32(t10, _mm_unpackhi_epi64(t11, t11));
+ b.val = _mm_unpacklo_epi32(_mm_unpackhi_epi64(t10, t10), t12);
+ c.val = _mm_unpacklo_epi32(t11, _mm_unpackhi_epi64(t12, t12));
+}
+
+inline void v_load_deinterleave(const unsigned* ptr, v_uint32x4& a, v_uint32x4& b, v_uint32x4& c, v_uint32x4& d)
+{
+ v_uint32x4 u0(_mm_loadu_si128((const __m128i*)ptr)); // a0 b0 c0 d0
+ v_uint32x4 u1(_mm_loadu_si128((const __m128i*)(ptr + 4))); // a1 b1 c1 d1
+ v_uint32x4 u2(_mm_loadu_si128((const __m128i*)(ptr + 8))); // a2 b2 c2 d2
+ v_uint32x4 u3(_mm_loadu_si128((const __m128i*)(ptr + 12))); // a3 b3 c3 d3
+
+ v_transpose4x4(u0, u1, u2, u3, a, b, c, d);
+}
+
+// 2-channel, float only
+inline void v_load_deinterleave(const float* ptr, v_float32x4& a, v_float32x4& b)
+{
+ const int mask_lo = _MM_SHUFFLE(2, 0, 2, 0), mask_hi = _MM_SHUFFLE(3, 1, 3, 1);
+
+ __m128 u0 = _mm_loadu_ps(ptr); // a0 b0 a1 b1
+ __m128 u1 = _mm_loadu_ps((ptr + 4)); // a2 b2 a3 b3
+
+ a.val = _mm_shuffle_ps(u0, u1, mask_lo); // a0 a1 a2 a3
+ b.val = _mm_shuffle_ps(u0, u1, mask_hi); // b0 b1 ab b3
+}
+
+inline void v_store_interleave( short* ptr, const v_int16x8& a, const v_int16x8& b )
+{
+ __m128i t0, t1;
+ t0 = _mm_unpacklo_epi16(a.val, b.val);
+ t1 = _mm_unpackhi_epi16(a.val, b.val);
+ _mm_storeu_si128((__m128i*)(ptr), t0);
+ _mm_storeu_si128((__m128i*)(ptr + 8), t1);
+}
+
+inline void v_store_interleave( uchar* ptr, const v_uint8x16& a, const v_uint8x16& b,
+ const v_uint8x16& c )
+{
+ __m128i z = _mm_setzero_si128();
+ __m128i ab0 = _mm_unpacklo_epi8(a.val, b.val);
+ __m128i ab1 = _mm_unpackhi_epi8(a.val, b.val);
+ __m128i c0 = _mm_unpacklo_epi8(c.val, z);
+ __m128i c1 = _mm_unpackhi_epi8(c.val, z);
+
+ __m128i p00 = _mm_unpacklo_epi16(ab0, c0);
+ __m128i p01 = _mm_unpackhi_epi16(ab0, c0);
+ __m128i p02 = _mm_unpacklo_epi16(ab1, c1);
+ __m128i p03 = _mm_unpackhi_epi16(ab1, c1);
+
+ __m128i p10 = _mm_unpacklo_epi32(p00, p01);
+ __m128i p11 = _mm_unpackhi_epi32(p00, p01);
+ __m128i p12 = _mm_unpacklo_epi32(p02, p03);
+ __m128i p13 = _mm_unpackhi_epi32(p02, p03);
+
+ __m128i p20 = _mm_unpacklo_epi64(p10, p11);
+ __m128i p21 = _mm_unpackhi_epi64(p10, p11);
+ __m128i p22 = _mm_unpacklo_epi64(p12, p13);
+ __m128i p23 = _mm_unpackhi_epi64(p12, p13);
+
+ p20 = _mm_slli_si128(p20, 1);
+ p22 = _mm_slli_si128(p22, 1);
+
+ __m128i p30 = _mm_slli_epi64(_mm_unpacklo_epi32(p20, p21), 8);
+ __m128i p31 = _mm_srli_epi64(_mm_unpackhi_epi32(p20, p21), 8);
+ __m128i p32 = _mm_slli_epi64(_mm_unpacklo_epi32(p22, p23), 8);
+ __m128i p33 = _mm_srli_epi64(_mm_unpackhi_epi32(p22, p23), 8);
+
+ __m128i p40 = _mm_unpacklo_epi64(p30, p31);
+ __m128i p41 = _mm_unpackhi_epi64(p30, p31);
+ __m128i p42 = _mm_unpacklo_epi64(p32, p33);
+ __m128i p43 = _mm_unpackhi_epi64(p32, p33);
+
+ __m128i v0 = _mm_or_si128(_mm_srli_si128(p40, 2), _mm_slli_si128(p41, 10));
+ __m128i v1 = _mm_or_si128(_mm_srli_si128(p41, 6), _mm_slli_si128(p42, 6));
+ __m128i v2 = _mm_or_si128(_mm_srli_si128(p42, 10), _mm_slli_si128(p43, 2));
+
+ _mm_storeu_si128((__m128i*)(ptr), v0);
+ _mm_storeu_si128((__m128i*)(ptr + 16), v1);
+ _mm_storeu_si128((__m128i*)(ptr + 32), v2);
+}
+
+inline void v_store_interleave( uchar* ptr, const v_uint8x16& a, const v_uint8x16& b,
+ const v_uint8x16& c, const v_uint8x16& d)
+{
+ // a0 a1 a2 a3 ....
+ // b0 b1 b2 b3 ....
+ // c0 c1 c2 c3 ....
+ // d0 d1 d2 d3 ....
+ __m128i u0 = _mm_unpacklo_epi8(a.val, c.val); // a0 c0 a1 c1 ...
+ __m128i u1 = _mm_unpackhi_epi8(a.val, c.val); // a8 c8 a9 c9 ...
+ __m128i u2 = _mm_unpacklo_epi8(b.val, d.val); // b0 d0 b1 d1 ...
+ __m128i u3 = _mm_unpackhi_epi8(b.val, d.val); // b8 d8 b9 d9 ...
+
+ __m128i v0 = _mm_unpacklo_epi8(u0, u2); // a0 b0 c0 d0 ...
+ __m128i v1 = _mm_unpacklo_epi8(u1, u3); // a8 b8 c8 d8 ...
+ __m128i v2 = _mm_unpackhi_epi8(u0, u2); // a4 b4 c4 d4 ...
+ __m128i v3 = _mm_unpackhi_epi8(u1, u3); // a12 b12 c12 d12 ...
+
+ _mm_storeu_si128((__m128i*)ptr, v0);
+ _mm_storeu_si128((__m128i*)(ptr + 16), v2);
+ _mm_storeu_si128((__m128i*)(ptr + 32), v1);
+ _mm_storeu_si128((__m128i*)(ptr + 48), v3);
+}
+
+inline void v_store_interleave( ushort* ptr, const v_uint16x8& a,
+ const v_uint16x8& b,
+ const v_uint16x8& c )
+{
+ __m128i z = _mm_setzero_si128();
+ __m128i ab0 = _mm_unpacklo_epi16(a.val, b.val);
+ __m128i ab1 = _mm_unpackhi_epi16(a.val, b.val);
+ __m128i c0 = _mm_unpacklo_epi16(c.val, z);
+ __m128i c1 = _mm_unpackhi_epi16(c.val, z);
+
+ __m128i p10 = _mm_unpacklo_epi32(ab0, c0);
+ __m128i p11 = _mm_unpackhi_epi32(ab0, c0);
+ __m128i p12 = _mm_unpacklo_epi32(ab1, c1);
+ __m128i p13 = _mm_unpackhi_epi32(ab1, c1);
+
+ __m128i p20 = _mm_unpacklo_epi64(p10, p11);
+ __m128i p21 = _mm_unpackhi_epi64(p10, p11);
+ __m128i p22 = _mm_unpacklo_epi64(p12, p13);
+ __m128i p23 = _mm_unpackhi_epi64(p12, p13);
+
+ p20 = _mm_slli_si128(p20, 2);
+ p22 = _mm_slli_si128(p22, 2);
+
+ __m128i p30 = _mm_unpacklo_epi64(p20, p21);
+ __m128i p31 = _mm_unpackhi_epi64(p20, p21);
+ __m128i p32 = _mm_unpacklo_epi64(p22, p23);
+ __m128i p33 = _mm_unpackhi_epi64(p22, p23);
+
+ __m128i v0 = _mm_or_si128(_mm_srli_si128(p30, 2), _mm_slli_si128(p31, 10));
+ __m128i v1 = _mm_or_si128(_mm_srli_si128(p31, 6), _mm_slli_si128(p32, 6));
+ __m128i v2 = _mm_or_si128(_mm_srli_si128(p32, 10), _mm_slli_si128(p33, 2));
+
+ _mm_storeu_si128((__m128i*)(ptr), v0);
+ _mm_storeu_si128((__m128i*)(ptr + 8), v1);
+ _mm_storeu_si128((__m128i*)(ptr + 16), v2);
+}
+
+inline void v_store_interleave( ushort* ptr, const v_uint16x8& a, const v_uint16x8& b,
+ const v_uint16x8& c, const v_uint16x8& d)
+{
+ // a0 a1 a2 a3 ....
+ // b0 b1 b2 b3 ....
+ // c0 c1 c2 c3 ....
+ // d0 d1 d2 d3 ....
+ __m128i u0 = _mm_unpacklo_epi16(a.val, c.val); // a0 c0 a1 c1 ...
+ __m128i u1 = _mm_unpackhi_epi16(a.val, c.val); // a4 c4 a5 c5 ...
+ __m128i u2 = _mm_unpacklo_epi16(b.val, d.val); // b0 d0 b1 d1 ...
+ __m128i u3 = _mm_unpackhi_epi16(b.val, d.val); // b4 d4 b5 d5 ...
+
+ __m128i v0 = _mm_unpacklo_epi16(u0, u2); // a0 b0 c0 d0 ...
+ __m128i v1 = _mm_unpacklo_epi16(u1, u3); // a4 b4 c4 d4 ...
+ __m128i v2 = _mm_unpackhi_epi16(u0, u2); // a2 b2 c2 d2 ...
+ __m128i v3 = _mm_unpackhi_epi16(u1, u3); // a6 b6 c6 d6 ...
+
+ _mm_storeu_si128((__m128i*)ptr, v0);
+ _mm_storeu_si128((__m128i*)(ptr + 8), v2);
+ _mm_storeu_si128((__m128i*)(ptr + 16), v1);
+ _mm_storeu_si128((__m128i*)(ptr + 24), v3);
+}
+
+inline void v_store_interleave( unsigned* ptr, const v_uint32x4& a, const v_uint32x4& b,
+ const v_uint32x4& c )
+{
+ v_uint32x4 z = v_setzero_u32(), u0, u1, u2, u3;
+ v_transpose4x4(a, b, c, z, u0, u1, u2, u3);
+
+ __m128i v0 = _mm_or_si128(u0.val, _mm_slli_si128(u1.val, 12));
+ __m128i v1 = _mm_or_si128(_mm_srli_si128(u1.val, 4), _mm_slli_si128(u2.val, 8));
+ __m128i v2 = _mm_or_si128(_mm_srli_si128(u2.val, 8), _mm_slli_si128(u3.val, 4));
+
+ _mm_storeu_si128((__m128i*)ptr, v0);
+ _mm_storeu_si128((__m128i*)(ptr + 4), v1);
+ _mm_storeu_si128((__m128i*)(ptr + 8), v2);
+}
+
+inline void v_store_interleave(unsigned* ptr, const v_uint32x4& a, const v_uint32x4& b,
+ const v_uint32x4& c, const v_uint32x4& d)
+{
+ v_uint32x4 t0, t1, t2, t3;
+ v_transpose4x4(a, b, c, d, t0, t1, t2, t3);
+ v_store(ptr, t0);
+ v_store(ptr + 4, t1);
+ v_store(ptr + 8, t2);
+ v_store(ptr + 12, t3);
+}
+
+// 2-channel, float only
+inline void v_store_interleave(float* ptr, const v_float32x4& a, const v_float32x4& b)
+{
+ // a0 a1 a2 a3 ...
+ // b0 b1 b2 b3 ...
+ __m128 u0 = _mm_unpacklo_ps(a.val, b.val); // a0 b0 a1 b1
+ __m128 u1 = _mm_unpackhi_ps(a.val, b.val); // a2 b2 a3 b3
+
+ _mm_storeu_ps(ptr, u0);
+ _mm_storeu_ps((ptr + 4), u1);
+}
+
+#define OPENCV_HAL_IMPL_SSE_LOADSTORE_INTERLEAVE(_Tpvec, _Tp, suffix, _Tpuvec, _Tpu, usuffix) \
+inline void v_load_deinterleave( const _Tp* ptr, _Tpvec& a0, \
+ _Tpvec& b0, _Tpvec& c0 ) \
+{ \
+ _Tpuvec a1, b1, c1; \
+ v_load_deinterleave((const _Tpu*)ptr, a1, b1, c1); \
+ a0 = v_reinterpret_as_##suffix(a1); \
+ b0 = v_reinterpret_as_##suffix(b1); \
+ c0 = v_reinterpret_as_##suffix(c1); \
+} \
+inline void v_load_deinterleave( const _Tp* ptr, _Tpvec& a0, \
+ _Tpvec& b0, _Tpvec& c0, _Tpvec& d0 ) \
+{ \
+ _Tpuvec a1, b1, c1, d1; \
+ v_load_deinterleave((const _Tpu*)ptr, a1, b1, c1, d1); \
+ a0 = v_reinterpret_as_##suffix(a1); \
+ b0 = v_reinterpret_as_##suffix(b1); \
+ c0 = v_reinterpret_as_##suffix(c1); \
+ d0 = v_reinterpret_as_##suffix(d1); \
+} \
+inline void v_store_interleave( _Tp* ptr, const _Tpvec& a0, \
+ const _Tpvec& b0, const _Tpvec& c0 ) \
+{ \
+ _Tpuvec a1 = v_reinterpret_as_##usuffix(a0); \
+ _Tpuvec b1 = v_reinterpret_as_##usuffix(b0); \
+ _Tpuvec c1 = v_reinterpret_as_##usuffix(c0); \
+ v_store_interleave((_Tpu*)ptr, a1, b1, c1); \
+} \
+inline void v_store_interleave( _Tp* ptr, const _Tpvec& a0, const _Tpvec& b0, \
+ const _Tpvec& c0, const _Tpvec& d0 ) \
+{ \
+ _Tpuvec a1 = v_reinterpret_as_##usuffix(a0); \
+ _Tpuvec b1 = v_reinterpret_as_##usuffix(b0); \
+ _Tpuvec c1 = v_reinterpret_as_##usuffix(c0); \
+ _Tpuvec d1 = v_reinterpret_as_##usuffix(d0); \
+ v_store_interleave((_Tpu*)ptr, a1, b1, c1, d1); \
+}
+
+OPENCV_HAL_IMPL_SSE_LOADSTORE_INTERLEAVE(v_int8x16, schar, s8, v_uint8x16, uchar, u8)
+OPENCV_HAL_IMPL_SSE_LOADSTORE_INTERLEAVE(v_int16x8, short, s16, v_uint16x8, ushort, u16)
+OPENCV_HAL_IMPL_SSE_LOADSTORE_INTERLEAVE(v_int32x4, int, s32, v_uint32x4, unsigned, u32)
+OPENCV_HAL_IMPL_SSE_LOADSTORE_INTERLEAVE(v_float32x4, float, f32, v_uint32x4, unsigned, u32)
+
+inline v_float32x4 v_cvt_f32(const v_int32x4& a)
+{
+ return v_float32x4(_mm_cvtepi32_ps(a.val));
+}
+
+inline v_float32x4 v_cvt_f32(const v_float64x2& a)
+{
+ return v_float32x4(_mm_cvtpd_ps(a.val));
+}
+
+inline v_float64x2 v_cvt_f64(const v_int32x4& a)
+{
+ return v_float64x2(_mm_cvtepi32_pd(a.val));
+}
+
+inline v_float64x2 v_cvt_f64_high(const v_int32x4& a)
+{
+ return v_float64x2(_mm_cvtepi32_pd(_mm_srli_si128(a.val,8)));
+}
+
+inline v_float64x2 v_cvt_f64(const v_float32x4& a)
+{
+ return v_float64x2(_mm_cvtps_pd(a.val));
+}
+
+inline v_float64x2 v_cvt_f64_high(const v_float32x4& a)
+{
+ return v_float64x2(_mm_cvtps_pd(_mm_castsi128_ps(_mm_srli_si128(_mm_castps_si128(a.val),8))));
+}
+
+#if defined(HAVE_FP16)
+inline v_float32x4 v_cvt_f32(const v_float16x4& a)
+{
+ return v_float32x4(_mm_cvtph_ps(a.val));
+}
+
+inline v_float16x4 v_cvt_f16(const v_float32x4& a)
+{
+ return v_float16x4(_mm_cvtps_ph(a.val, 0));
+}
+#endif
+
+//! @name Check SIMD support
+//! @{
+//! @brief Check CPU capability of SIMD operation
+static inline bool hasSIMD128()
+{
+ return checkHardwareSupport(CV_CPU_SSE2);
+}
+
+//! @}
+
+//! @endcond
+
+}
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/core/ippasync.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,195 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2015, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
+// Copyright (C) 2015, Itseez Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_CORE_IPPASYNC_HPP
+#define OPENCV_CORE_IPPASYNC_HPP
+
+#ifdef HAVE_IPP_A
+
+#include "opencv2/core.hpp"
+#include <ipp_async_op.h>
+#include <ipp_async_accel.h>
+
+namespace cv
+{
+
+namespace hpp
+{
+
+/** @addtogroup core_ipp
+This section describes conversion between OpenCV and [Intel® IPP Asynchronous
+C/C++](http://software.intel.com/en-us/intel-ipp-preview) library. [Getting Started
+Guide](http://registrationcenter.intel.com/irc_nas/3727/ipp_async_get_started.htm) help you to
+install the library, configure header and library build paths.
+ */
+//! @{
+
+ //! convert OpenCV data type to hppDataType
+ inline int toHppType(const int cvType)
+ {
+ int depth = CV_MAT_DEPTH(cvType);
+ int hppType = depth == CV_8U ? HPP_DATA_TYPE_8U :
+ depth == CV_16U ? HPP_DATA_TYPE_16U :
+ depth == CV_16S ? HPP_DATA_TYPE_16S :
+ depth == CV_32S ? HPP_DATA_TYPE_32S :
+ depth == CV_32F ? HPP_DATA_TYPE_32F :
+ depth == CV_64F ? HPP_DATA_TYPE_64F : -1;
+ CV_Assert( hppType >= 0 );
+ return hppType;
+ }
+
+ //! convert hppDataType to OpenCV data type
+ inline int toCvType(const int hppType)
+ {
+ int cvType = hppType == HPP_DATA_TYPE_8U ? CV_8U :
+ hppType == HPP_DATA_TYPE_16U ? CV_16U :
+ hppType == HPP_DATA_TYPE_16S ? CV_16S :
+ hppType == HPP_DATA_TYPE_32S ? CV_32S :
+ hppType == HPP_DATA_TYPE_32F ? CV_32F :
+ hppType == HPP_DATA_TYPE_64F ? CV_64F : -1;
+ CV_Assert( cvType >= 0 );
+ return cvType;
+ }
+
+ /** @brief Convert hppiMatrix to Mat.
+
+ This function allocates and initializes new matrix (if needed) that has the same size and type as
+ input matrix. Supports CV_8U, CV_16U, CV_16S, CV_32S, CV_32F, CV_64F.
+ @param src input hppiMatrix.
+ @param dst output matrix.
+ @param accel accelerator instance (see hpp::getHpp for the list of acceleration framework types).
+ @param cn number of channels.
+ */
+ inline void copyHppToMat(hppiMatrix* src, Mat& dst, hppAccel accel, int cn)
+ {
+ hppDataType type;
+ hpp32u width, height;
+ hppStatus sts;
+
+ if (src == NULL)
+ return dst.release();
+
+ sts = hppiInquireMatrix(src, &type, &width, &height);
+
+ CV_Assert( sts == HPP_STATUS_NO_ERROR);
+
+ int matType = CV_MAKETYPE(toCvType(type), cn);
+
+ CV_Assert(width%cn == 0);
+
+ width /= cn;
+
+ dst.create((int)height, (int)width, (int)matType);
+
+ size_t newSize = (size_t)(height*(hpp32u)(dst.step));
+
+ sts = hppiGetMatrixData(accel,src,(hpp32u)(dst.step),dst.data,&newSize);
+
+ CV_Assert( sts == HPP_STATUS_NO_ERROR);
+ }
+
+ /** @brief Create Mat from hppiMatrix.
+
+ This function allocates and initializes the Mat that has the same size and type as input matrix.
+ Supports CV_8U, CV_16U, CV_16S, CV_32S, CV_32F, CV_64F.
+ @param src input hppiMatrix.
+ @param accel accelerator instance (see hpp::getHpp for the list of acceleration framework types).
+ @param cn number of channels.
+ @sa howToUseIPPAconversion, hpp::copyHppToMat, hpp::getHpp.
+ */
+ inline Mat getMat(hppiMatrix* src, hppAccel accel, int cn)
+ {
+ Mat dst;
+ copyHppToMat(src, dst, accel, cn);
+ return dst;
+ }
+
+ /** @brief Create hppiMatrix from Mat.
+
+ This function allocates and initializes the hppiMatrix that has the same size and type as input
+ matrix, returns the hppiMatrix*.
+
+ If you want to use zero-copy for GPU you should to have 4KB aligned matrix data. See details
+ [hppiCreateSharedMatrix](http://software.intel.com/ru-ru/node/501697).
+
+ Supports CV_8U, CV_16U, CV_16S, CV_32S, CV_32F, CV_64F.
+
+ @note The hppiMatrix pointer to the image buffer in system memory refers to the src.data. Control
+ the lifetime of the matrix and don't change its data, if there is no special need.
+ @param src input matrix.
+ @param accel accelerator instance. Supports type:
+ - **HPP_ACCEL_TYPE_CPU** - accelerated by optimized CPU instructions.
+ - **HPP_ACCEL_TYPE_GPU** - accelerated by GPU programmable units or fixed-function
+ accelerators.
+ - **HPP_ACCEL_TYPE_ANY** - any acceleration or no acceleration available.
+ @sa howToUseIPPAconversion, hpp::getMat
+ */
+ inline hppiMatrix* getHpp(const Mat& src, hppAccel accel)
+ {
+ int htype = toHppType(src.type());
+ int cn = src.channels();
+
+ CV_Assert(src.data);
+ hppAccelType accelType = hppQueryAccelType(accel);
+
+ if (accelType!=HPP_ACCEL_TYPE_CPU)
+ {
+ hpp32u pitch, size;
+ hppQueryMatrixAllocParams(accel, src.cols*cn, src.rows, htype, &pitch, &size);
+ if (pitch!=0 && size!=0)
+ if ((int)(src.data)%4096==0 && pitch==(hpp32u)(src.step))
+ {
+ return hppiCreateSharedMatrix(htype, src.cols*cn, src.rows, src.data, pitch, size);
+ }
+ }
+
+ return hppiCreateMatrix(htype, src.cols*cn, src.rows, src.data, (hpp32s)(src.step));;
+ }
+
+//! @}
+}}
+
+#endif
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/core/mat.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,3520 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_CORE_MAT_HPP
+#define OPENCV_CORE_MAT_HPP
+
+#ifndef __cplusplus
+# error mat.hpp header must be compiled as C++
+#endif
+
+#include "opencv2/core/matx.hpp"
+#include "opencv2/core/types.hpp"
+
+#include "opencv2/core/bufferpool.hpp"
+
+namespace cv
+{
+
+//! @addtogroup core_basic
+//! @{
+
+enum { ACCESS_READ=1<<24, ACCESS_WRITE=1<<25,
+ ACCESS_RW=3<<24, ACCESS_MASK=ACCESS_RW, ACCESS_FAST=1<<26 };
+
+class CV_EXPORTS _OutputArray;
+
+//////////////////////// Input/Output Array Arguments /////////////////////////////////
+
+/** @brief This is the proxy class for passing read-only input arrays into OpenCV functions.
+
+It is defined as:
+@code
+ typedef const _InputArray& InputArray;
+@endcode
+where _InputArray is a class that can be constructed from `Mat`, `Mat_<T>`, `Matx<T, m, n>`,
+`std::vector<T>`, `std::vector<std::vector<T> >` or `std::vector<Mat>`. It can also be constructed
+from a matrix expression.
+
+Since this is mostly implementation-level class, and its interface may change in future versions, we
+do not describe it in details. There are a few key things, though, that should be kept in mind:
+
+- When you see in the reference manual or in OpenCV source code a function that takes
+ InputArray, it means that you can actually pass `Mat`, `Matx`, `vector<T>` etc. (see above the
+ complete list).
+- Optional input arguments: If some of the input arrays may be empty, pass cv::noArray() (or
+ simply cv::Mat() as you probably did before).
+- The class is designed solely for passing parameters. That is, normally you *should not*
+ declare class members, local and global variables of this type.
+- If you want to design your own function or a class method that can operate of arrays of
+ multiple types, you can use InputArray (or OutputArray) for the respective parameters. Inside
+ a function you should use _InputArray::getMat() method to construct a matrix header for the
+ array (without copying data). _InputArray::kind() can be used to distinguish Mat from
+ `vector<>` etc., but normally it is not needed.
+
+Here is how you can use a function that takes InputArray :
+@code
+ std::vector<Point2f> vec;
+ // points or a circle
+ for( int i = 0; i < 30; i++ )
+ vec.push_back(Point2f((float)(100 + 30*cos(i*CV_PI*2/5)),
+ (float)(100 - 30*sin(i*CV_PI*2/5))));
+ cv::transform(vec, vec, cv::Matx23f(0.707, -0.707, 10, 0.707, 0.707, 20));
+@endcode
+That is, we form an STL vector containing points, and apply in-place affine transformation to the
+vector using the 2x3 matrix created inline as `Matx<float, 2, 3>` instance.
+
+Here is how such a function can be implemented (for simplicity, we implement a very specific case of
+it, according to the assertion statement inside) :
+@code
+ void myAffineTransform(InputArray _src, OutputArray _dst, InputArray _m)
+ {
+ // get Mat headers for input arrays. This is O(1) operation,
+ // unless _src and/or _m are matrix expressions.
+ Mat src = _src.getMat(), m = _m.getMat();
+ CV_Assert( src.type() == CV_32FC2 && m.type() == CV_32F && m.size() == Size(3, 2) );
+
+ // [re]create the output array so that it has the proper size and type.
+ // In case of Mat it calls Mat::create, in case of STL vector it calls vector::resize.
+ _dst.create(src.size(), src.type());
+ Mat dst = _dst.getMat();
+
+ for( int i = 0; i < src.rows; i++ )
+ for( int j = 0; j < src.cols; j++ )
+ {
+ Point2f pt = src.at<Point2f>(i, j);
+ dst.at<Point2f>(i, j) = Point2f(m.at<float>(0, 0)*pt.x +
+ m.at<float>(0, 1)*pt.y +
+ m.at<float>(0, 2),
+ m.at<float>(1, 0)*pt.x +
+ m.at<float>(1, 1)*pt.y +
+ m.at<float>(1, 2));
+ }
+ }
+@endcode
+There is another related type, InputArrayOfArrays, which is currently defined as a synonym for
+InputArray:
+@code
+ typedef InputArray InputArrayOfArrays;
+@endcode
+It denotes function arguments that are either vectors of vectors or vectors of matrices. A separate
+synonym is needed to generate Python/Java etc. wrappers properly. At the function implementation
+level their use is similar, but _InputArray::getMat(idx) should be used to get header for the
+idx-th component of the outer vector and _InputArray::size().area() should be used to find the
+number of components (vectors/matrices) of the outer vector.
+ */
+class CV_EXPORTS _InputArray
+{
+public:
+ enum {
+ KIND_SHIFT = 16,
+ FIXED_TYPE = 0x8000 << KIND_SHIFT,
+ FIXED_SIZE = 0x4000 << KIND_SHIFT,
+ KIND_MASK = 31 << KIND_SHIFT,
+
+ NONE = 0 << KIND_SHIFT,
+ MAT = 1 << KIND_SHIFT,
+ MATX = 2 << KIND_SHIFT,
+ STD_VECTOR = 3 << KIND_SHIFT,
+ STD_VECTOR_VECTOR = 4 << KIND_SHIFT,
+ STD_VECTOR_MAT = 5 << KIND_SHIFT,
+ EXPR = 6 << KIND_SHIFT,
+ OPENGL_BUFFER = 7 << KIND_SHIFT,
+ CUDA_HOST_MEM = 8 << KIND_SHIFT,
+ CUDA_GPU_MAT = 9 << KIND_SHIFT,
+ UMAT =10 << KIND_SHIFT,
+ STD_VECTOR_UMAT =11 << KIND_SHIFT,
+ STD_BOOL_VECTOR =12 << KIND_SHIFT,
+ STD_VECTOR_CUDA_GPU_MAT = 13 << KIND_SHIFT
+ };
+
+ _InputArray();
+ _InputArray(int _flags, void* _obj);
+ _InputArray(const Mat& m);
+ _InputArray(const MatExpr& expr);
+ _InputArray(const std::vector<Mat>& vec);
+ template<typename _Tp> _InputArray(const Mat_<_Tp>& m);
+ template<typename _Tp> _InputArray(const std::vector<_Tp>& vec);
+ _InputArray(const std::vector<bool>& vec);
+ template<typename _Tp> _InputArray(const std::vector<std::vector<_Tp> >& vec);
+ template<typename _Tp> _InputArray(const std::vector<Mat_<_Tp> >& vec);
+ template<typename _Tp> _InputArray(const _Tp* vec, int n);
+ template<typename _Tp, int m, int n> _InputArray(const Matx<_Tp, m, n>& matx);
+ _InputArray(const double& val);
+ _InputArray(const cuda::GpuMat& d_mat);
+ _InputArray(const std::vector<cuda::GpuMat>& d_mat_array);
+ _InputArray(const ogl::Buffer& buf);
+ _InputArray(const cuda::HostMem& cuda_mem);
+ template<typename _Tp> _InputArray(const cudev::GpuMat_<_Tp>& m);
+ _InputArray(const UMat& um);
+ _InputArray(const std::vector<UMat>& umv);
+
+ Mat getMat(int idx=-1) const;
+ Mat getMat_(int idx=-1) const;
+ UMat getUMat(int idx=-1) const;
+ void getMatVector(std::vector<Mat>& mv) const;
+ void getUMatVector(std::vector<UMat>& umv) const;
+ void getGpuMatVector(std::vector<cuda::GpuMat>& gpumv) const;
+ cuda::GpuMat getGpuMat() const;
+ ogl::Buffer getOGlBuffer() const;
+
+ int getFlags() const;
+ void* getObj() const;
+ Size getSz() const;
+
+ int kind() const;
+ int dims(int i=-1) const;
+ int cols(int i=-1) const;
+ int rows(int i=-1) const;
+ Size size(int i=-1) const;
+ int sizend(int* sz, int i=-1) const;
+ bool sameSize(const _InputArray& arr) const;
+ size_t total(int i=-1) const;
+ int type(int i=-1) const;
+ int depth(int i=-1) const;
+ int channels(int i=-1) const;
+ bool isContinuous(int i=-1) const;
+ bool isSubmatrix(int i=-1) const;
+ bool empty() const;
+ void copyTo(const _OutputArray& arr) const;
+ void copyTo(const _OutputArray& arr, const _InputArray & mask) const;
+ size_t offset(int i=-1) const;
+ size_t step(int i=-1) const;
+ bool isMat() const;
+ bool isUMat() const;
+ bool isMatVector() const;
+ bool isUMatVector() const;
+ bool isMatx() const;
+ bool isVector() const;
+ bool isGpuMatVector() const;
+ ~_InputArray();
+
+protected:
+ int flags;
+ void* obj;
+ Size sz;
+
+ void init(int _flags, const void* _obj);
+ void init(int _flags, const void* _obj, Size _sz);
+};
+
+
+/** @brief This type is very similar to InputArray except that it is used for input/output and output function
+parameters.
+
+Just like with InputArray, OpenCV users should not care about OutputArray, they just pass `Mat`,
+`vector<T>` etc. to the functions. The same limitation as for `InputArray`: *Do not explicitly
+create OutputArray instances* applies here too.
+
+If you want to make your function polymorphic (i.e. accept different arrays as output parameters),
+it is also not very difficult. Take the sample above as the reference. Note that
+_OutputArray::create() needs to be called before _OutputArray::getMat(). This way you guarantee
+that the output array is properly allocated.
+
+Optional output parameters. If you do not need certain output array to be computed and returned to
+you, pass cv::noArray(), just like you would in the case of optional input array. At the
+implementation level, use _OutputArray::needed() to check if certain output array needs to be
+computed or not.
+
+There are several synonyms for OutputArray that are used to assist automatic Python/Java/... wrapper
+generators:
+@code
+ typedef OutputArray OutputArrayOfArrays;
+ typedef OutputArray InputOutputArray;
+ typedef OutputArray InputOutputArrayOfArrays;
+@endcode
+ */
+class CV_EXPORTS _OutputArray : public _InputArray
+{
+public:
+ enum
+ {
+ DEPTH_MASK_8U = 1 << CV_8U,
+ DEPTH_MASK_8S = 1 << CV_8S,
+ DEPTH_MASK_16U = 1 << CV_16U,
+ DEPTH_MASK_16S = 1 << CV_16S,
+ DEPTH_MASK_32S = 1 << CV_32S,
+ DEPTH_MASK_32F = 1 << CV_32F,
+ DEPTH_MASK_64F = 1 << CV_64F,
+ DEPTH_MASK_ALL = (DEPTH_MASK_64F<<1)-1,
+ DEPTH_MASK_ALL_BUT_8S = DEPTH_MASK_ALL & ~DEPTH_MASK_8S,
+ DEPTH_MASK_FLT = DEPTH_MASK_32F + DEPTH_MASK_64F
+ };
+
+ _OutputArray();
+ _OutputArray(int _flags, void* _obj);
+ _OutputArray(Mat& m);
+ _OutputArray(std::vector<Mat>& vec);
+ _OutputArray(cuda::GpuMat& d_mat);
+ _OutputArray(std::vector<cuda::GpuMat>& d_mat);
+ _OutputArray(ogl::Buffer& buf);
+ _OutputArray(cuda::HostMem& cuda_mem);
+ template<typename _Tp> _OutputArray(cudev::GpuMat_<_Tp>& m);
+ template<typename _Tp> _OutputArray(std::vector<_Tp>& vec);
+ _OutputArray(std::vector<bool>& vec);
+ template<typename _Tp> _OutputArray(std::vector<std::vector<_Tp> >& vec);
+ template<typename _Tp> _OutputArray(std::vector<Mat_<_Tp> >& vec);
+ template<typename _Tp> _OutputArray(Mat_<_Tp>& m);
+ template<typename _Tp> _OutputArray(_Tp* vec, int n);
+ template<typename _Tp, int m, int n> _OutputArray(Matx<_Tp, m, n>& matx);
+ _OutputArray(UMat& m);
+ _OutputArray(std::vector<UMat>& vec);
+
+ _OutputArray(const Mat& m);
+ _OutputArray(const std::vector<Mat>& vec);
+ _OutputArray(const cuda::GpuMat& d_mat);
+ _OutputArray(const std::vector<cuda::GpuMat>& d_mat);
+ _OutputArray(const ogl::Buffer& buf);
+ _OutputArray(const cuda::HostMem& cuda_mem);
+ template<typename _Tp> _OutputArray(const cudev::GpuMat_<_Tp>& m);
+ template<typename _Tp> _OutputArray(const std::vector<_Tp>& vec);
+ template<typename _Tp> _OutputArray(const std::vector<std::vector<_Tp> >& vec);
+ template<typename _Tp> _OutputArray(const std::vector<Mat_<_Tp> >& vec);
+ template<typename _Tp> _OutputArray(const Mat_<_Tp>& m);
+ template<typename _Tp> _OutputArray(const _Tp* vec, int n);
+ template<typename _Tp, int m, int n> _OutputArray(const Matx<_Tp, m, n>& matx);
+ _OutputArray(const UMat& m);
+ _OutputArray(const std::vector<UMat>& vec);
+
+ bool fixedSize() const;
+ bool fixedType() const;
+ bool needed() const;
+ Mat& getMatRef(int i=-1) const;
+ UMat& getUMatRef(int i=-1) const;
+ cuda::GpuMat& getGpuMatRef() const;
+ std::vector<cuda::GpuMat>& getGpuMatVecRef() const;
+ ogl::Buffer& getOGlBufferRef() const;
+ cuda::HostMem& getHostMemRef() const;
+ void create(Size sz, int type, int i=-1, bool allowTransposed=false, int fixedDepthMask=0) const;
+ void create(int rows, int cols, int type, int i=-1, bool allowTransposed=false, int fixedDepthMask=0) const;
+ void create(int dims, const int* size, int type, int i=-1, bool allowTransposed=false, int fixedDepthMask=0) const;
+ void createSameSize(const _InputArray& arr, int mtype) const;
+ void release() const;
+ void clear() const;
+ void setTo(const _InputArray& value, const _InputArray & mask = _InputArray()) const;
+
+ void assign(const UMat& u) const;
+ void assign(const Mat& m) const;
+};
+
+
+class CV_EXPORTS _InputOutputArray : public _OutputArray
+{
+public:
+ _InputOutputArray();
+ _InputOutputArray(int _flags, void* _obj);
+ _InputOutputArray(Mat& m);
+ _InputOutputArray(std::vector<Mat>& vec);
+ _InputOutputArray(cuda::GpuMat& d_mat);
+ _InputOutputArray(ogl::Buffer& buf);
+ _InputOutputArray(cuda::HostMem& cuda_mem);
+ template<typename _Tp> _InputOutputArray(cudev::GpuMat_<_Tp>& m);
+ template<typename _Tp> _InputOutputArray(std::vector<_Tp>& vec);
+ _InputOutputArray(std::vector<bool>& vec);
+ template<typename _Tp> _InputOutputArray(std::vector<std::vector<_Tp> >& vec);
+ template<typename _Tp> _InputOutputArray(std::vector<Mat_<_Tp> >& vec);
+ template<typename _Tp> _InputOutputArray(Mat_<_Tp>& m);
+ template<typename _Tp> _InputOutputArray(_Tp* vec, int n);
+ template<typename _Tp, int m, int n> _InputOutputArray(Matx<_Tp, m, n>& matx);
+ _InputOutputArray(UMat& m);
+ _InputOutputArray(std::vector<UMat>& vec);
+
+ _InputOutputArray(const Mat& m);
+ _InputOutputArray(const std::vector<Mat>& vec);
+ _InputOutputArray(const cuda::GpuMat& d_mat);
+ _InputOutputArray(const std::vector<cuda::GpuMat>& d_mat);
+ _InputOutputArray(const ogl::Buffer& buf);
+ _InputOutputArray(const cuda::HostMem& cuda_mem);
+ template<typename _Tp> _InputOutputArray(const cudev::GpuMat_<_Tp>& m);
+ template<typename _Tp> _InputOutputArray(const std::vector<_Tp>& vec);
+ template<typename _Tp> _InputOutputArray(const std::vector<std::vector<_Tp> >& vec);
+ template<typename _Tp> _InputOutputArray(const std::vector<Mat_<_Tp> >& vec);
+ template<typename _Tp> _InputOutputArray(const Mat_<_Tp>& m);
+ template<typename _Tp> _InputOutputArray(const _Tp* vec, int n);
+ template<typename _Tp, int m, int n> _InputOutputArray(const Matx<_Tp, m, n>& matx);
+ _InputOutputArray(const UMat& m);
+ _InputOutputArray(const std::vector<UMat>& vec);
+};
+
+typedef const _InputArray& InputArray;
+typedef InputArray InputArrayOfArrays;
+typedef const _OutputArray& OutputArray;
+typedef OutputArray OutputArrayOfArrays;
+typedef const _InputOutputArray& InputOutputArray;
+typedef InputOutputArray InputOutputArrayOfArrays;
+
+CV_EXPORTS InputOutputArray noArray();
+
+/////////////////////////////////// MatAllocator //////////////////////////////////////
+
+//! Usage flags for allocator
+enum UMatUsageFlags
+{
+ USAGE_DEFAULT = 0,
+
+ // buffer allocation policy is platform and usage specific
+ USAGE_ALLOCATE_HOST_MEMORY = 1 << 0,
+ USAGE_ALLOCATE_DEVICE_MEMORY = 1 << 1,
+ USAGE_ALLOCATE_SHARED_MEMORY = 1 << 2, // It is not equal to: USAGE_ALLOCATE_HOST_MEMORY | USAGE_ALLOCATE_DEVICE_MEMORY
+
+ __UMAT_USAGE_FLAGS_32BIT = 0x7fffffff // Binary compatibility hint
+};
+
+struct CV_EXPORTS UMatData;
+
+/** @brief Custom array allocator
+*/
+class CV_EXPORTS MatAllocator
+{
+public:
+ MatAllocator() {}
+ virtual ~MatAllocator() {}
+
+ // let's comment it off for now to detect and fix all the uses of allocator
+ //virtual void allocate(int dims, const int* sizes, int type, int*& refcount,
+ // uchar*& datastart, uchar*& data, size_t* step) = 0;
+ //virtual void deallocate(int* refcount, uchar* datastart, uchar* data) = 0;
+ virtual UMatData* allocate(int dims, const int* sizes, int type,
+ void* data, size_t* step, int flags, UMatUsageFlags usageFlags) const = 0;
+ virtual bool allocate(UMatData* data, int accessflags, UMatUsageFlags usageFlags) const = 0;
+ virtual void deallocate(UMatData* data) const = 0;
+ virtual void map(UMatData* data, int accessflags) const;
+ virtual void unmap(UMatData* data) const;
+ virtual void download(UMatData* data, void* dst, int dims, const size_t sz[],
+ const size_t srcofs[], const size_t srcstep[],
+ const size_t dststep[]) const;
+ virtual void upload(UMatData* data, const void* src, int dims, const size_t sz[],
+ const size_t dstofs[], const size_t dststep[],
+ const size_t srcstep[]) const;
+ virtual void copy(UMatData* srcdata, UMatData* dstdata, int dims, const size_t sz[],
+ const size_t srcofs[], const size_t srcstep[],
+ const size_t dstofs[], const size_t dststep[], bool sync) const;
+
+ // default implementation returns DummyBufferPoolController
+ virtual BufferPoolController* getBufferPoolController(const char* id = NULL) const;
+};
+
+
+//////////////////////////////// MatCommaInitializer //////////////////////////////////
+
+/** @brief Comma-separated Matrix Initializer
+
+ The class instances are usually not created explicitly.
+ Instead, they are created on "matrix << firstValue" operator.
+
+ The sample below initializes 2x2 rotation matrix:
+
+ \code
+ double angle = 30, a = cos(angle*CV_PI/180), b = sin(angle*CV_PI/180);
+ Mat R = (Mat_<double>(2,2) << a, -b, b, a);
+ \endcode
+*/
+template<typename _Tp> class MatCommaInitializer_
+{
+public:
+ //! the constructor, created by "matrix << firstValue" operator, where matrix is cv::Mat
+ MatCommaInitializer_(Mat_<_Tp>* _m);
+ //! the operator that takes the next value and put it to the matrix
+ template<typename T2> MatCommaInitializer_<_Tp>& operator , (T2 v);
+ //! another form of conversion operator
+ operator Mat_<_Tp>() const;
+protected:
+ MatIterator_<_Tp> it;
+};
+
+
+/////////////////////////////////////// Mat ///////////////////////////////////////////
+
+// note that umatdata might be allocated together
+// with the matrix data, not as a separate object.
+// therefore, it does not have constructor or destructor;
+// it should be explicitly initialized using init().
+struct CV_EXPORTS UMatData
+{
+ enum { COPY_ON_MAP=1, HOST_COPY_OBSOLETE=2,
+ DEVICE_COPY_OBSOLETE=4, TEMP_UMAT=8, TEMP_COPIED_UMAT=24,
+ USER_ALLOCATED=32, DEVICE_MEM_MAPPED=64};
+ UMatData(const MatAllocator* allocator);
+ ~UMatData();
+
+ // provide atomic access to the structure
+ void lock();
+ void unlock();
+
+ bool hostCopyObsolete() const;
+ bool deviceCopyObsolete() const;
+ bool deviceMemMapped() const;
+ bool copyOnMap() const;
+ bool tempUMat() const;
+ bool tempCopiedUMat() const;
+ void markHostCopyObsolete(bool flag);
+ void markDeviceCopyObsolete(bool flag);
+ void markDeviceMemMapped(bool flag);
+
+ const MatAllocator* prevAllocator;
+ const MatAllocator* currAllocator;
+ int urefcount;
+ int refcount;
+ uchar* data;
+ uchar* origdata;
+ size_t size;
+
+ int flags;
+ void* handle;
+ void* userdata;
+ int allocatorFlags_;
+ int mapcount;
+ UMatData* originalUMatData;
+};
+
+
+struct CV_EXPORTS UMatDataAutoLock
+{
+ explicit UMatDataAutoLock(UMatData* u);
+ ~UMatDataAutoLock();
+ UMatData* u;
+};
+
+
+struct CV_EXPORTS MatSize
+{
+ explicit MatSize(int* _p);
+ Size operator()() const;
+ const int& operator[](int i) const;
+ int& operator[](int i);
+ operator const int*() const;
+ bool operator == (const MatSize& sz) const;
+ bool operator != (const MatSize& sz) const;
+
+ int* p;
+};
+
+struct CV_EXPORTS MatStep
+{
+ MatStep();
+ explicit MatStep(size_t s);
+ const size_t& operator[](int i) const;
+ size_t& operator[](int i);
+ operator size_t() const;
+ MatStep& operator = (size_t s);
+
+ size_t* p;
+ size_t buf[2];
+protected:
+ MatStep& operator = (const MatStep&);
+};
+
+/** @example cout_mat.cpp
+An example demonstrating the serial out capabilities of cv::Mat
+*/
+
+ /** @brief n-dimensional dense array class
+
+The class Mat represents an n-dimensional dense numerical single-channel or multi-channel array. It
+can be used to store real or complex-valued vectors and matrices, grayscale or color images, voxel
+volumes, vector fields, point clouds, tensors, histograms (though, very high-dimensional histograms
+may be better stored in a SparseMat ). The data layout of the array `M` is defined by the array
+`M.step[]`, so that the address of element \f$(i_0,...,i_{M.dims-1})\f$, where \f$0\leq i_k<M.size[k]\f$, is
+computed as:
+\f[addr(M_{i_0,...,i_{M.dims-1}}) = M.data + M.step[0]*i_0 + M.step[1]*i_1 + ... + M.step[M.dims-1]*i_{M.dims-1}\f]
+In case of a 2-dimensional array, the above formula is reduced to:
+\f[addr(M_{i,j}) = M.data + M.step[0]*i + M.step[1]*j\f]
+Note that `M.step[i] >= M.step[i+1]` (in fact, `M.step[i] >= M.step[i+1]*M.size[i+1]` ). This means
+that 2-dimensional matrices are stored row-by-row, 3-dimensional matrices are stored plane-by-plane,
+and so on. M.step[M.dims-1] is minimal and always equal to the element size M.elemSize() .
+
+So, the data layout in Mat is fully compatible with CvMat, IplImage, and CvMatND types from OpenCV
+1.x. It is also compatible with the majority of dense array types from the standard toolkits and
+SDKs, such as Numpy (ndarray), Win32 (independent device bitmaps), and others, that is, with any
+array that uses *steps* (or *strides*) to compute the position of a pixel. Due to this
+compatibility, it is possible to make a Mat header for user-allocated data and process it in-place
+using OpenCV functions.
+
+There are many different ways to create a Mat object. The most popular options are listed below:
+
+- Use the create(nrows, ncols, type) method or the similar Mat(nrows, ncols, type[, fillValue])
+constructor. A new array of the specified size and type is allocated. type has the same meaning as
+in the cvCreateMat method. For example, CV_8UC1 means a 8-bit single-channel array, CV_32FC2
+means a 2-channel (complex) floating-point array, and so on.
+@code
+ // make a 7x7 complex matrix filled with 1+3j.
+ Mat M(7,7,CV_32FC2,Scalar(1,3));
+ // and now turn M to a 100x60 15-channel 8-bit matrix.
+ // The old content will be deallocated
+ M.create(100,60,CV_8UC(15));
+@endcode
+As noted in the introduction to this chapter, create() allocates only a new array when the shape
+or type of the current array are different from the specified ones.
+
+- Create a multi-dimensional array:
+@code
+ // create a 100x100x100 8-bit array
+ int sz[] = {100, 100, 100};
+ Mat bigCube(3, sz, CV_8U, Scalar::all(0));
+@endcode
+It passes the number of dimensions =1 to the Mat constructor but the created array will be
+2-dimensional with the number of columns set to 1. So, Mat::dims is always \>= 2 (can also be 0
+when the array is empty).
+
+- Use a copy constructor or assignment operator where there can be an array or expression on the
+right side (see below). As noted in the introduction, the array assignment is an O(1) operation
+because it only copies the header and increases the reference counter. The Mat::clone() method can
+be used to get a full (deep) copy of the array when you need it.
+
+- Construct a header for a part of another array. It can be a single row, single column, several
+rows, several columns, rectangular region in the array (called a *minor* in algebra) or a
+diagonal. Such operations are also O(1) because the new header references the same data. You can
+actually modify a part of the array using this feature, for example:
+@code
+ // add the 5-th row, multiplied by 3 to the 3rd row
+ M.row(3) = M.row(3) + M.row(5)*3;
+ // now copy the 7-th column to the 1-st column
+ // M.col(1) = M.col(7); // this will not work
+ Mat M1 = M.col(1);
+ M.col(7).copyTo(M1);
+ // create a new 320x240 image
+ Mat img(Size(320,240),CV_8UC3);
+ // select a ROI
+ Mat roi(img, Rect(10,10,100,100));
+ // fill the ROI with (0,255,0) (which is green in RGB space);
+ // the original 320x240 image will be modified
+ roi = Scalar(0,255,0);
+@endcode
+Due to the additional datastart and dataend members, it is possible to compute a relative
+sub-array position in the main *container* array using locateROI():
+@code
+ Mat A = Mat::eye(10, 10, CV_32S);
+ // extracts A columns, 1 (inclusive) to 3 (exclusive).
+ Mat B = A(Range::all(), Range(1, 3));
+ // extracts B rows, 5 (inclusive) to 9 (exclusive).
+ // that is, C \~ A(Range(5, 9), Range(1, 3))
+ Mat C = B(Range(5, 9), Range::all());
+ Size size; Point ofs;
+ C.locateROI(size, ofs);
+ // size will be (width=10,height=10) and the ofs will be (x=1, y=5)
+@endcode
+As in case of whole matrices, if you need a deep copy, use the `clone()` method of the extracted
+sub-matrices.
+
+- Make a header for user-allocated data. It can be useful to do the following:
+ -# Process "foreign" data using OpenCV (for example, when you implement a DirectShow\* filter or
+ a processing module for gstreamer, and so on). For example:
+ @code
+ void process_video_frame(const unsigned char* pixels,
+ int width, int height, int step)
+ {
+ Mat img(height, width, CV_8UC3, pixels, step);
+ GaussianBlur(img, img, Size(7,7), 1.5, 1.5);
+ }
+ @endcode
+ -# Quickly initialize small matrices and/or get a super-fast element access.
+ @code
+ double m[3][3] = {{a, b, c}, {d, e, f}, {g, h, i}};
+ Mat M = Mat(3, 3, CV_64F, m).inv();
+ @endcode
+ .
+ Partial yet very common cases of this *user-allocated data* case are conversions from CvMat and
+ IplImage to Mat. For this purpose, there is function cv::cvarrToMat taking pointers to CvMat or
+ IplImage and the optional flag indicating whether to copy the data or not.
+ @snippet samples/cpp/image.cpp iplimage
+
+- Use MATLAB-style array initializers, zeros(), ones(), eye(), for example:
+@code
+ // create a double-precision identity martix and add it to M.
+ M += Mat::eye(M.rows, M.cols, CV_64F);
+@endcode
+
+- Use a comma-separated initializer:
+@code
+ // create a 3x3 double-precision identity matrix
+ Mat M = (Mat_<double>(3,3) << 1, 0, 0, 0, 1, 0, 0, 0, 1);
+@endcode
+With this approach, you first call a constructor of the Mat class with the proper parameters, and
+then you just put `<< operator` followed by comma-separated values that can be constants,
+variables, expressions, and so on. Also, note the extra parentheses required to avoid compilation
+errors.
+
+Once the array is created, it is automatically managed via a reference-counting mechanism. If the
+array header is built on top of user-allocated data, you should handle the data by yourself. The
+array data is deallocated when no one points to it. If you want to release the data pointed by a
+array header before the array destructor is called, use Mat::release().
+
+The next important thing to learn about the array class is element access. This manual already
+described how to compute an address of each array element. Normally, you are not required to use the
+formula directly in the code. If you know the array element type (which can be retrieved using the
+method Mat::type() ), you can access the element \f$M_{ij}\f$ of a 2-dimensional array as:
+@code
+ M.at<double>(i,j) += 1.f;
+@endcode
+assuming that `M` is a double-precision floating-point array. There are several variants of the method
+at for a different number of dimensions.
+
+If you need to process a whole row of a 2D array, the most efficient way is to get the pointer to
+the row first, and then just use the plain C operator [] :
+@code
+ // compute sum of positive matrix elements
+ // (assuming that M isa double-precision matrix)
+ double sum=0;
+ for(int i = 0; i < M.rows; i++)
+ {
+ const double* Mi = M.ptr<double>(i);
+ for(int j = 0; j < M.cols; j++)
+ sum += std::max(Mi[j], 0.);
+ }
+@endcode
+Some operations, like the one above, do not actually depend on the array shape. They just process
+elements of an array one by one (or elements from multiple arrays that have the same coordinates,
+for example, array addition). Such operations are called *element-wise*. It makes sense to check
+whether all the input/output arrays are continuous, namely, have no gaps at the end of each row. If
+yes, process them as a long single row:
+@code
+ // compute the sum of positive matrix elements, optimized variant
+ double sum=0;
+ int cols = M.cols, rows = M.rows;
+ if(M.isContinuous())
+ {
+ cols *= rows;
+ rows = 1;
+ }
+ for(int i = 0; i < rows; i++)
+ {
+ const double* Mi = M.ptr<double>(i);
+ for(int j = 0; j < cols; j++)
+ sum += std::max(Mi[j], 0.);
+ }
+@endcode
+In case of the continuous matrix, the outer loop body is executed just once. So, the overhead is
+smaller, which is especially noticeable in case of small matrices.
+
+Finally, there are STL-style iterators that are smart enough to skip gaps between successive rows:
+@code
+ // compute sum of positive matrix elements, iterator-based variant
+ double sum=0;
+ MatConstIterator_<double> it = M.begin<double>(), it_end = M.end<double>();
+ for(; it != it_end; ++it)
+ sum += std::max(*it, 0.);
+@endcode
+The matrix iterators are random-access iterators, so they can be passed to any STL algorithm,
+including std::sort().
+*/
+class CV_EXPORTS Mat
+{
+public:
+ /**
+ These are various constructors that form a matrix. As noted in the AutomaticAllocation, often
+ the default constructor is enough, and the proper matrix will be allocated by an OpenCV function.
+ The constructed matrix can further be assigned to another matrix or matrix expression or can be
+ allocated with Mat::create . In the former case, the old content is de-referenced.
+ */
+ Mat();
+
+ /** @overload
+ @param rows Number of rows in a 2D array.
+ @param cols Number of columns in a 2D array.
+ @param type Array type. Use CV_8UC1, ..., CV_64FC4 to create 1-4 channel matrices, or
+ CV_8UC(n), ..., CV_64FC(n) to create multi-channel (up to CV_CN_MAX channels) matrices.
+ */
+ Mat(int rows, int cols, int type);
+
+ /** @overload
+ @param size 2D array size: Size(cols, rows) . In the Size() constructor, the number of rows and the
+ number of columns go in the reverse order.
+ @param type Array type. Use CV_8UC1, ..., CV_64FC4 to create 1-4 channel matrices, or
+ CV_8UC(n), ..., CV_64FC(n) to create multi-channel (up to CV_CN_MAX channels) matrices.
+ */
+ Mat(Size size, int type);
+
+ /** @overload
+ @param rows Number of rows in a 2D array.
+ @param cols Number of columns in a 2D array.
+ @param type Array type. Use CV_8UC1, ..., CV_64FC4 to create 1-4 channel matrices, or
+ CV_8UC(n), ..., CV_64FC(n) to create multi-channel (up to CV_CN_MAX channels) matrices.
+ @param s An optional value to initialize each matrix element with. To set all the matrix elements to
+ the particular value after the construction, use the assignment operator
+ Mat::operator=(const Scalar& value) .
+ */
+ Mat(int rows, int cols, int type, const Scalar& s);
+
+ /** @overload
+ @param size 2D array size: Size(cols, rows) . In the Size() constructor, the number of rows and the
+ number of columns go in the reverse order.
+ @param type Array type. Use CV_8UC1, ..., CV_64FC4 to create 1-4 channel matrices, or
+ CV_8UC(n), ..., CV_64FC(n) to create multi-channel (up to CV_CN_MAX channels) matrices.
+ @param s An optional value to initialize each matrix element with. To set all the matrix elements to
+ the particular value after the construction, use the assignment operator
+ Mat::operator=(const Scalar& value) .
+ */
+ Mat(Size size, int type, const Scalar& s);
+
+ /** @overload
+ @param ndims Array dimensionality.
+ @param sizes Array of integers specifying an n-dimensional array shape.
+ @param type Array type. Use CV_8UC1, ..., CV_64FC4 to create 1-4 channel matrices, or
+ CV_8UC(n), ..., CV_64FC(n) to create multi-channel (up to CV_CN_MAX channels) matrices.
+ */
+ Mat(int ndims, const int* sizes, int type);
+
+ /** @overload
+ @param sizes Array of integers specifying an n-dimensional array shape.
+ @param type Array type. Use CV_8UC1, ..., CV_64FC4 to create 1-4 channel matrices, or
+ CV_8UC(n), ..., CV_64FC(n) to create multi-channel (up to CV_CN_MAX channels) matrices.
+ */
+ Mat(const std::vector<int>& sizes, int type);
+
+ /** @overload
+ @param ndims Array dimensionality.
+ @param sizes Array of integers specifying an n-dimensional array shape.
+ @param type Array type. Use CV_8UC1, ..., CV_64FC4 to create 1-4 channel matrices, or
+ CV_8UC(n), ..., CV_64FC(n) to create multi-channel (up to CV_CN_MAX channels) matrices.
+ @param s An optional value to initialize each matrix element with. To set all the matrix elements to
+ the particular value after the construction, use the assignment operator
+ Mat::operator=(const Scalar& value) .
+ */
+ Mat(int ndims, const int* sizes, int type, const Scalar& s);
+
+ /** @overload
+ @param sizes Array of integers specifying an n-dimensional array shape.
+ @param type Array type. Use CV_8UC1, ..., CV_64FC4 to create 1-4 channel matrices, or
+ CV_8UC(n), ..., CV_64FC(n) to create multi-channel (up to CV_CN_MAX channels) matrices.
+ @param s An optional value to initialize each matrix element with. To set all the matrix elements to
+ the particular value after the construction, use the assignment operator
+ Mat::operator=(const Scalar& value) .
+ */
+ Mat(const std::vector<int>& sizes, int type, const Scalar& s);
+
+
+ /** @overload
+ @param m Array that (as a whole or partly) is assigned to the constructed matrix. No data is copied
+ by these constructors. Instead, the header pointing to m data or its sub-array is constructed and
+ associated with it. The reference counter, if any, is incremented. So, when you modify the matrix
+ formed using such a constructor, you also modify the corresponding elements of m . If you want to
+ have an independent copy of the sub-array, use Mat::clone() .
+ */
+ Mat(const Mat& m);
+
+ /** @overload
+ @param rows Number of rows in a 2D array.
+ @param cols Number of columns in a 2D array.
+ @param type Array type. Use CV_8UC1, ..., CV_64FC4 to create 1-4 channel matrices, or
+ CV_8UC(n), ..., CV_64FC(n) to create multi-channel (up to CV_CN_MAX channels) matrices.
+ @param data Pointer to the user data. Matrix constructors that take data and step parameters do not
+ allocate matrix data. Instead, they just initialize the matrix header that points to the specified
+ data, which means that no data is copied. This operation is very efficient and can be used to
+ process external data using OpenCV functions. The external data is not automatically deallocated, so
+ you should take care of it.
+ @param step Number of bytes each matrix row occupies. The value should include the padding bytes at
+ the end of each row, if any. If the parameter is missing (set to AUTO_STEP ), no padding is assumed
+ and the actual step is calculated as cols*elemSize(). See Mat::elemSize.
+ */
+ Mat(int rows, int cols, int type, void* data, size_t step=AUTO_STEP);
+
+ /** @overload
+ @param size 2D array size: Size(cols, rows) . In the Size() constructor, the number of rows and the
+ number of columns go in the reverse order.
+ @param type Array type. Use CV_8UC1, ..., CV_64FC4 to create 1-4 channel matrices, or
+ CV_8UC(n), ..., CV_64FC(n) to create multi-channel (up to CV_CN_MAX channels) matrices.
+ @param data Pointer to the user data. Matrix constructors that take data and step parameters do not
+ allocate matrix data. Instead, they just initialize the matrix header that points to the specified
+ data, which means that no data is copied. This operation is very efficient and can be used to
+ process external data using OpenCV functions. The external data is not automatically deallocated, so
+ you should take care of it.
+ @param step Number of bytes each matrix row occupies. The value should include the padding bytes at
+ the end of each row, if any. If the parameter is missing (set to AUTO_STEP ), no padding is assumed
+ and the actual step is calculated as cols*elemSize(). See Mat::elemSize.
+ */
+ Mat(Size size, int type, void* data, size_t step=AUTO_STEP);
+
+ /** @overload
+ @param ndims Array dimensionality.
+ @param sizes Array of integers specifying an n-dimensional array shape.
+ @param type Array type. Use CV_8UC1, ..., CV_64FC4 to create 1-4 channel matrices, or
+ CV_8UC(n), ..., CV_64FC(n) to create multi-channel (up to CV_CN_MAX channels) matrices.
+ @param data Pointer to the user data. Matrix constructors that take data and step parameters do not
+ allocate matrix data. Instead, they just initialize the matrix header that points to the specified
+ data, which means that no data is copied. This operation is very efficient and can be used to
+ process external data using OpenCV functions. The external data is not automatically deallocated, so
+ you should take care of it.
+ @param steps Array of ndims-1 steps in case of a multi-dimensional array (the last step is always
+ set to the element size). If not specified, the matrix is assumed to be continuous.
+ */
+ Mat(int ndims, const int* sizes, int type, void* data, const size_t* steps=0);
+
+ /** @overload
+ @param sizes Array of integers specifying an n-dimensional array shape.
+ @param type Array type. Use CV_8UC1, ..., CV_64FC4 to create 1-4 channel matrices, or
+ CV_8UC(n), ..., CV_64FC(n) to create multi-channel (up to CV_CN_MAX channels) matrices.
+ @param data Pointer to the user data. Matrix constructors that take data and step parameters do not
+ allocate matrix data. Instead, they just initialize the matrix header that points to the specified
+ data, which means that no data is copied. This operation is very efficient and can be used to
+ process external data using OpenCV functions. The external data is not automatically deallocated, so
+ you should take care of it.
+ @param steps Array of ndims-1 steps in case of a multi-dimensional array (the last step is always
+ set to the element size). If not specified, the matrix is assumed to be continuous.
+ */
+ Mat(const std::vector<int>& sizes, int type, void* data, const size_t* steps=0);
+
+ /** @overload
+ @param m Array that (as a whole or partly) is assigned to the constructed matrix. No data is copied
+ by these constructors. Instead, the header pointing to m data or its sub-array is constructed and
+ associated with it. The reference counter, if any, is incremented. So, when you modify the matrix
+ formed using such a constructor, you also modify the corresponding elements of m . If you want to
+ have an independent copy of the sub-array, use Mat::clone() .
+ @param rowRange Range of the m rows to take. As usual, the range start is inclusive and the range
+ end is exclusive. Use Range::all() to take all the rows.
+ @param colRange Range of the m columns to take. Use Range::all() to take all the columns.
+ */
+ Mat(const Mat& m, const Range& rowRange, const Range& colRange=Range::all());
+
+ /** @overload
+ @param m Array that (as a whole or partly) is assigned to the constructed matrix. No data is copied
+ by these constructors. Instead, the header pointing to m data or its sub-array is constructed and
+ associated with it. The reference counter, if any, is incremented. So, when you modify the matrix
+ formed using such a constructor, you also modify the corresponding elements of m . If you want to
+ have an independent copy of the sub-array, use Mat::clone() .
+ @param roi Region of interest.
+ */
+ Mat(const Mat& m, const Rect& roi);
+
+ /** @overload
+ @param m Array that (as a whole or partly) is assigned to the constructed matrix. No data is copied
+ by these constructors. Instead, the header pointing to m data or its sub-array is constructed and
+ associated with it. The reference counter, if any, is incremented. So, when you modify the matrix
+ formed using such a constructor, you also modify the corresponding elements of m . If you want to
+ have an independent copy of the sub-array, use Mat::clone() .
+ @param ranges Array of selected ranges of m along each dimensionality.
+ */
+ Mat(const Mat& m, const Range* ranges);
+
+ /** @overload
+ @param m Array that (as a whole or partly) is assigned to the constructed matrix. No data is copied
+ by these constructors. Instead, the header pointing to m data or its sub-array is constructed and
+ associated with it. The reference counter, if any, is incremented. So, when you modify the matrix
+ formed using such a constructor, you also modify the corresponding elements of m . If you want to
+ have an independent copy of the sub-array, use Mat::clone() .
+ @param ranges Array of selected ranges of m along each dimensionality.
+ */
+ Mat(const Mat& m, const std::vector<Range>& ranges);
+
+ /** @overload
+ @param vec STL vector whose elements form the matrix. The matrix has a single column and the number
+ of rows equal to the number of vector elements. Type of the matrix matches the type of vector
+ elements. The constructor can handle arbitrary types, for which there is a properly declared
+ DataType . This means that the vector elements must be primitive numbers or uni-type numerical
+ tuples of numbers. Mixed-type structures are not supported. The corresponding constructor is
+ explicit. Since STL vectors are not automatically converted to Mat instances, you should write
+ Mat(vec) explicitly. Unless you copy the data into the matrix ( copyData=true ), no new elements
+ will be added to the vector because it can potentially yield vector data reallocation, and, thus,
+ the matrix data pointer will be invalid.
+ @param copyData Flag to specify whether the underlying data of the STL vector should be copied
+ to (true) or shared with (false) the newly constructed matrix. When the data is copied, the
+ allocated buffer is managed using Mat reference counting mechanism. While the data is shared,
+ the reference counter is NULL, and you should not deallocate the data until the matrix is not
+ destructed.
+ */
+ template<typename _Tp> explicit Mat(const std::vector<_Tp>& vec, bool copyData=false);
+
+ /** @overload
+ */
+ template<typename _Tp, int n> explicit Mat(const Vec<_Tp, n>& vec, bool copyData=true);
+
+ /** @overload
+ */
+ template<typename _Tp, int m, int n> explicit Mat(const Matx<_Tp, m, n>& mtx, bool copyData=true);
+
+ /** @overload
+ */
+ template<typename _Tp> explicit Mat(const Point_<_Tp>& pt, bool copyData=true);
+
+ /** @overload
+ */
+ template<typename _Tp> explicit Mat(const Point3_<_Tp>& pt, bool copyData=true);
+
+ /** @overload
+ */
+ template<typename _Tp> explicit Mat(const MatCommaInitializer_<_Tp>& commaInitializer);
+
+ //! download data from GpuMat
+ explicit Mat(const cuda::GpuMat& m);
+
+ //! destructor - calls release()
+ ~Mat();
+
+ /** @brief assignment operators
+
+ These are available assignment operators. Since they all are very different, make sure to read the
+ operator parameters description.
+ @param m Assigned, right-hand-side matrix. Matrix assignment is an O(1) operation. This means that
+ no data is copied but the data is shared and the reference counter, if any, is incremented. Before
+ assigning new data, the old data is de-referenced via Mat::release .
+ */
+ Mat& operator = (const Mat& m);
+
+ /** @overload
+ @param expr Assigned matrix expression object. As opposite to the first form of the assignment
+ operation, the second form can reuse already allocated matrix if it has the right size and type to
+ fit the matrix expression result. It is automatically handled by the real function that the matrix
+ expressions is expanded to. For example, C=A+B is expanded to add(A, B, C), and add takes care of
+ automatic C reallocation.
+ */
+ Mat& operator = (const MatExpr& expr);
+
+ //! retrieve UMat from Mat
+ UMat getUMat(int accessFlags, UMatUsageFlags usageFlags = USAGE_DEFAULT) const;
+
+ /** @brief Creates a matrix header for the specified matrix row.
+
+ The method makes a new header for the specified matrix row and returns it. This is an O(1)
+ operation, regardless of the matrix size. The underlying data of the new matrix is shared with the
+ original matrix. Here is the example of one of the classical basic matrix processing operations,
+ axpy, used by LU and many other algorithms:
+ @code
+ inline void matrix_axpy(Mat& A, int i, int j, double alpha)
+ {
+ A.row(i) += A.row(j)*alpha;
+ }
+ @endcode
+ @note In the current implementation, the following code does not work as expected:
+ @code
+ Mat A;
+ ...
+ A.row(i) = A.row(j); // will not work
+ @endcode
+ This happens because A.row(i) forms a temporary header that is further assigned to another header.
+ Remember that each of these operations is O(1), that is, no data is copied. Thus, the above
+ assignment is not true if you may have expected the j-th row to be copied to the i-th row. To
+ achieve that, you should either turn this simple assignment into an expression or use the
+ Mat::copyTo method:
+ @code
+ Mat A;
+ ...
+ // works, but looks a bit obscure.
+ A.row(i) = A.row(j) + 0;
+ // this is a bit longer, but the recommended method.
+ A.row(j).copyTo(A.row(i));
+ @endcode
+ @param y A 0-based row index.
+ */
+ Mat row(int y) const;
+
+ /** @brief Creates a matrix header for the specified matrix column.
+
+ The method makes a new header for the specified matrix column and returns it. This is an O(1)
+ operation, regardless of the matrix size. The underlying data of the new matrix is shared with the
+ original matrix. See also the Mat::row description.
+ @param x A 0-based column index.
+ */
+ Mat col(int x) const;
+
+ /** @brief Creates a matrix header for the specified row span.
+
+ The method makes a new header for the specified row span of the matrix. Similarly to Mat::row and
+ Mat::col , this is an O(1) operation.
+ @param startrow An inclusive 0-based start index of the row span.
+ @param endrow An exclusive 0-based ending index of the row span.
+ */
+ Mat rowRange(int startrow, int endrow) const;
+
+ /** @overload
+ @param r Range structure containing both the start and the end indices.
+ */
+ Mat rowRange(const Range& r) const;
+
+ /** @brief Creates a matrix header for the specified column span.
+
+ The method makes a new header for the specified column span of the matrix. Similarly to Mat::row and
+ Mat::col , this is an O(1) operation.
+ @param startcol An inclusive 0-based start index of the column span.
+ @param endcol An exclusive 0-based ending index of the column span.
+ */
+ Mat colRange(int startcol, int endcol) const;
+
+ /** @overload
+ @param r Range structure containing both the start and the end indices.
+ */
+ Mat colRange(const Range& r) const;
+
+ /** @brief Extracts a diagonal from a matrix
+
+ The method makes a new header for the specified matrix diagonal. The new matrix is represented as a
+ single-column matrix. Similarly to Mat::row and Mat::col, this is an O(1) operation.
+ @param d index of the diagonal, with the following values:
+ - `d=0` is the main diagonal.
+ - `d>0` is a diagonal from the lower half. For example, d=1 means the diagonal is set
+ immediately below the main one.
+ - `d<0` is a diagonal from the upper half. For example, d=-1 means the diagonal is set
+ immediately above the main one.
+ */
+ Mat diag(int d=0) const;
+
+ /** @brief creates a diagonal matrix
+
+ The method creates a square diagonal matrix from specified main diagonal.
+ @param d One-dimensional matrix that represents the main diagonal.
+ */
+ static Mat diag(const Mat& d);
+
+ /** @brief Creates a full copy of the array and the underlying data.
+
+ The method creates a full copy of the array. The original step[] is not taken into account. So, the
+ array copy is a continuous array occupying total()*elemSize() bytes.
+ */
+ Mat clone() const;
+
+ /** @brief Copies the matrix to another one.
+
+ The method copies the matrix data to another matrix. Before copying the data, the method invokes :
+ @code
+ m.create(this->size(), this->type());
+ @endcode
+ so that the destination matrix is reallocated if needed. While m.copyTo(m); works flawlessly, the
+ function does not handle the case of a partial overlap between the source and the destination
+ matrices.
+
+ When the operation mask is specified, if the Mat::create call shown above reallocates the matrix,
+ the newly allocated matrix is initialized with all zeros before copying the data.
+ @param m Destination matrix. If it does not have a proper size or type before the operation, it is
+ reallocated.
+ */
+ void copyTo( OutputArray m ) const;
+
+ /** @overload
+ @param m Destination matrix. If it does not have a proper size or type before the operation, it is
+ reallocated.
+ @param mask Operation mask. Its non-zero elements indicate which matrix elements need to be copied.
+ The mask has to be of type CV_8U and can have 1 or multiple channels.
+ */
+ void copyTo( OutputArray m, InputArray mask ) const;
+
+ /** @brief Converts an array to another data type with optional scaling.
+
+ The method converts source pixel values to the target data type. saturate_cast\<\> is applied at
+ the end to avoid possible overflows:
+
+ \f[m(x,y) = saturate \_ cast<rType>( \alpha (*this)(x,y) + \beta )\f]
+ @param m output matrix; if it does not have a proper size or type before the operation, it is
+ reallocated.
+ @param rtype desired output matrix type or, rather, the depth since the number of channels are the
+ same as the input has; if rtype is negative, the output matrix will have the same type as the input.
+ @param alpha optional scale factor.
+ @param beta optional delta added to the scaled values.
+ */
+ void convertTo( OutputArray m, int rtype, double alpha=1, double beta=0 ) const;
+
+ /** @brief Provides a functional form of convertTo.
+
+ This is an internally used method called by the @ref MatrixExpressions engine.
+ @param m Destination array.
+ @param type Desired destination array depth (or -1 if it should be the same as the source type).
+ */
+ void assignTo( Mat& m, int type=-1 ) const;
+
+ /** @brief Sets all or some of the array elements to the specified value.
+ @param s Assigned scalar converted to the actual array type.
+ */
+ Mat& operator = (const Scalar& s);
+
+ /** @brief Sets all or some of the array elements to the specified value.
+
+ This is an advanced variant of the Mat::operator=(const Scalar& s) operator.
+ @param value Assigned scalar converted to the actual array type.
+ @param mask Operation mask of the same size as \*this.
+ */
+ Mat& setTo(InputArray value, InputArray mask=noArray());
+
+ /** @brief Changes the shape and/or the number of channels of a 2D matrix without copying the data.
+
+ The method makes a new matrix header for \*this elements. The new matrix may have a different size
+ and/or different number of channels. Any combination is possible if:
+ - No extra elements are included into the new matrix and no elements are excluded. Consequently,
+ the product rows\*cols\*channels() must stay the same after the transformation.
+ - No data is copied. That is, this is an O(1) operation. Consequently, if you change the number of
+ rows, or the operation changes the indices of elements row in some other way, the matrix must be
+ continuous. See Mat::isContinuous .
+
+ For example, if there is a set of 3D points stored as an STL vector, and you want to represent the
+ points as a 3xN matrix, do the following:
+ @code
+ std::vector<Point3f> vec;
+ ...
+ Mat pointMat = Mat(vec). // convert vector to Mat, O(1) operation
+ reshape(1). // make Nx3 1-channel matrix out of Nx1 3-channel.
+ // Also, an O(1) operation
+ t(); // finally, transpose the Nx3 matrix.
+ // This involves copying all the elements
+ @endcode
+ @param cn New number of channels. If the parameter is 0, the number of channels remains the same.
+ @param rows New number of rows. If the parameter is 0, the number of rows remains the same.
+ */
+ Mat reshape(int cn, int rows=0) const;
+
+ /** @overload */
+ Mat reshape(int cn, int newndims, const int* newsz) const;
+
+ /** @brief Transposes a matrix.
+
+ The method performs matrix transposition by means of matrix expressions. It does not perform the
+ actual transposition but returns a temporary matrix transposition object that can be further used as
+ a part of more complex matrix expressions or can be assigned to a matrix:
+ @code
+ Mat A1 = A + Mat::eye(A.size(), A.type())*lambda;
+ Mat C = A1.t()*A1; // compute (A + lambda*I)^t * (A + lamda*I)
+ @endcode
+ */
+ MatExpr t() const;
+
+ /** @brief Inverses a matrix.
+
+ The method performs a matrix inversion by means of matrix expressions. This means that a temporary
+ matrix inversion object is returned by the method and can be used further as a part of more complex
+ matrix expressions or can be assigned to a matrix.
+ @param method Matrix inversion method. One of cv::DecompTypes
+ */
+ MatExpr inv(int method=DECOMP_LU) const;
+
+ /** @brief Performs an element-wise multiplication or division of the two matrices.
+
+ The method returns a temporary object encoding per-element array multiplication, with optional
+ scale. Note that this is not a matrix multiplication that corresponds to a simpler "\*" operator.
+
+ Example:
+ @code
+ Mat C = A.mul(5/B); // equivalent to divide(A, B, C, 5)
+ @endcode
+ @param m Another array of the same type and the same size as \*this, or a matrix expression.
+ @param scale Optional scale factor.
+ */
+ MatExpr mul(InputArray m, double scale=1) const;
+
+ /** @brief Computes a cross-product of two 3-element vectors.
+
+ The method computes a cross-product of two 3-element vectors. The vectors must be 3-element
+ floating-point vectors of the same shape and size. The result is another 3-element vector of the
+ same shape and type as operands.
+ @param m Another cross-product operand.
+ */
+ Mat cross(InputArray m) const;
+
+ /** @brief Computes a dot-product of two vectors.
+
+ The method computes a dot-product of two matrices. If the matrices are not single-column or
+ single-row vectors, the top-to-bottom left-to-right scan ordering is used to treat them as 1D
+ vectors. The vectors must have the same size and type. If the matrices have more than one channel,
+ the dot products from all the channels are summed together.
+ @param m another dot-product operand.
+ */
+ double dot(InputArray m) const;
+
+ /** @brief Returns a zero array of the specified size and type.
+
+ The method returns a Matlab-style zero array initializer. It can be used to quickly form a constant
+ array as a function parameter, part of a matrix expression, or as a matrix initializer. :
+ @code
+ Mat A;
+ A = Mat::zeros(3, 3, CV_32F);
+ @endcode
+ In the example above, a new matrix is allocated only if A is not a 3x3 floating-point matrix.
+ Otherwise, the existing matrix A is filled with zeros.
+ @param rows Number of rows.
+ @param cols Number of columns.
+ @param type Created matrix type.
+ */
+ static MatExpr zeros(int rows, int cols, int type);
+
+ /** @overload
+ @param size Alternative to the matrix size specification Size(cols, rows) .
+ @param type Created matrix type.
+ */
+ static MatExpr zeros(Size size, int type);
+
+ /** @overload
+ @param ndims Array dimensionality.
+ @param sz Array of integers specifying the array shape.
+ @param type Created matrix type.
+ */
+ static MatExpr zeros(int ndims, const int* sz, int type);
+
+ /** @brief Returns an array of all 1's of the specified size and type.
+
+ The method returns a Matlab-style 1's array initializer, similarly to Mat::zeros. Note that using
+ this method you can initialize an array with an arbitrary value, using the following Matlab idiom:
+ @code
+ Mat A = Mat::ones(100, 100, CV_8U)*3; // make 100x100 matrix filled with 3.
+ @endcode
+ The above operation does not form a 100x100 matrix of 1's and then multiply it by 3. Instead, it
+ just remembers the scale factor (3 in this case) and use it when actually invoking the matrix
+ initializer.
+ @param rows Number of rows.
+ @param cols Number of columns.
+ @param type Created matrix type.
+ */
+ static MatExpr ones(int rows, int cols, int type);
+
+ /** @overload
+ @param size Alternative to the matrix size specification Size(cols, rows) .
+ @param type Created matrix type.
+ */
+ static MatExpr ones(Size size, int type);
+
+ /** @overload
+ @param ndims Array dimensionality.
+ @param sz Array of integers specifying the array shape.
+ @param type Created matrix type.
+ */
+ static MatExpr ones(int ndims, const int* sz, int type);
+
+ /** @brief Returns an identity matrix of the specified size and type.
+
+ The method returns a Matlab-style identity matrix initializer, similarly to Mat::zeros. Similarly to
+ Mat::ones, you can use a scale operation to create a scaled identity matrix efficiently:
+ @code
+ // make a 4x4 diagonal matrix with 0.1's on the diagonal.
+ Mat A = Mat::eye(4, 4, CV_32F)*0.1;
+ @endcode
+ @param rows Number of rows.
+ @param cols Number of columns.
+ @param type Created matrix type.
+ */
+ static MatExpr eye(int rows, int cols, int type);
+
+ /** @overload
+ @param size Alternative matrix size specification as Size(cols, rows) .
+ @param type Created matrix type.
+ */
+ static MatExpr eye(Size size, int type);
+
+ /** @brief Allocates new array data if needed.
+
+ This is one of the key Mat methods. Most new-style OpenCV functions and methods that produce arrays
+ call this method for each output array. The method uses the following algorithm:
+
+ -# If the current array shape and the type match the new ones, return immediately. Otherwise,
+ de-reference the previous data by calling Mat::release.
+ -# Initialize the new header.
+ -# Allocate the new data of total()\*elemSize() bytes.
+ -# Allocate the new, associated with the data, reference counter and set it to 1.
+
+ Such a scheme makes the memory management robust and efficient at the same time and helps avoid
+ extra typing for you. This means that usually there is no need to explicitly allocate output arrays.
+ That is, instead of writing:
+ @code
+ Mat color;
+ ...
+ Mat gray(color.rows, color.cols, color.depth());
+ cvtColor(color, gray, COLOR_BGR2GRAY);
+ @endcode
+ you can simply write:
+ @code
+ Mat color;
+ ...
+ Mat gray;
+ cvtColor(color, gray, COLOR_BGR2GRAY);
+ @endcode
+ because cvtColor, as well as the most of OpenCV functions, calls Mat::create() for the output array
+ internally.
+ @param rows New number of rows.
+ @param cols New number of columns.
+ @param type New matrix type.
+ */
+ void create(int rows, int cols, int type);
+
+ /** @overload
+ @param size Alternative new matrix size specification: Size(cols, rows)
+ @param type New matrix type.
+ */
+ void create(Size size, int type);
+
+ /** @overload
+ @param ndims New array dimensionality.
+ @param sizes Array of integers specifying a new array shape.
+ @param type New matrix type.
+ */
+ void create(int ndims, const int* sizes, int type);
+
+ /** @overload
+ @param sizes Array of integers specifying a new array shape.
+ @param type New matrix type.
+ */
+ void create(const std::vector<int>& sizes, int type);
+
+ /** @brief Increments the reference counter.
+
+ The method increments the reference counter associated with the matrix data. If the matrix header
+ points to an external data set (see Mat::Mat ), the reference counter is NULL, and the method has no
+ effect in this case. Normally, to avoid memory leaks, the method should not be called explicitly. It
+ is called implicitly by the matrix assignment operator. The reference counter increment is an atomic
+ operation on the platforms that support it. Thus, it is safe to operate on the same matrices
+ asynchronously in different threads.
+ */
+ void addref();
+
+ /** @brief Decrements the reference counter and deallocates the matrix if needed.
+
+ The method decrements the reference counter associated with the matrix data. When the reference
+ counter reaches 0, the matrix data is deallocated and the data and the reference counter pointers
+ are set to NULL's. If the matrix header points to an external data set (see Mat::Mat ), the
+ reference counter is NULL, and the method has no effect in this case.
+
+ This method can be called manually to force the matrix data deallocation. But since this method is
+ automatically called in the destructor, or by any other method that changes the data pointer, it is
+ usually not needed. The reference counter decrement and check for 0 is an atomic operation on the
+ platforms that support it. Thus, it is safe to operate on the same matrices asynchronously in
+ different threads.
+ */
+ void release();
+
+ //! deallocates the matrix data
+ void deallocate();
+ //! internal use function; properly re-allocates _size, _step arrays
+ void copySize(const Mat& m);
+
+ /** @brief Reserves space for the certain number of rows.
+
+ The method reserves space for sz rows. If the matrix already has enough space to store sz rows,
+ nothing happens. If the matrix is reallocated, the first Mat::rows rows are preserved. The method
+ emulates the corresponding method of the STL vector class.
+ @param sz Number of rows.
+ */
+ void reserve(size_t sz);
+
+ /** @brief Changes the number of matrix rows.
+
+ The methods change the number of matrix rows. If the matrix is reallocated, the first
+ min(Mat::rows, sz) rows are preserved. The methods emulate the corresponding methods of the STL
+ vector class.
+ @param sz New number of rows.
+ */
+ void resize(size_t sz);
+
+ /** @overload
+ @param sz New number of rows.
+ @param s Value assigned to the newly added elements.
+ */
+ void resize(size_t sz, const Scalar& s);
+
+ //! internal function
+ void push_back_(const void* elem);
+
+ /** @brief Adds elements to the bottom of the matrix.
+
+ The methods add one or more elements to the bottom of the matrix. They emulate the corresponding
+ method of the STL vector class. When elem is Mat , its type and the number of columns must be the
+ same as in the container matrix.
+ @param elem Added element(s).
+ */
+ template<typename _Tp> void push_back(const _Tp& elem);
+
+ /** @overload
+ @param elem Added element(s).
+ */
+ template<typename _Tp> void push_back(const Mat_<_Tp>& elem);
+
+ /** @overload
+ @param m Added line(s).
+ */
+ void push_back(const Mat& m);
+
+ /** @brief Removes elements from the bottom of the matrix.
+
+ The method removes one or more rows from the bottom of the matrix.
+ @param nelems Number of removed rows. If it is greater than the total number of rows, an exception
+ is thrown.
+ */
+ void pop_back(size_t nelems=1);
+
+ /** @brief Locates the matrix header within a parent matrix.
+
+ After you extracted a submatrix from a matrix using Mat::row, Mat::col, Mat::rowRange,
+ Mat::colRange, and others, the resultant submatrix points just to the part of the original big
+ matrix. However, each submatrix contains information (represented by datastart and dataend
+ fields) that helps reconstruct the original matrix size and the position of the extracted
+ submatrix within the original matrix. The method locateROI does exactly that.
+ @param wholeSize Output parameter that contains the size of the whole matrix containing *this*
+ as a part.
+ @param ofs Output parameter that contains an offset of *this* inside the whole matrix.
+ */
+ void locateROI( Size& wholeSize, Point& ofs ) const;
+
+ /** @brief Adjusts a submatrix size and position within the parent matrix.
+
+ The method is complimentary to Mat::locateROI . The typical use of these functions is to determine
+ the submatrix position within the parent matrix and then shift the position somehow. Typically, it
+ can be required for filtering operations when pixels outside of the ROI should be taken into
+ account. When all the method parameters are positive, the ROI needs to grow in all directions by the
+ specified amount, for example:
+ @code
+ A.adjustROI(2, 2, 2, 2);
+ @endcode
+ In this example, the matrix size is increased by 4 elements in each direction. The matrix is shifted
+ by 2 elements to the left and 2 elements up, which brings in all the necessary pixels for the
+ filtering with the 5x5 kernel.
+
+ adjustROI forces the adjusted ROI to be inside of the parent matrix that is boundaries of the
+ adjusted ROI are constrained by boundaries of the parent matrix. For example, if the submatrix A is
+ located in the first row of a parent matrix and you called A.adjustROI(2, 2, 2, 2) then A will not
+ be increased in the upward direction.
+
+ The function is used internally by the OpenCV filtering functions, like filter2D , morphological
+ operations, and so on.
+ @param dtop Shift of the top submatrix boundary upwards.
+ @param dbottom Shift of the bottom submatrix boundary downwards.
+ @param dleft Shift of the left submatrix boundary to the left.
+ @param dright Shift of the right submatrix boundary to the right.
+ @sa copyMakeBorder
+ */
+ Mat& adjustROI( int dtop, int dbottom, int dleft, int dright );
+
+ /** @brief Extracts a rectangular submatrix.
+
+ The operators make a new header for the specified sub-array of \*this . They are the most
+ generalized forms of Mat::row, Mat::col, Mat::rowRange, and Mat::colRange . For example,
+ `A(Range(0, 10), Range::all())` is equivalent to `A.rowRange(0, 10)`. Similarly to all of the above,
+ the operators are O(1) operations, that is, no matrix data is copied.
+ @param rowRange Start and end row of the extracted submatrix. The upper boundary is not included. To
+ select all the rows, use Range::all().
+ @param colRange Start and end column of the extracted submatrix. The upper boundary is not included.
+ To select all the columns, use Range::all().
+ */
+ Mat operator()( Range rowRange, Range colRange ) const;
+
+ /** @overload
+ @param roi Extracted submatrix specified as a rectangle.
+ */
+ Mat operator()( const Rect& roi ) const;
+
+ /** @overload
+ @param ranges Array of selected ranges along each array dimension.
+ */
+ Mat operator()( const Range* ranges ) const;
+
+ /** @overload
+ @param ranges Array of selected ranges along each array dimension.
+ */
+ Mat operator()(const std::vector<Range>& ranges) const;
+
+ // //! converts header to CvMat; no data is copied
+ // operator CvMat() const;
+ // //! converts header to CvMatND; no data is copied
+ // operator CvMatND() const;
+ // //! converts header to IplImage; no data is copied
+ // operator IplImage() const;
+
+ template<typename _Tp> operator std::vector<_Tp>() const;
+ template<typename _Tp, int n> operator Vec<_Tp, n>() const;
+ template<typename _Tp, int m, int n> operator Matx<_Tp, m, n>() const;
+
+ /** @brief Reports whether the matrix is continuous or not.
+
+ The method returns true if the matrix elements are stored continuously without gaps at the end of
+ each row. Otherwise, it returns false. Obviously, 1x1 or 1xN matrices are always continuous.
+ Matrices created with Mat::create are always continuous. But if you extract a part of the matrix
+ using Mat::col, Mat::diag, and so on, or constructed a matrix header for externally allocated data,
+ such matrices may no longer have this property.
+
+ The continuity flag is stored as a bit in the Mat::flags field and is computed automatically when
+ you construct a matrix header. Thus, the continuity check is a very fast operation, though
+ theoretically it could be done as follows:
+ @code
+ // alternative implementation of Mat::isContinuous()
+ bool myCheckMatContinuity(const Mat& m)
+ {
+ //return (m.flags & Mat::CONTINUOUS_FLAG) != 0;
+ return m.rows == 1 || m.step == m.cols*m.elemSize();
+ }
+ @endcode
+ The method is used in quite a few of OpenCV functions. The point is that element-wise operations
+ (such as arithmetic and logical operations, math functions, alpha blending, color space
+ transformations, and others) do not depend on the image geometry. Thus, if all the input and output
+ arrays are continuous, the functions can process them as very long single-row vectors. The example
+ below illustrates how an alpha-blending function can be implemented:
+ @code
+ template<typename T>
+ void alphaBlendRGBA(const Mat& src1, const Mat& src2, Mat& dst)
+ {
+ const float alpha_scale = (float)std::numeric_limits<T>::max(),
+ inv_scale = 1.f/alpha_scale;
+
+ CV_Assert( src1.type() == src2.type() &&
+ src1.type() == CV_MAKETYPE(DataType<T>::depth, 4) &&
+ src1.size() == src2.size());
+ Size size = src1.size();
+ dst.create(size, src1.type());
+
+ // here is the idiom: check the arrays for continuity and,
+ // if this is the case,
+ // treat the arrays as 1D vectors
+ if( src1.isContinuous() && src2.isContinuous() && dst.isContinuous() )
+ {
+ size.width *= size.height;
+ size.height = 1;
+ }
+ size.width *= 4;
+
+ for( int i = 0; i < size.height; i++ )
+ {
+ // when the arrays are continuous,
+ // the outer loop is executed only once
+ const T* ptr1 = src1.ptr<T>(i);
+ const T* ptr2 = src2.ptr<T>(i);
+ T* dptr = dst.ptr<T>(i);
+
+ for( int j = 0; j < size.width; j += 4 )
+ {
+ float alpha = ptr1[j+3]*inv_scale, beta = ptr2[j+3]*inv_scale;
+ dptr[j] = saturate_cast<T>(ptr1[j]*alpha + ptr2[j]*beta);
+ dptr[j+1] = saturate_cast<T>(ptr1[j+1]*alpha + ptr2[j+1]*beta);
+ dptr[j+2] = saturate_cast<T>(ptr1[j+2]*alpha + ptr2[j+2]*beta);
+ dptr[j+3] = saturate_cast<T>((1 - (1-alpha)*(1-beta))*alpha_scale);
+ }
+ }
+ }
+ @endcode
+ This approach, while being very simple, can boost the performance of a simple element-operation by
+ 10-20 percents, especially if the image is rather small and the operation is quite simple.
+
+ Another OpenCV idiom in this function, a call of Mat::create for the destination array, that
+ allocates the destination array unless it already has the proper size and type. And while the newly
+ allocated arrays are always continuous, you still need to check the destination array because
+ Mat::create does not always allocate a new matrix.
+ */
+ bool isContinuous() const;
+
+ //! returns true if the matrix is a submatrix of another matrix
+ bool isSubmatrix() const;
+
+ /** @brief Returns the matrix element size in bytes.
+
+ The method returns the matrix element size in bytes. For example, if the matrix type is CV_16SC3 ,
+ the method returns 3\*sizeof(short) or 6.
+ */
+ size_t elemSize() const;
+
+ /** @brief Returns the size of each matrix element channel in bytes.
+
+ The method returns the matrix element channel size in bytes, that is, it ignores the number of
+ channels. For example, if the matrix type is CV_16SC3 , the method returns sizeof(short) or 2.
+ */
+ size_t elemSize1() const;
+
+ /** @brief Returns the type of a matrix element.
+
+ The method returns a matrix element type. This is an identifier compatible with the CvMat type
+ system, like CV_16SC3 or 16-bit signed 3-channel array, and so on.
+ */
+ int type() const;
+
+ /** @brief Returns the depth of a matrix element.
+
+ The method returns the identifier of the matrix element depth (the type of each individual channel).
+ For example, for a 16-bit signed element array, the method returns CV_16S . A complete list of
+ matrix types contains the following values:
+ - CV_8U - 8-bit unsigned integers ( 0..255 )
+ - CV_8S - 8-bit signed integers ( -128..127 )
+ - CV_16U - 16-bit unsigned integers ( 0..65535 )
+ - CV_16S - 16-bit signed integers ( -32768..32767 )
+ - CV_32S - 32-bit signed integers ( -2147483648..2147483647 )
+ - CV_32F - 32-bit floating-point numbers ( -FLT_MAX..FLT_MAX, INF, NAN )
+ - CV_64F - 64-bit floating-point numbers ( -DBL_MAX..DBL_MAX, INF, NAN )
+ */
+ int depth() const;
+
+ /** @brief Returns the number of matrix channels.
+
+ The method returns the number of matrix channels.
+ */
+ int channels() const;
+
+ /** @brief Returns a normalized step.
+
+ The method returns a matrix step divided by Mat::elemSize1() . It can be useful to quickly access an
+ arbitrary matrix element.
+ */
+ size_t step1(int i=0) const;
+
+ /** @brief Returns true if the array has no elements.
+
+ The method returns true if Mat::total() is 0 or if Mat::data is NULL. Because of pop_back() and
+ resize() methods `M.total() == 0` does not imply that `M.data == NULL`.
+ */
+ bool empty() const;
+
+ /** @brief Returns the total number of array elements.
+
+ The method returns the number of array elements (a number of pixels if the array represents an
+ image).
+ */
+ size_t total() const;
+
+ //! returns N if the matrix is 1-channel (N x ptdim) or ptdim-channel (1 x N) or (N x 1); negative number otherwise
+ int checkVector(int elemChannels, int depth=-1, bool requireContinuous=true) const;
+
+ /** @brief Returns a pointer to the specified matrix row.
+
+ The methods return `uchar*` or typed pointer to the specified matrix row. See the sample in
+ Mat::isContinuous to know how to use these methods.
+ @param i0 A 0-based row index.
+ */
+ uchar* ptr(int i0=0);
+ /** @overload */
+ const uchar* ptr(int i0=0) const;
+
+ /** @overload
+ @param row Index along the dimension 0
+ @param col Index along the dimension 1
+ */
+ uchar* ptr(int row, int col);
+ /** @overload
+ @param row Index along the dimension 0
+ @param col Index along the dimension 1
+ */
+ const uchar* ptr(int row, int col) const;
+
+ /** @overload */
+ uchar* ptr(int i0, int i1, int i2);
+ /** @overload */
+ const uchar* ptr(int i0, int i1, int i2) const;
+
+ /** @overload */
+ uchar* ptr(const int* idx);
+ /** @overload */
+ const uchar* ptr(const int* idx) const;
+ /** @overload */
+ template<int n> uchar* ptr(const Vec<int, n>& idx);
+ /** @overload */
+ template<int n> const uchar* ptr(const Vec<int, n>& idx) const;
+
+ /** @overload */
+ template<typename _Tp> _Tp* ptr(int i0=0);
+ /** @overload */
+ template<typename _Tp> const _Tp* ptr(int i0=0) const;
+ /** @overload
+ @param row Index along the dimension 0
+ @param col Index along the dimension 1
+ */
+ template<typename _Tp> _Tp* ptr(int row, int col);
+ /** @overload
+ @param row Index along the dimension 0
+ @param col Index along the dimension 1
+ */
+ template<typename _Tp> const _Tp* ptr(int row, int col) const;
+ /** @overload */
+ template<typename _Tp> _Tp* ptr(int i0, int i1, int i2);
+ /** @overload */
+ template<typename _Tp> const _Tp* ptr(int i0, int i1, int i2) const;
+ /** @overload */
+ template<typename _Tp> _Tp* ptr(const int* idx);
+ /** @overload */
+ template<typename _Tp> const _Tp* ptr(const int* idx) const;
+ /** @overload */
+ template<typename _Tp, int n> _Tp* ptr(const Vec<int, n>& idx);
+ /** @overload */
+ template<typename _Tp, int n> const _Tp* ptr(const Vec<int, n>& idx) const;
+
+ /** @brief Returns a reference to the specified array element.
+
+ The template methods return a reference to the specified array element. For the sake of higher
+ performance, the index range checks are only performed in the Debug configuration.
+
+ Note that the variants with a single index (i) can be used to access elements of single-row or
+ single-column 2-dimensional arrays. That is, if, for example, A is a 1 x N floating-point matrix and
+ B is an M x 1 integer matrix, you can simply write `A.at<float>(k+4)` and `B.at<int>(2*i+1)`
+ instead of `A.at<float>(0,k+4)` and `B.at<int>(2*i+1,0)`, respectively.
+
+ The example below initializes a Hilbert matrix:
+ @code
+ Mat H(100, 100, CV_64F);
+ for(int i = 0; i < H.rows; i++)
+ for(int j = 0; j < H.cols; j++)
+ H.at<double>(i,j)=1./(i+j+1);
+ @endcode
+
+ Keep in mind that the size identifier used in the at operator cannot be chosen at random. It depends
+ on the image from which you are trying to retrieve the data. The table below gives a better insight in this:
+ - If matrix is of type `CV_8U` then use `Mat.at<uchar>(y,x)`.
+ - If matrix is of type `CV_8S` then use `Mat.at<schar>(y,x)`.
+ - If matrix is of type `CV_16U` then use `Mat.at<ushort>(y,x)`.
+ - If matrix is of type `CV_16S` then use `Mat.at<short>(y,x)`.
+ - If matrix is of type `CV_32S` then use `Mat.at<int>(y,x)`.
+ - If matrix is of type `CV_32F` then use `Mat.at<float>(y,x)`.
+ - If matrix is of type `CV_64F` then use `Mat.at<double>(y,x)`.
+
+ @param i0 Index along the dimension 0
+ */
+ template<typename _Tp> _Tp& at(int i0=0);
+ /** @overload
+ @param i0 Index along the dimension 0
+ */
+ template<typename _Tp> const _Tp& at(int i0=0) const;
+ /** @overload
+ @param row Index along the dimension 0
+ @param col Index along the dimension 1
+ */
+ template<typename _Tp> _Tp& at(int row, int col);
+ /** @overload
+ @param row Index along the dimension 0
+ @param col Index along the dimension 1
+ */
+ template<typename _Tp> const _Tp& at(int row, int col) const;
+
+ /** @overload
+ @param i0 Index along the dimension 0
+ @param i1 Index along the dimension 1
+ @param i2 Index along the dimension 2
+ */
+ template<typename _Tp> _Tp& at(int i0, int i1, int i2);
+ /** @overload
+ @param i0 Index along the dimension 0
+ @param i1 Index along the dimension 1
+ @param i2 Index along the dimension 2
+ */
+ template<typename _Tp> const _Tp& at(int i0, int i1, int i2) const;
+
+ /** @overload
+ @param idx Array of Mat::dims indices.
+ */
+ template<typename _Tp> _Tp& at(const int* idx);
+ /** @overload
+ @param idx Array of Mat::dims indices.
+ */
+ template<typename _Tp> const _Tp& at(const int* idx) const;
+
+ /** @overload */
+ template<typename _Tp, int n> _Tp& at(const Vec<int, n>& idx);
+ /** @overload */
+ template<typename _Tp, int n> const _Tp& at(const Vec<int, n>& idx) const;
+
+ /** @overload
+ special versions for 2D arrays (especially convenient for referencing image pixels)
+ @param pt Element position specified as Point(j,i) .
+ */
+ template<typename _Tp> _Tp& at(Point pt);
+ /** @overload
+ special versions for 2D arrays (especially convenient for referencing image pixels)
+ @param pt Element position specified as Point(j,i) .
+ */
+ template<typename _Tp> const _Tp& at(Point pt) const;
+
+ /** @brief Returns the matrix iterator and sets it to the first matrix element.
+
+ The methods return the matrix read-only or read-write iterators. The use of matrix iterators is very
+ similar to the use of bi-directional STL iterators. In the example below, the alpha blending
+ function is rewritten using the matrix iterators:
+ @code
+ template<typename T>
+ void alphaBlendRGBA(const Mat& src1, const Mat& src2, Mat& dst)
+ {
+ typedef Vec<T, 4> VT;
+
+ const float alpha_scale = (float)std::numeric_limits<T>::max(),
+ inv_scale = 1.f/alpha_scale;
+
+ CV_Assert( src1.type() == src2.type() &&
+ src1.type() == DataType<VT>::type &&
+ src1.size() == src2.size());
+ Size size = src1.size();
+ dst.create(size, src1.type());
+
+ MatConstIterator_<VT> it1 = src1.begin<VT>(), it1_end = src1.end<VT>();
+ MatConstIterator_<VT> it2 = src2.begin<VT>();
+ MatIterator_<VT> dst_it = dst.begin<VT>();
+
+ for( ; it1 != it1_end; ++it1, ++it2, ++dst_it )
+ {
+ VT pix1 = *it1, pix2 = *it2;
+ float alpha = pix1[3]*inv_scale, beta = pix2[3]*inv_scale;
+ *dst_it = VT(saturate_cast<T>(pix1[0]*alpha + pix2[0]*beta),
+ saturate_cast<T>(pix1[1]*alpha + pix2[1]*beta),
+ saturate_cast<T>(pix1[2]*alpha + pix2[2]*beta),
+ saturate_cast<T>((1 - (1-alpha)*(1-beta))*alpha_scale));
+ }
+ }
+ @endcode
+ */
+ template<typename _Tp> MatIterator_<_Tp> begin();
+ template<typename _Tp> MatConstIterator_<_Tp> begin() const;
+
+ /** @brief Returns the matrix iterator and sets it to the after-last matrix element.
+
+ The methods return the matrix read-only or read-write iterators, set to the point following the last
+ matrix element.
+ */
+ template<typename _Tp> MatIterator_<_Tp> end();
+ template<typename _Tp> MatConstIterator_<_Tp> end() const;
+
+ /** @brief Runs the given functor over all matrix elements in parallel.
+
+ The operation passed as argument has to be a function pointer, a function object or a lambda(C++11).
+
+ Example 1. All of the operations below put 0xFF the first channel of all matrix elements:
+ @code
+ Mat image(1920, 1080, CV_8UC3);
+ typedef cv::Point3_<uint8_t> Pixel;
+
+ // first. raw pointer access.
+ for (int r = 0; r < image.rows; ++r) {
+ Pixel* ptr = image.ptr<Pixel>(0, r);
+ const Pixel* ptr_end = ptr + image.cols;
+ for (; ptr != ptr_end; ++ptr) {
+ ptr->x = 255;
+ }
+ }
+
+ // Using MatIterator. (Simple but there are a Iterator's overhead)
+ for (Pixel &p : cv::Mat_<Pixel>(image)) {
+ p.x = 255;
+ }
+
+ // Parallel execution with function object.
+ struct Operator {
+ void operator ()(Pixel &pixel, const int * position) {
+ pixel.x = 255;
+ }
+ };
+ image.forEach<Pixel>(Operator());
+
+ // Parallel execution using C++11 lambda.
+ image.forEach<Pixel>([](Pixel &p, const int * position) -> void {
+ p.x = 255;
+ });
+ @endcode
+ Example 2. Using the pixel's position:
+ @code
+ // Creating 3D matrix (255 x 255 x 255) typed uint8_t
+ // and initialize all elements by the value which equals elements position.
+ // i.e. pixels (x,y,z) = (1,2,3) is (b,g,r) = (1,2,3).
+
+ int sizes[] = { 255, 255, 255 };
+ typedef cv::Point3_<uint8_t> Pixel;
+
+ Mat_<Pixel> image = Mat::zeros(3, sizes, CV_8UC3);
+
+ image.forEach<Pixel>([&](Pixel& pixel, const int position[]) -> void {
+ pixel.x = position[0];
+ pixel.y = position[1];
+ pixel.z = position[2];
+ });
+ @endcode
+ */
+ template<typename _Tp, typename Functor> void forEach(const Functor& operation);
+ /** @overload */
+ template<typename _Tp, typename Functor> void forEach(const Functor& operation) const;
+
+#ifdef CV_CXX_MOVE_SEMANTICS
+ Mat(Mat&& m);
+ Mat& operator = (Mat&& m);
+#endif
+
+ enum { MAGIC_VAL = 0x42FF0000, AUTO_STEP = 0, CONTINUOUS_FLAG = CV_MAT_CONT_FLAG, SUBMATRIX_FLAG = CV_SUBMAT_FLAG };
+ enum { MAGIC_MASK = 0xFFFF0000, TYPE_MASK = 0x00000FFF, DEPTH_MASK = 7 };
+
+ /*! includes several bit-fields:
+ - the magic signature
+ - continuity flag
+ - depth
+ - number of channels
+ */
+ int flags;
+ //! the matrix dimensionality, >= 2
+ int dims;
+ //! the number of rows and columns or (-1, -1) when the matrix has more than 2 dimensions
+ int rows, cols;
+ //! pointer to the data
+ uchar* data;
+
+ //! helper fields used in locateROI and adjustROI
+ const uchar* datastart;
+ const uchar* dataend;
+ const uchar* datalimit;
+
+ //! custom allocator
+ MatAllocator* allocator;
+ //! and the standard allocator
+ static MatAllocator* getStdAllocator();
+ static MatAllocator* getDefaultAllocator();
+ static void setDefaultAllocator(MatAllocator* allocator);
+
+ //! interaction with UMat
+ UMatData* u;
+
+ MatSize size;
+ MatStep step;
+
+protected:
+ template<typename _Tp, typename Functor> void forEach_impl(const Functor& operation);
+};
+
+
+///////////////////////////////// Mat_<_Tp> ////////////////////////////////////
+
+/** @brief Template matrix class derived from Mat
+
+@code
+ template<typename _Tp> class Mat_ : public Mat
+ {
+ public:
+ // ... some specific methods
+ // and
+ // no new extra fields
+ };
+@endcode
+The class `Mat_<_Tp>` is a *thin* template wrapper on top of the Mat class. It does not have any
+extra data fields. Nor this class nor Mat has any virtual methods. Thus, references or pointers to
+these two classes can be freely but carefully converted one to another. For example:
+@code
+ // create a 100x100 8-bit matrix
+ Mat M(100,100,CV_8U);
+ // this will be compiled fine. no any data conversion will be done.
+ Mat_<float>& M1 = (Mat_<float>&)M;
+ // the program is likely to crash at the statement below
+ M1(99,99) = 1.f;
+@endcode
+While Mat is sufficient in most cases, Mat_ can be more convenient if you use a lot of element
+access operations and if you know matrix type at the compilation time. Note that
+`Mat::at(int y,int x)` and `Mat_::operator()(int y,int x)` do absolutely the same
+and run at the same speed, but the latter is certainly shorter:
+@code
+ Mat_<double> M(20,20);
+ for(int i = 0; i < M.rows; i++)
+ for(int j = 0; j < M.cols; j++)
+ M(i,j) = 1./(i+j+1);
+ Mat E, V;
+ eigen(M,E,V);
+ cout << E.at<double>(0,0)/E.at<double>(M.rows-1,0);
+@endcode
+To use Mat_ for multi-channel images/matrices, pass Vec as a Mat_ parameter:
+@code
+ // allocate a 320x240 color image and fill it with green (in RGB space)
+ Mat_<Vec3b> img(240, 320, Vec3b(0,255,0));
+ // now draw a diagonal white line
+ for(int i = 0; i < 100; i++)
+ img(i,i)=Vec3b(255,255,255);
+ // and now scramble the 2nd (red) channel of each pixel
+ for(int i = 0; i < img.rows; i++)
+ for(int j = 0; j < img.cols; j++)
+ img(i,j)[2] ^= (uchar)(i ^ j);
+@endcode
+ */
+template<typename _Tp> class Mat_ : public Mat
+{
+public:
+ typedef _Tp value_type;
+ typedef typename DataType<_Tp>::channel_type channel_type;
+ typedef MatIterator_<_Tp> iterator;
+ typedef MatConstIterator_<_Tp> const_iterator;
+
+ //! default constructor
+ Mat_();
+ //! equivalent to Mat(_rows, _cols, DataType<_Tp>::type)
+ Mat_(int _rows, int _cols);
+ //! constructor that sets each matrix element to specified value
+ Mat_(int _rows, int _cols, const _Tp& value);
+ //! equivalent to Mat(_size, DataType<_Tp>::type)
+ explicit Mat_(Size _size);
+ //! constructor that sets each matrix element to specified value
+ Mat_(Size _size, const _Tp& value);
+ //! n-dim array constructor
+ Mat_(int _ndims, const int* _sizes);
+ //! n-dim array constructor that sets each matrix element to specified value
+ Mat_(int _ndims, const int* _sizes, const _Tp& value);
+ //! copy/conversion contructor. If m is of different type, it's converted
+ Mat_(const Mat& m);
+ //! copy constructor
+ Mat_(const Mat_& m);
+ //! constructs a matrix on top of user-allocated data. step is in bytes(!!!), regardless of the type
+ Mat_(int _rows, int _cols, _Tp* _data, size_t _step=AUTO_STEP);
+ //! constructs n-dim matrix on top of user-allocated data. steps are in bytes(!!!), regardless of the type
+ Mat_(int _ndims, const int* _sizes, _Tp* _data, const size_t* _steps=0);
+ //! selects a submatrix
+ Mat_(const Mat_& m, const Range& rowRange, const Range& colRange=Range::all());
+ //! selects a submatrix
+ Mat_(const Mat_& m, const Rect& roi);
+ //! selects a submatrix, n-dim version
+ Mat_(const Mat_& m, const Range* ranges);
+ //! selects a submatrix, n-dim version
+ Mat_(const Mat_& m, const std::vector<Range>& ranges);
+ //! from a matrix expression
+ explicit Mat_(const MatExpr& e);
+ //! makes a matrix out of Vec, std::vector, Point_ or Point3_. The matrix will have a single column
+ explicit Mat_(const std::vector<_Tp>& vec, bool copyData=false);
+ template<int n> explicit Mat_(const Vec<typename DataType<_Tp>::channel_type, n>& vec, bool copyData=true);
+ template<int m, int n> explicit Mat_(const Matx<typename DataType<_Tp>::channel_type, m, n>& mtx, bool copyData=true);
+ explicit Mat_(const Point_<typename DataType<_Tp>::channel_type>& pt, bool copyData=true);
+ explicit Mat_(const Point3_<typename DataType<_Tp>::channel_type>& pt, bool copyData=true);
+ explicit Mat_(const MatCommaInitializer_<_Tp>& commaInitializer);
+
+ Mat_& operator = (const Mat& m);
+ Mat_& operator = (const Mat_& m);
+ //! set all the elements to s.
+ Mat_& operator = (const _Tp& s);
+ //! assign a matrix expression
+ Mat_& operator = (const MatExpr& e);
+
+ //! iterators; they are smart enough to skip gaps in the end of rows
+ iterator begin();
+ iterator end();
+ const_iterator begin() const;
+ const_iterator end() const;
+
+ //! template methods for for operation over all matrix elements.
+ // the operations take care of skipping gaps in the end of rows (if any)
+ template<typename Functor> void forEach(const Functor& operation);
+ template<typename Functor> void forEach(const Functor& operation) const;
+
+ //! equivalent to Mat::create(_rows, _cols, DataType<_Tp>::type)
+ void create(int _rows, int _cols);
+ //! equivalent to Mat::create(_size, DataType<_Tp>::type)
+ void create(Size _size);
+ //! equivalent to Mat::create(_ndims, _sizes, DatType<_Tp>::type)
+ void create(int _ndims, const int* _sizes);
+ //! cross-product
+ Mat_ cross(const Mat_& m) const;
+ //! data type conversion
+ template<typename T2> operator Mat_<T2>() const;
+ //! overridden forms of Mat::row() etc.
+ Mat_ row(int y) const;
+ Mat_ col(int x) const;
+ Mat_ diag(int d=0) const;
+ Mat_ clone() const;
+
+ //! overridden forms of Mat::elemSize() etc.
+ size_t elemSize() const;
+ size_t elemSize1() const;
+ int type() const;
+ int depth() const;
+ int channels() const;
+ size_t step1(int i=0) const;
+ //! returns step()/sizeof(_Tp)
+ size_t stepT(int i=0) const;
+
+ //! overridden forms of Mat::zeros() etc. Data type is omitted, of course
+ static MatExpr zeros(int rows, int cols);
+ static MatExpr zeros(Size size);
+ static MatExpr zeros(int _ndims, const int* _sizes);
+ static MatExpr ones(int rows, int cols);
+ static MatExpr ones(Size size);
+ static MatExpr ones(int _ndims, const int* _sizes);
+ static MatExpr eye(int rows, int cols);
+ static MatExpr eye(Size size);
+
+ //! some more overriden methods
+ Mat_& adjustROI( int dtop, int dbottom, int dleft, int dright );
+ Mat_ operator()( const Range& rowRange, const Range& colRange ) const;
+ Mat_ operator()( const Rect& roi ) const;
+ Mat_ operator()( const Range* ranges ) const;
+ Mat_ operator()(const std::vector<Range>& ranges) const;
+
+ //! more convenient forms of row and element access operators
+ _Tp* operator [](int y);
+ const _Tp* operator [](int y) const;
+
+ //! returns reference to the specified element
+ _Tp& operator ()(const int* idx);
+ //! returns read-only reference to the specified element
+ const _Tp& operator ()(const int* idx) const;
+
+ //! returns reference to the specified element
+ template<int n> _Tp& operator ()(const Vec<int, n>& idx);
+ //! returns read-only reference to the specified element
+ template<int n> const _Tp& operator ()(const Vec<int, n>& idx) const;
+
+ //! returns reference to the specified element (1D case)
+ _Tp& operator ()(int idx0);
+ //! returns read-only reference to the specified element (1D case)
+ const _Tp& operator ()(int idx0) const;
+ //! returns reference to the specified element (2D case)
+ _Tp& operator ()(int row, int col);
+ //! returns read-only reference to the specified element (2D case)
+ const _Tp& operator ()(int row, int col) const;
+ //! returns reference to the specified element (3D case)
+ _Tp& operator ()(int idx0, int idx1, int idx2);
+ //! returns read-only reference to the specified element (3D case)
+ const _Tp& operator ()(int idx0, int idx1, int idx2) const;
+
+ _Tp& operator ()(Point pt);
+ const _Tp& operator ()(Point pt) const;
+
+ //! conversion to vector.
+ operator std::vector<_Tp>() const;
+ //! conversion to Vec
+ template<int n> operator Vec<typename DataType<_Tp>::channel_type, n>() const;
+ //! conversion to Matx
+ template<int m, int n> operator Matx<typename DataType<_Tp>::channel_type, m, n>() const;
+
+#ifdef CV_CXX_MOVE_SEMANTICS
+ Mat_(Mat_&& m);
+ Mat_& operator = (Mat_&& m);
+
+ Mat_(Mat&& m);
+ Mat_& operator = (Mat&& m);
+
+ Mat_(MatExpr&& e);
+#endif
+};
+
+typedef Mat_<uchar> Mat1b;
+typedef Mat_<Vec2b> Mat2b;
+typedef Mat_<Vec3b> Mat3b;
+typedef Mat_<Vec4b> Mat4b;
+
+typedef Mat_<short> Mat1s;
+typedef Mat_<Vec2s> Mat2s;
+typedef Mat_<Vec3s> Mat3s;
+typedef Mat_<Vec4s> Mat4s;
+
+typedef Mat_<ushort> Mat1w;
+typedef Mat_<Vec2w> Mat2w;
+typedef Mat_<Vec3w> Mat3w;
+typedef Mat_<Vec4w> Mat4w;
+
+typedef Mat_<int> Mat1i;
+typedef Mat_<Vec2i> Mat2i;
+typedef Mat_<Vec3i> Mat3i;
+typedef Mat_<Vec4i> Mat4i;
+
+typedef Mat_<float> Mat1f;
+typedef Mat_<Vec2f> Mat2f;
+typedef Mat_<Vec3f> Mat3f;
+typedef Mat_<Vec4f> Mat4f;
+
+typedef Mat_<double> Mat1d;
+typedef Mat_<Vec2d> Mat2d;
+typedef Mat_<Vec3d> Mat3d;
+typedef Mat_<Vec4d> Mat4d;
+
+/** @todo document */
+class CV_EXPORTS UMat
+{
+public:
+ //! default constructor
+ UMat(UMatUsageFlags usageFlags = USAGE_DEFAULT);
+ //! constructs 2D matrix of the specified size and type
+ // (_type is CV_8UC1, CV_64FC3, CV_32SC(12) etc.)
+ UMat(int rows, int cols, int type, UMatUsageFlags usageFlags = USAGE_DEFAULT);
+ UMat(Size size, int type, UMatUsageFlags usageFlags = USAGE_DEFAULT);
+ //! constucts 2D matrix and fills it with the specified value _s.
+ UMat(int rows, int cols, int type, const Scalar& s, UMatUsageFlags usageFlags = USAGE_DEFAULT);
+ UMat(Size size, int type, const Scalar& s, UMatUsageFlags usageFlags = USAGE_DEFAULT);
+
+ //! constructs n-dimensional matrix
+ UMat(int ndims, const int* sizes, int type, UMatUsageFlags usageFlags = USAGE_DEFAULT);
+ UMat(int ndims, const int* sizes, int type, const Scalar& s, UMatUsageFlags usageFlags = USAGE_DEFAULT);
+
+ //! copy constructor
+ UMat(const UMat& m);
+
+ //! creates a matrix header for a part of the bigger matrix
+ UMat(const UMat& m, const Range& rowRange, const Range& colRange=Range::all());
+ UMat(const UMat& m, const Rect& roi);
+ UMat(const UMat& m, const Range* ranges);
+ UMat(const UMat& m, const std::vector<Range>& ranges);
+ //! builds matrix from std::vector with or without copying the data
+ template<typename _Tp> explicit UMat(const std::vector<_Tp>& vec, bool copyData=false);
+ //! builds matrix from cv::Vec; the data is copied by default
+ template<typename _Tp, int n> explicit UMat(const Vec<_Tp, n>& vec, bool copyData=true);
+ //! builds matrix from cv::Matx; the data is copied by default
+ template<typename _Tp, int m, int n> explicit UMat(const Matx<_Tp, m, n>& mtx, bool copyData=true);
+ //! builds matrix from a 2D point
+ template<typename _Tp> explicit UMat(const Point_<_Tp>& pt, bool copyData=true);
+ //! builds matrix from a 3D point
+ template<typename _Tp> explicit UMat(const Point3_<_Tp>& pt, bool copyData=true);
+ //! builds matrix from comma initializer
+ template<typename _Tp> explicit UMat(const MatCommaInitializer_<_Tp>& commaInitializer);
+
+ //! destructor - calls release()
+ ~UMat();
+ //! assignment operators
+ UMat& operator = (const UMat& m);
+
+ Mat getMat(int flags) const;
+
+ //! returns a new matrix header for the specified row
+ UMat row(int y) const;
+ //! returns a new matrix header for the specified column
+ UMat col(int x) const;
+ //! ... for the specified row span
+ UMat rowRange(int startrow, int endrow) const;
+ UMat rowRange(const Range& r) const;
+ //! ... for the specified column span
+ UMat colRange(int startcol, int endcol) const;
+ UMat colRange(const Range& r) const;
+ //! ... for the specified diagonal
+ // (d=0 - the main diagonal,
+ // >0 - a diagonal from the lower half,
+ // <0 - a diagonal from the upper half)
+ UMat diag(int d=0) const;
+ //! constructs a square diagonal matrix which main diagonal is vector "d"
+ static UMat diag(const UMat& d);
+
+ //! returns deep copy of the matrix, i.e. the data is copied
+ UMat clone() const;
+ //! copies the matrix content to "m".
+ // It calls m.create(this->size(), this->type()).
+ void copyTo( OutputArray m ) const;
+ //! copies those matrix elements to "m" that are marked with non-zero mask elements.
+ void copyTo( OutputArray m, InputArray mask ) const;
+ //! converts matrix to another datatype with optional scalng. See cvConvertScale.
+ void convertTo( OutputArray m, int rtype, double alpha=1, double beta=0 ) const;
+
+ void assignTo( UMat& m, int type=-1 ) const;
+
+ //! sets every matrix element to s
+ UMat& operator = (const Scalar& s);
+ //! sets some of the matrix elements to s, according to the mask
+ UMat& setTo(InputArray value, InputArray mask=noArray());
+ //! creates alternative matrix header for the same data, with different
+ // number of channels and/or different number of rows. see cvReshape.
+ UMat reshape(int cn, int rows=0) const;
+ UMat reshape(int cn, int newndims, const int* newsz) const;
+
+ //! matrix transposition by means of matrix expressions
+ UMat t() const;
+ //! matrix inversion by means of matrix expressions
+ UMat inv(int method=DECOMP_LU) const;
+ //! per-element matrix multiplication by means of matrix expressions
+ UMat mul(InputArray m, double scale=1) const;
+
+ //! computes dot-product
+ double dot(InputArray m) const;
+
+ //! Matlab-style matrix initialization
+ static UMat zeros(int rows, int cols, int type);
+ static UMat zeros(Size size, int type);
+ static UMat zeros(int ndims, const int* sz, int type);
+ static UMat ones(int rows, int cols, int type);
+ static UMat ones(Size size, int type);
+ static UMat ones(int ndims, const int* sz, int type);
+ static UMat eye(int rows, int cols, int type);
+ static UMat eye(Size size, int type);
+
+ //! allocates new matrix data unless the matrix already has specified size and type.
+ // previous data is unreferenced if needed.
+ void create(int rows, int cols, int type, UMatUsageFlags usageFlags = USAGE_DEFAULT);
+ void create(Size size, int type, UMatUsageFlags usageFlags = USAGE_DEFAULT);
+ void create(int ndims, const int* sizes, int type, UMatUsageFlags usageFlags = USAGE_DEFAULT);
+ void create(const std::vector<int>& sizes, int type, UMatUsageFlags usageFlags = USAGE_DEFAULT);
+
+ //! increases the reference counter; use with care to avoid memleaks
+ void addref();
+ //! decreases reference counter;
+ // deallocates the data when reference counter reaches 0.
+ void release();
+
+ //! deallocates the matrix data
+ void deallocate();
+ //! internal use function; properly re-allocates _size, _step arrays
+ void copySize(const UMat& m);
+
+ //! locates matrix header within a parent matrix. See below
+ void locateROI( Size& wholeSize, Point& ofs ) const;
+ //! moves/resizes the current matrix ROI inside the parent matrix.
+ UMat& adjustROI( int dtop, int dbottom, int dleft, int dright );
+ //! extracts a rectangular sub-matrix
+ // (this is a generalized form of row, rowRange etc.)
+ UMat operator()( Range rowRange, Range colRange ) const;
+ UMat operator()( const Rect& roi ) const;
+ UMat operator()( const Range* ranges ) const;
+ UMat operator()(const std::vector<Range>& ranges) const;
+
+ //! returns true iff the matrix data is continuous
+ // (i.e. when there are no gaps between successive rows).
+ // similar to CV_IS_MAT_CONT(cvmat->type)
+ bool isContinuous() const;
+
+ //! returns true if the matrix is a submatrix of another matrix
+ bool isSubmatrix() const;
+
+ //! returns element size in bytes,
+ // similar to CV_ELEM_SIZE(cvmat->type)
+ size_t elemSize() const;
+ //! returns the size of element channel in bytes.
+ size_t elemSize1() const;
+ //! returns element type, similar to CV_MAT_TYPE(cvmat->type)
+ int type() const;
+ //! returns element type, similar to CV_MAT_DEPTH(cvmat->type)
+ int depth() const;
+ //! returns element type, similar to CV_MAT_CN(cvmat->type)
+ int channels() const;
+ //! returns step/elemSize1()
+ size_t step1(int i=0) const;
+ //! returns true if matrix data is NULL
+ bool empty() const;
+ //! returns the total number of matrix elements
+ size_t total() const;
+
+ //! returns N if the matrix is 1-channel (N x ptdim) or ptdim-channel (1 x N) or (N x 1); negative number otherwise
+ int checkVector(int elemChannels, int depth=-1, bool requireContinuous=true) const;
+
+#ifdef CV_CXX_MOVE_SEMANTICS
+ UMat(UMat&& m);
+ UMat& operator = (UMat&& m);
+#endif
+
+ void* handle(int accessFlags) const;
+ void ndoffset(size_t* ofs) const;
+
+ enum { MAGIC_VAL = 0x42FF0000, AUTO_STEP = 0, CONTINUOUS_FLAG = CV_MAT_CONT_FLAG, SUBMATRIX_FLAG = CV_SUBMAT_FLAG };
+ enum { MAGIC_MASK = 0xFFFF0000, TYPE_MASK = 0x00000FFF, DEPTH_MASK = 7 };
+
+ /*! includes several bit-fields:
+ - the magic signature
+ - continuity flag
+ - depth
+ - number of channels
+ */
+ int flags;
+ //! the matrix dimensionality, >= 2
+ int dims;
+ //! the number of rows and columns or (-1, -1) when the matrix has more than 2 dimensions
+ int rows, cols;
+
+ //! custom allocator
+ MatAllocator* allocator;
+ UMatUsageFlags usageFlags; // usage flags for allocator
+ //! and the standard allocator
+ static MatAllocator* getStdAllocator();
+
+ // black-box container of UMat data
+ UMatData* u;
+
+ // offset of the submatrix (or 0)
+ size_t offset;
+
+ MatSize size;
+ MatStep step;
+
+protected:
+};
+
+
+/////////////////////////// multi-dimensional sparse matrix //////////////////////////
+
+/** @brief The class SparseMat represents multi-dimensional sparse numerical arrays.
+
+Such a sparse array can store elements of any type that Mat can store. *Sparse* means that only
+non-zero elements are stored (though, as a result of operations on a sparse matrix, some of its
+stored elements can actually become 0. It is up to you to detect such elements and delete them
+using SparseMat::erase ). The non-zero elements are stored in a hash table that grows when it is
+filled so that the search time is O(1) in average (regardless of whether element is there or not).
+Elements can be accessed using the following methods:
+- Query operations (SparseMat::ptr and the higher-level SparseMat::ref, SparseMat::value and
+ SparseMat::find), for example:
+ @code
+ const int dims = 5;
+ int size[5] = {10, 10, 10, 10, 10};
+ SparseMat sparse_mat(dims, size, CV_32F);
+ for(int i = 0; i < 1000; i++)
+ {
+ int idx[dims];
+ for(int k = 0; k < dims; k++)
+ idx[k] = rand() % size[k];
+ sparse_mat.ref<float>(idx) += 1.f;
+ }
+ cout << "nnz = " << sparse_mat.nzcount() << endl;
+ @endcode
+- Sparse matrix iterators. They are similar to MatIterator but different from NAryMatIterator.
+ That is, the iteration loop is familiar to STL users:
+ @code
+ // prints elements of a sparse floating-point matrix
+ // and the sum of elements.
+ SparseMatConstIterator_<float>
+ it = sparse_mat.begin<float>(),
+ it_end = sparse_mat.end<float>();
+ double s = 0;
+ int dims = sparse_mat.dims();
+ for(; it != it_end; ++it)
+ {
+ // print element indices and the element value
+ const SparseMat::Node* n = it.node();
+ printf("(");
+ for(int i = 0; i < dims; i++)
+ printf("%d%s", n->idx[i], i < dims-1 ? ", " : ")");
+ printf(": %g\n", it.value<float>());
+ s += *it;
+ }
+ printf("Element sum is %g\n", s);
+ @endcode
+ If you run this loop, you will notice that elements are not enumerated in a logical order
+ (lexicographical, and so on). They come in the same order as they are stored in the hash table
+ (semi-randomly). You may collect pointers to the nodes and sort them to get the proper ordering.
+ Note, however, that pointers to the nodes may become invalid when you add more elements to the
+ matrix. This may happen due to possible buffer reallocation.
+- Combination of the above 2 methods when you need to process 2 or more sparse matrices
+ simultaneously. For example, this is how you can compute unnormalized cross-correlation of the 2
+ floating-point sparse matrices:
+ @code
+ double cross_corr(const SparseMat& a, const SparseMat& b)
+ {
+ const SparseMat *_a = &a, *_b = &b;
+ // if b contains less elements than a,
+ // it is faster to iterate through b
+ if(_a->nzcount() > _b->nzcount())
+ std::swap(_a, _b);
+ SparseMatConstIterator_<float> it = _a->begin<float>(),
+ it_end = _a->end<float>();
+ double ccorr = 0;
+ for(; it != it_end; ++it)
+ {
+ // take the next element from the first matrix
+ float avalue = *it;
+ const Node* anode = it.node();
+ // and try to find an element with the same index in the second matrix.
+ // since the hash value depends only on the element index,
+ // reuse the hash value stored in the node
+ float bvalue = _b->value<float>(anode->idx,&anode->hashval);
+ ccorr += avalue*bvalue;
+ }
+ return ccorr;
+ }
+ @endcode
+ */
+class CV_EXPORTS SparseMat
+{
+public:
+ typedef SparseMatIterator iterator;
+ typedef SparseMatConstIterator const_iterator;
+
+ enum { MAGIC_VAL=0x42FD0000, MAX_DIM=32, HASH_SCALE=0x5bd1e995, HASH_BIT=0x80000000 };
+
+ //! the sparse matrix header
+ struct CV_EXPORTS Hdr
+ {
+ Hdr(int _dims, const int* _sizes, int _type);
+ void clear();
+ int refcount;
+ int dims;
+ int valueOffset;
+ size_t nodeSize;
+ size_t nodeCount;
+ size_t freeList;
+ std::vector<uchar> pool;
+ std::vector<size_t> hashtab;
+ int size[MAX_DIM];
+ };
+
+ //! sparse matrix node - element of a hash table
+ struct CV_EXPORTS Node
+ {
+ //! hash value
+ size_t hashval;
+ //! index of the next node in the same hash table entry
+ size_t next;
+ //! index of the matrix element
+ int idx[MAX_DIM];
+ };
+
+ /** @brief Various SparseMat constructors.
+ */
+ SparseMat();
+
+ /** @overload
+ @param dims Array dimensionality.
+ @param _sizes Sparce matrix size on all dementions.
+ @param _type Sparse matrix data type.
+ */
+ SparseMat(int dims, const int* _sizes, int _type);
+
+ /** @overload
+ @param m Source matrix for copy constructor. If m is dense matrix (ocvMat) then it will be converted
+ to sparse representation.
+ */
+ SparseMat(const SparseMat& m);
+
+ /** @overload
+ @param m Source matrix for copy constructor. If m is dense matrix (ocvMat) then it will be converted
+ to sparse representation.
+ */
+ explicit SparseMat(const Mat& m);
+
+ //! the destructor
+ ~SparseMat();
+
+ //! assignment operator. This is O(1) operation, i.e. no data is copied
+ SparseMat& operator = (const SparseMat& m);
+ //! equivalent to the corresponding constructor
+ SparseMat& operator = (const Mat& m);
+
+ //! creates full copy of the matrix
+ SparseMat clone() const;
+
+ //! copies all the data to the destination matrix. All the previous content of m is erased
+ void copyTo( SparseMat& m ) const;
+ //! converts sparse matrix to dense matrix.
+ void copyTo( Mat& m ) const;
+ //! multiplies all the matrix elements by the specified scale factor alpha and converts the results to the specified data type
+ void convertTo( SparseMat& m, int rtype, double alpha=1 ) const;
+ //! converts sparse matrix to dense n-dim matrix with optional type conversion and scaling.
+ /*!
+ @param [out] m - output matrix; if it does not have a proper size or type before the operation,
+ it is reallocated
+ @param [in] rtype – desired output matrix type or, rather, the depth since the number of channels
+ are the same as the input has; if rtype is negative, the output matrix will have the
+ same type as the input.
+ @param [in] alpha – optional scale factor
+ @param [in] beta – optional delta added to the scaled values
+ */
+ void convertTo( Mat& m, int rtype, double alpha=1, double beta=0 ) const;
+
+ // not used now
+ void assignTo( SparseMat& m, int type=-1 ) const;
+
+ //! reallocates sparse matrix.
+ /*!
+ If the matrix already had the proper size and type,
+ it is simply cleared with clear(), otherwise,
+ the old matrix is released (using release()) and the new one is allocated.
+ */
+ void create(int dims, const int* _sizes, int _type);
+ //! sets all the sparse matrix elements to 0, which means clearing the hash table.
+ void clear();
+ //! manually increments the reference counter to the header.
+ void addref();
+ // decrements the header reference counter. When the counter reaches 0, the header and all the underlying data are deallocated.
+ void release();
+
+ //! converts sparse matrix to the old-style representation; all the elements are copied.
+ //operator CvSparseMat*() const;
+ //! returns the size of each element in bytes (not including the overhead - the space occupied by SparseMat::Node elements)
+ size_t elemSize() const;
+ //! returns elemSize()/channels()
+ size_t elemSize1() const;
+
+ //! returns type of sparse matrix elements
+ int type() const;
+ //! returns the depth of sparse matrix elements
+ int depth() const;
+ //! returns the number of channels
+ int channels() const;
+
+ //! returns the array of sizes, or NULL if the matrix is not allocated
+ const int* size() const;
+ //! returns the size of i-th matrix dimension (or 0)
+ int size(int i) const;
+ //! returns the matrix dimensionality
+ int dims() const;
+ //! returns the number of non-zero elements (=the number of hash table nodes)
+ size_t nzcount() const;
+
+ //! computes the element hash value (1D case)
+ size_t hash(int i0) const;
+ //! computes the element hash value (2D case)
+ size_t hash(int i0, int i1) const;
+ //! computes the element hash value (3D case)
+ size_t hash(int i0, int i1, int i2) const;
+ //! computes the element hash value (nD case)
+ size_t hash(const int* idx) const;
+
+ //!@{
+ /*!
+ specialized variants for 1D, 2D, 3D cases and the generic_type one for n-D case.
+ return pointer to the matrix element.
+ - if the element is there (it's non-zero), the pointer to it is returned
+ - if it's not there and createMissing=false, NULL pointer is returned
+ - if it's not there and createMissing=true, then the new element
+ is created and initialized with 0. Pointer to it is returned
+ - if the optional hashval pointer is not NULL, the element hash value is
+ not computed, but *hashval is taken instead.
+ */
+ //! returns pointer to the specified element (1D case)
+ uchar* ptr(int i0, bool createMissing, size_t* hashval=0);
+ //! returns pointer to the specified element (2D case)
+ uchar* ptr(int i0, int i1, bool createMissing, size_t* hashval=0);
+ //! returns pointer to the specified element (3D case)
+ uchar* ptr(int i0, int i1, int i2, bool createMissing, size_t* hashval=0);
+ //! returns pointer to the specified element (nD case)
+ uchar* ptr(const int* idx, bool createMissing, size_t* hashval=0);
+ //!@}
+
+ //!@{
+ /*!
+ return read-write reference to the specified sparse matrix element.
+
+ `ref<_Tp>(i0,...[,hashval])` is equivalent to `*(_Tp*)ptr(i0,...,true[,hashval])`.
+ The methods always return a valid reference.
+ If the element did not exist, it is created and initialiazed with 0.
+ */
+ //! returns reference to the specified element (1D case)
+ template<typename _Tp> _Tp& ref(int i0, size_t* hashval=0);
+ //! returns reference to the specified element (2D case)
+ template<typename _Tp> _Tp& ref(int i0, int i1, size_t* hashval=0);
+ //! returns reference to the specified element (3D case)
+ template<typename _Tp> _Tp& ref(int i0, int i1, int i2, size_t* hashval=0);
+ //! returns reference to the specified element (nD case)
+ template<typename _Tp> _Tp& ref(const int* idx, size_t* hashval=0);
+ //!@}
+
+ //!@{
+ /*!
+ return value of the specified sparse matrix element.
+
+ `value<_Tp>(i0,...[,hashval])` is equivalent to
+ @code
+ { const _Tp* p = find<_Tp>(i0,...[,hashval]); return p ? *p : _Tp(); }
+ @endcode
+
+ That is, if the element did not exist, the methods return 0.
+ */
+ //! returns value of the specified element (1D case)
+ template<typename _Tp> _Tp value(int i0, size_t* hashval=0) const;
+ //! returns value of the specified element (2D case)
+ template<typename _Tp> _Tp value(int i0, int i1, size_t* hashval=0) const;
+ //! returns value of the specified element (3D case)
+ template<typename _Tp> _Tp value(int i0, int i1, int i2, size_t* hashval=0) const;
+ //! returns value of the specified element (nD case)
+ template<typename _Tp> _Tp value(const int* idx, size_t* hashval=0) const;
+ //!@}
+
+ //!@{
+ /*!
+ Return pointer to the specified sparse matrix element if it exists
+
+ `find<_Tp>(i0,...[,hashval])` is equivalent to `(_const Tp*)ptr(i0,...false[,hashval])`.
+
+ If the specified element does not exist, the methods return NULL.
+ */
+ //! returns pointer to the specified element (1D case)
+ template<typename _Tp> const _Tp* find(int i0, size_t* hashval=0) const;
+ //! returns pointer to the specified element (2D case)
+ template<typename _Tp> const _Tp* find(int i0, int i1, size_t* hashval=0) const;
+ //! returns pointer to the specified element (3D case)
+ template<typename _Tp> const _Tp* find(int i0, int i1, int i2, size_t* hashval=0) const;
+ //! returns pointer to the specified element (nD case)
+ template<typename _Tp> const _Tp* find(const int* idx, size_t* hashval=0) const;
+ //!@}
+
+ //! erases the specified element (2D case)
+ void erase(int i0, int i1, size_t* hashval=0);
+ //! erases the specified element (3D case)
+ void erase(int i0, int i1, int i2, size_t* hashval=0);
+ //! erases the specified element (nD case)
+ void erase(const int* idx, size_t* hashval=0);
+
+ //!@{
+ /*!
+ return the sparse matrix iterator pointing to the first sparse matrix element
+ */
+ //! returns the sparse matrix iterator at the matrix beginning
+ SparseMatIterator begin();
+ //! returns the sparse matrix iterator at the matrix beginning
+ template<typename _Tp> SparseMatIterator_<_Tp> begin();
+ //! returns the read-only sparse matrix iterator at the matrix beginning
+ SparseMatConstIterator begin() const;
+ //! returns the read-only sparse matrix iterator at the matrix beginning
+ template<typename _Tp> SparseMatConstIterator_<_Tp> begin() const;
+ //!@}
+ /*!
+ return the sparse matrix iterator pointing to the element following the last sparse matrix element
+ */
+ //! returns the sparse matrix iterator at the matrix end
+ SparseMatIterator end();
+ //! returns the read-only sparse matrix iterator at the matrix end
+ SparseMatConstIterator end() const;
+ //! returns the typed sparse matrix iterator at the matrix end
+ template<typename _Tp> SparseMatIterator_<_Tp> end();
+ //! returns the typed read-only sparse matrix iterator at the matrix end
+ template<typename _Tp> SparseMatConstIterator_<_Tp> end() const;
+
+ //! returns the value stored in the sparse martix node
+ template<typename _Tp> _Tp& value(Node* n);
+ //! returns the value stored in the sparse martix node
+ template<typename _Tp> const _Tp& value(const Node* n) const;
+
+ ////////////// some internal-use methods ///////////////
+ Node* node(size_t nidx);
+ const Node* node(size_t nidx) const;
+
+ uchar* newNode(const int* idx, size_t hashval);
+ void removeNode(size_t hidx, size_t nidx, size_t previdx);
+ void resizeHashTab(size_t newsize);
+
+ int flags;
+ Hdr* hdr;
+};
+
+
+
+///////////////////////////////// SparseMat_<_Tp> ////////////////////////////////////
+
+/** @brief Template sparse n-dimensional array class derived from SparseMat
+
+SparseMat_ is a thin wrapper on top of SparseMat created in the same way as Mat_ . It simplifies
+notation of some operations:
+@code
+ int sz[] = {10, 20, 30};
+ SparseMat_<double> M(3, sz);
+ ...
+ M.ref(1, 2, 3) = M(4, 5, 6) + M(7, 8, 9);
+@endcode
+ */
+template<typename _Tp> class SparseMat_ : public SparseMat
+{
+public:
+ typedef SparseMatIterator_<_Tp> iterator;
+ typedef SparseMatConstIterator_<_Tp> const_iterator;
+
+ //! the default constructor
+ SparseMat_();
+ //! the full constructor equivelent to SparseMat(dims, _sizes, DataType<_Tp>::type)
+ SparseMat_(int dims, const int* _sizes);
+ //! the copy constructor. If DataType<_Tp>.type != m.type(), the m elements are converted
+ SparseMat_(const SparseMat& m);
+ //! the copy constructor. This is O(1) operation - no data is copied
+ SparseMat_(const SparseMat_& m);
+ //! converts dense matrix to the sparse form
+ SparseMat_(const Mat& m);
+ //! converts the old-style sparse matrix to the C++ class. All the elements are copied
+ //SparseMat_(const CvSparseMat* m);
+ //! the assignment operator. If DataType<_Tp>.type != m.type(), the m elements are converted
+ SparseMat_& operator = (const SparseMat& m);
+ //! the assignment operator. This is O(1) operation - no data is copied
+ SparseMat_& operator = (const SparseMat_& m);
+ //! converts dense matrix to the sparse form
+ SparseMat_& operator = (const Mat& m);
+
+ //! makes full copy of the matrix. All the elements are duplicated
+ SparseMat_ clone() const;
+ //! equivalent to cv::SparseMat::create(dims, _sizes, DataType<_Tp>::type)
+ void create(int dims, const int* _sizes);
+ //! converts sparse matrix to the old-style CvSparseMat. All the elements are copied
+ //operator CvSparseMat*() const;
+
+ //! returns type of the matrix elements
+ int type() const;
+ //! returns depth of the matrix elements
+ int depth() const;
+ //! returns the number of channels in each matrix element
+ int channels() const;
+
+ //! equivalent to SparseMat::ref<_Tp>(i0, hashval)
+ _Tp& ref(int i0, size_t* hashval=0);
+ //! equivalent to SparseMat::ref<_Tp>(i0, i1, hashval)
+ _Tp& ref(int i0, int i1, size_t* hashval=0);
+ //! equivalent to SparseMat::ref<_Tp>(i0, i1, i2, hashval)
+ _Tp& ref(int i0, int i1, int i2, size_t* hashval=0);
+ //! equivalent to SparseMat::ref<_Tp>(idx, hashval)
+ _Tp& ref(const int* idx, size_t* hashval=0);
+
+ //! equivalent to SparseMat::value<_Tp>(i0, hashval)
+ _Tp operator()(int i0, size_t* hashval=0) const;
+ //! equivalent to SparseMat::value<_Tp>(i0, i1, hashval)
+ _Tp operator()(int i0, int i1, size_t* hashval=0) const;
+ //! equivalent to SparseMat::value<_Tp>(i0, i1, i2, hashval)
+ _Tp operator()(int i0, int i1, int i2, size_t* hashval=0) const;
+ //! equivalent to SparseMat::value<_Tp>(idx, hashval)
+ _Tp operator()(const int* idx, size_t* hashval=0) const;
+
+ //! returns sparse matrix iterator pointing to the first sparse matrix element
+ SparseMatIterator_<_Tp> begin();
+ //! returns read-only sparse matrix iterator pointing to the first sparse matrix element
+ SparseMatConstIterator_<_Tp> begin() const;
+ //! returns sparse matrix iterator pointing to the element following the last sparse matrix element
+ SparseMatIterator_<_Tp> end();
+ //! returns read-only sparse matrix iterator pointing to the element following the last sparse matrix element
+ SparseMatConstIterator_<_Tp> end() const;
+};
+
+
+
+////////////////////////////////// MatConstIterator //////////////////////////////////
+
+class CV_EXPORTS MatConstIterator
+{
+public:
+ typedef uchar* value_type;
+ typedef ptrdiff_t difference_type;
+ typedef const uchar** pointer;
+ typedef uchar* reference;
+
+#ifndef OPENCV_NOSTL
+ typedef std::random_access_iterator_tag iterator_category;
+#endif
+
+ //! default constructor
+ MatConstIterator();
+ //! constructor that sets the iterator to the beginning of the matrix
+ MatConstIterator(const Mat* _m);
+ //! constructor that sets the iterator to the specified element of the matrix
+ MatConstIterator(const Mat* _m, int _row, int _col=0);
+ //! constructor that sets the iterator to the specified element of the matrix
+ MatConstIterator(const Mat* _m, Point _pt);
+ //! constructor that sets the iterator to the specified element of the matrix
+ MatConstIterator(const Mat* _m, const int* _idx);
+ //! copy constructor
+ MatConstIterator(const MatConstIterator& it);
+
+ //! copy operator
+ MatConstIterator& operator = (const MatConstIterator& it);
+ //! returns the current matrix element
+ const uchar* operator *() const;
+ //! returns the i-th matrix element, relative to the current
+ const uchar* operator [](ptrdiff_t i) const;
+
+ //! shifts the iterator forward by the specified number of elements
+ MatConstIterator& operator += (ptrdiff_t ofs);
+ //! shifts the iterator backward by the specified number of elements
+ MatConstIterator& operator -= (ptrdiff_t ofs);
+ //! decrements the iterator
+ MatConstIterator& operator --();
+ //! decrements the iterator
+ MatConstIterator operator --(int);
+ //! increments the iterator
+ MatConstIterator& operator ++();
+ //! increments the iterator
+ MatConstIterator operator ++(int);
+ //! returns the current iterator position
+ Point pos() const;
+ //! returns the current iterator position
+ void pos(int* _idx) const;
+
+ ptrdiff_t lpos() const;
+ void seek(ptrdiff_t ofs, bool relative = false);
+ void seek(const int* _idx, bool relative = false);
+
+ const Mat* m;
+ size_t elemSize;
+ const uchar* ptr;
+ const uchar* sliceStart;
+ const uchar* sliceEnd;
+};
+
+
+
+////////////////////////////////// MatConstIterator_ /////////////////////////////////
+
+/** @brief Matrix read-only iterator
+ */
+template<typename _Tp>
+class MatConstIterator_ : public MatConstIterator
+{
+public:
+ typedef _Tp value_type;
+ typedef ptrdiff_t difference_type;
+ typedef const _Tp* pointer;
+ typedef const _Tp& reference;
+
+#ifndef OPENCV_NOSTL
+ typedef std::random_access_iterator_tag iterator_category;
+#endif
+
+ //! default constructor
+ MatConstIterator_();
+ //! constructor that sets the iterator to the beginning of the matrix
+ MatConstIterator_(const Mat_<_Tp>* _m);
+ //! constructor that sets the iterator to the specified element of the matrix
+ MatConstIterator_(const Mat_<_Tp>* _m, int _row, int _col=0);
+ //! constructor that sets the iterator to the specified element of the matrix
+ MatConstIterator_(const Mat_<_Tp>* _m, Point _pt);
+ //! constructor that sets the iterator to the specified element of the matrix
+ MatConstIterator_(const Mat_<_Tp>* _m, const int* _idx);
+ //! copy constructor
+ MatConstIterator_(const MatConstIterator_& it);
+
+ //! copy operator
+ MatConstIterator_& operator = (const MatConstIterator_& it);
+ //! returns the current matrix element
+ const _Tp& operator *() const;
+ //! returns the i-th matrix element, relative to the current
+ const _Tp& operator [](ptrdiff_t i) const;
+
+ //! shifts the iterator forward by the specified number of elements
+ MatConstIterator_& operator += (ptrdiff_t ofs);
+ //! shifts the iterator backward by the specified number of elements
+ MatConstIterator_& operator -= (ptrdiff_t ofs);
+ //! decrements the iterator
+ MatConstIterator_& operator --();
+ //! decrements the iterator
+ MatConstIterator_ operator --(int);
+ //! increments the iterator
+ MatConstIterator_& operator ++();
+ //! increments the iterator
+ MatConstIterator_ operator ++(int);
+ //! returns the current iterator position
+ Point pos() const;
+};
+
+
+
+//////////////////////////////////// MatIterator_ ////////////////////////////////////
+
+/** @brief Matrix read-write iterator
+*/
+template<typename _Tp>
+class MatIterator_ : public MatConstIterator_<_Tp>
+{
+public:
+ typedef _Tp* pointer;
+ typedef _Tp& reference;
+
+#ifndef OPENCV_NOSTL
+ typedef std::random_access_iterator_tag iterator_category;
+#endif
+
+ //! the default constructor
+ MatIterator_();
+ //! constructor that sets the iterator to the beginning of the matrix
+ MatIterator_(Mat_<_Tp>* _m);
+ //! constructor that sets the iterator to the specified element of the matrix
+ MatIterator_(Mat_<_Tp>* _m, int _row, int _col=0);
+ //! constructor that sets the iterator to the specified element of the matrix
+ MatIterator_(Mat_<_Tp>* _m, Point _pt);
+ //! constructor that sets the iterator to the specified element of the matrix
+ MatIterator_(Mat_<_Tp>* _m, const int* _idx);
+ //! copy constructor
+ MatIterator_(const MatIterator_& it);
+ //! copy operator
+ MatIterator_& operator = (const MatIterator_<_Tp>& it );
+
+ //! returns the current matrix element
+ _Tp& operator *() const;
+ //! returns the i-th matrix element, relative to the current
+ _Tp& operator [](ptrdiff_t i) const;
+
+ //! shifts the iterator forward by the specified number of elements
+ MatIterator_& operator += (ptrdiff_t ofs);
+ //! shifts the iterator backward by the specified number of elements
+ MatIterator_& operator -= (ptrdiff_t ofs);
+ //! decrements the iterator
+ MatIterator_& operator --();
+ //! decrements the iterator
+ MatIterator_ operator --(int);
+ //! increments the iterator
+ MatIterator_& operator ++();
+ //! increments the iterator
+ MatIterator_ operator ++(int);
+};
+
+
+
+/////////////////////////////// SparseMatConstIterator ///////////////////////////////
+
+/** @brief Read-Only Sparse Matrix Iterator.
+
+ Here is how to use the iterator to compute the sum of floating-point sparse matrix elements:
+
+ \code
+ SparseMatConstIterator it = m.begin(), it_end = m.end();
+ double s = 0;
+ CV_Assert( m.type() == CV_32F );
+ for( ; it != it_end; ++it )
+ s += it.value<float>();
+ \endcode
+*/
+class CV_EXPORTS SparseMatConstIterator
+{
+public:
+ //! the default constructor
+ SparseMatConstIterator();
+ //! the full constructor setting the iterator to the first sparse matrix element
+ SparseMatConstIterator(const SparseMat* _m);
+ //! the copy constructor
+ SparseMatConstIterator(const SparseMatConstIterator& it);
+
+ //! the assignment operator
+ SparseMatConstIterator& operator = (const SparseMatConstIterator& it);
+
+ //! template method returning the current matrix element
+ template<typename _Tp> const _Tp& value() const;
+ //! returns the current node of the sparse matrix. it.node->idx is the current element index
+ const SparseMat::Node* node() const;
+
+ //! moves iterator to the previous element
+ SparseMatConstIterator& operator --();
+ //! moves iterator to the previous element
+ SparseMatConstIterator operator --(int);
+ //! moves iterator to the next element
+ SparseMatConstIterator& operator ++();
+ //! moves iterator to the next element
+ SparseMatConstIterator operator ++(int);
+
+ //! moves iterator to the element after the last element
+ void seekEnd();
+
+ const SparseMat* m;
+ size_t hashidx;
+ uchar* ptr;
+};
+
+
+
+////////////////////////////////// SparseMatIterator /////////////////////////////////
+
+/** @brief Read-write Sparse Matrix Iterator
+
+ The class is similar to cv::SparseMatConstIterator,
+ but can be used for in-place modification of the matrix elements.
+*/
+class CV_EXPORTS SparseMatIterator : public SparseMatConstIterator
+{
+public:
+ //! the default constructor
+ SparseMatIterator();
+ //! the full constructor setting the iterator to the first sparse matrix element
+ SparseMatIterator(SparseMat* _m);
+ //! the full constructor setting the iterator to the specified sparse matrix element
+ SparseMatIterator(SparseMat* _m, const int* idx);
+ //! the copy constructor
+ SparseMatIterator(const SparseMatIterator& it);
+
+ //! the assignment operator
+ SparseMatIterator& operator = (const SparseMatIterator& it);
+ //! returns read-write reference to the current sparse matrix element
+ template<typename _Tp> _Tp& value() const;
+ //! returns pointer to the current sparse matrix node. it.node->idx is the index of the current element (do not modify it!)
+ SparseMat::Node* node() const;
+
+ //! moves iterator to the next element
+ SparseMatIterator& operator ++();
+ //! moves iterator to the next element
+ SparseMatIterator operator ++(int);
+};
+
+
+
+/////////////////////////////// SparseMatConstIterator_ //////////////////////////////
+
+/** @brief Template Read-Only Sparse Matrix Iterator Class.
+
+ This is the derived from SparseMatConstIterator class that
+ introduces more convenient operator *() for accessing the current element.
+*/
+template<typename _Tp> class SparseMatConstIterator_ : public SparseMatConstIterator
+{
+public:
+
+#ifndef OPENCV_NOSTL
+ typedef std::forward_iterator_tag iterator_category;
+#endif
+
+ //! the default constructor
+ SparseMatConstIterator_();
+ //! the full constructor setting the iterator to the first sparse matrix element
+ SparseMatConstIterator_(const SparseMat_<_Tp>* _m);
+ SparseMatConstIterator_(const SparseMat* _m);
+ //! the copy constructor
+ SparseMatConstIterator_(const SparseMatConstIterator_& it);
+
+ //! the assignment operator
+ SparseMatConstIterator_& operator = (const SparseMatConstIterator_& it);
+ //! the element access operator
+ const _Tp& operator *() const;
+
+ //! moves iterator to the next element
+ SparseMatConstIterator_& operator ++();
+ //! moves iterator to the next element
+ SparseMatConstIterator_ operator ++(int);
+};
+
+
+
+///////////////////////////////// SparseMatIterator_ /////////////////////////////////
+
+/** @brief Template Read-Write Sparse Matrix Iterator Class.
+
+ This is the derived from cv::SparseMatConstIterator_ class that
+ introduces more convenient operator *() for accessing the current element.
+*/
+template<typename _Tp> class SparseMatIterator_ : public SparseMatConstIterator_<_Tp>
+{
+public:
+
+#ifndef OPENCV_NOSTL
+ typedef std::forward_iterator_tag iterator_category;
+#endif
+
+ //! the default constructor
+ SparseMatIterator_();
+ //! the full constructor setting the iterator to the first sparse matrix element
+ SparseMatIterator_(SparseMat_<_Tp>* _m);
+ SparseMatIterator_(SparseMat* _m);
+ //! the copy constructor
+ SparseMatIterator_(const SparseMatIterator_& it);
+
+ //! the assignment operator
+ SparseMatIterator_& operator = (const SparseMatIterator_& it);
+ //! returns the reference to the current element
+ _Tp& operator *() const;
+
+ //! moves the iterator to the next element
+ SparseMatIterator_& operator ++();
+ //! moves the iterator to the next element
+ SparseMatIterator_ operator ++(int);
+};
+
+
+
+/////////////////////////////////// NAryMatIterator //////////////////////////////////
+
+/** @brief n-ary multi-dimensional array iterator.
+
+Use the class to implement unary, binary, and, generally, n-ary element-wise operations on
+multi-dimensional arrays. Some of the arguments of an n-ary function may be continuous arrays, some
+may be not. It is possible to use conventional MatIterator 's for each array but incrementing all of
+the iterators after each small operations may be a big overhead. In this case consider using
+NAryMatIterator to iterate through several matrices simultaneously as long as they have the same
+geometry (dimensionality and all the dimension sizes are the same). On each iteration `it.planes[0]`,
+`it.planes[1]`,... will be the slices of the corresponding matrices.
+
+The example below illustrates how you can compute a normalized and threshold 3D color histogram:
+@code
+ void computeNormalizedColorHist(const Mat& image, Mat& hist, int N, double minProb)
+ {
+ const int histSize[] = {N, N, N};
+
+ // make sure that the histogram has a proper size and type
+ hist.create(3, histSize, CV_32F);
+
+ // and clear it
+ hist = Scalar(0);
+
+ // the loop below assumes that the image
+ // is a 8-bit 3-channel. check it.
+ CV_Assert(image.type() == CV_8UC3);
+ MatConstIterator_<Vec3b> it = image.begin<Vec3b>(),
+ it_end = image.end<Vec3b>();
+ for( ; it != it_end; ++it )
+ {
+ const Vec3b& pix = *it;
+ hist.at<float>(pix[0]*N/256, pix[1]*N/256, pix[2]*N/256) += 1.f;
+ }
+
+ minProb *= image.rows*image.cols;
+
+ // initialize iterator (the style is different from STL).
+ // after initialization the iterator will contain
+ // the number of slices or planes the iterator will go through.
+ // it simultaneously increments iterators for several matrices
+ // supplied as a null terminated list of pointers
+ const Mat* arrays[] = {&hist, 0};
+ Mat planes[1];
+ NAryMatIterator itNAry(arrays, planes, 1);
+ double s = 0;
+ // iterate through the matrix. on each iteration
+ // itNAry.planes[i] (of type Mat) will be set to the current plane
+ // of the i-th n-dim matrix passed to the iterator constructor.
+ for(int p = 0; p < itNAry.nplanes; p++, ++itNAry)
+ {
+ threshold(itNAry.planes[0], itNAry.planes[0], minProb, 0, THRESH_TOZERO);
+ s += sum(itNAry.planes[0])[0];
+ }
+
+ s = 1./s;
+ itNAry = NAryMatIterator(arrays, planes, 1);
+ for(int p = 0; p < itNAry.nplanes; p++, ++itNAry)
+ itNAry.planes[0] *= s;
+ }
+@endcode
+ */
+class CV_EXPORTS NAryMatIterator
+{
+public:
+ //! the default constructor
+ NAryMatIterator();
+ //! the full constructor taking arbitrary number of n-dim matrices
+ NAryMatIterator(const Mat** arrays, uchar** ptrs, int narrays=-1);
+ //! the full constructor taking arbitrary number of n-dim matrices
+ NAryMatIterator(const Mat** arrays, Mat* planes, int narrays=-1);
+ //! the separate iterator initialization method
+ void init(const Mat** arrays, Mat* planes, uchar** ptrs, int narrays=-1);
+
+ //! proceeds to the next plane of every iterated matrix
+ NAryMatIterator& operator ++();
+ //! proceeds to the next plane of every iterated matrix (postfix increment operator)
+ NAryMatIterator operator ++(int);
+
+ //! the iterated arrays
+ const Mat** arrays;
+ //! the current planes
+ Mat* planes;
+ //! data pointers
+ uchar** ptrs;
+ //! the number of arrays
+ int narrays;
+ //! the number of hyper-planes that the iterator steps through
+ size_t nplanes;
+ //! the size of each segment (in elements)
+ size_t size;
+protected:
+ int iterdepth;
+ size_t idx;
+};
+
+
+
+///////////////////////////////// Matrix Expressions /////////////////////////////////
+
+class CV_EXPORTS MatOp
+{
+public:
+ MatOp();
+ virtual ~MatOp();
+
+ virtual bool elementWise(const MatExpr& expr) const;
+ virtual void assign(const MatExpr& expr, Mat& m, int type=-1) const = 0;
+ virtual void roi(const MatExpr& expr, const Range& rowRange,
+ const Range& colRange, MatExpr& res) const;
+ virtual void diag(const MatExpr& expr, int d, MatExpr& res) const;
+ virtual void augAssignAdd(const MatExpr& expr, Mat& m) const;
+ virtual void augAssignSubtract(const MatExpr& expr, Mat& m) const;
+ virtual void augAssignMultiply(const MatExpr& expr, Mat& m) const;
+ virtual void augAssignDivide(const MatExpr& expr, Mat& m) const;
+ virtual void augAssignAnd(const MatExpr& expr, Mat& m) const;
+ virtual void augAssignOr(const MatExpr& expr, Mat& m) const;
+ virtual void augAssignXor(const MatExpr& expr, Mat& m) const;
+
+ virtual void add(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res) const;
+ virtual void add(const MatExpr& expr1, const Scalar& s, MatExpr& res) const;
+
+ virtual void subtract(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res) const;
+ virtual void subtract(const Scalar& s, const MatExpr& expr, MatExpr& res) const;
+
+ virtual void multiply(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res, double scale=1) const;
+ virtual void multiply(const MatExpr& expr1, double s, MatExpr& res) const;
+
+ virtual void divide(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res, double scale=1) const;
+ virtual void divide(double s, const MatExpr& expr, MatExpr& res) const;
+
+ virtual void abs(const MatExpr& expr, MatExpr& res) const;
+
+ virtual void transpose(const MatExpr& expr, MatExpr& res) const;
+ virtual void matmul(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res) const;
+ virtual void invert(const MatExpr& expr, int method, MatExpr& res) const;
+
+ virtual Size size(const MatExpr& expr) const;
+ virtual int type(const MatExpr& expr) const;
+};
+
+/** @brief Matrix expression representation
+@anchor MatrixExpressions
+This is a list of implemented matrix operations that can be combined in arbitrary complex
+expressions (here A, B stand for matrices ( Mat ), s for a scalar ( Scalar ), alpha for a
+real-valued scalar ( double )):
+- Addition, subtraction, negation: `A+B`, `A-B`, `A+s`, `A-s`, `s+A`, `s-A`, `-A`
+- Scaling: `A*alpha`
+- Per-element multiplication and division: `A.mul(B)`, `A/B`, `alpha/A`
+- Matrix multiplication: `A*B`
+- Transposition: `A.t()` (means A<sup>T</sup>)
+- Matrix inversion and pseudo-inversion, solving linear systems and least-squares problems:
+ `A.inv([method]) (~ A<sup>-1</sup>)`, `A.inv([method])*B (~ X: AX=B)`
+- Comparison: `A cmpop B`, `A cmpop alpha`, `alpha cmpop A`, where *cmpop* is one of
+ `>`, `>=`, `==`, `!=`, `<=`, `<`. The result of comparison is an 8-bit single channel mask whose
+ elements are set to 255 (if the particular element or pair of elements satisfy the condition) or
+ 0.
+- Bitwise logical operations: `A logicop B`, `A logicop s`, `s logicop A`, `~A`, where *logicop* is one of
+ `&`, `|`, `^`.
+- Element-wise minimum and maximum: `min(A, B)`, `min(A, alpha)`, `max(A, B)`, `max(A, alpha)`
+- Element-wise absolute value: `abs(A)`
+- Cross-product, dot-product: `A.cross(B)`, `A.dot(B)`
+- Any function of matrix or matrices and scalars that returns a matrix or a scalar, such as norm,
+ mean, sum, countNonZero, trace, determinant, repeat, and others.
+- Matrix initializers ( Mat::eye(), Mat::zeros(), Mat::ones() ), matrix comma-separated
+ initializers, matrix constructors and operators that extract sub-matrices (see Mat description).
+- Mat_<destination_type>() constructors to cast the result to the proper type.
+@note Comma-separated initializers and probably some other operations may require additional
+explicit Mat() or Mat_<T>() constructor calls to resolve a possible ambiguity.
+
+Here are examples of matrix expressions:
+@code
+ // compute pseudo-inverse of A, equivalent to A.inv(DECOMP_SVD)
+ SVD svd(A);
+ Mat pinvA = svd.vt.t()*Mat::diag(1./svd.w)*svd.u.t();
+
+ // compute the new vector of parameters in the Levenberg-Marquardt algorithm
+ x -= (A.t()*A + lambda*Mat::eye(A.cols,A.cols,A.type())).inv(DECOMP_CHOLESKY)*(A.t()*err);
+
+ // sharpen image using "unsharp mask" algorithm
+ Mat blurred; double sigma = 1, threshold = 5, amount = 1;
+ GaussianBlur(img, blurred, Size(), sigma, sigma);
+ Mat lowContrastMask = abs(img - blurred) < threshold;
+ Mat sharpened = img*(1+amount) + blurred*(-amount);
+ img.copyTo(sharpened, lowContrastMask);
+@endcode
+*/
+class CV_EXPORTS MatExpr
+{
+public:
+ MatExpr();
+ explicit MatExpr(const Mat& m);
+
+ MatExpr(const MatOp* _op, int _flags, const Mat& _a = Mat(), const Mat& _b = Mat(),
+ const Mat& _c = Mat(), double _alpha = 1, double _beta = 1, const Scalar& _s = Scalar());
+
+ operator Mat() const;
+ template<typename _Tp> operator Mat_<_Tp>() const;
+
+ Size size() const;
+ int type() const;
+
+ MatExpr row(int y) const;
+ MatExpr col(int x) const;
+ MatExpr diag(int d = 0) const;
+ MatExpr operator()( const Range& rowRange, const Range& colRange ) const;
+ MatExpr operator()( const Rect& roi ) const;
+
+ MatExpr t() const;
+ MatExpr inv(int method = DECOMP_LU) const;
+ MatExpr mul(const MatExpr& e, double scale=1) const;
+ MatExpr mul(const Mat& m, double scale=1) const;
+
+ Mat cross(const Mat& m) const;
+ double dot(const Mat& m) const;
+
+ const MatOp* op;
+ int flags;
+
+ Mat a, b, c;
+ double alpha, beta;
+ Scalar s;
+};
+
+//! @} core_basic
+
+//! @relates cv::MatExpr
+//! @{
+CV_EXPORTS MatExpr operator + (const Mat& a, const Mat& b);
+CV_EXPORTS MatExpr operator + (const Mat& a, const Scalar& s);
+CV_EXPORTS MatExpr operator + (const Scalar& s, const Mat& a);
+CV_EXPORTS MatExpr operator + (const MatExpr& e, const Mat& m);
+CV_EXPORTS MatExpr operator + (const Mat& m, const MatExpr& e);
+CV_EXPORTS MatExpr operator + (const MatExpr& e, const Scalar& s);
+CV_EXPORTS MatExpr operator + (const Scalar& s, const MatExpr& e);
+CV_EXPORTS MatExpr operator + (const MatExpr& e1, const MatExpr& e2);
+
+CV_EXPORTS MatExpr operator - (const Mat& a, const Mat& b);
+CV_EXPORTS MatExpr operator - (const Mat& a, const Scalar& s);
+CV_EXPORTS MatExpr operator - (const Scalar& s, const Mat& a);
+CV_EXPORTS MatExpr operator - (const MatExpr& e, const Mat& m);
+CV_EXPORTS MatExpr operator - (const Mat& m, const MatExpr& e);
+CV_EXPORTS MatExpr operator - (const MatExpr& e, const Scalar& s);
+CV_EXPORTS MatExpr operator - (const Scalar& s, const MatExpr& e);
+CV_EXPORTS MatExpr operator - (const MatExpr& e1, const MatExpr& e2);
+
+CV_EXPORTS MatExpr operator - (const Mat& m);
+CV_EXPORTS MatExpr operator - (const MatExpr& e);
+
+CV_EXPORTS MatExpr operator * (const Mat& a, const Mat& b);
+CV_EXPORTS MatExpr operator * (const Mat& a, double s);
+CV_EXPORTS MatExpr operator * (double s, const Mat& a);
+CV_EXPORTS MatExpr operator * (const MatExpr& e, const Mat& m);
+CV_EXPORTS MatExpr operator * (const Mat& m, const MatExpr& e);
+CV_EXPORTS MatExpr operator * (const MatExpr& e, double s);
+CV_EXPORTS MatExpr operator * (double s, const MatExpr& e);
+CV_EXPORTS MatExpr operator * (const MatExpr& e1, const MatExpr& e2);
+
+CV_EXPORTS MatExpr operator / (const Mat& a, const Mat& b);
+CV_EXPORTS MatExpr operator / (const Mat& a, double s);
+CV_EXPORTS MatExpr operator / (double s, const Mat& a);
+CV_EXPORTS MatExpr operator / (const MatExpr& e, const Mat& m);
+CV_EXPORTS MatExpr operator / (const Mat& m, const MatExpr& e);
+CV_EXPORTS MatExpr operator / (const MatExpr& e, double s);
+CV_EXPORTS MatExpr operator / (double s, const MatExpr& e);
+CV_EXPORTS MatExpr operator / (const MatExpr& e1, const MatExpr& e2);
+
+CV_EXPORTS MatExpr operator < (const Mat& a, const Mat& b);
+CV_EXPORTS MatExpr operator < (const Mat& a, double s);
+CV_EXPORTS MatExpr operator < (double s, const Mat& a);
+
+CV_EXPORTS MatExpr operator <= (const Mat& a, const Mat& b);
+CV_EXPORTS MatExpr operator <= (const Mat& a, double s);
+CV_EXPORTS MatExpr operator <= (double s, const Mat& a);
+
+CV_EXPORTS MatExpr operator == (const Mat& a, const Mat& b);
+CV_EXPORTS MatExpr operator == (const Mat& a, double s);
+CV_EXPORTS MatExpr operator == (double s, const Mat& a);
+
+CV_EXPORTS MatExpr operator != (const Mat& a, const Mat& b);
+CV_EXPORTS MatExpr operator != (const Mat& a, double s);
+CV_EXPORTS MatExpr operator != (double s, const Mat& a);
+
+CV_EXPORTS MatExpr operator >= (const Mat& a, const Mat& b);
+CV_EXPORTS MatExpr operator >= (const Mat& a, double s);
+CV_EXPORTS MatExpr operator >= (double s, const Mat& a);
+
+CV_EXPORTS MatExpr operator > (const Mat& a, const Mat& b);
+CV_EXPORTS MatExpr operator > (const Mat& a, double s);
+CV_EXPORTS MatExpr operator > (double s, const Mat& a);
+
+CV_EXPORTS MatExpr operator & (const Mat& a, const Mat& b);
+CV_EXPORTS MatExpr operator & (const Mat& a, const Scalar& s);
+CV_EXPORTS MatExpr operator & (const Scalar& s, const Mat& a);
+
+CV_EXPORTS MatExpr operator | (const Mat& a, const Mat& b);
+CV_EXPORTS MatExpr operator | (const Mat& a, const Scalar& s);
+CV_EXPORTS MatExpr operator | (const Scalar& s, const Mat& a);
+
+CV_EXPORTS MatExpr operator ^ (const Mat& a, const Mat& b);
+CV_EXPORTS MatExpr operator ^ (const Mat& a, const Scalar& s);
+CV_EXPORTS MatExpr operator ^ (const Scalar& s, const Mat& a);
+
+CV_EXPORTS MatExpr operator ~(const Mat& m);
+
+CV_EXPORTS MatExpr min(const Mat& a, const Mat& b);
+CV_EXPORTS MatExpr min(const Mat& a, double s);
+CV_EXPORTS MatExpr min(double s, const Mat& a);
+
+CV_EXPORTS MatExpr max(const Mat& a, const Mat& b);
+CV_EXPORTS MatExpr max(const Mat& a, double s);
+CV_EXPORTS MatExpr max(double s, const Mat& a);
+
+/** @brief Calculates an absolute value of each matrix element.
+
+abs is a meta-function that is expanded to one of absdiff or convertScaleAbs forms:
+- C = abs(A-B) is equivalent to `absdiff(A, B, C)`
+- C = abs(A) is equivalent to `absdiff(A, Scalar::all(0), C)`
+- C = `Mat_<Vec<uchar,n> >(abs(A*alpha + beta))` is equivalent to `convertScaleAbs(A, C, alpha,
+beta)`
+
+The output matrix has the same size and the same type as the input one except for the last case,
+where C is depth=CV_8U .
+@param m matrix.
+@sa @ref MatrixExpressions, absdiff, convertScaleAbs
+ */
+CV_EXPORTS MatExpr abs(const Mat& m);
+/** @overload
+@param e matrix expression.
+*/
+CV_EXPORTS MatExpr abs(const MatExpr& e);
+//! @} relates cv::MatExpr
+
+} // cv
+
+#include "opencv2/core/mat.inl.hpp"
+
+#endif // OPENCV_CORE_MAT_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/core/mat.inl.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,3733 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
+// Copyright (C) 2015, Itseez Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_CORE_MATRIX_OPERATIONS_HPP
+#define OPENCV_CORE_MATRIX_OPERATIONS_HPP
+
+#ifndef __cplusplus
+# error mat.inl.hpp header must be compiled as C++
+#endif
+
+namespace cv
+{
+
+//! @cond IGNORED
+
+//////////////////////// Input/Output Arrays ////////////////////////
+
+inline void _InputArray::init(int _flags, const void* _obj)
+{ flags = _flags; obj = (void*)_obj; }
+
+inline void _InputArray::init(int _flags, const void* _obj, Size _sz)
+{ flags = _flags; obj = (void*)_obj; sz = _sz; }
+
+inline void* _InputArray::getObj() const { return obj; }
+inline int _InputArray::getFlags() const { return flags; }
+inline Size _InputArray::getSz() const { return sz; }
+
+inline _InputArray::_InputArray() { init(NONE, 0); }
+inline _InputArray::_InputArray(int _flags, void* _obj) { init(_flags, _obj); }
+inline _InputArray::_InputArray(const Mat& m) { init(MAT+ACCESS_READ, &m); }
+inline _InputArray::_InputArray(const std::vector<Mat>& vec) { init(STD_VECTOR_MAT+ACCESS_READ, &vec); }
+inline _InputArray::_InputArray(const UMat& m) { init(UMAT+ACCESS_READ, &m); }
+inline _InputArray::_InputArray(const std::vector<UMat>& vec) { init(STD_VECTOR_UMAT+ACCESS_READ, &vec); }
+
+template<typename _Tp> inline
+_InputArray::_InputArray(const std::vector<_Tp>& vec)
+{ init(FIXED_TYPE + STD_VECTOR + DataType<_Tp>::type + ACCESS_READ, &vec); }
+
+inline
+_InputArray::_InputArray(const std::vector<bool>& vec)
+{ init(FIXED_TYPE + STD_BOOL_VECTOR + DataType<bool>::type + ACCESS_READ, &vec); }
+
+template<typename _Tp> inline
+_InputArray::_InputArray(const std::vector<std::vector<_Tp> >& vec)
+{ init(FIXED_TYPE + STD_VECTOR_VECTOR + DataType<_Tp>::type + ACCESS_READ, &vec); }
+
+template<typename _Tp> inline
+_InputArray::_InputArray(const std::vector<Mat_<_Tp> >& vec)
+{ init(FIXED_TYPE + STD_VECTOR_MAT + DataType<_Tp>::type + ACCESS_READ, &vec); }
+
+template<typename _Tp, int m, int n> inline
+_InputArray::_InputArray(const Matx<_Tp, m, n>& mtx)
+{ init(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type + ACCESS_READ, &mtx, Size(n, m)); }
+
+template<typename _Tp> inline
+_InputArray::_InputArray(const _Tp* vec, int n)
+{ init(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type + ACCESS_READ, vec, Size(n, 1)); }
+
+template<typename _Tp> inline
+_InputArray::_InputArray(const Mat_<_Tp>& m)
+{ init(FIXED_TYPE + MAT + DataType<_Tp>::type + ACCESS_READ, &m); }
+
+inline _InputArray::_InputArray(const double& val)
+{ init(FIXED_TYPE + FIXED_SIZE + MATX + CV_64F + ACCESS_READ, &val, Size(1,1)); }
+
+inline _InputArray::_InputArray(const MatExpr& expr)
+{ init(FIXED_TYPE + FIXED_SIZE + EXPR + ACCESS_READ, &expr); }
+
+inline _InputArray::_InputArray(const cuda::GpuMat& d_mat)
+{ init(CUDA_GPU_MAT + ACCESS_READ, &d_mat); }
+
+inline _InputArray::_InputArray(const std::vector<cuda::GpuMat>& d_mat)
+{ init(STD_VECTOR_CUDA_GPU_MAT + ACCESS_READ, &d_mat);}
+
+inline _InputArray::_InputArray(const ogl::Buffer& buf)
+{ init(OPENGL_BUFFER + ACCESS_READ, &buf); }
+
+inline _InputArray::_InputArray(const cuda::HostMem& cuda_mem)
+{ init(CUDA_HOST_MEM + ACCESS_READ, &cuda_mem); }
+
+inline _InputArray::~_InputArray() {}
+
+inline Mat _InputArray::getMat(int i) const
+{
+ if( kind() == MAT && i < 0 )
+ return *(const Mat*)obj;
+ return getMat_(i);
+}
+
+inline bool _InputArray::isMat() const { return kind() == _InputArray::MAT; }
+inline bool _InputArray::isUMat() const { return kind() == _InputArray::UMAT; }
+inline bool _InputArray::isMatVector() const { return kind() == _InputArray::STD_VECTOR_MAT; }
+inline bool _InputArray::isUMatVector() const { return kind() == _InputArray::STD_VECTOR_UMAT; }
+inline bool _InputArray::isMatx() const { return kind() == _InputArray::MATX; }
+inline bool _InputArray::isVector() const { return kind() == _InputArray::STD_VECTOR || kind() == _InputArray::STD_BOOL_VECTOR; }
+inline bool _InputArray::isGpuMatVector() const { return kind() == _InputArray::STD_VECTOR_CUDA_GPU_MAT; }
+
+////////////////////////////////////////////////////////////////////////////////////////
+
+inline _OutputArray::_OutputArray() { init(ACCESS_WRITE, 0); }
+inline _OutputArray::_OutputArray(int _flags, void* _obj) { init(_flags|ACCESS_WRITE, _obj); }
+inline _OutputArray::_OutputArray(Mat& m) { init(MAT+ACCESS_WRITE, &m); }
+inline _OutputArray::_OutputArray(std::vector<Mat>& vec) { init(STD_VECTOR_MAT+ACCESS_WRITE, &vec); }
+inline _OutputArray::_OutputArray(UMat& m) { init(UMAT+ACCESS_WRITE, &m); }
+inline _OutputArray::_OutputArray(std::vector<UMat>& vec) { init(STD_VECTOR_UMAT+ACCESS_WRITE, &vec); }
+
+template<typename _Tp> inline
+_OutputArray::_OutputArray(std::vector<_Tp>& vec)
+{ init(FIXED_TYPE + STD_VECTOR + DataType<_Tp>::type + ACCESS_WRITE, &vec); }
+
+inline
+_OutputArray::_OutputArray(std::vector<bool>&)
+{ CV_Error(Error::StsUnsupportedFormat, "std::vector<bool> cannot be an output array\n"); }
+
+template<typename _Tp> inline
+_OutputArray::_OutputArray(std::vector<std::vector<_Tp> >& vec)
+{ init(FIXED_TYPE + STD_VECTOR_VECTOR + DataType<_Tp>::type + ACCESS_WRITE, &vec); }
+
+template<typename _Tp> inline
+_OutputArray::_OutputArray(std::vector<Mat_<_Tp> >& vec)
+{ init(FIXED_TYPE + STD_VECTOR_MAT + DataType<_Tp>::type + ACCESS_WRITE, &vec); }
+
+template<typename _Tp> inline
+_OutputArray::_OutputArray(Mat_<_Tp>& m)
+{ init(FIXED_TYPE + MAT + DataType<_Tp>::type + ACCESS_WRITE, &m); }
+
+template<typename _Tp, int m, int n> inline
+_OutputArray::_OutputArray(Matx<_Tp, m, n>& mtx)
+{ init(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type + ACCESS_WRITE, &mtx, Size(n, m)); }
+
+template<typename _Tp> inline
+_OutputArray::_OutputArray(_Tp* vec, int n)
+{ init(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type + ACCESS_WRITE, vec, Size(n, 1)); }
+
+template<typename _Tp> inline
+_OutputArray::_OutputArray(const std::vector<_Tp>& vec)
+{ init(FIXED_TYPE + FIXED_SIZE + STD_VECTOR + DataType<_Tp>::type + ACCESS_WRITE, &vec); }
+
+template<typename _Tp> inline
+_OutputArray::_OutputArray(const std::vector<std::vector<_Tp> >& vec)
+{ init(FIXED_TYPE + FIXED_SIZE + STD_VECTOR_VECTOR + DataType<_Tp>::type + ACCESS_WRITE, &vec); }
+
+template<typename _Tp> inline
+_OutputArray::_OutputArray(const std::vector<Mat_<_Tp> >& vec)
+{ init(FIXED_TYPE + FIXED_SIZE + STD_VECTOR_MAT + DataType<_Tp>::type + ACCESS_WRITE, &vec); }
+
+template<typename _Tp> inline
+_OutputArray::_OutputArray(const Mat_<_Tp>& m)
+{ init(FIXED_TYPE + FIXED_SIZE + MAT + DataType<_Tp>::type + ACCESS_WRITE, &m); }
+
+template<typename _Tp, int m, int n> inline
+_OutputArray::_OutputArray(const Matx<_Tp, m, n>& mtx)
+{ init(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type + ACCESS_WRITE, &mtx, Size(n, m)); }
+
+template<typename _Tp> inline
+_OutputArray::_OutputArray(const _Tp* vec, int n)
+{ init(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type + ACCESS_WRITE, vec, Size(n, 1)); }
+
+inline _OutputArray::_OutputArray(cuda::GpuMat& d_mat)
+{ init(CUDA_GPU_MAT + ACCESS_WRITE, &d_mat); }
+
+inline _OutputArray::_OutputArray(std::vector<cuda::GpuMat>& d_mat)
+{ init(STD_VECTOR_CUDA_GPU_MAT + ACCESS_WRITE, &d_mat);}
+
+inline _OutputArray::_OutputArray(ogl::Buffer& buf)
+{ init(OPENGL_BUFFER + ACCESS_WRITE, &buf); }
+
+inline _OutputArray::_OutputArray(cuda::HostMem& cuda_mem)
+{ init(CUDA_HOST_MEM + ACCESS_WRITE, &cuda_mem); }
+
+inline _OutputArray::_OutputArray(const Mat& m)
+{ init(FIXED_TYPE + FIXED_SIZE + MAT + ACCESS_WRITE, &m); }
+
+inline _OutputArray::_OutputArray(const std::vector<Mat>& vec)
+{ init(FIXED_SIZE + STD_VECTOR_MAT + ACCESS_WRITE, &vec); }
+
+inline _OutputArray::_OutputArray(const UMat& m)
+{ init(FIXED_TYPE + FIXED_SIZE + UMAT + ACCESS_WRITE, &m); }
+
+inline _OutputArray::_OutputArray(const std::vector<UMat>& vec)
+{ init(FIXED_SIZE + STD_VECTOR_UMAT + ACCESS_WRITE, &vec); }
+
+inline _OutputArray::_OutputArray(const cuda::GpuMat& d_mat)
+{ init(FIXED_TYPE + FIXED_SIZE + CUDA_GPU_MAT + ACCESS_WRITE, &d_mat); }
+
+
+inline _OutputArray::_OutputArray(const ogl::Buffer& buf)
+{ init(FIXED_TYPE + FIXED_SIZE + OPENGL_BUFFER + ACCESS_WRITE, &buf); }
+
+inline _OutputArray::_OutputArray(const cuda::HostMem& cuda_mem)
+{ init(FIXED_TYPE + FIXED_SIZE + CUDA_HOST_MEM + ACCESS_WRITE, &cuda_mem); }
+
+///////////////////////////////////////////////////////////////////////////////////////////
+
+inline _InputOutputArray::_InputOutputArray() { init(ACCESS_RW, 0); }
+inline _InputOutputArray::_InputOutputArray(int _flags, void* _obj) { init(_flags|ACCESS_RW, _obj); }
+inline _InputOutputArray::_InputOutputArray(Mat& m) { init(MAT+ACCESS_RW, &m); }
+inline _InputOutputArray::_InputOutputArray(std::vector<Mat>& vec) { init(STD_VECTOR_MAT+ACCESS_RW, &vec); }
+inline _InputOutputArray::_InputOutputArray(UMat& m) { init(UMAT+ACCESS_RW, &m); }
+inline _InputOutputArray::_InputOutputArray(std::vector<UMat>& vec) { init(STD_VECTOR_UMAT+ACCESS_RW, &vec); }
+
+template<typename _Tp> inline
+_InputOutputArray::_InputOutputArray(std::vector<_Tp>& vec)
+{ init(FIXED_TYPE + STD_VECTOR + DataType<_Tp>::type + ACCESS_RW, &vec); }
+
+inline _InputOutputArray::_InputOutputArray(std::vector<bool>&)
+{ CV_Error(Error::StsUnsupportedFormat, "std::vector<bool> cannot be an input/output array\n"); }
+
+template<typename _Tp> inline
+_InputOutputArray::_InputOutputArray(std::vector<std::vector<_Tp> >& vec)
+{ init(FIXED_TYPE + STD_VECTOR_VECTOR + DataType<_Tp>::type + ACCESS_RW, &vec); }
+
+template<typename _Tp> inline
+_InputOutputArray::_InputOutputArray(std::vector<Mat_<_Tp> >& vec)
+{ init(FIXED_TYPE + STD_VECTOR_MAT + DataType<_Tp>::type + ACCESS_RW, &vec); }
+
+template<typename _Tp> inline
+_InputOutputArray::_InputOutputArray(Mat_<_Tp>& m)
+{ init(FIXED_TYPE + MAT + DataType<_Tp>::type + ACCESS_RW, &m); }
+
+template<typename _Tp, int m, int n> inline
+_InputOutputArray::_InputOutputArray(Matx<_Tp, m, n>& mtx)
+{ init(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type + ACCESS_RW, &mtx, Size(n, m)); }
+
+template<typename _Tp> inline
+_InputOutputArray::_InputOutputArray(_Tp* vec, int n)
+{ init(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type + ACCESS_RW, vec, Size(n, 1)); }
+
+template<typename _Tp> inline
+_InputOutputArray::_InputOutputArray(const std::vector<_Tp>& vec)
+{ init(FIXED_TYPE + FIXED_SIZE + STD_VECTOR + DataType<_Tp>::type + ACCESS_RW, &vec); }
+
+template<typename _Tp> inline
+_InputOutputArray::_InputOutputArray(const std::vector<std::vector<_Tp> >& vec)
+{ init(FIXED_TYPE + FIXED_SIZE + STD_VECTOR_VECTOR + DataType<_Tp>::type + ACCESS_RW, &vec); }
+
+template<typename _Tp> inline
+_InputOutputArray::_InputOutputArray(const std::vector<Mat_<_Tp> >& vec)
+{ init(FIXED_TYPE + FIXED_SIZE + STD_VECTOR_MAT + DataType<_Tp>::type + ACCESS_RW, &vec); }
+
+template<typename _Tp> inline
+_InputOutputArray::_InputOutputArray(const Mat_<_Tp>& m)
+{ init(FIXED_TYPE + FIXED_SIZE + MAT + DataType<_Tp>::type + ACCESS_RW, &m); }
+
+template<typename _Tp, int m, int n> inline
+_InputOutputArray::_InputOutputArray(const Matx<_Tp, m, n>& mtx)
+{ init(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type + ACCESS_RW, &mtx, Size(n, m)); }
+
+template<typename _Tp> inline
+_InputOutputArray::_InputOutputArray(const _Tp* vec, int n)
+{ init(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type + ACCESS_RW, vec, Size(n, 1)); }
+
+inline _InputOutputArray::_InputOutputArray(cuda::GpuMat& d_mat)
+{ init(CUDA_GPU_MAT + ACCESS_RW, &d_mat); }
+
+inline _InputOutputArray::_InputOutputArray(ogl::Buffer& buf)
+{ init(OPENGL_BUFFER + ACCESS_RW, &buf); }
+
+inline _InputOutputArray::_InputOutputArray(cuda::HostMem& cuda_mem)
+{ init(CUDA_HOST_MEM + ACCESS_RW, &cuda_mem); }
+
+inline _InputOutputArray::_InputOutputArray(const Mat& m)
+{ init(FIXED_TYPE + FIXED_SIZE + MAT + ACCESS_RW, &m); }
+
+inline _InputOutputArray::_InputOutputArray(const std::vector<Mat>& vec)
+{ init(FIXED_SIZE + STD_VECTOR_MAT + ACCESS_RW, &vec); }
+
+inline _InputOutputArray::_InputOutputArray(const UMat& m)
+{ init(FIXED_TYPE + FIXED_SIZE + UMAT + ACCESS_RW, &m); }
+
+inline _InputOutputArray::_InputOutputArray(const std::vector<UMat>& vec)
+{ init(FIXED_SIZE + STD_VECTOR_UMAT + ACCESS_RW, &vec); }
+
+inline _InputOutputArray::_InputOutputArray(const cuda::GpuMat& d_mat)
+{ init(FIXED_TYPE + FIXED_SIZE + CUDA_GPU_MAT + ACCESS_RW, &d_mat); }
+
+inline _InputOutputArray::_InputOutputArray(const std::vector<cuda::GpuMat>& d_mat)
+{ init(FIXED_TYPE + FIXED_SIZE + STD_VECTOR_CUDA_GPU_MAT + ACCESS_RW, &d_mat);}
+
+template<> inline _InputOutputArray::_InputOutputArray(std::vector<cuda::GpuMat>& d_mat)
+{ init(FIXED_TYPE + FIXED_SIZE + STD_VECTOR_CUDA_GPU_MAT + ACCESS_RW, &d_mat);}
+
+inline _InputOutputArray::_InputOutputArray(const ogl::Buffer& buf)
+{ init(FIXED_TYPE + FIXED_SIZE + OPENGL_BUFFER + ACCESS_RW, &buf); }
+
+inline _InputOutputArray::_InputOutputArray(const cuda::HostMem& cuda_mem)
+{ init(FIXED_TYPE + FIXED_SIZE + CUDA_HOST_MEM + ACCESS_RW, &cuda_mem); }
+
+//////////////////////////////////////////// Mat //////////////////////////////////////////
+
+inline
+Mat::Mat()
+ : flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
+ datalimit(0), allocator(0), u(0), size(&rows)
+{}
+
+inline
+Mat::Mat(int _rows, int _cols, int _type)
+ : flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
+ datalimit(0), allocator(0), u(0), size(&rows)
+{
+ create(_rows, _cols, _type);
+}
+
+inline
+Mat::Mat(int _rows, int _cols, int _type, const Scalar& _s)
+ : flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
+ datalimit(0), allocator(0), u(0), size(&rows)
+{
+ create(_rows, _cols, _type);
+ *this = _s;
+}
+
+inline
+Mat::Mat(Size _sz, int _type)
+ : flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
+ datalimit(0), allocator(0), u(0), size(&rows)
+{
+ create( _sz.height, _sz.width, _type );
+}
+
+inline
+Mat::Mat(Size _sz, int _type, const Scalar& _s)
+ : flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
+ datalimit(0), allocator(0), u(0), size(&rows)
+{
+ create(_sz.height, _sz.width, _type);
+ *this = _s;
+}
+
+inline
+Mat::Mat(int _dims, const int* _sz, int _type)
+ : flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
+ datalimit(0), allocator(0), u(0), size(&rows)
+{
+ create(_dims, _sz, _type);
+}
+
+inline
+Mat::Mat(int _dims, const int* _sz, int _type, const Scalar& _s)
+ : flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
+ datalimit(0), allocator(0), u(0), size(&rows)
+{
+ create(_dims, _sz, _type);
+ *this = _s;
+}
+
+inline
+Mat::Mat(const std::vector<int>& _sz, int _type)
+ : flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
+ datalimit(0), allocator(0), u(0), size(&rows)
+{
+ create(_sz, _type);
+}
+
+inline
+Mat::Mat(const std::vector<int>& _sz, int _type, const Scalar& _s)
+ : flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
+ datalimit(0), allocator(0), u(0), size(&rows)
+{
+ create(_sz, _type);
+ *this = _s;
+}
+
+inline
+Mat::Mat(const Mat& m)
+ : flags(m.flags), dims(m.dims), rows(m.rows), cols(m.cols), data(m.data),
+ datastart(m.datastart), dataend(m.dataend), datalimit(m.datalimit), allocator(m.allocator),
+ u(m.u), size(&rows)
+{
+ if( u )
+ CV_XADD(&u->refcount, 1);
+ if( m.dims <= 2 )
+ {
+ step[0] = m.step[0]; step[1] = m.step[1];
+ }
+ else
+ {
+ dims = 0;
+ copySize(m);
+ }
+}
+
+inline
+Mat::Mat(int _rows, int _cols, int _type, void* _data, size_t _step)
+ : flags(MAGIC_VAL + (_type & TYPE_MASK)), dims(2), rows(_rows), cols(_cols),
+ data((uchar*)_data), datastart((uchar*)_data), dataend(0), datalimit(0),
+ allocator(0), u(0), size(&rows)
+{
+ CV_Assert(total() == 0 || data != NULL);
+
+ size_t esz = CV_ELEM_SIZE(_type), esz1 = CV_ELEM_SIZE1(_type);
+ size_t minstep = cols * esz;
+ if( _step == AUTO_STEP )
+ {
+ _step = minstep;
+ flags |= CONTINUOUS_FLAG;
+ }
+ else
+ {
+ if( rows == 1 ) _step = minstep;
+ CV_DbgAssert( _step >= minstep );
+
+ if (_step % esz1 != 0)
+ {
+ CV_Error(Error::BadStep, "Step must be a multiple of esz1");
+ }
+
+ flags |= _step == minstep ? CONTINUOUS_FLAG : 0;
+ }
+ step[0] = _step;
+ step[1] = esz;
+ datalimit = datastart + _step * rows;
+ dataend = datalimit - _step + minstep;
+}
+
+inline
+Mat::Mat(Size _sz, int _type, void* _data, size_t _step)
+ : flags(MAGIC_VAL + (_type & TYPE_MASK)), dims(2), rows(_sz.height), cols(_sz.width),
+ data((uchar*)_data), datastart((uchar*)_data), dataend(0), datalimit(0),
+ allocator(0), u(0), size(&rows)
+{
+ CV_Assert(total() == 0 || data != NULL);
+
+ size_t esz = CV_ELEM_SIZE(_type), esz1 = CV_ELEM_SIZE1(_type);
+ size_t minstep = cols*esz;
+ if( _step == AUTO_STEP )
+ {
+ _step = minstep;
+ flags |= CONTINUOUS_FLAG;
+ }
+ else
+ {
+ if( rows == 1 ) _step = minstep;
+ CV_DbgAssert( _step >= minstep );
+
+ if (_step % esz1 != 0)
+ {
+ CV_Error(Error::BadStep, "Step must be a multiple of esz1");
+ }
+
+ flags |= _step == minstep ? CONTINUOUS_FLAG : 0;
+ }
+ step[0] = _step;
+ step[1] = esz;
+ datalimit = datastart + _step*rows;
+ dataend = datalimit - _step + minstep;
+}
+
+template<typename _Tp> inline
+Mat::Mat(const std::vector<_Tp>& vec, bool copyData)
+ : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG), dims(2), rows((int)vec.size()),
+ cols(1), data(0), datastart(0), dataend(0), allocator(0), u(0), size(&rows)
+{
+ if(vec.empty())
+ return;
+ if( !copyData )
+ {
+ step[0] = step[1] = sizeof(_Tp);
+ datastart = data = (uchar*)&vec[0];
+ datalimit = dataend = datastart + rows * step[0];
+ }
+ else
+ Mat((int)vec.size(), 1, DataType<_Tp>::type, (uchar*)&vec[0]).copyTo(*this);
+}
+
+template<typename _Tp, int n> inline
+Mat::Mat(const Vec<_Tp, n>& vec, bool copyData)
+ : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG), dims(2), rows(n), cols(1), data(0),
+ datastart(0), dataend(0), allocator(0), u(0), size(&rows)
+{
+ if( !copyData )
+ {
+ step[0] = step[1] = sizeof(_Tp);
+ datastart = data = (uchar*)vec.val;
+ datalimit = dataend = datastart + rows * step[0];
+ }
+ else
+ Mat(n, 1, DataType<_Tp>::type, (void*)vec.val).copyTo(*this);
+}
+
+
+template<typename _Tp, int m, int n> inline
+Mat::Mat(const Matx<_Tp,m,n>& M, bool copyData)
+ : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG), dims(2), rows(m), cols(n), data(0),
+ datastart(0), dataend(0), allocator(0), u(0), size(&rows)
+{
+ if( !copyData )
+ {
+ step[0] = cols * sizeof(_Tp);
+ step[1] = sizeof(_Tp);
+ datastart = data = (uchar*)M.val;
+ datalimit = dataend = datastart + rows * step[0];
+ }
+ else
+ Mat(m, n, DataType<_Tp>::type, (uchar*)M.val).copyTo(*this);
+}
+
+template<typename _Tp> inline
+Mat::Mat(const Point_<_Tp>& pt, bool copyData)
+ : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG), dims(2), rows(2), cols(1), data(0),
+ datastart(0), dataend(0), allocator(0), u(0), size(&rows)
+{
+ if( !copyData )
+ {
+ step[0] = step[1] = sizeof(_Tp);
+ datastart = data = (uchar*)&pt.x;
+ datalimit = dataend = datastart + rows * step[0];
+ }
+ else
+ {
+ create(2, 1, DataType<_Tp>::type);
+ ((_Tp*)data)[0] = pt.x;
+ ((_Tp*)data)[1] = pt.y;
+ }
+}
+
+template<typename _Tp> inline
+Mat::Mat(const Point3_<_Tp>& pt, bool copyData)
+ : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG), dims(2), rows(3), cols(1), data(0),
+ datastart(0), dataend(0), allocator(0), u(0), size(&rows)
+{
+ if( !copyData )
+ {
+ step[0] = step[1] = sizeof(_Tp);
+ datastart = data = (uchar*)&pt.x;
+ datalimit = dataend = datastart + rows * step[0];
+ }
+ else
+ {
+ create(3, 1, DataType<_Tp>::type);
+ ((_Tp*)data)[0] = pt.x;
+ ((_Tp*)data)[1] = pt.y;
+ ((_Tp*)data)[2] = pt.z;
+ }
+}
+
+template<typename _Tp> inline
+Mat::Mat(const MatCommaInitializer_<_Tp>& commaInitializer)
+ : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG), dims(0), rows(0), cols(0), data(0),
+ datastart(0), dataend(0), allocator(0), u(0), size(&rows)
+{
+ *this = commaInitializer.operator Mat_<_Tp>();
+}
+
+inline
+Mat::~Mat()
+{
+ release();
+ if( step.p != step.buf )
+ fastFree(step.p);
+}
+
+inline
+Mat& Mat::operator = (const Mat& m)
+{
+ if( this != &m )
+ {
+ if( m.u )
+ CV_XADD(&m.u->refcount, 1);
+ release();
+ flags = m.flags;
+ if( dims <= 2 && m.dims <= 2 )
+ {
+ dims = m.dims;
+ rows = m.rows;
+ cols = m.cols;
+ step[0] = m.step[0];
+ step[1] = m.step[1];
+ }
+ else
+ copySize(m);
+ data = m.data;
+ datastart = m.datastart;
+ dataend = m.dataend;
+ datalimit = m.datalimit;
+ allocator = m.allocator;
+ u = m.u;
+ }
+ return *this;
+}
+
+inline
+Mat Mat::row(int y) const
+{
+ return Mat(*this, Range(y, y + 1), Range::all());
+}
+
+inline
+Mat Mat::col(int x) const
+{
+ return Mat(*this, Range::all(), Range(x, x + 1));
+}
+
+inline
+Mat Mat::rowRange(int startrow, int endrow) const
+{
+ return Mat(*this, Range(startrow, endrow), Range::all());
+}
+
+inline
+Mat Mat::rowRange(const Range& r) const
+{
+ return Mat(*this, r, Range::all());
+}
+
+inline
+Mat Mat::colRange(int startcol, int endcol) const
+{
+ return Mat(*this, Range::all(), Range(startcol, endcol));
+}
+
+inline
+Mat Mat::colRange(const Range& r) const
+{
+ return Mat(*this, Range::all(), r);
+}
+
+inline
+Mat Mat::clone() const
+{
+ Mat m;
+ copyTo(m);
+ return m;
+}
+
+inline
+void Mat::assignTo( Mat& m, int _type ) const
+{
+ if( _type < 0 )
+ m = *this;
+ else
+ convertTo(m, _type);
+}
+
+inline
+void Mat::create(int _rows, int _cols, int _type)
+{
+ _type &= TYPE_MASK;
+ if( dims <= 2 && rows == _rows && cols == _cols && type() == _type && data )
+ return;
+ int sz[] = {_rows, _cols};
+ create(2, sz, _type);
+}
+
+inline
+void Mat::create(Size _sz, int _type)
+{
+ create(_sz.height, _sz.width, _type);
+}
+
+inline
+void Mat::addref()
+{
+ if( u )
+ CV_XADD(&u->refcount, 1);
+}
+
+inline
+void Mat::release()
+{
+ if( u && CV_XADD(&u->refcount, -1) == 1 )
+ deallocate();
+ u = NULL;
+ datastart = dataend = datalimit = data = 0;
+ for(int i = 0; i < dims; i++)
+ size.p[i] = 0;
+#ifdef _DEBUG
+ flags = MAGIC_VAL;
+ dims = rows = cols = 0;
+ if(step.p != step.buf)
+ {
+ fastFree(step.p);
+ step.p = step.buf;
+ size.p = &rows;
+ }
+#endif
+}
+
+inline
+Mat Mat::operator()( Range _rowRange, Range _colRange ) const
+{
+ return Mat(*this, _rowRange, _colRange);
+}
+
+inline
+Mat Mat::operator()( const Rect& roi ) const
+{
+ return Mat(*this, roi);
+}
+
+inline
+Mat Mat::operator()(const Range* ranges) const
+{
+ return Mat(*this, ranges);
+}
+
+inline
+Mat Mat::operator()(const std::vector<Range>& ranges) const
+{
+ return Mat(*this, ranges);
+}
+
+inline
+bool Mat::isContinuous() const
+{
+ return (flags & CONTINUOUS_FLAG) != 0;
+}
+
+inline
+bool Mat::isSubmatrix() const
+{
+ return (flags & SUBMATRIX_FLAG) != 0;
+}
+
+inline
+size_t Mat::elemSize() const
+{
+ return dims > 0 ? step.p[dims - 1] : 0;
+}
+
+inline
+size_t Mat::elemSize1() const
+{
+ return CV_ELEM_SIZE1(flags);
+}
+
+inline
+int Mat::type() const
+{
+ return CV_MAT_TYPE(flags);
+}
+
+inline
+int Mat::depth() const
+{
+ return CV_MAT_DEPTH(flags);
+}
+
+inline
+int Mat::channels() const
+{
+ return CV_MAT_CN(flags);
+}
+
+inline
+size_t Mat::step1(int i) const
+{
+ return step.p[i] / elemSize1();
+}
+
+inline
+bool Mat::empty() const
+{
+ return data == 0 || total() == 0;
+}
+
+inline
+size_t Mat::total() const
+{
+ if( dims <= 2 )
+ return (size_t)rows * cols;
+ size_t p = 1;
+ for( int i = 0; i < dims; i++ )
+ p *= size[i];
+ return p;
+}
+
+inline
+uchar* Mat::ptr(int y)
+{
+ CV_DbgAssert( y == 0 || (data && dims >= 1 && (unsigned)y < (unsigned)size.p[0]) );
+ return data + step.p[0] * y;
+}
+
+inline
+const uchar* Mat::ptr(int y) const
+{
+ CV_DbgAssert( y == 0 || (data && dims >= 1 && (unsigned)y < (unsigned)size.p[0]) );
+ return data + step.p[0] * y;
+}
+
+template<typename _Tp> inline
+_Tp* Mat::ptr(int y)
+{
+ CV_DbgAssert( y == 0 || (data && dims >= 1 && (unsigned)y < (unsigned)size.p[0]) );
+ return (_Tp*)(data + step.p[0] * y);
+}
+
+template<typename _Tp> inline
+const _Tp* Mat::ptr(int y) const
+{
+ CV_DbgAssert( y == 0 || (data && dims >= 1 && data && (unsigned)y < (unsigned)size.p[0]) );
+ return (const _Tp*)(data + step.p[0] * y);
+}
+
+inline
+uchar* Mat::ptr(int i0, int i1)
+{
+ CV_DbgAssert(dims >= 2);
+ CV_DbgAssert(data);
+ CV_DbgAssert((unsigned)i0 < (unsigned)size.p[0]);
+ CV_DbgAssert((unsigned)i1 < (unsigned)size.p[1]);
+ return data + i0 * step.p[0] + i1 * step.p[1];
+}
+
+inline
+const uchar* Mat::ptr(int i0, int i1) const
+{
+ CV_DbgAssert(dims >= 2);
+ CV_DbgAssert(data);
+ CV_DbgAssert((unsigned)i0 < (unsigned)size.p[0]);
+ CV_DbgAssert((unsigned)i1 < (unsigned)size.p[1]);
+ return data + i0 * step.p[0] + i1 * step.p[1];
+}
+
+template<typename _Tp> inline
+_Tp* Mat::ptr(int i0, int i1)
+{
+ CV_DbgAssert(dims >= 2);
+ CV_DbgAssert(data);
+ CV_DbgAssert((unsigned)i0 < (unsigned)size.p[0]);
+ CV_DbgAssert((unsigned)i1 < (unsigned)size.p[1]);
+ return (_Tp*)(data + i0 * step.p[0] + i1 * step.p[1]);
+}
+
+template<typename _Tp> inline
+const _Tp* Mat::ptr(int i0, int i1) const
+{
+ CV_DbgAssert(dims >= 2);
+ CV_DbgAssert(data);
+ CV_DbgAssert((unsigned)i0 < (unsigned)size.p[0]);
+ CV_DbgAssert((unsigned)i1 < (unsigned)size.p[1]);
+ return (const _Tp*)(data + i0 * step.p[0] + i1 * step.p[1]);
+}
+
+inline
+uchar* Mat::ptr(int i0, int i1, int i2)
+{
+ CV_DbgAssert(dims >= 3);
+ CV_DbgAssert(data);
+ CV_DbgAssert((unsigned)i0 < (unsigned)size.p[0]);
+ CV_DbgAssert((unsigned)i1 < (unsigned)size.p[1]);
+ CV_DbgAssert((unsigned)i2 < (unsigned)size.p[2]);
+ return data + i0 * step.p[0] + i1 * step.p[1] + i2 * step.p[2];
+}
+
+inline
+const uchar* Mat::ptr(int i0, int i1, int i2) const
+{
+ CV_DbgAssert(dims >= 3);
+ CV_DbgAssert(data);
+ CV_DbgAssert((unsigned)i0 < (unsigned)size.p[0]);
+ CV_DbgAssert((unsigned)i1 < (unsigned)size.p[1]);
+ CV_DbgAssert((unsigned)i2 < (unsigned)size.p[2]);
+ return data + i0 * step.p[0] + i1 * step.p[1] + i2 * step.p[2];
+}
+
+template<typename _Tp> inline
+_Tp* Mat::ptr(int i0, int i1, int i2)
+{
+ CV_DbgAssert(dims >= 3);
+ CV_DbgAssert(data);
+ CV_DbgAssert((unsigned)i0 < (unsigned)size.p[0]);
+ CV_DbgAssert((unsigned)i1 < (unsigned)size.p[1]);
+ CV_DbgAssert((unsigned)i2 < (unsigned)size.p[2]);
+ return (_Tp*)(data + i0 * step.p[0] + i1 * step.p[1] + i2 * step.p[2]);
+}
+
+template<typename _Tp> inline
+const _Tp* Mat::ptr(int i0, int i1, int i2) const
+{
+ CV_DbgAssert(dims >= 3);
+ CV_DbgAssert(data);
+ CV_DbgAssert((unsigned)i0 < (unsigned)size.p[0]);
+ CV_DbgAssert((unsigned)i1 < (unsigned)size.p[1]);
+ CV_DbgAssert((unsigned)i2 < (unsigned)size.p[2]);
+ return (const _Tp*)(data + i0 * step.p[0] + i1 * step.p[1] + i2 * step.p[2]);
+}
+
+inline
+uchar* Mat::ptr(const int* idx)
+{
+ int i, d = dims;
+ uchar* p = data;
+ CV_DbgAssert( d >= 1 && p );
+ for( i = 0; i < d; i++ )
+ {
+ CV_DbgAssert( (unsigned)idx[i] < (unsigned)size.p[i] );
+ p += idx[i] * step.p[i];
+ }
+ return p;
+}
+
+inline
+const uchar* Mat::ptr(const int* idx) const
+{
+ int i, d = dims;
+ uchar* p = data;
+ CV_DbgAssert( d >= 1 && p );
+ for( i = 0; i < d; i++ )
+ {
+ CV_DbgAssert( (unsigned)idx[i] < (unsigned)size.p[i] );
+ p += idx[i] * step.p[i];
+ }
+ return p;
+}
+
+template<typename _Tp> inline
+_Tp& Mat::at(int i0, int i1)
+{
+ CV_DbgAssert(dims <= 2);
+ CV_DbgAssert(data);
+ CV_DbgAssert((unsigned)i0 < (unsigned)size.p[0]);
+ CV_DbgAssert((unsigned)(i1 * DataType<_Tp>::channels) < (unsigned)(size.p[1] * channels()));
+ CV_DbgAssert(CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1());
+ return ((_Tp*)(data + step.p[0] * i0))[i1];
+}
+
+template<typename _Tp> inline
+const _Tp& Mat::at(int i0, int i1) const
+{
+ CV_DbgAssert(dims <= 2);
+ CV_DbgAssert(data);
+ CV_DbgAssert((unsigned)i0 < (unsigned)size.p[0]);
+ CV_DbgAssert((unsigned)(i1 * DataType<_Tp>::channels) < (unsigned)(size.p[1] * channels()));
+ CV_DbgAssert(CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1());
+ return ((const _Tp*)(data + step.p[0] * i0))[i1];
+}
+
+template<typename _Tp> inline
+_Tp& Mat::at(Point pt)
+{
+ CV_DbgAssert(dims <= 2);
+ CV_DbgAssert(data);
+ CV_DbgAssert((unsigned)pt.y < (unsigned)size.p[0]);
+ CV_DbgAssert((unsigned)(pt.x * DataType<_Tp>::channels) < (unsigned)(size.p[1] * channels()));
+ CV_DbgAssert(CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1());
+ return ((_Tp*)(data + step.p[0] * pt.y))[pt.x];
+}
+
+template<typename _Tp> inline
+const _Tp& Mat::at(Point pt) const
+{
+ CV_DbgAssert(dims <= 2);
+ CV_DbgAssert(data);
+ CV_DbgAssert((unsigned)pt.y < (unsigned)size.p[0]);
+ CV_DbgAssert((unsigned)(pt.x * DataType<_Tp>::channels) < (unsigned)(size.p[1] * channels()));
+ CV_DbgAssert(CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1());
+ return ((const _Tp*)(data + step.p[0] * pt.y))[pt.x];
+}
+
+template<typename _Tp> inline
+_Tp& Mat::at(int i0)
+{
+ CV_DbgAssert(dims <= 2);
+ CV_DbgAssert(data);
+ CV_DbgAssert((unsigned)i0 < (unsigned)(size.p[0] * size.p[1]));
+ CV_DbgAssert(elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type));
+ if( isContinuous() || size.p[0] == 1 )
+ return ((_Tp*)data)[i0];
+ if( size.p[1] == 1 )
+ return *(_Tp*)(data + step.p[0] * i0);
+ int i = i0 / cols, j = i0 - i * cols;
+ return ((_Tp*)(data + step.p[0] * i))[j];
+}
+
+template<typename _Tp> inline
+const _Tp& Mat::at(int i0) const
+{
+ CV_DbgAssert(dims <= 2);
+ CV_DbgAssert(data);
+ CV_DbgAssert((unsigned)i0 < (unsigned)(size.p[0] * size.p[1]));
+ CV_DbgAssert(elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type));
+ if( isContinuous() || size.p[0] == 1 )
+ return ((const _Tp*)data)[i0];
+ if( size.p[1] == 1 )
+ return *(const _Tp*)(data + step.p[0] * i0);
+ int i = i0 / cols, j = i0 - i * cols;
+ return ((const _Tp*)(data + step.p[0] * i))[j];
+}
+
+template<typename _Tp> inline
+_Tp& Mat::at(int i0, int i1, int i2)
+{
+ CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
+ return *(_Tp*)ptr(i0, i1, i2);
+}
+
+template<typename _Tp> inline
+const _Tp& Mat::at(int i0, int i1, int i2) const
+{
+ CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
+ return *(const _Tp*)ptr(i0, i1, i2);
+}
+
+template<typename _Tp> inline
+_Tp& Mat::at(const int* idx)
+{
+ CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
+ return *(_Tp*)ptr(idx);
+}
+
+template<typename _Tp> inline
+const _Tp& Mat::at(const int* idx) const
+{
+ CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
+ return *(const _Tp*)ptr(idx);
+}
+
+template<typename _Tp, int n> inline
+_Tp& Mat::at(const Vec<int, n>& idx)
+{
+ CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
+ return *(_Tp*)ptr(idx.val);
+}
+
+template<typename _Tp, int n> inline
+const _Tp& Mat::at(const Vec<int, n>& idx) const
+{
+ CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
+ return *(const _Tp*)ptr(idx.val);
+}
+
+template<typename _Tp> inline
+MatConstIterator_<_Tp> Mat::begin() const
+{
+ CV_DbgAssert( elemSize() == sizeof(_Tp) );
+ return MatConstIterator_<_Tp>((const Mat_<_Tp>*)this);
+}
+
+template<typename _Tp> inline
+MatConstIterator_<_Tp> Mat::end() const
+{
+ CV_DbgAssert( elemSize() == sizeof(_Tp) );
+ MatConstIterator_<_Tp> it((const Mat_<_Tp>*)this);
+ it += total();
+ return it;
+}
+
+template<typename _Tp> inline
+MatIterator_<_Tp> Mat::begin()
+{
+ CV_DbgAssert( elemSize() == sizeof(_Tp) );
+ return MatIterator_<_Tp>((Mat_<_Tp>*)this);
+}
+
+template<typename _Tp> inline
+MatIterator_<_Tp> Mat::end()
+{
+ CV_DbgAssert( elemSize() == sizeof(_Tp) );
+ MatIterator_<_Tp> it((Mat_<_Tp>*)this);
+ it += total();
+ return it;
+}
+
+template<typename _Tp, typename Functor> inline
+void Mat::forEach(const Functor& operation) {
+ this->forEach_impl<_Tp>(operation);
+}
+
+template<typename _Tp, typename Functor> inline
+void Mat::forEach(const Functor& operation) const {
+ // call as not const
+ (const_cast<Mat*>(this))->forEach<const _Tp>(operation);
+}
+
+template<typename _Tp> inline
+Mat::operator std::vector<_Tp>() const
+{
+ std::vector<_Tp> v;
+ copyTo(v);
+ return v;
+}
+
+template<typename _Tp, int n> inline
+Mat::operator Vec<_Tp, n>() const
+{
+ CV_Assert( data && dims <= 2 && (rows == 1 || cols == 1) &&
+ rows + cols - 1 == n && channels() == 1 );
+
+ if( isContinuous() && type() == DataType<_Tp>::type )
+ return Vec<_Tp, n>((_Tp*)data);
+ Vec<_Tp, n> v;
+ Mat tmp(rows, cols, DataType<_Tp>::type, v.val);
+ convertTo(tmp, tmp.type());
+ return v;
+}
+
+template<typename _Tp, int m, int n> inline
+Mat::operator Matx<_Tp, m, n>() const
+{
+ CV_Assert( data && dims <= 2 && rows == m && cols == n && channels() == 1 );
+
+ if( isContinuous() && type() == DataType<_Tp>::type )
+ return Matx<_Tp, m, n>((_Tp*)data);
+ Matx<_Tp, m, n> mtx;
+ Mat tmp(rows, cols, DataType<_Tp>::type, mtx.val);
+ convertTo(tmp, tmp.type());
+ return mtx;
+}
+
+template<typename _Tp> inline
+void Mat::push_back(const _Tp& elem)
+{
+ if( !data )
+ {
+ *this = Mat(1, 1, DataType<_Tp>::type, (void*)&elem).clone();
+ return;
+ }
+ CV_Assert(DataType<_Tp>::type == type() && cols == 1
+ /* && dims == 2 (cols == 1 implies dims == 2) */);
+ const uchar* tmp = dataend + step[0];
+ if( !isSubmatrix() && isContinuous() && tmp <= datalimit )
+ {
+ *(_Tp*)(data + (size.p[0]++) * step.p[0]) = elem;
+ dataend = tmp;
+ }
+ else
+ push_back_(&elem);
+}
+
+template<typename _Tp> inline
+void Mat::push_back(const Mat_<_Tp>& m)
+{
+ push_back((const Mat&)m);
+}
+
+template<> inline
+void Mat::push_back(const MatExpr& expr)
+{
+ push_back(static_cast<Mat>(expr));
+}
+
+#ifdef CV_CXX_MOVE_SEMANTICS
+
+inline
+Mat::Mat(Mat&& m)
+ : flags(m.flags), dims(m.dims), rows(m.rows), cols(m.cols), data(m.data),
+ datastart(m.datastart), dataend(m.dataend), datalimit(m.datalimit), allocator(m.allocator),
+ u(m.u), size(&rows)
+{
+ if (m.dims <= 2) // move new step/size info
+ {
+ step[0] = m.step[0];
+ step[1] = m.step[1];
+ }
+ else
+ {
+ CV_DbgAssert(m.step.p != m.step.buf);
+ step.p = m.step.p;
+ size.p = m.size.p;
+ m.step.p = m.step.buf;
+ m.size.p = &m.rows;
+ }
+ m.flags = MAGIC_VAL; m.dims = m.rows = m.cols = 0;
+ m.data = NULL; m.datastart = NULL; m.dataend = NULL; m.datalimit = NULL;
+ m.allocator = NULL;
+ m.u = NULL;
+}
+
+inline
+Mat& Mat::operator = (Mat&& m)
+{
+ if (this == &m)
+ return *this;
+
+ release();
+ flags = m.flags; dims = m.dims; rows = m.rows; cols = m.cols; data = m.data;
+ datastart = m.datastart; dataend = m.dataend; datalimit = m.datalimit; allocator = m.allocator;
+ u = m.u;
+ if (step.p != step.buf) // release self step/size
+ {
+ fastFree(step.p);
+ step.p = step.buf;
+ size.p = &rows;
+ }
+ if (m.dims <= 2) // move new step/size info
+ {
+ step[0] = m.step[0];
+ step[1] = m.step[1];
+ }
+ else
+ {
+ CV_DbgAssert(m.step.p != m.step.buf);
+ step.p = m.step.p;
+ size.p = m.size.p;
+ m.step.p = m.step.buf;
+ m.size.p = &m.rows;
+ }
+ m.flags = MAGIC_VAL; m.dims = m.rows = m.cols = 0;
+ m.data = NULL; m.datastart = NULL; m.dataend = NULL; m.datalimit = NULL;
+ m.allocator = NULL;
+ m.u = NULL;
+ return *this;
+}
+
+#endif
+
+
+///////////////////////////// MatSize ////////////////////////////
+
+inline
+MatSize::MatSize(int* _p)
+ : p(_p) {}
+
+inline
+Size MatSize::operator()() const
+{
+ CV_DbgAssert(p[-1] <= 2);
+ return Size(p[1], p[0]);
+}
+
+inline
+const int& MatSize::operator[](int i) const
+{
+ return p[i];
+}
+
+inline
+int& MatSize::operator[](int i)
+{
+ return p[i];
+}
+
+inline
+MatSize::operator const int*() const
+{
+ return p;
+}
+
+inline
+bool MatSize::operator == (const MatSize& sz) const
+{
+ int d = p[-1];
+ int dsz = sz.p[-1];
+ if( d != dsz )
+ return false;
+ if( d == 2 )
+ return p[0] == sz.p[0] && p[1] == sz.p[1];
+
+ for( int i = 0; i < d; i++ )
+ if( p[i] != sz.p[i] )
+ return false;
+ return true;
+}
+
+inline
+bool MatSize::operator != (const MatSize& sz) const
+{
+ return !(*this == sz);
+}
+
+
+
+///////////////////////////// MatStep ////////////////////////////
+
+inline
+MatStep::MatStep()
+{
+ p = buf; p[0] = p[1] = 0;
+}
+
+inline
+MatStep::MatStep(size_t s)
+{
+ p = buf; p[0] = s; p[1] = 0;
+}
+
+inline
+const size_t& MatStep::operator[](int i) const
+{
+ return p[i];
+}
+
+inline
+size_t& MatStep::operator[](int i)
+{
+ return p[i];
+}
+
+inline MatStep::operator size_t() const
+{
+ CV_DbgAssert( p == buf );
+ return buf[0];
+}
+
+inline MatStep& MatStep::operator = (size_t s)
+{
+ CV_DbgAssert( p == buf );
+ buf[0] = s;
+ return *this;
+}
+
+
+
+////////////////////////////// Mat_<_Tp> ////////////////////////////
+
+template<typename _Tp> inline
+Mat_<_Tp>::Mat_()
+ : Mat()
+{
+ flags = (flags & ~CV_MAT_TYPE_MASK) | DataType<_Tp>::type;
+}
+
+template<typename _Tp> inline
+Mat_<_Tp>::Mat_(int _rows, int _cols)
+ : Mat(_rows, _cols, DataType<_Tp>::type)
+{
+}
+
+template<typename _Tp> inline
+Mat_<_Tp>::Mat_(int _rows, int _cols, const _Tp& value)
+ : Mat(_rows, _cols, DataType<_Tp>::type)
+{
+ *this = value;
+}
+
+template<typename _Tp> inline
+Mat_<_Tp>::Mat_(Size _sz)
+ : Mat(_sz.height, _sz.width, DataType<_Tp>::type)
+{}
+
+template<typename _Tp> inline
+Mat_<_Tp>::Mat_(Size _sz, const _Tp& value)
+ : Mat(_sz.height, _sz.width, DataType<_Tp>::type)
+{
+ *this = value;
+}
+
+template<typename _Tp> inline
+Mat_<_Tp>::Mat_(int _dims, const int* _sz)
+ : Mat(_dims, _sz, DataType<_Tp>::type)
+{}
+
+template<typename _Tp> inline
+Mat_<_Tp>::Mat_(int _dims, const int* _sz, const _Tp& _s)
+ : Mat(_dims, _sz, DataType<_Tp>::type, Scalar(_s))
+{}
+
+template<typename _Tp> inline
+Mat_<_Tp>::Mat_(int _dims, const int* _sz, _Tp* _data, const size_t* _steps)
+ : Mat(_dims, _sz, DataType<_Tp>::type, _data, _steps)
+{}
+
+template<typename _Tp> inline
+Mat_<_Tp>::Mat_(const Mat_<_Tp>& m, const Range* ranges)
+ : Mat(m, ranges)
+{}
+
+template<typename _Tp> inline
+Mat_<_Tp>::Mat_(const Mat_<_Tp>& m, const std::vector<Range>& ranges)
+ : Mat(m, ranges)
+{}
+
+template<typename _Tp> inline
+Mat_<_Tp>::Mat_(const Mat& m)
+ : Mat()
+{
+ flags = (flags & ~CV_MAT_TYPE_MASK) | DataType<_Tp>::type;
+ *this = m;
+}
+
+template<typename _Tp> inline
+Mat_<_Tp>::Mat_(const Mat_& m)
+ : Mat(m)
+{}
+
+template<typename _Tp> inline
+Mat_<_Tp>::Mat_(int _rows, int _cols, _Tp* _data, size_t steps)
+ : Mat(_rows, _cols, DataType<_Tp>::type, _data, steps)
+{}
+
+template<typename _Tp> inline
+Mat_<_Tp>::Mat_(const Mat_& m, const Range& _rowRange, const Range& _colRange)
+ : Mat(m, _rowRange, _colRange)
+{}
+
+template<typename _Tp> inline
+Mat_<_Tp>::Mat_(const Mat_& m, const Rect& roi)
+ : Mat(m, roi)
+{}
+
+template<typename _Tp> template<int n> inline
+Mat_<_Tp>::Mat_(const Vec<typename DataType<_Tp>::channel_type, n>& vec, bool copyData)
+ : Mat(n / DataType<_Tp>::channels, 1, DataType<_Tp>::type, (void*)&vec)
+{
+ CV_Assert(n%DataType<_Tp>::channels == 0);
+ if( copyData )
+ *this = clone();
+}
+
+template<typename _Tp> template<int m, int n> inline
+Mat_<_Tp>::Mat_(const Matx<typename DataType<_Tp>::channel_type, m, n>& M, bool copyData)
+ : Mat(m, n / DataType<_Tp>::channels, DataType<_Tp>::type, (void*)&M)
+{
+ CV_Assert(n % DataType<_Tp>::channels == 0);
+ if( copyData )
+ *this = clone();
+}
+
+template<typename _Tp> inline
+Mat_<_Tp>::Mat_(const Point_<typename DataType<_Tp>::channel_type>& pt, bool copyData)
+ : Mat(2 / DataType<_Tp>::channels, 1, DataType<_Tp>::type, (void*)&pt)
+{
+ CV_Assert(2 % DataType<_Tp>::channels == 0);
+ if( copyData )
+ *this = clone();
+}
+
+template<typename _Tp> inline
+Mat_<_Tp>::Mat_(const Point3_<typename DataType<_Tp>::channel_type>& pt, bool copyData)
+ : Mat(3 / DataType<_Tp>::channels, 1, DataType<_Tp>::type, (void*)&pt)
+{
+ CV_Assert(3 % DataType<_Tp>::channels == 0);
+ if( copyData )
+ *this = clone();
+}
+
+template<typename _Tp> inline
+Mat_<_Tp>::Mat_(const MatCommaInitializer_<_Tp>& commaInitializer)
+ : Mat(commaInitializer)
+{}
+
+template<typename _Tp> inline
+Mat_<_Tp>::Mat_(const std::vector<_Tp>& vec, bool copyData)
+ : Mat(vec, copyData)
+{}
+
+template<typename _Tp> inline
+Mat_<_Tp>& Mat_<_Tp>::operator = (const Mat& m)
+{
+ if( DataType<_Tp>::type == m.type() )
+ {
+ Mat::operator = (m);
+ return *this;
+ }
+ if( DataType<_Tp>::depth == m.depth() )
+ {
+ return (*this = m.reshape(DataType<_Tp>::channels, m.dims, 0));
+ }
+ CV_DbgAssert(DataType<_Tp>::channels == m.channels());
+ m.convertTo(*this, type());
+ return *this;
+}
+
+template<typename _Tp> inline
+Mat_<_Tp>& Mat_<_Tp>::operator = (const Mat_& m)
+{
+ Mat::operator=(m);
+ return *this;
+}
+
+template<typename _Tp> inline
+Mat_<_Tp>& Mat_<_Tp>::operator = (const _Tp& s)
+{
+ typedef typename DataType<_Tp>::vec_type VT;
+ Mat::operator=(Scalar((const VT&)s));
+ return *this;
+}
+
+template<typename _Tp> inline
+void Mat_<_Tp>::create(int _rows, int _cols)
+{
+ Mat::create(_rows, _cols, DataType<_Tp>::type);
+}
+
+template<typename _Tp> inline
+void Mat_<_Tp>::create(Size _sz)
+{
+ Mat::create(_sz, DataType<_Tp>::type);
+}
+
+template<typename _Tp> inline
+void Mat_<_Tp>::create(int _dims, const int* _sz)
+{
+ Mat::create(_dims, _sz, DataType<_Tp>::type);
+}
+
+template<typename _Tp> inline
+Mat_<_Tp> Mat_<_Tp>::cross(const Mat_& m) const
+{
+ return Mat_<_Tp>(Mat::cross(m));
+}
+
+template<typename _Tp> template<typename T2> inline
+Mat_<_Tp>::operator Mat_<T2>() const
+{
+ return Mat_<T2>(*this);
+}
+
+template<typename _Tp> inline
+Mat_<_Tp> Mat_<_Tp>::row(int y) const
+{
+ return Mat_(*this, Range(y, y+1), Range::all());
+}
+
+template<typename _Tp> inline
+Mat_<_Tp> Mat_<_Tp>::col(int x) const
+{
+ return Mat_(*this, Range::all(), Range(x, x+1));
+}
+
+template<typename _Tp> inline
+Mat_<_Tp> Mat_<_Tp>::diag(int d) const
+{
+ return Mat_(Mat::diag(d));
+}
+
+template<typename _Tp> inline
+Mat_<_Tp> Mat_<_Tp>::clone() const
+{
+ return Mat_(Mat::clone());
+}
+
+template<typename _Tp> inline
+size_t Mat_<_Tp>::elemSize() const
+{
+ CV_DbgAssert( Mat::elemSize() == sizeof(_Tp) );
+ return sizeof(_Tp);
+}
+
+template<typename _Tp> inline
+size_t Mat_<_Tp>::elemSize1() const
+{
+ CV_DbgAssert( Mat::elemSize1() == sizeof(_Tp) / DataType<_Tp>::channels );
+ return sizeof(_Tp) / DataType<_Tp>::channels;
+}
+
+template<typename _Tp> inline
+int Mat_<_Tp>::type() const
+{
+ CV_DbgAssert( Mat::type() == DataType<_Tp>::type );
+ return DataType<_Tp>::type;
+}
+
+template<typename _Tp> inline
+int Mat_<_Tp>::depth() const
+{
+ CV_DbgAssert( Mat::depth() == DataType<_Tp>::depth );
+ return DataType<_Tp>::depth;
+}
+
+template<typename _Tp> inline
+int Mat_<_Tp>::channels() const
+{
+ CV_DbgAssert( Mat::channels() == DataType<_Tp>::channels );
+ return DataType<_Tp>::channels;
+}
+
+template<typename _Tp> inline
+size_t Mat_<_Tp>::stepT(int i) const
+{
+ return step.p[i] / elemSize();
+}
+
+template<typename _Tp> inline
+size_t Mat_<_Tp>::step1(int i) const
+{
+ return step.p[i] / elemSize1();
+}
+
+template<typename _Tp> inline
+Mat_<_Tp>& Mat_<_Tp>::adjustROI( int dtop, int dbottom, int dleft, int dright )
+{
+ return (Mat_<_Tp>&)(Mat::adjustROI(dtop, dbottom, dleft, dright));
+}
+
+template<typename _Tp> inline
+Mat_<_Tp> Mat_<_Tp>::operator()( const Range& _rowRange, const Range& _colRange ) const
+{
+ return Mat_<_Tp>(*this, _rowRange, _colRange);
+}
+
+template<typename _Tp> inline
+Mat_<_Tp> Mat_<_Tp>::operator()( const Rect& roi ) const
+{
+ return Mat_<_Tp>(*this, roi);
+}
+
+template<typename _Tp> inline
+Mat_<_Tp> Mat_<_Tp>::operator()( const Range* ranges ) const
+{
+ return Mat_<_Tp>(*this, ranges);
+}
+
+template<typename _Tp> inline
+Mat_<_Tp> Mat_<_Tp>::operator()(const std::vector<Range>& ranges) const
+{
+ return Mat_<_Tp>(*this, ranges);
+}
+
+template<typename _Tp> inline
+_Tp* Mat_<_Tp>::operator [](int y)
+{
+ CV_DbgAssert( 0 <= y && y < rows );
+ return (_Tp*)(data + y*step.p[0]);
+}
+
+template<typename _Tp> inline
+const _Tp* Mat_<_Tp>::operator [](int y) const
+{
+ CV_DbgAssert( 0 <= y && y < rows );
+ return (const _Tp*)(data + y*step.p[0]);
+}
+
+template<typename _Tp> inline
+_Tp& Mat_<_Tp>::operator ()(int i0, int i1)
+{
+ CV_DbgAssert(dims <= 2);
+ CV_DbgAssert(data);
+ CV_DbgAssert((unsigned)i0 < (unsigned)size.p[0]);
+ CV_DbgAssert((unsigned)i1 < (unsigned)size.p[1]);
+ CV_DbgAssert(type() == DataType<_Tp>::type);
+ return ((_Tp*)(data + step.p[0] * i0))[i1];
+}
+
+template<typename _Tp> inline
+const _Tp& Mat_<_Tp>::operator ()(int i0, int i1) const
+{
+ CV_DbgAssert(dims <= 2);
+ CV_DbgAssert(data);
+ CV_DbgAssert((unsigned)i0 < (unsigned)size.p[0]);
+ CV_DbgAssert((unsigned)i1 < (unsigned)size.p[1]);
+ CV_DbgAssert(type() == DataType<_Tp>::type);
+ return ((const _Tp*)(data + step.p[0] * i0))[i1];
+}
+
+template<typename _Tp> inline
+_Tp& Mat_<_Tp>::operator ()(Point pt)
+{
+ CV_DbgAssert(dims <= 2);
+ CV_DbgAssert(data);
+ CV_DbgAssert((unsigned)pt.y < (unsigned)size.p[0]);
+ CV_DbgAssert((unsigned)pt.x < (unsigned)size.p[1]);
+ CV_DbgAssert(type() == DataType<_Tp>::type);
+ return ((_Tp*)(data + step.p[0] * pt.y))[pt.x];
+}
+
+template<typename _Tp> inline
+const _Tp& Mat_<_Tp>::operator ()(Point pt) const
+{
+ CV_DbgAssert(dims <= 2);
+ CV_DbgAssert(data);
+ CV_DbgAssert((unsigned)pt.y < (unsigned)size.p[0]);
+ CV_DbgAssert((unsigned)pt.x < (unsigned)size.p[1]);
+ CV_DbgAssert(type() == DataType<_Tp>::type);
+ return ((const _Tp*)(data + step.p[0] * pt.y))[pt.x];
+}
+
+template<typename _Tp> inline
+_Tp& Mat_<_Tp>::operator ()(const int* idx)
+{
+ return Mat::at<_Tp>(idx);
+}
+
+template<typename _Tp> inline
+const _Tp& Mat_<_Tp>::operator ()(const int* idx) const
+{
+ return Mat::at<_Tp>(idx);
+}
+
+template<typename _Tp> template<int n> inline
+_Tp& Mat_<_Tp>::operator ()(const Vec<int, n>& idx)
+{
+ return Mat::at<_Tp>(idx);
+}
+
+template<typename _Tp> template<int n> inline
+const _Tp& Mat_<_Tp>::operator ()(const Vec<int, n>& idx) const
+{
+ return Mat::at<_Tp>(idx);
+}
+
+template<typename _Tp> inline
+_Tp& Mat_<_Tp>::operator ()(int i0)
+{
+ return this->at<_Tp>(i0);
+}
+
+template<typename _Tp> inline
+const _Tp& Mat_<_Tp>::operator ()(int i0) const
+{
+ return this->at<_Tp>(i0);
+}
+
+template<typename _Tp> inline
+_Tp& Mat_<_Tp>::operator ()(int i0, int i1, int i2)
+{
+ return this->at<_Tp>(i0, i1, i2);
+}
+
+template<typename _Tp> inline
+const _Tp& Mat_<_Tp>::operator ()(int i0, int i1, int i2) const
+{
+ return this->at<_Tp>(i0, i1, i2);
+}
+
+template<typename _Tp> inline
+Mat_<_Tp>::operator std::vector<_Tp>() const
+{
+ std::vector<_Tp> v;
+ copyTo(v);
+ return v;
+}
+
+template<typename _Tp> template<int n> inline
+Mat_<_Tp>::operator Vec<typename DataType<_Tp>::channel_type, n>() const
+{
+ CV_Assert(n % DataType<_Tp>::channels == 0);
+
+#if defined _MSC_VER
+ const Mat* pMat = (const Mat*)this; // workaround for MSVS <= 2012 compiler bugs (but GCC 4.6 dislikes this workaround)
+ return pMat->operator Vec<typename DataType<_Tp>::channel_type, n>();
+#else
+ return this->Mat::operator Vec<typename DataType<_Tp>::channel_type, n>();
+#endif
+}
+
+template<typename _Tp> template<int m, int n> inline
+Mat_<_Tp>::operator Matx<typename DataType<_Tp>::channel_type, m, n>() const
+{
+ CV_Assert(n % DataType<_Tp>::channels == 0);
+
+#if defined _MSC_VER
+ const Mat* pMat = (const Mat*)this; // workaround for MSVS <= 2012 compiler bugs (but GCC 4.6 dislikes this workaround)
+ Matx<typename DataType<_Tp>::channel_type, m, n> res = pMat->operator Matx<typename DataType<_Tp>::channel_type, m, n>();
+ return res;
+#else
+ Matx<typename DataType<_Tp>::channel_type, m, n> res = this->Mat::operator Matx<typename DataType<_Tp>::channel_type, m, n>();
+ return res;
+#endif
+}
+
+template<typename _Tp> inline
+MatConstIterator_<_Tp> Mat_<_Tp>::begin() const
+{
+ return Mat::begin<_Tp>();
+}
+
+template<typename _Tp> inline
+MatConstIterator_<_Tp> Mat_<_Tp>::end() const
+{
+ return Mat::end<_Tp>();
+}
+
+template<typename _Tp> inline
+MatIterator_<_Tp> Mat_<_Tp>::begin()
+{
+ return Mat::begin<_Tp>();
+}
+
+template<typename _Tp> inline
+MatIterator_<_Tp> Mat_<_Tp>::end()
+{
+ return Mat::end<_Tp>();
+}
+
+template<typename _Tp> template<typename Functor> inline
+void Mat_<_Tp>::forEach(const Functor& operation) {
+ Mat::forEach<_Tp, Functor>(operation);
+}
+
+template<typename _Tp> template<typename Functor> inline
+void Mat_<_Tp>::forEach(const Functor& operation) const {
+ Mat::forEach<_Tp, Functor>(operation);
+}
+
+#ifdef CV_CXX_MOVE_SEMANTICS
+
+template<typename _Tp> inline
+Mat_<_Tp>::Mat_(Mat_&& m)
+ : Mat(m)
+{
+}
+
+template<typename _Tp> inline
+Mat_<_Tp>& Mat_<_Tp>::operator = (Mat_&& m)
+{
+ Mat::operator = (m);
+ return *this;
+}
+
+template<typename _Tp> inline
+Mat_<_Tp>::Mat_(Mat&& m)
+ : Mat()
+{
+ flags = (flags & ~CV_MAT_TYPE_MASK) | DataType<_Tp>::type;
+ *this = m;
+}
+
+template<typename _Tp> inline
+Mat_<_Tp>& Mat_<_Tp>::operator = (Mat&& m)
+{
+ if( DataType<_Tp>::type == m.type() )
+ {
+ Mat::operator = ((Mat&&)m);
+ return *this;
+ }
+ if( DataType<_Tp>::depth == m.depth() )
+ {
+ Mat::operator = ((Mat&&)m.reshape(DataType<_Tp>::channels, m.dims, 0));
+ return *this;
+ }
+ CV_DbgAssert(DataType<_Tp>::channels == m.channels());
+ m.convertTo(*this, type());
+ return *this;
+}
+
+template<typename _Tp> inline
+Mat_<_Tp>::Mat_(MatExpr&& e)
+ : Mat()
+{
+ flags = (flags & ~CV_MAT_TYPE_MASK) | DataType<_Tp>::type;
+ *this = Mat(e);
+}
+
+#endif
+
+///////////////////////////// SparseMat /////////////////////////////
+
+inline
+SparseMat::SparseMat()
+ : flags(MAGIC_VAL), hdr(0)
+{}
+
+inline
+SparseMat::SparseMat(int _dims, const int* _sizes, int _type)
+ : flags(MAGIC_VAL), hdr(0)
+{
+ create(_dims, _sizes, _type);
+}
+
+inline
+SparseMat::SparseMat(const SparseMat& m)
+ : flags(m.flags), hdr(m.hdr)
+{
+ addref();
+}
+
+inline
+SparseMat::~SparseMat()
+{
+ release();
+}
+
+inline
+SparseMat& SparseMat::operator = (const SparseMat& m)
+{
+ if( this != &m )
+ {
+ if( m.hdr )
+ CV_XADD(&m.hdr->refcount, 1);
+ release();
+ flags = m.flags;
+ hdr = m.hdr;
+ }
+ return *this;
+}
+
+inline
+SparseMat& SparseMat::operator = (const Mat& m)
+{
+ return (*this = SparseMat(m));
+}
+
+inline
+SparseMat SparseMat::clone() const
+{
+ SparseMat temp;
+ this->copyTo(temp);
+ return temp;
+}
+
+inline
+void SparseMat::assignTo( SparseMat& m, int _type ) const
+{
+ if( _type < 0 )
+ m = *this;
+ else
+ convertTo(m, _type);
+}
+
+inline
+void SparseMat::addref()
+{
+ if( hdr )
+ CV_XADD(&hdr->refcount, 1);
+}
+
+inline
+void SparseMat::release()
+{
+ if( hdr && CV_XADD(&hdr->refcount, -1) == 1 )
+ delete hdr;
+ hdr = 0;
+}
+
+inline
+size_t SparseMat::elemSize() const
+{
+ return CV_ELEM_SIZE(flags);
+}
+
+inline
+size_t SparseMat::elemSize1() const
+{
+ return CV_ELEM_SIZE1(flags);
+}
+
+inline
+int SparseMat::type() const
+{
+ return CV_MAT_TYPE(flags);
+}
+
+inline
+int SparseMat::depth() const
+{
+ return CV_MAT_DEPTH(flags);
+}
+
+inline
+int SparseMat::channels() const
+{
+ return CV_MAT_CN(flags);
+}
+
+inline
+const int* SparseMat::size() const
+{
+ return hdr ? hdr->size : 0;
+}
+
+inline
+int SparseMat::size(int i) const
+{
+ if( hdr )
+ {
+ CV_DbgAssert((unsigned)i < (unsigned)hdr->dims);
+ return hdr->size[i];
+ }
+ return 0;
+}
+
+inline
+int SparseMat::dims() const
+{
+ return hdr ? hdr->dims : 0;
+}
+
+inline
+size_t SparseMat::nzcount() const
+{
+ return hdr ? hdr->nodeCount : 0;
+}
+
+inline
+size_t SparseMat::hash(int i0) const
+{
+ return (size_t)i0;
+}
+
+inline
+size_t SparseMat::hash(int i0, int i1) const
+{
+ return (size_t)(unsigned)i0 * HASH_SCALE + (unsigned)i1;
+}
+
+inline
+size_t SparseMat::hash(int i0, int i1, int i2) const
+{
+ return ((size_t)(unsigned)i0 * HASH_SCALE + (unsigned)i1) * HASH_SCALE + (unsigned)i2;
+}
+
+inline
+size_t SparseMat::hash(const int* idx) const
+{
+ size_t h = (unsigned)idx[0];
+ if( !hdr )
+ return 0;
+ int d = hdr->dims;
+ for(int i = 1; i < d; i++ )
+ h = h * HASH_SCALE + (unsigned)idx[i];
+ return h;
+}
+
+template<typename _Tp> inline
+_Tp& SparseMat::ref(int i0, size_t* hashval)
+{
+ return *(_Tp*)((SparseMat*)this)->ptr(i0, true, hashval);
+}
+
+template<typename _Tp> inline
+_Tp& SparseMat::ref(int i0, int i1, size_t* hashval)
+{
+ return *(_Tp*)((SparseMat*)this)->ptr(i0, i1, true, hashval);
+}
+
+template<typename _Tp> inline
+_Tp& SparseMat::ref(int i0, int i1, int i2, size_t* hashval)
+{
+ return *(_Tp*)((SparseMat*)this)->ptr(i0, i1, i2, true, hashval);
+}
+
+template<typename _Tp> inline
+_Tp& SparseMat::ref(const int* idx, size_t* hashval)
+{
+ return *(_Tp*)((SparseMat*)this)->ptr(idx, true, hashval);
+}
+
+template<typename _Tp> inline
+_Tp SparseMat::value(int i0, size_t* hashval) const
+{
+ const _Tp* p = (const _Tp*)((SparseMat*)this)->ptr(i0, false, hashval);
+ return p ? *p : _Tp();
+}
+
+template<typename _Tp> inline
+_Tp SparseMat::value(int i0, int i1, size_t* hashval) const
+{
+ const _Tp* p = (const _Tp*)((SparseMat*)this)->ptr(i0, i1, false, hashval);
+ return p ? *p : _Tp();
+}
+
+template<typename _Tp> inline
+_Tp SparseMat::value(int i0, int i1, int i2, size_t* hashval) const
+{
+ const _Tp* p = (const _Tp*)((SparseMat*)this)->ptr(i0, i1, i2, false, hashval);
+ return p ? *p : _Tp();
+}
+
+template<typename _Tp> inline
+_Tp SparseMat::value(const int* idx, size_t* hashval) const
+{
+ const _Tp* p = (const _Tp*)((SparseMat*)this)->ptr(idx, false, hashval);
+ return p ? *p : _Tp();
+}
+
+template<typename _Tp> inline
+const _Tp* SparseMat::find(int i0, size_t* hashval) const
+{
+ return (const _Tp*)((SparseMat*)this)->ptr(i0, false, hashval);
+}
+
+template<typename _Tp> inline
+const _Tp* SparseMat::find(int i0, int i1, size_t* hashval) const
+{
+ return (const _Tp*)((SparseMat*)this)->ptr(i0, i1, false, hashval);
+}
+
+template<typename _Tp> inline
+const _Tp* SparseMat::find(int i0, int i1, int i2, size_t* hashval) const
+{
+ return (const _Tp*)((SparseMat*)this)->ptr(i0, i1, i2, false, hashval);
+}
+
+template<typename _Tp> inline
+const _Tp* SparseMat::find(const int* idx, size_t* hashval) const
+{
+ return (const _Tp*)((SparseMat*)this)->ptr(idx, false, hashval);
+}
+
+template<typename _Tp> inline
+_Tp& SparseMat::value(Node* n)
+{
+ return *(_Tp*)((uchar*)n + hdr->valueOffset);
+}
+
+template<typename _Tp> inline
+const _Tp& SparseMat::value(const Node* n) const
+{
+ return *(const _Tp*)((const uchar*)n + hdr->valueOffset);
+}
+
+inline
+SparseMat::Node* SparseMat::node(size_t nidx)
+{
+ return (Node*)(void*)&hdr->pool[nidx];
+}
+
+inline
+const SparseMat::Node* SparseMat::node(size_t nidx) const
+{
+ return (const Node*)(const void*)&hdr->pool[nidx];
+}
+
+inline
+SparseMatIterator SparseMat::begin()
+{
+ return SparseMatIterator(this);
+}
+
+inline
+SparseMatConstIterator SparseMat::begin() const
+{
+ return SparseMatConstIterator(this);
+}
+
+inline
+SparseMatIterator SparseMat::end()
+{
+ SparseMatIterator it(this);
+ it.seekEnd();
+ return it;
+}
+
+inline
+SparseMatConstIterator SparseMat::end() const
+{
+ SparseMatConstIterator it(this);
+ it.seekEnd();
+ return it;
+}
+
+template<typename _Tp> inline
+SparseMatIterator_<_Tp> SparseMat::begin()
+{
+ return SparseMatIterator_<_Tp>(this);
+}
+
+template<typename _Tp> inline
+SparseMatConstIterator_<_Tp> SparseMat::begin() const
+{
+ return SparseMatConstIterator_<_Tp>(this);
+}
+
+template<typename _Tp> inline
+SparseMatIterator_<_Tp> SparseMat::end()
+{
+ SparseMatIterator_<_Tp> it(this);
+ it.seekEnd();
+ return it;
+}
+
+template<typename _Tp> inline
+SparseMatConstIterator_<_Tp> SparseMat::end() const
+{
+ SparseMatConstIterator_<_Tp> it(this);
+ it.seekEnd();
+ return it;
+}
+
+
+
+///////////////////////////// SparseMat_ ////////////////////////////
+
+template<typename _Tp> inline
+SparseMat_<_Tp>::SparseMat_()
+{
+ flags = MAGIC_VAL | DataType<_Tp>::type;
+}
+
+template<typename _Tp> inline
+SparseMat_<_Tp>::SparseMat_(int _dims, const int* _sizes)
+ : SparseMat(_dims, _sizes, DataType<_Tp>::type)
+{}
+
+template<typename _Tp> inline
+SparseMat_<_Tp>::SparseMat_(const SparseMat& m)
+{
+ if( m.type() == DataType<_Tp>::type )
+ *this = (const SparseMat_<_Tp>&)m;
+ else
+ m.convertTo(*this, DataType<_Tp>::type);
+}
+
+template<typename _Tp> inline
+SparseMat_<_Tp>::SparseMat_(const SparseMat_<_Tp>& m)
+{
+ this->flags = m.flags;
+ this->hdr = m.hdr;
+ if( this->hdr )
+ CV_XADD(&this->hdr->refcount, 1);
+}
+
+template<typename _Tp> inline
+SparseMat_<_Tp>::SparseMat_(const Mat& m)
+{
+ SparseMat sm(m);
+ *this = sm;
+}
+
+template<typename _Tp> inline
+SparseMat_<_Tp>& SparseMat_<_Tp>::operator = (const SparseMat_<_Tp>& m)
+{
+ if( this != &m )
+ {
+ if( m.hdr ) CV_XADD(&m.hdr->refcount, 1);
+ release();
+ flags = m.flags;
+ hdr = m.hdr;
+ }
+ return *this;
+}
+
+template<typename _Tp> inline
+SparseMat_<_Tp>& SparseMat_<_Tp>::operator = (const SparseMat& m)
+{
+ if( m.type() == DataType<_Tp>::type )
+ return (*this = (const SparseMat_<_Tp>&)m);
+ m.convertTo(*this, DataType<_Tp>::type);
+ return *this;
+}
+
+template<typename _Tp> inline
+SparseMat_<_Tp>& SparseMat_<_Tp>::operator = (const Mat& m)
+{
+ return (*this = SparseMat(m));
+}
+
+template<typename _Tp> inline
+SparseMat_<_Tp> SparseMat_<_Tp>::clone() const
+{
+ SparseMat_<_Tp> m;
+ this->copyTo(m);
+ return m;
+}
+
+template<typename _Tp> inline
+void SparseMat_<_Tp>::create(int _dims, const int* _sizes)
+{
+ SparseMat::create(_dims, _sizes, DataType<_Tp>::type);
+}
+
+template<typename _Tp> inline
+int SparseMat_<_Tp>::type() const
+{
+ return DataType<_Tp>::type;
+}
+
+template<typename _Tp> inline
+int SparseMat_<_Tp>::depth() const
+{
+ return DataType<_Tp>::depth;
+}
+
+template<typename _Tp> inline
+int SparseMat_<_Tp>::channels() const
+{
+ return DataType<_Tp>::channels;
+}
+
+template<typename _Tp> inline
+_Tp& SparseMat_<_Tp>::ref(int i0, size_t* hashval)
+{
+ return SparseMat::ref<_Tp>(i0, hashval);
+}
+
+template<typename _Tp> inline
+_Tp SparseMat_<_Tp>::operator()(int i0, size_t* hashval) const
+{
+ return SparseMat::value<_Tp>(i0, hashval);
+}
+
+template<typename _Tp> inline
+_Tp& SparseMat_<_Tp>::ref(int i0, int i1, size_t* hashval)
+{
+ return SparseMat::ref<_Tp>(i0, i1, hashval);
+}
+
+template<typename _Tp> inline
+_Tp SparseMat_<_Tp>::operator()(int i0, int i1, size_t* hashval) const
+{
+ return SparseMat::value<_Tp>(i0, i1, hashval);
+}
+
+template<typename _Tp> inline
+_Tp& SparseMat_<_Tp>::ref(int i0, int i1, int i2, size_t* hashval)
+{
+ return SparseMat::ref<_Tp>(i0, i1, i2, hashval);
+}
+
+template<typename _Tp> inline
+_Tp SparseMat_<_Tp>::operator()(int i0, int i1, int i2, size_t* hashval) const
+{
+ return SparseMat::value<_Tp>(i0, i1, i2, hashval);
+}
+
+template<typename _Tp> inline
+_Tp& SparseMat_<_Tp>::ref(const int* idx, size_t* hashval)
+{
+ return SparseMat::ref<_Tp>(idx, hashval);
+}
+
+template<typename _Tp> inline
+_Tp SparseMat_<_Tp>::operator()(const int* idx, size_t* hashval) const
+{
+ return SparseMat::value<_Tp>(idx, hashval);
+}
+
+template<typename _Tp> inline
+SparseMatIterator_<_Tp> SparseMat_<_Tp>::begin()
+{
+ return SparseMatIterator_<_Tp>(this);
+}
+
+template<typename _Tp> inline
+SparseMatConstIterator_<_Tp> SparseMat_<_Tp>::begin() const
+{
+ return SparseMatConstIterator_<_Tp>(this);
+}
+
+template<typename _Tp> inline
+SparseMatIterator_<_Tp> SparseMat_<_Tp>::end()
+{
+ SparseMatIterator_<_Tp> it(this);
+ it.seekEnd();
+ return it;
+}
+
+template<typename _Tp> inline
+SparseMatConstIterator_<_Tp> SparseMat_<_Tp>::end() const
+{
+ SparseMatConstIterator_<_Tp> it(this);
+ it.seekEnd();
+ return it;
+}
+
+
+
+////////////////////////// MatConstIterator /////////////////////////
+
+inline
+MatConstIterator::MatConstIterator()
+ : m(0), elemSize(0), ptr(0), sliceStart(0), sliceEnd(0)
+{}
+
+inline
+MatConstIterator::MatConstIterator(const Mat* _m)
+ : m(_m), elemSize(_m->elemSize()), ptr(0), sliceStart(0), sliceEnd(0)
+{
+ if( m && m->isContinuous() )
+ {
+ sliceStart = m->ptr();
+ sliceEnd = sliceStart + m->total()*elemSize;
+ }
+ seek((const int*)0);
+}
+
+inline
+MatConstIterator::MatConstIterator(const Mat* _m, int _row, int _col)
+ : m(_m), elemSize(_m->elemSize()), ptr(0), sliceStart(0), sliceEnd(0)
+{
+ CV_Assert(m && m->dims <= 2);
+ if( m->isContinuous() )
+ {
+ sliceStart = m->ptr();
+ sliceEnd = sliceStart + m->total()*elemSize;
+ }
+ int idx[] = {_row, _col};
+ seek(idx);
+}
+
+inline
+MatConstIterator::MatConstIterator(const Mat* _m, Point _pt)
+ : m(_m), elemSize(_m->elemSize()), ptr(0), sliceStart(0), sliceEnd(0)
+{
+ CV_Assert(m && m->dims <= 2);
+ if( m->isContinuous() )
+ {
+ sliceStart = m->ptr();
+ sliceEnd = sliceStart + m->total()*elemSize;
+ }
+ int idx[] = {_pt.y, _pt.x};
+ seek(idx);
+}
+
+inline
+MatConstIterator::MatConstIterator(const MatConstIterator& it)
+ : m(it.m), elemSize(it.elemSize), ptr(it.ptr), sliceStart(it.sliceStart), sliceEnd(it.sliceEnd)
+{}
+
+inline
+MatConstIterator& MatConstIterator::operator = (const MatConstIterator& it )
+{
+ m = it.m; elemSize = it.elemSize; ptr = it.ptr;
+ sliceStart = it.sliceStart; sliceEnd = it.sliceEnd;
+ return *this;
+}
+
+inline
+const uchar* MatConstIterator::operator *() const
+{
+ return ptr;
+}
+
+inline MatConstIterator& MatConstIterator::operator += (ptrdiff_t ofs)
+{
+ if( !m || ofs == 0 )
+ return *this;
+ ptrdiff_t ofsb = ofs*elemSize;
+ ptr += ofsb;
+ if( ptr < sliceStart || sliceEnd <= ptr )
+ {
+ ptr -= ofsb;
+ seek(ofs, true);
+ }
+ return *this;
+}
+
+inline
+MatConstIterator& MatConstIterator::operator -= (ptrdiff_t ofs)
+{
+ return (*this += -ofs);
+}
+
+inline
+MatConstIterator& MatConstIterator::operator --()
+{
+ if( m && (ptr -= elemSize) < sliceStart )
+ {
+ ptr += elemSize;
+ seek(-1, true);
+ }
+ return *this;
+}
+
+inline
+MatConstIterator MatConstIterator::operator --(int)
+{
+ MatConstIterator b = *this;
+ *this += -1;
+ return b;
+}
+
+inline
+MatConstIterator& MatConstIterator::operator ++()
+{
+ if( m && (ptr += elemSize) >= sliceEnd )
+ {
+ ptr -= elemSize;
+ seek(1, true);
+ }
+ return *this;
+}
+
+inline MatConstIterator MatConstIterator::operator ++(int)
+{
+ MatConstIterator b = *this;
+ *this += 1;
+ return b;
+}
+
+
+static inline
+bool operator == (const MatConstIterator& a, const MatConstIterator& b)
+{
+ return a.m == b.m && a.ptr == b.ptr;
+}
+
+static inline
+bool operator != (const MatConstIterator& a, const MatConstIterator& b)
+{
+ return !(a == b);
+}
+
+static inline
+bool operator < (const MatConstIterator& a, const MatConstIterator& b)
+{
+ return a.ptr < b.ptr;
+}
+
+static inline
+bool operator > (const MatConstIterator& a, const MatConstIterator& b)
+{
+ return a.ptr > b.ptr;
+}
+
+static inline
+bool operator <= (const MatConstIterator& a, const MatConstIterator& b)
+{
+ return a.ptr <= b.ptr;
+}
+
+static inline
+bool operator >= (const MatConstIterator& a, const MatConstIterator& b)
+{
+ return a.ptr >= b.ptr;
+}
+
+static inline
+ptrdiff_t operator - (const MatConstIterator& b, const MatConstIterator& a)
+{
+ if( a.m != b.m )
+ return ((size_t)(-1) >> 1);
+ if( a.sliceEnd == b.sliceEnd )
+ return (b.ptr - a.ptr)/static_cast<ptrdiff_t>(b.elemSize);
+
+ return b.lpos() - a.lpos();
+}
+
+static inline
+MatConstIterator operator + (const MatConstIterator& a, ptrdiff_t ofs)
+{
+ MatConstIterator b = a;
+ return b += ofs;
+}
+
+static inline
+MatConstIterator operator + (ptrdiff_t ofs, const MatConstIterator& a)
+{
+ MatConstIterator b = a;
+ return b += ofs;
+}
+
+static inline
+MatConstIterator operator - (const MatConstIterator& a, ptrdiff_t ofs)
+{
+ MatConstIterator b = a;
+ return b += -ofs;
+}
+
+
+inline
+const uchar* MatConstIterator::operator [](ptrdiff_t i) const
+{
+ return *(*this + i);
+}
+
+
+
+///////////////////////// MatConstIterator_ /////////////////////////
+
+template<typename _Tp> inline
+MatConstIterator_<_Tp>::MatConstIterator_()
+{}
+
+template<typename _Tp> inline
+MatConstIterator_<_Tp>::MatConstIterator_(const Mat_<_Tp>* _m)
+ : MatConstIterator(_m)
+{}
+
+template<typename _Tp> inline
+MatConstIterator_<_Tp>::MatConstIterator_(const Mat_<_Tp>* _m, int _row, int _col)
+ : MatConstIterator(_m, _row, _col)
+{}
+
+template<typename _Tp> inline
+MatConstIterator_<_Tp>::MatConstIterator_(const Mat_<_Tp>* _m, Point _pt)
+ : MatConstIterator(_m, _pt)
+{}
+
+template<typename _Tp> inline
+MatConstIterator_<_Tp>::MatConstIterator_(const MatConstIterator_& it)
+ : MatConstIterator(it)
+{}
+
+template<typename _Tp> inline
+MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator = (const MatConstIterator_& it )
+{
+ MatConstIterator::operator = (it);
+ return *this;
+}
+
+template<typename _Tp> inline
+const _Tp& MatConstIterator_<_Tp>::operator *() const
+{
+ return *(_Tp*)(this->ptr);
+}
+
+template<typename _Tp> inline
+MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator += (ptrdiff_t ofs)
+{
+ MatConstIterator::operator += (ofs);
+ return *this;
+}
+
+template<typename _Tp> inline
+MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator -= (ptrdiff_t ofs)
+{
+ return (*this += -ofs);
+}
+
+template<typename _Tp> inline
+MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator --()
+{
+ MatConstIterator::operator --();
+ return *this;
+}
+
+template<typename _Tp> inline
+MatConstIterator_<_Tp> MatConstIterator_<_Tp>::operator --(int)
+{
+ MatConstIterator_ b = *this;
+ MatConstIterator::operator --();
+ return b;
+}
+
+template<typename _Tp> inline
+MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator ++()
+{
+ MatConstIterator::operator ++();
+ return *this;
+}
+
+template<typename _Tp> inline
+MatConstIterator_<_Tp> MatConstIterator_<_Tp>::operator ++(int)
+{
+ MatConstIterator_ b = *this;
+ MatConstIterator::operator ++();
+ return b;
+}
+
+
+template<typename _Tp> inline
+Point MatConstIterator_<_Tp>::pos() const
+{
+ if( !m )
+ return Point();
+ CV_DbgAssert( m->dims <= 2 );
+ if( m->isContinuous() )
+ {
+ ptrdiff_t ofs = (const _Tp*)ptr - (const _Tp*)m->data;
+ int y = (int)(ofs / m->cols);
+ int x = (int)(ofs - (ptrdiff_t)y * m->cols);
+ return Point(x, y);
+ }
+ else
+ {
+ ptrdiff_t ofs = (uchar*)ptr - m->data;
+ int y = (int)(ofs / m->step);
+ int x = (int)((ofs - y * m->step)/sizeof(_Tp));
+ return Point(x, y);
+ }
+}
+
+
+template<typename _Tp> static inline
+bool operator == (const MatConstIterator_<_Tp>& a, const MatConstIterator_<_Tp>& b)
+{
+ return a.m == b.m && a.ptr == b.ptr;
+}
+
+template<typename _Tp> static inline
+bool operator != (const MatConstIterator_<_Tp>& a, const MatConstIterator_<_Tp>& b)
+{
+ return a.m != b.m || a.ptr != b.ptr;
+}
+
+template<typename _Tp> static inline
+MatConstIterator_<_Tp> operator + (const MatConstIterator_<_Tp>& a, ptrdiff_t ofs)
+{
+ MatConstIterator t = (const MatConstIterator&)a + ofs;
+ return (MatConstIterator_<_Tp>&)t;
+}
+
+template<typename _Tp> static inline
+MatConstIterator_<_Tp> operator + (ptrdiff_t ofs, const MatConstIterator_<_Tp>& a)
+{
+ MatConstIterator t = (const MatConstIterator&)a + ofs;
+ return (MatConstIterator_<_Tp>&)t;
+}
+
+template<typename _Tp> static inline
+MatConstIterator_<_Tp> operator - (const MatConstIterator_<_Tp>& a, ptrdiff_t ofs)
+{
+ MatConstIterator t = (const MatConstIterator&)a - ofs;
+ return (MatConstIterator_<_Tp>&)t;
+}
+
+template<typename _Tp> inline
+const _Tp& MatConstIterator_<_Tp>::operator [](ptrdiff_t i) const
+{
+ return *(_Tp*)MatConstIterator::operator [](i);
+}
+
+
+
+//////////////////////////// MatIterator_ ///////////////////////////
+
+template<typename _Tp> inline
+MatIterator_<_Tp>::MatIterator_()
+ : MatConstIterator_<_Tp>()
+{}
+
+template<typename _Tp> inline
+MatIterator_<_Tp>::MatIterator_(Mat_<_Tp>* _m)
+ : MatConstIterator_<_Tp>(_m)
+{}
+
+template<typename _Tp> inline
+MatIterator_<_Tp>::MatIterator_(Mat_<_Tp>* _m, int _row, int _col)
+ : MatConstIterator_<_Tp>(_m, _row, _col)
+{}
+
+template<typename _Tp> inline
+MatIterator_<_Tp>::MatIterator_(Mat_<_Tp>* _m, Point _pt)
+ : MatConstIterator_<_Tp>(_m, _pt)
+{}
+
+template<typename _Tp> inline
+MatIterator_<_Tp>::MatIterator_(Mat_<_Tp>* _m, const int* _idx)
+ : MatConstIterator_<_Tp>(_m, _idx)
+{}
+
+template<typename _Tp> inline
+MatIterator_<_Tp>::MatIterator_(const MatIterator_& it)
+ : MatConstIterator_<_Tp>(it)
+{}
+
+template<typename _Tp> inline
+MatIterator_<_Tp>& MatIterator_<_Tp>::operator = (const MatIterator_<_Tp>& it )
+{
+ MatConstIterator::operator = (it);
+ return *this;
+}
+
+template<typename _Tp> inline
+_Tp& MatIterator_<_Tp>::operator *() const
+{
+ return *(_Tp*)(this->ptr);
+}
+
+template<typename _Tp> inline
+MatIterator_<_Tp>& MatIterator_<_Tp>::operator += (ptrdiff_t ofs)
+{
+ MatConstIterator::operator += (ofs);
+ return *this;
+}
+
+template<typename _Tp> inline
+MatIterator_<_Tp>& MatIterator_<_Tp>::operator -= (ptrdiff_t ofs)
+{
+ MatConstIterator::operator += (-ofs);
+ return *this;
+}
+
+template<typename _Tp> inline
+MatIterator_<_Tp>& MatIterator_<_Tp>::operator --()
+{
+ MatConstIterator::operator --();
+ return *this;
+}
+
+template<typename _Tp> inline
+MatIterator_<_Tp> MatIterator_<_Tp>::operator --(int)
+{
+ MatIterator_ b = *this;
+ MatConstIterator::operator --();
+ return b;
+}
+
+template<typename _Tp> inline
+MatIterator_<_Tp>& MatIterator_<_Tp>::operator ++()
+{
+ MatConstIterator::operator ++();
+ return *this;
+}
+
+template<typename _Tp> inline
+MatIterator_<_Tp> MatIterator_<_Tp>::operator ++(int)
+{
+ MatIterator_ b = *this;
+ MatConstIterator::operator ++();
+ return b;
+}
+
+template<typename _Tp> inline
+_Tp& MatIterator_<_Tp>::operator [](ptrdiff_t i) const
+{
+ return *(*this + i);
+}
+
+
+template<typename _Tp> static inline
+bool operator == (const MatIterator_<_Tp>& a, const MatIterator_<_Tp>& b)
+{
+ return a.m == b.m && a.ptr == b.ptr;
+}
+
+template<typename _Tp> static inline
+bool operator != (const MatIterator_<_Tp>& a, const MatIterator_<_Tp>& b)
+{
+ return a.m != b.m || a.ptr != b.ptr;
+}
+
+template<typename _Tp> static inline
+MatIterator_<_Tp> operator + (const MatIterator_<_Tp>& a, ptrdiff_t ofs)
+{
+ MatConstIterator t = (const MatConstIterator&)a + ofs;
+ return (MatIterator_<_Tp>&)t;
+}
+
+template<typename _Tp> static inline
+MatIterator_<_Tp> operator + (ptrdiff_t ofs, const MatIterator_<_Tp>& a)
+{
+ MatConstIterator t = (const MatConstIterator&)a + ofs;
+ return (MatIterator_<_Tp>&)t;
+}
+
+template<typename _Tp> static inline
+MatIterator_<_Tp> operator - (const MatIterator_<_Tp>& a, ptrdiff_t ofs)
+{
+ MatConstIterator t = (const MatConstIterator&)a - ofs;
+ return (MatIterator_<_Tp>&)t;
+}
+
+
+
+/////////////////////// SparseMatConstIterator //////////////////////
+
+inline
+SparseMatConstIterator::SparseMatConstIterator()
+ : m(0), hashidx(0), ptr(0)
+{}
+
+inline
+SparseMatConstIterator::SparseMatConstIterator(const SparseMatConstIterator& it)
+ : m(it.m), hashidx(it.hashidx), ptr(it.ptr)
+{}
+
+inline SparseMatConstIterator& SparseMatConstIterator::operator = (const SparseMatConstIterator& it)
+{
+ if( this != &it )
+ {
+ m = it.m;
+ hashidx = it.hashidx;
+ ptr = it.ptr;
+ }
+ return *this;
+}
+
+template<typename _Tp> inline
+const _Tp& SparseMatConstIterator::value() const
+{
+ return *(const _Tp*)ptr;
+}
+
+inline
+const SparseMat::Node* SparseMatConstIterator::node() const
+{
+ return (ptr && m && m->hdr) ? (const SparseMat::Node*)(const void*)(ptr - m->hdr->valueOffset) : 0;
+}
+
+inline
+SparseMatConstIterator SparseMatConstIterator::operator ++(int)
+{
+ SparseMatConstIterator it = *this;
+ ++*this;
+ return it;
+}
+
+inline
+void SparseMatConstIterator::seekEnd()
+{
+ if( m && m->hdr )
+ {
+ hashidx = m->hdr->hashtab.size();
+ ptr = 0;
+ }
+}
+
+
+static inline
+bool operator == (const SparseMatConstIterator& it1, const SparseMatConstIterator& it2)
+{
+ return it1.m == it2.m && it1.ptr == it2.ptr;
+}
+
+static inline
+bool operator != (const SparseMatConstIterator& it1, const SparseMatConstIterator& it2)
+{
+ return !(it1 == it2);
+}
+
+
+
+///////////////////////// SparseMatIterator /////////////////////////
+
+inline
+SparseMatIterator::SparseMatIterator()
+{}
+
+inline
+SparseMatIterator::SparseMatIterator(SparseMat* _m)
+ : SparseMatConstIterator(_m)
+{}
+
+inline
+SparseMatIterator::SparseMatIterator(const SparseMatIterator& it)
+ : SparseMatConstIterator(it)
+{}
+
+inline
+SparseMatIterator& SparseMatIterator::operator = (const SparseMatIterator& it)
+{
+ (SparseMatConstIterator&)*this = it;
+ return *this;
+}
+
+template<typename _Tp> inline
+_Tp& SparseMatIterator::value() const
+{
+ return *(_Tp*)ptr;
+}
+
+inline
+SparseMat::Node* SparseMatIterator::node() const
+{
+ return (SparseMat::Node*)SparseMatConstIterator::node();
+}
+
+inline
+SparseMatIterator& SparseMatIterator::operator ++()
+{
+ SparseMatConstIterator::operator ++();
+ return *this;
+}
+
+inline
+SparseMatIterator SparseMatIterator::operator ++(int)
+{
+ SparseMatIterator it = *this;
+ ++*this;
+ return it;
+}
+
+
+
+////////////////////// SparseMatConstIterator_ //////////////////////
+
+template<typename _Tp> inline
+SparseMatConstIterator_<_Tp>::SparseMatConstIterator_()
+{}
+
+template<typename _Tp> inline
+SparseMatConstIterator_<_Tp>::SparseMatConstIterator_(const SparseMat_<_Tp>* _m)
+ : SparseMatConstIterator(_m)
+{}
+
+template<typename _Tp> inline
+SparseMatConstIterator_<_Tp>::SparseMatConstIterator_(const SparseMat* _m)
+ : SparseMatConstIterator(_m)
+{
+ CV_Assert( _m->type() == DataType<_Tp>::type );
+}
+
+template<typename _Tp> inline
+SparseMatConstIterator_<_Tp>::SparseMatConstIterator_(const SparseMatConstIterator_<_Tp>& it)
+ : SparseMatConstIterator(it)
+{}
+
+template<typename _Tp> inline
+SparseMatConstIterator_<_Tp>& SparseMatConstIterator_<_Tp>::operator = (const SparseMatConstIterator_<_Tp>& it)
+{
+ return reinterpret_cast<SparseMatConstIterator_<_Tp>&>
+ (*reinterpret_cast<SparseMatConstIterator*>(this) =
+ reinterpret_cast<const SparseMatConstIterator&>(it));
+}
+
+template<typename _Tp> inline
+const _Tp& SparseMatConstIterator_<_Tp>::operator *() const
+{
+ return *(const _Tp*)this->ptr;
+}
+
+template<typename _Tp> inline
+SparseMatConstIterator_<_Tp>& SparseMatConstIterator_<_Tp>::operator ++()
+{
+ SparseMatConstIterator::operator ++();
+ return *this;
+}
+
+template<typename _Tp> inline
+SparseMatConstIterator_<_Tp> SparseMatConstIterator_<_Tp>::operator ++(int)
+{
+ SparseMatConstIterator_<_Tp> it = *this;
+ SparseMatConstIterator::operator ++();
+ return it;
+}
+
+
+
+///////////////////////// SparseMatIterator_ ////////////////////////
+
+template<typename _Tp> inline
+SparseMatIterator_<_Tp>::SparseMatIterator_()
+{}
+
+template<typename _Tp> inline
+SparseMatIterator_<_Tp>::SparseMatIterator_(SparseMat_<_Tp>* _m)
+ : SparseMatConstIterator_<_Tp>(_m)
+{}
+
+template<typename _Tp> inline
+SparseMatIterator_<_Tp>::SparseMatIterator_(SparseMat* _m)
+ : SparseMatConstIterator_<_Tp>(_m)
+{}
+
+template<typename _Tp> inline
+SparseMatIterator_<_Tp>::SparseMatIterator_(const SparseMatIterator_<_Tp>& it)
+ : SparseMatConstIterator_<_Tp>(it)
+{}
+
+template<typename _Tp> inline
+SparseMatIterator_<_Tp>& SparseMatIterator_<_Tp>::operator = (const SparseMatIterator_<_Tp>& it)
+{
+ return reinterpret_cast<SparseMatIterator_<_Tp>&>
+ (*reinterpret_cast<SparseMatConstIterator*>(this) =
+ reinterpret_cast<const SparseMatConstIterator&>(it));
+}
+
+template<typename _Tp> inline
+_Tp& SparseMatIterator_<_Tp>::operator *() const
+{
+ return *(_Tp*)this->ptr;
+}
+
+template<typename _Tp> inline
+SparseMatIterator_<_Tp>& SparseMatIterator_<_Tp>::operator ++()
+{
+ SparseMatConstIterator::operator ++();
+ return *this;
+}
+
+template<typename _Tp> inline
+SparseMatIterator_<_Tp> SparseMatIterator_<_Tp>::operator ++(int)
+{
+ SparseMatIterator_<_Tp> it = *this;
+ SparseMatConstIterator::operator ++();
+ return it;
+}
+
+
+
+//////////////////////// MatCommaInitializer_ ///////////////////////
+
+template<typename _Tp> inline
+MatCommaInitializer_<_Tp>::MatCommaInitializer_(Mat_<_Tp>* _m)
+ : it(_m)
+{}
+
+template<typename _Tp> template<typename T2> inline
+MatCommaInitializer_<_Tp>& MatCommaInitializer_<_Tp>::operator , (T2 v)
+{
+ CV_DbgAssert( this->it < ((const Mat_<_Tp>*)this->it.m)->end() );
+ *this->it = _Tp(v);
+ ++this->it;
+ return *this;
+}
+
+template<typename _Tp> inline
+MatCommaInitializer_<_Tp>::operator Mat_<_Tp>() const
+{
+ CV_DbgAssert( this->it == ((const Mat_<_Tp>*)this->it.m)->end() );
+ return Mat_<_Tp>(*this->it.m);
+}
+
+
+template<typename _Tp, typename T2> static inline
+MatCommaInitializer_<_Tp> operator << (const Mat_<_Tp>& m, T2 val)
+{
+ MatCommaInitializer_<_Tp> commaInitializer((Mat_<_Tp>*)&m);
+ return (commaInitializer, val);
+}
+
+
+
+///////////////////////// Matrix Expressions ////////////////////////
+
+inline
+Mat& Mat::operator = (const MatExpr& e)
+{
+ e.op->assign(e, *this);
+ return *this;
+}
+
+template<typename _Tp> inline
+Mat_<_Tp>::Mat_(const MatExpr& e)
+{
+ e.op->assign(e, *this, DataType<_Tp>::type);
+}
+
+template<typename _Tp> inline
+Mat_<_Tp>& Mat_<_Tp>::operator = (const MatExpr& e)
+{
+ e.op->assign(e, *this, DataType<_Tp>::type);
+ return *this;
+}
+
+template<typename _Tp> inline
+MatExpr Mat_<_Tp>::zeros(int rows, int cols)
+{
+ return Mat::zeros(rows, cols, DataType<_Tp>::type);
+}
+
+template<typename _Tp> inline
+MatExpr Mat_<_Tp>::zeros(Size sz)
+{
+ return Mat::zeros(sz, DataType<_Tp>::type);
+}
+
+template<typename _Tp> inline
+MatExpr Mat_<_Tp>::ones(int rows, int cols)
+{
+ return Mat::ones(rows, cols, DataType<_Tp>::type);
+}
+
+template<typename _Tp> inline
+MatExpr Mat_<_Tp>::ones(Size sz)
+{
+ return Mat::ones(sz, DataType<_Tp>::type);
+}
+
+template<typename _Tp> inline
+MatExpr Mat_<_Tp>::eye(int rows, int cols)
+{
+ return Mat::eye(rows, cols, DataType<_Tp>::type);
+}
+
+template<typename _Tp> inline
+MatExpr Mat_<_Tp>::eye(Size sz)
+{
+ return Mat::eye(sz, DataType<_Tp>::type);
+}
+
+inline
+MatExpr::MatExpr()
+ : op(0), flags(0), a(Mat()), b(Mat()), c(Mat()), alpha(0), beta(0), s()
+{}
+
+inline
+MatExpr::MatExpr(const MatOp* _op, int _flags, const Mat& _a, const Mat& _b,
+ const Mat& _c, double _alpha, double _beta, const Scalar& _s)
+ : op(_op), flags(_flags), a(_a), b(_b), c(_c), alpha(_alpha), beta(_beta), s(_s)
+{}
+
+inline
+MatExpr::operator Mat() const
+{
+ Mat m;
+ op->assign(*this, m);
+ return m;
+}
+
+template<typename _Tp> inline
+MatExpr::operator Mat_<_Tp>() const
+{
+ Mat_<_Tp> m;
+ op->assign(*this, m, DataType<_Tp>::type);
+ return m;
+}
+
+
+template<typename _Tp> static inline
+MatExpr min(const Mat_<_Tp>& a, const Mat_<_Tp>& b)
+{
+ return cv::min((const Mat&)a, (const Mat&)b);
+}
+
+template<typename _Tp> static inline
+MatExpr min(const Mat_<_Tp>& a, double s)
+{
+ return cv::min((const Mat&)a, s);
+}
+
+template<typename _Tp> static inline
+MatExpr min(double s, const Mat_<_Tp>& a)
+{
+ return cv::min((const Mat&)a, s);
+}
+
+template<typename _Tp> static inline
+MatExpr max(const Mat_<_Tp>& a, const Mat_<_Tp>& b)
+{
+ return cv::max((const Mat&)a, (const Mat&)b);
+}
+
+template<typename _Tp> static inline
+MatExpr max(const Mat_<_Tp>& a, double s)
+{
+ return cv::max((const Mat&)a, s);
+}
+
+template<typename _Tp> static inline
+MatExpr max(double s, const Mat_<_Tp>& a)
+{
+ return cv::max((const Mat&)a, s);
+}
+
+template<typename _Tp> static inline
+MatExpr abs(const Mat_<_Tp>& m)
+{
+ return cv::abs((const Mat&)m);
+}
+
+
+static inline
+Mat& operator += (Mat& a, const MatExpr& b)
+{
+ b.op->augAssignAdd(b, a);
+ return a;
+}
+
+static inline
+const Mat& operator += (const Mat& a, const MatExpr& b)
+{
+ b.op->augAssignAdd(b, (Mat&)a);
+ return a;
+}
+
+template<typename _Tp> static inline
+Mat_<_Tp>& operator += (Mat_<_Tp>& a, const MatExpr& b)
+{
+ b.op->augAssignAdd(b, a);
+ return a;
+}
+
+template<typename _Tp> static inline
+const Mat_<_Tp>& operator += (const Mat_<_Tp>& a, const MatExpr& b)
+{
+ b.op->augAssignAdd(b, (Mat&)a);
+ return a;
+}
+
+static inline
+Mat& operator -= (Mat& a, const MatExpr& b)
+{
+ b.op->augAssignSubtract(b, a);
+ return a;
+}
+
+static inline
+const Mat& operator -= (const Mat& a, const MatExpr& b)
+{
+ b.op->augAssignSubtract(b, (Mat&)a);
+ return a;
+}
+
+template<typename _Tp> static inline
+Mat_<_Tp>& operator -= (Mat_<_Tp>& a, const MatExpr& b)
+{
+ b.op->augAssignSubtract(b, a);
+ return a;
+}
+
+template<typename _Tp> static inline
+const Mat_<_Tp>& operator -= (const Mat_<_Tp>& a, const MatExpr& b)
+{
+ b.op->augAssignSubtract(b, (Mat&)a);
+ return a;
+}
+
+static inline
+Mat& operator *= (Mat& a, const MatExpr& b)
+{
+ b.op->augAssignMultiply(b, a);
+ return a;
+}
+
+static inline
+const Mat& operator *= (const Mat& a, const MatExpr& b)
+{
+ b.op->augAssignMultiply(b, (Mat&)a);
+ return a;
+}
+
+template<typename _Tp> static inline
+Mat_<_Tp>& operator *= (Mat_<_Tp>& a, const MatExpr& b)
+{
+ b.op->augAssignMultiply(b, a);
+ return a;
+}
+
+template<typename _Tp> static inline
+const Mat_<_Tp>& operator *= (const Mat_<_Tp>& a, const MatExpr& b)
+{
+ b.op->augAssignMultiply(b, (Mat&)a);
+ return a;
+}
+
+static inline
+Mat& operator /= (Mat& a, const MatExpr& b)
+{
+ b.op->augAssignDivide(b, a);
+ return a;
+}
+
+static inline
+const Mat& operator /= (const Mat& a, const MatExpr& b)
+{
+ b.op->augAssignDivide(b, (Mat&)a);
+ return a;
+}
+
+template<typename _Tp> static inline
+Mat_<_Tp>& operator /= (Mat_<_Tp>& a, const MatExpr& b)
+{
+ b.op->augAssignDivide(b, a);
+ return a;
+}
+
+template<typename _Tp> static inline
+const Mat_<_Tp>& operator /= (const Mat_<_Tp>& a, const MatExpr& b)
+{
+ b.op->augAssignDivide(b, (Mat&)a);
+ return a;
+}
+
+
+//////////////////////////////// UMat ////////////////////////////////
+
+inline
+UMat::UMat(UMatUsageFlags _usageFlags)
+: flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0), size(&rows)
+{}
+
+inline
+UMat::UMat(int _rows, int _cols, int _type, UMatUsageFlags _usageFlags)
+: flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0), size(&rows)
+{
+ create(_rows, _cols, _type);
+}
+
+inline
+UMat::UMat(int _rows, int _cols, int _type, const Scalar& _s, UMatUsageFlags _usageFlags)
+: flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0), size(&rows)
+{
+ create(_rows, _cols, _type);
+ *this = _s;
+}
+
+inline
+UMat::UMat(Size _sz, int _type, UMatUsageFlags _usageFlags)
+: flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0), size(&rows)
+{
+ create( _sz.height, _sz.width, _type );
+}
+
+inline
+UMat::UMat(Size _sz, int _type, const Scalar& _s, UMatUsageFlags _usageFlags)
+: flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0), size(&rows)
+{
+ create(_sz.height, _sz.width, _type);
+ *this = _s;
+}
+
+inline
+UMat::UMat(int _dims, const int* _sz, int _type, UMatUsageFlags _usageFlags)
+: flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0), size(&rows)
+{
+ create(_dims, _sz, _type);
+}
+
+inline
+UMat::UMat(int _dims, const int* _sz, int _type, const Scalar& _s, UMatUsageFlags _usageFlags)
+: flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0), size(&rows)
+{
+ create(_dims, _sz, _type);
+ *this = _s;
+}
+
+inline
+UMat::UMat(const UMat& m)
+: flags(m.flags), dims(m.dims), rows(m.rows), cols(m.cols), allocator(m.allocator),
+ usageFlags(m.usageFlags), u(m.u), offset(m.offset), size(&rows)
+{
+ addref();
+ if( m.dims <= 2 )
+ {
+ step[0] = m.step[0]; step[1] = m.step[1];
+ }
+ else
+ {
+ dims = 0;
+ copySize(m);
+ }
+}
+
+
+template<typename _Tp> inline
+UMat::UMat(const std::vector<_Tp>& vec, bool copyData)
+: flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG), dims(2), rows((int)vec.size()),
+cols(1), allocator(0), usageFlags(USAGE_DEFAULT), u(0), offset(0), size(&rows)
+{
+ if(vec.empty())
+ return;
+ if( !copyData )
+ {
+ // !!!TODO!!!
+ CV_Error(Error::StsNotImplemented, "");
+ }
+ else
+ Mat((int)vec.size(), 1, DataType<_Tp>::type, (uchar*)&vec[0]).copyTo(*this);
+}
+
+
+inline
+UMat& UMat::operator = (const UMat& m)
+{
+ if( this != &m )
+ {
+ const_cast<UMat&>(m).addref();
+ release();
+ flags = m.flags;
+ if( dims <= 2 && m.dims <= 2 )
+ {
+ dims = m.dims;
+ rows = m.rows;
+ cols = m.cols;
+ step[0] = m.step[0];
+ step[1] = m.step[1];
+ }
+ else
+ copySize(m);
+ allocator = m.allocator;
+ if (usageFlags == USAGE_DEFAULT)
+ usageFlags = m.usageFlags;
+ u = m.u;
+ offset = m.offset;
+ }
+ return *this;
+}
+
+inline
+UMat UMat::row(int y) const
+{
+ return UMat(*this, Range(y, y + 1), Range::all());
+}
+
+inline
+UMat UMat::col(int x) const
+{
+ return UMat(*this, Range::all(), Range(x, x + 1));
+}
+
+inline
+UMat UMat::rowRange(int startrow, int endrow) const
+{
+ return UMat(*this, Range(startrow, endrow), Range::all());
+}
+
+inline
+UMat UMat::rowRange(const Range& r) const
+{
+ return UMat(*this, r, Range::all());
+}
+
+inline
+UMat UMat::colRange(int startcol, int endcol) const
+{
+ return UMat(*this, Range::all(), Range(startcol, endcol));
+}
+
+inline
+UMat UMat::colRange(const Range& r) const
+{
+ return UMat(*this, Range::all(), r);
+}
+
+inline
+UMat UMat::clone() const
+{
+ UMat m;
+ copyTo(m);
+ return m;
+}
+
+inline
+void UMat::assignTo( UMat& m, int _type ) const
+{
+ if( _type < 0 )
+ m = *this;
+ else
+ convertTo(m, _type);
+}
+
+inline
+void UMat::create(int _rows, int _cols, int _type, UMatUsageFlags _usageFlags)
+{
+ _type &= TYPE_MASK;
+ if( dims <= 2 && rows == _rows && cols == _cols && type() == _type && u )
+ return;
+ int sz[] = {_rows, _cols};
+ create(2, sz, _type, _usageFlags);
+}
+
+inline
+void UMat::create(Size _sz, int _type, UMatUsageFlags _usageFlags)
+{
+ create(_sz.height, _sz.width, _type, _usageFlags);
+}
+
+inline
+void UMat::addref()
+{
+ if( u )
+ CV_XADD(&(u->urefcount), 1);
+}
+
+inline void UMat::release()
+{
+ if( u && CV_XADD(&(u->urefcount), -1) == 1 )
+ deallocate();
+ for(int i = 0; i < dims; i++)
+ size.p[i] = 0;
+ u = 0;
+}
+
+inline
+UMat UMat::operator()( Range _rowRange, Range _colRange ) const
+{
+ return UMat(*this, _rowRange, _colRange);
+}
+
+inline
+UMat UMat::operator()( const Rect& roi ) const
+{
+ return UMat(*this, roi);
+}
+
+inline
+UMat UMat::operator()(const Range* ranges) const
+{
+ return UMat(*this, ranges);
+}
+
+inline
+UMat UMat::operator()(const std::vector<Range>& ranges) const
+{
+ return UMat(*this, ranges);
+}
+
+inline
+bool UMat::isContinuous() const
+{
+ return (flags & CONTINUOUS_FLAG) != 0;
+}
+
+inline
+bool UMat::isSubmatrix() const
+{
+ return (flags & SUBMATRIX_FLAG) != 0;
+}
+
+inline
+size_t UMat::elemSize() const
+{
+ return dims > 0 ? step.p[dims - 1] : 0;
+}
+
+inline
+size_t UMat::elemSize1() const
+{
+ return CV_ELEM_SIZE1(flags);
+}
+
+inline
+int UMat::type() const
+{
+ return CV_MAT_TYPE(flags);
+}
+
+inline
+int UMat::depth() const
+{
+ return CV_MAT_DEPTH(flags);
+}
+
+inline
+int UMat::channels() const
+{
+ return CV_MAT_CN(flags);
+}
+
+inline
+size_t UMat::step1(int i) const
+{
+ return step.p[i] / elemSize1();
+}
+
+inline
+bool UMat::empty() const
+{
+ return u == 0 || total() == 0;
+}
+
+inline
+size_t UMat::total() const
+{
+ if( dims <= 2 )
+ return (size_t)rows * cols;
+ size_t p = 1;
+ for( int i = 0; i < dims; i++ )
+ p *= size[i];
+ return p;
+}
+
+#ifdef CV_CXX_MOVE_SEMANTICS
+
+inline
+UMat::UMat(UMat&& m)
+: flags(m.flags), dims(m.dims), rows(m.rows), cols(m.cols), allocator(m.allocator),
+ usageFlags(m.usageFlags), u(m.u), offset(m.offset), size(&rows)
+{
+ if (m.dims <= 2) // move new step/size info
+ {
+ step[0] = m.step[0];
+ step[1] = m.step[1];
+ }
+ else
+ {
+ CV_DbgAssert(m.step.p != m.step.buf);
+ step.p = m.step.p;
+ size.p = m.size.p;
+ m.step.p = m.step.buf;
+ m.size.p = &m.rows;
+ }
+ m.flags = MAGIC_VAL; m.dims = m.rows = m.cols = 0;
+ m.allocator = NULL;
+ m.u = NULL;
+ m.offset = 0;
+}
+
+inline
+UMat& UMat::operator = (UMat&& m)
+{
+ if (this == &m)
+ return *this;
+ release();
+ flags = m.flags; dims = m.dims; rows = m.rows; cols = m.cols;
+ allocator = m.allocator; usageFlags = m.usageFlags;
+ u = m.u;
+ offset = m.offset;
+ if (step.p != step.buf) // release self step/size
+ {
+ fastFree(step.p);
+ step.p = step.buf;
+ size.p = &rows;
+ }
+ if (m.dims <= 2) // move new step/size info
+ {
+ step[0] = m.step[0];
+ step[1] = m.step[1];
+ }
+ else
+ {
+ CV_DbgAssert(m.step.p != m.step.buf);
+ step.p = m.step.p;
+ size.p = m.size.p;
+ m.step.p = m.step.buf;
+ m.size.p = &m.rows;
+ }
+ m.flags = MAGIC_VAL; m.dims = m.rows = m.cols = 0;
+ m.allocator = NULL;
+ m.u = NULL;
+ m.offset = 0;
+ return *this;
+}
+
+#endif
+
+
+inline bool UMatData::hostCopyObsolete() const { return (flags & HOST_COPY_OBSOLETE) != 0; }
+inline bool UMatData::deviceCopyObsolete() const { return (flags & DEVICE_COPY_OBSOLETE) != 0; }
+inline bool UMatData::deviceMemMapped() const { return (flags & DEVICE_MEM_MAPPED) != 0; }
+inline bool UMatData::copyOnMap() const { return (flags & COPY_ON_MAP) != 0; }
+inline bool UMatData::tempUMat() const { return (flags & TEMP_UMAT) != 0; }
+inline bool UMatData::tempCopiedUMat() const { return (flags & TEMP_COPIED_UMAT) == TEMP_COPIED_UMAT; }
+
+inline void UMatData::markDeviceMemMapped(bool flag)
+{
+ if(flag)
+ flags |= DEVICE_MEM_MAPPED;
+ else
+ flags &= ~DEVICE_MEM_MAPPED;
+}
+
+inline void UMatData::markHostCopyObsolete(bool flag)
+{
+ if(flag)
+ flags |= HOST_COPY_OBSOLETE;
+ else
+ flags &= ~HOST_COPY_OBSOLETE;
+}
+inline void UMatData::markDeviceCopyObsolete(bool flag)
+{
+ if(flag)
+ flags |= DEVICE_COPY_OBSOLETE;
+ else
+ flags &= ~DEVICE_COPY_OBSOLETE;
+}
+
+inline UMatDataAutoLock::UMatDataAutoLock(UMatData* _u) : u(_u) { u->lock(); }
+inline UMatDataAutoLock::~UMatDataAutoLock() { u->unlock(); }
+
+//! @endcond
+
+} //cv
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/core/matx.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,1407 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_CORE_MATX_HPP
+#define OPENCV_CORE_MATX_HPP
+
+#ifndef __cplusplus
+# error matx.hpp header must be compiled as C++
+#endif
+
+#include "opencv2/core/cvdef.h"
+#include "opencv2/core/base.hpp"
+#include "opencv2/core/traits.hpp"
+#include "opencv2/core/saturate.hpp"
+
+namespace cv
+{
+
+//! @addtogroup core_basic
+//! @{
+
+////////////////////////////// Small Matrix ///////////////////////////
+
+//! @cond IGNORED
+struct CV_EXPORTS Matx_AddOp {};
+struct CV_EXPORTS Matx_SubOp {};
+struct CV_EXPORTS Matx_ScaleOp {};
+struct CV_EXPORTS Matx_MulOp {};
+struct CV_EXPORTS Matx_DivOp {};
+struct CV_EXPORTS Matx_MatMulOp {};
+struct CV_EXPORTS Matx_TOp {};
+//! @endcond
+
+/** @brief Template class for small matrices whose type and size are known at compilation time
+
+If you need a more flexible type, use Mat . The elements of the matrix M are accessible using the
+M(i,j) notation. Most of the common matrix operations (see also @ref MatrixExpressions ) are
+available. To do an operation on Matx that is not implemented, you can easily convert the matrix to
+Mat and backwards:
+@code
+ Matx33f m(1, 2, 3,
+ 4, 5, 6,
+ 7, 8, 9);
+ cout << sum(Mat(m*m.t())) << endl;
+ @endcode
+ */
+template<typename _Tp, int m, int n> class Matx
+{
+public:
+ enum { depth = DataType<_Tp>::depth,
+ rows = m,
+ cols = n,
+ channels = rows*cols,
+ type = CV_MAKETYPE(depth, channels),
+ shortdim = (m < n ? m : n)
+ };
+
+ typedef _Tp value_type;
+ typedef Matx<_Tp, m, n> mat_type;
+ typedef Matx<_Tp, shortdim, 1> diag_type;
+
+ //! default constructor
+ Matx();
+
+ Matx(_Tp v0); //!< 1x1 matrix
+ Matx(_Tp v0, _Tp v1); //!< 1x2 or 2x1 matrix
+ Matx(_Tp v0, _Tp v1, _Tp v2); //!< 1x3 or 3x1 matrix
+ Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3); //!< 1x4, 2x2 or 4x1 matrix
+ Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4); //!< 1x5 or 5x1 matrix
+ Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5); //!< 1x6, 2x3, 3x2 or 6x1 matrix
+ Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6); //!< 1x7 or 7x1 matrix
+ Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7); //!< 1x8, 2x4, 4x2 or 8x1 matrix
+ Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8); //!< 1x9, 3x3 or 9x1 matrix
+ Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9); //!< 1x10, 2x5 or 5x2 or 10x1 matrix
+ Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
+ _Tp v4, _Tp v5, _Tp v6, _Tp v7,
+ _Tp v8, _Tp v9, _Tp v10, _Tp v11); //!< 1x12, 2x6, 3x4, 4x3, 6x2 or 12x1 matrix
+ Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
+ _Tp v4, _Tp v5, _Tp v6, _Tp v7,
+ _Tp v8, _Tp v9, _Tp v10, _Tp v11,
+ _Tp v12, _Tp v13); //!< 1x14, 2x7, 7x2 or 14x1 matrix
+ Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
+ _Tp v4, _Tp v5, _Tp v6, _Tp v7,
+ _Tp v8, _Tp v9, _Tp v10, _Tp v11,
+ _Tp v12, _Tp v13, _Tp v14, _Tp v15); //!< 1x16, 4x4 or 16x1 matrix
+ explicit Matx(const _Tp* vals); //!< initialize from a plain array
+
+ static Matx all(_Tp alpha);
+ static Matx zeros();
+ static Matx ones();
+ static Matx eye();
+ static Matx diag(const diag_type& d);
+ static Matx randu(_Tp a, _Tp b);
+ static Matx randn(_Tp a, _Tp b);
+
+ //! dot product computed with the default precision
+ _Tp dot(const Matx<_Tp, m, n>& v) const;
+
+ //! dot product computed in double-precision arithmetics
+ double ddot(const Matx<_Tp, m, n>& v) const;
+
+ //! conversion to another data type
+ template<typename T2> operator Matx<T2, m, n>() const;
+
+ //! change the matrix shape
+ template<int m1, int n1> Matx<_Tp, m1, n1> reshape() const;
+
+ //! extract part of the matrix
+ template<int m1, int n1> Matx<_Tp, m1, n1> get_minor(int i, int j) const;
+
+ //! extract the matrix row
+ Matx<_Tp, 1, n> row(int i) const;
+
+ //! extract the matrix column
+ Matx<_Tp, m, 1> col(int i) const;
+
+ //! extract the matrix diagonal
+ diag_type diag() const;
+
+ //! transpose the matrix
+ Matx<_Tp, n, m> t() const;
+
+ //! invert the matrix
+ Matx<_Tp, n, m> inv(int method=DECOMP_LU, bool *p_is_ok = NULL) const;
+
+ //! solve linear system
+ template<int l> Matx<_Tp, n, l> solve(const Matx<_Tp, m, l>& rhs, int flags=DECOMP_LU) const;
+ Vec<_Tp, n> solve(const Vec<_Tp, m>& rhs, int method) const;
+
+ //! multiply two matrices element-wise
+ Matx<_Tp, m, n> mul(const Matx<_Tp, m, n>& a) const;
+
+ //! divide two matrices element-wise
+ Matx<_Tp, m, n> div(const Matx<_Tp, m, n>& a) const;
+
+ //! element access
+ const _Tp& operator ()(int i, int j) const;
+ _Tp& operator ()(int i, int j);
+
+ //! 1D element access
+ const _Tp& operator ()(int i) const;
+ _Tp& operator ()(int i);
+
+ Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_AddOp);
+ Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_SubOp);
+ template<typename _T2> Matx(const Matx<_Tp, m, n>& a, _T2 alpha, Matx_ScaleOp);
+ Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_MulOp);
+ Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_DivOp);
+ template<int l> Matx(const Matx<_Tp, m, l>& a, const Matx<_Tp, l, n>& b, Matx_MatMulOp);
+ Matx(const Matx<_Tp, n, m>& a, Matx_TOp);
+
+ _Tp val[m*n]; //< matrix elements
+};
+
+typedef Matx<float, 1, 2> Matx12f;
+typedef Matx<double, 1, 2> Matx12d;
+typedef Matx<float, 1, 3> Matx13f;
+typedef Matx<double, 1, 3> Matx13d;
+typedef Matx<float, 1, 4> Matx14f;
+typedef Matx<double, 1, 4> Matx14d;
+typedef Matx<float, 1, 6> Matx16f;
+typedef Matx<double, 1, 6> Matx16d;
+
+typedef Matx<float, 2, 1> Matx21f;
+typedef Matx<double, 2, 1> Matx21d;
+typedef Matx<float, 3, 1> Matx31f;
+typedef Matx<double, 3, 1> Matx31d;
+typedef Matx<float, 4, 1> Matx41f;
+typedef Matx<double, 4, 1> Matx41d;
+typedef Matx<float, 6, 1> Matx61f;
+typedef Matx<double, 6, 1> Matx61d;
+
+typedef Matx<float, 2, 2> Matx22f;
+typedef Matx<double, 2, 2> Matx22d;
+typedef Matx<float, 2, 3> Matx23f;
+typedef Matx<double, 2, 3> Matx23d;
+typedef Matx<float, 3, 2> Matx32f;
+typedef Matx<double, 3, 2> Matx32d;
+
+typedef Matx<float, 3, 3> Matx33f;
+typedef Matx<double, 3, 3> Matx33d;
+
+typedef Matx<float, 3, 4> Matx34f;
+typedef Matx<double, 3, 4> Matx34d;
+typedef Matx<float, 4, 3> Matx43f;
+typedef Matx<double, 4, 3> Matx43d;
+
+typedef Matx<float, 4, 4> Matx44f;
+typedef Matx<double, 4, 4> Matx44d;
+typedef Matx<float, 6, 6> Matx66f;
+typedef Matx<double, 6, 6> Matx66d;
+
+/*!
+ traits
+*/
+template<typename _Tp, int m, int n> class DataType< Matx<_Tp, m, n> >
+{
+public:
+ typedef Matx<_Tp, m, n> value_type;
+ typedef Matx<typename DataType<_Tp>::work_type, m, n> work_type;
+ typedef _Tp channel_type;
+ typedef value_type vec_type;
+
+ enum { generic_type = 0,
+ depth = DataType<channel_type>::depth,
+ channels = m * n,
+ fmt = DataType<channel_type>::fmt + ((channels - 1) << 8),
+ type = CV_MAKETYPE(depth, channels)
+ };
+};
+
+/** @brief Comma-separated Matrix Initializer
+*/
+template<typename _Tp, int m, int n> class MatxCommaInitializer
+{
+public:
+ MatxCommaInitializer(Matx<_Tp, m, n>* _mtx);
+ template<typename T2> MatxCommaInitializer<_Tp, m, n>& operator , (T2 val);
+ Matx<_Tp, m, n> operator *() const;
+
+ Matx<_Tp, m, n>* dst;
+ int idx;
+};
+
+/*
+ Utility methods
+*/
+template<typename _Tp, int m> static double determinant(const Matx<_Tp, m, m>& a);
+template<typename _Tp, int m, int n> static double trace(const Matx<_Tp, m, n>& a);
+template<typename _Tp, int m, int n> static double norm(const Matx<_Tp, m, n>& M);
+template<typename _Tp, int m, int n> static double norm(const Matx<_Tp, m, n>& M, int normType);
+
+
+
+/////////////////////// Vec (used as element of multi-channel images /////////////////////
+
+/** @brief Template class for short numerical vectors, a partial case of Matx
+
+This template class represents short numerical vectors (of 1, 2, 3, 4 ... elements) on which you
+can perform basic arithmetical operations, access individual elements using [] operator etc. The
+vectors are allocated on stack, as opposite to std::valarray, std::vector, cv::Mat etc., which
+elements are dynamically allocated in the heap.
+
+The template takes 2 parameters:
+@tparam _Tp element type
+@tparam cn the number of elements
+
+In addition to the universal notation like Vec<float, 3>, you can use shorter aliases
+for the most popular specialized variants of Vec, e.g. Vec3f ~ Vec<float, 3>.
+
+It is possible to convert Vec\<T,2\> to/from Point_, Vec\<T,3\> to/from Point3_ , and Vec\<T,4\>
+to CvScalar or Scalar_. Use operator[] to access the elements of Vec.
+
+All the expected vector operations are also implemented:
+- v1 = v2 + v3
+- v1 = v2 - v3
+- v1 = v2 \* scale
+- v1 = scale \* v2
+- v1 = -v2
+- v1 += v2 and other augmenting operations
+- v1 == v2, v1 != v2
+- norm(v1) (euclidean norm)
+The Vec class is commonly used to describe pixel types of multi-channel arrays. See Mat for details.
+*/
+template<typename _Tp, int cn> class Vec : public Matx<_Tp, cn, 1>
+{
+public:
+ typedef _Tp value_type;
+ enum { depth = Matx<_Tp, cn, 1>::depth,
+ channels = cn,
+ type = CV_MAKETYPE(depth, channels)
+ };
+
+ //! default constructor
+ Vec();
+
+ Vec(_Tp v0); //!< 1-element vector constructor
+ Vec(_Tp v0, _Tp v1); //!< 2-element vector constructor
+ Vec(_Tp v0, _Tp v1, _Tp v2); //!< 3-element vector constructor
+ Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3); //!< 4-element vector constructor
+ Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4); //!< 5-element vector constructor
+ Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5); //!< 6-element vector constructor
+ Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6); //!< 7-element vector constructor
+ Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7); //!< 8-element vector constructor
+ Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8); //!< 9-element vector constructor
+ Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9); //!< 10-element vector constructor
+ Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9, _Tp v10, _Tp v11, _Tp v12, _Tp v13); //!< 14-element vector constructor
+ explicit Vec(const _Tp* values);
+
+ Vec(const Vec<_Tp, cn>& v);
+
+ static Vec all(_Tp alpha);
+
+ //! per-element multiplication
+ Vec mul(const Vec<_Tp, cn>& v) const;
+
+ //! conjugation (makes sense for complex numbers and quaternions)
+ Vec conj() const;
+
+ /*!
+ cross product of the two 3D vectors.
+
+ For other dimensionalities the exception is raised
+ */
+ Vec cross(const Vec& v) const;
+ //! conversion to another data type
+ template<typename T2> operator Vec<T2, cn>() const;
+
+ /*! element access */
+ const _Tp& operator [](int i) const;
+ _Tp& operator[](int i);
+ const _Tp& operator ()(int i) const;
+ _Tp& operator ()(int i);
+
+ Vec(const Matx<_Tp, cn, 1>& a, const Matx<_Tp, cn, 1>& b, Matx_AddOp);
+ Vec(const Matx<_Tp, cn, 1>& a, const Matx<_Tp, cn, 1>& b, Matx_SubOp);
+ template<typename _T2> Vec(const Matx<_Tp, cn, 1>& a, _T2 alpha, Matx_ScaleOp);
+};
+
+/** @name Shorter aliases for the most popular specializations of Vec<T,n>
+ @{
+*/
+typedef Vec<uchar, 2> Vec2b;
+typedef Vec<uchar, 3> Vec3b;
+typedef Vec<uchar, 4> Vec4b;
+
+typedef Vec<short, 2> Vec2s;
+typedef Vec<short, 3> Vec3s;
+typedef Vec<short, 4> Vec4s;
+
+typedef Vec<ushort, 2> Vec2w;
+typedef Vec<ushort, 3> Vec3w;
+typedef Vec<ushort, 4> Vec4w;
+
+typedef Vec<int, 2> Vec2i;
+typedef Vec<int, 3> Vec3i;
+typedef Vec<int, 4> Vec4i;
+typedef Vec<int, 6> Vec6i;
+typedef Vec<int, 8> Vec8i;
+
+typedef Vec<float, 2> Vec2f;
+typedef Vec<float, 3> Vec3f;
+typedef Vec<float, 4> Vec4f;
+typedef Vec<float, 6> Vec6f;
+
+typedef Vec<double, 2> Vec2d;
+typedef Vec<double, 3> Vec3d;
+typedef Vec<double, 4> Vec4d;
+typedef Vec<double, 6> Vec6d;
+/** @} */
+
+/*!
+ traits
+*/
+template<typename _Tp, int cn> class DataType< Vec<_Tp, cn> >
+{
+public:
+ typedef Vec<_Tp, cn> value_type;
+ typedef Vec<typename DataType<_Tp>::work_type, cn> work_type;
+ typedef _Tp channel_type;
+ typedef value_type vec_type;
+
+ enum { generic_type = 0,
+ depth = DataType<channel_type>::depth,
+ channels = cn,
+ fmt = DataType<channel_type>::fmt + ((channels - 1) << 8),
+ type = CV_MAKETYPE(depth, channels)
+ };
+};
+
+/** @brief Comma-separated Vec Initializer
+*/
+template<typename _Tp, int m> class VecCommaInitializer : public MatxCommaInitializer<_Tp, m, 1>
+{
+public:
+ VecCommaInitializer(Vec<_Tp, m>* _vec);
+ template<typename T2> VecCommaInitializer<_Tp, m>& operator , (T2 val);
+ Vec<_Tp, m> operator *() const;
+};
+
+template<typename _Tp, int cn> static Vec<_Tp, cn> normalize(const Vec<_Tp, cn>& v);
+
+//! @} core_basic
+
+//! @cond IGNORED
+
+///////////////////////////////////// helper classes /////////////////////////////////////
+namespace internal
+{
+
+template<typename _Tp, int m> struct Matx_DetOp
+{
+ double operator ()(const Matx<_Tp, m, m>& a) const
+ {
+ Matx<_Tp, m, m> temp = a;
+ double p = LU(temp.val, m*sizeof(_Tp), m, 0, 0, 0);
+ if( p == 0 )
+ return p;
+ for( int i = 0; i < m; i++ )
+ p *= temp(i, i);
+ return p;
+ }
+};
+
+template<typename _Tp> struct Matx_DetOp<_Tp, 1>
+{
+ double operator ()(const Matx<_Tp, 1, 1>& a) const
+ {
+ return a(0,0);
+ }
+};
+
+template<typename _Tp> struct Matx_DetOp<_Tp, 2>
+{
+ double operator ()(const Matx<_Tp, 2, 2>& a) const
+ {
+ return a(0,0)*a(1,1) - a(0,1)*a(1,0);
+ }
+};
+
+template<typename _Tp> struct Matx_DetOp<_Tp, 3>
+{
+ double operator ()(const Matx<_Tp, 3, 3>& a) const
+ {
+ return a(0,0)*(a(1,1)*a(2,2) - a(2,1)*a(1,2)) -
+ a(0,1)*(a(1,0)*a(2,2) - a(2,0)*a(1,2)) +
+ a(0,2)*(a(1,0)*a(2,1) - a(2,0)*a(1,1));
+ }
+};
+
+template<typename _Tp> Vec<_Tp, 2> inline conjugate(const Vec<_Tp, 2>& v)
+{
+ return Vec<_Tp, 2>(v[0], -v[1]);
+}
+
+template<typename _Tp> Vec<_Tp, 4> inline conjugate(const Vec<_Tp, 4>& v)
+{
+ return Vec<_Tp, 4>(v[0], -v[1], -v[2], -v[3]);
+}
+
+} // internal
+
+
+
+////////////////////////////////// Matx Implementation ///////////////////////////////////
+
+template<typename _Tp, int m, int n> inline
+Matx<_Tp, m, n>::Matx()
+{
+ for(int i = 0; i < channels; i++) val[i] = _Tp(0);
+}
+
+template<typename _Tp, int m, int n> inline
+Matx<_Tp, m, n>::Matx(_Tp v0)
+{
+ val[0] = v0;
+ for(int i = 1; i < channels; i++) val[i] = _Tp(0);
+}
+
+template<typename _Tp, int m, int n> inline
+Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1)
+{
+ CV_StaticAssert(channels >= 2, "Matx should have at least 2 elements.");
+ val[0] = v0; val[1] = v1;
+ for(int i = 2; i < channels; i++) val[i] = _Tp(0);
+}
+
+template<typename _Tp, int m, int n> inline
+Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2)
+{
+ CV_StaticAssert(channels >= 3, "Matx should have at least 3 elements.");
+ val[0] = v0; val[1] = v1; val[2] = v2;
+ for(int i = 3; i < channels; i++) val[i] = _Tp(0);
+}
+
+template<typename _Tp, int m, int n> inline
+Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3)
+{
+ CV_StaticAssert(channels >= 4, "Matx should have at least 4 elements.");
+ val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
+ for(int i = 4; i < channels; i++) val[i] = _Tp(0);
+}
+
+template<typename _Tp, int m, int n> inline
+Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4)
+{
+ CV_StaticAssert(channels >= 5, "Matx should have at least 5 elements.");
+ val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; val[4] = v4;
+ for(int i = 5; i < channels; i++) val[i] = _Tp(0);
+}
+
+template<typename _Tp, int m, int n> inline
+Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5)
+{
+ CV_StaticAssert(channels >= 6, "Matx should have at least 6 elements.");
+ val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
+ val[4] = v4; val[5] = v5;
+ for(int i = 6; i < channels; i++) val[i] = _Tp(0);
+}
+
+template<typename _Tp, int m, int n> inline
+Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6)
+{
+ CV_StaticAssert(channels >= 7, "Matx should have at least 7 elements.");
+ val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
+ val[4] = v4; val[5] = v5; val[6] = v6;
+ for(int i = 7; i < channels; i++) val[i] = _Tp(0);
+}
+
+template<typename _Tp, int m, int n> inline
+Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7)
+{
+ CV_StaticAssert(channels >= 8, "Matx should have at least 8 elements.");
+ val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
+ val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7;
+ for(int i = 8; i < channels; i++) val[i] = _Tp(0);
+}
+
+template<typename _Tp, int m, int n> inline
+Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8)
+{
+ CV_StaticAssert(channels >= 9, "Matx should have at least 9 elements.");
+ val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
+ val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7;
+ val[8] = v8;
+ for(int i = 9; i < channels; i++) val[i] = _Tp(0);
+}
+
+template<typename _Tp, int m, int n> inline
+Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9)
+{
+ CV_StaticAssert(channels >= 10, "Matx should have at least 10 elements.");
+ val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
+ val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7;
+ val[8] = v8; val[9] = v9;
+ for(int i = 10; i < channels; i++) val[i] = _Tp(0);
+}
+
+
+template<typename _Tp, int m, int n> inline
+Matx<_Tp,m,n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9, _Tp v10, _Tp v11)
+{
+ CV_StaticAssert(channels >= 12, "Matx should have at least 12 elements.");
+ val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
+ val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7;
+ val[8] = v8; val[9] = v9; val[10] = v10; val[11] = v11;
+ for(int i = 12; i < channels; i++) val[i] = _Tp(0);
+}
+
+template<typename _Tp, int m, int n> inline
+Matx<_Tp,m,n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9, _Tp v10, _Tp v11, _Tp v12, _Tp v13)
+{
+ CV_StaticAssert(channels == 14, "Matx should have at least 14 elements.");
+ val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
+ val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7;
+ val[8] = v8; val[9] = v9; val[10] = v10; val[11] = v11;
+ val[12] = v12; val[13] = v13;
+}
+
+
+template<typename _Tp, int m, int n> inline
+Matx<_Tp,m,n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9, _Tp v10, _Tp v11, _Tp v12, _Tp v13, _Tp v14, _Tp v15)
+{
+ CV_StaticAssert(channels >= 16, "Matx should have at least 16 elements.");
+ val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
+ val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7;
+ val[8] = v8; val[9] = v9; val[10] = v10; val[11] = v11;
+ val[12] = v12; val[13] = v13; val[14] = v14; val[15] = v15;
+ for(int i = 16; i < channels; i++) val[i] = _Tp(0);
+}
+
+template<typename _Tp, int m, int n> inline
+Matx<_Tp, m, n>::Matx(const _Tp* values)
+{
+ for( int i = 0; i < channels; i++ ) val[i] = values[i];
+}
+
+template<typename _Tp, int m, int n> inline
+Matx<_Tp, m, n> Matx<_Tp, m, n>::all(_Tp alpha)
+{
+ Matx<_Tp, m, n> M;
+ for( int i = 0; i < m*n; i++ ) M.val[i] = alpha;
+ return M;
+}
+
+template<typename _Tp, int m, int n> inline
+Matx<_Tp,m,n> Matx<_Tp,m,n>::zeros()
+{
+ return all(0);
+}
+
+template<typename _Tp, int m, int n> inline
+Matx<_Tp,m,n> Matx<_Tp,m,n>::ones()
+{
+ return all(1);
+}
+
+template<typename _Tp, int m, int n> inline
+Matx<_Tp,m,n> Matx<_Tp,m,n>::eye()
+{
+ Matx<_Tp,m,n> M;
+ for(int i = 0; i < shortdim; i++)
+ M(i,i) = 1;
+ return M;
+}
+
+template<typename _Tp, int m, int n> inline
+_Tp Matx<_Tp, m, n>::dot(const Matx<_Tp, m, n>& M) const
+{
+ _Tp s = 0;
+ for( int i = 0; i < channels; i++ ) s += val[i]*M.val[i];
+ return s;
+}
+
+template<typename _Tp, int m, int n> inline
+double Matx<_Tp, m, n>::ddot(const Matx<_Tp, m, n>& M) const
+{
+ double s = 0;
+ for( int i = 0; i < channels; i++ ) s += (double)val[i]*M.val[i];
+ return s;
+}
+
+template<typename _Tp, int m, int n> inline
+Matx<_Tp,m,n> Matx<_Tp,m,n>::diag(const typename Matx<_Tp,m,n>::diag_type& d)
+{
+ Matx<_Tp,m,n> M;
+ for(int i = 0; i < shortdim; i++)
+ M(i,i) = d(i, 0);
+ return M;
+}
+
+template<typename _Tp, int m, int n> template<typename T2>
+inline Matx<_Tp, m, n>::operator Matx<T2, m, n>() const
+{
+ Matx<T2, m, n> M;
+ for( int i = 0; i < m*n; i++ ) M.val[i] = saturate_cast<T2>(val[i]);
+ return M;
+}
+
+template<typename _Tp, int m, int n> template<int m1, int n1> inline
+Matx<_Tp, m1, n1> Matx<_Tp, m, n>::reshape() const
+{
+ CV_StaticAssert(m1*n1 == m*n, "Input and destnarion matrices must have the same number of elements");
+ return (const Matx<_Tp, m1, n1>&)*this;
+}
+
+template<typename _Tp, int m, int n>
+template<int m1, int n1> inline
+Matx<_Tp, m1, n1> Matx<_Tp, m, n>::get_minor(int i, int j) const
+{
+ CV_DbgAssert(0 <= i && i+m1 <= m && 0 <= j && j+n1 <= n);
+ Matx<_Tp, m1, n1> s;
+ for( int di = 0; di < m1; di++ )
+ for( int dj = 0; dj < n1; dj++ )
+ s(di, dj) = (*this)(i+di, j+dj);
+ return s;
+}
+
+template<typename _Tp, int m, int n> inline
+Matx<_Tp, 1, n> Matx<_Tp, m, n>::row(int i) const
+{
+ CV_DbgAssert((unsigned)i < (unsigned)m);
+ return Matx<_Tp, 1, n>(&val[i*n]);
+}
+
+template<typename _Tp, int m, int n> inline
+Matx<_Tp, m, 1> Matx<_Tp, m, n>::col(int j) const
+{
+ CV_DbgAssert((unsigned)j < (unsigned)n);
+ Matx<_Tp, m, 1> v;
+ for( int i = 0; i < m; i++ )
+ v.val[i] = val[i*n + j];
+ return v;
+}
+
+template<typename _Tp, int m, int n> inline
+typename Matx<_Tp, m, n>::diag_type Matx<_Tp, m, n>::diag() const
+{
+ diag_type d;
+ for( int i = 0; i < shortdim; i++ )
+ d.val[i] = val[i*n + i];
+ return d;
+}
+
+template<typename _Tp, int m, int n> inline
+const _Tp& Matx<_Tp, m, n>::operator()(int i, int j) const
+{
+ CV_DbgAssert( (unsigned)i < (unsigned)m && (unsigned)j < (unsigned)n );
+ return this->val[i*n + j];
+}
+
+template<typename _Tp, int m, int n> inline
+_Tp& Matx<_Tp, m, n>::operator ()(int i, int j)
+{
+ CV_DbgAssert( (unsigned)i < (unsigned)m && (unsigned)j < (unsigned)n );
+ return val[i*n + j];
+}
+
+template<typename _Tp, int m, int n> inline
+const _Tp& Matx<_Tp, m, n>::operator ()(int i) const
+{
+ CV_StaticAssert(m == 1 || n == 1, "Single index indexation requires matrix to be a column or a row");
+ CV_DbgAssert( (unsigned)i < (unsigned)(m+n-1) );
+ return val[i];
+}
+
+template<typename _Tp, int m, int n> inline
+_Tp& Matx<_Tp, m, n>::operator ()(int i)
+{
+ CV_StaticAssert(m == 1 || n == 1, "Single index indexation requires matrix to be a column or a row");
+ CV_DbgAssert( (unsigned)i < (unsigned)(m+n-1) );
+ return val[i];
+}
+
+template<typename _Tp, int m, int n> inline
+Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_AddOp)
+{
+ for( int i = 0; i < channels; i++ )
+ val[i] = saturate_cast<_Tp>(a.val[i] + b.val[i]);
+}
+
+template<typename _Tp, int m, int n> inline
+Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_SubOp)
+{
+ for( int i = 0; i < channels; i++ )
+ val[i] = saturate_cast<_Tp>(a.val[i] - b.val[i]);
+}
+
+template<typename _Tp, int m, int n> template<typename _T2> inline
+Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, _T2 alpha, Matx_ScaleOp)
+{
+ for( int i = 0; i < channels; i++ )
+ val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
+}
+
+template<typename _Tp, int m, int n> inline
+Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_MulOp)
+{
+ for( int i = 0; i < channels; i++ )
+ val[i] = saturate_cast<_Tp>(a.val[i] * b.val[i]);
+}
+
+template<typename _Tp, int m, int n> inline
+Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_DivOp)
+{
+ for( int i = 0; i < channels; i++ )
+ val[i] = saturate_cast<_Tp>(a.val[i] / b.val[i]);
+}
+
+template<typename _Tp, int m, int n> template<int l> inline
+Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, l>& a, const Matx<_Tp, l, n>& b, Matx_MatMulOp)
+{
+ for( int i = 0; i < m; i++ )
+ for( int j = 0; j < n; j++ )
+ {
+ _Tp s = 0;
+ for( int k = 0; k < l; k++ )
+ s += a(i, k) * b(k, j);
+ val[i*n + j] = s;
+ }
+}
+
+template<typename _Tp, int m, int n> inline
+Matx<_Tp,m,n>::Matx(const Matx<_Tp, n, m>& a, Matx_TOp)
+{
+ for( int i = 0; i < m; i++ )
+ for( int j = 0; j < n; j++ )
+ val[i*n + j] = a(j, i);
+}
+
+template<typename _Tp, int m, int n> inline
+Matx<_Tp, m, n> Matx<_Tp, m, n>::mul(const Matx<_Tp, m, n>& a) const
+{
+ return Matx<_Tp, m, n>(*this, a, Matx_MulOp());
+}
+
+template<typename _Tp, int m, int n> inline
+Matx<_Tp, m, n> Matx<_Tp, m, n>::div(const Matx<_Tp, m, n>& a) const
+{
+ return Matx<_Tp, m, n>(*this, a, Matx_DivOp());
+}
+
+template<typename _Tp, int m, int n> inline
+Matx<_Tp, n, m> Matx<_Tp, m, n>::t() const
+{
+ return Matx<_Tp, n, m>(*this, Matx_TOp());
+}
+
+template<typename _Tp, int m, int n> inline
+Vec<_Tp, n> Matx<_Tp, m, n>::solve(const Vec<_Tp, m>& rhs, int method) const
+{
+ Matx<_Tp, n, 1> x = solve((const Matx<_Tp, m, 1>&)(rhs), method);
+ return (Vec<_Tp, n>&)(x);
+}
+
+template<typename _Tp, int m> static inline
+double determinant(const Matx<_Tp, m, m>& a)
+{
+ return cv::internal::Matx_DetOp<_Tp, m>()(a);
+}
+
+template<typename _Tp, int m, int n> static inline
+double trace(const Matx<_Tp, m, n>& a)
+{
+ _Tp s = 0;
+ for( int i = 0; i < std::min(m, n); i++ )
+ s += a(i,i);
+ return s;
+}
+
+template<typename _Tp, int m, int n> static inline
+double norm(const Matx<_Tp, m, n>& M)
+{
+ return std::sqrt(normL2Sqr<_Tp, double>(M.val, m*n));
+}
+
+template<typename _Tp, int m, int n> static inline
+double norm(const Matx<_Tp, m, n>& M, int normType)
+{
+ switch(normType) {
+ case NORM_INF:
+ return (double)normInf<_Tp, typename DataType<_Tp>::work_type>(M.val, m*n);
+ case NORM_L1:
+ return (double)normL1<_Tp, typename DataType<_Tp>::work_type>(M.val, m*n);
+ case NORM_L2SQR:
+ return (double)normL2Sqr<_Tp, typename DataType<_Tp>::work_type>(M.val, m*n);
+ default:
+ case NORM_L2:
+ return std::sqrt((double)normL2Sqr<_Tp, typename DataType<_Tp>::work_type>(M.val, m*n));
+ }
+}
+
+
+
+//////////////////////////////// matx comma initializer //////////////////////////////////
+
+template<typename _Tp, typename _T2, int m, int n> static inline
+MatxCommaInitializer<_Tp, m, n> operator << (const Matx<_Tp, m, n>& mtx, _T2 val)
+{
+ MatxCommaInitializer<_Tp, m, n> commaInitializer((Matx<_Tp, m, n>*)&mtx);
+ return (commaInitializer, val);
+}
+
+template<typename _Tp, int m, int n> inline
+MatxCommaInitializer<_Tp, m, n>::MatxCommaInitializer(Matx<_Tp, m, n>* _mtx)
+ : dst(_mtx), idx(0)
+{}
+
+template<typename _Tp, int m, int n> template<typename _T2> inline
+MatxCommaInitializer<_Tp, m, n>& MatxCommaInitializer<_Tp, m, n>::operator , (_T2 value)
+{
+ CV_DbgAssert( idx < m*n );
+ dst->val[idx++] = saturate_cast<_Tp>(value);
+ return *this;
+}
+
+template<typename _Tp, int m, int n> inline
+Matx<_Tp, m, n> MatxCommaInitializer<_Tp, m, n>::operator *() const
+{
+ CV_DbgAssert( idx == n*m );
+ return *dst;
+}
+
+
+
+/////////////////////////////////// Vec Implementation ///////////////////////////////////
+
+template<typename _Tp, int cn> inline
+Vec<_Tp, cn>::Vec() {}
+
+template<typename _Tp, int cn> inline
+Vec<_Tp, cn>::Vec(_Tp v0)
+ : Matx<_Tp, cn, 1>(v0) {}
+
+template<typename _Tp, int cn> inline
+Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1)
+ : Matx<_Tp, cn, 1>(v0, v1) {}
+
+template<typename _Tp, int cn> inline
+Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2)
+ : Matx<_Tp, cn, 1>(v0, v1, v2) {}
+
+template<typename _Tp, int cn> inline
+Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3)
+ : Matx<_Tp, cn, 1>(v0, v1, v2, v3) {}
+
+template<typename _Tp, int cn> inline
+Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4)
+ : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4) {}
+
+template<typename _Tp, int cn> inline
+Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5)
+ : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5) {}
+
+template<typename _Tp, int cn> inline
+Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6)
+ : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6) {}
+
+template<typename _Tp, int cn> inline
+Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7)
+ : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6, v7) {}
+
+template<typename _Tp, int cn> inline
+Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8)
+ : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6, v7, v8) {}
+
+template<typename _Tp, int cn> inline
+Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9)
+ : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) {}
+
+template<typename _Tp, int cn> inline
+Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9, _Tp v10, _Tp v11, _Tp v12, _Tp v13)
+ : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) {}
+
+template<typename _Tp, int cn> inline
+Vec<_Tp, cn>::Vec(const _Tp* values)
+ : Matx<_Tp, cn, 1>(values) {}
+
+template<typename _Tp, int cn> inline
+Vec<_Tp, cn>::Vec(const Vec<_Tp, cn>& m)
+ : Matx<_Tp, cn, 1>(m.val) {}
+
+template<typename _Tp, int cn> inline
+Vec<_Tp, cn>::Vec(const Matx<_Tp, cn, 1>& a, const Matx<_Tp, cn, 1>& b, Matx_AddOp op)
+ : Matx<_Tp, cn, 1>(a, b, op) {}
+
+template<typename _Tp, int cn> inline
+Vec<_Tp, cn>::Vec(const Matx<_Tp, cn, 1>& a, const Matx<_Tp, cn, 1>& b, Matx_SubOp op)
+ : Matx<_Tp, cn, 1>(a, b, op) {}
+
+template<typename _Tp, int cn> template<typename _T2> inline
+Vec<_Tp, cn>::Vec(const Matx<_Tp, cn, 1>& a, _T2 alpha, Matx_ScaleOp op)
+ : Matx<_Tp, cn, 1>(a, alpha, op) {}
+
+template<typename _Tp, int cn> inline
+Vec<_Tp, cn> Vec<_Tp, cn>::all(_Tp alpha)
+{
+ Vec v;
+ for( int i = 0; i < cn; i++ ) v.val[i] = alpha;
+ return v;
+}
+
+template<typename _Tp, int cn> inline
+Vec<_Tp, cn> Vec<_Tp, cn>::mul(const Vec<_Tp, cn>& v) const
+{
+ Vec<_Tp, cn> w;
+ for( int i = 0; i < cn; i++ ) w.val[i] = saturate_cast<_Tp>(this->val[i]*v.val[i]);
+ return w;
+}
+
+template<> inline
+Vec<float, 2> Vec<float, 2>::conj() const
+{
+ return cv::internal::conjugate(*this);
+}
+
+template<> inline
+Vec<double, 2> Vec<double, 2>::conj() const
+{
+ return cv::internal::conjugate(*this);
+}
+
+template<> inline
+Vec<float, 4> Vec<float, 4>::conj() const
+{
+ return cv::internal::conjugate(*this);
+}
+
+template<> inline
+Vec<double, 4> Vec<double, 4>::conj() const
+{
+ return cv::internal::conjugate(*this);
+}
+
+template<typename _Tp, int cn> inline
+Vec<_Tp, cn> Vec<_Tp, cn>::cross(const Vec<_Tp, cn>&) const
+{
+ CV_StaticAssert(cn == 3, "for arbitrary-size vector there is no cross-product defined");
+ return Vec<_Tp, cn>();
+}
+
+template<> inline
+Vec<float, 3> Vec<float, 3>::cross(const Vec<float, 3>& v) const
+{
+ return Vec<float,3>(this->val[1]*v.val[2] - this->val[2]*v.val[1],
+ this->val[2]*v.val[0] - this->val[0]*v.val[2],
+ this->val[0]*v.val[1] - this->val[1]*v.val[0]);
+}
+
+template<> inline
+Vec<double, 3> Vec<double, 3>::cross(const Vec<double, 3>& v) const
+{
+ return Vec<double,3>(this->val[1]*v.val[2] - this->val[2]*v.val[1],
+ this->val[2]*v.val[0] - this->val[0]*v.val[2],
+ this->val[0]*v.val[1] - this->val[1]*v.val[0]);
+}
+
+template<typename _Tp, int cn> template<typename T2> inline
+Vec<_Tp, cn>::operator Vec<T2, cn>() const
+{
+ Vec<T2, cn> v;
+ for( int i = 0; i < cn; i++ ) v.val[i] = saturate_cast<T2>(this->val[i]);
+ return v;
+}
+
+template<typename _Tp, int cn> inline
+const _Tp& Vec<_Tp, cn>::operator [](int i) const
+{
+ CV_DbgAssert( (unsigned)i < (unsigned)cn );
+ return this->val[i];
+}
+
+template<typename _Tp, int cn> inline
+_Tp& Vec<_Tp, cn>::operator [](int i)
+{
+ CV_DbgAssert( (unsigned)i < (unsigned)cn );
+ return this->val[i];
+}
+
+template<typename _Tp, int cn> inline
+const _Tp& Vec<_Tp, cn>::operator ()(int i) const
+{
+ CV_DbgAssert( (unsigned)i < (unsigned)cn );
+ return this->val[i];
+}
+
+template<typename _Tp, int cn> inline
+_Tp& Vec<_Tp, cn>::operator ()(int i)
+{
+ CV_DbgAssert( (unsigned)i < (unsigned)cn );
+ return this->val[i];
+}
+
+template<typename _Tp, int cn> inline
+Vec<_Tp, cn> normalize(const Vec<_Tp, cn>& v)
+{
+ double nv = norm(v);
+ return v * (nv ? 1./nv : 0.);
+}
+
+
+
+//////////////////////////////// matx comma initializer //////////////////////////////////
+
+
+template<typename _Tp, typename _T2, int cn> static inline
+VecCommaInitializer<_Tp, cn> operator << (const Vec<_Tp, cn>& vec, _T2 val)
+{
+ VecCommaInitializer<_Tp, cn> commaInitializer((Vec<_Tp, cn>*)&vec);
+ return (commaInitializer, val);
+}
+
+template<typename _Tp, int cn> inline
+VecCommaInitializer<_Tp, cn>::VecCommaInitializer(Vec<_Tp, cn>* _vec)
+ : MatxCommaInitializer<_Tp, cn, 1>(_vec)
+{}
+
+template<typename _Tp, int cn> template<typename _T2> inline
+VecCommaInitializer<_Tp, cn>& VecCommaInitializer<_Tp, cn>::operator , (_T2 value)
+{
+ CV_DbgAssert( this->idx < cn );
+ this->dst->val[this->idx++] = saturate_cast<_Tp>(value);
+ return *this;
+}
+
+template<typename _Tp, int cn> inline
+Vec<_Tp, cn> VecCommaInitializer<_Tp, cn>::operator *() const
+{
+ CV_DbgAssert( this->idx == cn );
+ return *this->dst;
+}
+
+//! @endcond
+
+///////////////////////////// Matx out-of-class operators ////////////////////////////////
+
+//! @relates cv::Matx
+//! @{
+
+template<typename _Tp1, typename _Tp2, int m, int n> static inline
+Matx<_Tp1, m, n>& operator += (Matx<_Tp1, m, n>& a, const Matx<_Tp2, m, n>& b)
+{
+ for( int i = 0; i < m*n; i++ )
+ a.val[i] = saturate_cast<_Tp1>(a.val[i] + b.val[i]);
+ return a;
+}
+
+template<typename _Tp1, typename _Tp2, int m, int n> static inline
+Matx<_Tp1, m, n>& operator -= (Matx<_Tp1, m, n>& a, const Matx<_Tp2, m, n>& b)
+{
+ for( int i = 0; i < m*n; i++ )
+ a.val[i] = saturate_cast<_Tp1>(a.val[i] - b.val[i]);
+ return a;
+}
+
+template<typename _Tp, int m, int n> static inline
+Matx<_Tp, m, n> operator + (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b)
+{
+ return Matx<_Tp, m, n>(a, b, Matx_AddOp());
+}
+
+template<typename _Tp, int m, int n> static inline
+Matx<_Tp, m, n> operator - (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b)
+{
+ return Matx<_Tp, m, n>(a, b, Matx_SubOp());
+}
+
+template<typename _Tp, int m, int n> static inline
+Matx<_Tp, m, n>& operator *= (Matx<_Tp, m, n>& a, int alpha)
+{
+ for( int i = 0; i < m*n; i++ )
+ a.val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
+ return a;
+}
+
+template<typename _Tp, int m, int n> static inline
+Matx<_Tp, m, n>& operator *= (Matx<_Tp, m, n>& a, float alpha)
+{
+ for( int i = 0; i < m*n; i++ )
+ a.val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
+ return a;
+}
+
+template<typename _Tp, int m, int n> static inline
+Matx<_Tp, m, n>& operator *= (Matx<_Tp, m, n>& a, double alpha)
+{
+ for( int i = 0; i < m*n; i++ )
+ a.val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
+ return a;
+}
+
+template<typename _Tp, int m, int n> static inline
+Matx<_Tp, m, n> operator * (const Matx<_Tp, m, n>& a, int alpha)
+{
+ return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp());
+}
+
+template<typename _Tp, int m, int n> static inline
+Matx<_Tp, m, n> operator * (const Matx<_Tp, m, n>& a, float alpha)
+{
+ return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp());
+}
+
+template<typename _Tp, int m, int n> static inline
+Matx<_Tp, m, n> operator * (const Matx<_Tp, m, n>& a, double alpha)
+{
+ return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp());
+}
+
+template<typename _Tp, int m, int n> static inline
+Matx<_Tp, m, n> operator * (int alpha, const Matx<_Tp, m, n>& a)
+{
+ return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp());
+}
+
+template<typename _Tp, int m, int n> static inline
+Matx<_Tp, m, n> operator * (float alpha, const Matx<_Tp, m, n>& a)
+{
+ return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp());
+}
+
+template<typename _Tp, int m, int n> static inline
+Matx<_Tp, m, n> operator * (double alpha, const Matx<_Tp, m, n>& a)
+{
+ return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp());
+}
+
+template<typename _Tp, int m, int n> static inline
+Matx<_Tp, m, n> operator - (const Matx<_Tp, m, n>& a)
+{
+ return Matx<_Tp, m, n>(a, -1, Matx_ScaleOp());
+}
+
+template<typename _Tp, int m, int n, int l> static inline
+Matx<_Tp, m, n> operator * (const Matx<_Tp, m, l>& a, const Matx<_Tp, l, n>& b)
+{
+ return Matx<_Tp, m, n>(a, b, Matx_MatMulOp());
+}
+
+template<typename _Tp, int m, int n> static inline
+Vec<_Tp, m> operator * (const Matx<_Tp, m, n>& a, const Vec<_Tp, n>& b)
+{
+ Matx<_Tp, m, 1> c(a, b, Matx_MatMulOp());
+ return (const Vec<_Tp, m>&)(c);
+}
+
+template<typename _Tp, int m, int n> static inline
+bool operator == (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b)
+{
+ for( int i = 0; i < m*n; i++ )
+ if( a.val[i] != b.val[i] ) return false;
+ return true;
+}
+
+template<typename _Tp, int m, int n> static inline
+bool operator != (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b)
+{
+ return !(a == b);
+}
+
+//! @}
+
+////////////////////////////// Vec out-of-class operators ////////////////////////////////
+
+//! @relates cv::Vec
+//! @{
+
+template<typename _Tp1, typename _Tp2, int cn> static inline
+Vec<_Tp1, cn>& operator += (Vec<_Tp1, cn>& a, const Vec<_Tp2, cn>& b)
+{
+ for( int i = 0; i < cn; i++ )
+ a.val[i] = saturate_cast<_Tp1>(a.val[i] + b.val[i]);
+ return a;
+}
+
+template<typename _Tp1, typename _Tp2, int cn> static inline
+Vec<_Tp1, cn>& operator -= (Vec<_Tp1, cn>& a, const Vec<_Tp2, cn>& b)
+{
+ for( int i = 0; i < cn; i++ )
+ a.val[i] = saturate_cast<_Tp1>(a.val[i] - b.val[i]);
+ return a;
+}
+
+template<typename _Tp, int cn> static inline
+Vec<_Tp, cn> operator + (const Vec<_Tp, cn>& a, const Vec<_Tp, cn>& b)
+{
+ return Vec<_Tp, cn>(a, b, Matx_AddOp());
+}
+
+template<typename _Tp, int cn> static inline
+Vec<_Tp, cn> operator - (const Vec<_Tp, cn>& a, const Vec<_Tp, cn>& b)
+{
+ return Vec<_Tp, cn>(a, b, Matx_SubOp());
+}
+
+template<typename _Tp, int cn> static inline
+Vec<_Tp, cn>& operator *= (Vec<_Tp, cn>& a, int alpha)
+{
+ for( int i = 0; i < cn; i++ )
+ a[i] = saturate_cast<_Tp>(a[i]*alpha);
+ return a;
+}
+
+template<typename _Tp, int cn> static inline
+Vec<_Tp, cn>& operator *= (Vec<_Tp, cn>& a, float alpha)
+{
+ for( int i = 0; i < cn; i++ )
+ a[i] = saturate_cast<_Tp>(a[i]*alpha);
+ return a;
+}
+
+template<typename _Tp, int cn> static inline
+Vec<_Tp, cn>& operator *= (Vec<_Tp, cn>& a, double alpha)
+{
+ for( int i = 0; i < cn; i++ )
+ a[i] = saturate_cast<_Tp>(a[i]*alpha);
+ return a;
+}
+
+template<typename _Tp, int cn> static inline
+Vec<_Tp, cn>& operator /= (Vec<_Tp, cn>& a, int alpha)
+{
+ double ialpha = 1./alpha;
+ for( int i = 0; i < cn; i++ )
+ a[i] = saturate_cast<_Tp>(a[i]*ialpha);
+ return a;
+}
+
+template<typename _Tp, int cn> static inline
+Vec<_Tp, cn>& operator /= (Vec<_Tp, cn>& a, float alpha)
+{
+ float ialpha = 1.f/alpha;
+ for( int i = 0; i < cn; i++ )
+ a[i] = saturate_cast<_Tp>(a[i]*ialpha);
+ return a;
+}
+
+template<typename _Tp, int cn> static inline
+Vec<_Tp, cn>& operator /= (Vec<_Tp, cn>& a, double alpha)
+{
+ double ialpha = 1./alpha;
+ for( int i = 0; i < cn; i++ )
+ a[i] = saturate_cast<_Tp>(a[i]*ialpha);
+ return a;
+}
+
+template<typename _Tp, int cn> static inline
+Vec<_Tp, cn> operator * (const Vec<_Tp, cn>& a, int alpha)
+{
+ return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp());
+}
+
+template<typename _Tp, int cn> static inline
+Vec<_Tp, cn> operator * (int alpha, const Vec<_Tp, cn>& a)
+{
+ return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp());
+}
+
+template<typename _Tp, int cn> static inline
+Vec<_Tp, cn> operator * (const Vec<_Tp, cn>& a, float alpha)
+{
+ return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp());
+}
+
+template<typename _Tp, int cn> static inline
+Vec<_Tp, cn> operator * (float alpha, const Vec<_Tp, cn>& a)
+{
+ return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp());
+}
+
+template<typename _Tp, int cn> static inline
+Vec<_Tp, cn> operator * (const Vec<_Tp, cn>& a, double alpha)
+{
+ return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp());
+}
+
+template<typename _Tp, int cn> static inline
+Vec<_Tp, cn> operator * (double alpha, const Vec<_Tp, cn>& a)
+{
+ return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp());
+}
+
+template<typename _Tp, int cn> static inline
+Vec<_Tp, cn> operator / (const Vec<_Tp, cn>& a, int alpha)
+{
+ return Vec<_Tp, cn>(a, 1./alpha, Matx_ScaleOp());
+}
+
+template<typename _Tp, int cn> static inline
+Vec<_Tp, cn> operator / (const Vec<_Tp, cn>& a, float alpha)
+{
+ return Vec<_Tp, cn>(a, 1.f/alpha, Matx_ScaleOp());
+}
+
+template<typename _Tp, int cn> static inline
+Vec<_Tp, cn> operator / (const Vec<_Tp, cn>& a, double alpha)
+{
+ return Vec<_Tp, cn>(a, 1./alpha, Matx_ScaleOp());
+}
+
+template<typename _Tp, int cn> static inline
+Vec<_Tp, cn> operator - (const Vec<_Tp, cn>& a)
+{
+ Vec<_Tp,cn> t;
+ for( int i = 0; i < cn; i++ ) t.val[i] = saturate_cast<_Tp>(-a.val[i]);
+ return t;
+}
+
+template<typename _Tp> inline Vec<_Tp, 4> operator * (const Vec<_Tp, 4>& v1, const Vec<_Tp, 4>& v2)
+{
+ return Vec<_Tp, 4>(saturate_cast<_Tp>(v1[0]*v2[0] - v1[1]*v2[1] - v1[2]*v2[2] - v1[3]*v2[3]),
+ saturate_cast<_Tp>(v1[0]*v2[1] + v1[1]*v2[0] + v1[2]*v2[3] - v1[3]*v2[2]),
+ saturate_cast<_Tp>(v1[0]*v2[2] - v1[1]*v2[3] + v1[2]*v2[0] + v1[3]*v2[1]),
+ saturate_cast<_Tp>(v1[0]*v2[3] + v1[1]*v2[2] - v1[2]*v2[1] + v1[3]*v2[0]));
+}
+
+template<typename _Tp> inline Vec<_Tp, 4>& operator *= (Vec<_Tp, 4>& v1, const Vec<_Tp, 4>& v2)
+{
+ v1 = v1 * v2;
+ return v1;
+}
+
+//! @}
+
+} // cv
+
+#endif // OPENCV_CORE_MATX_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/core/neon_utils.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,128 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2015, Itseez Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_HAL_NEON_UTILS_HPP
+#define OPENCV_HAL_NEON_UTILS_HPP
+
+#include "opencv2/core/cvdef.h"
+
+//! @addtogroup core_utils_neon
+//! @{
+
+#if CV_NEON
+
+inline int32x2_t cv_vrnd_s32_f32(float32x2_t v)
+{
+ static int32x2_t v_sign = vdup_n_s32(1 << 31),
+ v_05 = vreinterpret_s32_f32(vdup_n_f32(0.5f));
+
+ int32x2_t v_addition = vorr_s32(v_05, vand_s32(v_sign, vreinterpret_s32_f32(v)));
+ return vcvt_s32_f32(vadd_f32(v, vreinterpret_f32_s32(v_addition)));
+}
+
+inline int32x4_t cv_vrndq_s32_f32(float32x4_t v)
+{
+ static int32x4_t v_sign = vdupq_n_s32(1 << 31),
+ v_05 = vreinterpretq_s32_f32(vdupq_n_f32(0.5f));
+
+ int32x4_t v_addition = vorrq_s32(v_05, vandq_s32(v_sign, vreinterpretq_s32_f32(v)));
+ return vcvtq_s32_f32(vaddq_f32(v, vreinterpretq_f32_s32(v_addition)));
+}
+
+inline uint32x2_t cv_vrnd_u32_f32(float32x2_t v)
+{
+ static float32x2_t v_05 = vdup_n_f32(0.5f);
+ return vcvt_u32_f32(vadd_f32(v, v_05));
+}
+
+inline uint32x4_t cv_vrndq_u32_f32(float32x4_t v)
+{
+ static float32x4_t v_05 = vdupq_n_f32(0.5f);
+ return vcvtq_u32_f32(vaddq_f32(v, v_05));
+}
+
+inline float32x4_t cv_vrecpq_f32(float32x4_t val)
+{
+ float32x4_t reciprocal = vrecpeq_f32(val);
+ reciprocal = vmulq_f32(vrecpsq_f32(val, reciprocal), reciprocal);
+ reciprocal = vmulq_f32(vrecpsq_f32(val, reciprocal), reciprocal);
+ return reciprocal;
+}
+
+inline float32x2_t cv_vrecp_f32(float32x2_t val)
+{
+ float32x2_t reciprocal = vrecpe_f32(val);
+ reciprocal = vmul_f32(vrecps_f32(val, reciprocal), reciprocal);
+ reciprocal = vmul_f32(vrecps_f32(val, reciprocal), reciprocal);
+ return reciprocal;
+}
+
+inline float32x4_t cv_vrsqrtq_f32(float32x4_t val)
+{
+ float32x4_t e = vrsqrteq_f32(val);
+ e = vmulq_f32(vrsqrtsq_f32(vmulq_f32(e, e), val), e);
+ e = vmulq_f32(vrsqrtsq_f32(vmulq_f32(e, e), val), e);
+ return e;
+}
+
+inline float32x2_t cv_vrsqrt_f32(float32x2_t val)
+{
+ float32x2_t e = vrsqrte_f32(val);
+ e = vmul_f32(vrsqrts_f32(vmul_f32(e, e), val), e);
+ e = vmul_f32(vrsqrts_f32(vmul_f32(e, e), val), e);
+ return e;
+}
+
+inline float32x4_t cv_vsqrtq_f32(float32x4_t val)
+{
+ return cv_vrecpq_f32(cv_vrsqrtq_f32(val));
+}
+
+inline float32x2_t cv_vsqrt_f32(float32x2_t val)
+{
+ return cv_vrecp_f32(cv_vrsqrt_f32(val));
+}
+
+#endif
+
+//! @}
+
+#endif // OPENCV_HAL_NEON_UTILS_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/core/ocl.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,757 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the OpenCV Foundation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_OPENCL_HPP
+#define OPENCV_OPENCL_HPP
+
+#include "opencv2/core.hpp"
+
+namespace cv { namespace ocl {
+
+//! @addtogroup core_opencl
+//! @{
+
+CV_EXPORTS_W bool haveOpenCL();
+CV_EXPORTS_W bool useOpenCL();
+CV_EXPORTS_W bool haveAmdBlas();
+CV_EXPORTS_W bool haveAmdFft();
+CV_EXPORTS_W void setUseOpenCL(bool flag);
+CV_EXPORTS_W void finish();
+
+CV_EXPORTS bool haveSVM();
+
+class CV_EXPORTS Context;
+class CV_EXPORTS Device;
+class CV_EXPORTS Kernel;
+class CV_EXPORTS Program;
+class CV_EXPORTS ProgramSource;
+class CV_EXPORTS Queue;
+class CV_EXPORTS PlatformInfo;
+class CV_EXPORTS Image2D;
+
+class CV_EXPORTS Device
+{
+public:
+ Device();
+ explicit Device(void* d);
+ Device(const Device& d);
+ Device& operator = (const Device& d);
+ ~Device();
+
+ void set(void* d);
+
+ enum
+ {
+ TYPE_DEFAULT = (1 << 0),
+ TYPE_CPU = (1 << 1),
+ TYPE_GPU = (1 << 2),
+ TYPE_ACCELERATOR = (1 << 3),
+ TYPE_DGPU = TYPE_GPU + (1 << 16),
+ TYPE_IGPU = TYPE_GPU + (1 << 17),
+ TYPE_ALL = 0xFFFFFFFF
+ };
+
+ String name() const;
+ String extensions() const;
+ String version() const;
+ String vendorName() const;
+ String OpenCL_C_Version() const;
+ String OpenCLVersion() const;
+ int deviceVersionMajor() const;
+ int deviceVersionMinor() const;
+ String driverVersion() const;
+ void* ptr() const;
+
+ int type() const;
+
+ int addressBits() const;
+ bool available() const;
+ bool compilerAvailable() const;
+ bool linkerAvailable() const;
+
+ enum
+ {
+ FP_DENORM=(1 << 0),
+ FP_INF_NAN=(1 << 1),
+ FP_ROUND_TO_NEAREST=(1 << 2),
+ FP_ROUND_TO_ZERO=(1 << 3),
+ FP_ROUND_TO_INF=(1 << 4),
+ FP_FMA=(1 << 5),
+ FP_SOFT_FLOAT=(1 << 6),
+ FP_CORRECTLY_ROUNDED_DIVIDE_SQRT=(1 << 7)
+ };
+ int doubleFPConfig() const;
+ int singleFPConfig() const;
+ int halfFPConfig() const;
+
+ bool endianLittle() const;
+ bool errorCorrectionSupport() const;
+
+ enum
+ {
+ EXEC_KERNEL=(1 << 0),
+ EXEC_NATIVE_KERNEL=(1 << 1)
+ };
+ int executionCapabilities() const;
+
+ size_t globalMemCacheSize() const;
+
+ enum
+ {
+ NO_CACHE=0,
+ READ_ONLY_CACHE=1,
+ READ_WRITE_CACHE=2
+ };
+ int globalMemCacheType() const;
+ int globalMemCacheLineSize() const;
+ size_t globalMemSize() const;
+
+ size_t localMemSize() const;
+ enum
+ {
+ NO_LOCAL_MEM=0,
+ LOCAL_IS_LOCAL=1,
+ LOCAL_IS_GLOBAL=2
+ };
+ int localMemType() const;
+ bool hostUnifiedMemory() const;
+
+ bool imageSupport() const;
+
+ bool imageFromBufferSupport() const;
+ uint imagePitchAlignment() const;
+ uint imageBaseAddressAlignment() const;
+
+ size_t image2DMaxWidth() const;
+ size_t image2DMaxHeight() const;
+
+ size_t image3DMaxWidth() const;
+ size_t image3DMaxHeight() const;
+ size_t image3DMaxDepth() const;
+
+ size_t imageMaxBufferSize() const;
+ size_t imageMaxArraySize() const;
+
+ enum
+ {
+ UNKNOWN_VENDOR=0,
+ VENDOR_AMD=1,
+ VENDOR_INTEL=2,
+ VENDOR_NVIDIA=3
+ };
+ int vendorID() const;
+ // FIXIT
+ // dev.isAMD() doesn't work for OpenCL CPU devices from AMD OpenCL platform.
+ // This method should use platform name instead of vendor name.
+ // After fix restore code in arithm.cpp: ocl_compare()
+ inline bool isAMD() const { return vendorID() == VENDOR_AMD; }
+ inline bool isIntel() const { return vendorID() == VENDOR_INTEL; }
+ inline bool isNVidia() const { return vendorID() == VENDOR_NVIDIA; }
+
+ int maxClockFrequency() const;
+ int maxComputeUnits() const;
+ int maxConstantArgs() const;
+ size_t maxConstantBufferSize() const;
+
+ size_t maxMemAllocSize() const;
+ size_t maxParameterSize() const;
+
+ int maxReadImageArgs() const;
+ int maxWriteImageArgs() const;
+ int maxSamplers() const;
+
+ size_t maxWorkGroupSize() const;
+ int maxWorkItemDims() const;
+ void maxWorkItemSizes(size_t*) const;
+
+ int memBaseAddrAlign() const;
+
+ int nativeVectorWidthChar() const;
+ int nativeVectorWidthShort() const;
+ int nativeVectorWidthInt() const;
+ int nativeVectorWidthLong() const;
+ int nativeVectorWidthFloat() const;
+ int nativeVectorWidthDouble() const;
+ int nativeVectorWidthHalf() const;
+
+ int preferredVectorWidthChar() const;
+ int preferredVectorWidthShort() const;
+ int preferredVectorWidthInt() const;
+ int preferredVectorWidthLong() const;
+ int preferredVectorWidthFloat() const;
+ int preferredVectorWidthDouble() const;
+ int preferredVectorWidthHalf() const;
+
+ size_t printfBufferSize() const;
+ size_t profilingTimerResolution() const;
+
+ static const Device& getDefault();
+
+protected:
+ struct Impl;
+ Impl* p;
+};
+
+
+class CV_EXPORTS Context
+{
+public:
+ Context();
+ explicit Context(int dtype);
+ ~Context();
+ Context(const Context& c);
+ Context& operator = (const Context& c);
+
+ bool create();
+ bool create(int dtype);
+ size_t ndevices() const;
+ const Device& device(size_t idx) const;
+ Program getProg(const ProgramSource& prog,
+ const String& buildopt, String& errmsg);
+
+ static Context& getDefault(bool initialize = true);
+ void* ptr() const;
+
+ friend void initializeContextFromHandle(Context& ctx, void* platform, void* context, void* device);
+
+ bool useSVM() const;
+ void setUseSVM(bool enabled);
+
+ struct Impl;
+ Impl* p;
+};
+
+class CV_EXPORTS Platform
+{
+public:
+ Platform();
+ ~Platform();
+ Platform(const Platform& p);
+ Platform& operator = (const Platform& p);
+
+ void* ptr() const;
+ static Platform& getDefault();
+
+ friend void initializeContextFromHandle(Context& ctx, void* platform, void* context, void* device);
+protected:
+ struct Impl;
+ Impl* p;
+};
+
+/*
+//! @brief Attaches OpenCL context to OpenCV
+//
+//! @note Note:
+// OpenCV will check if available OpenCL platform has platformName name,
+// then assign context to OpenCV and call clRetainContext function.
+// The deviceID device will be used as target device and new command queue
+// will be created.
+//
+// Params:
+//! @param platformName - name of OpenCL platform to attach,
+//! this string is used to check if platform is available
+//! to OpenCV at runtime
+//! @param platfromID - ID of platform attached context was created for
+//! @param context - OpenCL context to be attached to OpenCV
+//! @param deviceID - ID of device, must be created from attached context
+*/
+CV_EXPORTS void attachContext(const String& platformName, void* platformID, void* context, void* deviceID);
+
+/*
+//! @brief Convert OpenCL buffer to UMat
+//
+//! @note Note:
+// OpenCL buffer (cl_mem_buffer) should contain 2D image data, compatible with OpenCV.
+// Memory content is not copied from clBuffer to UMat. Instead, buffer handle assigned
+// to UMat and clRetainMemObject is called.
+//
+// Params:
+//! @param cl_mem_buffer - source clBuffer handle
+//! @param step - num of bytes in single row
+//! @param rows - number of rows
+//! @param cols - number of cols
+//! @param type - OpenCV type of image
+//! @param dst - destination UMat
+*/
+CV_EXPORTS void convertFromBuffer(void* cl_mem_buffer, size_t step, int rows, int cols, int type, UMat& dst);
+
+/*
+//! @brief Convert OpenCL image2d_t to UMat
+//
+//! @note Note:
+// OpenCL image2d_t (cl_mem_image), should be compatible with OpenCV
+// UMat formats.
+// Memory content is copied from image to UMat with
+// clEnqueueCopyImageToBuffer function.
+//
+// Params:
+//! @param cl_mem_image - source image2d_t handle
+//! @param dst - destination UMat
+*/
+CV_EXPORTS void convertFromImage(void* cl_mem_image, UMat& dst);
+
+// TODO Move to internal header
+void initializeContextFromHandle(Context& ctx, void* platform, void* context, void* device);
+
+class CV_EXPORTS Queue
+{
+public:
+ Queue();
+ explicit Queue(const Context& c, const Device& d=Device());
+ ~Queue();
+ Queue(const Queue& q);
+ Queue& operator = (const Queue& q);
+
+ bool create(const Context& c=Context(), const Device& d=Device());
+ void finish();
+ void* ptr() const;
+ static Queue& getDefault();
+
+protected:
+ struct Impl;
+ Impl* p;
+};
+
+
+class CV_EXPORTS KernelArg
+{
+public:
+ enum { LOCAL=1, READ_ONLY=2, WRITE_ONLY=4, READ_WRITE=6, CONSTANT=8, PTR_ONLY = 16, NO_SIZE=256 };
+ KernelArg(int _flags, UMat* _m, int wscale=1, int iwscale=1, const void* _obj=0, size_t _sz=0);
+ KernelArg();
+
+ static KernelArg Local() { return KernelArg(LOCAL, 0); }
+ static KernelArg PtrWriteOnly(const UMat& m)
+ { return KernelArg(PTR_ONLY+WRITE_ONLY, (UMat*)&m); }
+ static KernelArg PtrReadOnly(const UMat& m)
+ { return KernelArg(PTR_ONLY+READ_ONLY, (UMat*)&m); }
+ static KernelArg PtrReadWrite(const UMat& m)
+ { return KernelArg(PTR_ONLY+READ_WRITE, (UMat*)&m); }
+ static KernelArg ReadWrite(const UMat& m, int wscale=1, int iwscale=1)
+ { return KernelArg(READ_WRITE, (UMat*)&m, wscale, iwscale); }
+ static KernelArg ReadWriteNoSize(const UMat& m, int wscale=1, int iwscale=1)
+ { return KernelArg(READ_WRITE+NO_SIZE, (UMat*)&m, wscale, iwscale); }
+ static KernelArg ReadOnly(const UMat& m, int wscale=1, int iwscale=1)
+ { return KernelArg(READ_ONLY, (UMat*)&m, wscale, iwscale); }
+ static KernelArg WriteOnly(const UMat& m, int wscale=1, int iwscale=1)
+ { return KernelArg(WRITE_ONLY, (UMat*)&m, wscale, iwscale); }
+ static KernelArg ReadOnlyNoSize(const UMat& m, int wscale=1, int iwscale=1)
+ { return KernelArg(READ_ONLY+NO_SIZE, (UMat*)&m, wscale, iwscale); }
+ static KernelArg WriteOnlyNoSize(const UMat& m, int wscale=1, int iwscale=1)
+ { return KernelArg(WRITE_ONLY+NO_SIZE, (UMat*)&m, wscale, iwscale); }
+ static KernelArg Constant(const Mat& m);
+ template<typename _Tp> static KernelArg Constant(const _Tp* arr, size_t n)
+ { return KernelArg(CONSTANT, 0, 1, 1, (void*)arr, n); }
+
+ int flags;
+ UMat* m;
+ const void* obj;
+ size_t sz;
+ int wscale, iwscale;
+};
+
+
+class CV_EXPORTS Kernel
+{
+public:
+ Kernel();
+ Kernel(const char* kname, const Program& prog);
+ Kernel(const char* kname, const ProgramSource& prog,
+ const String& buildopts = String(), String* errmsg=0);
+ ~Kernel();
+ Kernel(const Kernel& k);
+ Kernel& operator = (const Kernel& k);
+
+ bool empty() const;
+ bool create(const char* kname, const Program& prog);
+ bool create(const char* kname, const ProgramSource& prog,
+ const String& buildopts, String* errmsg=0);
+
+ int set(int i, const void* value, size_t sz);
+ int set(int i, const Image2D& image2D);
+ int set(int i, const UMat& m);
+ int set(int i, const KernelArg& arg);
+ template<typename _Tp> int set(int i, const _Tp& value)
+ { return set(i, &value, sizeof(value)); }
+
+ template<typename _Tp0>
+ Kernel& args(const _Tp0& a0)
+ {
+ set(0, a0); return *this;
+ }
+
+ template<typename _Tp0, typename _Tp1>
+ Kernel& args(const _Tp0& a0, const _Tp1& a1)
+ {
+ int i = set(0, a0); set(i, a1); return *this;
+ }
+
+ template<typename _Tp0, typename _Tp1, typename _Tp2>
+ Kernel& args(const _Tp0& a0, const _Tp1& a1, const _Tp2& a2)
+ {
+ int i = set(0, a0); i = set(i, a1); set(i, a2); return *this;
+ }
+
+ template<typename _Tp0, typename _Tp1, typename _Tp2, typename _Tp3>
+ Kernel& args(const _Tp0& a0, const _Tp1& a1, const _Tp2& a2, const _Tp3& a3)
+ {
+ int i = set(0, a0); i = set(i, a1); i = set(i, a2); i = set(i, a3); return *this;
+ }
+
+ template<typename _Tp0, typename _Tp1, typename _Tp2, typename _Tp3, typename _Tp4>
+ Kernel& args(const _Tp0& a0, const _Tp1& a1, const _Tp2& a2,
+ const _Tp3& a3, const _Tp4& a4)
+ {
+ int i = set(0, a0); i = set(i, a1); i = set(i, a2);
+ i = set(i, a3); set(i, a4); return *this;
+ }
+
+ template<typename _Tp0, typename _Tp1, typename _Tp2,
+ typename _Tp3, typename _Tp4, typename _Tp5>
+ Kernel& args(const _Tp0& a0, const _Tp1& a1, const _Tp2& a2,
+ const _Tp3& a3, const _Tp4& a4, const _Tp5& a5)
+ {
+ int i = set(0, a0); i = set(i, a1); i = set(i, a2);
+ i = set(i, a3); i = set(i, a4); set(i, a5); return *this;
+ }
+
+ template<typename _Tp0, typename _Tp1, typename _Tp2, typename _Tp3,
+ typename _Tp4, typename _Tp5, typename _Tp6>
+ Kernel& args(const _Tp0& a0, const _Tp1& a1, const _Tp2& a2, const _Tp3& a3,
+ const _Tp4& a4, const _Tp5& a5, const _Tp6& a6)
+ {
+ int i = set(0, a0); i = set(i, a1); i = set(i, a2); i = set(i, a3);
+ i = set(i, a4); i = set(i, a5); set(i, a6); return *this;
+ }
+
+ template<typename _Tp0, typename _Tp1, typename _Tp2, typename _Tp3,
+ typename _Tp4, typename _Tp5, typename _Tp6, typename _Tp7>
+ Kernel& args(const _Tp0& a0, const _Tp1& a1, const _Tp2& a2, const _Tp3& a3,
+ const _Tp4& a4, const _Tp5& a5, const _Tp6& a6, const _Tp7& a7)
+ {
+ int i = set(0, a0); i = set(i, a1); i = set(i, a2); i = set(i, a3);
+ i = set(i, a4); i = set(i, a5); i = set(i, a6); set(i, a7); return *this;
+ }
+
+ template<typename _Tp0, typename _Tp1, typename _Tp2, typename _Tp3, typename _Tp4,
+ typename _Tp5, typename _Tp6, typename _Tp7, typename _Tp8>
+ Kernel& args(const _Tp0& a0, const _Tp1& a1, const _Tp2& a2, const _Tp3& a3,
+ const _Tp4& a4, const _Tp5& a5, const _Tp6& a6, const _Tp7& a7,
+ const _Tp8& a8)
+ {
+ int i = set(0, a0); i = set(i, a1); i = set(i, a2); i = set(i, a3); i = set(i, a4);
+ i = set(i, a5); i = set(i, a6); i = set(i, a7); set(i, a8); return *this;
+ }
+
+ template<typename _Tp0, typename _Tp1, typename _Tp2, typename _Tp3, typename _Tp4,
+ typename _Tp5, typename _Tp6, typename _Tp7, typename _Tp8, typename _Tp9>
+ Kernel& args(const _Tp0& a0, const _Tp1& a1, const _Tp2& a2, const _Tp3& a3,
+ const _Tp4& a4, const _Tp5& a5, const _Tp6& a6, const _Tp7& a7,
+ const _Tp8& a8, const _Tp9& a9)
+ {
+ int i = set(0, a0); i = set(i, a1); i = set(i, a2); i = set(i, a3); i = set(i, a4); i = set(i, a5);
+ i = set(i, a6); i = set(i, a7); i = set(i, a8); set(i, a9); return *this;
+ }
+
+ template<typename _Tp0, typename _Tp1, typename _Tp2, typename _Tp3,
+ typename _Tp4, typename _Tp5, typename _Tp6, typename _Tp7,
+ typename _Tp8, typename _Tp9, typename _Tp10>
+ Kernel& args(const _Tp0& a0, const _Tp1& a1, const _Tp2& a2, const _Tp3& a3,
+ const _Tp4& a4, const _Tp5& a5, const _Tp6& a6, const _Tp7& a7,
+ const _Tp8& a8, const _Tp9& a9, const _Tp10& a10)
+ {
+ int i = set(0, a0); i = set(i, a1); i = set(i, a2); i = set(i, a3); i = set(i, a4); i = set(i, a5);
+ i = set(i, a6); i = set(i, a7); i = set(i, a8); i = set(i, a9); set(i, a10); return *this;
+ }
+
+ template<typename _Tp0, typename _Tp1, typename _Tp2, typename _Tp3,
+ typename _Tp4, typename _Tp5, typename _Tp6, typename _Tp7,
+ typename _Tp8, typename _Tp9, typename _Tp10, typename _Tp11>
+ Kernel& args(const _Tp0& a0, const _Tp1& a1, const _Tp2& a2, const _Tp3& a3,
+ const _Tp4& a4, const _Tp5& a5, const _Tp6& a6, const _Tp7& a7,
+ const _Tp8& a8, const _Tp9& a9, const _Tp10& a10, const _Tp11& a11)
+ {
+ int i = set(0, a0); i = set(i, a1); i = set(i, a2); i = set(i, a3); i = set(i, a4); i = set(i, a5);
+ i = set(i, a6); i = set(i, a7); i = set(i, a8); i = set(i, a9); i = set(i, a10); set(i, a11); return *this;
+ }
+
+ template<typename _Tp0, typename _Tp1, typename _Tp2, typename _Tp3,
+ typename _Tp4, typename _Tp5, typename _Tp6, typename _Tp7,
+ typename _Tp8, typename _Tp9, typename _Tp10, typename _Tp11, typename _Tp12>
+ Kernel& args(const _Tp0& a0, const _Tp1& a1, const _Tp2& a2, const _Tp3& a3,
+ const _Tp4& a4, const _Tp5& a5, const _Tp6& a6, const _Tp7& a7,
+ const _Tp8& a8, const _Tp9& a9, const _Tp10& a10, const _Tp11& a11,
+ const _Tp12& a12)
+ {
+ int i = set(0, a0); i = set(i, a1); i = set(i, a2); i = set(i, a3); i = set(i, a4); i = set(i, a5);
+ i = set(i, a6); i = set(i, a7); i = set(i, a8); i = set(i, a9); i = set(i, a10); i = set(i, a11);
+ set(i, a12); return *this;
+ }
+
+ template<typename _Tp0, typename _Tp1, typename _Tp2, typename _Tp3,
+ typename _Tp4, typename _Tp5, typename _Tp6, typename _Tp7,
+ typename _Tp8, typename _Tp9, typename _Tp10, typename _Tp11, typename _Tp12,
+ typename _Tp13>
+ Kernel& args(const _Tp0& a0, const _Tp1& a1, const _Tp2& a2, const _Tp3& a3,
+ const _Tp4& a4, const _Tp5& a5, const _Tp6& a6, const _Tp7& a7,
+ const _Tp8& a8, const _Tp9& a9, const _Tp10& a10, const _Tp11& a11,
+ const _Tp12& a12, const _Tp13& a13)
+ {
+ int i = set(0, a0); i = set(i, a1); i = set(i, a2); i = set(i, a3); i = set(i, a4); i = set(i, a5);
+ i = set(i, a6); i = set(i, a7); i = set(i, a8); i = set(i, a9); i = set(i, a10); i = set(i, a11);
+ i = set(i, a12); set(i, a13); return *this;
+ }
+
+ template<typename _Tp0, typename _Tp1, typename _Tp2, typename _Tp3,
+ typename _Tp4, typename _Tp5, typename _Tp6, typename _Tp7,
+ typename _Tp8, typename _Tp9, typename _Tp10, typename _Tp11, typename _Tp12,
+ typename _Tp13, typename _Tp14>
+ Kernel& args(const _Tp0& a0, const _Tp1& a1, const _Tp2& a2, const _Tp3& a3,
+ const _Tp4& a4, const _Tp5& a5, const _Tp6& a6, const _Tp7& a7,
+ const _Tp8& a8, const _Tp9& a9, const _Tp10& a10, const _Tp11& a11,
+ const _Tp12& a12, const _Tp13& a13, const _Tp14& a14)
+ {
+ int i = set(0, a0); i = set(i, a1); i = set(i, a2); i = set(i, a3); i = set(i, a4); i = set(i, a5);
+ i = set(i, a6); i = set(i, a7); i = set(i, a8); i = set(i, a9); i = set(i, a10); i = set(i, a11);
+ i = set(i, a12); i = set(i, a13); set(i, a14); return *this;
+ }
+
+ template<typename _Tp0, typename _Tp1, typename _Tp2, typename _Tp3,
+ typename _Tp4, typename _Tp5, typename _Tp6, typename _Tp7,
+ typename _Tp8, typename _Tp9, typename _Tp10, typename _Tp11, typename _Tp12,
+ typename _Tp13, typename _Tp14, typename _Tp15>
+ Kernel& args(const _Tp0& a0, const _Tp1& a1, const _Tp2& a2, const _Tp3& a3,
+ const _Tp4& a4, const _Tp5& a5, const _Tp6& a6, const _Tp7& a7,
+ const _Tp8& a8, const _Tp9& a9, const _Tp10& a10, const _Tp11& a11,
+ const _Tp12& a12, const _Tp13& a13, const _Tp14& a14, const _Tp15& a15)
+ {
+ int i = set(0, a0); i = set(i, a1); i = set(i, a2); i = set(i, a3); i = set(i, a4); i = set(i, a5);
+ i = set(i, a6); i = set(i, a7); i = set(i, a8); i = set(i, a9); i = set(i, a10); i = set(i, a11);
+ i = set(i, a12); i = set(i, a13); i = set(i, a14); set(i, a15); return *this;
+ }
+ /*
+ Run the OpenCL kernel.
+ @param dims the work problem dimensions. It is the length of globalsize and localsize. It can be either 1, 2 or 3.
+ @param globalsize work items for each dimension.
+ It is not the final globalsize passed to OpenCL.
+ Each dimension will be adjusted to the nearest integer divisible by the corresponding value in localsize.
+ If localsize is NULL, it will still be adjusted depending on dims.
+ The adjusted values are greater than or equal to the original values.
+ @param localsize work-group size for each dimension.
+ @param sync specify whether to wait for OpenCL computation to finish before return.
+ @param q command queue
+ */
+ bool run(int dims, size_t globalsize[],
+ size_t localsize[], bool sync, const Queue& q=Queue());
+ bool runTask(bool sync, const Queue& q=Queue());
+
+ size_t workGroupSize() const;
+ size_t preferedWorkGroupSizeMultiple() const;
+ bool compileWorkGroupSize(size_t wsz[]) const;
+ size_t localMemSize() const;
+
+ void* ptr() const;
+ struct Impl;
+
+protected:
+ Impl* p;
+};
+
+class CV_EXPORTS Program
+{
+public:
+ Program();
+ Program(const ProgramSource& src,
+ const String& buildflags, String& errmsg);
+ explicit Program(const String& buf);
+ Program(const Program& prog);
+
+ Program& operator = (const Program& prog);
+ ~Program();
+
+ bool create(const ProgramSource& src,
+ const String& buildflags, String& errmsg);
+ bool read(const String& buf, const String& buildflags);
+ bool write(String& buf) const;
+
+ const ProgramSource& source() const;
+ void* ptr() const;
+
+ String getPrefix() const;
+ static String getPrefix(const String& buildflags);
+
+protected:
+ struct Impl;
+ Impl* p;
+};
+
+
+class CV_EXPORTS ProgramSource
+{
+public:
+ typedef uint64 hash_t;
+
+ ProgramSource();
+ explicit ProgramSource(const String& prog);
+ explicit ProgramSource(const char* prog);
+ ~ProgramSource();
+ ProgramSource(const ProgramSource& prog);
+ ProgramSource& operator = (const ProgramSource& prog);
+
+ const String& source() const;
+ hash_t hash() const;
+
+protected:
+ struct Impl;
+ Impl* p;
+};
+
+class CV_EXPORTS PlatformInfo
+{
+public:
+ PlatformInfo();
+ explicit PlatformInfo(void* id);
+ ~PlatformInfo();
+
+ PlatformInfo(const PlatformInfo& i);
+ PlatformInfo& operator =(const PlatformInfo& i);
+
+ String name() const;
+ String vendor() const;
+ String version() const;
+ int deviceNumber() const;
+ void getDevice(Device& device, int d) const;
+
+protected:
+ struct Impl;
+ Impl* p;
+};
+
+CV_EXPORTS const char* convertTypeStr(int sdepth, int ddepth, int cn, char* buf);
+CV_EXPORTS const char* typeToStr(int t);
+CV_EXPORTS const char* memopTypeToStr(int t);
+CV_EXPORTS const char* vecopTypeToStr(int t);
+CV_EXPORTS String kernelToStr(InputArray _kernel, int ddepth = -1, const char * name = NULL);
+CV_EXPORTS void getPlatfomsInfo(std::vector<PlatformInfo>& platform_info);
+
+
+enum OclVectorStrategy
+{
+ // all matrices have its own vector width
+ OCL_VECTOR_OWN = 0,
+ // all matrices have maximal vector width among all matrices
+ // (useful for cases when matrices have different data types)
+ OCL_VECTOR_MAX = 1,
+
+ // default strategy
+ OCL_VECTOR_DEFAULT = OCL_VECTOR_OWN
+};
+
+CV_EXPORTS int predictOptimalVectorWidth(InputArray src1, InputArray src2 = noArray(), InputArray src3 = noArray(),
+ InputArray src4 = noArray(), InputArray src5 = noArray(), InputArray src6 = noArray(),
+ InputArray src7 = noArray(), InputArray src8 = noArray(), InputArray src9 = noArray(),
+ OclVectorStrategy strat = OCL_VECTOR_DEFAULT);
+
+CV_EXPORTS int checkOptimalVectorWidth(const int *vectorWidths,
+ InputArray src1, InputArray src2 = noArray(), InputArray src3 = noArray(),
+ InputArray src4 = noArray(), InputArray src5 = noArray(), InputArray src6 = noArray(),
+ InputArray src7 = noArray(), InputArray src8 = noArray(), InputArray src9 = noArray(),
+ OclVectorStrategy strat = OCL_VECTOR_DEFAULT);
+
+// with OCL_VECTOR_MAX strategy
+CV_EXPORTS int predictOptimalVectorWidthMax(InputArray src1, InputArray src2 = noArray(), InputArray src3 = noArray(),
+ InputArray src4 = noArray(), InputArray src5 = noArray(), InputArray src6 = noArray(),
+ InputArray src7 = noArray(), InputArray src8 = noArray(), InputArray src9 = noArray());
+
+CV_EXPORTS void buildOptionsAddMatrixDescription(String& buildOptions, const String& name, InputArray _m);
+
+class CV_EXPORTS Image2D
+{
+public:
+ Image2D();
+
+ // src: The UMat from which to get image properties and data
+ // norm: Flag to enable the use of normalized channel data types
+ // alias: Flag indicating that the image should alias the src UMat.
+ // If true, changes to the image or src will be reflected in
+ // both objects.
+ explicit Image2D(const UMat &src, bool norm = false, bool alias = false);
+ Image2D(const Image2D & i);
+ ~Image2D();
+
+ Image2D & operator = (const Image2D & i);
+
+ // Indicates if creating an aliased image should succeed. Depends on the
+ // underlying platform and the dimensions of the UMat.
+ static bool canCreateAlias(const UMat &u);
+
+ // Indicates if the image format is supported.
+ static bool isFormatSupported(int depth, int cn, bool norm);
+
+ void* ptr() const;
+protected:
+ struct Impl;
+ Impl* p;
+};
+
+
+CV_EXPORTS MatAllocator* getOpenCLAllocator();
+
+
+#ifdef __OPENCV_BUILD
+namespace internal {
+
+CV_EXPORTS bool isOpenCLForced();
+#define OCL_FORCE_CHECK(condition) (cv::ocl::internal::isOpenCLForced() || (condition))
+
+CV_EXPORTS bool isPerformanceCheckBypassed();
+#define OCL_PERFORMANCE_CHECK(condition) (cv::ocl::internal::isPerformanceCheckBypassed() || (condition))
+
+CV_EXPORTS bool isCLBuffer(UMat& u);
+
+} // namespace internal
+#endif
+
+//! @}
+
+}}
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/core/ocl_genbase.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,64 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the OpenCV Foundation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_OPENCL_GENBASE_HPP
+#define OPENCV_OPENCL_GENBASE_HPP
+
+namespace cv
+{
+namespace ocl
+{
+
+//! @cond IGNORED
+
+struct ProgramEntry
+{
+ const char* name;
+ const char* programStr;
+ const char* programHash;
+};
+
+//! @endcond
+
+}
+}
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/core/opengl.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,729 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_CORE_OPENGL_HPP
+#define OPENCV_CORE_OPENGL_HPP
+
+#ifndef __cplusplus
+# error opengl.hpp header must be compiled as C++
+#endif
+
+#include "opencv2/core.hpp"
+#include "ocl.hpp"
+
+namespace cv { namespace ogl {
+
+/** @addtogroup core_opengl
+This section describes OpenGL interoperability.
+
+To enable OpenGL support, configure OpenCV using CMake with WITH_OPENGL=ON . Currently OpenGL is
+supported only with WIN32, GTK and Qt backends on Windows and Linux (MacOS and Android are not
+supported). For GTK backend gtkglext-1.0 library is required.
+
+To use OpenGL functionality you should first create OpenGL context (window or frame buffer). You can
+do this with namedWindow function or with other OpenGL toolkit (GLUT, for example).
+*/
+//! @{
+
+/////////////////// OpenGL Objects ///////////////////
+
+/** @brief Smart pointer for OpenGL buffer object with reference counting.
+
+Buffer Objects are OpenGL objects that store an array of unformatted memory allocated by the OpenGL
+context. These can be used to store vertex data, pixel data retrieved from images or the
+framebuffer, and a variety of other things.
+
+ogl::Buffer has interface similar with Mat interface and represents 2D array memory.
+
+ogl::Buffer supports memory transfers between host and device and also can be mapped to CUDA memory.
+ */
+class CV_EXPORTS Buffer
+{
+public:
+ /** @brief The target defines how you intend to use the buffer object.
+ */
+ enum Target
+ {
+ ARRAY_BUFFER = 0x8892, //!< The buffer will be used as a source for vertex data
+ ELEMENT_ARRAY_BUFFER = 0x8893, //!< The buffer will be used for indices (in glDrawElements, for example)
+ PIXEL_PACK_BUFFER = 0x88EB, //!< The buffer will be used for reading from OpenGL textures
+ PIXEL_UNPACK_BUFFER = 0x88EC //!< The buffer will be used for writing to OpenGL textures
+ };
+
+ enum Access
+ {
+ READ_ONLY = 0x88B8,
+ WRITE_ONLY = 0x88B9,
+ READ_WRITE = 0x88BA
+ };
+
+ /** @brief The constructors.
+
+ Creates empty ogl::Buffer object, creates ogl::Buffer object from existed buffer ( abufId
+ parameter), allocates memory for ogl::Buffer object or copies from host/device memory.
+ */
+ Buffer();
+
+ /** @overload
+ @param arows Number of rows in a 2D array.
+ @param acols Number of columns in a 2D array.
+ @param atype Array type ( CV_8UC1, ..., CV_64FC4 ). See Mat for details.
+ @param abufId Buffer object name.
+ @param autoRelease Auto release mode (if true, release will be called in object's destructor).
+ */
+ Buffer(int arows, int acols, int atype, unsigned int abufId, bool autoRelease = false);
+
+ /** @overload
+ @param asize 2D array size.
+ @param atype Array type ( CV_8UC1, ..., CV_64FC4 ). See Mat for details.
+ @param abufId Buffer object name.
+ @param autoRelease Auto release mode (if true, release will be called in object's destructor).
+ */
+ Buffer(Size asize, int atype, unsigned int abufId, bool autoRelease = false);
+
+ /** @overload
+ @param arows Number of rows in a 2D array.
+ @param acols Number of columns in a 2D array.
+ @param atype Array type ( CV_8UC1, ..., CV_64FC4 ). See Mat for details.
+ @param target Buffer usage. See cv::ogl::Buffer::Target .
+ @param autoRelease Auto release mode (if true, release will be called in object's destructor).
+ */
+ Buffer(int arows, int acols, int atype, Target target = ARRAY_BUFFER, bool autoRelease = false);
+
+ /** @overload
+ @param asize 2D array size.
+ @param atype Array type ( CV_8UC1, ..., CV_64FC4 ). See Mat for details.
+ @param target Buffer usage. See cv::ogl::Buffer::Target .
+ @param autoRelease Auto release mode (if true, release will be called in object's destructor).
+ */
+ Buffer(Size asize, int atype, Target target = ARRAY_BUFFER, bool autoRelease = false);
+
+ /** @overload
+ @param arr Input array (host or device memory, it can be Mat , cuda::GpuMat or std::vector ).
+ @param target Buffer usage. See cv::ogl::Buffer::Target .
+ @param autoRelease Auto release mode (if true, release will be called in object's destructor).
+ */
+ explicit Buffer(InputArray arr, Target target = ARRAY_BUFFER, bool autoRelease = false);
+
+ /** @brief Allocates memory for ogl::Buffer object.
+
+ @param arows Number of rows in a 2D array.
+ @param acols Number of columns in a 2D array.
+ @param atype Array type ( CV_8UC1, ..., CV_64FC4 ). See Mat for details.
+ @param target Buffer usage. See cv::ogl::Buffer::Target .
+ @param autoRelease Auto release mode (if true, release will be called in object's destructor).
+ */
+ void create(int arows, int acols, int atype, Target target = ARRAY_BUFFER, bool autoRelease = false);
+
+ /** @overload
+ @param asize 2D array size.
+ @param atype Array type ( CV_8UC1, ..., CV_64FC4 ). See Mat for details.
+ @param target Buffer usage. See cv::ogl::Buffer::Target .
+ @param autoRelease Auto release mode (if true, release will be called in object's destructor).
+ */
+ void create(Size asize, int atype, Target target = ARRAY_BUFFER, bool autoRelease = false);
+
+ /** @brief Decrements the reference counter and destroys the buffer object if needed.
+
+ The function will call setAutoRelease(true) .
+ */
+ void release();
+
+ /** @brief Sets auto release mode.
+
+ The lifetime of the OpenGL object is tied to the lifetime of the context. If OpenGL context was
+ bound to a window it could be released at any time (user can close a window). If object's destructor
+ is called after destruction of the context it will cause an error. Thus ogl::Buffer doesn't destroy
+ OpenGL object in destructor by default (all OpenGL resources will be released with OpenGL context).
+ This function can force ogl::Buffer destructor to destroy OpenGL object.
+ @param flag Auto release mode (if true, release will be called in object's destructor).
+ */
+ void setAutoRelease(bool flag);
+
+ /** @brief Copies from host/device memory to OpenGL buffer.
+ @param arr Input array (host or device memory, it can be Mat , cuda::GpuMat or std::vector ).
+ @param target Buffer usage. See cv::ogl::Buffer::Target .
+ @param autoRelease Auto release mode (if true, release will be called in object's destructor).
+ */
+ void copyFrom(InputArray arr, Target target = ARRAY_BUFFER, bool autoRelease = false);
+
+ /** @overload */
+ void copyFrom(InputArray arr, cuda::Stream& stream, Target target = ARRAY_BUFFER, bool autoRelease = false);
+
+ /** @brief Copies from OpenGL buffer to host/device memory or another OpenGL buffer object.
+
+ @param arr Destination array (host or device memory, can be Mat , cuda::GpuMat , std::vector or
+ ogl::Buffer ).
+ */
+ void copyTo(OutputArray arr) const;
+
+ /** @overload */
+ void copyTo(OutputArray arr, cuda::Stream& stream) const;
+
+ /** @brief Creates a full copy of the buffer object and the underlying data.
+
+ @param target Buffer usage for destination buffer.
+ @param autoRelease Auto release mode for destination buffer.
+ */
+ Buffer clone(Target target = ARRAY_BUFFER, bool autoRelease = false) const;
+
+ /** @brief Binds OpenGL buffer to the specified buffer binding point.
+
+ @param target Binding point. See cv::ogl::Buffer::Target .
+ */
+ void bind(Target target) const;
+
+ /** @brief Unbind any buffers from the specified binding point.
+
+ @param target Binding point. See cv::ogl::Buffer::Target .
+ */
+ static void unbind(Target target);
+
+ /** @brief Maps OpenGL buffer to host memory.
+
+ mapHost maps to the client's address space the entire data store of the buffer object. The data can
+ then be directly read and/or written relative to the returned pointer, depending on the specified
+ access policy.
+
+ A mapped data store must be unmapped with ogl::Buffer::unmapHost before its buffer object is used.
+
+ This operation can lead to memory transfers between host and device.
+
+ Only one buffer object can be mapped at a time.
+ @param access Access policy, indicating whether it will be possible to read from, write to, or both
+ read from and write to the buffer object's mapped data store. The symbolic constant must be
+ ogl::Buffer::READ_ONLY , ogl::Buffer::WRITE_ONLY or ogl::Buffer::READ_WRITE .
+ */
+ Mat mapHost(Access access);
+
+ /** @brief Unmaps OpenGL buffer.
+ */
+ void unmapHost();
+
+ //! map to device memory (blocking)
+ cuda::GpuMat mapDevice();
+ void unmapDevice();
+
+ /** @brief Maps OpenGL buffer to CUDA device memory.
+
+ This operatation doesn't copy data. Several buffer objects can be mapped to CUDA memory at a time.
+
+ A mapped data store must be unmapped with ogl::Buffer::unmapDevice before its buffer object is used.
+ */
+ cuda::GpuMat mapDevice(cuda::Stream& stream);
+
+ /** @brief Unmaps OpenGL buffer.
+ */
+ void unmapDevice(cuda::Stream& stream);
+
+ int rows() const;
+ int cols() const;
+ Size size() const;
+ bool empty() const;
+
+ int type() const;
+ int depth() const;
+ int channels() const;
+ int elemSize() const;
+ int elemSize1() const;
+
+ //! get OpenGL opject id
+ unsigned int bufId() const;
+
+ class Impl;
+
+private:
+ Ptr<Impl> impl_;
+ int rows_;
+ int cols_;
+ int type_;
+};
+
+/** @brief Smart pointer for OpenGL 2D texture memory with reference counting.
+ */
+class CV_EXPORTS Texture2D
+{
+public:
+ /** @brief An Image Format describes the way that the images in Textures store their data.
+ */
+ enum Format
+ {
+ NONE = 0,
+ DEPTH_COMPONENT = 0x1902, //!< Depth
+ RGB = 0x1907, //!< Red, Green, Blue
+ RGBA = 0x1908 //!< Red, Green, Blue, Alpha
+ };
+
+ /** @brief The constructors.
+
+ Creates empty ogl::Texture2D object, allocates memory for ogl::Texture2D object or copies from
+ host/device memory.
+ */
+ Texture2D();
+
+ /** @overload */
+ Texture2D(int arows, int acols, Format aformat, unsigned int atexId, bool autoRelease = false);
+
+ /** @overload */
+ Texture2D(Size asize, Format aformat, unsigned int atexId, bool autoRelease = false);
+
+ /** @overload
+ @param arows Number of rows.
+ @param acols Number of columns.
+ @param aformat Image format. See cv::ogl::Texture2D::Format .
+ @param autoRelease Auto release mode (if true, release will be called in object's destructor).
+ */
+ Texture2D(int arows, int acols, Format aformat, bool autoRelease = false);
+
+ /** @overload
+ @param asize 2D array size.
+ @param aformat Image format. See cv::ogl::Texture2D::Format .
+ @param autoRelease Auto release mode (if true, release will be called in object's destructor).
+ */
+ Texture2D(Size asize, Format aformat, bool autoRelease = false);
+
+ /** @overload
+ @param arr Input array (host or device memory, it can be Mat , cuda::GpuMat or ogl::Buffer ).
+ @param autoRelease Auto release mode (if true, release will be called in object's destructor).
+ */
+ explicit Texture2D(InputArray arr, bool autoRelease = false);
+
+ /** @brief Allocates memory for ogl::Texture2D object.
+
+ @param arows Number of rows.
+ @param acols Number of columns.
+ @param aformat Image format. See cv::ogl::Texture2D::Format .
+ @param autoRelease Auto release mode (if true, release will be called in object's destructor).
+ */
+ void create(int arows, int acols, Format aformat, bool autoRelease = false);
+ /** @overload
+ @param asize 2D array size.
+ @param aformat Image format. See cv::ogl::Texture2D::Format .
+ @param autoRelease Auto release mode (if true, release will be called in object's destructor).
+ */
+ void create(Size asize, Format aformat, bool autoRelease = false);
+
+ /** @brief Decrements the reference counter and destroys the texture object if needed.
+
+ The function will call setAutoRelease(true) .
+ */
+ void release();
+
+ /** @brief Sets auto release mode.
+
+ @param flag Auto release mode (if true, release will be called in object's destructor).
+
+ The lifetime of the OpenGL object is tied to the lifetime of the context. If OpenGL context was
+ bound to a window it could be released at any time (user can close a window). If object's destructor
+ is called after destruction of the context it will cause an error. Thus ogl::Texture2D doesn't
+ destroy OpenGL object in destructor by default (all OpenGL resources will be released with OpenGL
+ context). This function can force ogl::Texture2D destructor to destroy OpenGL object.
+ */
+ void setAutoRelease(bool flag);
+
+ /** @brief Copies from host/device memory to OpenGL texture.
+
+ @param arr Input array (host or device memory, it can be Mat , cuda::GpuMat or ogl::Buffer ).
+ @param autoRelease Auto release mode (if true, release will be called in object's destructor).
+ */
+ void copyFrom(InputArray arr, bool autoRelease = false);
+
+ /** @brief Copies from OpenGL texture to host/device memory or another OpenGL texture object.
+
+ @param arr Destination array (host or device memory, can be Mat , cuda::GpuMat , ogl::Buffer or
+ ogl::Texture2D ).
+ @param ddepth Destination depth.
+ @param autoRelease Auto release mode for destination buffer (if arr is OpenGL buffer or texture).
+ */
+ void copyTo(OutputArray arr, int ddepth = CV_32F, bool autoRelease = false) const;
+
+ /** @brief Binds texture to current active texture unit for GL_TEXTURE_2D target.
+ */
+ void bind() const;
+
+ int rows() const;
+ int cols() const;
+ Size size() const;
+ bool empty() const;
+
+ Format format() const;
+
+ //! get OpenGL opject id
+ unsigned int texId() const;
+
+ class Impl;
+
+private:
+ Ptr<Impl> impl_;
+ int rows_;
+ int cols_;
+ Format format_;
+};
+
+/** @brief Wrapper for OpenGL Client-Side Vertex arrays.
+
+ogl::Arrays stores vertex data in ogl::Buffer objects.
+ */
+class CV_EXPORTS Arrays
+{
+public:
+ /** @brief Default constructor
+ */
+ Arrays();
+
+ /** @brief Sets an array of vertex coordinates.
+ @param vertex array with vertex coordinates, can be both host and device memory.
+ */
+ void setVertexArray(InputArray vertex);
+
+ /** @brief Resets vertex coordinates.
+ */
+ void resetVertexArray();
+
+ /** @brief Sets an array of vertex colors.
+ @param color array with vertex colors, can be both host and device memory.
+ */
+ void setColorArray(InputArray color);
+
+ /** @brief Resets vertex colors.
+ */
+ void resetColorArray();
+
+ /** @brief Sets an array of vertex normals.
+ @param normal array with vertex normals, can be both host and device memory.
+ */
+ void setNormalArray(InputArray normal);
+
+ /** @brief Resets vertex normals.
+ */
+ void resetNormalArray();
+
+ /** @brief Sets an array of vertex texture coordinates.
+ @param texCoord array with vertex texture coordinates, can be both host and device memory.
+ */
+ void setTexCoordArray(InputArray texCoord);
+
+ /** @brief Resets vertex texture coordinates.
+ */
+ void resetTexCoordArray();
+
+ /** @brief Releases all inner buffers.
+ */
+ void release();
+
+ /** @brief Sets auto release mode all inner buffers.
+ @param flag Auto release mode.
+ */
+ void setAutoRelease(bool flag);
+
+ /** @brief Binds all vertex arrays.
+ */
+ void bind() const;
+
+ /** @brief Returns the vertex count.
+ */
+ int size() const;
+ bool empty() const;
+
+private:
+ int size_;
+ Buffer vertex_;
+ Buffer color_;
+ Buffer normal_;
+ Buffer texCoord_;
+};
+
+/////////////////// Render Functions ///////////////////
+
+//! render mode
+enum RenderModes {
+ POINTS = 0x0000,
+ LINES = 0x0001,
+ LINE_LOOP = 0x0002,
+ LINE_STRIP = 0x0003,
+ TRIANGLES = 0x0004,
+ TRIANGLE_STRIP = 0x0005,
+ TRIANGLE_FAN = 0x0006,
+ QUADS = 0x0007,
+ QUAD_STRIP = 0x0008,
+ POLYGON = 0x0009
+};
+
+/** @brief Render OpenGL texture or primitives.
+@param tex Texture to draw.
+@param wndRect Region of window, where to draw a texture (normalized coordinates).
+@param texRect Region of texture to draw (normalized coordinates).
+ */
+CV_EXPORTS void render(const Texture2D& tex,
+ Rect_<double> wndRect = Rect_<double>(0.0, 0.0, 1.0, 1.0),
+ Rect_<double> texRect = Rect_<double>(0.0, 0.0, 1.0, 1.0));
+
+/** @overload
+@param arr Array of privitives vertices.
+@param mode Render mode. One of cv::ogl::RenderModes
+@param color Color for all vertices. Will be used if arr doesn't contain color array.
+*/
+CV_EXPORTS void render(const Arrays& arr, int mode = POINTS, Scalar color = Scalar::all(255));
+
+/** @overload
+@param arr Array of privitives vertices.
+@param indices Array of vertices indices (host or device memory).
+@param mode Render mode. One of cv::ogl::RenderModes
+@param color Color for all vertices. Will be used if arr doesn't contain color array.
+*/
+CV_EXPORTS void render(const Arrays& arr, InputArray indices, int mode = POINTS, Scalar color = Scalar::all(255));
+
+/////////////////// CL-GL Interoperability Functions ///////////////////
+
+namespace ocl {
+using namespace cv::ocl;
+
+// TODO static functions in the Context class
+/** @brief Creates OpenCL context from GL.
+@return Returns reference to OpenCL Context
+ */
+CV_EXPORTS Context& initializeContextFromGL();
+
+} // namespace cv::ogl::ocl
+
+/** @brief Converts InputArray to Texture2D object.
+@param src - source InputArray.
+@param texture - destination Texture2D object.
+ */
+CV_EXPORTS void convertToGLTexture2D(InputArray src, Texture2D& texture);
+
+/** @brief Converts Texture2D object to OutputArray.
+@param texture - source Texture2D object.
+@param dst - destination OutputArray.
+ */
+CV_EXPORTS void convertFromGLTexture2D(const Texture2D& texture, OutputArray dst);
+
+/** @brief Maps Buffer object to process on CL side (convert to UMat).
+
+Function creates CL buffer from GL one, and then constructs UMat that can be used
+to process buffer data with OpenCV functions. Note that in current implementation
+UMat constructed this way doesn't own corresponding GL buffer object, so it is
+the user responsibility to close down CL/GL buffers relationships by explicitly
+calling unmapGLBuffer() function.
+@param buffer - source Buffer object.
+@param accessFlags - data access flags (ACCESS_READ|ACCESS_WRITE).
+@return Returns UMat object
+ */
+CV_EXPORTS UMat mapGLBuffer(const Buffer& buffer, int accessFlags = ACCESS_READ|ACCESS_WRITE);
+
+/** @brief Unmaps Buffer object (releases UMat, previously mapped from Buffer).
+
+Function must be called explicitly by the user for each UMat previously constructed
+by the call to mapGLBuffer() function.
+@param u - source UMat, created by mapGLBuffer().
+ */
+CV_EXPORTS void unmapGLBuffer(UMat& u);
+
+}} // namespace cv::ogl
+
+namespace cv { namespace cuda {
+
+//! @addtogroup cuda
+//! @{
+
+/** @brief Sets a CUDA device and initializes it for the current thread with OpenGL interoperability.
+
+This function should be explicitly called after OpenGL context creation and before any CUDA calls.
+@param device System index of a CUDA device starting with 0.
+@ingroup core_opengl
+ */
+CV_EXPORTS void setGlDevice(int device = 0);
+
+//! @}
+
+}}
+
+//! @cond IGNORED
+
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+
+inline
+cv::ogl::Buffer::Buffer(int arows, int acols, int atype, Target target, bool autoRelease) : rows_(0), cols_(0), type_(0)
+{
+ create(arows, acols, atype, target, autoRelease);
+}
+
+inline
+cv::ogl::Buffer::Buffer(Size asize, int atype, Target target, bool autoRelease) : rows_(0), cols_(0), type_(0)
+{
+ create(asize, atype, target, autoRelease);
+}
+
+inline
+void cv::ogl::Buffer::create(Size asize, int atype, Target target, bool autoRelease)
+{
+ create(asize.height, asize.width, atype, target, autoRelease);
+}
+
+inline
+int cv::ogl::Buffer::rows() const
+{
+ return rows_;
+}
+
+inline
+int cv::ogl::Buffer::cols() const
+{
+ return cols_;
+}
+
+inline
+cv::Size cv::ogl::Buffer::size() const
+{
+ return Size(cols_, rows_);
+}
+
+inline
+bool cv::ogl::Buffer::empty() const
+{
+ return rows_ == 0 || cols_ == 0;
+}
+
+inline
+int cv::ogl::Buffer::type() const
+{
+ return type_;
+}
+
+inline
+int cv::ogl::Buffer::depth() const
+{
+ return CV_MAT_DEPTH(type_);
+}
+
+inline
+int cv::ogl::Buffer::channels() const
+{
+ return CV_MAT_CN(type_);
+}
+
+inline
+int cv::ogl::Buffer::elemSize() const
+{
+ return CV_ELEM_SIZE(type_);
+}
+
+inline
+int cv::ogl::Buffer::elemSize1() const
+{
+ return CV_ELEM_SIZE1(type_);
+}
+
+///////
+
+inline
+cv::ogl::Texture2D::Texture2D(int arows, int acols, Format aformat, bool autoRelease) : rows_(0), cols_(0), format_(NONE)
+{
+ create(arows, acols, aformat, autoRelease);
+}
+
+inline
+cv::ogl::Texture2D::Texture2D(Size asize, Format aformat, bool autoRelease) : rows_(0), cols_(0), format_(NONE)
+{
+ create(asize, aformat, autoRelease);
+}
+
+inline
+void cv::ogl::Texture2D::create(Size asize, Format aformat, bool autoRelease)
+{
+ create(asize.height, asize.width, aformat, autoRelease);
+}
+
+inline
+int cv::ogl::Texture2D::rows() const
+{
+ return rows_;
+}
+
+inline
+int cv::ogl::Texture2D::cols() const
+{
+ return cols_;
+}
+
+inline
+cv::Size cv::ogl::Texture2D::size() const
+{
+ return Size(cols_, rows_);
+}
+
+inline
+bool cv::ogl::Texture2D::empty() const
+{
+ return rows_ == 0 || cols_ == 0;
+}
+
+inline
+cv::ogl::Texture2D::Format cv::ogl::Texture2D::format() const
+{
+ return format_;
+}
+
+///////
+
+inline
+cv::ogl::Arrays::Arrays() : size_(0)
+{
+}
+
+inline
+int cv::ogl::Arrays::size() const
+{
+ return size_;
+}
+
+inline
+bool cv::ogl::Arrays::empty() const
+{
+ return size_ == 0;
+}
+
+//! @endcond
+
+#endif /* OPENCV_CORE_OPENGL_HPP */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/core/operations.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,530 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
+// Copyright (C) 2015, Itseez Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_CORE_OPERATIONS_HPP
+#define OPENCV_CORE_OPERATIONS_HPP
+
+#ifndef __cplusplus
+# error operations.hpp header must be compiled as C++
+#endif
+
+#include <cstdio>
+
+//! @cond IGNORED
+
+namespace cv
+{
+
+////////////////////////////// Matx methods depending on core API /////////////////////////////
+
+namespace internal
+{
+
+template<typename _Tp, int m> struct Matx_FastInvOp
+{
+ bool operator()(const Matx<_Tp, m, m>& a, Matx<_Tp, m, m>& b, int method) const
+ {
+ Matx<_Tp, m, m> temp = a;
+
+ // assume that b is all 0's on input => make it a unity matrix
+ for( int i = 0; i < m; i++ )
+ b(i, i) = (_Tp)1;
+
+ if( method == DECOMP_CHOLESKY )
+ return Cholesky(temp.val, m*sizeof(_Tp), m, b.val, m*sizeof(_Tp), m);
+
+ return LU(temp.val, m*sizeof(_Tp), m, b.val, m*sizeof(_Tp), m) != 0;
+ }
+};
+
+template<typename _Tp> struct Matx_FastInvOp<_Tp, 2>
+{
+ bool operator()(const Matx<_Tp, 2, 2>& a, Matx<_Tp, 2, 2>& b, int) const
+ {
+ _Tp d = determinant(a);
+ if( d == 0 )
+ return false;
+ d = 1/d;
+ b(1,1) = a(0,0)*d;
+ b(0,0) = a(1,1)*d;
+ b(0,1) = -a(0,1)*d;
+ b(1,0) = -a(1,0)*d;
+ return true;
+ }
+};
+
+template<typename _Tp> struct Matx_FastInvOp<_Tp, 3>
+{
+ bool operator()(const Matx<_Tp, 3, 3>& a, Matx<_Tp, 3, 3>& b, int) const
+ {
+ _Tp d = (_Tp)determinant(a);
+ if( d == 0 )
+ return false;
+ d = 1/d;
+ b(0,0) = (a(1,1) * a(2,2) - a(1,2) * a(2,1)) * d;
+ b(0,1) = (a(0,2) * a(2,1) - a(0,1) * a(2,2)) * d;
+ b(0,2) = (a(0,1) * a(1,2) - a(0,2) * a(1,1)) * d;
+
+ b(1,0) = (a(1,2) * a(2,0) - a(1,0) * a(2,2)) * d;
+ b(1,1) = (a(0,0) * a(2,2) - a(0,2) * a(2,0)) * d;
+ b(1,2) = (a(0,2) * a(1,0) - a(0,0) * a(1,2)) * d;
+
+ b(2,0) = (a(1,0) * a(2,1) - a(1,1) * a(2,0)) * d;
+ b(2,1) = (a(0,1) * a(2,0) - a(0,0) * a(2,1)) * d;
+ b(2,2) = (a(0,0) * a(1,1) - a(0,1) * a(1,0)) * d;
+ return true;
+ }
+};
+
+
+template<typename _Tp, int m, int n> struct Matx_FastSolveOp
+{
+ bool operator()(const Matx<_Tp, m, m>& a, const Matx<_Tp, m, n>& b,
+ Matx<_Tp, m, n>& x, int method) const
+ {
+ Matx<_Tp, m, m> temp = a;
+ x = b;
+ if( method == DECOMP_CHOLESKY )
+ return Cholesky(temp.val, m*sizeof(_Tp), m, x.val, n*sizeof(_Tp), n);
+
+ return LU(temp.val, m*sizeof(_Tp), m, x.val, n*sizeof(_Tp), n) != 0;
+ }
+};
+
+template<typename _Tp> struct Matx_FastSolveOp<_Tp, 2, 1>
+{
+ bool operator()(const Matx<_Tp, 2, 2>& a, const Matx<_Tp, 2, 1>& b,
+ Matx<_Tp, 2, 1>& x, int) const
+ {
+ _Tp d = determinant(a);
+ if( d == 0 )
+ return false;
+ d = 1/d;
+ x(0) = (b(0)*a(1,1) - b(1)*a(0,1))*d;
+ x(1) = (b(1)*a(0,0) - b(0)*a(1,0))*d;
+ return true;
+ }
+};
+
+template<typename _Tp> struct Matx_FastSolveOp<_Tp, 3, 1>
+{
+ bool operator()(const Matx<_Tp, 3, 3>& a, const Matx<_Tp, 3, 1>& b,
+ Matx<_Tp, 3, 1>& x, int) const
+ {
+ _Tp d = (_Tp)determinant(a);
+ if( d == 0 )
+ return false;
+ d = 1/d;
+ x(0) = d*(b(0)*(a(1,1)*a(2,2) - a(1,2)*a(2,1)) -
+ a(0,1)*(b(1)*a(2,2) - a(1,2)*b(2)) +
+ a(0,2)*(b(1)*a(2,1) - a(1,1)*b(2)));
+
+ x(1) = d*(a(0,0)*(b(1)*a(2,2) - a(1,2)*b(2)) -
+ b(0)*(a(1,0)*a(2,2) - a(1,2)*a(2,0)) +
+ a(0,2)*(a(1,0)*b(2) - b(1)*a(2,0)));
+
+ x(2) = d*(a(0,0)*(a(1,1)*b(2) - b(1)*a(2,1)) -
+ a(0,1)*(a(1,0)*b(2) - b(1)*a(2,0)) +
+ b(0)*(a(1,0)*a(2,1) - a(1,1)*a(2,0)));
+ return true;
+ }
+};
+
+} // internal
+
+template<typename _Tp, int m, int n> inline
+Matx<_Tp,m,n> Matx<_Tp,m,n>::randu(_Tp a, _Tp b)
+{
+ Matx<_Tp,m,n> M;
+ cv::randu(M, Scalar(a), Scalar(b));
+ return M;
+}
+
+template<typename _Tp, int m, int n> inline
+Matx<_Tp,m,n> Matx<_Tp,m,n>::randn(_Tp a, _Tp b)
+{
+ Matx<_Tp,m,n> M;
+ cv::randn(M, Scalar(a), Scalar(b));
+ return M;
+}
+
+template<typename _Tp, int m, int n> inline
+Matx<_Tp, n, m> Matx<_Tp, m, n>::inv(int method, bool *p_is_ok /*= NULL*/) const
+{
+ Matx<_Tp, n, m> b;
+ bool ok;
+ if( method == DECOMP_LU || method == DECOMP_CHOLESKY )
+ ok = cv::internal::Matx_FastInvOp<_Tp, m>()(*this, b, method);
+ else
+ {
+ Mat A(*this, false), B(b, false);
+ ok = (invert(A, B, method) != 0);
+ }
+ if( NULL != p_is_ok ) { *p_is_ok = ok; }
+ return ok ? b : Matx<_Tp, n, m>::zeros();
+}
+
+template<typename _Tp, int m, int n> template<int l> inline
+Matx<_Tp, n, l> Matx<_Tp, m, n>::solve(const Matx<_Tp, m, l>& rhs, int method) const
+{
+ Matx<_Tp, n, l> x;
+ bool ok;
+ if( method == DECOMP_LU || method == DECOMP_CHOLESKY )
+ ok = cv::internal::Matx_FastSolveOp<_Tp, m, l>()(*this, rhs, x, method);
+ else
+ {
+ Mat A(*this, false), B(rhs, false), X(x, false);
+ ok = cv::solve(A, B, X, method);
+ }
+
+ return ok ? x : Matx<_Tp, n, l>::zeros();
+}
+
+
+
+////////////////////////// Augmenting algebraic & logical operations //////////////////////////
+
+#define CV_MAT_AUG_OPERATOR1(op, cvop, A, B) \
+ static inline A& operator op (A& a, const B& b) { cvop; return a; }
+
+#define CV_MAT_AUG_OPERATOR(op, cvop, A, B) \
+ CV_MAT_AUG_OPERATOR1(op, cvop, A, B) \
+ CV_MAT_AUG_OPERATOR1(op, cvop, const A, B)
+
+#define CV_MAT_AUG_OPERATOR_T(op, cvop, A, B) \
+ template<typename _Tp> CV_MAT_AUG_OPERATOR1(op, cvop, A, B) \
+ template<typename _Tp> CV_MAT_AUG_OPERATOR1(op, cvop, const A, B)
+
+CV_MAT_AUG_OPERATOR (+=, cv::add(a,b,a), Mat, Mat)
+CV_MAT_AUG_OPERATOR (+=, cv::add(a,b,a), Mat, Scalar)
+CV_MAT_AUG_OPERATOR_T(+=, cv::add(a,b,a), Mat_<_Tp>, Mat)
+CV_MAT_AUG_OPERATOR_T(+=, cv::add(a,b,a), Mat_<_Tp>, Scalar)
+CV_MAT_AUG_OPERATOR_T(+=, cv::add(a,b,a), Mat_<_Tp>, Mat_<_Tp>)
+
+CV_MAT_AUG_OPERATOR (-=, cv::subtract(a,b,a), Mat, Mat)
+CV_MAT_AUG_OPERATOR (-=, cv::subtract(a,b,a), Mat, Scalar)
+CV_MAT_AUG_OPERATOR_T(-=, cv::subtract(a,b,a), Mat_<_Tp>, Mat)
+CV_MAT_AUG_OPERATOR_T(-=, cv::subtract(a,b,a), Mat_<_Tp>, Scalar)
+CV_MAT_AUG_OPERATOR_T(-=, cv::subtract(a,b,a), Mat_<_Tp>, Mat_<_Tp>)
+
+CV_MAT_AUG_OPERATOR (*=, cv::gemm(a, b, 1, Mat(), 0, a, 0), Mat, Mat)
+CV_MAT_AUG_OPERATOR_T(*=, cv::gemm(a, b, 1, Mat(), 0, a, 0), Mat_<_Tp>, Mat)
+CV_MAT_AUG_OPERATOR_T(*=, cv::gemm(a, b, 1, Mat(), 0, a, 0), Mat_<_Tp>, Mat_<_Tp>)
+CV_MAT_AUG_OPERATOR (*=, a.convertTo(a, -1, b), Mat, double)
+CV_MAT_AUG_OPERATOR_T(*=, a.convertTo(a, -1, b), Mat_<_Tp>, double)
+
+CV_MAT_AUG_OPERATOR (/=, cv::divide(a,b,a), Mat, Mat)
+CV_MAT_AUG_OPERATOR_T(/=, cv::divide(a,b,a), Mat_<_Tp>, Mat)
+CV_MAT_AUG_OPERATOR_T(/=, cv::divide(a,b,a), Mat_<_Tp>, Mat_<_Tp>)
+CV_MAT_AUG_OPERATOR (/=, a.convertTo((Mat&)a, -1, 1./b), Mat, double)
+CV_MAT_AUG_OPERATOR_T(/=, a.convertTo((Mat&)a, -1, 1./b), Mat_<_Tp>, double)
+
+CV_MAT_AUG_OPERATOR (&=, cv::bitwise_and(a,b,a), Mat, Mat)
+CV_MAT_AUG_OPERATOR (&=, cv::bitwise_and(a,b,a), Mat, Scalar)
+CV_MAT_AUG_OPERATOR_T(&=, cv::bitwise_and(a,b,a), Mat_<_Tp>, Mat)
+CV_MAT_AUG_OPERATOR_T(&=, cv::bitwise_and(a,b,a), Mat_<_Tp>, Scalar)
+CV_MAT_AUG_OPERATOR_T(&=, cv::bitwise_and(a,b,a), Mat_<_Tp>, Mat_<_Tp>)
+
+CV_MAT_AUG_OPERATOR (|=, cv::bitwise_or(a,b,a), Mat, Mat)
+CV_MAT_AUG_OPERATOR (|=, cv::bitwise_or(a,b,a), Mat, Scalar)
+CV_MAT_AUG_OPERATOR_T(|=, cv::bitwise_or(a,b,a), Mat_<_Tp>, Mat)
+CV_MAT_AUG_OPERATOR_T(|=, cv::bitwise_or(a,b,a), Mat_<_Tp>, Scalar)
+CV_MAT_AUG_OPERATOR_T(|=, cv::bitwise_or(a,b,a), Mat_<_Tp>, Mat_<_Tp>)
+
+CV_MAT_AUG_OPERATOR (^=, cv::bitwise_xor(a,b,a), Mat, Mat)
+CV_MAT_AUG_OPERATOR (^=, cv::bitwise_xor(a,b,a), Mat, Scalar)
+CV_MAT_AUG_OPERATOR_T(^=, cv::bitwise_xor(a,b,a), Mat_<_Tp>, Mat)
+CV_MAT_AUG_OPERATOR_T(^=, cv::bitwise_xor(a,b,a), Mat_<_Tp>, Scalar)
+CV_MAT_AUG_OPERATOR_T(^=, cv::bitwise_xor(a,b,a), Mat_<_Tp>, Mat_<_Tp>)
+
+#undef CV_MAT_AUG_OPERATOR_T
+#undef CV_MAT_AUG_OPERATOR
+#undef CV_MAT_AUG_OPERATOR1
+
+
+
+///////////////////////////////////////////// SVD /////////////////////////////////////////////
+
+inline SVD::SVD() {}
+inline SVD::SVD( InputArray m, int flags ) { operator ()(m, flags); }
+inline void SVD::solveZ( InputArray m, OutputArray _dst )
+{
+ Mat mtx = m.getMat();
+ SVD svd(mtx, (mtx.rows >= mtx.cols ? 0 : SVD::FULL_UV));
+ _dst.create(svd.vt.cols, 1, svd.vt.type());
+ Mat dst = _dst.getMat();
+ svd.vt.row(svd.vt.rows-1).reshape(1,svd.vt.cols).copyTo(dst);
+}
+
+template<typename _Tp, int m, int n, int nm> inline void
+ SVD::compute( const Matx<_Tp, m, n>& a, Matx<_Tp, nm, 1>& w, Matx<_Tp, m, nm>& u, Matx<_Tp, n, nm>& vt )
+{
+ CV_StaticAssert( nm == MIN(m, n), "Invalid size of output vector.");
+ Mat _a(a, false), _u(u, false), _w(w, false), _vt(vt, false);
+ SVD::compute(_a, _w, _u, _vt);
+ CV_Assert(_w.data == (uchar*)&w.val[0] && _u.data == (uchar*)&u.val[0] && _vt.data == (uchar*)&vt.val[0]);
+}
+
+template<typename _Tp, int m, int n, int nm> inline void
+SVD::compute( const Matx<_Tp, m, n>& a, Matx<_Tp, nm, 1>& w )
+{
+ CV_StaticAssert( nm == MIN(m, n), "Invalid size of output vector.");
+ Mat _a(a, false), _w(w, false);
+ SVD::compute(_a, _w);
+ CV_Assert(_w.data == (uchar*)&w.val[0]);
+}
+
+template<typename _Tp, int m, int n, int nm, int nb> inline void
+SVD::backSubst( const Matx<_Tp, nm, 1>& w, const Matx<_Tp, m, nm>& u,
+ const Matx<_Tp, n, nm>& vt, const Matx<_Tp, m, nb>& rhs,
+ Matx<_Tp, n, nb>& dst )
+{
+ CV_StaticAssert( nm == MIN(m, n), "Invalid size of output vector.");
+ Mat _u(u, false), _w(w, false), _vt(vt, false), _rhs(rhs, false), _dst(dst, false);
+ SVD::backSubst(_w, _u, _vt, _rhs, _dst);
+ CV_Assert(_dst.data == (uchar*)&dst.val[0]);
+}
+
+
+
+/////////////////////////////////// Multiply-with-Carry RNG ///////////////////////////////////
+
+inline RNG::RNG() { state = 0xffffffff; }
+inline RNG::RNG(uint64 _state) { state = _state ? _state : 0xffffffff; }
+
+inline RNG::operator uchar() { return (uchar)next(); }
+inline RNG::operator schar() { return (schar)next(); }
+inline RNG::operator ushort() { return (ushort)next(); }
+inline RNG::operator short() { return (short)next(); }
+inline RNG::operator int() { return (int)next(); }
+inline RNG::operator unsigned() { return next(); }
+inline RNG::operator float() { return next()*2.3283064365386962890625e-10f; }
+inline RNG::operator double() { unsigned t = next(); return (((uint64)t << 32) | next()) * 5.4210108624275221700372640043497e-20; }
+
+inline unsigned RNG::operator ()(unsigned N) { return (unsigned)uniform(0,N); }
+inline unsigned RNG::operator ()() { return next(); }
+
+inline int RNG::uniform(int a, int b) { return a == b ? a : (int)(next() % (b - a) + a); }
+inline float RNG::uniform(float a, float b) { return ((float)*this)*(b - a) + a; }
+inline double RNG::uniform(double a, double b) { return ((double)*this)*(b - a) + a; }
+
+inline unsigned RNG::next()
+{
+ state = (uint64)(unsigned)state* /*CV_RNG_COEFF*/ 4164903690U + (unsigned)(state >> 32);
+ return (unsigned)state;
+}
+
+//! returns the next unifomly-distributed random number of the specified type
+template<typename _Tp> static inline _Tp randu()
+{
+ return (_Tp)theRNG();
+}
+
+///////////////////////////////// Formatted string generation /////////////////////////////////
+
+CV_EXPORTS String format( const char* fmt, ... );
+
+///////////////////////////////// Formatted output of cv::Mat /////////////////////////////////
+
+static inline
+Ptr<Formatted> format(InputArray mtx, int fmt)
+{
+ return Formatter::get(fmt)->format(mtx.getMat());
+}
+
+static inline
+int print(Ptr<Formatted> fmtd, FILE* stream = stdout)
+{
+ int written = 0;
+ fmtd->reset();
+ for(const char* str = fmtd->next(); str; str = fmtd->next())
+ written += fputs(str, stream);
+
+ return written;
+}
+
+static inline
+int print(const Mat& mtx, FILE* stream = stdout)
+{
+ return print(Formatter::get()->format(mtx), stream);
+}
+
+static inline
+int print(const UMat& mtx, FILE* stream = stdout)
+{
+ return print(Formatter::get()->format(mtx.getMat(ACCESS_READ)), stream);
+}
+
+template<typename _Tp> static inline
+int print(const std::vector<Point_<_Tp> >& vec, FILE* stream = stdout)
+{
+ return print(Formatter::get()->format(Mat(vec)), stream);
+}
+
+template<typename _Tp> static inline
+int print(const std::vector<Point3_<_Tp> >& vec, FILE* stream = stdout)
+{
+ return print(Formatter::get()->format(Mat(vec)), stream);
+}
+
+template<typename _Tp, int m, int n> static inline
+int print(const Matx<_Tp, m, n>& matx, FILE* stream = stdout)
+{
+ return print(Formatter::get()->format(cv::Mat(matx)), stream);
+}
+
+//! @endcond
+
+/****************************************************************************************\
+* Auxiliary algorithms *
+\****************************************************************************************/
+
+/** @brief Splits an element set into equivalency classes.
+
+The generic function partition implements an \f$O(N^2)\f$ algorithm for splitting a set of \f$N\f$ elements
+into one or more equivalency classes, as described in
+<http://en.wikipedia.org/wiki/Disjoint-set_data_structure> . The function returns the number of
+equivalency classes.
+@param _vec Set of elements stored as a vector.
+@param labels Output vector of labels. It contains as many elements as vec. Each label labels[i] is
+a 0-based cluster index of `vec[i]`.
+@param predicate Equivalence predicate (pointer to a boolean function of two arguments or an
+instance of the class that has the method bool operator()(const _Tp& a, const _Tp& b) ). The
+predicate returns true when the elements are certainly in the same class, and returns false if they
+may or may not be in the same class.
+@ingroup core_cluster
+*/
+template<typename _Tp, class _EqPredicate> int
+partition( const std::vector<_Tp>& _vec, std::vector<int>& labels,
+ _EqPredicate predicate=_EqPredicate())
+{
+ int i, j, N = (int)_vec.size();
+ const _Tp* vec = &_vec[0];
+
+ const int PARENT=0;
+ const int RANK=1;
+
+ std::vector<int> _nodes(N*2);
+ int (*nodes)[2] = (int(*)[2])&_nodes[0];
+
+ // The first O(N) pass: create N single-vertex trees
+ for(i = 0; i < N; i++)
+ {
+ nodes[i][PARENT]=-1;
+ nodes[i][RANK] = 0;
+ }
+
+ // The main O(N^2) pass: merge connected components
+ for( i = 0; i < N; i++ )
+ {
+ int root = i;
+
+ // find root
+ while( nodes[root][PARENT] >= 0 )
+ root = nodes[root][PARENT];
+
+ for( j = 0; j < N; j++ )
+ {
+ if( i == j || !predicate(vec[i], vec[j]))
+ continue;
+ int root2 = j;
+
+ while( nodes[root2][PARENT] >= 0 )
+ root2 = nodes[root2][PARENT];
+
+ if( root2 != root )
+ {
+ // unite both trees
+ int rank = nodes[root][RANK], rank2 = nodes[root2][RANK];
+ if( rank > rank2 )
+ nodes[root2][PARENT] = root;
+ else
+ {
+ nodes[root][PARENT] = root2;
+ nodes[root2][RANK] += rank == rank2;
+ root = root2;
+ }
+ CV_Assert( nodes[root][PARENT] < 0 );
+
+ int k = j, parent;
+
+ // compress the path from node2 to root
+ while( (parent = nodes[k][PARENT]) >= 0 )
+ {
+ nodes[k][PARENT] = root;
+ k = parent;
+ }
+
+ // compress the path from node to root
+ k = i;
+ while( (parent = nodes[k][PARENT]) >= 0 )
+ {
+ nodes[k][PARENT] = root;
+ k = parent;
+ }
+ }
+ }
+ }
+
+ // Final O(N) pass: enumerate classes
+ labels.resize(N);
+ int nclasses = 0;
+
+ for( i = 0; i < N; i++ )
+ {
+ int root = i;
+ while( nodes[root][PARENT] >= 0 )
+ root = nodes[root][PARENT];
+ // re-use the rank as the class label
+ if( nodes[root][RANK] >= 0 )
+ nodes[root][RANK] = ~nclasses++;
+ labels[i] = ~nodes[root][RANK];
+ }
+
+ return nclasses;
+}
+
+} // cv
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/core/optim.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,302 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the OpenCV Foundation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_OPTIM_HPP
+#define OPENCV_OPTIM_HPP
+
+#include "opencv2/core.hpp"
+
+namespace cv
+{
+
+/** @addtogroup core_optim
+The algorithms in this section minimize or maximize function value within specified constraints or
+without any constraints.
+@{
+*/
+
+/** @brief Basic interface for all solvers
+ */
+class CV_EXPORTS MinProblemSolver : public Algorithm
+{
+public:
+ /** @brief Represents function being optimized
+ */
+ class CV_EXPORTS Function
+ {
+ public:
+ virtual ~Function() {}
+ virtual int getDims() const = 0;
+ virtual double getGradientEps() const;
+ virtual double calc(const double* x) const = 0;
+ virtual void getGradient(const double* x,double* grad);
+ };
+
+ /** @brief Getter for the optimized function.
+
+ The optimized function is represented by Function interface, which requires derivatives to
+ implement the sole method calc(double*) to evaluate the function.
+
+ @return Smart-pointer to an object that implements Function interface - it represents the
+ function that is being optimized. It can be empty, if no function was given so far.
+ */
+ virtual Ptr<Function> getFunction() const = 0;
+
+ /** @brief Setter for the optimized function.
+
+ *It should be called at least once before the call to* minimize(), as default value is not usable.
+
+ @param f The new function to optimize.
+ */
+ virtual void setFunction(const Ptr<Function>& f) = 0;
+
+ /** @brief Getter for the previously set terminal criteria for this algorithm.
+
+ @return Deep copy of the terminal criteria used at the moment.
+ */
+ virtual TermCriteria getTermCriteria() const = 0;
+
+ /** @brief Set terminal criteria for solver.
+
+ This method *is not necessary* to be called before the first call to minimize(), as the default
+ value is sensible.
+
+ Algorithm stops when the number of function evaluations done exceeds termcrit.maxCount, when
+ the function values at the vertices of simplex are within termcrit.epsilon range or simplex
+ becomes so small that it can enclosed in a box with termcrit.epsilon sides, whatever comes
+ first.
+ @param termcrit Terminal criteria to be used, represented as cv::TermCriteria structure.
+ */
+ virtual void setTermCriteria(const TermCriteria& termcrit) = 0;
+
+ /** @brief actually runs the algorithm and performs the minimization.
+
+ The sole input parameter determines the centroid of the starting simplex (roughly, it tells
+ where to start), all the others (terminal criteria, initial step, function to be minimized) are
+ supposed to be set via the setters before the call to this method or the default values (not
+ always sensible) will be used.
+
+ @param x The initial point, that will become a centroid of an initial simplex. After the algorithm
+ will terminate, it will be setted to the point where the algorithm stops, the point of possible
+ minimum.
+ @return The value of a function at the point found.
+ */
+ virtual double minimize(InputOutputArray x) = 0;
+};
+
+/** @brief This class is used to perform the non-linear non-constrained minimization of a function,
+
+defined on an `n`-dimensional Euclidean space, using the **Nelder-Mead method**, also known as
+**downhill simplex method**. The basic idea about the method can be obtained from
+<http://en.wikipedia.org/wiki/Nelder-Mead_method>.
+
+It should be noted, that this method, although deterministic, is rather a heuristic and therefore
+may converge to a local minima, not necessary a global one. It is iterative optimization technique,
+which at each step uses an information about the values of a function evaluated only at `n+1`
+points, arranged as a *simplex* in `n`-dimensional space (hence the second name of the method). At
+each step new point is chosen to evaluate function at, obtained value is compared with previous
+ones and based on this information simplex changes it's shape , slowly moving to the local minimum.
+Thus this method is using *only* function values to make decision, on contrary to, say, Nonlinear
+Conjugate Gradient method (which is also implemented in optim).
+
+Algorithm stops when the number of function evaluations done exceeds termcrit.maxCount, when the
+function values at the vertices of simplex are within termcrit.epsilon range or simplex becomes so
+small that it can enclosed in a box with termcrit.epsilon sides, whatever comes first, for some
+defined by user positive integer termcrit.maxCount and positive non-integer termcrit.epsilon.
+
+@note DownhillSolver is a derivative of the abstract interface
+cv::MinProblemSolver, which in turn is derived from the Algorithm interface and is used to
+encapsulate the functionality, common to all non-linear optimization algorithms in the optim
+module.
+
+@note term criteria should meet following condition:
+@code
+ termcrit.type == (TermCriteria::MAX_ITER + TermCriteria::EPS) && termcrit.epsilon > 0 && termcrit.maxCount > 0
+@endcode
+ */
+class CV_EXPORTS DownhillSolver : public MinProblemSolver
+{
+public:
+ /** @brief Returns the initial step that will be used in downhill simplex algorithm.
+
+ @param step Initial step that will be used in algorithm. Note, that although corresponding setter
+ accepts column-vectors as well as row-vectors, this method will return a row-vector.
+ @see DownhillSolver::setInitStep
+ */
+ virtual void getInitStep(OutputArray step) const=0;
+
+ /** @brief Sets the initial step that will be used in downhill simplex algorithm.
+
+ Step, together with initial point (givin in DownhillSolver::minimize) are two `n`-dimensional
+ vectors that are used to determine the shape of initial simplex. Roughly said, initial point
+ determines the position of a simplex (it will become simplex's centroid), while step determines the
+ spread (size in each dimension) of a simplex. To be more precise, if \f$s,x_0\in\mathbb{R}^n\f$ are
+ the initial step and initial point respectively, the vertices of a simplex will be:
+ \f$v_0:=x_0-\frac{1}{2} s\f$ and \f$v_i:=x_0+s_i\f$ for \f$i=1,2,\dots,n\f$ where \f$s_i\f$ denotes
+ projections of the initial step of *n*-th coordinate (the result of projection is treated to be
+ vector given by \f$s_i:=e_i\cdot\left<e_i\cdot s\right>\f$, where \f$e_i\f$ form canonical basis)
+
+ @param step Initial step that will be used in algorithm. Roughly said, it determines the spread
+ (size in each dimension) of an initial simplex.
+ */
+ virtual void setInitStep(InputArray step)=0;
+
+ /** @brief This function returns the reference to the ready-to-use DownhillSolver object.
+
+ All the parameters are optional, so this procedure can be called even without parameters at
+ all. In this case, the default values will be used. As default value for terminal criteria are
+ the only sensible ones, MinProblemSolver::setFunction() and DownhillSolver::setInitStep()
+ should be called upon the obtained object, if the respective parameters were not given to
+ create(). Otherwise, the two ways (give parameters to createDownhillSolver() or miss them out
+ and call the MinProblemSolver::setFunction() and DownhillSolver::setInitStep()) are absolutely
+ equivalent (and will drop the same errors in the same way, should invalid input be detected).
+ @param f Pointer to the function that will be minimized, similarly to the one you submit via
+ MinProblemSolver::setFunction.
+ @param initStep Initial step, that will be used to construct the initial simplex, similarly to the one
+ you submit via MinProblemSolver::setInitStep.
+ @param termcrit Terminal criteria to the algorithm, similarly to the one you submit via
+ MinProblemSolver::setTermCriteria.
+ */
+ static Ptr<DownhillSolver> create(const Ptr<MinProblemSolver::Function>& f=Ptr<MinProblemSolver::Function>(),
+ InputArray initStep=Mat_<double>(1,1,0.0),
+ TermCriteria termcrit=TermCriteria(TermCriteria::MAX_ITER+TermCriteria::EPS,5000,0.000001));
+};
+
+/** @brief This class is used to perform the non-linear non-constrained minimization of a function
+with known gradient,
+
+defined on an *n*-dimensional Euclidean space, using the **Nonlinear Conjugate Gradient method**.
+The implementation was done based on the beautifully clear explanatory article [An Introduction to
+the Conjugate Gradient Method Without the Agonizing
+Pain](http://www.cs.cmu.edu/~quake-papers/painless-conjugate-gradient.pdf) by Jonathan Richard
+Shewchuk. The method can be seen as an adaptation of a standard Conjugate Gradient method (see, for
+example <http://en.wikipedia.org/wiki/Conjugate_gradient_method>) for numerically solving the
+systems of linear equations.
+
+It should be noted, that this method, although deterministic, is rather a heuristic method and
+therefore may converge to a local minima, not necessary a global one. What is even more disastrous,
+most of its behaviour is ruled by gradient, therefore it essentially cannot distinguish between
+local minima and maxima. Therefore, if it starts sufficiently near to the local maximum, it may
+converge to it. Another obvious restriction is that it should be possible to compute the gradient of
+a function at any point, thus it is preferable to have analytic expression for gradient and
+computational burden should be born by the user.
+
+The latter responsibility is accompilished via the getGradient method of a
+MinProblemSolver::Function interface (which represents function being optimized). This method takes
+point a point in *n*-dimensional space (first argument represents the array of coordinates of that
+point) and comput its gradient (it should be stored in the second argument as an array).
+
+@note class ConjGradSolver thus does not add any new methods to the basic MinProblemSolver interface.
+
+@note term criteria should meet following condition:
+@code
+ termcrit.type == (TermCriteria::MAX_ITER + TermCriteria::EPS) && termcrit.epsilon > 0 && termcrit.maxCount > 0
+ // or
+ termcrit.type == TermCriteria::MAX_ITER) && termcrit.maxCount > 0
+@endcode
+ */
+class CV_EXPORTS ConjGradSolver : public MinProblemSolver
+{
+public:
+ /** @brief This function returns the reference to the ready-to-use ConjGradSolver object.
+
+ All the parameters are optional, so this procedure can be called even without parameters at
+ all. In this case, the default values will be used. As default value for terminal criteria are
+ the only sensible ones, MinProblemSolver::setFunction() should be called upon the obtained
+ object, if the function was not given to create(). Otherwise, the two ways (submit it to
+ create() or miss it out and call the MinProblemSolver::setFunction()) are absolutely equivalent
+ (and will drop the same errors in the same way, should invalid input be detected).
+ @param f Pointer to the function that will be minimized, similarly to the one you submit via
+ MinProblemSolver::setFunction.
+ @param termcrit Terminal criteria to the algorithm, similarly to the one you submit via
+ MinProblemSolver::setTermCriteria.
+ */
+ static Ptr<ConjGradSolver> create(const Ptr<MinProblemSolver::Function>& f=Ptr<ConjGradSolver::Function>(),
+ TermCriteria termcrit=TermCriteria(TermCriteria::MAX_ITER+TermCriteria::EPS,5000,0.000001));
+};
+
+//! return codes for cv::solveLP() function
+enum SolveLPResult
+{
+ SOLVELP_UNBOUNDED = -2, //!< problem is unbounded (target function can achieve arbitrary high values)
+ SOLVELP_UNFEASIBLE = -1, //!< problem is unfeasible (there are no points that satisfy all the constraints imposed)
+ SOLVELP_SINGLE = 0, //!< there is only one maximum for target function
+ SOLVELP_MULTI = 1 //!< there are multiple maxima for target function - the arbitrary one is returned
+};
+
+/** @brief Solve given (non-integer) linear programming problem using the Simplex Algorithm (Simplex Method).
+
+What we mean here by "linear programming problem" (or LP problem, for short) can be formulated as:
+
+\f[\mbox{Maximize } c\cdot x\\
+ \mbox{Subject to:}\\
+ Ax\leq b\\
+ x\geq 0\f]
+
+Where \f$c\f$ is fixed `1`-by-`n` row-vector, \f$A\f$ is fixed `m`-by-`n` matrix, \f$b\f$ is fixed `m`-by-`1`
+column vector and \f$x\f$ is an arbitrary `n`-by-`1` column vector, which satisfies the constraints.
+
+Simplex algorithm is one of many algorithms that are designed to handle this sort of problems
+efficiently. Although it is not optimal in theoretical sense (there exist algorithms that can solve
+any problem written as above in polynomial time, while simplex method degenerates to exponential
+time for some special cases), it is well-studied, easy to implement and is shown to work well for
+real-life purposes.
+
+The particular implementation is taken almost verbatim from **Introduction to Algorithms, third
+edition** by T. H. Cormen, C. E. Leiserson, R. L. Rivest and Clifford Stein. In particular, the
+Bland's rule <http://en.wikipedia.org/wiki/Bland%27s_rule> is used to prevent cycling.
+
+@param Func This row-vector corresponds to \f$c\f$ in the LP problem formulation (see above). It should
+contain 32- or 64-bit floating point numbers. As a convenience, column-vector may be also submitted,
+in the latter case it is understood to correspond to \f$c^T\f$.
+@param Constr `m`-by-`n+1` matrix, whose rightmost column corresponds to \f$b\f$ in formulation above
+and the remaining to \f$A\f$. It should containt 32- or 64-bit floating point numbers.
+@param z The solution will be returned here as a column-vector - it corresponds to \f$c\f$ in the
+formulation above. It will contain 64-bit floating point numbers.
+@return One of cv::SolveLPResult
+ */
+CV_EXPORTS_W int solveLP(const Mat& Func, const Mat& Constr, Mat& z);
+
+//! @}
+
+}// cv
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/core/ovx.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,28 @@
+// This file is part of OpenCV project.
+// It is subject to the license terms in the LICENSE file found in the top-level directory
+// of this distribution and at http://opencv.org/license.html.
+
+// Copyright (C) 2016, Intel Corporation, all rights reserved.
+// Third party copyrights are property of their respective owners.
+
+// OpenVX related definitions and declarations
+
+#pragma once
+#ifndef OPENCV_OVX_HPP
+#define OPENCV_OVX_HPP
+
+#include "cvdef.h"
+
+namespace cv
+{
+/// Check if use of OpenVX is possible
+CV_EXPORTS_W bool haveOpenVX();
+
+/// Check if use of OpenVX is enabled
+CV_EXPORTS_W bool useOpenVX();
+
+/// Enable/disable use of OpenVX
+CV_EXPORTS_W void setUseOpenVX(bool flag);
+} // namespace cv
+
+#endif // OPENCV_OVX_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/core/persistence.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,1274 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_CORE_PERSISTENCE_HPP
+#define OPENCV_CORE_PERSISTENCE_HPP
+
+#ifndef __cplusplus
+# error persistence.hpp header must be compiled as C++
+#endif
+
+//! @addtogroup core_c
+//! @{
+
+/** @brief "black box" representation of the file storage associated with a file on disk.
+
+Several functions that are described below take CvFileStorage\* as inputs and allow the user to
+save or to load hierarchical collections that consist of scalar values, standard CXCore objects
+(such as matrices, sequences, graphs), and user-defined objects.
+
+OpenCV can read and write data in XML (<http://www.w3c.org/XML>), YAML (<http://www.yaml.org>) or
+JSON (<http://www.json.org/>) formats. Below is an example of 3x3 floating-point identity matrix A,
+stored in XML and YAML files
+using CXCore functions:
+XML:
+@code{.xml}
+ <?xml version="1.0">
+ <opencv_storage>
+ <A type_id="opencv-matrix">
+ <rows>3</rows>
+ <cols>3</cols>
+ <dt>f</dt>
+ <data>1. 0. 0. 0. 1. 0. 0. 0. 1.</data>
+ </A>
+ </opencv_storage>
+@endcode
+YAML:
+@code{.yaml}
+ %YAML:1.0
+ A: !!opencv-matrix
+ rows: 3
+ cols: 3
+ dt: f
+ data: [ 1., 0., 0., 0., 1., 0., 0., 0., 1.]
+@endcode
+As it can be seen from the examples, XML uses nested tags to represent hierarchy, while YAML uses
+indentation for that purpose (similar to the Python programming language).
+
+The same functions can read and write data in both formats; the particular format is determined by
+the extension of the opened file, ".xml" for XML files, ".yml" or ".yaml" for YAML and ".json" for
+JSON.
+ */
+typedef struct CvFileStorage CvFileStorage;
+typedef struct CvFileNode CvFileNode;
+typedef struct CvMat CvMat;
+typedef struct CvMatND CvMatND;
+
+//! @} core_c
+
+#include "opencv2/core/types.hpp"
+#include "opencv2/core/mat.hpp"
+
+namespace cv {
+
+/** @addtogroup core_xml
+
+XML/YAML/JSON file storages. {#xml_storage}
+=======================
+Writing to a file storage.
+--------------------------
+You can store and then restore various OpenCV data structures to/from XML (<http://www.w3c.org/XML>),
+YAML (<http://www.yaml.org>) or JSON (<http://www.json.org/>) formats. Also, it is possible store
+and load arbitrarily complex data structures, which include OpenCV data structures, as well as
+primitive data types (integer and floating-point numbers and text strings) as their elements.
+
+Use the following procedure to write something to XML, YAML or JSON:
+-# Create new FileStorage and open it for writing. It can be done with a single call to
+FileStorage::FileStorage constructor that takes a filename, or you can use the default constructor
+and then call FileStorage::open. Format of the file (XML, YAML or JSON) is determined from the filename
+extension (".xml", ".yml"/".yaml" and ".json", respectively)
+-# Write all the data you want using the streaming operator `<<`, just like in the case of STL
+streams.
+-# Close the file using FileStorage::release. FileStorage destructor also closes the file.
+
+Here is an example:
+@code
+ #include "opencv2/opencv.hpp"
+ #include <time.h>
+
+ using namespace cv;
+
+ int main(int, char** argv)
+ {
+ FileStorage fs("test.yml", FileStorage::WRITE);
+
+ fs << "frameCount" << 5;
+ time_t rawtime; time(&rawtime);
+ fs << "calibrationDate" << asctime(localtime(&rawtime));
+ Mat cameraMatrix = (Mat_<double>(3,3) << 1000, 0, 320, 0, 1000, 240, 0, 0, 1);
+ Mat distCoeffs = (Mat_<double>(5,1) << 0.1, 0.01, -0.001, 0, 0);
+ fs << "cameraMatrix" << cameraMatrix << "distCoeffs" << distCoeffs;
+ fs << "features" << "[";
+ for( int i = 0; i < 3; i++ )
+ {
+ int x = rand() % 640;
+ int y = rand() % 480;
+ uchar lbp = rand() % 256;
+
+ fs << "{:" << "x" << x << "y" << y << "lbp" << "[:";
+ for( int j = 0; j < 8; j++ )
+ fs << ((lbp >> j) & 1);
+ fs << "]" << "}";
+ }
+ fs << "]";
+ fs.release();
+ return 0;
+ }
+@endcode
+The sample above stores to XML and integer, text string (calibration date), 2 matrices, and a custom
+structure "feature", which includes feature coordinates and LBP (local binary pattern) value. Here
+is output of the sample:
+@code{.yaml}
+%YAML:1.0
+frameCount: 5
+calibrationDate: "Fri Jun 17 14:09:29 2011\n"
+cameraMatrix: !!opencv-matrix
+ rows: 3
+ cols: 3
+ dt: d
+ data: [ 1000., 0., 320., 0., 1000., 240., 0., 0., 1. ]
+distCoeffs: !!opencv-matrix
+ rows: 5
+ cols: 1
+ dt: d
+ data: [ 1.0000000000000001e-01, 1.0000000000000000e-02,
+ -1.0000000000000000e-03, 0., 0. ]
+features:
+ - { x:167, y:49, lbp:[ 1, 0, 0, 1, 1, 0, 1, 1 ] }
+ - { x:298, y:130, lbp:[ 0, 0, 0, 1, 0, 0, 1, 1 ] }
+ - { x:344, y:158, lbp:[ 1, 1, 0, 0, 0, 0, 1, 0 ] }
+@endcode
+
+As an exercise, you can replace ".yml" with ".xml" or ".json" in the sample above and see, how the
+corresponding XML file will look like.
+
+Several things can be noted by looking at the sample code and the output:
+
+- The produced YAML (and XML/JSON) consists of heterogeneous collections that can be nested. There are
+ 2 types of collections: named collections (mappings) and unnamed collections (sequences). In mappings
+ each element has a name and is accessed by name. This is similar to structures and std::map in
+ C/C++ and dictionaries in Python. In sequences elements do not have names, they are accessed by
+ indices. This is similar to arrays and std::vector in C/C++ and lists, tuples in Python.
+ "Heterogeneous" means that elements of each single collection can have different types.
+
+ Top-level collection in YAML/XML/JSON is a mapping. Each matrix is stored as a mapping, and the matrix
+ elements are stored as a sequence. Then, there is a sequence of features, where each feature is
+ represented a mapping, and lbp value in a nested sequence.
+
+- When you write to a mapping (a structure), you write element name followed by its value. When you
+ write to a sequence, you simply write the elements one by one. OpenCV data structures (such as
+ cv::Mat) are written in absolutely the same way as simple C data structures - using `<<`
+ operator.
+
+- To write a mapping, you first write the special string `{` to the storage, then write the
+ elements as pairs (`fs << <element_name> << <element_value>`) and then write the closing
+ `}`.
+
+- To write a sequence, you first write the special string `[`, then write the elements, then
+ write the closing `]`.
+
+- In YAML/JSON (but not XML), mappings and sequences can be written in a compact Python-like inline
+ form. In the sample above matrix elements, as well as each feature, including its lbp value, is
+ stored in such inline form. To store a mapping/sequence in a compact form, put `:` after the
+ opening character, e.g. use `{:` instead of `{` and `[:` instead of `[`. When the
+ data is written to XML, those extra `:` are ignored.
+
+Reading data from a file storage.
+---------------------------------
+To read the previously written XML, YAML or JSON file, do the following:
+-# Open the file storage using FileStorage::FileStorage constructor or FileStorage::open method.
+ In the current implementation the whole file is parsed and the whole representation of file
+ storage is built in memory as a hierarchy of file nodes (see FileNode)
+
+-# Read the data you are interested in. Use FileStorage::operator [], FileNode::operator []
+ and/or FileNodeIterator.
+
+-# Close the storage using FileStorage::release.
+
+Here is how to read the file created by the code sample above:
+@code
+ FileStorage fs2("test.yml", FileStorage::READ);
+
+ // first method: use (type) operator on FileNode.
+ int frameCount = (int)fs2["frameCount"];
+
+ String date;
+ // second method: use FileNode::operator >>
+ fs2["calibrationDate"] >> date;
+
+ Mat cameraMatrix2, distCoeffs2;
+ fs2["cameraMatrix"] >> cameraMatrix2;
+ fs2["distCoeffs"] >> distCoeffs2;
+
+ cout << "frameCount: " << frameCount << endl
+ << "calibration date: " << date << endl
+ << "camera matrix: " << cameraMatrix2 << endl
+ << "distortion coeffs: " << distCoeffs2 << endl;
+
+ FileNode features = fs2["features"];
+ FileNodeIterator it = features.begin(), it_end = features.end();
+ int idx = 0;
+ std::vector<uchar> lbpval;
+
+ // iterate through a sequence using FileNodeIterator
+ for( ; it != it_end; ++it, idx++ )
+ {
+ cout << "feature #" << idx << ": ";
+ cout << "x=" << (int)(*it)["x"] << ", y=" << (int)(*it)["y"] << ", lbp: (";
+ // you can also easily read numerical arrays using FileNode >> std::vector operator.
+ (*it)["lbp"] >> lbpval;
+ for( int i = 0; i < (int)lbpval.size(); i++ )
+ cout << " " << (int)lbpval[i];
+ cout << ")" << endl;
+ }
+ fs2.release();
+@endcode
+
+Format specification {#format_spec}
+--------------------
+`([count]{u|c|w|s|i|f|d})`... where the characters correspond to fundamental C++ types:
+- `u` 8-bit unsigned number
+- `c` 8-bit signed number
+- `w` 16-bit unsigned number
+- `s` 16-bit signed number
+- `i` 32-bit signed number
+- `f` single precision floating-point number
+- `d` double precision floating-point number
+- `r` pointer, 32 lower bits of which are written as a signed integer. The type can be used to
+ store structures with links between the elements.
+
+`count` is the optional counter of values of a given type. For example, `2if` means that each array
+element is a structure of 2 integers, followed by a single-precision floating-point number. The
+equivalent notations of the above specification are `iif`, `2i1f` and so forth. Other examples: `u`
+means that the array consists of bytes, and `2d` means the array consists of pairs of doubles.
+
+@see @ref filestorage.cpp
+*/
+
+//! @{
+
+/** @example filestorage.cpp
+A complete example using the FileStorage interface
+*/
+
+////////////////////////// XML & YAML I/O //////////////////////////
+
+class CV_EXPORTS FileNode;
+class CV_EXPORTS FileNodeIterator;
+
+/** @brief XML/YAML/JSON file storage class that encapsulates all the information necessary for writing or
+reading data to/from a file.
+ */
+class CV_EXPORTS_W FileStorage
+{
+public:
+ //! file storage mode
+ enum Mode
+ {
+ READ = 0, //!< value, open the file for reading
+ WRITE = 1, //!< value, open the file for writing
+ APPEND = 2, //!< value, open the file for appending
+ MEMORY = 4, //!< flag, read data from source or write data to the internal buffer (which is
+ //!< returned by FileStorage::release)
+ FORMAT_MASK = (7<<3), //!< mask for format flags
+ FORMAT_AUTO = 0, //!< flag, auto format
+ FORMAT_XML = (1<<3), //!< flag, XML format
+ FORMAT_YAML = (2<<3), //!< flag, YAML format
+ FORMAT_JSON = (3<<3), //!< flag, JSON format
+
+ BASE64 = 64, //!< flag, write rawdata in Base64 by default. (consider using WRITE_BASE64)
+ WRITE_BASE64 = BASE64 | WRITE, //!< flag, enable both WRITE and BASE64
+ };
+ enum
+ {
+ UNDEFINED = 0,
+ VALUE_EXPECTED = 1,
+ NAME_EXPECTED = 2,
+ INSIDE_MAP = 4
+ };
+
+ /** @brief The constructors.
+
+ The full constructor opens the file. Alternatively you can use the default constructor and then
+ call FileStorage::open.
+ */
+ CV_WRAP FileStorage();
+
+ /** @overload
+ @param source Name of the file to open or the text string to read the data from. Extension of the
+ file (.xml, .yml/.yaml, or .json) determines its format (XML, YAML or JSON respectively). Also you can
+ append .gz to work with compressed files, for example myHugeMatrix.xml.gz. If both FileStorage::WRITE
+ and FileStorage::MEMORY flags are specified, source is used just to specify the output file format (e.g.
+ mydata.xml, .yml etc.).
+ @param flags Mode of operation. See FileStorage::Mode
+ @param encoding Encoding of the file. Note that UTF-16 XML encoding is not supported currently and
+ you should use 8-bit encoding instead of it.
+ */
+ CV_WRAP FileStorage(const String& source, int flags, const String& encoding=String());
+
+ /** @overload */
+ FileStorage(CvFileStorage* fs, bool owning=true);
+
+ //! the destructor. calls release()
+ virtual ~FileStorage();
+
+ /** @brief Opens a file.
+
+ See description of parameters in FileStorage::FileStorage. The method calls FileStorage::release
+ before opening the file.
+ @param filename Name of the file to open or the text string to read the data from.
+ Extension of the file (.xml, .yml/.yaml or .json) determines its format (XML, YAML or JSON
+ respectively). Also you can append .gz to work with compressed files, for example myHugeMatrix.xml.gz. If both
+ FileStorage::WRITE and FileStorage::MEMORY flags are specified, source is used just to specify
+ the output file format (e.g. mydata.xml, .yml etc.). A file name can also contain parameters.
+ You can use this format, "*?base64" (e.g. "file.json?base64" (case sensitive)), as an alternative to
+ FileStorage::BASE64 flag.
+ @param flags Mode of operation. One of FileStorage::Mode
+ @param encoding Encoding of the file. Note that UTF-16 XML encoding is not supported currently and
+ you should use 8-bit encoding instead of it.
+ */
+ CV_WRAP virtual bool open(const String& filename, int flags, const String& encoding=String());
+
+ /** @brief Checks whether the file is opened.
+
+ @returns true if the object is associated with the current file and false otherwise. It is a
+ good practice to call this method after you tried to open a file.
+ */
+ CV_WRAP virtual bool isOpened() const;
+
+ /** @brief Closes the file and releases all the memory buffers.
+
+ Call this method after all I/O operations with the storage are finished.
+ */
+ CV_WRAP virtual void release();
+
+ /** @brief Closes the file and releases all the memory buffers.
+
+ Call this method after all I/O operations with the storage are finished. If the storage was
+ opened for writing data and FileStorage::WRITE was specified
+ */
+ CV_WRAP virtual String releaseAndGetString();
+
+ /** @brief Returns the first element of the top-level mapping.
+ @returns The first element of the top-level mapping.
+ */
+ CV_WRAP FileNode getFirstTopLevelNode() const;
+
+ /** @brief Returns the top-level mapping
+ @param streamidx Zero-based index of the stream. In most cases there is only one stream in the file.
+ However, YAML supports multiple streams and so there can be several.
+ @returns The top-level mapping.
+ */
+ CV_WRAP FileNode root(int streamidx=0) const;
+
+ /** @brief Returns the specified element of the top-level mapping.
+ @param nodename Name of the file node.
+ @returns Node with the given name.
+ */
+ FileNode operator[](const String& nodename) const;
+
+ /** @overload */
+ CV_WRAP_AS(getNode) FileNode operator[](const char* nodename) const;
+
+ /** @brief Returns the obsolete C FileStorage structure.
+ @returns Pointer to the underlying C FileStorage structure
+ */
+ CvFileStorage* operator *() { return fs.get(); }
+
+ /** @overload */
+ const CvFileStorage* operator *() const { return fs.get(); }
+
+ /** @brief Writes multiple numbers.
+
+ Writes one or more numbers of the specified format to the currently written structure. Usually it is
+ more convenient to use operator `<<` instead of this method.
+ @param fmt Specification of each array element, see @ref format_spec "format specification"
+ @param vec Pointer to the written array.
+ @param len Number of the uchar elements to write.
+ */
+ void writeRaw( const String& fmt, const uchar* vec, size_t len );
+
+ /** @brief Writes the registered C structure (CvMat, CvMatND, CvSeq).
+ @param name Name of the written object.
+ @param obj Pointer to the object.
+ @see ocvWrite for details.
+ */
+ void writeObj( const String& name, const void* obj );
+
+ /**
+ * @brief Simplified writing API to use with bindings.
+ * @param name Name of the written object
+ * @param val Value of the written object
+ */
+ CV_WRAP void write(const String& name, double val);
+ /// @overload
+ CV_WRAP void write(const String& name, const String& val);
+ /// @overload
+ CV_WRAP void write(const String& name, InputArray val);
+
+ /** @brief Writes a comment.
+
+ The function writes a comment into file storage. The comments are skipped when the storage is read.
+ @param comment The written comment, single-line or multi-line
+ @param append If true, the function tries to put the comment at the end of current line.
+ Else if the comment is multi-line, or if it does not fit at the end of the current
+ line, the comment starts a new line.
+ */
+ CV_WRAP void writeComment(const String& comment, bool append = false);
+
+ /** @brief Returns the normalized object name for the specified name of a file.
+ @param filename Name of a file
+ @returns The normalized object name.
+ */
+ static String getDefaultObjectName(const String& filename);
+
+ Ptr<CvFileStorage> fs; //!< the underlying C FileStorage structure
+ String elname; //!< the currently written element
+ std::vector<char> structs; //!< the stack of written structures
+ int state; //!< the writer state
+};
+
+template<> CV_EXPORTS void DefaultDeleter<CvFileStorage>::operator ()(CvFileStorage* obj) const;
+
+/** @brief File Storage Node class.
+
+The node is used to store each and every element of the file storage opened for reading. When
+XML/YAML file is read, it is first parsed and stored in the memory as a hierarchical collection of
+nodes. Each node can be a “leaf” that is contain a single number or a string, or be a collection of
+other nodes. There can be named collections (mappings) where each element has a name and it is
+accessed by a name, and ordered collections (sequences) where elements do not have names but rather
+accessed by index. Type of the file node can be determined using FileNode::type method.
+
+Note that file nodes are only used for navigating file storages opened for reading. When a file
+storage is opened for writing, no data is stored in memory after it is written.
+ */
+class CV_EXPORTS_W_SIMPLE FileNode
+{
+public:
+ //! type of the file storage node
+ enum Type
+ {
+ NONE = 0, //!< empty node
+ INT = 1, //!< an integer
+ REAL = 2, //!< floating-point number
+ FLOAT = REAL, //!< synonym or REAL
+ STR = 3, //!< text string in UTF-8 encoding
+ STRING = STR, //!< synonym for STR
+ REF = 4, //!< integer of size size_t. Typically used for storing complex dynamic structures where some elements reference the others
+ SEQ = 5, //!< sequence
+ MAP = 6, //!< mapping
+ TYPE_MASK = 7,
+ FLOW = 8, //!< compact representation of a sequence or mapping. Used only by YAML writer
+ USER = 16, //!< a registered object (e.g. a matrix)
+ EMPTY = 32, //!< empty structure (sequence or mapping)
+ NAMED = 64 //!< the node has a name (i.e. it is element of a mapping)
+ };
+ /** @brief The constructors.
+
+ These constructors are used to create a default file node, construct it from obsolete structures or
+ from the another file node.
+ */
+ CV_WRAP FileNode();
+
+ /** @overload
+ @param fs Pointer to the obsolete file storage structure.
+ @param node File node to be used as initialization for the created file node.
+ */
+ FileNode(const CvFileStorage* fs, const CvFileNode* node);
+
+ /** @overload
+ @param node File node to be used as initialization for the created file node.
+ */
+ FileNode(const FileNode& node);
+
+ /** @brief Returns element of a mapping node or a sequence node.
+ @param nodename Name of an element in the mapping node.
+ @returns Returns the element with the given identifier.
+ */
+ FileNode operator[](const String& nodename) const;
+
+ /** @overload
+ @param nodename Name of an element in the mapping node.
+ */
+ CV_WRAP_AS(getNode) FileNode operator[](const char* nodename) const;
+
+ /** @overload
+ @param i Index of an element in the sequence node.
+ */
+ CV_WRAP_AS(at) FileNode operator[](int i) const;
+
+ /** @brief Returns type of the node.
+ @returns Type of the node. See FileNode::Type
+ */
+ CV_WRAP int type() const;
+
+ //! returns true if the node is empty
+ CV_WRAP bool empty() const;
+ //! returns true if the node is a "none" object
+ CV_WRAP bool isNone() const;
+ //! returns true if the node is a sequence
+ CV_WRAP bool isSeq() const;
+ //! returns true if the node is a mapping
+ CV_WRAP bool isMap() const;
+ //! returns true if the node is an integer
+ CV_WRAP bool isInt() const;
+ //! returns true if the node is a floating-point number
+ CV_WRAP bool isReal() const;
+ //! returns true if the node is a text string
+ CV_WRAP bool isString() const;
+ //! returns true if the node has a name
+ CV_WRAP bool isNamed() const;
+ //! returns the node name or an empty string if the node is nameless
+ CV_WRAP String name() const;
+ //! returns the number of elements in the node, if it is a sequence or mapping, or 1 otherwise.
+ CV_WRAP size_t size() const;
+ //! returns the node content as an integer. If the node stores floating-point number, it is rounded.
+ operator int() const;
+ //! returns the node content as float
+ operator float() const;
+ //! returns the node content as double
+ operator double() const;
+ //! returns the node content as text string
+ operator String() const;
+#ifndef OPENCV_NOSTL
+ operator std::string() const;
+#endif
+
+ //! returns pointer to the underlying file node
+ CvFileNode* operator *();
+ //! returns pointer to the underlying file node
+ const CvFileNode* operator* () const;
+
+ //! returns iterator pointing to the first node element
+ FileNodeIterator begin() const;
+ //! returns iterator pointing to the element following the last node element
+ FileNodeIterator end() const;
+
+ /** @brief Reads node elements to the buffer with the specified format.
+
+ Usually it is more convenient to use operator `>>` instead of this method.
+ @param fmt Specification of each array element. See @ref format_spec "format specification"
+ @param vec Pointer to the destination array.
+ @param len Number of elements to read. If it is greater than number of remaining elements then all
+ of them will be read.
+ */
+ void readRaw( const String& fmt, uchar* vec, size_t len ) const;
+
+ //! reads the registered object and returns pointer to it
+ void* readObj() const;
+
+ //! Simplified reading API to use with bindings.
+ CV_WRAP double real() const;
+ //! Simplified reading API to use with bindings.
+ CV_WRAP String string() const;
+ //! Simplified reading API to use with bindings.
+ CV_WRAP Mat mat() const;
+
+ // do not use wrapper pointer classes for better efficiency
+ const CvFileStorage* fs;
+ const CvFileNode* node;
+};
+
+
+/** @brief used to iterate through sequences and mappings.
+
+A standard STL notation, with node.begin(), node.end() denoting the beginning and the end of a
+sequence, stored in node. See the data reading sample in the beginning of the section.
+ */
+class CV_EXPORTS FileNodeIterator
+{
+public:
+ /** @brief The constructors.
+
+ These constructors are used to create a default iterator, set it to specific element in a file node
+ or construct it from another iterator.
+ */
+ FileNodeIterator();
+
+ /** @overload
+ @param fs File storage for the iterator.
+ @param node File node for the iterator.
+ @param ofs Index of the element in the node. The created iterator will point to this element.
+ */
+ FileNodeIterator(const CvFileStorage* fs, const CvFileNode* node, size_t ofs=0);
+
+ /** @overload
+ @param it Iterator to be used as initialization for the created iterator.
+ */
+ FileNodeIterator(const FileNodeIterator& it);
+
+ //! returns the currently observed element
+ FileNode operator *() const;
+ //! accesses the currently observed element methods
+ FileNode operator ->() const;
+
+ //! moves iterator to the next node
+ FileNodeIterator& operator ++ ();
+ //! moves iterator to the next node
+ FileNodeIterator operator ++ (int);
+ //! moves iterator to the previous node
+ FileNodeIterator& operator -- ();
+ //! moves iterator to the previous node
+ FileNodeIterator operator -- (int);
+ //! moves iterator forward by the specified offset (possibly negative)
+ FileNodeIterator& operator += (int ofs);
+ //! moves iterator backward by the specified offset (possibly negative)
+ FileNodeIterator& operator -= (int ofs);
+
+ /** @brief Reads node elements to the buffer with the specified format.
+
+ Usually it is more convenient to use operator `>>` instead of this method.
+ @param fmt Specification of each array element. See @ref format_spec "format specification"
+ @param vec Pointer to the destination array.
+ @param maxCount Number of elements to read. If it is greater than number of remaining elements then
+ all of them will be read.
+ */
+ FileNodeIterator& readRaw( const String& fmt, uchar* vec,
+ size_t maxCount=(size_t)INT_MAX );
+
+ struct SeqReader
+ {
+ int header_size;
+ void* seq; /* sequence, beign read; CvSeq */
+ void* block; /* current block; CvSeqBlock */
+ schar* ptr; /* pointer to element be read next */
+ schar* block_min; /* pointer to the beginning of block */
+ schar* block_max; /* pointer to the end of block */
+ int delta_index;/* = seq->first->start_index */
+ schar* prev_elem; /* pointer to previous element */
+ };
+
+ const CvFileStorage* fs;
+ const CvFileNode* container;
+ SeqReader reader;
+ size_t remaining;
+};
+
+//! @} core_xml
+
+/////////////////// XML & YAML I/O implementation //////////////////
+
+//! @relates cv::FileStorage
+//! @{
+
+CV_EXPORTS void write( FileStorage& fs, const String& name, int value );
+CV_EXPORTS void write( FileStorage& fs, const String& name, float value );
+CV_EXPORTS void write( FileStorage& fs, const String& name, double value );
+CV_EXPORTS void write( FileStorage& fs, const String& name, const String& value );
+CV_EXPORTS void write( FileStorage& fs, const String& name, const Mat& value );
+CV_EXPORTS void write( FileStorage& fs, const String& name, const SparseMat& value );
+CV_EXPORTS void write( FileStorage& fs, const String& name, const std::vector<KeyPoint>& value);
+CV_EXPORTS void write( FileStorage& fs, const String& name, const std::vector<DMatch>& value);
+
+CV_EXPORTS void writeScalar( FileStorage& fs, int value );
+CV_EXPORTS void writeScalar( FileStorage& fs, float value );
+CV_EXPORTS void writeScalar( FileStorage& fs, double value );
+CV_EXPORTS void writeScalar( FileStorage& fs, const String& value );
+
+//! @}
+
+//! @relates cv::FileNode
+//! @{
+
+CV_EXPORTS void read(const FileNode& node, int& value, int default_value);
+CV_EXPORTS void read(const FileNode& node, float& value, float default_value);
+CV_EXPORTS void read(const FileNode& node, double& value, double default_value);
+CV_EXPORTS void read(const FileNode& node, String& value, const String& default_value);
+CV_EXPORTS void read(const FileNode& node, Mat& mat, const Mat& default_mat = Mat() );
+CV_EXPORTS void read(const FileNode& node, SparseMat& mat, const SparseMat& default_mat = SparseMat() );
+CV_EXPORTS void read(const FileNode& node, std::vector<KeyPoint>& keypoints);
+CV_EXPORTS void read(const FileNode& node, std::vector<DMatch>& matches);
+
+template<typename _Tp> static inline void read(const FileNode& node, Point_<_Tp>& value, const Point_<_Tp>& default_value)
+{
+ std::vector<_Tp> temp; FileNodeIterator it = node.begin(); it >> temp;
+ value = temp.size() != 2 ? default_value : Point_<_Tp>(saturate_cast<_Tp>(temp[0]), saturate_cast<_Tp>(temp[1]));
+}
+
+template<typename _Tp> static inline void read(const FileNode& node, Point3_<_Tp>& value, const Point3_<_Tp>& default_value)
+{
+ std::vector<_Tp> temp; FileNodeIterator it = node.begin(); it >> temp;
+ value = temp.size() != 3 ? default_value : Point3_<_Tp>(saturate_cast<_Tp>(temp[0]), saturate_cast<_Tp>(temp[1]),
+ saturate_cast<_Tp>(temp[2]));
+}
+
+template<typename _Tp> static inline void read(const FileNode& node, Size_<_Tp>& value, const Size_<_Tp>& default_value)
+{
+ std::vector<_Tp> temp; FileNodeIterator it = node.begin(); it >> temp;
+ value = temp.size() != 2 ? default_value : Size_<_Tp>(saturate_cast<_Tp>(temp[0]), saturate_cast<_Tp>(temp[1]));
+}
+
+template<typename _Tp> static inline void read(const FileNode& node, Complex<_Tp>& value, const Complex<_Tp>& default_value)
+{
+ std::vector<_Tp> temp; FileNodeIterator it = node.begin(); it >> temp;
+ value = temp.size() != 2 ? default_value : Complex<_Tp>(saturate_cast<_Tp>(temp[0]), saturate_cast<_Tp>(temp[1]));
+}
+
+template<typename _Tp> static inline void read(const FileNode& node, Rect_<_Tp>& value, const Rect_<_Tp>& default_value)
+{
+ std::vector<_Tp> temp; FileNodeIterator it = node.begin(); it >> temp;
+ value = temp.size() != 4 ? default_value : Rect_<_Tp>(saturate_cast<_Tp>(temp[0]), saturate_cast<_Tp>(temp[1]),
+ saturate_cast<_Tp>(temp[2]), saturate_cast<_Tp>(temp[3]));
+}
+
+template<typename _Tp, int cn> static inline void read(const FileNode& node, Vec<_Tp, cn>& value, const Vec<_Tp, cn>& default_value)
+{
+ std::vector<_Tp> temp; FileNodeIterator it = node.begin(); it >> temp;
+ value = temp.size() != cn ? default_value : Vec<_Tp, cn>(&temp[0]);
+}
+
+template<typename _Tp> static inline void read(const FileNode& node, Scalar_<_Tp>& value, const Scalar_<_Tp>& default_value)
+{
+ std::vector<_Tp> temp; FileNodeIterator it = node.begin(); it >> temp;
+ value = temp.size() != 4 ? default_value : Scalar_<_Tp>(saturate_cast<_Tp>(temp[0]), saturate_cast<_Tp>(temp[1]),
+ saturate_cast<_Tp>(temp[2]), saturate_cast<_Tp>(temp[3]));
+}
+
+static inline void read(const FileNode& node, Range& value, const Range& default_value)
+{
+ Point2i temp(value.start, value.end); const Point2i default_temp = Point2i(default_value.start, default_value.end);
+ read(node, temp, default_temp);
+ value.start = temp.x; value.end = temp.y;
+}
+
+//! @}
+
+/** @brief Writes string to a file storage.
+@relates cv::FileStorage
+ */
+CV_EXPORTS FileStorage& operator << (FileStorage& fs, const String& str);
+
+//! @cond IGNORED
+
+namespace internal
+{
+ class CV_EXPORTS WriteStructContext
+ {
+ public:
+ WriteStructContext(FileStorage& _fs, const String& name, int flags, const String& typeName = String());
+ ~WriteStructContext();
+ private:
+ FileStorage* fs;
+ };
+
+ template<typename _Tp, int numflag> class VecWriterProxy
+ {
+ public:
+ VecWriterProxy( FileStorage* _fs ) : fs(_fs) {}
+ void operator()(const std::vector<_Tp>& vec) const
+ {
+ size_t count = vec.size();
+ for (size_t i = 0; i < count; i++)
+ write(*fs, vec[i]);
+ }
+ private:
+ FileStorage* fs;
+ };
+
+ template<typename _Tp> class VecWriterProxy<_Tp, 1>
+ {
+ public:
+ VecWriterProxy( FileStorage* _fs ) : fs(_fs) {}
+ void operator()(const std::vector<_Tp>& vec) const
+ {
+ int _fmt = DataType<_Tp>::fmt;
+ char fmt[] = { (char)((_fmt >> 8) + '1'), (char)_fmt, '\0' };
+ fs->writeRaw(fmt, !vec.empty() ? (uchar*)&vec[0] : 0, vec.size() * sizeof(_Tp));
+ }
+ private:
+ FileStorage* fs;
+ };
+
+ template<typename _Tp, int numflag> class VecReaderProxy
+ {
+ public:
+ VecReaderProxy( FileNodeIterator* _it ) : it(_it) {}
+ void operator()(std::vector<_Tp>& vec, size_t count) const
+ {
+ count = std::min(count, it->remaining);
+ vec.resize(count);
+ for (size_t i = 0; i < count; i++, ++(*it))
+ read(**it, vec[i], _Tp());
+ }
+ private:
+ FileNodeIterator* it;
+ };
+
+ template<typename _Tp> class VecReaderProxy<_Tp, 1>
+ {
+ public:
+ VecReaderProxy( FileNodeIterator* _it ) : it(_it) {}
+ void operator()(std::vector<_Tp>& vec, size_t count) const
+ {
+ size_t remaining = it->remaining;
+ size_t cn = DataType<_Tp>::channels;
+ int _fmt = DataType<_Tp>::fmt;
+ char fmt[] = { (char)((_fmt >> 8)+'1'), (char)_fmt, '\0' };
+ size_t remaining1 = remaining / cn;
+ count = count < remaining1 ? count : remaining1;
+ vec.resize(count);
+ it->readRaw(fmt, !vec.empty() ? (uchar*)&vec[0] : 0, count*sizeof(_Tp));
+ }
+ private:
+ FileNodeIterator* it;
+ };
+
+} // internal
+
+//! @endcond
+
+//! @relates cv::FileStorage
+//! @{
+
+template<typename _Tp> static inline
+void write(FileStorage& fs, const _Tp& value)
+{
+ write(fs, String(), value);
+}
+
+template<> inline
+void write( FileStorage& fs, const int& value )
+{
+ writeScalar(fs, value);
+}
+
+template<> inline
+void write( FileStorage& fs, const float& value )
+{
+ writeScalar(fs, value);
+}
+
+template<> inline
+void write( FileStorage& fs, const double& value )
+{
+ writeScalar(fs, value);
+}
+
+template<> inline
+void write( FileStorage& fs, const String& value )
+{
+ writeScalar(fs, value);
+}
+
+template<typename _Tp> static inline
+void write(FileStorage& fs, const Point_<_Tp>& pt )
+{
+ write(fs, pt.x);
+ write(fs, pt.y);
+}
+
+template<typename _Tp> static inline
+void write(FileStorage& fs, const Point3_<_Tp>& pt )
+{
+ write(fs, pt.x);
+ write(fs, pt.y);
+ write(fs, pt.z);
+}
+
+template<typename _Tp> static inline
+void write(FileStorage& fs, const Size_<_Tp>& sz )
+{
+ write(fs, sz.width);
+ write(fs, sz.height);
+}
+
+template<typename _Tp> static inline
+void write(FileStorage& fs, const Complex<_Tp>& c )
+{
+ write(fs, c.re);
+ write(fs, c.im);
+}
+
+template<typename _Tp> static inline
+void write(FileStorage& fs, const Rect_<_Tp>& r )
+{
+ write(fs, r.x);
+ write(fs, r.y);
+ write(fs, r.width);
+ write(fs, r.height);
+}
+
+template<typename _Tp, int cn> static inline
+void write(FileStorage& fs, const Vec<_Tp, cn>& v )
+{
+ for(int i = 0; i < cn; i++)
+ write(fs, v.val[i]);
+}
+
+template<typename _Tp> static inline
+void write(FileStorage& fs, const Scalar_<_Tp>& s )
+{
+ write(fs, s.val[0]);
+ write(fs, s.val[1]);
+ write(fs, s.val[2]);
+ write(fs, s.val[3]);
+}
+
+static inline
+void write(FileStorage& fs, const Range& r )
+{
+ write(fs, r.start);
+ write(fs, r.end);
+}
+
+template<typename _Tp> static inline
+void write( FileStorage& fs, const std::vector<_Tp>& vec )
+{
+ cv::internal::VecWriterProxy<_Tp, DataType<_Tp>::fmt != 0> w(&fs);
+ w(vec);
+}
+
+template<typename _Tp> static inline
+void write(FileStorage& fs, const String& name, const Point_<_Tp>& pt )
+{
+ cv::internal::WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW);
+ write(fs, pt);
+}
+
+template<typename _Tp> static inline
+void write(FileStorage& fs, const String& name, const Point3_<_Tp>& pt )
+{
+ cv::internal::WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW);
+ write(fs, pt);
+}
+
+template<typename _Tp> static inline
+void write(FileStorage& fs, const String& name, const Size_<_Tp>& sz )
+{
+ cv::internal::WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW);
+ write(fs, sz);
+}
+
+template<typename _Tp> static inline
+void write(FileStorage& fs, const String& name, const Complex<_Tp>& c )
+{
+ cv::internal::WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW);
+ write(fs, c);
+}
+
+template<typename _Tp> static inline
+void write(FileStorage& fs, const String& name, const Rect_<_Tp>& r )
+{
+ cv::internal::WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW);
+ write(fs, r);
+}
+
+template<typename _Tp, int cn> static inline
+void write(FileStorage& fs, const String& name, const Vec<_Tp, cn>& v )
+{
+ cv::internal::WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW);
+ write(fs, v);
+}
+
+template<typename _Tp> static inline
+void write(FileStorage& fs, const String& name, const Scalar_<_Tp>& s )
+{
+ cv::internal::WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW);
+ write(fs, s);
+}
+
+static inline
+void write(FileStorage& fs, const String& name, const Range& r )
+{
+ cv::internal::WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW);
+ write(fs, r);
+}
+
+template<typename _Tp> static inline
+void write( FileStorage& fs, const String& name, const std::vector<_Tp>& vec )
+{
+ cv::internal::WriteStructContext ws(fs, name, FileNode::SEQ+(DataType<_Tp>::fmt != 0 ? FileNode::FLOW : 0));
+ write(fs, vec);
+}
+
+template<typename _Tp> static inline
+void write( FileStorage& fs, const String& name, const std::vector< std::vector<_Tp> >& vec )
+{
+ cv::internal::WriteStructContext ws(fs, name, FileNode::SEQ);
+ for(size_t i = 0; i < vec.size(); i++)
+ {
+ cv::internal::WriteStructContext ws_(fs, name, FileNode::SEQ+(DataType<_Tp>::fmt != 0 ? FileNode::FLOW : 0));
+ write(fs, vec[i]);
+ }
+}
+
+//! @} FileStorage
+
+//! @relates cv::FileNode
+//! @{
+
+static inline
+void read(const FileNode& node, bool& value, bool default_value)
+{
+ int temp;
+ read(node, temp, (int)default_value);
+ value = temp != 0;
+}
+
+static inline
+void read(const FileNode& node, uchar& value, uchar default_value)
+{
+ int temp;
+ read(node, temp, (int)default_value);
+ value = saturate_cast<uchar>(temp);
+}
+
+static inline
+void read(const FileNode& node, schar& value, schar default_value)
+{
+ int temp;
+ read(node, temp, (int)default_value);
+ value = saturate_cast<schar>(temp);
+}
+
+static inline
+void read(const FileNode& node, ushort& value, ushort default_value)
+{
+ int temp;
+ read(node, temp, (int)default_value);
+ value = saturate_cast<ushort>(temp);
+}
+
+static inline
+void read(const FileNode& node, short& value, short default_value)
+{
+ int temp;
+ read(node, temp, (int)default_value);
+ value = saturate_cast<short>(temp);
+}
+
+template<typename _Tp> static inline
+void read( FileNodeIterator& it, std::vector<_Tp>& vec, size_t maxCount = (size_t)INT_MAX )
+{
+ cv::internal::VecReaderProxy<_Tp, DataType<_Tp>::fmt != 0> r(&it);
+ r(vec, maxCount);
+}
+
+template<typename _Tp> static inline
+void read( const FileNode& node, std::vector<_Tp>& vec, const std::vector<_Tp>& default_value = std::vector<_Tp>() )
+{
+ if(!node.node)
+ vec = default_value;
+ else
+ {
+ FileNodeIterator it = node.begin();
+ read( it, vec );
+ }
+}
+
+//! @} FileNode
+
+//! @relates cv::FileStorage
+//! @{
+
+/** @brief Writes data to a file storage.
+ */
+template<typename _Tp> static inline
+FileStorage& operator << (FileStorage& fs, const _Tp& value)
+{
+ if( !fs.isOpened() )
+ return fs;
+ if( fs.state == FileStorage::NAME_EXPECTED + FileStorage::INSIDE_MAP )
+ CV_Error( Error::StsError, "No element name has been given" );
+ write( fs, fs.elname, value );
+ if( fs.state & FileStorage::INSIDE_MAP )
+ fs.state = FileStorage::NAME_EXPECTED + FileStorage::INSIDE_MAP;
+ return fs;
+}
+
+/** @brief Writes data to a file storage.
+ */
+static inline
+FileStorage& operator << (FileStorage& fs, const char* str)
+{
+ return (fs << String(str));
+}
+
+/** @brief Writes data to a file storage.
+ */
+static inline
+FileStorage& operator << (FileStorage& fs, char* value)
+{
+ return (fs << String(value));
+}
+
+//! @} FileStorage
+
+//! @relates cv::FileNodeIterator
+//! @{
+
+/** @brief Reads data from a file storage.
+ */
+template<typename _Tp> static inline
+FileNodeIterator& operator >> (FileNodeIterator& it, _Tp& value)
+{
+ read( *it, value, _Tp());
+ return ++it;
+}
+
+/** @brief Reads data from a file storage.
+ */
+template<typename _Tp> static inline
+FileNodeIterator& operator >> (FileNodeIterator& it, std::vector<_Tp>& vec)
+{
+ cv::internal::VecReaderProxy<_Tp, DataType<_Tp>::fmt != 0> r(&it);
+ r(vec, (size_t)INT_MAX);
+ return it;
+}
+
+//! @} FileNodeIterator
+
+//! @relates cv::FileNode
+//! @{
+
+/** @brief Reads data from a file storage.
+ */
+template<typename _Tp> static inline
+void operator >> (const FileNode& n, _Tp& value)
+{
+ read( n, value, _Tp());
+}
+
+/** @brief Reads data from a file storage.
+ */
+template<typename _Tp> static inline
+void operator >> (const FileNode& n, std::vector<_Tp>& vec)
+{
+ FileNodeIterator it = n.begin();
+ it >> vec;
+}
+
+/** @brief Reads KeyPoint from a file storage.
+*/
+//It needs special handling because it contains two types of fields, int & float.
+static inline
+void operator >> (const FileNode& n, std::vector<KeyPoint>& vec)
+{
+ read(n, vec);
+}
+/** @brief Reads DMatch from a file storage.
+*/
+//It needs special handling because it contains two types of fields, int & float.
+static inline
+void operator >> (const FileNode& n, std::vector<DMatch>& vec)
+{
+ read(n, vec);
+}
+
+//! @} FileNode
+
+//! @relates cv::FileNodeIterator
+//! @{
+
+static inline
+bool operator == (const FileNodeIterator& it1, const FileNodeIterator& it2)
+{
+ return it1.fs == it2.fs && it1.container == it2.container &&
+ it1.reader.ptr == it2.reader.ptr && it1.remaining == it2.remaining;
+}
+
+static inline
+bool operator != (const FileNodeIterator& it1, const FileNodeIterator& it2)
+{
+ return !(it1 == it2);
+}
+
+static inline
+ptrdiff_t operator - (const FileNodeIterator& it1, const FileNodeIterator& it2)
+{
+ return it2.remaining - it1.remaining;
+}
+
+static inline
+bool operator < (const FileNodeIterator& it1, const FileNodeIterator& it2)
+{
+ return it1.remaining > it2.remaining;
+}
+
+//! @} FileNodeIterator
+
+//! @cond IGNORED
+
+inline FileNode FileStorage::getFirstTopLevelNode() const { FileNode r = root(); FileNodeIterator it = r.begin(); return it != r.end() ? *it : FileNode(); }
+inline FileNode::FileNode() : fs(0), node(0) {}
+inline FileNode::FileNode(const CvFileStorage* _fs, const CvFileNode* _node) : fs(_fs), node(_node) {}
+inline FileNode::FileNode(const FileNode& _node) : fs(_node.fs), node(_node.node) {}
+inline bool FileNode::empty() const { return node == 0; }
+inline bool FileNode::isNone() const { return type() == NONE; }
+inline bool FileNode::isSeq() const { return type() == SEQ; }
+inline bool FileNode::isMap() const { return type() == MAP; }
+inline bool FileNode::isInt() const { return type() == INT; }
+inline bool FileNode::isReal() const { return type() == REAL; }
+inline bool FileNode::isString() const { return type() == STR; }
+inline CvFileNode* FileNode::operator *() { return (CvFileNode*)node; }
+inline const CvFileNode* FileNode::operator* () const { return node; }
+inline FileNode::operator int() const { int value; read(*this, value, 0); return value; }
+inline FileNode::operator float() const { float value; read(*this, value, 0.f); return value; }
+inline FileNode::operator double() const { double value; read(*this, value, 0.); return value; }
+inline FileNode::operator String() const { String value; read(*this, value, value); return value; }
+inline double FileNode::real() const { return double(*this); }
+inline String FileNode::string() const { return String(*this); }
+inline Mat FileNode::mat() const { Mat value; read(*this, value, value); return value; }
+inline FileNodeIterator FileNode::begin() const { return FileNodeIterator(fs, node); }
+inline FileNodeIterator FileNode::end() const { return FileNodeIterator(fs, node, size()); }
+inline void FileNode::readRaw( const String& fmt, uchar* vec, size_t len ) const { begin().readRaw( fmt, vec, len ); }
+inline FileNode FileNodeIterator::operator *() const { return FileNode(fs, (const CvFileNode*)(const void*)reader.ptr); }
+inline FileNode FileNodeIterator::operator ->() const { return FileNode(fs, (const CvFileNode*)(const void*)reader.ptr); }
+inline String::String(const FileNode& fn): cstr_(0), len_(0) { read(fn, *this, *this); }
+
+//! @endcond
+
+
+CV_EXPORTS void cvStartWriteRawData_Base64(::CvFileStorage * fs, const char* name, int len, const char* dt);
+
+CV_EXPORTS void cvWriteRawData_Base64(::CvFileStorage * fs, const void* _data, int len);
+
+CV_EXPORTS void cvEndWriteRawData_Base64(::CvFileStorage * fs);
+
+CV_EXPORTS void cvWriteMat_Base64(::CvFileStorage* fs, const char* name, const ::CvMat* mat);
+
+CV_EXPORTS void cvWriteMatND_Base64(::CvFileStorage* fs, const char* name, const ::CvMatND* mat);
+
+} // cv
+
+#endif // OPENCV_CORE_PERSISTENCE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/core/private.cuda.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,172 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_CORE_PRIVATE_CUDA_HPP
+#define OPENCV_CORE_PRIVATE_CUDA_HPP
+
+#ifndef __OPENCV_BUILD
+# error this is a private header which should not be used from outside of the OpenCV library
+#endif
+
+#include "cvconfig.h"
+
+#include "opencv2/core/cvdef.h"
+#include "opencv2/core/base.hpp"
+
+#include "opencv2/core/cuda.hpp"
+
+#ifdef HAVE_CUDA
+# include <cuda.h>
+# include <cuda_runtime.h>
+# include <npp.h>
+# include "opencv2/core/cuda_stream_accessor.hpp"
+# include "opencv2/core/cuda/common.hpp"
+
+# define NPP_VERSION (NPP_VERSION_MAJOR * 1000 + NPP_VERSION_MINOR * 100 + NPP_VERSION_BUILD)
+
+# define CUDART_MINIMUM_REQUIRED_VERSION 6050
+
+# if (CUDART_VERSION < CUDART_MINIMUM_REQUIRED_VERSION)
+# error "Insufficient Cuda Runtime library version, please update it."
+# endif
+
+# if defined(CUDA_ARCH_BIN_OR_PTX_10)
+# error "OpenCV CUDA module doesn't support NVIDIA compute capability 1.0"
+# endif
+#endif
+
+//! @cond IGNORED
+
+namespace cv { namespace cuda {
+ CV_EXPORTS cv::String getNppErrorMessage(int code);
+ CV_EXPORTS cv::String getCudaDriverApiErrorMessage(int code);
+
+ CV_EXPORTS GpuMat getInputMat(InputArray _src, Stream& stream);
+
+ CV_EXPORTS GpuMat getOutputMat(OutputArray _dst, int rows, int cols, int type, Stream& stream);
+ static inline GpuMat getOutputMat(OutputArray _dst, Size size, int type, Stream& stream)
+ {
+ return getOutputMat(_dst, size.height, size.width, type, stream);
+ }
+
+ CV_EXPORTS void syncOutput(const GpuMat& dst, OutputArray _dst, Stream& stream);
+}}
+
+#ifndef HAVE_CUDA
+
+static inline void throw_no_cuda() { CV_Error(cv::Error::GpuNotSupported, "The library is compiled without CUDA support"); }
+
+#else // HAVE_CUDA
+
+static inline void throw_no_cuda() { CV_Error(cv::Error::StsNotImplemented, "The called functionality is disabled for current build or platform"); }
+
+namespace cv { namespace cuda
+{
+ class CV_EXPORTS BufferPool
+ {
+ public:
+ explicit BufferPool(Stream& stream);
+
+ GpuMat getBuffer(int rows, int cols, int type);
+ GpuMat getBuffer(Size size, int type) { return getBuffer(size.height, size.width, type); }
+
+ GpuMat::Allocator* getAllocator() const { return allocator_; }
+
+ private:
+ GpuMat::Allocator* allocator_;
+ };
+
+ static inline void checkNppError(int code, const char* file, const int line, const char* func)
+ {
+ if (code < 0)
+ cv::error(cv::Error::GpuApiCallError, getNppErrorMessage(code), func, file, line);
+ }
+
+ static inline void checkCudaDriverApiError(int code, const char* file, const int line, const char* func)
+ {
+ if (code != CUDA_SUCCESS)
+ cv::error(cv::Error::GpuApiCallError, getCudaDriverApiErrorMessage(code), func, file, line);
+ }
+
+ template<int n> struct NPPTypeTraits;
+ template<> struct NPPTypeTraits<CV_8U> { typedef Npp8u npp_type; };
+ template<> struct NPPTypeTraits<CV_8S> { typedef Npp8s npp_type; };
+ template<> struct NPPTypeTraits<CV_16U> { typedef Npp16u npp_type; };
+ template<> struct NPPTypeTraits<CV_16S> { typedef Npp16s npp_type; };
+ template<> struct NPPTypeTraits<CV_32S> { typedef Npp32s npp_type; };
+ template<> struct NPPTypeTraits<CV_32F> { typedef Npp32f npp_type; };
+ template<> struct NPPTypeTraits<CV_64F> { typedef Npp64f npp_type; };
+
+ class NppStreamHandler
+ {
+ public:
+ inline explicit NppStreamHandler(Stream& newStream)
+ {
+ oldStream = nppGetStream();
+ nppSetStream(StreamAccessor::getStream(newStream));
+ }
+
+ inline explicit NppStreamHandler(cudaStream_t newStream)
+ {
+ oldStream = nppGetStream();
+ nppSetStream(newStream);
+ }
+
+ inline ~NppStreamHandler()
+ {
+ nppSetStream(oldStream);
+ }
+
+ private:
+ cudaStream_t oldStream;
+ };
+}}
+
+#define nppSafeCall(expr) cv::cuda::checkNppError(expr, __FILE__, __LINE__, CV_Func)
+#define cuSafeCall(expr) cv::cuda::checkCudaDriverApiError(expr, __FILE__, __LINE__, CV_Func)
+
+#endif // HAVE_CUDA
+
+//! @endcond
+
+#endif // OPENCV_CORE_PRIVATE_CUDA_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/core/private.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,585 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_CORE_PRIVATE_HPP
+#define OPENCV_CORE_PRIVATE_HPP
+
+#ifndef __OPENCV_BUILD
+# error this is a private header which should not be used from outside of the OpenCV library
+#endif
+
+#include "opencv2/core.hpp"
+#include "cvconfig.h"
+
+#ifdef HAVE_EIGEN
+# if defined __GNUC__ && defined __APPLE__
+# pragma GCC diagnostic ignored "-Wshadow"
+# endif
+# include <Eigen/Core>
+# include "opencv2/core/eigen.hpp"
+#endif
+
+#ifdef HAVE_TBB
+# include "tbb/tbb.h"
+# include "tbb/task.h"
+# undef min
+# undef max
+#endif
+
+#if defined HAVE_FP16 && (defined __F16C__ || (defined _MSC_VER && _MSC_VER >= 1700))
+# include <immintrin.h>
+# define CV_FP16 1
+#elif defined HAVE_FP16 && defined __GNUC__
+# define CV_FP16 1
+#endif
+
+#ifndef CV_FP16
+# define CV_FP16 0
+#endif
+
+//! @cond IGNORED
+
+namespace cv
+{
+#ifdef HAVE_TBB
+
+ typedef tbb::blocked_range<int> BlockedRange;
+
+ template<typename Body> static inline
+ void parallel_for( const BlockedRange& range, const Body& body )
+ {
+ tbb::parallel_for(range, body);
+ }
+
+ typedef tbb::split Split;
+
+ template<typename Body> static inline
+ void parallel_reduce( const BlockedRange& range, Body& body )
+ {
+ tbb::parallel_reduce(range, body);
+ }
+
+ typedef tbb::concurrent_vector<Rect> ConcurrentRectVector;
+#else
+ class BlockedRange
+ {
+ public:
+ BlockedRange() : _begin(0), _end(0), _grainsize(0) {}
+ BlockedRange(int b, int e, int g=1) : _begin(b), _end(e), _grainsize(g) {}
+ int begin() const { return _begin; }
+ int end() const { return _end; }
+ int grainsize() const { return _grainsize; }
+
+ protected:
+ int _begin, _end, _grainsize;
+ };
+
+ template<typename Body> static inline
+ void parallel_for( const BlockedRange& range, const Body& body )
+ {
+ body(range);
+ }
+ typedef std::vector<Rect> ConcurrentRectVector;
+
+ class Split {};
+
+ template<typename Body> static inline
+ void parallel_reduce( const BlockedRange& range, Body& body )
+ {
+ body(range);
+ }
+#endif
+
+ // Returns a static string if there is a parallel framework,
+ // NULL otherwise.
+ CV_EXPORTS const char* currentParallelFramework();
+} //namespace cv
+
+/****************************************************************************************\
+* Common declarations *
+\****************************************************************************************/
+
+/* the alignment of all the allocated buffers */
+#define CV_MALLOC_ALIGN 16
+
+/* IEEE754 constants and macros */
+#define CV_TOGGLE_FLT(x) ((x)^((int)(x) < 0 ? 0x7fffffff : 0))
+#define CV_TOGGLE_DBL(x) ((x)^((int64)(x) < 0 ? CV_BIG_INT(0x7fffffffffffffff) : 0))
+
+static inline void* cvAlignPtr( const void* ptr, int align = 32 )
+{
+ CV_DbgAssert ( (align & (align-1)) == 0 );
+ return (void*)( ((size_t)ptr + align - 1) & ~(size_t)(align-1) );
+}
+
+static inline int cvAlign( int size, int align )
+{
+ CV_DbgAssert( (align & (align-1)) == 0 && size < INT_MAX );
+ return (size + align - 1) & -align;
+}
+
+#ifdef IPL_DEPTH_8U
+static inline cv::Size cvGetMatSize( const CvMat* mat )
+{
+ return cv::Size(mat->cols, mat->rows);
+}
+#endif
+
+namespace cv
+{
+CV_EXPORTS void scalarToRawData(const cv::Scalar& s, void* buf, int type, int unroll_to = 0);
+}
+
+// property implementation macros
+
+#define CV_IMPL_PROPERTY_RO(type, name, member) \
+ inline type get##name() const { return member; }
+
+#define CV_HELP_IMPL_PROPERTY(r_type, w_type, name, member) \
+ CV_IMPL_PROPERTY_RO(r_type, name, member) \
+ inline void set##name(w_type val) { member = val; }
+
+#define CV_HELP_WRAP_PROPERTY(r_type, w_type, name, internal_name, internal_obj) \
+ r_type get##name() const { return internal_obj.get##internal_name(); } \
+ void set##name(w_type val) { internal_obj.set##internal_name(val); }
+
+#define CV_IMPL_PROPERTY(type, name, member) CV_HELP_IMPL_PROPERTY(type, type, name, member)
+#define CV_IMPL_PROPERTY_S(type, name, member) CV_HELP_IMPL_PROPERTY(type, const type &, name, member)
+
+#define CV_WRAP_PROPERTY(type, name, internal_name, internal_obj) CV_HELP_WRAP_PROPERTY(type, type, name, internal_name, internal_obj)
+#define CV_WRAP_PROPERTY_S(type, name, internal_name, internal_obj) CV_HELP_WRAP_PROPERTY(type, const type &, name, internal_name, internal_obj)
+
+#define CV_WRAP_SAME_PROPERTY(type, name, internal_obj) CV_WRAP_PROPERTY(type, name, name, internal_obj)
+#define CV_WRAP_SAME_PROPERTY_S(type, name, internal_obj) CV_WRAP_PROPERTY_S(type, name, name, internal_obj)
+
+/****************************************************************************************\
+* Structures and macros for integration with IPP *
+\****************************************************************************************/
+
+#ifdef HAVE_IPP
+#include "ipp.h"
+
+#ifndef IPP_VERSION_UPDATE // prior to 7.1
+#define IPP_VERSION_UPDATE 0
+#endif
+
+#define IPP_VERSION_X100 (IPP_VERSION_MAJOR * 100 + IPP_VERSION_MINOR*10 + IPP_VERSION_UPDATE)
+
+// General define for ipp function disabling
+#define IPP_DISABLE_BLOCK 0
+
+#ifdef CV_MALLOC_ALIGN
+#undef CV_MALLOC_ALIGN
+#endif
+#define CV_MALLOC_ALIGN 32 // required for AVX optimization
+
+#define setIppErrorStatus() cv::ipp::setIppStatus(-1, CV_Func, __FILE__, __LINE__)
+
+static inline IppiSize ippiSize(int width, int height)
+{
+ IppiSize size = { width, height };
+ return size;
+}
+
+static inline IppiSize ippiSize(const cv::Size & _size)
+{
+ IppiSize size = { _size.width, _size.height };
+ return size;
+}
+
+static inline IppiPoint ippiPoint(const cv::Point & _point)
+{
+ IppiPoint point = { _point.x, _point.y };
+ return point;
+}
+
+static inline IppiPoint ippiPoint(int x, int y)
+{
+ IppiPoint point = { x, y };
+ return point;
+}
+
+static inline IppiBorderType ippiGetBorderType(int borderTypeNI)
+{
+ return borderTypeNI == cv::BORDER_CONSTANT ? ippBorderConst :
+ borderTypeNI == cv::BORDER_WRAP ? ippBorderWrap :
+ borderTypeNI == cv::BORDER_REPLICATE ? ippBorderRepl :
+ borderTypeNI == cv::BORDER_REFLECT_101 ? ippBorderMirror :
+ borderTypeNI == cv::BORDER_REFLECT ? ippBorderMirrorR : (IppiBorderType)-1;
+}
+
+static inline IppDataType ippiGetDataType(int depth)
+{
+ return depth == CV_8U ? ipp8u :
+ depth == CV_8S ? ipp8s :
+ depth == CV_16U ? ipp16u :
+ depth == CV_16S ? ipp16s :
+ depth == CV_32S ? ipp32s :
+ depth == CV_32F ? ipp32f :
+ depth == CV_64F ? ipp64f : (IppDataType)-1;
+}
+
+// IPP temporary buffer hepler
+template<typename T>
+class IppAutoBuffer
+{
+public:
+ IppAutoBuffer() { m_pBuffer = NULL; }
+ IppAutoBuffer(int size) { Alloc(size); }
+ ~IppAutoBuffer() { Release(); }
+ T* Alloc(int size) { m_pBuffer = (T*)ippMalloc(size); return m_pBuffer; }
+ void Release() { if(m_pBuffer) ippFree(m_pBuffer); }
+ inline operator T* () { return (T*)m_pBuffer;}
+ inline operator const T* () const { return (const T*)m_pBuffer;}
+private:
+ // Disable copy operations
+ IppAutoBuffer(IppAutoBuffer &) {}
+ IppAutoBuffer& operator =(const IppAutoBuffer &) {return *this;}
+
+ T* m_pBuffer;
+};
+
+#else
+#define IPP_VERSION_X100 0
+#endif
+
+#if defined HAVE_IPP
+#if IPP_VERSION_X100 >= 900
+#define IPP_INITIALIZER(FEAT) \
+{ \
+ if(FEAT) \
+ ippSetCpuFeatures(FEAT); \
+ else \
+ ippInit(); \
+}
+#elif IPP_VERSION_X100 >= 800
+#define IPP_INITIALIZER(FEAT) \
+{ \
+ ippInit(); \
+}
+#else
+#define IPP_INITIALIZER(FEAT) \
+{ \
+ ippStaticInit(); \
+}
+#endif
+
+#ifdef CVAPI_EXPORTS
+#define IPP_INITIALIZER_AUTO \
+struct __IppInitializer__ \
+{ \
+ __IppInitializer__() \
+ {IPP_INITIALIZER(cv::ipp::getIppFeatures())} \
+}; \
+static struct __IppInitializer__ __ipp_initializer__;
+#else
+#define IPP_INITIALIZER_AUTO
+#endif
+#else
+#define IPP_INITIALIZER
+#define IPP_INITIALIZER_AUTO
+#endif
+
+#define CV_IPP_CHECK_COND (cv::ipp::useIPP())
+#define CV_IPP_CHECK() if(CV_IPP_CHECK_COND)
+
+#ifdef HAVE_IPP
+
+#ifdef CV_IPP_RUN_VERBOSE
+#define CV_IPP_RUN_(condition, func, ...) \
+ { \
+ if (cv::ipp::useIPP() && (condition) && (func)) \
+ { \
+ printf("%s: IPP implementation is running\n", CV_Func); \
+ fflush(stdout); \
+ CV_IMPL_ADD(CV_IMPL_IPP); \
+ return __VA_ARGS__; \
+ } \
+ else \
+ { \
+ printf("%s: Plain implementation is running\n", CV_Func); \
+ fflush(stdout); \
+ } \
+ }
+#elif defined CV_IPP_RUN_ASSERT
+#define CV_IPP_RUN_(condition, func, ...) \
+ { \
+ if (cv::ipp::useIPP() && (condition)) \
+ { \
+ if(func) \
+ { \
+ CV_IMPL_ADD(CV_IMPL_IPP); \
+ } \
+ else \
+ { \
+ setIppErrorStatus(); \
+ CV_Error(cv::Error::StsAssert, #func); \
+ } \
+ return __VA_ARGS__; \
+ } \
+ }
+#else
+#define CV_IPP_RUN_(condition, func, ...) \
+ if (cv::ipp::useIPP() && (condition) && (func)) \
+ { \
+ CV_IMPL_ADD(CV_IMPL_IPP); \
+ return __VA_ARGS__; \
+ }
+#endif
+#define CV_IPP_RUN_FAST(func, ...) \
+ if (cv::ipp::useIPP() && (func)) \
+ { \
+ CV_IMPL_ADD(CV_IMPL_IPP); \
+ return __VA_ARGS__; \
+ }
+#else
+#define CV_IPP_RUN_(condition, func, ...)
+#define CV_IPP_RUN_FAST(func, ...)
+#endif
+
+#define CV_IPP_RUN(condition, func, ...) CV_IPP_RUN_((condition), (func), __VA_ARGS__)
+
+
+#ifndef IPPI_CALL
+# define IPPI_CALL(func) CV_Assert((func) >= 0)
+#endif
+
+/* IPP-compatible return codes */
+typedef enum CvStatus
+{
+ CV_BADMEMBLOCK_ERR = -113,
+ CV_INPLACE_NOT_SUPPORTED_ERR= -112,
+ CV_UNMATCHED_ROI_ERR = -111,
+ CV_NOTFOUND_ERR = -110,
+ CV_BADCONVERGENCE_ERR = -109,
+
+ CV_BADDEPTH_ERR = -107,
+ CV_BADROI_ERR = -106,
+ CV_BADHEADER_ERR = -105,
+ CV_UNMATCHED_FORMATS_ERR = -104,
+ CV_UNSUPPORTED_COI_ERR = -103,
+ CV_UNSUPPORTED_CHANNELS_ERR = -102,
+ CV_UNSUPPORTED_DEPTH_ERR = -101,
+ CV_UNSUPPORTED_FORMAT_ERR = -100,
+
+ CV_BADARG_ERR = -49, //ipp comp
+ CV_NOTDEFINED_ERR = -48, //ipp comp
+
+ CV_BADCHANNELS_ERR = -47, //ipp comp
+ CV_BADRANGE_ERR = -44, //ipp comp
+ CV_BADSTEP_ERR = -29, //ipp comp
+
+ CV_BADFLAG_ERR = -12,
+ CV_DIV_BY_ZERO_ERR = -11, //ipp comp
+ CV_BADCOEF_ERR = -10,
+
+ CV_BADFACTOR_ERR = -7,
+ CV_BADPOINT_ERR = -6,
+ CV_BADSCALE_ERR = -4,
+ CV_OUTOFMEM_ERR = -3,
+ CV_NULLPTR_ERR = -2,
+ CV_BADSIZE_ERR = -1,
+ CV_NO_ERR = 0,
+ CV_OK = CV_NO_ERR
+}
+CvStatus;
+
+#ifdef HAVE_TEGRA_OPTIMIZATION
+namespace tegra {
+
+CV_EXPORTS bool useTegra();
+CV_EXPORTS void setUseTegra(bool flag);
+
+}
+#endif
+
+#ifdef ENABLE_INSTRUMENTATION
+namespace cv
+{
+namespace instr
+{
+struct InstrTLSStruct
+{
+ InstrTLSStruct()
+ {
+ pCurrentNode = NULL;
+ }
+ InstrNode* pCurrentNode;
+};
+
+class InstrStruct
+{
+public:
+ InstrStruct()
+ {
+ useInstr = false;
+ flags = FLAGS_MAPPING;
+ maxDepth = 0;
+
+ rootNode.m_payload = NodeData("ROOT", NULL, 0, NULL, false, TYPE_GENERAL, IMPL_PLAIN);
+ tlsStruct.get()->pCurrentNode = &rootNode;
+ }
+
+ Mutex mutexCreate;
+ Mutex mutexCount;
+
+ bool useInstr;
+ int flags;
+ int maxDepth;
+ InstrNode rootNode;
+ TLSData<InstrTLSStruct> tlsStruct;
+};
+
+class CV_EXPORTS IntrumentationRegion
+{
+public:
+ IntrumentationRegion(const char* funName, const char* fileName, int lineNum, void *retAddress, bool alwaysExpand, TYPE instrType = TYPE_GENERAL, IMPL implType = IMPL_PLAIN);
+ ~IntrumentationRegion();
+
+private:
+ bool m_disabled; // region status
+ uint64 m_regionTicks;
+};
+
+CV_EXPORTS InstrStruct& getInstrumentStruct();
+InstrTLSStruct& getInstrumentTLSStruct();
+CV_EXPORTS InstrNode* getCurrentNode();
+}
+}
+
+#ifdef _WIN32
+#define CV_INSTRUMENT_GET_RETURN_ADDRESS _ReturnAddress()
+#else
+#define CV_INSTRUMENT_GET_RETURN_ADDRESS __builtin_extract_return_addr(__builtin_return_address(0))
+#endif
+
+// Instrument region
+#define CV_INSTRUMENT_REGION_META(NAME, ALWAYS_EXPAND, TYPE, IMPL) ::cv::instr::IntrumentationRegion __instr_region__(NAME, __FILE__, __LINE__, CV_INSTRUMENT_GET_RETURN_ADDRESS, ALWAYS_EXPAND, TYPE, IMPL);
+#define CV_INSTRUMENT_REGION_CUSTOM_META(NAME, ALWAYS_EXPAND, TYPE, IMPL)\
+ void *__curr_address__ = [&]() {return CV_INSTRUMENT_GET_RETURN_ADDRESS;}();\
+ ::cv::instr::IntrumentationRegion __instr_region__(NAME, __FILE__, __LINE__, __curr_address__, false, ::cv::instr::TYPE_GENERAL, ::cv::instr::IMPL_PLAIN);
+// Instrument functions with non-void return type
+#define CV_INSTRUMENT_FUN_RT_META(TYPE, IMPL, ERROR_COND, FUN, ...) ([&]()\
+{\
+ if(::cv::instr::useInstrumentation()){\
+ ::cv::instr::IntrumentationRegion __instr__(#FUN, __FILE__, __LINE__, NULL, false, TYPE, IMPL);\
+ try{\
+ auto status = ((FUN)(__VA_ARGS__));\
+ if(ERROR_COND){\
+ ::cv::instr::getCurrentNode()->m_payload.m_funError = true;\
+ CV_INSTRUMENT_MARK_META(IMPL, #FUN " - BadExit");\
+ }\
+ return status;\
+ }catch(...){\
+ ::cv::instr::getCurrentNode()->m_payload.m_funError = true;\
+ CV_INSTRUMENT_MARK_META(IMPL, #FUN " - BadExit");\
+ throw;\
+ }\
+ }else{\
+ return ((FUN)(__VA_ARGS__));\
+ }\
+}())
+// Instrument functions with void return type
+#define CV_INSTRUMENT_FUN_RV_META(TYPE, IMPL, FUN, ...) ([&]()\
+{\
+ if(::cv::instr::useInstrumentation()){\
+ ::cv::instr::IntrumentationRegion __instr__(#FUN, __FILE__, __LINE__, NULL, false, TYPE, IMPL);\
+ try{\
+ (FUN)(__VA_ARGS__);\
+ }catch(...){\
+ ::cv::instr::getCurrentNode()->m_payload.m_funError = true;\
+ CV_INSTRUMENT_MARK_META(IMPL, #FUN "- BadExit");\
+ throw;\
+ }\
+ }else{\
+ (FUN)(__VA_ARGS__);\
+ }\
+}())
+// Instrumentation information marker
+#define CV_INSTRUMENT_MARK_META(IMPL, NAME, ...) {::cv::instr::IntrumentationRegion __instr_mark__(NAME, __FILE__, __LINE__, NULL, false, ::cv::instr::TYPE_MARKER, IMPL);}
+
+///// General instrumentation
+// General OpenCV region instrumentation macro
+#define CV_INSTRUMENT_REGION() CV_INSTRUMENT_REGION_META(__FUNCTION__, false, ::cv::instr::TYPE_GENERAL, ::cv::instr::IMPL_PLAIN)
+// Custom OpenCV region instrumentation macro
+#define CV_INSTRUMENT_REGION_NAME(NAME) CV_INSTRUMENT_REGION_CUSTOM_META(NAME, false, ::cv::instr::TYPE_GENERAL, ::cv::instr::IMPL_PLAIN)
+// Instrumentation for parallel_for_ or other regions which forks and gathers threads
+#define CV_INSTRUMENT_REGION_MT_FORK() CV_INSTRUMENT_REGION_META(__FUNCTION__, true, ::cv::instr::TYPE_GENERAL, ::cv::instr::IMPL_PLAIN);
+
+///// IPP instrumentation
+// Wrapper region instrumentation macro
+#define CV_INSTRUMENT_REGION_IPP() CV_INSTRUMENT_REGION_META(__FUNCTION__, false, ::cv::instr::TYPE_WRAPPER, ::cv::instr::IMPL_IPP)
+// Function instrumentation macro
+#define CV_INSTRUMENT_FUN_IPP(FUN, ...) CV_INSTRUMENT_FUN_RT_META(::cv::instr::TYPE_FUN, ::cv::instr::IMPL_IPP, status < 0, FUN, __VA_ARGS__)
+// Diagnostic markers
+#define CV_INSTRUMENT_MARK_IPP(NAME) CV_INSTRUMENT_MARK_META(::cv::instr::IMPL_IPP, NAME)
+
+///// OpenCL instrumentation
+// Wrapper region instrumentation macro
+#define CV_INSTRUMENT_REGION_OPENCL() CV_INSTRUMENT_REGION_META(__FUNCTION__, false, ::cv::instr::TYPE_WRAPPER, ::cv::instr::IMPL_OPENCL)
+// OpenCL kernel compilation wrapper
+#define CV_INSTRUMENT_REGION_OPENCL_COMPILE(NAME) CV_INSTRUMENT_REGION_META(NAME, false, ::cv::instr::TYPE_WRAPPER, ::cv::instr::IMPL_OPENCL)
+// OpenCL kernel run wrapper
+#define CV_INSTRUMENT_REGION_OPENCL_RUN(NAME) CV_INSTRUMENT_REGION_META(NAME, false, ::cv::instr::TYPE_FUN, ::cv::instr::IMPL_OPENCL)
+// Diagnostic markers
+#define CV_INSTRUMENT_MARK_OPENCL(NAME) CV_INSTRUMENT_MARK_META(::cv::instr::IMPL_OPENCL, NAME)
+#else
+#define CV_INSTRUMENT_REGION_META(...)
+
+#define CV_INSTRUMENT_REGION()
+#define CV_INSTRUMENT_REGION_NAME(...)
+#define CV_INSTRUMENT_REGION_MT_FORK()
+
+#define CV_INSTRUMENT_REGION_IPP()
+#define CV_INSTRUMENT_FUN_IPP(FUN, ...) ((FUN)(__VA_ARGS__))
+#define CV_INSTRUMENT_MARK_IPP(...)
+
+#define CV_INSTRUMENT_REGION_OPENCL()
+#define CV_INSTRUMENT_REGION_OPENCL_COMPILE(...)
+#define CV_INSTRUMENT_REGION_OPENCL_RUN(...)
+#define CV_INSTRUMENT_MARK_OPENCL(...)
+#endif
+
+//! @endcond
+
+#endif // OPENCV_CORE_PRIVATE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/core/ptr.inl.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,379 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2013, NVIDIA Corporation, all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the copyright holders or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_CORE_PTR_INL_HPP
+#define OPENCV_CORE_PTR_INL_HPP
+
+#include <algorithm>
+
+//! @cond IGNORED
+
+namespace cv {
+
+template<typename Y>
+void DefaultDeleter<Y>::operator () (Y* p) const
+{
+ delete p;
+}
+
+namespace detail
+{
+
+struct PtrOwner
+{
+ PtrOwner() : refCount(1)
+ {}
+
+ void incRef()
+ {
+ CV_XADD(&refCount, 1);
+ }
+
+ void decRef()
+ {
+ if (CV_XADD(&refCount, -1) == 1) deleteSelf();
+ }
+
+protected:
+ /* This doesn't really need to be virtual, since PtrOwner is never deleted
+ directly, but it doesn't hurt and it helps avoid warnings. */
+ virtual ~PtrOwner()
+ {}
+
+ virtual void deleteSelf() = 0;
+
+private:
+ unsigned int refCount;
+
+ // noncopyable
+ PtrOwner(const PtrOwner&);
+ PtrOwner& operator = (const PtrOwner&);
+};
+
+template<typename Y, typename D>
+struct PtrOwnerImpl : PtrOwner
+{
+ PtrOwnerImpl(Y* p, D d) : owned(p), deleter(d)
+ {}
+
+ void deleteSelf()
+ {
+ deleter(owned);
+ delete this;
+ }
+
+private:
+ Y* owned;
+ D deleter;
+};
+
+
+}
+
+template<typename T>
+Ptr<T>::Ptr() : owner(NULL), stored(NULL)
+{}
+
+template<typename T>
+template<typename Y>
+Ptr<T>::Ptr(Y* p)
+ : owner(p
+ ? new detail::PtrOwnerImpl<Y, DefaultDeleter<Y> >(p, DefaultDeleter<Y>())
+ : NULL),
+ stored(p)
+{}
+
+template<typename T>
+template<typename Y, typename D>
+Ptr<T>::Ptr(Y* p, D d)
+ : owner(p
+ ? new detail::PtrOwnerImpl<Y, D>(p, d)
+ : NULL),
+ stored(p)
+{}
+
+template<typename T>
+Ptr<T>::Ptr(const Ptr& o) : owner(o.owner), stored(o.stored)
+{
+ if (owner) owner->incRef();
+}
+
+template<typename T>
+template<typename Y>
+Ptr<T>::Ptr(const Ptr<Y>& o) : owner(o.owner), stored(o.stored)
+{
+ if (owner) owner->incRef();
+}
+
+template<typename T>
+template<typename Y>
+Ptr<T>::Ptr(const Ptr<Y>& o, T* p) : owner(o.owner), stored(p)
+{
+ if (owner) owner->incRef();
+}
+
+template<typename T>
+Ptr<T>::~Ptr()
+{
+ release();
+}
+
+template<typename T>
+Ptr<T>& Ptr<T>::operator = (const Ptr<T>& o)
+{
+ Ptr(o).swap(*this);
+ return *this;
+}
+
+template<typename T>
+template<typename Y>
+Ptr<T>& Ptr<T>::operator = (const Ptr<Y>& o)
+{
+ Ptr(o).swap(*this);
+ return *this;
+}
+
+template<typename T>
+void Ptr<T>::release()
+{
+ if (owner) owner->decRef();
+ owner = NULL;
+ stored = NULL;
+}
+
+template<typename T>
+template<typename Y>
+void Ptr<T>::reset(Y* p)
+{
+ Ptr(p).swap(*this);
+}
+
+template<typename T>
+template<typename Y, typename D>
+void Ptr<T>::reset(Y* p, D d)
+{
+ Ptr(p, d).swap(*this);
+}
+
+template<typename T>
+void Ptr<T>::swap(Ptr<T>& o)
+{
+ std::swap(owner, o.owner);
+ std::swap(stored, o.stored);
+}
+
+template<typename T>
+T* Ptr<T>::get() const
+{
+ return stored;
+}
+
+template<typename T>
+typename detail::RefOrVoid<T>::type Ptr<T>::operator * () const
+{
+ return *stored;
+}
+
+template<typename T>
+T* Ptr<T>::operator -> () const
+{
+ return stored;
+}
+
+template<typename T>
+Ptr<T>::operator T* () const
+{
+ return stored;
+}
+
+
+template<typename T>
+bool Ptr<T>::empty() const
+{
+ return !stored;
+}
+
+template<typename T>
+template<typename Y>
+Ptr<Y> Ptr<T>::staticCast() const
+{
+ return Ptr<Y>(*this, static_cast<Y*>(stored));
+}
+
+template<typename T>
+template<typename Y>
+Ptr<Y> Ptr<T>::constCast() const
+{
+ return Ptr<Y>(*this, const_cast<Y*>(stored));
+}
+
+template<typename T>
+template<typename Y>
+Ptr<Y> Ptr<T>::dynamicCast() const
+{
+ return Ptr<Y>(*this, dynamic_cast<Y*>(stored));
+}
+
+#ifdef CV_CXX_MOVE_SEMANTICS
+
+template<typename T>
+Ptr<T>::Ptr(Ptr&& o) : owner(o.owner), stored(o.stored)
+{
+ o.owner = NULL;
+ o.stored = NULL;
+}
+
+template<typename T>
+Ptr<T>& Ptr<T>::operator = (Ptr<T>&& o)
+{
+ if (this == &o)
+ return *this;
+
+ release();
+ owner = o.owner;
+ stored = o.stored;
+ o.owner = NULL;
+ o.stored = NULL;
+ return *this;
+}
+
+#endif
+
+
+template<typename T>
+void swap(Ptr<T>& ptr1, Ptr<T>& ptr2){
+ ptr1.swap(ptr2);
+}
+
+template<typename T>
+bool operator == (const Ptr<T>& ptr1, const Ptr<T>& ptr2)
+{
+ return ptr1.get() == ptr2.get();
+}
+
+template<typename T>
+bool operator != (const Ptr<T>& ptr1, const Ptr<T>& ptr2)
+{
+ return ptr1.get() != ptr2.get();
+}
+
+template<typename T>
+Ptr<T> makePtr()
+{
+ return Ptr<T>(new T());
+}
+
+template<typename T, typename A1>
+Ptr<T> makePtr(const A1& a1)
+{
+ return Ptr<T>(new T(a1));
+}
+
+template<typename T, typename A1, typename A2>
+Ptr<T> makePtr(const A1& a1, const A2& a2)
+{
+ return Ptr<T>(new T(a1, a2));
+}
+
+template<typename T, typename A1, typename A2, typename A3>
+Ptr<T> makePtr(const A1& a1, const A2& a2, const A3& a3)
+{
+ return Ptr<T>(new T(a1, a2, a3));
+}
+
+template<typename T, typename A1, typename A2, typename A3, typename A4>
+Ptr<T> makePtr(const A1& a1, const A2& a2, const A3& a3, const A4& a4)
+{
+ return Ptr<T>(new T(a1, a2, a3, a4));
+}
+
+template<typename T, typename A1, typename A2, typename A3, typename A4, typename A5>
+Ptr<T> makePtr(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5)
+{
+ return Ptr<T>(new T(a1, a2, a3, a4, a5));
+}
+
+template<typename T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>
+Ptr<T> makePtr(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6)
+{
+ return Ptr<T>(new T(a1, a2, a3, a4, a5, a6));
+}
+
+template<typename T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>
+Ptr<T> makePtr(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7)
+{
+ return Ptr<T>(new T(a1, a2, a3, a4, a5, a6, a7));
+}
+
+template<typename T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8>
+Ptr<T> makePtr(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8)
+{
+ return Ptr<T>(new T(a1, a2, a3, a4, a5, a6, a7, a8));
+}
+
+template<typename T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9>
+Ptr<T> makePtr(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9)
+{
+ return Ptr<T>(new T(a1, a2, a3, a4, a5, a6, a7, a8, a9));
+}
+
+template<typename T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10>
+Ptr<T> makePtr(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9, const A10& a10)
+{
+ return Ptr<T>(new T(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10));
+}
+
+template<typename T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11>
+Ptr<T> makePtr(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9, const A10& a10, const A11& a11)
+{
+ return Ptr<T>(new T(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11));
+}
+
+template<typename T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename A12>
+Ptr<T> makePtr(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9, const A10& a10, const A11& a11, const A12& a12)
+{
+ return Ptr<T>(new T(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12));
+}
+} // namespace cv
+
+//! @endcond
+
+#endif // OPENCV_CORE_PTR_INL_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/core/saturate.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,150 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
+// Copyright (C) 2014, Itseez Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_CORE_SATURATE_HPP
+#define OPENCV_CORE_SATURATE_HPP
+
+#include "opencv2/core/cvdef.h"
+#include "opencv2/core/fast_math.hpp"
+
+namespace cv
+{
+
+//! @addtogroup core_utils
+//! @{
+
+/////////////// saturate_cast (used in image & signal processing) ///////////////////
+
+/** @brief Template function for accurate conversion from one primitive type to another.
+
+ The functions saturate_cast resemble the standard C++ cast operations, such as static_cast\<T\>()
+ and others. They perform an efficient and accurate conversion from one primitive type to another
+ (see the introduction chapter). saturate in the name means that when the input value v is out of the
+ range of the target type, the result is not formed just by taking low bits of the input, but instead
+ the value is clipped. For example:
+ @code
+ uchar a = saturate_cast<uchar>(-100); // a = 0 (UCHAR_MIN)
+ short b = saturate_cast<short>(33333.33333); // b = 32767 (SHRT_MAX)
+ @endcode
+ Such clipping is done when the target type is unsigned char , signed char , unsigned short or
+ signed short . For 32-bit integers, no clipping is done.
+
+ When the parameter is a floating-point value and the target type is an integer (8-, 16- or 32-bit),
+ the floating-point value is first rounded to the nearest integer and then clipped if needed (when
+ the target type is 8- or 16-bit).
+
+ This operation is used in the simplest or most complex image processing functions in OpenCV.
+
+ @param v Function parameter.
+ @sa add, subtract, multiply, divide, Mat::convertTo
+ */
+template<typename _Tp> static inline _Tp saturate_cast(uchar v) { return _Tp(v); }
+/** @overload */
+template<typename _Tp> static inline _Tp saturate_cast(schar v) { return _Tp(v); }
+/** @overload */
+template<typename _Tp> static inline _Tp saturate_cast(ushort v) { return _Tp(v); }
+/** @overload */
+template<typename _Tp> static inline _Tp saturate_cast(short v) { return _Tp(v); }
+/** @overload */
+template<typename _Tp> static inline _Tp saturate_cast(unsigned v) { return _Tp(v); }
+/** @overload */
+template<typename _Tp> static inline _Tp saturate_cast(int v) { return _Tp(v); }
+/** @overload */
+template<typename _Tp> static inline _Tp saturate_cast(float v) { return _Tp(v); }
+/** @overload */
+template<typename _Tp> static inline _Tp saturate_cast(double v) { return _Tp(v); }
+/** @overload */
+template<typename _Tp> static inline _Tp saturate_cast(int64 v) { return _Tp(v); }
+/** @overload */
+template<typename _Tp> static inline _Tp saturate_cast(uint64 v) { return _Tp(v); }
+
+template<> inline uchar saturate_cast<uchar>(schar v) { return (uchar)std::max((int)v, 0); }
+template<> inline uchar saturate_cast<uchar>(ushort v) { return (uchar)std::min((unsigned)v, (unsigned)UCHAR_MAX); }
+template<> inline uchar saturate_cast<uchar>(int v) { return (uchar)((unsigned)v <= UCHAR_MAX ? v : v > 0 ? UCHAR_MAX : 0); }
+template<> inline uchar saturate_cast<uchar>(short v) { return saturate_cast<uchar>((int)v); }
+template<> inline uchar saturate_cast<uchar>(unsigned v) { return (uchar)std::min(v, (unsigned)UCHAR_MAX); }
+template<> inline uchar saturate_cast<uchar>(float v) { int iv = cvRound(v); return saturate_cast<uchar>(iv); }
+template<> inline uchar saturate_cast<uchar>(double v) { int iv = cvRound(v); return saturate_cast<uchar>(iv); }
+template<> inline uchar saturate_cast<uchar>(int64 v) { return (uchar)((uint64)v <= (uint64)UCHAR_MAX ? v : v > 0 ? UCHAR_MAX : 0); }
+template<> inline uchar saturate_cast<uchar>(uint64 v) { return (uchar)std::min(v, (uint64)UCHAR_MAX); }
+
+template<> inline schar saturate_cast<schar>(uchar v) { return (schar)std::min((int)v, SCHAR_MAX); }
+template<> inline schar saturate_cast<schar>(ushort v) { return (schar)std::min((unsigned)v, (unsigned)SCHAR_MAX); }
+template<> inline schar saturate_cast<schar>(int v) { return (schar)((unsigned)(v-SCHAR_MIN) <= (unsigned)UCHAR_MAX ? v : v > 0 ? SCHAR_MAX : SCHAR_MIN); }
+template<> inline schar saturate_cast<schar>(short v) { return saturate_cast<schar>((int)v); }
+template<> inline schar saturate_cast<schar>(unsigned v) { return (schar)std::min(v, (unsigned)SCHAR_MAX); }
+template<> inline schar saturate_cast<schar>(float v) { int iv = cvRound(v); return saturate_cast<schar>(iv); }
+template<> inline schar saturate_cast<schar>(double v) { int iv = cvRound(v); return saturate_cast<schar>(iv); }
+template<> inline schar saturate_cast<schar>(int64 v) { return (schar)((uint64)((int64)v-SCHAR_MIN) <= (uint64)UCHAR_MAX ? v : v > 0 ? SCHAR_MAX : SCHAR_MIN); }
+template<> inline schar saturate_cast<schar>(uint64 v) { return (schar)std::min(v, (uint64)SCHAR_MAX); }
+
+template<> inline ushort saturate_cast<ushort>(schar v) { return (ushort)std::max((int)v, 0); }
+template<> inline ushort saturate_cast<ushort>(short v) { return (ushort)std::max((int)v, 0); }
+template<> inline ushort saturate_cast<ushort>(int v) { return (ushort)((unsigned)v <= (unsigned)USHRT_MAX ? v : v > 0 ? USHRT_MAX : 0); }
+template<> inline ushort saturate_cast<ushort>(unsigned v) { return (ushort)std::min(v, (unsigned)USHRT_MAX); }
+template<> inline ushort saturate_cast<ushort>(float v) { int iv = cvRound(v); return saturate_cast<ushort>(iv); }
+template<> inline ushort saturate_cast<ushort>(double v) { int iv = cvRound(v); return saturate_cast<ushort>(iv); }
+template<> inline ushort saturate_cast<ushort>(int64 v) { return (ushort)((uint64)v <= (uint64)USHRT_MAX ? v : v > 0 ? USHRT_MAX : 0); }
+template<> inline ushort saturate_cast<ushort>(uint64 v) { return (ushort)std::min(v, (uint64)USHRT_MAX); }
+
+template<> inline short saturate_cast<short>(ushort v) { return (short)std::min((int)v, SHRT_MAX); }
+template<> inline short saturate_cast<short>(int v) { return (short)((unsigned)(v - SHRT_MIN) <= (unsigned)USHRT_MAX ? v : v > 0 ? SHRT_MAX : SHRT_MIN); }
+template<> inline short saturate_cast<short>(unsigned v) { return (short)std::min(v, (unsigned)SHRT_MAX); }
+template<> inline short saturate_cast<short>(float v) { int iv = cvRound(v); return saturate_cast<short>(iv); }
+template<> inline short saturate_cast<short>(double v) { int iv = cvRound(v); return saturate_cast<short>(iv); }
+template<> inline short saturate_cast<short>(int64 v) { return (short)((uint64)((int64)v - SHRT_MIN) <= (uint64)USHRT_MAX ? v : v > 0 ? SHRT_MAX : SHRT_MIN); }
+template<> inline short saturate_cast<short>(uint64 v) { return (short)std::min(v, (uint64)SHRT_MAX); }
+
+template<> inline int saturate_cast<int>(float v) { return cvRound(v); }
+template<> inline int saturate_cast<int>(double v) { return cvRound(v); }
+
+// we intentionally do not clip negative numbers, to make -1 become 0xffffffff etc.
+template<> inline unsigned saturate_cast<unsigned>(float v) { return cvRound(v); }
+template<> inline unsigned saturate_cast<unsigned>(double v) { return cvRound(v); }
+
+//! @}
+
+} // cv
+
+#endif // OPENCV_CORE_SATURATE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/core/sse_utils.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,652 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2015, Itseez Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_CORE_SSE_UTILS_HPP
+#define OPENCV_CORE_SSE_UTILS_HPP
+
+#ifndef __cplusplus
+# error sse_utils.hpp header must be compiled as C++
+#endif
+
+#include "opencv2/core/cvdef.h"
+
+//! @addtogroup core_utils_sse
+//! @{
+
+#if CV_SSE2
+
+inline void _mm_deinterleave_epi8(__m128i & v_r0, __m128i & v_r1, __m128i & v_g0, __m128i & v_g1)
+{
+ __m128i layer1_chunk0 = _mm_unpacklo_epi8(v_r0, v_g0);
+ __m128i layer1_chunk1 = _mm_unpackhi_epi8(v_r0, v_g0);
+ __m128i layer1_chunk2 = _mm_unpacklo_epi8(v_r1, v_g1);
+ __m128i layer1_chunk3 = _mm_unpackhi_epi8(v_r1, v_g1);
+
+ __m128i layer2_chunk0 = _mm_unpacklo_epi8(layer1_chunk0, layer1_chunk2);
+ __m128i layer2_chunk1 = _mm_unpackhi_epi8(layer1_chunk0, layer1_chunk2);
+ __m128i layer2_chunk2 = _mm_unpacklo_epi8(layer1_chunk1, layer1_chunk3);
+ __m128i layer2_chunk3 = _mm_unpackhi_epi8(layer1_chunk1, layer1_chunk3);
+
+ __m128i layer3_chunk0 = _mm_unpacklo_epi8(layer2_chunk0, layer2_chunk2);
+ __m128i layer3_chunk1 = _mm_unpackhi_epi8(layer2_chunk0, layer2_chunk2);
+ __m128i layer3_chunk2 = _mm_unpacklo_epi8(layer2_chunk1, layer2_chunk3);
+ __m128i layer3_chunk3 = _mm_unpackhi_epi8(layer2_chunk1, layer2_chunk3);
+
+ __m128i layer4_chunk0 = _mm_unpacklo_epi8(layer3_chunk0, layer3_chunk2);
+ __m128i layer4_chunk1 = _mm_unpackhi_epi8(layer3_chunk0, layer3_chunk2);
+ __m128i layer4_chunk2 = _mm_unpacklo_epi8(layer3_chunk1, layer3_chunk3);
+ __m128i layer4_chunk3 = _mm_unpackhi_epi8(layer3_chunk1, layer3_chunk3);
+
+ v_r0 = _mm_unpacklo_epi8(layer4_chunk0, layer4_chunk2);
+ v_r1 = _mm_unpackhi_epi8(layer4_chunk0, layer4_chunk2);
+ v_g0 = _mm_unpacklo_epi8(layer4_chunk1, layer4_chunk3);
+ v_g1 = _mm_unpackhi_epi8(layer4_chunk1, layer4_chunk3);
+}
+
+inline void _mm_deinterleave_epi8(__m128i & v_r0, __m128i & v_r1, __m128i & v_g0,
+ __m128i & v_g1, __m128i & v_b0, __m128i & v_b1)
+{
+ __m128i layer1_chunk0 = _mm_unpacklo_epi8(v_r0, v_g1);
+ __m128i layer1_chunk1 = _mm_unpackhi_epi8(v_r0, v_g1);
+ __m128i layer1_chunk2 = _mm_unpacklo_epi8(v_r1, v_b0);
+ __m128i layer1_chunk3 = _mm_unpackhi_epi8(v_r1, v_b0);
+ __m128i layer1_chunk4 = _mm_unpacklo_epi8(v_g0, v_b1);
+ __m128i layer1_chunk5 = _mm_unpackhi_epi8(v_g0, v_b1);
+
+ __m128i layer2_chunk0 = _mm_unpacklo_epi8(layer1_chunk0, layer1_chunk3);
+ __m128i layer2_chunk1 = _mm_unpackhi_epi8(layer1_chunk0, layer1_chunk3);
+ __m128i layer2_chunk2 = _mm_unpacklo_epi8(layer1_chunk1, layer1_chunk4);
+ __m128i layer2_chunk3 = _mm_unpackhi_epi8(layer1_chunk1, layer1_chunk4);
+ __m128i layer2_chunk4 = _mm_unpacklo_epi8(layer1_chunk2, layer1_chunk5);
+ __m128i layer2_chunk5 = _mm_unpackhi_epi8(layer1_chunk2, layer1_chunk5);
+
+ __m128i layer3_chunk0 = _mm_unpacklo_epi8(layer2_chunk0, layer2_chunk3);
+ __m128i layer3_chunk1 = _mm_unpackhi_epi8(layer2_chunk0, layer2_chunk3);
+ __m128i layer3_chunk2 = _mm_unpacklo_epi8(layer2_chunk1, layer2_chunk4);
+ __m128i layer3_chunk3 = _mm_unpackhi_epi8(layer2_chunk1, layer2_chunk4);
+ __m128i layer3_chunk4 = _mm_unpacklo_epi8(layer2_chunk2, layer2_chunk5);
+ __m128i layer3_chunk5 = _mm_unpackhi_epi8(layer2_chunk2, layer2_chunk5);
+
+ __m128i layer4_chunk0 = _mm_unpacklo_epi8(layer3_chunk0, layer3_chunk3);
+ __m128i layer4_chunk1 = _mm_unpackhi_epi8(layer3_chunk0, layer3_chunk3);
+ __m128i layer4_chunk2 = _mm_unpacklo_epi8(layer3_chunk1, layer3_chunk4);
+ __m128i layer4_chunk3 = _mm_unpackhi_epi8(layer3_chunk1, layer3_chunk4);
+ __m128i layer4_chunk4 = _mm_unpacklo_epi8(layer3_chunk2, layer3_chunk5);
+ __m128i layer4_chunk5 = _mm_unpackhi_epi8(layer3_chunk2, layer3_chunk5);
+
+ v_r0 = _mm_unpacklo_epi8(layer4_chunk0, layer4_chunk3);
+ v_r1 = _mm_unpackhi_epi8(layer4_chunk0, layer4_chunk3);
+ v_g0 = _mm_unpacklo_epi8(layer4_chunk1, layer4_chunk4);
+ v_g1 = _mm_unpackhi_epi8(layer4_chunk1, layer4_chunk4);
+ v_b0 = _mm_unpacklo_epi8(layer4_chunk2, layer4_chunk5);
+ v_b1 = _mm_unpackhi_epi8(layer4_chunk2, layer4_chunk5);
+}
+
+inline void _mm_deinterleave_epi8(__m128i & v_r0, __m128i & v_r1, __m128i & v_g0, __m128i & v_g1,
+ __m128i & v_b0, __m128i & v_b1, __m128i & v_a0, __m128i & v_a1)
+{
+ __m128i layer1_chunk0 = _mm_unpacklo_epi8(v_r0, v_b0);
+ __m128i layer1_chunk1 = _mm_unpackhi_epi8(v_r0, v_b0);
+ __m128i layer1_chunk2 = _mm_unpacklo_epi8(v_r1, v_b1);
+ __m128i layer1_chunk3 = _mm_unpackhi_epi8(v_r1, v_b1);
+ __m128i layer1_chunk4 = _mm_unpacklo_epi8(v_g0, v_a0);
+ __m128i layer1_chunk5 = _mm_unpackhi_epi8(v_g0, v_a0);
+ __m128i layer1_chunk6 = _mm_unpacklo_epi8(v_g1, v_a1);
+ __m128i layer1_chunk7 = _mm_unpackhi_epi8(v_g1, v_a1);
+
+ __m128i layer2_chunk0 = _mm_unpacklo_epi8(layer1_chunk0, layer1_chunk4);
+ __m128i layer2_chunk1 = _mm_unpackhi_epi8(layer1_chunk0, layer1_chunk4);
+ __m128i layer2_chunk2 = _mm_unpacklo_epi8(layer1_chunk1, layer1_chunk5);
+ __m128i layer2_chunk3 = _mm_unpackhi_epi8(layer1_chunk1, layer1_chunk5);
+ __m128i layer2_chunk4 = _mm_unpacklo_epi8(layer1_chunk2, layer1_chunk6);
+ __m128i layer2_chunk5 = _mm_unpackhi_epi8(layer1_chunk2, layer1_chunk6);
+ __m128i layer2_chunk6 = _mm_unpacklo_epi8(layer1_chunk3, layer1_chunk7);
+ __m128i layer2_chunk7 = _mm_unpackhi_epi8(layer1_chunk3, layer1_chunk7);
+
+ __m128i layer3_chunk0 = _mm_unpacklo_epi8(layer2_chunk0, layer2_chunk4);
+ __m128i layer3_chunk1 = _mm_unpackhi_epi8(layer2_chunk0, layer2_chunk4);
+ __m128i layer3_chunk2 = _mm_unpacklo_epi8(layer2_chunk1, layer2_chunk5);
+ __m128i layer3_chunk3 = _mm_unpackhi_epi8(layer2_chunk1, layer2_chunk5);
+ __m128i layer3_chunk4 = _mm_unpacklo_epi8(layer2_chunk2, layer2_chunk6);
+ __m128i layer3_chunk5 = _mm_unpackhi_epi8(layer2_chunk2, layer2_chunk6);
+ __m128i layer3_chunk6 = _mm_unpacklo_epi8(layer2_chunk3, layer2_chunk7);
+ __m128i layer3_chunk7 = _mm_unpackhi_epi8(layer2_chunk3, layer2_chunk7);
+
+ __m128i layer4_chunk0 = _mm_unpacklo_epi8(layer3_chunk0, layer3_chunk4);
+ __m128i layer4_chunk1 = _mm_unpackhi_epi8(layer3_chunk0, layer3_chunk4);
+ __m128i layer4_chunk2 = _mm_unpacklo_epi8(layer3_chunk1, layer3_chunk5);
+ __m128i layer4_chunk3 = _mm_unpackhi_epi8(layer3_chunk1, layer3_chunk5);
+ __m128i layer4_chunk4 = _mm_unpacklo_epi8(layer3_chunk2, layer3_chunk6);
+ __m128i layer4_chunk5 = _mm_unpackhi_epi8(layer3_chunk2, layer3_chunk6);
+ __m128i layer4_chunk6 = _mm_unpacklo_epi8(layer3_chunk3, layer3_chunk7);
+ __m128i layer4_chunk7 = _mm_unpackhi_epi8(layer3_chunk3, layer3_chunk7);
+
+ v_r0 = _mm_unpacklo_epi8(layer4_chunk0, layer4_chunk4);
+ v_r1 = _mm_unpackhi_epi8(layer4_chunk0, layer4_chunk4);
+ v_g0 = _mm_unpacklo_epi8(layer4_chunk1, layer4_chunk5);
+ v_g1 = _mm_unpackhi_epi8(layer4_chunk1, layer4_chunk5);
+ v_b0 = _mm_unpacklo_epi8(layer4_chunk2, layer4_chunk6);
+ v_b1 = _mm_unpackhi_epi8(layer4_chunk2, layer4_chunk6);
+ v_a0 = _mm_unpacklo_epi8(layer4_chunk3, layer4_chunk7);
+ v_a1 = _mm_unpackhi_epi8(layer4_chunk3, layer4_chunk7);
+}
+
+inline void _mm_interleave_epi8(__m128i & v_r0, __m128i & v_r1, __m128i & v_g0, __m128i & v_g1)
+{
+ __m128i v_mask = _mm_set1_epi16(0x00ff);
+
+ __m128i layer4_chunk0 = _mm_packus_epi16(_mm_and_si128(v_r0, v_mask), _mm_and_si128(v_r1, v_mask));
+ __m128i layer4_chunk2 = _mm_packus_epi16(_mm_srli_epi16(v_r0, 8), _mm_srli_epi16(v_r1, 8));
+ __m128i layer4_chunk1 = _mm_packus_epi16(_mm_and_si128(v_g0, v_mask), _mm_and_si128(v_g1, v_mask));
+ __m128i layer4_chunk3 = _mm_packus_epi16(_mm_srli_epi16(v_g0, 8), _mm_srli_epi16(v_g1, 8));
+
+ __m128i layer3_chunk0 = _mm_packus_epi16(_mm_and_si128(layer4_chunk0, v_mask), _mm_and_si128(layer4_chunk1, v_mask));
+ __m128i layer3_chunk2 = _mm_packus_epi16(_mm_srli_epi16(layer4_chunk0, 8), _mm_srli_epi16(layer4_chunk1, 8));
+ __m128i layer3_chunk1 = _mm_packus_epi16(_mm_and_si128(layer4_chunk2, v_mask), _mm_and_si128(layer4_chunk3, v_mask));
+ __m128i layer3_chunk3 = _mm_packus_epi16(_mm_srli_epi16(layer4_chunk2, 8), _mm_srli_epi16(layer4_chunk3, 8));
+
+ __m128i layer2_chunk0 = _mm_packus_epi16(_mm_and_si128(layer3_chunk0, v_mask), _mm_and_si128(layer3_chunk1, v_mask));
+ __m128i layer2_chunk2 = _mm_packus_epi16(_mm_srli_epi16(layer3_chunk0, 8), _mm_srli_epi16(layer3_chunk1, 8));
+ __m128i layer2_chunk1 = _mm_packus_epi16(_mm_and_si128(layer3_chunk2, v_mask), _mm_and_si128(layer3_chunk3, v_mask));
+ __m128i layer2_chunk3 = _mm_packus_epi16(_mm_srli_epi16(layer3_chunk2, 8), _mm_srli_epi16(layer3_chunk3, 8));
+
+ __m128i layer1_chunk0 = _mm_packus_epi16(_mm_and_si128(layer2_chunk0, v_mask), _mm_and_si128(layer2_chunk1, v_mask));
+ __m128i layer1_chunk2 = _mm_packus_epi16(_mm_srli_epi16(layer2_chunk0, 8), _mm_srli_epi16(layer2_chunk1, 8));
+ __m128i layer1_chunk1 = _mm_packus_epi16(_mm_and_si128(layer2_chunk2, v_mask), _mm_and_si128(layer2_chunk3, v_mask));
+ __m128i layer1_chunk3 = _mm_packus_epi16(_mm_srli_epi16(layer2_chunk2, 8), _mm_srli_epi16(layer2_chunk3, 8));
+
+ v_r0 = _mm_packus_epi16(_mm_and_si128(layer1_chunk0, v_mask), _mm_and_si128(layer1_chunk1, v_mask));
+ v_g0 = _mm_packus_epi16(_mm_srli_epi16(layer1_chunk0, 8), _mm_srli_epi16(layer1_chunk1, 8));
+ v_r1 = _mm_packus_epi16(_mm_and_si128(layer1_chunk2, v_mask), _mm_and_si128(layer1_chunk3, v_mask));
+ v_g1 = _mm_packus_epi16(_mm_srli_epi16(layer1_chunk2, 8), _mm_srli_epi16(layer1_chunk3, 8));
+}
+
+inline void _mm_interleave_epi8(__m128i & v_r0, __m128i & v_r1, __m128i & v_g0,
+ __m128i & v_g1, __m128i & v_b0, __m128i & v_b1)
+{
+ __m128i v_mask = _mm_set1_epi16(0x00ff);
+
+ __m128i layer4_chunk0 = _mm_packus_epi16(_mm_and_si128(v_r0, v_mask), _mm_and_si128(v_r1, v_mask));
+ __m128i layer4_chunk3 = _mm_packus_epi16(_mm_srli_epi16(v_r0, 8), _mm_srli_epi16(v_r1, 8));
+ __m128i layer4_chunk1 = _mm_packus_epi16(_mm_and_si128(v_g0, v_mask), _mm_and_si128(v_g1, v_mask));
+ __m128i layer4_chunk4 = _mm_packus_epi16(_mm_srli_epi16(v_g0, 8), _mm_srli_epi16(v_g1, 8));
+ __m128i layer4_chunk2 = _mm_packus_epi16(_mm_and_si128(v_b0, v_mask), _mm_and_si128(v_b1, v_mask));
+ __m128i layer4_chunk5 = _mm_packus_epi16(_mm_srli_epi16(v_b0, 8), _mm_srli_epi16(v_b1, 8));
+
+ __m128i layer3_chunk0 = _mm_packus_epi16(_mm_and_si128(layer4_chunk0, v_mask), _mm_and_si128(layer4_chunk1, v_mask));
+ __m128i layer3_chunk3 = _mm_packus_epi16(_mm_srli_epi16(layer4_chunk0, 8), _mm_srli_epi16(layer4_chunk1, 8));
+ __m128i layer3_chunk1 = _mm_packus_epi16(_mm_and_si128(layer4_chunk2, v_mask), _mm_and_si128(layer4_chunk3, v_mask));
+ __m128i layer3_chunk4 = _mm_packus_epi16(_mm_srli_epi16(layer4_chunk2, 8), _mm_srli_epi16(layer4_chunk3, 8));
+ __m128i layer3_chunk2 = _mm_packus_epi16(_mm_and_si128(layer4_chunk4, v_mask), _mm_and_si128(layer4_chunk5, v_mask));
+ __m128i layer3_chunk5 = _mm_packus_epi16(_mm_srli_epi16(layer4_chunk4, 8), _mm_srli_epi16(layer4_chunk5, 8));
+
+ __m128i layer2_chunk0 = _mm_packus_epi16(_mm_and_si128(layer3_chunk0, v_mask), _mm_and_si128(layer3_chunk1, v_mask));
+ __m128i layer2_chunk3 = _mm_packus_epi16(_mm_srli_epi16(layer3_chunk0, 8), _mm_srli_epi16(layer3_chunk1, 8));
+ __m128i layer2_chunk1 = _mm_packus_epi16(_mm_and_si128(layer3_chunk2, v_mask), _mm_and_si128(layer3_chunk3, v_mask));
+ __m128i layer2_chunk4 = _mm_packus_epi16(_mm_srli_epi16(layer3_chunk2, 8), _mm_srli_epi16(layer3_chunk3, 8));
+ __m128i layer2_chunk2 = _mm_packus_epi16(_mm_and_si128(layer3_chunk4, v_mask), _mm_and_si128(layer3_chunk5, v_mask));
+ __m128i layer2_chunk5 = _mm_packus_epi16(_mm_srli_epi16(layer3_chunk4, 8), _mm_srli_epi16(layer3_chunk5, 8));
+
+ __m128i layer1_chunk0 = _mm_packus_epi16(_mm_and_si128(layer2_chunk0, v_mask), _mm_and_si128(layer2_chunk1, v_mask));
+ __m128i layer1_chunk3 = _mm_packus_epi16(_mm_srli_epi16(layer2_chunk0, 8), _mm_srli_epi16(layer2_chunk1, 8));
+ __m128i layer1_chunk1 = _mm_packus_epi16(_mm_and_si128(layer2_chunk2, v_mask), _mm_and_si128(layer2_chunk3, v_mask));
+ __m128i layer1_chunk4 = _mm_packus_epi16(_mm_srli_epi16(layer2_chunk2, 8), _mm_srli_epi16(layer2_chunk3, 8));
+ __m128i layer1_chunk2 = _mm_packus_epi16(_mm_and_si128(layer2_chunk4, v_mask), _mm_and_si128(layer2_chunk5, v_mask));
+ __m128i layer1_chunk5 = _mm_packus_epi16(_mm_srli_epi16(layer2_chunk4, 8), _mm_srli_epi16(layer2_chunk5, 8));
+
+ v_r0 = _mm_packus_epi16(_mm_and_si128(layer1_chunk0, v_mask), _mm_and_si128(layer1_chunk1, v_mask));
+ v_g1 = _mm_packus_epi16(_mm_srli_epi16(layer1_chunk0, 8), _mm_srli_epi16(layer1_chunk1, 8));
+ v_r1 = _mm_packus_epi16(_mm_and_si128(layer1_chunk2, v_mask), _mm_and_si128(layer1_chunk3, v_mask));
+ v_b0 = _mm_packus_epi16(_mm_srli_epi16(layer1_chunk2, 8), _mm_srli_epi16(layer1_chunk3, 8));
+ v_g0 = _mm_packus_epi16(_mm_and_si128(layer1_chunk4, v_mask), _mm_and_si128(layer1_chunk5, v_mask));
+ v_b1 = _mm_packus_epi16(_mm_srli_epi16(layer1_chunk4, 8), _mm_srli_epi16(layer1_chunk5, 8));
+}
+
+inline void _mm_interleave_epi8(__m128i & v_r0, __m128i & v_r1, __m128i & v_g0, __m128i & v_g1,
+ __m128i & v_b0, __m128i & v_b1, __m128i & v_a0, __m128i & v_a1)
+{
+ __m128i v_mask = _mm_set1_epi16(0x00ff);
+
+ __m128i layer4_chunk0 = _mm_packus_epi16(_mm_and_si128(v_r0, v_mask), _mm_and_si128(v_r1, v_mask));
+ __m128i layer4_chunk4 = _mm_packus_epi16(_mm_srli_epi16(v_r0, 8), _mm_srli_epi16(v_r1, 8));
+ __m128i layer4_chunk1 = _mm_packus_epi16(_mm_and_si128(v_g0, v_mask), _mm_and_si128(v_g1, v_mask));
+ __m128i layer4_chunk5 = _mm_packus_epi16(_mm_srli_epi16(v_g0, 8), _mm_srli_epi16(v_g1, 8));
+ __m128i layer4_chunk2 = _mm_packus_epi16(_mm_and_si128(v_b0, v_mask), _mm_and_si128(v_b1, v_mask));
+ __m128i layer4_chunk6 = _mm_packus_epi16(_mm_srli_epi16(v_b0, 8), _mm_srli_epi16(v_b1, 8));
+ __m128i layer4_chunk3 = _mm_packus_epi16(_mm_and_si128(v_a0, v_mask), _mm_and_si128(v_a1, v_mask));
+ __m128i layer4_chunk7 = _mm_packus_epi16(_mm_srli_epi16(v_a0, 8), _mm_srli_epi16(v_a1, 8));
+
+ __m128i layer3_chunk0 = _mm_packus_epi16(_mm_and_si128(layer4_chunk0, v_mask), _mm_and_si128(layer4_chunk1, v_mask));
+ __m128i layer3_chunk4 = _mm_packus_epi16(_mm_srli_epi16(layer4_chunk0, 8), _mm_srli_epi16(layer4_chunk1, 8));
+ __m128i layer3_chunk1 = _mm_packus_epi16(_mm_and_si128(layer4_chunk2, v_mask), _mm_and_si128(layer4_chunk3, v_mask));
+ __m128i layer3_chunk5 = _mm_packus_epi16(_mm_srli_epi16(layer4_chunk2, 8), _mm_srli_epi16(layer4_chunk3, 8));
+ __m128i layer3_chunk2 = _mm_packus_epi16(_mm_and_si128(layer4_chunk4, v_mask), _mm_and_si128(layer4_chunk5, v_mask));
+ __m128i layer3_chunk6 = _mm_packus_epi16(_mm_srli_epi16(layer4_chunk4, 8), _mm_srli_epi16(layer4_chunk5, 8));
+ __m128i layer3_chunk3 = _mm_packus_epi16(_mm_and_si128(layer4_chunk6, v_mask), _mm_and_si128(layer4_chunk7, v_mask));
+ __m128i layer3_chunk7 = _mm_packus_epi16(_mm_srli_epi16(layer4_chunk6, 8), _mm_srli_epi16(layer4_chunk7, 8));
+
+ __m128i layer2_chunk0 = _mm_packus_epi16(_mm_and_si128(layer3_chunk0, v_mask), _mm_and_si128(layer3_chunk1, v_mask));
+ __m128i layer2_chunk4 = _mm_packus_epi16(_mm_srli_epi16(layer3_chunk0, 8), _mm_srli_epi16(layer3_chunk1, 8));
+ __m128i layer2_chunk1 = _mm_packus_epi16(_mm_and_si128(layer3_chunk2, v_mask), _mm_and_si128(layer3_chunk3, v_mask));
+ __m128i layer2_chunk5 = _mm_packus_epi16(_mm_srli_epi16(layer3_chunk2, 8), _mm_srli_epi16(layer3_chunk3, 8));
+ __m128i layer2_chunk2 = _mm_packus_epi16(_mm_and_si128(layer3_chunk4, v_mask), _mm_and_si128(layer3_chunk5, v_mask));
+ __m128i layer2_chunk6 = _mm_packus_epi16(_mm_srli_epi16(layer3_chunk4, 8), _mm_srli_epi16(layer3_chunk5, 8));
+ __m128i layer2_chunk3 = _mm_packus_epi16(_mm_and_si128(layer3_chunk6, v_mask), _mm_and_si128(layer3_chunk7, v_mask));
+ __m128i layer2_chunk7 = _mm_packus_epi16(_mm_srli_epi16(layer3_chunk6, 8), _mm_srli_epi16(layer3_chunk7, 8));
+
+ __m128i layer1_chunk0 = _mm_packus_epi16(_mm_and_si128(layer2_chunk0, v_mask), _mm_and_si128(layer2_chunk1, v_mask));
+ __m128i layer1_chunk4 = _mm_packus_epi16(_mm_srli_epi16(layer2_chunk0, 8), _mm_srli_epi16(layer2_chunk1, 8));
+ __m128i layer1_chunk1 = _mm_packus_epi16(_mm_and_si128(layer2_chunk2, v_mask), _mm_and_si128(layer2_chunk3, v_mask));
+ __m128i layer1_chunk5 = _mm_packus_epi16(_mm_srli_epi16(layer2_chunk2, 8), _mm_srli_epi16(layer2_chunk3, 8));
+ __m128i layer1_chunk2 = _mm_packus_epi16(_mm_and_si128(layer2_chunk4, v_mask), _mm_and_si128(layer2_chunk5, v_mask));
+ __m128i layer1_chunk6 = _mm_packus_epi16(_mm_srli_epi16(layer2_chunk4, 8), _mm_srli_epi16(layer2_chunk5, 8));
+ __m128i layer1_chunk3 = _mm_packus_epi16(_mm_and_si128(layer2_chunk6, v_mask), _mm_and_si128(layer2_chunk7, v_mask));
+ __m128i layer1_chunk7 = _mm_packus_epi16(_mm_srli_epi16(layer2_chunk6, 8), _mm_srli_epi16(layer2_chunk7, 8));
+
+ v_r0 = _mm_packus_epi16(_mm_and_si128(layer1_chunk0, v_mask), _mm_and_si128(layer1_chunk1, v_mask));
+ v_b0 = _mm_packus_epi16(_mm_srli_epi16(layer1_chunk0, 8), _mm_srli_epi16(layer1_chunk1, 8));
+ v_r1 = _mm_packus_epi16(_mm_and_si128(layer1_chunk2, v_mask), _mm_and_si128(layer1_chunk3, v_mask));
+ v_b1 = _mm_packus_epi16(_mm_srli_epi16(layer1_chunk2, 8), _mm_srli_epi16(layer1_chunk3, 8));
+ v_g0 = _mm_packus_epi16(_mm_and_si128(layer1_chunk4, v_mask), _mm_and_si128(layer1_chunk5, v_mask));
+ v_a0 = _mm_packus_epi16(_mm_srli_epi16(layer1_chunk4, 8), _mm_srli_epi16(layer1_chunk5, 8));
+ v_g1 = _mm_packus_epi16(_mm_and_si128(layer1_chunk6, v_mask), _mm_and_si128(layer1_chunk7, v_mask));
+ v_a1 = _mm_packus_epi16(_mm_srli_epi16(layer1_chunk6, 8), _mm_srli_epi16(layer1_chunk7, 8));
+}
+
+inline void _mm_deinterleave_epi16(__m128i & v_r0, __m128i & v_r1, __m128i & v_g0, __m128i & v_g1)
+{
+ __m128i layer1_chunk0 = _mm_unpacklo_epi16(v_r0, v_g0);
+ __m128i layer1_chunk1 = _mm_unpackhi_epi16(v_r0, v_g0);
+ __m128i layer1_chunk2 = _mm_unpacklo_epi16(v_r1, v_g1);
+ __m128i layer1_chunk3 = _mm_unpackhi_epi16(v_r1, v_g1);
+
+ __m128i layer2_chunk0 = _mm_unpacklo_epi16(layer1_chunk0, layer1_chunk2);
+ __m128i layer2_chunk1 = _mm_unpackhi_epi16(layer1_chunk0, layer1_chunk2);
+ __m128i layer2_chunk2 = _mm_unpacklo_epi16(layer1_chunk1, layer1_chunk3);
+ __m128i layer2_chunk3 = _mm_unpackhi_epi16(layer1_chunk1, layer1_chunk3);
+
+ __m128i layer3_chunk0 = _mm_unpacklo_epi16(layer2_chunk0, layer2_chunk2);
+ __m128i layer3_chunk1 = _mm_unpackhi_epi16(layer2_chunk0, layer2_chunk2);
+ __m128i layer3_chunk2 = _mm_unpacklo_epi16(layer2_chunk1, layer2_chunk3);
+ __m128i layer3_chunk3 = _mm_unpackhi_epi16(layer2_chunk1, layer2_chunk3);
+
+ v_r0 = _mm_unpacklo_epi16(layer3_chunk0, layer3_chunk2);
+ v_r1 = _mm_unpackhi_epi16(layer3_chunk0, layer3_chunk2);
+ v_g0 = _mm_unpacklo_epi16(layer3_chunk1, layer3_chunk3);
+ v_g1 = _mm_unpackhi_epi16(layer3_chunk1, layer3_chunk3);
+}
+
+inline void _mm_deinterleave_epi16(__m128i & v_r0, __m128i & v_r1, __m128i & v_g0,
+ __m128i & v_g1, __m128i & v_b0, __m128i & v_b1)
+{
+ __m128i layer1_chunk0 = _mm_unpacklo_epi16(v_r0, v_g1);
+ __m128i layer1_chunk1 = _mm_unpackhi_epi16(v_r0, v_g1);
+ __m128i layer1_chunk2 = _mm_unpacklo_epi16(v_r1, v_b0);
+ __m128i layer1_chunk3 = _mm_unpackhi_epi16(v_r1, v_b0);
+ __m128i layer1_chunk4 = _mm_unpacklo_epi16(v_g0, v_b1);
+ __m128i layer1_chunk5 = _mm_unpackhi_epi16(v_g0, v_b1);
+
+ __m128i layer2_chunk0 = _mm_unpacklo_epi16(layer1_chunk0, layer1_chunk3);
+ __m128i layer2_chunk1 = _mm_unpackhi_epi16(layer1_chunk0, layer1_chunk3);
+ __m128i layer2_chunk2 = _mm_unpacklo_epi16(layer1_chunk1, layer1_chunk4);
+ __m128i layer2_chunk3 = _mm_unpackhi_epi16(layer1_chunk1, layer1_chunk4);
+ __m128i layer2_chunk4 = _mm_unpacklo_epi16(layer1_chunk2, layer1_chunk5);
+ __m128i layer2_chunk5 = _mm_unpackhi_epi16(layer1_chunk2, layer1_chunk5);
+
+ __m128i layer3_chunk0 = _mm_unpacklo_epi16(layer2_chunk0, layer2_chunk3);
+ __m128i layer3_chunk1 = _mm_unpackhi_epi16(layer2_chunk0, layer2_chunk3);
+ __m128i layer3_chunk2 = _mm_unpacklo_epi16(layer2_chunk1, layer2_chunk4);
+ __m128i layer3_chunk3 = _mm_unpackhi_epi16(layer2_chunk1, layer2_chunk4);
+ __m128i layer3_chunk4 = _mm_unpacklo_epi16(layer2_chunk2, layer2_chunk5);
+ __m128i layer3_chunk5 = _mm_unpackhi_epi16(layer2_chunk2, layer2_chunk5);
+
+ v_r0 = _mm_unpacklo_epi16(layer3_chunk0, layer3_chunk3);
+ v_r1 = _mm_unpackhi_epi16(layer3_chunk0, layer3_chunk3);
+ v_g0 = _mm_unpacklo_epi16(layer3_chunk1, layer3_chunk4);
+ v_g1 = _mm_unpackhi_epi16(layer3_chunk1, layer3_chunk4);
+ v_b0 = _mm_unpacklo_epi16(layer3_chunk2, layer3_chunk5);
+ v_b1 = _mm_unpackhi_epi16(layer3_chunk2, layer3_chunk5);
+}
+
+inline void _mm_deinterleave_epi16(__m128i & v_r0, __m128i & v_r1, __m128i & v_g0, __m128i & v_g1,
+ __m128i & v_b0, __m128i & v_b1, __m128i & v_a0, __m128i & v_a1)
+{
+ __m128i layer1_chunk0 = _mm_unpacklo_epi16(v_r0, v_b0);
+ __m128i layer1_chunk1 = _mm_unpackhi_epi16(v_r0, v_b0);
+ __m128i layer1_chunk2 = _mm_unpacklo_epi16(v_r1, v_b1);
+ __m128i layer1_chunk3 = _mm_unpackhi_epi16(v_r1, v_b1);
+ __m128i layer1_chunk4 = _mm_unpacklo_epi16(v_g0, v_a0);
+ __m128i layer1_chunk5 = _mm_unpackhi_epi16(v_g0, v_a0);
+ __m128i layer1_chunk6 = _mm_unpacklo_epi16(v_g1, v_a1);
+ __m128i layer1_chunk7 = _mm_unpackhi_epi16(v_g1, v_a1);
+
+ __m128i layer2_chunk0 = _mm_unpacklo_epi16(layer1_chunk0, layer1_chunk4);
+ __m128i layer2_chunk1 = _mm_unpackhi_epi16(layer1_chunk0, layer1_chunk4);
+ __m128i layer2_chunk2 = _mm_unpacklo_epi16(layer1_chunk1, layer1_chunk5);
+ __m128i layer2_chunk3 = _mm_unpackhi_epi16(layer1_chunk1, layer1_chunk5);
+ __m128i layer2_chunk4 = _mm_unpacklo_epi16(layer1_chunk2, layer1_chunk6);
+ __m128i layer2_chunk5 = _mm_unpackhi_epi16(layer1_chunk2, layer1_chunk6);
+ __m128i layer2_chunk6 = _mm_unpacklo_epi16(layer1_chunk3, layer1_chunk7);
+ __m128i layer2_chunk7 = _mm_unpackhi_epi16(layer1_chunk3, layer1_chunk7);
+
+ __m128i layer3_chunk0 = _mm_unpacklo_epi16(layer2_chunk0, layer2_chunk4);
+ __m128i layer3_chunk1 = _mm_unpackhi_epi16(layer2_chunk0, layer2_chunk4);
+ __m128i layer3_chunk2 = _mm_unpacklo_epi16(layer2_chunk1, layer2_chunk5);
+ __m128i layer3_chunk3 = _mm_unpackhi_epi16(layer2_chunk1, layer2_chunk5);
+ __m128i layer3_chunk4 = _mm_unpacklo_epi16(layer2_chunk2, layer2_chunk6);
+ __m128i layer3_chunk5 = _mm_unpackhi_epi16(layer2_chunk2, layer2_chunk6);
+ __m128i layer3_chunk6 = _mm_unpacklo_epi16(layer2_chunk3, layer2_chunk7);
+ __m128i layer3_chunk7 = _mm_unpackhi_epi16(layer2_chunk3, layer2_chunk7);
+
+ v_r0 = _mm_unpacklo_epi16(layer3_chunk0, layer3_chunk4);
+ v_r1 = _mm_unpackhi_epi16(layer3_chunk0, layer3_chunk4);
+ v_g0 = _mm_unpacklo_epi16(layer3_chunk1, layer3_chunk5);
+ v_g1 = _mm_unpackhi_epi16(layer3_chunk1, layer3_chunk5);
+ v_b0 = _mm_unpacklo_epi16(layer3_chunk2, layer3_chunk6);
+ v_b1 = _mm_unpackhi_epi16(layer3_chunk2, layer3_chunk6);
+ v_a0 = _mm_unpacklo_epi16(layer3_chunk3, layer3_chunk7);
+ v_a1 = _mm_unpackhi_epi16(layer3_chunk3, layer3_chunk7);
+}
+
+#if CV_SSE4_1
+
+inline void _mm_interleave_epi16(__m128i & v_r0, __m128i & v_r1, __m128i & v_g0, __m128i & v_g1)
+{
+ __m128i v_mask = _mm_set1_epi32(0x0000ffff);
+
+ __m128i layer3_chunk0 = _mm_packus_epi32(_mm_and_si128(v_r0, v_mask), _mm_and_si128(v_r1, v_mask));
+ __m128i layer3_chunk2 = _mm_packus_epi32(_mm_srli_epi32(v_r0, 16), _mm_srli_epi32(v_r1, 16));
+ __m128i layer3_chunk1 = _mm_packus_epi32(_mm_and_si128(v_g0, v_mask), _mm_and_si128(v_g1, v_mask));
+ __m128i layer3_chunk3 = _mm_packus_epi32(_mm_srli_epi32(v_g0, 16), _mm_srli_epi32(v_g1, 16));
+
+ __m128i layer2_chunk0 = _mm_packus_epi32(_mm_and_si128(layer3_chunk0, v_mask), _mm_and_si128(layer3_chunk1, v_mask));
+ __m128i layer2_chunk2 = _mm_packus_epi32(_mm_srli_epi32(layer3_chunk0, 16), _mm_srli_epi32(layer3_chunk1, 16));
+ __m128i layer2_chunk1 = _mm_packus_epi32(_mm_and_si128(layer3_chunk2, v_mask), _mm_and_si128(layer3_chunk3, v_mask));
+ __m128i layer2_chunk3 = _mm_packus_epi32(_mm_srli_epi32(layer3_chunk2, 16), _mm_srli_epi32(layer3_chunk3, 16));
+
+ __m128i layer1_chunk0 = _mm_packus_epi32(_mm_and_si128(layer2_chunk0, v_mask), _mm_and_si128(layer2_chunk1, v_mask));
+ __m128i layer1_chunk2 = _mm_packus_epi32(_mm_srli_epi32(layer2_chunk0, 16), _mm_srli_epi32(layer2_chunk1, 16));
+ __m128i layer1_chunk1 = _mm_packus_epi32(_mm_and_si128(layer2_chunk2, v_mask), _mm_and_si128(layer2_chunk3, v_mask));
+ __m128i layer1_chunk3 = _mm_packus_epi32(_mm_srli_epi32(layer2_chunk2, 16), _mm_srli_epi32(layer2_chunk3, 16));
+
+ v_r0 = _mm_packus_epi32(_mm_and_si128(layer1_chunk0, v_mask), _mm_and_si128(layer1_chunk1, v_mask));
+ v_g0 = _mm_packus_epi32(_mm_srli_epi32(layer1_chunk0, 16), _mm_srli_epi32(layer1_chunk1, 16));
+ v_r1 = _mm_packus_epi32(_mm_and_si128(layer1_chunk2, v_mask), _mm_and_si128(layer1_chunk3, v_mask));
+ v_g1 = _mm_packus_epi32(_mm_srli_epi32(layer1_chunk2, 16), _mm_srli_epi32(layer1_chunk3, 16));
+}
+
+inline void _mm_interleave_epi16(__m128i & v_r0, __m128i & v_r1, __m128i & v_g0,
+ __m128i & v_g1, __m128i & v_b0, __m128i & v_b1)
+{
+ __m128i v_mask = _mm_set1_epi32(0x0000ffff);
+
+ __m128i layer3_chunk0 = _mm_packus_epi32(_mm_and_si128(v_r0, v_mask), _mm_and_si128(v_r1, v_mask));
+ __m128i layer3_chunk3 = _mm_packus_epi32(_mm_srli_epi32(v_r0, 16), _mm_srli_epi32(v_r1, 16));
+ __m128i layer3_chunk1 = _mm_packus_epi32(_mm_and_si128(v_g0, v_mask), _mm_and_si128(v_g1, v_mask));
+ __m128i layer3_chunk4 = _mm_packus_epi32(_mm_srli_epi32(v_g0, 16), _mm_srli_epi32(v_g1, 16));
+ __m128i layer3_chunk2 = _mm_packus_epi32(_mm_and_si128(v_b0, v_mask), _mm_and_si128(v_b1, v_mask));
+ __m128i layer3_chunk5 = _mm_packus_epi32(_mm_srli_epi32(v_b0, 16), _mm_srli_epi32(v_b1, 16));
+
+ __m128i layer2_chunk0 = _mm_packus_epi32(_mm_and_si128(layer3_chunk0, v_mask), _mm_and_si128(layer3_chunk1, v_mask));
+ __m128i layer2_chunk3 = _mm_packus_epi32(_mm_srli_epi32(layer3_chunk0, 16), _mm_srli_epi32(layer3_chunk1, 16));
+ __m128i layer2_chunk1 = _mm_packus_epi32(_mm_and_si128(layer3_chunk2, v_mask), _mm_and_si128(layer3_chunk3, v_mask));
+ __m128i layer2_chunk4 = _mm_packus_epi32(_mm_srli_epi32(layer3_chunk2, 16), _mm_srli_epi32(layer3_chunk3, 16));
+ __m128i layer2_chunk2 = _mm_packus_epi32(_mm_and_si128(layer3_chunk4, v_mask), _mm_and_si128(layer3_chunk5, v_mask));
+ __m128i layer2_chunk5 = _mm_packus_epi32(_mm_srli_epi32(layer3_chunk4, 16), _mm_srli_epi32(layer3_chunk5, 16));
+
+ __m128i layer1_chunk0 = _mm_packus_epi32(_mm_and_si128(layer2_chunk0, v_mask), _mm_and_si128(layer2_chunk1, v_mask));
+ __m128i layer1_chunk3 = _mm_packus_epi32(_mm_srli_epi32(layer2_chunk0, 16), _mm_srli_epi32(layer2_chunk1, 16));
+ __m128i layer1_chunk1 = _mm_packus_epi32(_mm_and_si128(layer2_chunk2, v_mask), _mm_and_si128(layer2_chunk3, v_mask));
+ __m128i layer1_chunk4 = _mm_packus_epi32(_mm_srli_epi32(layer2_chunk2, 16), _mm_srli_epi32(layer2_chunk3, 16));
+ __m128i layer1_chunk2 = _mm_packus_epi32(_mm_and_si128(layer2_chunk4, v_mask), _mm_and_si128(layer2_chunk5, v_mask));
+ __m128i layer1_chunk5 = _mm_packus_epi32(_mm_srli_epi32(layer2_chunk4, 16), _mm_srli_epi32(layer2_chunk5, 16));
+
+ v_r0 = _mm_packus_epi32(_mm_and_si128(layer1_chunk0, v_mask), _mm_and_si128(layer1_chunk1, v_mask));
+ v_g1 = _mm_packus_epi32(_mm_srli_epi32(layer1_chunk0, 16), _mm_srli_epi32(layer1_chunk1, 16));
+ v_r1 = _mm_packus_epi32(_mm_and_si128(layer1_chunk2, v_mask), _mm_and_si128(layer1_chunk3, v_mask));
+ v_b0 = _mm_packus_epi32(_mm_srli_epi32(layer1_chunk2, 16), _mm_srli_epi32(layer1_chunk3, 16));
+ v_g0 = _mm_packus_epi32(_mm_and_si128(layer1_chunk4, v_mask), _mm_and_si128(layer1_chunk5, v_mask));
+ v_b1 = _mm_packus_epi32(_mm_srli_epi32(layer1_chunk4, 16), _mm_srli_epi32(layer1_chunk5, 16));
+}
+
+inline void _mm_interleave_epi16(__m128i & v_r0, __m128i & v_r1, __m128i & v_g0, __m128i & v_g1,
+ __m128i & v_b0, __m128i & v_b1, __m128i & v_a0, __m128i & v_a1)
+{
+ __m128i v_mask = _mm_set1_epi32(0x0000ffff);
+
+ __m128i layer3_chunk0 = _mm_packus_epi32(_mm_and_si128(v_r0, v_mask), _mm_and_si128(v_r1, v_mask));
+ __m128i layer3_chunk4 = _mm_packus_epi32(_mm_srli_epi32(v_r0, 16), _mm_srli_epi32(v_r1, 16));
+ __m128i layer3_chunk1 = _mm_packus_epi32(_mm_and_si128(v_g0, v_mask), _mm_and_si128(v_g1, v_mask));
+ __m128i layer3_chunk5 = _mm_packus_epi32(_mm_srli_epi32(v_g0, 16), _mm_srli_epi32(v_g1, 16));
+ __m128i layer3_chunk2 = _mm_packus_epi32(_mm_and_si128(v_b0, v_mask), _mm_and_si128(v_b1, v_mask));
+ __m128i layer3_chunk6 = _mm_packus_epi32(_mm_srli_epi32(v_b0, 16), _mm_srli_epi32(v_b1, 16));
+ __m128i layer3_chunk3 = _mm_packus_epi32(_mm_and_si128(v_a0, v_mask), _mm_and_si128(v_a1, v_mask));
+ __m128i layer3_chunk7 = _mm_packus_epi32(_mm_srli_epi32(v_a0, 16), _mm_srli_epi32(v_a1, 16));
+
+ __m128i layer2_chunk0 = _mm_packus_epi32(_mm_and_si128(layer3_chunk0, v_mask), _mm_and_si128(layer3_chunk1, v_mask));
+ __m128i layer2_chunk4 = _mm_packus_epi32(_mm_srli_epi32(layer3_chunk0, 16), _mm_srli_epi32(layer3_chunk1, 16));
+ __m128i layer2_chunk1 = _mm_packus_epi32(_mm_and_si128(layer3_chunk2, v_mask), _mm_and_si128(layer3_chunk3, v_mask));
+ __m128i layer2_chunk5 = _mm_packus_epi32(_mm_srli_epi32(layer3_chunk2, 16), _mm_srli_epi32(layer3_chunk3, 16));
+ __m128i layer2_chunk2 = _mm_packus_epi32(_mm_and_si128(layer3_chunk4, v_mask), _mm_and_si128(layer3_chunk5, v_mask));
+ __m128i layer2_chunk6 = _mm_packus_epi32(_mm_srli_epi32(layer3_chunk4, 16), _mm_srli_epi32(layer3_chunk5, 16));
+ __m128i layer2_chunk3 = _mm_packus_epi32(_mm_and_si128(layer3_chunk6, v_mask), _mm_and_si128(layer3_chunk7, v_mask));
+ __m128i layer2_chunk7 = _mm_packus_epi32(_mm_srli_epi32(layer3_chunk6, 16), _mm_srli_epi32(layer3_chunk7, 16));
+
+ __m128i layer1_chunk0 = _mm_packus_epi32(_mm_and_si128(layer2_chunk0, v_mask), _mm_and_si128(layer2_chunk1, v_mask));
+ __m128i layer1_chunk4 = _mm_packus_epi32(_mm_srli_epi32(layer2_chunk0, 16), _mm_srli_epi32(layer2_chunk1, 16));
+ __m128i layer1_chunk1 = _mm_packus_epi32(_mm_and_si128(layer2_chunk2, v_mask), _mm_and_si128(layer2_chunk3, v_mask));
+ __m128i layer1_chunk5 = _mm_packus_epi32(_mm_srli_epi32(layer2_chunk2, 16), _mm_srli_epi32(layer2_chunk3, 16));
+ __m128i layer1_chunk2 = _mm_packus_epi32(_mm_and_si128(layer2_chunk4, v_mask), _mm_and_si128(layer2_chunk5, v_mask));
+ __m128i layer1_chunk6 = _mm_packus_epi32(_mm_srli_epi32(layer2_chunk4, 16), _mm_srli_epi32(layer2_chunk5, 16));
+ __m128i layer1_chunk3 = _mm_packus_epi32(_mm_and_si128(layer2_chunk6, v_mask), _mm_and_si128(layer2_chunk7, v_mask));
+ __m128i layer1_chunk7 = _mm_packus_epi32(_mm_srli_epi32(layer2_chunk6, 16), _mm_srli_epi32(layer2_chunk7, 16));
+
+ v_r0 = _mm_packus_epi32(_mm_and_si128(layer1_chunk0, v_mask), _mm_and_si128(layer1_chunk1, v_mask));
+ v_b0 = _mm_packus_epi32(_mm_srli_epi32(layer1_chunk0, 16), _mm_srli_epi32(layer1_chunk1, 16));
+ v_r1 = _mm_packus_epi32(_mm_and_si128(layer1_chunk2, v_mask), _mm_and_si128(layer1_chunk3, v_mask));
+ v_b1 = _mm_packus_epi32(_mm_srli_epi32(layer1_chunk2, 16), _mm_srli_epi32(layer1_chunk3, 16));
+ v_g0 = _mm_packus_epi32(_mm_and_si128(layer1_chunk4, v_mask), _mm_and_si128(layer1_chunk5, v_mask));
+ v_a0 = _mm_packus_epi32(_mm_srli_epi32(layer1_chunk4, 16), _mm_srli_epi32(layer1_chunk5, 16));
+ v_g1 = _mm_packus_epi32(_mm_and_si128(layer1_chunk6, v_mask), _mm_and_si128(layer1_chunk7, v_mask));
+ v_a1 = _mm_packus_epi32(_mm_srli_epi32(layer1_chunk6, 16), _mm_srli_epi32(layer1_chunk7, 16));
+}
+
+#endif // CV_SSE4_1
+
+inline void _mm_deinterleave_ps(__m128 & v_r0, __m128 & v_r1, __m128 & v_g0, __m128 & v_g1)
+{
+ __m128 layer1_chunk0 = _mm_unpacklo_ps(v_r0, v_g0);
+ __m128 layer1_chunk1 = _mm_unpackhi_ps(v_r0, v_g0);
+ __m128 layer1_chunk2 = _mm_unpacklo_ps(v_r1, v_g1);
+ __m128 layer1_chunk3 = _mm_unpackhi_ps(v_r1, v_g1);
+
+ __m128 layer2_chunk0 = _mm_unpacklo_ps(layer1_chunk0, layer1_chunk2);
+ __m128 layer2_chunk1 = _mm_unpackhi_ps(layer1_chunk0, layer1_chunk2);
+ __m128 layer2_chunk2 = _mm_unpacklo_ps(layer1_chunk1, layer1_chunk3);
+ __m128 layer2_chunk3 = _mm_unpackhi_ps(layer1_chunk1, layer1_chunk3);
+
+ v_r0 = _mm_unpacklo_ps(layer2_chunk0, layer2_chunk2);
+ v_r1 = _mm_unpackhi_ps(layer2_chunk0, layer2_chunk2);
+ v_g0 = _mm_unpacklo_ps(layer2_chunk1, layer2_chunk3);
+ v_g1 = _mm_unpackhi_ps(layer2_chunk1, layer2_chunk3);
+}
+
+inline void _mm_deinterleave_ps(__m128 & v_r0, __m128 & v_r1, __m128 & v_g0,
+ __m128 & v_g1, __m128 & v_b0, __m128 & v_b1)
+{
+ __m128 layer1_chunk0 = _mm_unpacklo_ps(v_r0, v_g1);
+ __m128 layer1_chunk1 = _mm_unpackhi_ps(v_r0, v_g1);
+ __m128 layer1_chunk2 = _mm_unpacklo_ps(v_r1, v_b0);
+ __m128 layer1_chunk3 = _mm_unpackhi_ps(v_r1, v_b0);
+ __m128 layer1_chunk4 = _mm_unpacklo_ps(v_g0, v_b1);
+ __m128 layer1_chunk5 = _mm_unpackhi_ps(v_g0, v_b1);
+
+ __m128 layer2_chunk0 = _mm_unpacklo_ps(layer1_chunk0, layer1_chunk3);
+ __m128 layer2_chunk1 = _mm_unpackhi_ps(layer1_chunk0, layer1_chunk3);
+ __m128 layer2_chunk2 = _mm_unpacklo_ps(layer1_chunk1, layer1_chunk4);
+ __m128 layer2_chunk3 = _mm_unpackhi_ps(layer1_chunk1, layer1_chunk4);
+ __m128 layer2_chunk4 = _mm_unpacklo_ps(layer1_chunk2, layer1_chunk5);
+ __m128 layer2_chunk5 = _mm_unpackhi_ps(layer1_chunk2, layer1_chunk5);
+
+ v_r0 = _mm_unpacklo_ps(layer2_chunk0, layer2_chunk3);
+ v_r1 = _mm_unpackhi_ps(layer2_chunk0, layer2_chunk3);
+ v_g0 = _mm_unpacklo_ps(layer2_chunk1, layer2_chunk4);
+ v_g1 = _mm_unpackhi_ps(layer2_chunk1, layer2_chunk4);
+ v_b0 = _mm_unpacklo_ps(layer2_chunk2, layer2_chunk5);
+ v_b1 = _mm_unpackhi_ps(layer2_chunk2, layer2_chunk5);
+}
+
+inline void _mm_deinterleave_ps(__m128 & v_r0, __m128 & v_r1, __m128 & v_g0, __m128 & v_g1,
+ __m128 & v_b0, __m128 & v_b1, __m128 & v_a0, __m128 & v_a1)
+{
+ __m128 layer1_chunk0 = _mm_unpacklo_ps(v_r0, v_b0);
+ __m128 layer1_chunk1 = _mm_unpackhi_ps(v_r0, v_b0);
+ __m128 layer1_chunk2 = _mm_unpacklo_ps(v_r1, v_b1);
+ __m128 layer1_chunk3 = _mm_unpackhi_ps(v_r1, v_b1);
+ __m128 layer1_chunk4 = _mm_unpacklo_ps(v_g0, v_a0);
+ __m128 layer1_chunk5 = _mm_unpackhi_ps(v_g0, v_a0);
+ __m128 layer1_chunk6 = _mm_unpacklo_ps(v_g1, v_a1);
+ __m128 layer1_chunk7 = _mm_unpackhi_ps(v_g1, v_a1);
+
+ __m128 layer2_chunk0 = _mm_unpacklo_ps(layer1_chunk0, layer1_chunk4);
+ __m128 layer2_chunk1 = _mm_unpackhi_ps(layer1_chunk0, layer1_chunk4);
+ __m128 layer2_chunk2 = _mm_unpacklo_ps(layer1_chunk1, layer1_chunk5);
+ __m128 layer2_chunk3 = _mm_unpackhi_ps(layer1_chunk1, layer1_chunk5);
+ __m128 layer2_chunk4 = _mm_unpacklo_ps(layer1_chunk2, layer1_chunk6);
+ __m128 layer2_chunk5 = _mm_unpackhi_ps(layer1_chunk2, layer1_chunk6);
+ __m128 layer2_chunk6 = _mm_unpacklo_ps(layer1_chunk3, layer1_chunk7);
+ __m128 layer2_chunk7 = _mm_unpackhi_ps(layer1_chunk3, layer1_chunk7);
+
+ v_r0 = _mm_unpacklo_ps(layer2_chunk0, layer2_chunk4);
+ v_r1 = _mm_unpackhi_ps(layer2_chunk0, layer2_chunk4);
+ v_g0 = _mm_unpacklo_ps(layer2_chunk1, layer2_chunk5);
+ v_g1 = _mm_unpackhi_ps(layer2_chunk1, layer2_chunk5);
+ v_b0 = _mm_unpacklo_ps(layer2_chunk2, layer2_chunk6);
+ v_b1 = _mm_unpackhi_ps(layer2_chunk2, layer2_chunk6);
+ v_a0 = _mm_unpacklo_ps(layer2_chunk3, layer2_chunk7);
+ v_a1 = _mm_unpackhi_ps(layer2_chunk3, layer2_chunk7);
+}
+
+inline void _mm_interleave_ps(__m128 & v_r0, __m128 & v_r1, __m128 & v_g0, __m128 & v_g1)
+{
+ const int mask_lo = _MM_SHUFFLE(2, 0, 2, 0), mask_hi = _MM_SHUFFLE(3, 1, 3, 1);
+
+ __m128 layer2_chunk0 = _mm_shuffle_ps(v_r0, v_r1, mask_lo);
+ __m128 layer2_chunk2 = _mm_shuffle_ps(v_r0, v_r1, mask_hi);
+ __m128 layer2_chunk1 = _mm_shuffle_ps(v_g0, v_g1, mask_lo);
+ __m128 layer2_chunk3 = _mm_shuffle_ps(v_g0, v_g1, mask_hi);
+
+ __m128 layer1_chunk0 = _mm_shuffle_ps(layer2_chunk0, layer2_chunk1, mask_lo);
+ __m128 layer1_chunk2 = _mm_shuffle_ps(layer2_chunk0, layer2_chunk1, mask_hi);
+ __m128 layer1_chunk1 = _mm_shuffle_ps(layer2_chunk2, layer2_chunk3, mask_lo);
+ __m128 layer1_chunk3 = _mm_shuffle_ps(layer2_chunk2, layer2_chunk3, mask_hi);
+
+ v_r0 = _mm_shuffle_ps(layer1_chunk0, layer1_chunk1, mask_lo);
+ v_g0 = _mm_shuffle_ps(layer1_chunk0, layer1_chunk1, mask_hi);
+ v_r1 = _mm_shuffle_ps(layer1_chunk2, layer1_chunk3, mask_lo);
+ v_g1 = _mm_shuffle_ps(layer1_chunk2, layer1_chunk3, mask_hi);
+}
+
+inline void _mm_interleave_ps(__m128 & v_r0, __m128 & v_r1, __m128 & v_g0,
+ __m128 & v_g1, __m128 & v_b0, __m128 & v_b1)
+{
+ const int mask_lo = _MM_SHUFFLE(2, 0, 2, 0), mask_hi = _MM_SHUFFLE(3, 1, 3, 1);
+
+ __m128 layer2_chunk0 = _mm_shuffle_ps(v_r0, v_r1, mask_lo);
+ __m128 layer2_chunk3 = _mm_shuffle_ps(v_r0, v_r1, mask_hi);
+ __m128 layer2_chunk1 = _mm_shuffle_ps(v_g0, v_g1, mask_lo);
+ __m128 layer2_chunk4 = _mm_shuffle_ps(v_g0, v_g1, mask_hi);
+ __m128 layer2_chunk2 = _mm_shuffle_ps(v_b0, v_b1, mask_lo);
+ __m128 layer2_chunk5 = _mm_shuffle_ps(v_b0, v_b1, mask_hi);
+
+ __m128 layer1_chunk0 = _mm_shuffle_ps(layer2_chunk0, layer2_chunk1, mask_lo);
+ __m128 layer1_chunk3 = _mm_shuffle_ps(layer2_chunk0, layer2_chunk1, mask_hi);
+ __m128 layer1_chunk1 = _mm_shuffle_ps(layer2_chunk2, layer2_chunk3, mask_lo);
+ __m128 layer1_chunk4 = _mm_shuffle_ps(layer2_chunk2, layer2_chunk3, mask_hi);
+ __m128 layer1_chunk2 = _mm_shuffle_ps(layer2_chunk4, layer2_chunk5, mask_lo);
+ __m128 layer1_chunk5 = _mm_shuffle_ps(layer2_chunk4, layer2_chunk5, mask_hi);
+
+ v_r0 = _mm_shuffle_ps(layer1_chunk0, layer1_chunk1, mask_lo);
+ v_g1 = _mm_shuffle_ps(layer1_chunk0, layer1_chunk1, mask_hi);
+ v_r1 = _mm_shuffle_ps(layer1_chunk2, layer1_chunk3, mask_lo);
+ v_b0 = _mm_shuffle_ps(layer1_chunk2, layer1_chunk3, mask_hi);
+ v_g0 = _mm_shuffle_ps(layer1_chunk4, layer1_chunk5, mask_lo);
+ v_b1 = _mm_shuffle_ps(layer1_chunk4, layer1_chunk5, mask_hi);
+}
+
+inline void _mm_interleave_ps(__m128 & v_r0, __m128 & v_r1, __m128 & v_g0, __m128 & v_g1,
+ __m128 & v_b0, __m128 & v_b1, __m128 & v_a0, __m128 & v_a1)
+{
+ const int mask_lo = _MM_SHUFFLE(2, 0, 2, 0), mask_hi = _MM_SHUFFLE(3, 1, 3, 1);
+
+ __m128 layer2_chunk0 = _mm_shuffle_ps(v_r0, v_r1, mask_lo);
+ __m128 layer2_chunk4 = _mm_shuffle_ps(v_r0, v_r1, mask_hi);
+ __m128 layer2_chunk1 = _mm_shuffle_ps(v_g0, v_g1, mask_lo);
+ __m128 layer2_chunk5 = _mm_shuffle_ps(v_g0, v_g1, mask_hi);
+ __m128 layer2_chunk2 = _mm_shuffle_ps(v_b0, v_b1, mask_lo);
+ __m128 layer2_chunk6 = _mm_shuffle_ps(v_b0, v_b1, mask_hi);
+ __m128 layer2_chunk3 = _mm_shuffle_ps(v_a0, v_a1, mask_lo);
+ __m128 layer2_chunk7 = _mm_shuffle_ps(v_a0, v_a1, mask_hi);
+
+ __m128 layer1_chunk0 = _mm_shuffle_ps(layer2_chunk0, layer2_chunk1, mask_lo);
+ __m128 layer1_chunk4 = _mm_shuffle_ps(layer2_chunk0, layer2_chunk1, mask_hi);
+ __m128 layer1_chunk1 = _mm_shuffle_ps(layer2_chunk2, layer2_chunk3, mask_lo);
+ __m128 layer1_chunk5 = _mm_shuffle_ps(layer2_chunk2, layer2_chunk3, mask_hi);
+ __m128 layer1_chunk2 = _mm_shuffle_ps(layer2_chunk4, layer2_chunk5, mask_lo);
+ __m128 layer1_chunk6 = _mm_shuffle_ps(layer2_chunk4, layer2_chunk5, mask_hi);
+ __m128 layer1_chunk3 = _mm_shuffle_ps(layer2_chunk6, layer2_chunk7, mask_lo);
+ __m128 layer1_chunk7 = _mm_shuffle_ps(layer2_chunk6, layer2_chunk7, mask_hi);
+
+ v_r0 = _mm_shuffle_ps(layer1_chunk0, layer1_chunk1, mask_lo);
+ v_b0 = _mm_shuffle_ps(layer1_chunk0, layer1_chunk1, mask_hi);
+ v_r1 = _mm_shuffle_ps(layer1_chunk2, layer1_chunk3, mask_lo);
+ v_b1 = _mm_shuffle_ps(layer1_chunk2, layer1_chunk3, mask_hi);
+ v_g0 = _mm_shuffle_ps(layer1_chunk4, layer1_chunk5, mask_lo);
+ v_a0 = _mm_shuffle_ps(layer1_chunk4, layer1_chunk5, mask_hi);
+ v_g1 = _mm_shuffle_ps(layer1_chunk6, layer1_chunk7, mask_lo);
+ v_a1 = _mm_shuffle_ps(layer1_chunk6, layer1_chunk7, mask_hi);
+}
+
+#endif // CV_SSE2
+
+//! @}
+
+#endif //OPENCV_CORE_SSE_UTILS_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/core/traits.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,326 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_CORE_TRAITS_HPP
+#define OPENCV_CORE_TRAITS_HPP
+
+#include "opencv2/core/cvdef.h"
+
+namespace cv
+{
+
+//! @addtogroup core_basic
+//! @{
+
+/** @brief Template "trait" class for OpenCV primitive data types.
+
+A primitive OpenCV data type is one of unsigned char, bool, signed char, unsigned short, signed
+short, int, float, double, or a tuple of values of one of these types, where all the values in the
+tuple have the same type. Any primitive type from the list can be defined by an identifier in the
+form CV_\<bit-depth\>{U|S|F}C(\<number_of_channels\>), for example: uchar \~ CV_8UC1, 3-element
+floating-point tuple \~ CV_32FC3, and so on. A universal OpenCV structure that is able to store a
+single instance of such a primitive data type is Vec. Multiple instances of such a type can be
+stored in a std::vector, Mat, Mat_, SparseMat, SparseMat_, or any other container that is able to
+store Vec instances.
+
+The DataType class is basically used to provide a description of such primitive data types without
+adding any fields or methods to the corresponding classes (and it is actually impossible to add
+anything to primitive C/C++ data types). This technique is known in C++ as class traits. It is not
+DataType itself that is used but its specialized versions, such as:
+@code
+ template<> class DataType<uchar>
+ {
+ typedef uchar value_type;
+ typedef int work_type;
+ typedef uchar channel_type;
+ enum { channel_type = CV_8U, channels = 1, fmt='u', type = CV_8U };
+ };
+ ...
+ template<typename _Tp> DataType<std::complex<_Tp> >
+ {
+ typedef std::complex<_Tp> value_type;
+ typedef std::complex<_Tp> work_type;
+ typedef _Tp channel_type;
+ // DataDepth is another helper trait class
+ enum { depth = DataDepth<_Tp>::value, channels=2,
+ fmt=(channels-1)*256+DataDepth<_Tp>::fmt,
+ type=CV_MAKETYPE(depth, channels) };
+ };
+ ...
+@endcode
+The main purpose of this class is to convert compilation-time type information to an
+OpenCV-compatible data type identifier, for example:
+@code
+ // allocates a 30x40 floating-point matrix
+ Mat A(30, 40, DataType<float>::type);
+
+ Mat B = Mat_<std::complex<double> >(3, 3);
+ // the statement below will print 6, 2 , that is depth == CV_64F, channels == 2
+ cout << B.depth() << ", " << B.channels() << endl;
+@endcode
+So, such traits are used to tell OpenCV which data type you are working with, even if such a type is
+not native to OpenCV. For example, the matrix B initialization above is compiled because OpenCV
+defines the proper specialized template class DataType\<complex\<_Tp\> \> . This mechanism is also
+useful (and used in OpenCV this way) for generic algorithms implementations.
+*/
+template<typename _Tp> class DataType
+{
+public:
+ typedef _Tp value_type;
+ typedef value_type work_type;
+ typedef value_type channel_type;
+ typedef value_type vec_type;
+ enum { generic_type = 1,
+ depth = -1,
+ channels = 1,
+ fmt = 0,
+ type = CV_MAKETYPE(depth, channels)
+ };
+};
+
+template<> class DataType<bool>
+{
+public:
+ typedef bool value_type;
+ typedef int work_type;
+ typedef value_type channel_type;
+ typedef value_type vec_type;
+ enum { generic_type = 0,
+ depth = CV_8U,
+ channels = 1,
+ fmt = (int)'u',
+ type = CV_MAKETYPE(depth, channels)
+ };
+};
+
+template<> class DataType<uchar>
+{
+public:
+ typedef uchar value_type;
+ typedef int work_type;
+ typedef value_type channel_type;
+ typedef value_type vec_type;
+ enum { generic_type = 0,
+ depth = CV_8U,
+ channels = 1,
+ fmt = (int)'u',
+ type = CV_MAKETYPE(depth, channels)
+ };
+};
+
+template<> class DataType<schar>
+{
+public:
+ typedef schar value_type;
+ typedef int work_type;
+ typedef value_type channel_type;
+ typedef value_type vec_type;
+ enum { generic_type = 0,
+ depth = CV_8S,
+ channels = 1,
+ fmt = (int)'c',
+ type = CV_MAKETYPE(depth, channels)
+ };
+};
+
+template<> class DataType<char>
+{
+public:
+ typedef schar value_type;
+ typedef int work_type;
+ typedef value_type channel_type;
+ typedef value_type vec_type;
+ enum { generic_type = 0,
+ depth = CV_8S,
+ channels = 1,
+ fmt = (int)'c',
+ type = CV_MAKETYPE(depth, channels)
+ };
+};
+
+template<> class DataType<ushort>
+{
+public:
+ typedef ushort value_type;
+ typedef int work_type;
+ typedef value_type channel_type;
+ typedef value_type vec_type;
+ enum { generic_type = 0,
+ depth = CV_16U,
+ channels = 1,
+ fmt = (int)'w',
+ type = CV_MAKETYPE(depth, channels)
+ };
+};
+
+template<> class DataType<short>
+{
+public:
+ typedef short value_type;
+ typedef int work_type;
+ typedef value_type channel_type;
+ typedef value_type vec_type;
+ enum { generic_type = 0,
+ depth = CV_16S,
+ channels = 1,
+ fmt = (int)'s',
+ type = CV_MAKETYPE(depth, channels)
+ };
+};
+
+template<> class DataType<int>
+{
+public:
+ typedef int value_type;
+ typedef value_type work_type;
+ typedef value_type channel_type;
+ typedef value_type vec_type;
+ enum { generic_type = 0,
+ depth = CV_32S,
+ channels = 1,
+ fmt = (int)'i',
+ type = CV_MAKETYPE(depth, channels)
+ };
+};
+
+template<> class DataType<float>
+{
+public:
+ typedef float value_type;
+ typedef value_type work_type;
+ typedef value_type channel_type;
+ typedef value_type vec_type;
+ enum { generic_type = 0,
+ depth = CV_32F,
+ channels = 1,
+ fmt = (int)'f',
+ type = CV_MAKETYPE(depth, channels)
+ };
+};
+
+template<> class DataType<double>
+{
+public:
+ typedef double value_type;
+ typedef value_type work_type;
+ typedef value_type channel_type;
+ typedef value_type vec_type;
+ enum { generic_type = 0,
+ depth = CV_64F,
+ channels = 1,
+ fmt = (int)'d',
+ type = CV_MAKETYPE(depth, channels)
+ };
+};
+
+
+/** @brief A helper class for cv::DataType
+
+The class is specialized for each fundamental numerical data type supported by OpenCV. It provides
+DataDepth<T>::value constant.
+*/
+template<typename _Tp> class DataDepth
+{
+public:
+ enum
+ {
+ value = DataType<_Tp>::depth,
+ fmt = DataType<_Tp>::fmt
+ };
+};
+
+
+
+template<int _depth> class TypeDepth
+{
+ enum { depth = CV_USRTYPE1 };
+ typedef void value_type;
+};
+
+template<> class TypeDepth<CV_8U>
+{
+ enum { depth = CV_8U };
+ typedef uchar value_type;
+};
+
+template<> class TypeDepth<CV_8S>
+{
+ enum { depth = CV_8S };
+ typedef schar value_type;
+};
+
+template<> class TypeDepth<CV_16U>
+{
+ enum { depth = CV_16U };
+ typedef ushort value_type;
+};
+
+template<> class TypeDepth<CV_16S>
+{
+ enum { depth = CV_16S };
+ typedef short value_type;
+};
+
+template<> class TypeDepth<CV_32S>
+{
+ enum { depth = CV_32S };
+ typedef int value_type;
+};
+
+template<> class TypeDepth<CV_32F>
+{
+ enum { depth = CV_32F };
+ typedef float value_type;
+};
+
+template<> class TypeDepth<CV_64F>
+{
+ enum { depth = CV_64F };
+ typedef double value_type;
+};
+
+//! @}
+
+} // cv
+
+#endif // OPENCV_CORE_TRAITS_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/core/types.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,2264 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_CORE_TYPES_HPP
+#define OPENCV_CORE_TYPES_HPP
+
+#ifndef __cplusplus
+# error types.hpp header must be compiled as C++
+#endif
+
+#include <climits>
+#include <cfloat>
+#include <vector>
+#include <limits>
+
+#include "opencv2/core/cvdef.h"
+#include "opencv2/core/cvstd.hpp"
+#include "opencv2/core/matx.hpp"
+
+namespace cv
+{
+
+//! @addtogroup core_basic
+//! @{
+
+//////////////////////////////// Complex //////////////////////////////
+
+/** @brief A complex number class.
+
+ The template class is similar and compatible with std::complex, however it provides slightly
+ more convenient access to the real and imaginary parts using through the simple field access, as opposite
+ to std::complex::real() and std::complex::imag().
+*/
+template<typename _Tp> class Complex
+{
+public:
+
+ //! constructors
+ Complex();
+ Complex( _Tp _re, _Tp _im = 0 );
+
+ //! conversion to another data type
+ template<typename T2> operator Complex<T2>() const;
+ //! conjugation
+ Complex conj() const;
+
+ _Tp re, im; //< the real and the imaginary parts
+};
+
+typedef Complex<float> Complexf;
+typedef Complex<double> Complexd;
+
+template<typename _Tp> class DataType< Complex<_Tp> >
+{
+public:
+ typedef Complex<_Tp> value_type;
+ typedef value_type work_type;
+ typedef _Tp channel_type;
+
+ enum { generic_type = 0,
+ depth = DataType<channel_type>::depth,
+ channels = 2,
+ fmt = DataType<channel_type>::fmt + ((channels - 1) << 8),
+ type = CV_MAKETYPE(depth, channels) };
+
+ typedef Vec<channel_type, channels> vec_type;
+};
+
+
+
+//////////////////////////////// Point_ ////////////////////////////////
+
+/** @brief Template class for 2D points specified by its coordinates `x` and `y`.
+
+An instance of the class is interchangeable with C structures, CvPoint and CvPoint2D32f . There is
+also a cast operator to convert point coordinates to the specified type. The conversion from
+floating-point coordinates to integer coordinates is done by rounding. Commonly, the conversion
+uses this operation for each of the coordinates. Besides the class members listed in the
+declaration above, the following operations on points are implemented:
+@code
+ pt1 = pt2 + pt3;
+ pt1 = pt2 - pt3;
+ pt1 = pt2 * a;
+ pt1 = a * pt2;
+ pt1 = pt2 / a;
+ pt1 += pt2;
+ pt1 -= pt2;
+ pt1 *= a;
+ pt1 /= a;
+ double value = norm(pt); // L2 norm
+ pt1 == pt2;
+ pt1 != pt2;
+@endcode
+For your convenience, the following type aliases are defined:
+@code
+ typedef Point_<int> Point2i;
+ typedef Point2i Point;
+ typedef Point_<float> Point2f;
+ typedef Point_<double> Point2d;
+@endcode
+Example:
+@code
+ Point2f a(0.3f, 0.f), b(0.f, 0.4f);
+ Point pt = (a + b)*10.f;
+ cout << pt.x << ", " << pt.y << endl;
+@endcode
+*/
+template<typename _Tp> class Point_
+{
+public:
+ typedef _Tp value_type;
+
+ // various constructors
+ Point_();
+ Point_(_Tp _x, _Tp _y);
+ Point_(const Point_& pt);
+ Point_(const Size_<_Tp>& sz);
+ Point_(const Vec<_Tp, 2>& v);
+
+ Point_& operator = (const Point_& pt);
+ //! conversion to another data type
+ template<typename _Tp2> operator Point_<_Tp2>() const;
+
+ //! conversion to the old-style C structures
+ operator Vec<_Tp, 2>() const;
+
+ //! dot product
+ _Tp dot(const Point_& pt) const;
+ //! dot product computed in double-precision arithmetics
+ double ddot(const Point_& pt) const;
+ //! cross-product
+ double cross(const Point_& pt) const;
+ //! checks whether the point is inside the specified rectangle
+ bool inside(const Rect_<_Tp>& r) const;
+
+ _Tp x, y; //< the point coordinates
+};
+
+typedef Point_<int> Point2i;
+typedef Point_<int64> Point2l;
+typedef Point_<float> Point2f;
+typedef Point_<double> Point2d;
+typedef Point2i Point;
+
+template<typename _Tp> class DataType< Point_<_Tp> >
+{
+public:
+ typedef Point_<_Tp> value_type;
+ typedef Point_<typename DataType<_Tp>::work_type> work_type;
+ typedef _Tp channel_type;
+
+ enum { generic_type = 0,
+ depth = DataType<channel_type>::depth,
+ channels = 2,
+ fmt = DataType<channel_type>::fmt + ((channels - 1) << 8),
+ type = CV_MAKETYPE(depth, channels)
+ };
+
+ typedef Vec<channel_type, channels> vec_type;
+};
+
+
+
+//////////////////////////////// Point3_ ////////////////////////////////
+
+/** @brief Template class for 3D points specified by its coordinates `x`, `y` and `z`.
+
+An instance of the class is interchangeable with the C structure CvPoint2D32f . Similarly to
+Point_ , the coordinates of 3D points can be converted to another type. The vector arithmetic and
+comparison operations are also supported.
+
+The following Point3_\<\> aliases are available:
+@code
+ typedef Point3_<int> Point3i;
+ typedef Point3_<float> Point3f;
+ typedef Point3_<double> Point3d;
+@endcode
+@see cv::Point3i, cv::Point3f and cv::Point3d
+*/
+template<typename _Tp> class Point3_
+{
+public:
+ typedef _Tp value_type;
+
+ // various constructors
+ Point3_();
+ Point3_(_Tp _x, _Tp _y, _Tp _z);
+ Point3_(const Point3_& pt);
+ explicit Point3_(const Point_<_Tp>& pt);
+ Point3_(const Vec<_Tp, 3>& v);
+
+ Point3_& operator = (const Point3_& pt);
+ //! conversion to another data type
+ template<typename _Tp2> operator Point3_<_Tp2>() const;
+ //! conversion to cv::Vec<>
+#if OPENCV_ABI_COMPATIBILITY > 300
+ template<typename _Tp2> operator Vec<_Tp2, 3>() const;
+#else
+ operator Vec<_Tp, 3>() const;
+#endif
+
+ //! dot product
+ _Tp dot(const Point3_& pt) const;
+ //! dot product computed in double-precision arithmetics
+ double ddot(const Point3_& pt) const;
+ //! cross product of the 2 3D points
+ Point3_ cross(const Point3_& pt) const;
+
+ _Tp x, y, z; //< the point coordinates
+};
+
+typedef Point3_<int> Point3i;
+typedef Point3_<float> Point3f;
+typedef Point3_<double> Point3d;
+
+template<typename _Tp> class DataType< Point3_<_Tp> >
+{
+public:
+ typedef Point3_<_Tp> value_type;
+ typedef Point3_<typename DataType<_Tp>::work_type> work_type;
+ typedef _Tp channel_type;
+
+ enum { generic_type = 0,
+ depth = DataType<channel_type>::depth,
+ channels = 3,
+ fmt = DataType<channel_type>::fmt + ((channels - 1) << 8),
+ type = CV_MAKETYPE(depth, channels)
+ };
+
+ typedef Vec<channel_type, channels> vec_type;
+};
+
+
+
+//////////////////////////////// Size_ ////////////////////////////////
+
+/** @brief Template class for specifying the size of an image or rectangle.
+
+The class includes two members called width and height. The structure can be converted to and from
+the old OpenCV structures CvSize and CvSize2D32f . The same set of arithmetic and comparison
+operations as for Point_ is available.
+
+OpenCV defines the following Size_\<\> aliases:
+@code
+ typedef Size_<int> Size2i;
+ typedef Size2i Size;
+ typedef Size_<float> Size2f;
+@endcode
+*/
+template<typename _Tp> class Size_
+{
+public:
+ typedef _Tp value_type;
+
+ //! various constructors
+ Size_();
+ Size_(_Tp _width, _Tp _height);
+ Size_(const Size_& sz);
+ Size_(const Point_<_Tp>& pt);
+
+ Size_& operator = (const Size_& sz);
+ //! the area (width*height)
+ _Tp area() const;
+
+ //! conversion of another data type.
+ template<typename _Tp2> operator Size_<_Tp2>() const;
+
+ _Tp width, height; // the width and the height
+};
+
+typedef Size_<int> Size2i;
+typedef Size_<int64> Size2l;
+typedef Size_<float> Size2f;
+typedef Size_<double> Size2d;
+typedef Size2i Size;
+
+template<typename _Tp> class DataType< Size_<_Tp> >
+{
+public:
+ typedef Size_<_Tp> value_type;
+ typedef Size_<typename DataType<_Tp>::work_type> work_type;
+ typedef _Tp channel_type;
+
+ enum { generic_type = 0,
+ depth = DataType<channel_type>::depth,
+ channels = 2,
+ fmt = DataType<channel_type>::fmt + ((channels - 1) << 8),
+ type = CV_MAKETYPE(depth, channels)
+ };
+
+ typedef Vec<channel_type, channels> vec_type;
+};
+
+
+
+//////////////////////////////// Rect_ ////////////////////////////////
+
+/** @brief Template class for 2D rectangles
+
+described by the following parameters:
+- Coordinates of the top-left corner. This is a default interpretation of Rect_::x and Rect_::y
+ in OpenCV. Though, in your algorithms you may count x and y from the bottom-left corner.
+- Rectangle width and height.
+
+OpenCV typically assumes that the top and left boundary of the rectangle are inclusive, while the
+right and bottom boundaries are not. For example, the method Rect_::contains returns true if
+
+\f[x \leq pt.x < x+width,
+ y \leq pt.y < y+height\f]
+
+Virtually every loop over an image ROI in OpenCV (where ROI is specified by Rect_\<int\> ) is
+implemented as:
+@code
+ for(int y = roi.y; y < roi.y + roi.height; y++)
+ for(int x = roi.x; x < roi.x + roi.width; x++)
+ {
+ // ...
+ }
+@endcode
+In addition to the class members, the following operations on rectangles are implemented:
+- \f$\texttt{rect} = \texttt{rect} \pm \texttt{point}\f$ (shifting a rectangle by a certain offset)
+- \f$\texttt{rect} = \texttt{rect} \pm \texttt{size}\f$ (expanding or shrinking a rectangle by a
+ certain amount)
+- rect += point, rect -= point, rect += size, rect -= size (augmenting operations)
+- rect = rect1 & rect2 (rectangle intersection)
+- rect = rect1 | rect2 (minimum area rectangle containing rect1 and rect2 )
+- rect &= rect1, rect |= rect1 (and the corresponding augmenting operations)
+- rect == rect1, rect != rect1 (rectangle comparison)
+
+This is an example how the partial ordering on rectangles can be established (rect1 \f$\subseteq\f$
+rect2):
+@code
+ template<typename _Tp> inline bool
+ operator <= (const Rect_<_Tp>& r1, const Rect_<_Tp>& r2)
+ {
+ return (r1 & r2) == r1;
+ }
+@endcode
+For your convenience, the Rect_\<\> alias is available: cv::Rect
+*/
+template<typename _Tp> class Rect_
+{
+public:
+ typedef _Tp value_type;
+
+ //! various constructors
+ Rect_();
+ Rect_(_Tp _x, _Tp _y, _Tp _width, _Tp _height);
+ Rect_(const Rect_& r);
+ Rect_(const Point_<_Tp>& org, const Size_<_Tp>& sz);
+ Rect_(const Point_<_Tp>& pt1, const Point_<_Tp>& pt2);
+
+ Rect_& operator = ( const Rect_& r );
+ //! the top-left corner
+ Point_<_Tp> tl() const;
+ //! the bottom-right corner
+ Point_<_Tp> br() const;
+
+ //! size (width, height) of the rectangle
+ Size_<_Tp> size() const;
+ //! area (width*height) of the rectangle
+ _Tp area() const;
+
+ //! conversion to another data type
+ template<typename _Tp2> operator Rect_<_Tp2>() const;
+
+ //! checks whether the rectangle contains the point
+ bool contains(const Point_<_Tp>& pt) const;
+
+ _Tp x, y, width, height; //< the top-left corner, as well as width and height of the rectangle
+};
+
+typedef Rect_<int> Rect2i;
+typedef Rect_<float> Rect2f;
+typedef Rect_<double> Rect2d;
+typedef Rect2i Rect;
+
+template<typename _Tp> class DataType< Rect_<_Tp> >
+{
+public:
+ typedef Rect_<_Tp> value_type;
+ typedef Rect_<typename DataType<_Tp>::work_type> work_type;
+ typedef _Tp channel_type;
+
+ enum { generic_type = 0,
+ depth = DataType<channel_type>::depth,
+ channels = 4,
+ fmt = DataType<channel_type>::fmt + ((channels - 1) << 8),
+ type = CV_MAKETYPE(depth, channels)
+ };
+
+ typedef Vec<channel_type, channels> vec_type;
+};
+
+
+
+///////////////////////////// RotatedRect /////////////////////////////
+
+/** @brief The class represents rotated (i.e. not up-right) rectangles on a plane.
+
+Each rectangle is specified by the center point (mass center), length of each side (represented by
+cv::Size2f structure) and the rotation angle in degrees.
+
+The sample below demonstrates how to use RotatedRect:
+@code
+ Mat image(200, 200, CV_8UC3, Scalar(0));
+ RotatedRect rRect = RotatedRect(Point2f(100,100), Size2f(100,50), 30);
+
+ Point2f vertices[4];
+ rRect.points(vertices);
+ for (int i = 0; i < 4; i++)
+ line(image, vertices[i], vertices[(i+1)%4], Scalar(0,255,0));
+
+ Rect brect = rRect.boundingRect();
+ rectangle(image, brect, Scalar(255,0,0));
+
+ imshow("rectangles", image);
+ waitKey(0);
+@endcode
+
+
+@sa CamShift, fitEllipse, minAreaRect, CvBox2D
+*/
+class CV_EXPORTS RotatedRect
+{
+public:
+ //! various constructors
+ RotatedRect();
+ /**
+ @param center The rectangle mass center.
+ @param size Width and height of the rectangle.
+ @param angle The rotation angle in a clockwise direction. When the angle is 0, 90, 180, 270 etc.,
+ the rectangle becomes an up-right rectangle.
+ */
+ RotatedRect(const Point2f& center, const Size2f& size, float angle);
+ /**
+ Any 3 end points of the RotatedRect. They must be given in order (either clockwise or
+ anticlockwise).
+ */
+ RotatedRect(const Point2f& point1, const Point2f& point2, const Point2f& point3);
+
+ /** returns 4 vertices of the rectangle
+ @param pts The points array for storing rectangle vertices.
+ */
+ void points(Point2f pts[]) const;
+ //! returns the minimal up-right integer rectangle containing the rotated rectangle
+ Rect boundingRect() const;
+ //! returns the minimal (exact) floating point rectangle containing the rotated rectangle, not intended for use with images
+ Rect_<float> boundingRect2f() const;
+
+ Point2f center; //< the rectangle mass center
+ Size2f size; //< width and height of the rectangle
+ float angle; //< the rotation angle. When the angle is 0, 90, 180, 270 etc., the rectangle becomes an up-right rectangle.
+};
+
+template<> class DataType< RotatedRect >
+{
+public:
+ typedef RotatedRect value_type;
+ typedef value_type work_type;
+ typedef float channel_type;
+
+ enum { generic_type = 0,
+ depth = DataType<channel_type>::depth,
+ channels = (int)sizeof(value_type)/sizeof(channel_type), // 5
+ fmt = DataType<channel_type>::fmt + ((channels - 1) << 8),
+ type = CV_MAKETYPE(depth, channels)
+ };
+
+ typedef Vec<channel_type, channels> vec_type;
+};
+
+
+
+//////////////////////////////// Range /////////////////////////////////
+
+/** @brief Template class specifying a continuous subsequence (slice) of a sequence.
+
+The class is used to specify a row or a column span in a matrix ( Mat ) and for many other purposes.
+Range(a,b) is basically the same as a:b in Matlab or a..b in Python. As in Python, start is an
+inclusive left boundary of the range and end is an exclusive right boundary of the range. Such a
+half-opened interval is usually denoted as \f$[start,end)\f$ .
+
+The static method Range::all() returns a special variable that means "the whole sequence" or "the
+whole range", just like " : " in Matlab or " ... " in Python. All the methods and functions in
+OpenCV that take Range support this special Range::all() value. But, of course, in case of your own
+custom processing, you will probably have to check and handle it explicitly:
+@code
+ void my_function(..., const Range& r, ....)
+ {
+ if(r == Range::all()) {
+ // process all the data
+ }
+ else {
+ // process [r.start, r.end)
+ }
+ }
+@endcode
+*/
+class CV_EXPORTS Range
+{
+public:
+ Range();
+ Range(int _start, int _end);
+ int size() const;
+ bool empty() const;
+ static Range all();
+
+ int start, end;
+};
+
+template<> class DataType<Range>
+{
+public:
+ typedef Range value_type;
+ typedef value_type work_type;
+ typedef int channel_type;
+
+ enum { generic_type = 0,
+ depth = DataType<channel_type>::depth,
+ channels = 2,
+ fmt = DataType<channel_type>::fmt + ((channels - 1) << 8),
+ type = CV_MAKETYPE(depth, channels)
+ };
+
+ typedef Vec<channel_type, channels> vec_type;
+};
+
+
+
+//////////////////////////////// Scalar_ ///////////////////////////////
+
+/** @brief Template class for a 4-element vector derived from Vec.
+
+Being derived from Vec\<_Tp, 4\> , Scalar_ and Scalar can be used just as typical 4-element
+vectors. In addition, they can be converted to/from CvScalar . The type Scalar is widely used in
+OpenCV to pass pixel values.
+*/
+template<typename _Tp> class Scalar_ : public Vec<_Tp, 4>
+{
+public:
+ //! various constructors
+ Scalar_();
+ Scalar_(_Tp v0, _Tp v1, _Tp v2=0, _Tp v3=0);
+ Scalar_(_Tp v0);
+
+ template<typename _Tp2, int cn>
+ Scalar_(const Vec<_Tp2, cn>& v);
+
+ //! returns a scalar with all elements set to v0
+ static Scalar_<_Tp> all(_Tp v0);
+
+ //! conversion to another data type
+ template<typename T2> operator Scalar_<T2>() const;
+
+ //! per-element product
+ Scalar_<_Tp> mul(const Scalar_<_Tp>& a, double scale=1 ) const;
+
+ // returns (v0, -v1, -v2, -v3)
+ Scalar_<_Tp> conj() const;
+
+ // returns true iff v1 == v2 == v3 == 0
+ bool isReal() const;
+};
+
+typedef Scalar_<double> Scalar;
+
+template<typename _Tp> class DataType< Scalar_<_Tp> >
+{
+public:
+ typedef Scalar_<_Tp> value_type;
+ typedef Scalar_<typename DataType<_Tp>::work_type> work_type;
+ typedef _Tp channel_type;
+
+ enum { generic_type = 0,
+ depth = DataType<channel_type>::depth,
+ channels = 4,
+ fmt = DataType<channel_type>::fmt + ((channels - 1) << 8),
+ type = CV_MAKETYPE(depth, channels)
+ };
+
+ typedef Vec<channel_type, channels> vec_type;
+};
+
+
+
+/////////////////////////////// KeyPoint ////////////////////////////////
+
+/** @brief Data structure for salient point detectors.
+
+The class instance stores a keypoint, i.e. a point feature found by one of many available keypoint
+detectors, such as Harris corner detector, cv::FAST, cv::StarDetector, cv::SURF, cv::SIFT,
+cv::LDetector etc.
+
+The keypoint is characterized by the 2D position, scale (proportional to the diameter of the
+neighborhood that needs to be taken into account), orientation and some other parameters. The
+keypoint neighborhood is then analyzed by another algorithm that builds a descriptor (usually
+represented as a feature vector). The keypoints representing the same object in different images
+can then be matched using cv::KDTree or another method.
+*/
+class CV_EXPORTS_W_SIMPLE KeyPoint
+{
+public:
+ //! the default constructor
+ CV_WRAP KeyPoint();
+ /**
+ @param _pt x & y coordinates of the keypoint
+ @param _size keypoint diameter
+ @param _angle keypoint orientation
+ @param _response keypoint detector response on the keypoint (that is, strength of the keypoint)
+ @param _octave pyramid octave in which the keypoint has been detected
+ @param _class_id object id
+ */
+ KeyPoint(Point2f _pt, float _size, float _angle=-1, float _response=0, int _octave=0, int _class_id=-1);
+ /**
+ @param x x-coordinate of the keypoint
+ @param y y-coordinate of the keypoint
+ @param _size keypoint diameter
+ @param _angle keypoint orientation
+ @param _response keypoint detector response on the keypoint (that is, strength of the keypoint)
+ @param _octave pyramid octave in which the keypoint has been detected
+ @param _class_id object id
+ */
+ CV_WRAP KeyPoint(float x, float y, float _size, float _angle=-1, float _response=0, int _octave=0, int _class_id=-1);
+
+ size_t hash() const;
+
+ /**
+ This method converts vector of keypoints to vector of points or the reverse, where each keypoint is
+ assigned the same size and the same orientation.
+
+ @param keypoints Keypoints obtained from any feature detection algorithm like SIFT/SURF/ORB
+ @param points2f Array of (x,y) coordinates of each keypoint
+ @param keypointIndexes Array of indexes of keypoints to be converted to points. (Acts like a mask to
+ convert only specified keypoints)
+ */
+ CV_WRAP static void convert(const std::vector<KeyPoint>& keypoints,
+ CV_OUT std::vector<Point2f>& points2f,
+ const std::vector<int>& keypointIndexes=std::vector<int>());
+ /** @overload
+ @param points2f Array of (x,y) coordinates of each keypoint
+ @param keypoints Keypoints obtained from any feature detection algorithm like SIFT/SURF/ORB
+ @param size keypoint diameter
+ @param response keypoint detector response on the keypoint (that is, strength of the keypoint)
+ @param octave pyramid octave in which the keypoint has been detected
+ @param class_id object id
+ */
+ CV_WRAP static void convert(const std::vector<Point2f>& points2f,
+ CV_OUT std::vector<KeyPoint>& keypoints,
+ float size=1, float response=1, int octave=0, int class_id=-1);
+
+ /**
+ This method computes overlap for pair of keypoints. Overlap is the ratio between area of keypoint
+ regions' intersection and area of keypoint regions' union (considering keypoint region as circle).
+ If they don't overlap, we get zero. If they coincide at same location with same size, we get 1.
+ @param kp1 First keypoint
+ @param kp2 Second keypoint
+ */
+ CV_WRAP static float overlap(const KeyPoint& kp1, const KeyPoint& kp2);
+
+ CV_PROP_RW Point2f pt; //!< coordinates of the keypoints
+ CV_PROP_RW float size; //!< diameter of the meaningful keypoint neighborhood
+ CV_PROP_RW float angle; //!< computed orientation of the keypoint (-1 if not applicable);
+ //!< it's in [0,360) degrees and measured relative to
+ //!< image coordinate system, ie in clockwise.
+ CV_PROP_RW float response; //!< the response by which the most strong keypoints have been selected. Can be used for the further sorting or subsampling
+ CV_PROP_RW int octave; //!< octave (pyramid layer) from which the keypoint has been extracted
+ CV_PROP_RW int class_id; //!< object class (if the keypoints need to be clustered by an object they belong to)
+};
+
+template<> class DataType<KeyPoint>
+{
+public:
+ typedef KeyPoint value_type;
+ typedef float work_type;
+ typedef float channel_type;
+
+ enum { generic_type = 0,
+ depth = DataType<channel_type>::depth,
+ channels = (int)(sizeof(value_type)/sizeof(channel_type)), // 7
+ fmt = DataType<channel_type>::fmt + ((channels - 1) << 8),
+ type = CV_MAKETYPE(depth, channels)
+ };
+
+ typedef Vec<channel_type, channels> vec_type;
+};
+
+
+
+//////////////////////////////// DMatch /////////////////////////////////
+
+/** @brief Class for matching keypoint descriptors
+
+query descriptor index, train descriptor index, train image index, and distance between
+descriptors.
+*/
+class CV_EXPORTS_W_SIMPLE DMatch
+{
+public:
+ CV_WRAP DMatch();
+ CV_WRAP DMatch(int _queryIdx, int _trainIdx, float _distance);
+ CV_WRAP DMatch(int _queryIdx, int _trainIdx, int _imgIdx, float _distance);
+
+ CV_PROP_RW int queryIdx; // query descriptor index
+ CV_PROP_RW int trainIdx; // train descriptor index
+ CV_PROP_RW int imgIdx; // train image index
+
+ CV_PROP_RW float distance;
+
+ // less is better
+ bool operator<(const DMatch &m) const;
+};
+
+template<> class DataType<DMatch>
+{
+public:
+ typedef DMatch value_type;
+ typedef int work_type;
+ typedef int channel_type;
+
+ enum { generic_type = 0,
+ depth = DataType<channel_type>::depth,
+ channels = (int)(sizeof(value_type)/sizeof(channel_type)), // 4
+ fmt = DataType<channel_type>::fmt + ((channels - 1) << 8),
+ type = CV_MAKETYPE(depth, channels)
+ };
+
+ typedef Vec<channel_type, channels> vec_type;
+};
+
+
+
+///////////////////////////// TermCriteria //////////////////////////////
+
+/** @brief The class defining termination criteria for iterative algorithms.
+
+You can initialize it by default constructor and then override any parameters, or the structure may
+be fully initialized using the advanced variant of the constructor.
+*/
+class CV_EXPORTS TermCriteria
+{
+public:
+ /**
+ Criteria type, can be one of: COUNT, EPS or COUNT + EPS
+ */
+ enum Type
+ {
+ COUNT=1, //!< the maximum number of iterations or elements to compute
+ MAX_ITER=COUNT, //!< ditto
+ EPS=2 //!< the desired accuracy or change in parameters at which the iterative algorithm stops
+ };
+
+ //! default constructor
+ TermCriteria();
+ /**
+ @param type The type of termination criteria, one of TermCriteria::Type
+ @param maxCount The maximum number of iterations or elements to compute.
+ @param epsilon The desired accuracy or change in parameters at which the iterative algorithm stops.
+ */
+ TermCriteria(int type, int maxCount, double epsilon);
+
+ int type; //!< the type of termination criteria: COUNT, EPS or COUNT + EPS
+ int maxCount; // the maximum number of iterations/elements
+ double epsilon; // the desired accuracy
+};
+
+
+//! @} core_basic
+
+///////////////////////// raster image moments //////////////////////////
+
+//! @addtogroup imgproc_shape
+//! @{
+
+/** @brief struct returned by cv::moments
+
+The spatial moments \f$\texttt{Moments::m}_{ji}\f$ are computed as:
+
+\f[\texttt{m} _{ji}= \sum _{x,y} \left ( \texttt{array} (x,y) \cdot x^j \cdot y^i \right )\f]
+
+The central moments \f$\texttt{Moments::mu}_{ji}\f$ are computed as:
+
+\f[\texttt{mu} _{ji}= \sum _{x,y} \left ( \texttt{array} (x,y) \cdot (x - \bar{x} )^j \cdot (y - \bar{y} )^i \right )\f]
+
+where \f$(\bar{x}, \bar{y})\f$ is the mass center:
+
+\f[\bar{x} = \frac{\texttt{m}_{10}}{\texttt{m}_{00}} , \; \bar{y} = \frac{\texttt{m}_{01}}{\texttt{m}_{00}}\f]
+
+The normalized central moments \f$\texttt{Moments::nu}_{ij}\f$ are computed as:
+
+\f[\texttt{nu} _{ji}= \frac{\texttt{mu}_{ji}}{\texttt{m}_{00}^{(i+j)/2+1}} .\f]
+
+@note
+\f$\texttt{mu}_{00}=\texttt{m}_{00}\f$, \f$\texttt{nu}_{00}=1\f$
+\f$\texttt{nu}_{10}=\texttt{mu}_{10}=\texttt{mu}_{01}=\texttt{mu}_{10}=0\f$ , hence the values are not
+stored.
+
+The moments of a contour are defined in the same way but computed using the Green's formula (see
+<http://en.wikipedia.org/wiki/Green_theorem>). So, due to a limited raster resolution, the moments
+computed for a contour are slightly different from the moments computed for the same rasterized
+contour.
+
+@note
+Since the contour moments are computed using Green formula, you may get seemingly odd results for
+contours with self-intersections, e.g. a zero area (m00) for butterfly-shaped contours.
+ */
+class CV_EXPORTS_W_MAP Moments
+{
+public:
+ //! the default constructor
+ Moments();
+ //! the full constructor
+ Moments(double m00, double m10, double m01, double m20, double m11,
+ double m02, double m30, double m21, double m12, double m03 );
+ ////! the conversion from CvMoments
+ //Moments( const CvMoments& moments );
+ ////! the conversion to CvMoments
+ //operator CvMoments() const;
+
+ //! @name spatial moments
+ //! @{
+ CV_PROP_RW double m00, m10, m01, m20, m11, m02, m30, m21, m12, m03;
+ //! @}
+
+ //! @name central moments
+ //! @{
+ CV_PROP_RW double mu20, mu11, mu02, mu30, mu21, mu12, mu03;
+ //! @}
+
+ //! @name central normalized moments
+ //! @{
+ CV_PROP_RW double nu20, nu11, nu02, nu30, nu21, nu12, nu03;
+ //! @}
+};
+
+template<> class DataType<Moments>
+{
+public:
+ typedef Moments value_type;
+ typedef double work_type;
+ typedef double channel_type;
+
+ enum { generic_type = 0,
+ depth = DataType<channel_type>::depth,
+ channels = (int)(sizeof(value_type)/sizeof(channel_type)), // 24
+ fmt = DataType<channel_type>::fmt + ((channels - 1) << 8),
+ type = CV_MAKETYPE(depth, channels)
+ };
+
+ typedef Vec<channel_type, channels> vec_type;
+};
+
+//! @} imgproc_shape
+
+//! @cond IGNORED
+
+/////////////////////////////////////////////////////////////////////////
+///////////////////////////// Implementation ////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+
+//////////////////////////////// Complex ////////////////////////////////
+
+template<typename _Tp> inline
+Complex<_Tp>::Complex()
+ : re(0), im(0) {}
+
+template<typename _Tp> inline
+Complex<_Tp>::Complex( _Tp _re, _Tp _im )
+ : re(_re), im(_im) {}
+
+template<typename _Tp> template<typename T2> inline
+Complex<_Tp>::operator Complex<T2>() const
+{
+ return Complex<T2>(saturate_cast<T2>(re), saturate_cast<T2>(im));
+}
+
+template<typename _Tp> inline
+Complex<_Tp> Complex<_Tp>::conj() const
+{
+ return Complex<_Tp>(re, -im);
+}
+
+
+template<typename _Tp> static inline
+bool operator == (const Complex<_Tp>& a, const Complex<_Tp>& b)
+{
+ return a.re == b.re && a.im == b.im;
+}
+
+template<typename _Tp> static inline
+bool operator != (const Complex<_Tp>& a, const Complex<_Tp>& b)
+{
+ return a.re != b.re || a.im != b.im;
+}
+
+template<typename _Tp> static inline
+Complex<_Tp> operator + (const Complex<_Tp>& a, const Complex<_Tp>& b)
+{
+ return Complex<_Tp>( a.re + b.re, a.im + b.im );
+}
+
+template<typename _Tp> static inline
+Complex<_Tp>& operator += (Complex<_Tp>& a, const Complex<_Tp>& b)
+{
+ a.re += b.re; a.im += b.im;
+ return a;
+}
+
+template<typename _Tp> static inline
+Complex<_Tp> operator - (const Complex<_Tp>& a, const Complex<_Tp>& b)
+{
+ return Complex<_Tp>( a.re - b.re, a.im - b.im );
+}
+
+template<typename _Tp> static inline
+Complex<_Tp>& operator -= (Complex<_Tp>& a, const Complex<_Tp>& b)
+{
+ a.re -= b.re; a.im -= b.im;
+ return a;
+}
+
+template<typename _Tp> static inline
+Complex<_Tp> operator - (const Complex<_Tp>& a)
+{
+ return Complex<_Tp>(-a.re, -a.im);
+}
+
+template<typename _Tp> static inline
+Complex<_Tp> operator * (const Complex<_Tp>& a, const Complex<_Tp>& b)
+{
+ return Complex<_Tp>( a.re*b.re - a.im*b.im, a.re*b.im + a.im*b.re );
+}
+
+template<typename _Tp> static inline
+Complex<_Tp> operator * (const Complex<_Tp>& a, _Tp b)
+{
+ return Complex<_Tp>( a.re*b, a.im*b );
+}
+
+template<typename _Tp> static inline
+Complex<_Tp> operator * (_Tp b, const Complex<_Tp>& a)
+{
+ return Complex<_Tp>( a.re*b, a.im*b );
+}
+
+template<typename _Tp> static inline
+Complex<_Tp> operator + (const Complex<_Tp>& a, _Tp b)
+{
+ return Complex<_Tp>( a.re + b, a.im );
+}
+
+template<typename _Tp> static inline
+Complex<_Tp> operator - (const Complex<_Tp>& a, _Tp b)
+{ return Complex<_Tp>( a.re - b, a.im ); }
+
+template<typename _Tp> static inline
+Complex<_Tp> operator + (_Tp b, const Complex<_Tp>& a)
+{
+ return Complex<_Tp>( a.re + b, a.im );
+}
+
+template<typename _Tp> static inline
+Complex<_Tp> operator - (_Tp b, const Complex<_Tp>& a)
+{
+ return Complex<_Tp>( b - a.re, -a.im );
+}
+
+template<typename _Tp> static inline
+Complex<_Tp>& operator += (Complex<_Tp>& a, _Tp b)
+{
+ a.re += b; return a;
+}
+
+template<typename _Tp> static inline
+Complex<_Tp>& operator -= (Complex<_Tp>& a, _Tp b)
+{
+ a.re -= b; return a;
+}
+
+template<typename _Tp> static inline
+Complex<_Tp>& operator *= (Complex<_Tp>& a, _Tp b)
+{
+ a.re *= b; a.im *= b; return a;
+}
+
+template<typename _Tp> static inline
+double abs(const Complex<_Tp>& a)
+{
+ return std::sqrt( (double)a.re*a.re + (double)a.im*a.im);
+}
+
+template<typename _Tp> static inline
+Complex<_Tp> operator / (const Complex<_Tp>& a, const Complex<_Tp>& b)
+{
+ double t = 1./((double)b.re*b.re + (double)b.im*b.im);
+ return Complex<_Tp>( (_Tp)((a.re*b.re + a.im*b.im)*t),
+ (_Tp)((-a.re*b.im + a.im*b.re)*t) );
+}
+
+template<typename _Tp> static inline
+Complex<_Tp>& operator /= (Complex<_Tp>& a, const Complex<_Tp>& b)
+{
+ return (a = a / b);
+}
+
+template<typename _Tp> static inline
+Complex<_Tp> operator / (const Complex<_Tp>& a, _Tp b)
+{
+ _Tp t = (_Tp)1/b;
+ return Complex<_Tp>( a.re*t, a.im*t );
+}
+
+template<typename _Tp> static inline
+Complex<_Tp> operator / (_Tp b, const Complex<_Tp>& a)
+{
+ return Complex<_Tp>(b)/a;
+}
+
+template<typename _Tp> static inline
+Complex<_Tp> operator /= (const Complex<_Tp>& a, _Tp b)
+{
+ _Tp t = (_Tp)1/b;
+ a.re *= t; a.im *= t; return a;
+}
+
+
+
+//////////////////////////////// 2D Point ///////////////////////////////
+
+template<typename _Tp> inline
+Point_<_Tp>::Point_()
+ : x(0), y(0) {}
+
+template<typename _Tp> inline
+Point_<_Tp>::Point_(_Tp _x, _Tp _y)
+ : x(_x), y(_y) {}
+
+template<typename _Tp> inline
+Point_<_Tp>::Point_(const Point_& pt)
+ : x(pt.x), y(pt.y) {}
+
+template<typename _Tp> inline
+Point_<_Tp>::Point_(const Size_<_Tp>& sz)
+ : x(sz.width), y(sz.height) {}
+
+template<typename _Tp> inline
+Point_<_Tp>::Point_(const Vec<_Tp,2>& v)
+ : x(v[0]), y(v[1]) {}
+
+template<typename _Tp> inline
+Point_<_Tp>& Point_<_Tp>::operator = (const Point_& pt)
+{
+ x = pt.x; y = pt.y;
+ return *this;
+}
+
+template<typename _Tp> template<typename _Tp2> inline
+Point_<_Tp>::operator Point_<_Tp2>() const
+{
+ return Point_<_Tp2>(saturate_cast<_Tp2>(x), saturate_cast<_Tp2>(y));
+}
+
+template<typename _Tp> inline
+Point_<_Tp>::operator Vec<_Tp, 2>() const
+{
+ return Vec<_Tp, 2>(x, y);
+}
+
+template<typename _Tp> inline
+_Tp Point_<_Tp>::dot(const Point_& pt) const
+{
+ return saturate_cast<_Tp>(x*pt.x + y*pt.y);
+}
+
+template<typename _Tp> inline
+double Point_<_Tp>::ddot(const Point_& pt) const
+{
+ return (double)x*pt.x + (double)y*pt.y;
+}
+
+template<typename _Tp> inline
+double Point_<_Tp>::cross(const Point_& pt) const
+{
+ return (double)x*pt.y - (double)y*pt.x;
+}
+
+template<typename _Tp> inline bool
+Point_<_Tp>::inside( const Rect_<_Tp>& r ) const
+{
+ return r.contains(*this);
+}
+
+
+template<typename _Tp> static inline
+Point_<_Tp>& operator += (Point_<_Tp>& a, const Point_<_Tp>& b)
+{
+ a.x += b.x;
+ a.y += b.y;
+ return a;
+}
+
+template<typename _Tp> static inline
+Point_<_Tp>& operator -= (Point_<_Tp>& a, const Point_<_Tp>& b)
+{
+ a.x -= b.x;
+ a.y -= b.y;
+ return a;
+}
+
+template<typename _Tp> static inline
+Point_<_Tp>& operator *= (Point_<_Tp>& a, int b)
+{
+ a.x = saturate_cast<_Tp>(a.x * b);
+ a.y = saturate_cast<_Tp>(a.y * b);
+ return a;
+}
+
+template<typename _Tp> static inline
+Point_<_Tp>& operator *= (Point_<_Tp>& a, float b)
+{
+ a.x = saturate_cast<_Tp>(a.x * b);
+ a.y = saturate_cast<_Tp>(a.y * b);
+ return a;
+}
+
+template<typename _Tp> static inline
+Point_<_Tp>& operator *= (Point_<_Tp>& a, double b)
+{
+ a.x = saturate_cast<_Tp>(a.x * b);
+ a.y = saturate_cast<_Tp>(a.y * b);
+ return a;
+}
+
+template<typename _Tp> static inline
+Point_<_Tp>& operator /= (Point_<_Tp>& a, int b)
+{
+ a.x = saturate_cast<_Tp>(a.x / b);
+ a.y = saturate_cast<_Tp>(a.y / b);
+ return a;
+}
+
+template<typename _Tp> static inline
+Point_<_Tp>& operator /= (Point_<_Tp>& a, float b)
+{
+ a.x = saturate_cast<_Tp>(a.x / b);
+ a.y = saturate_cast<_Tp>(a.y / b);
+ return a;
+}
+
+template<typename _Tp> static inline
+Point_<_Tp>& operator /= (Point_<_Tp>& a, double b)
+{
+ a.x = saturate_cast<_Tp>(a.x / b);
+ a.y = saturate_cast<_Tp>(a.y / b);
+ return a;
+}
+
+template<typename _Tp> static inline
+double norm(const Point_<_Tp>& pt)
+{
+ return std::sqrt((double)pt.x*pt.x + (double)pt.y*pt.y);
+}
+
+template<typename _Tp> static inline
+bool operator == (const Point_<_Tp>& a, const Point_<_Tp>& b)
+{
+ return a.x == b.x && a.y == b.y;
+}
+
+template<typename _Tp> static inline
+bool operator != (const Point_<_Tp>& a, const Point_<_Tp>& b)
+{
+ return a.x != b.x || a.y != b.y;
+}
+
+template<typename _Tp> static inline
+Point_<_Tp> operator + (const Point_<_Tp>& a, const Point_<_Tp>& b)
+{
+ return Point_<_Tp>( saturate_cast<_Tp>(a.x + b.x), saturate_cast<_Tp>(a.y + b.y) );
+}
+
+template<typename _Tp> static inline
+Point_<_Tp> operator - (const Point_<_Tp>& a, const Point_<_Tp>& b)
+{
+ return Point_<_Tp>( saturate_cast<_Tp>(a.x - b.x), saturate_cast<_Tp>(a.y - b.y) );
+}
+
+template<typename _Tp> static inline
+Point_<_Tp> operator - (const Point_<_Tp>& a)
+{
+ return Point_<_Tp>( saturate_cast<_Tp>(-a.x), saturate_cast<_Tp>(-a.y) );
+}
+
+template<typename _Tp> static inline
+Point_<_Tp> operator * (const Point_<_Tp>& a, int b)
+{
+ return Point_<_Tp>( saturate_cast<_Tp>(a.x*b), saturate_cast<_Tp>(a.y*b) );
+}
+
+template<typename _Tp> static inline
+Point_<_Tp> operator * (int a, const Point_<_Tp>& b)
+{
+ return Point_<_Tp>( saturate_cast<_Tp>(b.x*a), saturate_cast<_Tp>(b.y*a) );
+}
+
+template<typename _Tp> static inline
+Point_<_Tp> operator * (const Point_<_Tp>& a, float b)
+{
+ return Point_<_Tp>( saturate_cast<_Tp>(a.x*b), saturate_cast<_Tp>(a.y*b) );
+}
+
+template<typename _Tp> static inline
+Point_<_Tp> operator * (float a, const Point_<_Tp>& b)
+{
+ return Point_<_Tp>( saturate_cast<_Tp>(b.x*a), saturate_cast<_Tp>(b.y*a) );
+}
+
+template<typename _Tp> static inline
+Point_<_Tp> operator * (const Point_<_Tp>& a, double b)
+{
+ return Point_<_Tp>( saturate_cast<_Tp>(a.x*b), saturate_cast<_Tp>(a.y*b) );
+}
+
+template<typename _Tp> static inline
+Point_<_Tp> operator * (double a, const Point_<_Tp>& b)
+{
+ return Point_<_Tp>( saturate_cast<_Tp>(b.x*a), saturate_cast<_Tp>(b.y*a) );
+}
+
+template<typename _Tp> static inline
+Point_<_Tp> operator * (const Matx<_Tp, 2, 2>& a, const Point_<_Tp>& b)
+{
+ Matx<_Tp, 2, 1> tmp = a * Vec<_Tp,2>(b.x, b.y);
+ return Point_<_Tp>(tmp.val[0], tmp.val[1]);
+}
+
+template<typename _Tp> static inline
+Point3_<_Tp> operator * (const Matx<_Tp, 3, 3>& a, const Point_<_Tp>& b)
+{
+ Matx<_Tp, 3, 1> tmp = a * Vec<_Tp,3>(b.x, b.y, 1);
+ return Point3_<_Tp>(tmp.val[0], tmp.val[1], tmp.val[2]);
+}
+
+template<typename _Tp> static inline
+Point_<_Tp> operator / (const Point_<_Tp>& a, int b)
+{
+ Point_<_Tp> tmp(a);
+ tmp /= b;
+ return tmp;
+}
+
+template<typename _Tp> static inline
+Point_<_Tp> operator / (const Point_<_Tp>& a, float b)
+{
+ Point_<_Tp> tmp(a);
+ tmp /= b;
+ return tmp;
+}
+
+template<typename _Tp> static inline
+Point_<_Tp> operator / (const Point_<_Tp>& a, double b)
+{
+ Point_<_Tp> tmp(a);
+ tmp /= b;
+ return tmp;
+}
+
+
+
+//////////////////////////////// 3D Point ///////////////////////////////
+
+template<typename _Tp> inline
+Point3_<_Tp>::Point3_()
+ : x(0), y(0), z(0) {}
+
+template<typename _Tp> inline
+Point3_<_Tp>::Point3_(_Tp _x, _Tp _y, _Tp _z)
+ : x(_x), y(_y), z(_z) {}
+
+template<typename _Tp> inline
+Point3_<_Tp>::Point3_(const Point3_& pt)
+ : x(pt.x), y(pt.y), z(pt.z) {}
+
+template<typename _Tp> inline
+Point3_<_Tp>::Point3_(const Point_<_Tp>& pt)
+ : x(pt.x), y(pt.y), z(_Tp()) {}
+
+template<typename _Tp> inline
+Point3_<_Tp>::Point3_(const Vec<_Tp, 3>& v)
+ : x(v[0]), y(v[1]), z(v[2]) {}
+
+template<typename _Tp> template<typename _Tp2> inline
+Point3_<_Tp>::operator Point3_<_Tp2>() const
+{
+ return Point3_<_Tp2>(saturate_cast<_Tp2>(x), saturate_cast<_Tp2>(y), saturate_cast<_Tp2>(z));
+}
+
+#if OPENCV_ABI_COMPATIBILITY > 300
+template<typename _Tp> template<typename _Tp2> inline
+Point3_<_Tp>::operator Vec<_Tp2, 3>() const
+{
+ return Vec<_Tp2, 3>(x, y, z);
+}
+#else
+template<typename _Tp> inline
+Point3_<_Tp>::operator Vec<_Tp, 3>() const
+{
+ return Vec<_Tp, 3>(x, y, z);
+}
+#endif
+
+template<typename _Tp> inline
+Point3_<_Tp>& Point3_<_Tp>::operator = (const Point3_& pt)
+{
+ x = pt.x; y = pt.y; z = pt.z;
+ return *this;
+}
+
+template<typename _Tp> inline
+_Tp Point3_<_Tp>::dot(const Point3_& pt) const
+{
+ return saturate_cast<_Tp>(x*pt.x + y*pt.y + z*pt.z);
+}
+
+template<typename _Tp> inline
+double Point3_<_Tp>::ddot(const Point3_& pt) const
+{
+ return (double)x*pt.x + (double)y*pt.y + (double)z*pt.z;
+}
+
+template<typename _Tp> inline
+Point3_<_Tp> Point3_<_Tp>::cross(const Point3_<_Tp>& pt) const
+{
+ return Point3_<_Tp>(y*pt.z - z*pt.y, z*pt.x - x*pt.z, x*pt.y - y*pt.x);
+}
+
+
+template<typename _Tp> static inline
+Point3_<_Tp>& operator += (Point3_<_Tp>& a, const Point3_<_Tp>& b)
+{
+ a.x += b.x;
+ a.y += b.y;
+ a.z += b.z;
+ return a;
+}
+
+template<typename _Tp> static inline
+Point3_<_Tp>& operator -= (Point3_<_Tp>& a, const Point3_<_Tp>& b)
+{
+ a.x -= b.x;
+ a.y -= b.y;
+ a.z -= b.z;
+ return a;
+}
+
+template<typename _Tp> static inline
+Point3_<_Tp>& operator *= (Point3_<_Tp>& a, int b)
+{
+ a.x = saturate_cast<_Tp>(a.x * b);
+ a.y = saturate_cast<_Tp>(a.y * b);
+ a.z = saturate_cast<_Tp>(a.z * b);
+ return a;
+}
+
+template<typename _Tp> static inline
+Point3_<_Tp>& operator *= (Point3_<_Tp>& a, float b)
+{
+ a.x = saturate_cast<_Tp>(a.x * b);
+ a.y = saturate_cast<_Tp>(a.y * b);
+ a.z = saturate_cast<_Tp>(a.z * b);
+ return a;
+}
+
+template<typename _Tp> static inline
+Point3_<_Tp>& operator *= (Point3_<_Tp>& a, double b)
+{
+ a.x = saturate_cast<_Tp>(a.x * b);
+ a.y = saturate_cast<_Tp>(a.y * b);
+ a.z = saturate_cast<_Tp>(a.z * b);
+ return a;
+}
+
+template<typename _Tp> static inline
+Point3_<_Tp>& operator /= (Point3_<_Tp>& a, int b)
+{
+ a.x = saturate_cast<_Tp>(a.x / b);
+ a.y = saturate_cast<_Tp>(a.y / b);
+ a.z = saturate_cast<_Tp>(a.z / b);
+ return a;
+}
+
+template<typename _Tp> static inline
+Point3_<_Tp>& operator /= (Point3_<_Tp>& a, float b)
+{
+ a.x = saturate_cast<_Tp>(a.x / b);
+ a.y = saturate_cast<_Tp>(a.y / b);
+ a.z = saturate_cast<_Tp>(a.z / b);
+ return a;
+}
+
+template<typename _Tp> static inline
+Point3_<_Tp>& operator /= (Point3_<_Tp>& a, double b)
+{
+ a.x = saturate_cast<_Tp>(a.x / b);
+ a.y = saturate_cast<_Tp>(a.y / b);
+ a.z = saturate_cast<_Tp>(a.z / b);
+ return a;
+}
+
+template<typename _Tp> static inline
+double norm(const Point3_<_Tp>& pt)
+{
+ return std::sqrt((double)pt.x*pt.x + (double)pt.y*pt.y + (double)pt.z*pt.z);
+}
+
+template<typename _Tp> static inline
+bool operator == (const Point3_<_Tp>& a, const Point3_<_Tp>& b)
+{
+ return a.x == b.x && a.y == b.y && a.z == b.z;
+}
+
+template<typename _Tp> static inline
+bool operator != (const Point3_<_Tp>& a, const Point3_<_Tp>& b)
+{
+ return a.x != b.x || a.y != b.y || a.z != b.z;
+}
+
+template<typename _Tp> static inline
+Point3_<_Tp> operator + (const Point3_<_Tp>& a, const Point3_<_Tp>& b)
+{
+ return Point3_<_Tp>( saturate_cast<_Tp>(a.x + b.x), saturate_cast<_Tp>(a.y + b.y), saturate_cast<_Tp>(a.z + b.z));
+}
+
+template<typename _Tp> static inline
+Point3_<_Tp> operator - (const Point3_<_Tp>& a, const Point3_<_Tp>& b)
+{
+ return Point3_<_Tp>( saturate_cast<_Tp>(a.x - b.x), saturate_cast<_Tp>(a.y - b.y), saturate_cast<_Tp>(a.z - b.z));
+}
+
+template<typename _Tp> static inline
+Point3_<_Tp> operator - (const Point3_<_Tp>& a)
+{
+ return Point3_<_Tp>( saturate_cast<_Tp>(-a.x), saturate_cast<_Tp>(-a.y), saturate_cast<_Tp>(-a.z) );
+}
+
+template<typename _Tp> static inline
+Point3_<_Tp> operator * (const Point3_<_Tp>& a, int b)
+{
+ return Point3_<_Tp>( saturate_cast<_Tp>(a.x*b), saturate_cast<_Tp>(a.y*b), saturate_cast<_Tp>(a.z*b) );
+}
+
+template<typename _Tp> static inline
+Point3_<_Tp> operator * (int a, const Point3_<_Tp>& b)
+{
+ return Point3_<_Tp>( saturate_cast<_Tp>(b.x * a), saturate_cast<_Tp>(b.y * a), saturate_cast<_Tp>(b.z * a) );
+}
+
+template<typename _Tp> static inline
+Point3_<_Tp> operator * (const Point3_<_Tp>& a, float b)
+{
+ return Point3_<_Tp>( saturate_cast<_Tp>(a.x * b), saturate_cast<_Tp>(a.y * b), saturate_cast<_Tp>(a.z * b) );
+}
+
+template<typename _Tp> static inline
+Point3_<_Tp> operator * (float a, const Point3_<_Tp>& b)
+{
+ return Point3_<_Tp>( saturate_cast<_Tp>(b.x * a), saturate_cast<_Tp>(b.y * a), saturate_cast<_Tp>(b.z * a) );
+}
+
+template<typename _Tp> static inline
+Point3_<_Tp> operator * (const Point3_<_Tp>& a, double b)
+{
+ return Point3_<_Tp>( saturate_cast<_Tp>(a.x * b), saturate_cast<_Tp>(a.y * b), saturate_cast<_Tp>(a.z * b) );
+}
+
+template<typename _Tp> static inline
+Point3_<_Tp> operator * (double a, const Point3_<_Tp>& b)
+{
+ return Point3_<_Tp>( saturate_cast<_Tp>(b.x * a), saturate_cast<_Tp>(b.y * a), saturate_cast<_Tp>(b.z * a) );
+}
+
+template<typename _Tp> static inline
+Point3_<_Tp> operator * (const Matx<_Tp, 3, 3>& a, const Point3_<_Tp>& b)
+{
+ Matx<_Tp, 3, 1> tmp = a * Vec<_Tp,3>(b.x, b.y, b.z);
+ return Point3_<_Tp>(tmp.val[0], tmp.val[1], tmp.val[2]);
+}
+
+template<typename _Tp> static inline
+Matx<_Tp, 4, 1> operator * (const Matx<_Tp, 4, 4>& a, const Point3_<_Tp>& b)
+{
+ return a * Matx<_Tp, 4, 1>(b.x, b.y, b.z, 1);
+}
+
+template<typename _Tp> static inline
+Point3_<_Tp> operator / (const Point3_<_Tp>& a, int b)
+{
+ Point3_<_Tp> tmp(a);
+ tmp /= b;
+ return tmp;
+}
+
+template<typename _Tp> static inline
+Point3_<_Tp> operator / (const Point3_<_Tp>& a, float b)
+{
+ Point3_<_Tp> tmp(a);
+ tmp /= b;
+ return tmp;
+}
+
+template<typename _Tp> static inline
+Point3_<_Tp> operator / (const Point3_<_Tp>& a, double b)
+{
+ Point3_<_Tp> tmp(a);
+ tmp /= b;
+ return tmp;
+}
+
+
+
+////////////////////////////////// Size /////////////////////////////////
+
+template<typename _Tp> inline
+Size_<_Tp>::Size_()
+ : width(0), height(0) {}
+
+template<typename _Tp> inline
+Size_<_Tp>::Size_(_Tp _width, _Tp _height)
+ : width(_width), height(_height) {}
+
+template<typename _Tp> inline
+Size_<_Tp>::Size_(const Size_& sz)
+ : width(sz.width), height(sz.height) {}
+
+template<typename _Tp> inline
+Size_<_Tp>::Size_(const Point_<_Tp>& pt)
+ : width(pt.x), height(pt.y) {}
+
+template<typename _Tp> template<typename _Tp2> inline
+Size_<_Tp>::operator Size_<_Tp2>() const
+{
+ return Size_<_Tp2>(saturate_cast<_Tp2>(width), saturate_cast<_Tp2>(height));
+}
+
+template<typename _Tp> inline
+Size_<_Tp>& Size_<_Tp>::operator = (const Size_<_Tp>& sz)
+{
+ width = sz.width; height = sz.height;
+ return *this;
+}
+
+template<typename _Tp> inline
+_Tp Size_<_Tp>::area() const
+{
+ return width * height;
+}
+
+template<typename _Tp> static inline
+Size_<_Tp>& operator *= (Size_<_Tp>& a, _Tp b)
+{
+ a.width *= b;
+ a.height *= b;
+ return a;
+}
+
+template<typename _Tp> static inline
+Size_<_Tp> operator * (const Size_<_Tp>& a, _Tp b)
+{
+ Size_<_Tp> tmp(a);
+ tmp *= b;
+ return tmp;
+}
+
+template<typename _Tp> static inline
+Size_<_Tp>& operator /= (Size_<_Tp>& a, _Tp b)
+{
+ a.width /= b;
+ a.height /= b;
+ return a;
+}
+
+template<typename _Tp> static inline
+Size_<_Tp> operator / (const Size_<_Tp>& a, _Tp b)
+{
+ Size_<_Tp> tmp(a);
+ tmp /= b;
+ return tmp;
+}
+
+template<typename _Tp> static inline
+Size_<_Tp>& operator += (Size_<_Tp>& a, const Size_<_Tp>& b)
+{
+ a.width += b.width;
+ a.height += b.height;
+ return a;
+}
+
+template<typename _Tp> static inline
+Size_<_Tp> operator + (const Size_<_Tp>& a, const Size_<_Tp>& b)
+{
+ Size_<_Tp> tmp(a);
+ tmp += b;
+ return tmp;
+}
+
+template<typename _Tp> static inline
+Size_<_Tp>& operator -= (Size_<_Tp>& a, const Size_<_Tp>& b)
+{
+ a.width -= b.width;
+ a.height -= b.height;
+ return a;
+}
+
+template<typename _Tp> static inline
+Size_<_Tp> operator - (const Size_<_Tp>& a, const Size_<_Tp>& b)
+{
+ Size_<_Tp> tmp(a);
+ tmp -= b;
+ return tmp;
+}
+
+template<typename _Tp> static inline
+bool operator == (const Size_<_Tp>& a, const Size_<_Tp>& b)
+{
+ return a.width == b.width && a.height == b.height;
+}
+
+template<typename _Tp> static inline
+bool operator != (const Size_<_Tp>& a, const Size_<_Tp>& b)
+{
+ return !(a == b);
+}
+
+
+
+////////////////////////////////// Rect /////////////////////////////////
+
+template<typename _Tp> inline
+Rect_<_Tp>::Rect_()
+ : x(0), y(0), width(0), height(0) {}
+
+template<typename _Tp> inline
+Rect_<_Tp>::Rect_(_Tp _x, _Tp _y, _Tp _width, _Tp _height)
+ : x(_x), y(_y), width(_width), height(_height) {}
+
+template<typename _Tp> inline
+Rect_<_Tp>::Rect_(const Rect_<_Tp>& r)
+ : x(r.x), y(r.y), width(r.width), height(r.height) {}
+
+template<typename _Tp> inline
+Rect_<_Tp>::Rect_(const Point_<_Tp>& org, const Size_<_Tp>& sz)
+ : x(org.x), y(org.y), width(sz.width), height(sz.height) {}
+
+template<typename _Tp> inline
+Rect_<_Tp>::Rect_(const Point_<_Tp>& pt1, const Point_<_Tp>& pt2)
+{
+ x = std::min(pt1.x, pt2.x);
+ y = std::min(pt1.y, pt2.y);
+ width = std::max(pt1.x, pt2.x) - x;
+ height = std::max(pt1.y, pt2.y) - y;
+}
+
+template<typename _Tp> inline
+Rect_<_Tp>& Rect_<_Tp>::operator = ( const Rect_<_Tp>& r )
+{
+ x = r.x;
+ y = r.y;
+ width = r.width;
+ height = r.height;
+ return *this;
+}
+
+template<typename _Tp> inline
+Point_<_Tp> Rect_<_Tp>::tl() const
+{
+ return Point_<_Tp>(x,y);
+}
+
+template<typename _Tp> inline
+Point_<_Tp> Rect_<_Tp>::br() const
+{
+ return Point_<_Tp>(x + width, y + height);
+}
+
+template<typename _Tp> inline
+Size_<_Tp> Rect_<_Tp>::size() const
+{
+ return Size_<_Tp>(width, height);
+}
+
+template<typename _Tp> inline
+_Tp Rect_<_Tp>::area() const
+{
+ return width * height;
+}
+
+template<typename _Tp> template<typename _Tp2> inline
+Rect_<_Tp>::operator Rect_<_Tp2>() const
+{
+ return Rect_<_Tp2>(saturate_cast<_Tp2>(x), saturate_cast<_Tp2>(y), saturate_cast<_Tp2>(width), saturate_cast<_Tp2>(height));
+}
+
+template<typename _Tp> inline
+bool Rect_<_Tp>::contains(const Point_<_Tp>& pt) const
+{
+ return x <= pt.x && pt.x < x + width && y <= pt.y && pt.y < y + height;
+}
+
+
+template<typename _Tp> static inline
+Rect_<_Tp>& operator += ( Rect_<_Tp>& a, const Point_<_Tp>& b )
+{
+ a.x += b.x;
+ a.y += b.y;
+ return a;
+}
+
+template<typename _Tp> static inline
+Rect_<_Tp>& operator -= ( Rect_<_Tp>& a, const Point_<_Tp>& b )
+{
+ a.x -= b.x;
+ a.y -= b.y;
+ return a;
+}
+
+template<typename _Tp> static inline
+Rect_<_Tp>& operator += ( Rect_<_Tp>& a, const Size_<_Tp>& b )
+{
+ a.width += b.width;
+ a.height += b.height;
+ return a;
+}
+
+template<typename _Tp> static inline
+Rect_<_Tp>& operator -= ( Rect_<_Tp>& a, const Size_<_Tp>& b )
+{
+ a.width -= b.width;
+ a.height -= b.height;
+ return a;
+}
+
+template<typename _Tp> static inline
+Rect_<_Tp>& operator &= ( Rect_<_Tp>& a, const Rect_<_Tp>& b )
+{
+ _Tp x1 = std::max(a.x, b.x);
+ _Tp y1 = std::max(a.y, b.y);
+ a.width = std::min(a.x + a.width, b.x + b.width) - x1;
+ a.height = std::min(a.y + a.height, b.y + b.height) - y1;
+ a.x = x1;
+ a.y = y1;
+ if( a.width <= 0 || a.height <= 0 )
+ a = Rect();
+ return a;
+}
+
+template<typename _Tp> static inline
+Rect_<_Tp>& operator |= ( Rect_<_Tp>& a, const Rect_<_Tp>& b )
+{
+ _Tp x1 = std::min(a.x, b.x);
+ _Tp y1 = std::min(a.y, b.y);
+ a.width = std::max(a.x + a.width, b.x + b.width) - x1;
+ a.height = std::max(a.y + a.height, b.y + b.height) - y1;
+ a.x = x1;
+ a.y = y1;
+ return a;
+}
+
+template<typename _Tp> static inline
+bool operator == (const Rect_<_Tp>& a, const Rect_<_Tp>& b)
+{
+ return a.x == b.x && a.y == b.y && a.width == b.width && a.height == b.height;
+}
+
+template<typename _Tp> static inline
+bool operator != (const Rect_<_Tp>& a, const Rect_<_Tp>& b)
+{
+ return a.x != b.x || a.y != b.y || a.width != b.width || a.height != b.height;
+}
+
+template<typename _Tp> static inline
+Rect_<_Tp> operator + (const Rect_<_Tp>& a, const Point_<_Tp>& b)
+{
+ return Rect_<_Tp>( a.x + b.x, a.y + b.y, a.width, a.height );
+}
+
+template<typename _Tp> static inline
+Rect_<_Tp> operator - (const Rect_<_Tp>& a, const Point_<_Tp>& b)
+{
+ return Rect_<_Tp>( a.x - b.x, a.y - b.y, a.width, a.height );
+}
+
+template<typename _Tp> static inline
+Rect_<_Tp> operator + (const Rect_<_Tp>& a, const Size_<_Tp>& b)
+{
+ return Rect_<_Tp>( a.x, a.y, a.width + b.width, a.height + b.height );
+}
+
+template<typename _Tp> static inline
+Rect_<_Tp> operator & (const Rect_<_Tp>& a, const Rect_<_Tp>& b)
+{
+ Rect_<_Tp> c = a;
+ return c &= b;
+}
+
+template<typename _Tp> static inline
+Rect_<_Tp> operator | (const Rect_<_Tp>& a, const Rect_<_Tp>& b)
+{
+ Rect_<_Tp> c = a;
+ return c |= b;
+}
+
+/**
+ * @brief measure dissimilarity between two sample sets
+ *
+ * computes the complement of the Jaccard Index as described in <https://en.wikipedia.org/wiki/Jaccard_index>.
+ * For rectangles this reduces to computing the intersection over the union.
+ */
+template<typename _Tp> static inline
+double jaccardDistance(const Rect_<_Tp>& a, const Rect_<_Tp>& b) {
+ _Tp Aa = a.area();
+ _Tp Ab = b.area();
+
+ if ((Aa + Ab) <= std::numeric_limits<_Tp>::epsilon()) {
+ // jaccard_index = 1 -> distance = 0
+ return 0.0;
+ }
+
+ double Aab = (a & b).area();
+ // distance = 1 - jaccard_index
+ return 1.0 - Aab / (Aa + Ab - Aab);
+}
+
+////////////////////////////// RotatedRect //////////////////////////////
+
+inline
+RotatedRect::RotatedRect()
+ : center(), size(), angle(0) {}
+
+inline
+RotatedRect::RotatedRect(const Point2f& _center, const Size2f& _size, float _angle)
+ : center(_center), size(_size), angle(_angle) {}
+
+
+
+///////////////////////////////// Range /////////////////////////////////
+
+inline
+Range::Range()
+ : start(0), end(0) {}
+
+inline
+Range::Range(int _start, int _end)
+ : start(_start), end(_end) {}
+
+inline
+int Range::size() const
+{
+ return end - start;
+}
+
+inline
+bool Range::empty() const
+{
+ return start == end;
+}
+
+inline
+Range Range::all()
+{
+ return Range(INT_MIN, INT_MAX);
+}
+
+
+static inline
+bool operator == (const Range& r1, const Range& r2)
+{
+ return r1.start == r2.start && r1.end == r2.end;
+}
+
+static inline
+bool operator != (const Range& r1, const Range& r2)
+{
+ return !(r1 == r2);
+}
+
+static inline
+bool operator !(const Range& r)
+{
+ return r.start == r.end;
+}
+
+static inline
+Range operator & (const Range& r1, const Range& r2)
+{
+ Range r(std::max(r1.start, r2.start), std::min(r1.end, r2.end));
+ r.end = std::max(r.end, r.start);
+ return r;
+}
+
+static inline
+Range& operator &= (Range& r1, const Range& r2)
+{
+ r1 = r1 & r2;
+ return r1;
+}
+
+static inline
+Range operator + (const Range& r1, int delta)
+{
+ return Range(r1.start + delta, r1.end + delta);
+}
+
+static inline
+Range operator + (int delta, const Range& r1)
+{
+ return Range(r1.start + delta, r1.end + delta);
+}
+
+static inline
+Range operator - (const Range& r1, int delta)
+{
+ return r1 + (-delta);
+}
+
+
+
+///////////////////////////////// Scalar ////////////////////////////////
+
+template<typename _Tp> inline
+Scalar_<_Tp>::Scalar_()
+{
+ this->val[0] = this->val[1] = this->val[2] = this->val[3] = 0;
+}
+
+template<typename _Tp> inline
+Scalar_<_Tp>::Scalar_(_Tp v0, _Tp v1, _Tp v2, _Tp v3)
+{
+ this->val[0] = v0;
+ this->val[1] = v1;
+ this->val[2] = v2;
+ this->val[3] = v3;
+}
+
+template<typename _Tp> template<typename _Tp2, int cn> inline
+Scalar_<_Tp>::Scalar_(const Vec<_Tp2, cn>& v)
+{
+ int i;
+ for( i = 0; i < (cn < 4 ? cn : 4); i++ )
+ this->val[i] = cv::saturate_cast<_Tp>(v.val[i]);
+ for( ; i < 4; i++ )
+ this->val[i] = 0;
+}
+
+template<typename _Tp> inline
+Scalar_<_Tp>::Scalar_(_Tp v0)
+{
+ this->val[0] = v0;
+ this->val[1] = this->val[2] = this->val[3] = 0;
+}
+
+template<typename _Tp> inline
+Scalar_<_Tp> Scalar_<_Tp>::all(_Tp v0)
+{
+ return Scalar_<_Tp>(v0, v0, v0, v0);
+}
+
+
+template<typename _Tp> inline
+Scalar_<_Tp> Scalar_<_Tp>::mul(const Scalar_<_Tp>& a, double scale ) const
+{
+ return Scalar_<_Tp>(saturate_cast<_Tp>(this->val[0] * a.val[0] * scale),
+ saturate_cast<_Tp>(this->val[1] * a.val[1] * scale),
+ saturate_cast<_Tp>(this->val[2] * a.val[2] * scale),
+ saturate_cast<_Tp>(this->val[3] * a.val[3] * scale));
+}
+
+template<typename _Tp> inline
+Scalar_<_Tp> Scalar_<_Tp>::conj() const
+{
+ return Scalar_<_Tp>(saturate_cast<_Tp>( this->val[0]),
+ saturate_cast<_Tp>(-this->val[1]),
+ saturate_cast<_Tp>(-this->val[2]),
+ saturate_cast<_Tp>(-this->val[3]));
+}
+
+template<typename _Tp> inline
+bool Scalar_<_Tp>::isReal() const
+{
+ return this->val[1] == 0 && this->val[2] == 0 && this->val[3] == 0;
+}
+
+
+template<typename _Tp> template<typename T2> inline
+Scalar_<_Tp>::operator Scalar_<T2>() const
+{
+ return Scalar_<T2>(saturate_cast<T2>(this->val[0]),
+ saturate_cast<T2>(this->val[1]),
+ saturate_cast<T2>(this->val[2]),
+ saturate_cast<T2>(this->val[3]));
+}
+
+
+template<typename _Tp> static inline
+Scalar_<_Tp>& operator += (Scalar_<_Tp>& a, const Scalar_<_Tp>& b)
+{
+ a.val[0] += b.val[0];
+ a.val[1] += b.val[1];
+ a.val[2] += b.val[2];
+ a.val[3] += b.val[3];
+ return a;
+}
+
+template<typename _Tp> static inline
+Scalar_<_Tp>& operator -= (Scalar_<_Tp>& a, const Scalar_<_Tp>& b)
+{
+ a.val[0] -= b.val[0];
+ a.val[1] -= b.val[1];
+ a.val[2] -= b.val[2];
+ a.val[3] -= b.val[3];
+ return a;
+}
+
+template<typename _Tp> static inline
+Scalar_<_Tp>& operator *= ( Scalar_<_Tp>& a, _Tp v )
+{
+ a.val[0] *= v;
+ a.val[1] *= v;
+ a.val[2] *= v;
+ a.val[3] *= v;
+ return a;
+}
+
+template<typename _Tp> static inline
+bool operator == ( const Scalar_<_Tp>& a, const Scalar_<_Tp>& b )
+{
+ return a.val[0] == b.val[0] && a.val[1] == b.val[1] &&
+ a.val[2] == b.val[2] && a.val[3] == b.val[3];
+}
+
+template<typename _Tp> static inline
+bool operator != ( const Scalar_<_Tp>& a, const Scalar_<_Tp>& b )
+{
+ return a.val[0] != b.val[0] || a.val[1] != b.val[1] ||
+ a.val[2] != b.val[2] || a.val[3] != b.val[3];
+}
+
+template<typename _Tp> static inline
+Scalar_<_Tp> operator + (const Scalar_<_Tp>& a, const Scalar_<_Tp>& b)
+{
+ return Scalar_<_Tp>(a.val[0] + b.val[0],
+ a.val[1] + b.val[1],
+ a.val[2] + b.val[2],
+ a.val[3] + b.val[3]);
+}
+
+template<typename _Tp> static inline
+Scalar_<_Tp> operator - (const Scalar_<_Tp>& a, const Scalar_<_Tp>& b)
+{
+ return Scalar_<_Tp>(saturate_cast<_Tp>(a.val[0] - b.val[0]),
+ saturate_cast<_Tp>(a.val[1] - b.val[1]),
+ saturate_cast<_Tp>(a.val[2] - b.val[2]),
+ saturate_cast<_Tp>(a.val[3] - b.val[3]));
+}
+
+template<typename _Tp> static inline
+Scalar_<_Tp> operator * (const Scalar_<_Tp>& a, _Tp alpha)
+{
+ return Scalar_<_Tp>(a.val[0] * alpha,
+ a.val[1] * alpha,
+ a.val[2] * alpha,
+ a.val[3] * alpha);
+}
+
+template<typename _Tp> static inline
+Scalar_<_Tp> operator * (_Tp alpha, const Scalar_<_Tp>& a)
+{
+ return a*alpha;
+}
+
+template<typename _Tp> static inline
+Scalar_<_Tp> operator - (const Scalar_<_Tp>& a)
+{
+ return Scalar_<_Tp>(saturate_cast<_Tp>(-a.val[0]),
+ saturate_cast<_Tp>(-a.val[1]),
+ saturate_cast<_Tp>(-a.val[2]),
+ saturate_cast<_Tp>(-a.val[3]));
+}
+
+
+template<typename _Tp> static inline
+Scalar_<_Tp> operator * (const Scalar_<_Tp>& a, const Scalar_<_Tp>& b)
+{
+ return Scalar_<_Tp>(saturate_cast<_Tp>(a[0]*b[0] - a[1]*b[1] - a[2]*b[2] - a[3]*b[3]),
+ saturate_cast<_Tp>(a[0]*b[1] + a[1]*b[0] + a[2]*b[3] - a[3]*b[2]),
+ saturate_cast<_Tp>(a[0]*b[2] - a[1]*b[3] + a[2]*b[0] + a[3]*b[1]),
+ saturate_cast<_Tp>(a[0]*b[3] + a[1]*b[2] - a[2]*b[1] + a[3]*b[0]));
+}
+
+template<typename _Tp> static inline
+Scalar_<_Tp>& operator *= (Scalar_<_Tp>& a, const Scalar_<_Tp>& b)
+{
+ a = a * b;
+ return a;
+}
+
+template<typename _Tp> static inline
+Scalar_<_Tp> operator / (const Scalar_<_Tp>& a, _Tp alpha)
+{
+ return Scalar_<_Tp>(a.val[0] / alpha,
+ a.val[1] / alpha,
+ a.val[2] / alpha,
+ a.val[3] / alpha);
+}
+
+template<typename _Tp> static inline
+Scalar_<float> operator / (const Scalar_<float>& a, float alpha)
+{
+ float s = 1 / alpha;
+ return Scalar_<float>(a.val[0] * s, a.val[1] * s, a.val[2] * s, a.val[3] * s);
+}
+
+template<typename _Tp> static inline
+Scalar_<double> operator / (const Scalar_<double>& a, double alpha)
+{
+ double s = 1 / alpha;
+ return Scalar_<double>(a.val[0] * s, a.val[1] * s, a.val[2] * s, a.val[3] * s);
+}
+
+template<typename _Tp> static inline
+Scalar_<_Tp>& operator /= (Scalar_<_Tp>& a, _Tp alpha)
+{
+ a = a / alpha;
+ return a;
+}
+
+template<typename _Tp> static inline
+Scalar_<_Tp> operator / (_Tp a, const Scalar_<_Tp>& b)
+{
+ _Tp s = a / (b[0]*b[0] + b[1]*b[1] + b[2]*b[2] + b[3]*b[3]);
+ return b.conj() * s;
+}
+
+template<typename _Tp> static inline
+Scalar_<_Tp> operator / (const Scalar_<_Tp>& a, const Scalar_<_Tp>& b)
+{
+ return a * ((_Tp)1 / b);
+}
+
+template<typename _Tp> static inline
+Scalar_<_Tp>& operator /= (Scalar_<_Tp>& a, const Scalar_<_Tp>& b)
+{
+ a = a / b;
+ return a;
+}
+
+template<typename _Tp> static inline
+Scalar operator * (const Matx<_Tp, 4, 4>& a, const Scalar& b)
+{
+ Matx<double, 4, 1> c((Matx<double, 4, 4>)a, b, Matx_MatMulOp());
+ return reinterpret_cast<const Scalar&>(c);
+}
+
+template<> inline
+Scalar operator * (const Matx<double, 4, 4>& a, const Scalar& b)
+{
+ Matx<double, 4, 1> c(a, b, Matx_MatMulOp());
+ return reinterpret_cast<const Scalar&>(c);
+}
+
+
+
+//////////////////////////////// KeyPoint ///////////////////////////////
+
+inline
+KeyPoint::KeyPoint()
+ : pt(0,0), size(0), angle(-1), response(0), octave(0), class_id(-1) {}
+
+inline
+KeyPoint::KeyPoint(Point2f _pt, float _size, float _angle, float _response, int _octave, int _class_id)
+ : pt(_pt), size(_size), angle(_angle), response(_response), octave(_octave), class_id(_class_id) {}
+
+inline
+KeyPoint::KeyPoint(float x, float y, float _size, float _angle, float _response, int _octave, int _class_id)
+ : pt(x, y), size(_size), angle(_angle), response(_response), octave(_octave), class_id(_class_id) {}
+
+
+
+///////////////////////////////// DMatch ////////////////////////////////
+
+inline
+DMatch::DMatch()
+ : queryIdx(-1), trainIdx(-1), imgIdx(-1), distance(FLT_MAX) {}
+
+inline
+DMatch::DMatch(int _queryIdx, int _trainIdx, float _distance)
+ : queryIdx(_queryIdx), trainIdx(_trainIdx), imgIdx(-1), distance(_distance) {}
+
+inline
+DMatch::DMatch(int _queryIdx, int _trainIdx, int _imgIdx, float _distance)
+ : queryIdx(_queryIdx), trainIdx(_trainIdx), imgIdx(_imgIdx), distance(_distance) {}
+
+inline
+bool DMatch::operator < (const DMatch &m) const
+{
+ return distance < m.distance;
+}
+
+
+
+////////////////////////////// TermCriteria /////////////////////////////
+
+inline
+TermCriteria::TermCriteria()
+ : type(0), maxCount(0), epsilon(0) {}
+
+inline
+TermCriteria::TermCriteria(int _type, int _maxCount, double _epsilon)
+ : type(_type), maxCount(_maxCount), epsilon(_epsilon) {}
+
+//! @endcond
+
+} // cv
+
+#endif //OPENCV_CORE_TYPES_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/core/types_c.h Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,1837 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_CORE_TYPES_H
+#define OPENCV_CORE_TYPES_H
+
+#ifdef HAVE_IPL
+# ifndef __IPL_H__
+# if defined WIN32 || defined _WIN32
+# include <ipl.h>
+# else
+# include <ipl/ipl.h>
+# endif
+# endif
+#elif defined __IPL_H__
+# define HAVE_IPL
+#endif
+
+#include "opencv2/core/cvdef.h"
+
+#ifndef SKIP_INCLUDES
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <float.h>
+#endif // SKIP_INCLUDES
+
+#if defined WIN32 || defined _WIN32
+# define CV_CDECL __cdecl
+# define CV_STDCALL __stdcall
+#else
+# define CV_CDECL
+# define CV_STDCALL
+#endif
+
+#ifndef CV_DEFAULT
+# ifdef __cplusplus
+# define CV_DEFAULT(val) = val
+# else
+# define CV_DEFAULT(val)
+# endif
+#endif
+
+#ifndef CV_EXTERN_C_FUNCPTR
+# ifdef __cplusplus
+# define CV_EXTERN_C_FUNCPTR(x) extern "C" { typedef x; }
+# else
+# define CV_EXTERN_C_FUNCPTR(x) typedef x
+# endif
+#endif
+
+#ifndef CVAPI
+# define CVAPI(rettype) CV_EXTERN_C CV_EXPORTS rettype CV_CDECL
+#endif
+
+#ifndef CV_IMPL
+# define CV_IMPL CV_EXTERN_C
+#endif
+
+#ifdef __cplusplus
+# include "opencv2/core.hpp"
+#endif
+
+/** @addtogroup core_c
+ @{
+*/
+
+/** @brief This is the "metatype" used *only* as a function parameter.
+
+It denotes that the function accepts arrays of multiple types, such as IplImage*, CvMat* or even
+CvSeq* sometimes. The particular array type is determined at runtime by analyzing the first 4
+bytes of the header. In C++ interface the role of CvArr is played by InputArray and OutputArray.
+ */
+typedef void CvArr;
+
+typedef int CVStatus;
+
+/** @see cv::Error::Code */
+enum {
+ CV_StsOk= 0, /**< everything is ok */
+ CV_StsBackTrace= -1, /**< pseudo error for back trace */
+ CV_StsError= -2, /**< unknown /unspecified error */
+ CV_StsInternal= -3, /**< internal error (bad state) */
+ CV_StsNoMem= -4, /**< insufficient memory */
+ CV_StsBadArg= -5, /**< function arg/param is bad */
+ CV_StsBadFunc= -6, /**< unsupported function */
+ CV_StsNoConv= -7, /**< iter. didn't converge */
+ CV_StsAutoTrace= -8, /**< tracing */
+ CV_HeaderIsNull= -9, /**< image header is NULL */
+ CV_BadImageSize= -10, /**< image size is invalid */
+ CV_BadOffset= -11, /**< offset is invalid */
+ CV_BadDataPtr= -12, /**/
+ CV_BadStep= -13, /**/
+ CV_BadModelOrChSeq= -14, /**/
+ CV_BadNumChannels= -15, /**/
+ CV_BadNumChannel1U= -16, /**/
+ CV_BadDepth= -17, /**/
+ CV_BadAlphaChannel= -18, /**/
+ CV_BadOrder= -19, /**/
+ CV_BadOrigin= -20, /**/
+ CV_BadAlign= -21, /**/
+ CV_BadCallBack= -22, /**/
+ CV_BadTileSize= -23, /**/
+ CV_BadCOI= -24, /**/
+ CV_BadROISize= -25, /**/
+ CV_MaskIsTiled= -26, /**/
+ CV_StsNullPtr= -27, /**< null pointer */
+ CV_StsVecLengthErr= -28, /**< incorrect vector length */
+ CV_StsFilterStructContentErr= -29, /**< incorr. filter structure content */
+ CV_StsKernelStructContentErr= -30, /**< incorr. transform kernel content */
+ CV_StsFilterOffsetErr= -31, /**< incorrect filter offset value */
+ CV_StsBadSize= -201, /**< the input/output structure size is incorrect */
+ CV_StsDivByZero= -202, /**< division by zero */
+ CV_StsInplaceNotSupported= -203, /**< in-place operation is not supported */
+ CV_StsObjectNotFound= -204, /**< request can't be completed */
+ CV_StsUnmatchedFormats= -205, /**< formats of input/output arrays differ */
+ CV_StsBadFlag= -206, /**< flag is wrong or not supported */
+ CV_StsBadPoint= -207, /**< bad CvPoint */
+ CV_StsBadMask= -208, /**< bad format of mask (neither 8uC1 nor 8sC1)*/
+ CV_StsUnmatchedSizes= -209, /**< sizes of input/output structures do not match */
+ CV_StsUnsupportedFormat= -210, /**< the data format/type is not supported by the function*/
+ CV_StsOutOfRange= -211, /**< some of parameters are out of range */
+ CV_StsParseError= -212, /**< invalid syntax/structure of the parsed file */
+ CV_StsNotImplemented= -213, /**< the requested function/feature is not implemented */
+ CV_StsBadMemBlock= -214, /**< an allocated block has been corrupted */
+ CV_StsAssert= -215, /**< assertion failed */
+ CV_GpuNotSupported= -216,
+ CV_GpuApiCallError= -217,
+ CV_OpenGlNotSupported= -218,
+ CV_OpenGlApiCallError= -219,
+ CV_OpenCLApiCallError= -220,
+ CV_OpenCLDoubleNotSupported= -221,
+ CV_OpenCLInitError= -222,
+ CV_OpenCLNoAMDBlasFft= -223
+};
+
+/****************************************************************************************\
+* Common macros and inline functions *
+\****************************************************************************************/
+
+#define CV_SWAP(a,b,t) ((t) = (a), (a) = (b), (b) = (t))
+
+/** min & max without jumps */
+#define CV_IMIN(a, b) ((a) ^ (((a)^(b)) & (((a) < (b)) - 1)))
+
+#define CV_IMAX(a, b) ((a) ^ (((a)^(b)) & (((a) > (b)) - 1)))
+
+/** absolute value without jumps */
+#ifndef __cplusplus
+# define CV_IABS(a) (((a) ^ ((a) < 0 ? -1 : 0)) - ((a) < 0 ? -1 : 0))
+#else
+# define CV_IABS(a) abs(a)
+#endif
+#define CV_CMP(a,b) (((a) > (b)) - ((a) < (b)))
+#define CV_SIGN(a) CV_CMP((a),0)
+
+#define cvInvSqrt(value) ((float)(1./sqrt(value)))
+#define cvSqrt(value) ((float)sqrt(value))
+
+
+/*************** Random number generation *******************/
+
+typedef uint64 CvRNG;
+
+#define CV_RNG_COEFF 4164903690U
+
+/** @brief Initializes a random number generator state.
+
+The function initializes a random number generator and returns the state. The pointer to the state
+can be then passed to the cvRandInt, cvRandReal and cvRandArr functions. In the current
+implementation a multiply-with-carry generator is used.
+@param seed 64-bit value used to initiate a random sequence
+@sa the C++ class RNG replaced CvRNG.
+ */
+CV_INLINE CvRNG cvRNG( int64 seed CV_DEFAULT(-1))
+{
+ CvRNG rng = seed ? (uint64)seed : (uint64)(int64)-1;
+ return rng;
+}
+
+/** @brief Returns a 32-bit unsigned integer and updates RNG.
+
+The function returns a uniformly-distributed random 32-bit unsigned integer and updates the RNG
+state. It is similar to the rand() function from the C runtime library, except that OpenCV functions
+always generates a 32-bit random number, regardless of the platform.
+@param rng CvRNG state initialized by cvRNG.
+ */
+CV_INLINE unsigned cvRandInt( CvRNG* rng )
+{
+ uint64 temp = *rng;
+ temp = (uint64)(unsigned)temp*CV_RNG_COEFF + (temp >> 32);
+ *rng = temp;
+ return (unsigned)temp;
+}
+
+/** @brief Returns a floating-point random number and updates RNG.
+
+The function returns a uniformly-distributed random floating-point number between 0 and 1 (1 is not
+included).
+@param rng RNG state initialized by cvRNG
+ */
+CV_INLINE double cvRandReal( CvRNG* rng )
+{
+ return cvRandInt(rng)*2.3283064365386962890625e-10 /* 2^-32 */;
+}
+
+/****************************************************************************************\
+* Image type (IplImage) *
+\****************************************************************************************/
+
+#ifndef HAVE_IPL
+
+/*
+ * The following definitions (until #endif)
+ * is an extract from IPL headers.
+ * Copyright (c) 1995 Intel Corporation.
+ */
+#define IPL_DEPTH_SIGN 0x80000000
+
+#define IPL_DEPTH_1U 1
+#define IPL_DEPTH_8U 8
+#define IPL_DEPTH_16U 16
+#define IPL_DEPTH_32F 32
+
+#define IPL_DEPTH_8S (IPL_DEPTH_SIGN| 8)
+#define IPL_DEPTH_16S (IPL_DEPTH_SIGN|16)
+#define IPL_DEPTH_32S (IPL_DEPTH_SIGN|32)
+
+#define IPL_DATA_ORDER_PIXEL 0
+#define IPL_DATA_ORDER_PLANE 1
+
+#define IPL_ORIGIN_TL 0
+#define IPL_ORIGIN_BL 1
+
+#define IPL_ALIGN_4BYTES 4
+#define IPL_ALIGN_8BYTES 8
+#define IPL_ALIGN_16BYTES 16
+#define IPL_ALIGN_32BYTES 32
+
+#define IPL_ALIGN_DWORD IPL_ALIGN_4BYTES
+#define IPL_ALIGN_QWORD IPL_ALIGN_8BYTES
+
+#define IPL_BORDER_CONSTANT 0
+#define IPL_BORDER_REPLICATE 1
+#define IPL_BORDER_REFLECT 2
+#define IPL_BORDER_WRAP 3
+
+/** The IplImage is taken from the Intel Image Processing Library, in which the format is native. OpenCV
+only supports a subset of possible IplImage formats, as outlined in the parameter list above.
+
+In addition to the above restrictions, OpenCV handles ROIs differently. OpenCV functions require
+that the image size or ROI size of all source and destination images match exactly. On the other
+hand, the Intel Image Processing Library processes the area of intersection between the source and
+destination images (or ROIs), allowing them to vary independently.
+*/
+typedef struct
+#ifdef __cplusplus
+ CV_EXPORTS
+#endif
+_IplImage
+{
+ int nSize; /**< sizeof(IplImage) */
+ int ID; /**< version (=0)*/
+ int nChannels; /**< Most of OpenCV functions support 1,2,3 or 4 channels */
+ int alphaChannel; /**< Ignored by OpenCV */
+ int depth; /**< Pixel depth in bits: IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16S,
+ IPL_DEPTH_32S, IPL_DEPTH_32F and IPL_DEPTH_64F are supported. */
+ char colorModel[4]; /**< Ignored by OpenCV */
+ char channelSeq[4]; /**< ditto */
+ int dataOrder; /**< 0 - interleaved color channels, 1 - separate color channels.
+ cvCreateImage can only create interleaved images */
+ int origin; /**< 0 - top-left origin,
+ 1 - bottom-left origin (Windows bitmaps style). */
+ int align; /**< Alignment of image rows (4 or 8).
+ OpenCV ignores it and uses widthStep instead. */
+ int width; /**< Image width in pixels. */
+ int height; /**< Image height in pixels. */
+ struct _IplROI *roi; /**< Image ROI. If NULL, the whole image is selected. */
+ struct _IplImage *maskROI; /**< Must be NULL. */
+ void *imageId; /**< " " */
+ struct _IplTileInfo *tileInfo; /**< " " */
+ int imageSize; /**< Image data size in bytes
+ (==image->height*image->widthStep
+ in case of interleaved data)*/
+ char *imageData; /**< Pointer to aligned image data. */
+ int widthStep; /**< Size of aligned image row in bytes. */
+ int BorderMode[4]; /**< Ignored by OpenCV. */
+ int BorderConst[4]; /**< Ditto. */
+ char *imageDataOrigin; /**< Pointer to very origin of image data
+ (not necessarily aligned) -
+ needed for correct deallocation */
+
+#ifdef __cplusplus
+ _IplImage() {}
+ _IplImage(const cv::Mat& m);
+#endif
+}
+IplImage;
+
+typedef struct _IplTileInfo IplTileInfo;
+
+typedef struct _IplROI
+{
+ int coi; /**< 0 - no COI (all channels are selected), 1 - 0th channel is selected ...*/
+ int xOffset;
+ int yOffset;
+ int width;
+ int height;
+}
+IplROI;
+
+typedef struct _IplConvKernel
+{
+ int nCols;
+ int nRows;
+ int anchorX;
+ int anchorY;
+ int *values;
+ int nShiftR;
+}
+IplConvKernel;
+
+typedef struct _IplConvKernelFP
+{
+ int nCols;
+ int nRows;
+ int anchorX;
+ int anchorY;
+ float *values;
+}
+IplConvKernelFP;
+
+#define IPL_IMAGE_HEADER 1
+#define IPL_IMAGE_DATA 2
+#define IPL_IMAGE_ROI 4
+
+#endif/*HAVE_IPL*/
+
+/** extra border mode */
+#define IPL_BORDER_REFLECT_101 4
+#define IPL_BORDER_TRANSPARENT 5
+
+#define IPL_IMAGE_MAGIC_VAL ((int)sizeof(IplImage))
+#define CV_TYPE_NAME_IMAGE "opencv-image"
+
+#define CV_IS_IMAGE_HDR(img) \
+ ((img) != NULL && ((const IplImage*)(img))->nSize == sizeof(IplImage))
+
+#define CV_IS_IMAGE(img) \
+ (CV_IS_IMAGE_HDR(img) && ((IplImage*)img)->imageData != NULL)
+
+/** for storing double-precision
+ floating point data in IplImage's */
+#define IPL_DEPTH_64F 64
+
+/** get reference to pixel at (col,row),
+ for multi-channel images (col) should be multiplied by number of channels */
+#define CV_IMAGE_ELEM( image, elemtype, row, col ) \
+ (((elemtype*)((image)->imageData + (image)->widthStep*(row)))[(col)])
+
+/****************************************************************************************\
+* Matrix type (CvMat) *
+\****************************************************************************************/
+
+#define CV_AUTO_STEP 0x7fffffff
+#define CV_WHOLE_ARR cvSlice( 0, 0x3fffffff )
+
+#define CV_MAGIC_MASK 0xFFFF0000
+#define CV_MAT_MAGIC_VAL 0x42420000
+#define CV_TYPE_NAME_MAT "opencv-matrix"
+
+/** Matrix elements are stored row by row. Element (i, j) (i - 0-based row index, j - 0-based column
+index) of a matrix can be retrieved or modified using CV_MAT_ELEM macro:
+
+ uchar pixval = CV_MAT_ELEM(grayimg, uchar, i, j)
+ CV_MAT_ELEM(cameraMatrix, float, 0, 2) = image.width*0.5f;
+
+To access multiple-channel matrices, you can use
+CV_MAT_ELEM(matrix, type, i, j\*nchannels + channel_idx).
+
+@deprecated CvMat is now obsolete; consider using Mat instead.
+ */
+typedef struct CvMat
+{
+ int type;
+ int step;
+
+ /* for internal use only */
+ int* refcount;
+ int hdr_refcount;
+
+ union
+ {
+ uchar* ptr;
+ short* s;
+ int* i;
+ float* fl;
+ double* db;
+ } data;
+
+#ifdef __cplusplus
+ union
+ {
+ int rows;
+ int height;
+ };
+
+ union
+ {
+ int cols;
+ int width;
+ };
+#else
+ int rows;
+ int cols;
+#endif
+
+
+#ifdef __cplusplus
+ CvMat() {}
+ CvMat(const CvMat& m) { memcpy(this, &m, sizeof(CvMat));}
+ CvMat(const cv::Mat& m);
+#endif
+
+}
+CvMat;
+
+
+#define CV_IS_MAT_HDR(mat) \
+ ((mat) != NULL && \
+ (((const CvMat*)(mat))->type & CV_MAGIC_MASK) == CV_MAT_MAGIC_VAL && \
+ ((const CvMat*)(mat))->cols > 0 && ((const CvMat*)(mat))->rows > 0)
+
+#define CV_IS_MAT_HDR_Z(mat) \
+ ((mat) != NULL && \
+ (((const CvMat*)(mat))->type & CV_MAGIC_MASK) == CV_MAT_MAGIC_VAL && \
+ ((const CvMat*)(mat))->cols >= 0 && ((const CvMat*)(mat))->rows >= 0)
+
+#define CV_IS_MAT(mat) \
+ (CV_IS_MAT_HDR(mat) && ((const CvMat*)(mat))->data.ptr != NULL)
+
+#define CV_IS_MASK_ARR(mat) \
+ (((mat)->type & (CV_MAT_TYPE_MASK & ~CV_8SC1)) == 0)
+
+#define CV_ARE_TYPES_EQ(mat1, mat2) \
+ ((((mat1)->type ^ (mat2)->type) & CV_MAT_TYPE_MASK) == 0)
+
+#define CV_ARE_CNS_EQ(mat1, mat2) \
+ ((((mat1)->type ^ (mat2)->type) & CV_MAT_CN_MASK) == 0)
+
+#define CV_ARE_DEPTHS_EQ(mat1, mat2) \
+ ((((mat1)->type ^ (mat2)->type) & CV_MAT_DEPTH_MASK) == 0)
+
+#define CV_ARE_SIZES_EQ(mat1, mat2) \
+ ((mat1)->rows == (mat2)->rows && (mat1)->cols == (mat2)->cols)
+
+#define CV_IS_MAT_CONST(mat) \
+ (((mat)->rows|(mat)->cols) == 1)
+
+#define IPL2CV_DEPTH(depth) \
+ ((((CV_8U)+(CV_16U<<4)+(CV_32F<<8)+(CV_64F<<16)+(CV_8S<<20)+ \
+ (CV_16S<<24)+(CV_32S<<28)) >> ((((depth) & 0xF0) >> 2) + \
+ (((depth) & IPL_DEPTH_SIGN) ? 20 : 0))) & 15)
+
+/** Inline constructor. No data is allocated internally!!!
+ * (Use together with cvCreateData, or use cvCreateMat instead to
+ * get a matrix with allocated data):
+ */
+CV_INLINE CvMat cvMat( int rows, int cols, int type, void* data CV_DEFAULT(NULL))
+{
+ CvMat m;
+
+ assert( (unsigned)CV_MAT_DEPTH(type) <= CV_64F );
+ type = CV_MAT_TYPE(type);
+ m.type = CV_MAT_MAGIC_VAL | CV_MAT_CONT_FLAG | type;
+ m.cols = cols;
+ m.rows = rows;
+ m.step = m.cols*CV_ELEM_SIZE(type);
+ m.data.ptr = (uchar*)data;
+ m.refcount = NULL;
+ m.hdr_refcount = 0;
+
+ return m;
+}
+
+#ifdef __cplusplus
+inline CvMat::CvMat(const cv::Mat& m)
+{
+ CV_DbgAssert(m.dims <= 2);
+ *this = cvMat(m.rows, m.dims == 1 ? 1 : m.cols, m.type(), m.data);
+ step = (int)m.step[0];
+ type = (type & ~cv::Mat::CONTINUOUS_FLAG) | (m.flags & cv::Mat::CONTINUOUS_FLAG);
+}
+#endif
+
+
+#define CV_MAT_ELEM_PTR_FAST( mat, row, col, pix_size ) \
+ (assert( (unsigned)(row) < (unsigned)(mat).rows && \
+ (unsigned)(col) < (unsigned)(mat).cols ), \
+ (mat).data.ptr + (size_t)(mat).step*(row) + (pix_size)*(col))
+
+#define CV_MAT_ELEM_PTR( mat, row, col ) \
+ CV_MAT_ELEM_PTR_FAST( mat, row, col, CV_ELEM_SIZE((mat).type) )
+
+#define CV_MAT_ELEM( mat, elemtype, row, col ) \
+ (*(elemtype*)CV_MAT_ELEM_PTR_FAST( mat, row, col, sizeof(elemtype)))
+
+/** @brief Returns the particular element of single-channel floating-point matrix.
+
+The function is a fast replacement for cvGetReal2D in the case of single-channel floating-point
+matrices. It is faster because it is inline, it does fewer checks for array type and array element
+type, and it checks for the row and column ranges only in debug mode.
+@param mat Input matrix
+@param row The zero-based index of row
+@param col The zero-based index of column
+ */
+CV_INLINE double cvmGet( const CvMat* mat, int row, int col )
+{
+ int type;
+
+ type = CV_MAT_TYPE(mat->type);
+ assert( (unsigned)row < (unsigned)mat->rows &&
+ (unsigned)col < (unsigned)mat->cols );
+
+ if( type == CV_32FC1 )
+ return ((float*)(void*)(mat->data.ptr + (size_t)mat->step*row))[col];
+ else
+ {
+ assert( type == CV_64FC1 );
+ return ((double*)(void*)(mat->data.ptr + (size_t)mat->step*row))[col];
+ }
+}
+
+/** @brief Sets a specific element of a single-channel floating-point matrix.
+
+The function is a fast replacement for cvSetReal2D in the case of single-channel floating-point
+matrices. It is faster because it is inline, it does fewer checks for array type and array element
+type, and it checks for the row and column ranges only in debug mode.
+@param mat The matrix
+@param row The zero-based index of row
+@param col The zero-based index of column
+@param value The new value of the matrix element
+ */
+CV_INLINE void cvmSet( CvMat* mat, int row, int col, double value )
+{
+ int type;
+ type = CV_MAT_TYPE(mat->type);
+ assert( (unsigned)row < (unsigned)mat->rows &&
+ (unsigned)col < (unsigned)mat->cols );
+
+ if( type == CV_32FC1 )
+ ((float*)(void*)(mat->data.ptr + (size_t)mat->step*row))[col] = (float)value;
+ else
+ {
+ assert( type == CV_64FC1 );
+ ((double*)(void*)(mat->data.ptr + (size_t)mat->step*row))[col] = value;
+ }
+}
+
+
+CV_INLINE int cvIplDepth( int type )
+{
+ int depth = CV_MAT_DEPTH(type);
+ return CV_ELEM_SIZE1(depth)*8 | (depth == CV_8S || depth == CV_16S ||
+ depth == CV_32S ? IPL_DEPTH_SIGN : 0);
+}
+
+
+/****************************************************************************************\
+* Multi-dimensional dense array (CvMatND) *
+\****************************************************************************************/
+
+#define CV_MATND_MAGIC_VAL 0x42430000
+#define CV_TYPE_NAME_MATND "opencv-nd-matrix"
+
+#define CV_MAX_DIM 32
+#define CV_MAX_DIM_HEAP 1024
+
+/**
+ @deprecated consider using cv::Mat instead
+ */
+typedef struct
+#ifdef __cplusplus
+ CV_EXPORTS
+#endif
+CvMatND
+{
+ int type;
+ int dims;
+
+ int* refcount;
+ int hdr_refcount;
+
+ union
+ {
+ uchar* ptr;
+ float* fl;
+ double* db;
+ int* i;
+ short* s;
+ } data;
+
+ struct
+ {
+ int size;
+ int step;
+ }
+ dim[CV_MAX_DIM];
+
+#ifdef __cplusplus
+ CvMatND() {}
+ CvMatND(const cv::Mat& m);
+#endif
+}
+CvMatND;
+
+#define CV_IS_MATND_HDR(mat) \
+ ((mat) != NULL && (((const CvMatND*)(mat))->type & CV_MAGIC_MASK) == CV_MATND_MAGIC_VAL)
+
+#define CV_IS_MATND(mat) \
+ (CV_IS_MATND_HDR(mat) && ((const CvMatND*)(mat))->data.ptr != NULL)
+
+
+/****************************************************************************************\
+* Multi-dimensional sparse array (CvSparseMat) *
+\****************************************************************************************/
+
+#define CV_SPARSE_MAT_MAGIC_VAL 0x42440000
+#define CV_TYPE_NAME_SPARSE_MAT "opencv-sparse-matrix"
+
+struct CvSet;
+
+typedef struct
+#ifdef __cplusplus
+ CV_EXPORTS
+#endif
+CvSparseMat
+{
+ int type;
+ int dims;
+ int* refcount;
+ int hdr_refcount;
+
+ struct CvSet* heap;
+ void** hashtable;
+ int hashsize;
+ int valoffset;
+ int idxoffset;
+ int size[CV_MAX_DIM];
+
+#ifdef __cplusplus
+ void copyToSparseMat(cv::SparseMat& m) const;
+#endif
+}
+CvSparseMat;
+
+#ifdef __cplusplus
+ CV_EXPORTS CvSparseMat* cvCreateSparseMat(const cv::SparseMat& m);
+#endif
+
+#define CV_IS_SPARSE_MAT_HDR(mat) \
+ ((mat) != NULL && \
+ (((const CvSparseMat*)(mat))->type & CV_MAGIC_MASK) == CV_SPARSE_MAT_MAGIC_VAL)
+
+#define CV_IS_SPARSE_MAT(mat) \
+ CV_IS_SPARSE_MAT_HDR(mat)
+
+/**************** iteration through a sparse array *****************/
+
+typedef struct CvSparseNode
+{
+ unsigned hashval;
+ struct CvSparseNode* next;
+}
+CvSparseNode;
+
+typedef struct CvSparseMatIterator
+{
+ CvSparseMat* mat;
+ CvSparseNode* node;
+ int curidx;
+}
+CvSparseMatIterator;
+
+#define CV_NODE_VAL(mat,node) ((void*)((uchar*)(node) + (mat)->valoffset))
+#define CV_NODE_IDX(mat,node) ((int*)((uchar*)(node) + (mat)->idxoffset))
+
+/****************************************************************************************\
+* Histogram *
+\****************************************************************************************/
+
+typedef int CvHistType;
+
+#define CV_HIST_MAGIC_VAL 0x42450000
+#define CV_HIST_UNIFORM_FLAG (1 << 10)
+
+/** indicates whether bin ranges are set already or not */
+#define CV_HIST_RANGES_FLAG (1 << 11)
+
+#define CV_HIST_ARRAY 0
+#define CV_HIST_SPARSE 1
+#define CV_HIST_TREE CV_HIST_SPARSE
+
+/** should be used as a parameter only,
+ it turns to CV_HIST_UNIFORM_FLAG of hist->type */
+#define CV_HIST_UNIFORM 1
+
+typedef struct CvHistogram
+{
+ int type;
+ CvArr* bins;
+ float thresh[CV_MAX_DIM][2]; /**< For uniform histograms. */
+ float** thresh2; /**< For non-uniform histograms. */
+ CvMatND mat; /**< Embedded matrix header for array histograms. */
+}
+CvHistogram;
+
+#define CV_IS_HIST( hist ) \
+ ((hist) != NULL && \
+ (((CvHistogram*)(hist))->type & CV_MAGIC_MASK) == CV_HIST_MAGIC_VAL && \
+ (hist)->bins != NULL)
+
+#define CV_IS_UNIFORM_HIST( hist ) \
+ (((hist)->type & CV_HIST_UNIFORM_FLAG) != 0)
+
+#define CV_IS_SPARSE_HIST( hist ) \
+ CV_IS_SPARSE_MAT((hist)->bins)
+
+#define CV_HIST_HAS_RANGES( hist ) \
+ (((hist)->type & CV_HIST_RANGES_FLAG) != 0)
+
+/****************************************************************************************\
+* Other supplementary data type definitions *
+\****************************************************************************************/
+
+/*************************************** CvRect *****************************************/
+/** @sa Rect_ */
+typedef struct CvRect
+{
+ int x;
+ int y;
+ int width;
+ int height;
+
+#ifdef __cplusplus
+ CvRect(int _x = 0, int _y = 0, int w = 0, int h = 0): x(_x), y(_y), width(w), height(h) {}
+ template<typename _Tp>
+ CvRect(const cv::Rect_<_Tp>& r): x(cv::saturate_cast<int>(r.x)), y(cv::saturate_cast<int>(r.y)), width(cv::saturate_cast<int>(r.width)), height(cv::saturate_cast<int>(r.height)) {}
+ template<typename _Tp>
+ operator cv::Rect_<_Tp>() const { return cv::Rect_<_Tp>((_Tp)x, (_Tp)y, (_Tp)width, (_Tp)height); }
+#endif
+}
+CvRect;
+
+/** constructs CvRect structure. */
+CV_INLINE CvRect cvRect( int x, int y, int width, int height )
+{
+ CvRect r;
+
+ r.x = x;
+ r.y = y;
+ r.width = width;
+ r.height = height;
+
+ return r;
+}
+
+
+CV_INLINE IplROI cvRectToROI( CvRect rect, int coi )
+{
+ IplROI roi;
+ roi.xOffset = rect.x;
+ roi.yOffset = rect.y;
+ roi.width = rect.width;
+ roi.height = rect.height;
+ roi.coi = coi;
+
+ return roi;
+}
+
+
+CV_INLINE CvRect cvROIToRect( IplROI roi )
+{
+ return cvRect( roi.xOffset, roi.yOffset, roi.width, roi.height );
+}
+
+/*********************************** CvTermCriteria *************************************/
+
+#define CV_TERMCRIT_ITER 1
+#define CV_TERMCRIT_NUMBER CV_TERMCRIT_ITER
+#define CV_TERMCRIT_EPS 2
+
+/** @sa TermCriteria
+ */
+typedef struct CvTermCriteria
+{
+ int type; /**< may be combination of
+ CV_TERMCRIT_ITER
+ CV_TERMCRIT_EPS */
+ int max_iter;
+ double epsilon;
+
+#ifdef __cplusplus
+ CvTermCriteria(int _type = 0, int _iter = 0, double _eps = 0) : type(_type), max_iter(_iter), epsilon(_eps) {}
+ CvTermCriteria(const cv::TermCriteria& t) : type(t.type), max_iter(t.maxCount), epsilon(t.epsilon) {}
+ operator cv::TermCriteria() const { return cv::TermCriteria(type, max_iter, epsilon); }
+#endif
+
+}
+CvTermCriteria;
+
+CV_INLINE CvTermCriteria cvTermCriteria( int type, int max_iter, double epsilon )
+{
+ CvTermCriteria t;
+
+ t.type = type;
+ t.max_iter = max_iter;
+ t.epsilon = (float)epsilon;
+
+ return t;
+}
+
+
+/******************************* CvPoint and variants ***********************************/
+
+typedef struct CvPoint
+{
+ int x;
+ int y;
+
+#ifdef __cplusplus
+ CvPoint(int _x = 0, int _y = 0): x(_x), y(_y) {}
+ template<typename _Tp>
+ CvPoint(const cv::Point_<_Tp>& pt): x((int)pt.x), y((int)pt.y) {}
+ template<typename _Tp>
+ operator cv::Point_<_Tp>() const { return cv::Point_<_Tp>(cv::saturate_cast<_Tp>(x), cv::saturate_cast<_Tp>(y)); }
+#endif
+}
+CvPoint;
+
+/** constructs CvPoint structure. */
+CV_INLINE CvPoint cvPoint( int x, int y )
+{
+ CvPoint p;
+
+ p.x = x;
+ p.y = y;
+
+ return p;
+}
+
+
+typedef struct CvPoint2D32f
+{
+ float x;
+ float y;
+
+#ifdef __cplusplus
+ CvPoint2D32f(float _x = 0, float _y = 0): x(_x), y(_y) {}
+ template<typename _Tp>
+ CvPoint2D32f(const cv::Point_<_Tp>& pt): x((float)pt.x), y((float)pt.y) {}
+ template<typename _Tp>
+ operator cv::Point_<_Tp>() const { return cv::Point_<_Tp>(cv::saturate_cast<_Tp>(x), cv::saturate_cast<_Tp>(y)); }
+#endif
+}
+CvPoint2D32f;
+
+/** constructs CvPoint2D32f structure. */
+CV_INLINE CvPoint2D32f cvPoint2D32f( double x, double y )
+{
+ CvPoint2D32f p;
+
+ p.x = (float)x;
+ p.y = (float)y;
+
+ return p;
+}
+
+/** converts CvPoint to CvPoint2D32f. */
+CV_INLINE CvPoint2D32f cvPointTo32f( CvPoint point )
+{
+ return cvPoint2D32f( (float)point.x, (float)point.y );
+}
+
+/** converts CvPoint2D32f to CvPoint. */
+CV_INLINE CvPoint cvPointFrom32f( CvPoint2D32f point )
+{
+ CvPoint ipt;
+ ipt.x = cvRound(point.x);
+ ipt.y = cvRound(point.y);
+
+ return ipt;
+}
+
+
+typedef struct CvPoint3D32f
+{
+ float x;
+ float y;
+ float z;
+
+#ifdef __cplusplus
+ CvPoint3D32f(float _x = 0, float _y = 0, float _z = 0): x(_x), y(_y), z(_z) {}
+ template<typename _Tp>
+ CvPoint3D32f(const cv::Point3_<_Tp>& pt): x((float)pt.x), y((float)pt.y), z((float)pt.z) {}
+ template<typename _Tp>
+ operator cv::Point3_<_Tp>() const { return cv::Point3_<_Tp>(cv::saturate_cast<_Tp>(x), cv::saturate_cast<_Tp>(y), cv::saturate_cast<_Tp>(z)); }
+#endif
+}
+CvPoint3D32f;
+
+/** constructs CvPoint3D32f structure. */
+CV_INLINE CvPoint3D32f cvPoint3D32f( double x, double y, double z )
+{
+ CvPoint3D32f p;
+
+ p.x = (float)x;
+ p.y = (float)y;
+ p.z = (float)z;
+
+ return p;
+}
+
+
+typedef struct CvPoint2D64f
+{
+ double x;
+ double y;
+}
+CvPoint2D64f;
+
+/** constructs CvPoint2D64f structure.*/
+CV_INLINE CvPoint2D64f cvPoint2D64f( double x, double y )
+{
+ CvPoint2D64f p;
+
+ p.x = x;
+ p.y = y;
+
+ return p;
+}
+
+
+typedef struct CvPoint3D64f
+{
+ double x;
+ double y;
+ double z;
+}
+CvPoint3D64f;
+
+/** constructs CvPoint3D64f structure. */
+CV_INLINE CvPoint3D64f cvPoint3D64f( double x, double y, double z )
+{
+ CvPoint3D64f p;
+
+ p.x = x;
+ p.y = y;
+ p.z = z;
+
+ return p;
+}
+
+
+/******************************** CvSize's & CvBox **************************************/
+
+typedef struct CvSize
+{
+ int width;
+ int height;
+
+#ifdef __cplusplus
+ CvSize(int w = 0, int h = 0): width(w), height(h) {}
+ template<typename _Tp>
+ CvSize(const cv::Size_<_Tp>& sz): width(cv::saturate_cast<int>(sz.width)), height(cv::saturate_cast<int>(sz.height)) {}
+ template<typename _Tp>
+ operator cv::Size_<_Tp>() const { return cv::Size_<_Tp>(cv::saturate_cast<_Tp>(width), cv::saturate_cast<_Tp>(height)); }
+#endif
+}
+CvSize;
+
+/** constructs CvSize structure. */
+CV_INLINE CvSize cvSize( int width, int height )
+{
+ CvSize s;
+
+ s.width = width;
+ s.height = height;
+
+ return s;
+}
+
+typedef struct CvSize2D32f
+{
+ float width;
+ float height;
+
+#ifdef __cplusplus
+ CvSize2D32f(float w = 0, float h = 0): width(w), height(h) {}
+ template<typename _Tp>
+ CvSize2D32f(const cv::Size_<_Tp>& sz): width(cv::saturate_cast<float>(sz.width)), height(cv::saturate_cast<float>(sz.height)) {}
+ template<typename _Tp>
+ operator cv::Size_<_Tp>() const { return cv::Size_<_Tp>(cv::saturate_cast<_Tp>(width), cv::saturate_cast<_Tp>(height)); }
+#endif
+}
+CvSize2D32f;
+
+/** constructs CvSize2D32f structure. */
+CV_INLINE CvSize2D32f cvSize2D32f( double width, double height )
+{
+ CvSize2D32f s;
+
+ s.width = (float)width;
+ s.height = (float)height;
+
+ return s;
+}
+
+/** @sa RotatedRect
+ */
+typedef struct CvBox2D
+{
+ CvPoint2D32f center; /**< Center of the box. */
+ CvSize2D32f size; /**< Box width and length. */
+ float angle; /**< Angle between the horizontal axis */
+ /**< and the first side (i.e. length) in degrees */
+
+#ifdef __cplusplus
+ CvBox2D(CvPoint2D32f c = CvPoint2D32f(), CvSize2D32f s = CvSize2D32f(), float a = 0) : center(c), size(s), angle(a) {}
+ CvBox2D(const cv::RotatedRect& rr) : center(rr.center), size(rr.size), angle(rr.angle) {}
+ operator cv::RotatedRect() const { return cv::RotatedRect(center, size, angle); }
+#endif
+}
+CvBox2D;
+
+
+/** Line iterator state: */
+typedef struct CvLineIterator
+{
+ /** Pointer to the current point: */
+ uchar* ptr;
+
+ /* Bresenham algorithm state: */
+ int err;
+ int plus_delta;
+ int minus_delta;
+ int plus_step;
+ int minus_step;
+}
+CvLineIterator;
+
+
+
+/************************************* CvSlice ******************************************/
+#define CV_WHOLE_SEQ_END_INDEX 0x3fffffff
+#define CV_WHOLE_SEQ cvSlice(0, CV_WHOLE_SEQ_END_INDEX)
+
+typedef struct CvSlice
+{
+ int start_index, end_index;
+
+#if defined(__cplusplus) && !defined(__CUDACC__)
+ CvSlice(int start = 0, int end = 0) : start_index(start), end_index(end) {}
+ CvSlice(const cv::Range& r) { *this = (r.start != INT_MIN && r.end != INT_MAX) ? CvSlice(r.start, r.end) : CvSlice(0, CV_WHOLE_SEQ_END_INDEX); }
+ operator cv::Range() const { return (start_index == 0 && end_index == CV_WHOLE_SEQ_END_INDEX ) ? cv::Range::all() : cv::Range(start_index, end_index); }
+#endif
+}
+CvSlice;
+
+CV_INLINE CvSlice cvSlice( int start, int end )
+{
+ CvSlice slice;
+ slice.start_index = start;
+ slice.end_index = end;
+
+ return slice;
+}
+
+
+
+/************************************* CvScalar *****************************************/
+/** @sa Scalar_
+ */
+typedef struct CvScalar
+{
+ double val[4];
+
+#ifdef __cplusplus
+ CvScalar() {}
+ CvScalar(double d0, double d1 = 0, double d2 = 0, double d3 = 0) { val[0] = d0; val[1] = d1; val[2] = d2; val[3] = d3; }
+ template<typename _Tp>
+ CvScalar(const cv::Scalar_<_Tp>& s) { val[0] = s.val[0]; val[1] = s.val[1]; val[2] = s.val[2]; val[3] = s.val[3]; }
+ template<typename _Tp>
+ operator cv::Scalar_<_Tp>() const { return cv::Scalar_<_Tp>(cv::saturate_cast<_Tp>(val[0]), cv::saturate_cast<_Tp>(val[1]), cv::saturate_cast<_Tp>(val[2]), cv::saturate_cast<_Tp>(val[3])); }
+ template<typename _Tp, int cn>
+ CvScalar(const cv::Vec<_Tp, cn>& v)
+ {
+ int i;
+ for( i = 0; i < (cn < 4 ? cn : 4); i++ ) val[i] = v.val[i];
+ for( ; i < 4; i++ ) val[i] = 0;
+ }
+#endif
+}
+CvScalar;
+
+CV_INLINE CvScalar cvScalar( double val0, double val1 CV_DEFAULT(0),
+ double val2 CV_DEFAULT(0), double val3 CV_DEFAULT(0))
+{
+ CvScalar scalar;
+ scalar.val[0] = val0; scalar.val[1] = val1;
+ scalar.val[2] = val2; scalar.val[3] = val3;
+ return scalar;
+}
+
+
+CV_INLINE CvScalar cvRealScalar( double val0 )
+{
+ CvScalar scalar;
+ scalar.val[0] = val0;
+ scalar.val[1] = scalar.val[2] = scalar.val[3] = 0;
+ return scalar;
+}
+
+CV_INLINE CvScalar cvScalarAll( double val0123 )
+{
+ CvScalar scalar;
+ scalar.val[0] = val0123;
+ scalar.val[1] = val0123;
+ scalar.val[2] = val0123;
+ scalar.val[3] = val0123;
+ return scalar;
+}
+
+/****************************************************************************************\
+* Dynamic Data structures *
+\****************************************************************************************/
+
+/******************************** Memory storage ****************************************/
+
+typedef struct CvMemBlock
+{
+ struct CvMemBlock* prev;
+ struct CvMemBlock* next;
+}
+CvMemBlock;
+
+#define CV_STORAGE_MAGIC_VAL 0x42890000
+
+typedef struct CvMemStorage
+{
+ int signature;
+ CvMemBlock* bottom; /**< First allocated block. */
+ CvMemBlock* top; /**< Current memory block - top of the stack. */
+ struct CvMemStorage* parent; /**< We get new blocks from parent as needed. */
+ int block_size; /**< Block size. */
+ int free_space; /**< Remaining free space in current block. */
+}
+CvMemStorage;
+
+#define CV_IS_STORAGE(storage) \
+ ((storage) != NULL && \
+ (((CvMemStorage*)(storage))->signature & CV_MAGIC_MASK) == CV_STORAGE_MAGIC_VAL)
+
+
+typedef struct CvMemStoragePos
+{
+ CvMemBlock* top;
+ int free_space;
+}
+CvMemStoragePos;
+
+
+/*********************************** Sequence *******************************************/
+
+typedef struct CvSeqBlock
+{
+ struct CvSeqBlock* prev; /**< Previous sequence block. */
+ struct CvSeqBlock* next; /**< Next sequence block. */
+ int start_index; /**< Index of the first element in the block + */
+ /**< sequence->first->start_index. */
+ int count; /**< Number of elements in the block. */
+ schar* data; /**< Pointer to the first element of the block. */
+}
+CvSeqBlock;
+
+
+#define CV_TREE_NODE_FIELDS(node_type) \
+ int flags; /**< Miscellaneous flags. */ \
+ int header_size; /**< Size of sequence header. */ \
+ struct node_type* h_prev; /**< Previous sequence. */ \
+ struct node_type* h_next; /**< Next sequence. */ \
+ struct node_type* v_prev; /**< 2nd previous sequence. */ \
+ struct node_type* v_next /**< 2nd next sequence. */
+
+/**
+ Read/Write sequence.
+ Elements can be dynamically inserted to or deleted from the sequence.
+*/
+#define CV_SEQUENCE_FIELDS() \
+ CV_TREE_NODE_FIELDS(CvSeq); \
+ int total; /**< Total number of elements. */ \
+ int elem_size; /**< Size of sequence element in bytes. */ \
+ schar* block_max; /**< Maximal bound of the last block. */ \
+ schar* ptr; /**< Current write pointer. */ \
+ int delta_elems; /**< Grow seq this many at a time. */ \
+ CvMemStorage* storage; /**< Where the seq is stored. */ \
+ CvSeqBlock* free_blocks; /**< Free blocks list. */ \
+ CvSeqBlock* first; /**< Pointer to the first sequence block. */
+
+typedef struct CvSeq
+{
+ CV_SEQUENCE_FIELDS()
+}
+CvSeq;
+
+#define CV_TYPE_NAME_SEQ "opencv-sequence"
+#define CV_TYPE_NAME_SEQ_TREE "opencv-sequence-tree"
+
+/*************************************** Set ********************************************/
+/** @brief Set
+ Order is not preserved. There can be gaps between sequence elements.
+ After the element has been inserted it stays in the same place all the time.
+ The MSB(most-significant or sign bit) of the first field (flags) is 0 iff the element exists.
+*/
+#define CV_SET_ELEM_FIELDS(elem_type) \
+ int flags; \
+ struct elem_type* next_free;
+
+typedef struct CvSetElem
+{
+ CV_SET_ELEM_FIELDS(CvSetElem)
+}
+CvSetElem;
+
+#define CV_SET_FIELDS() \
+ CV_SEQUENCE_FIELDS() \
+ CvSetElem* free_elems; \
+ int active_count;
+
+typedef struct CvSet
+{
+ CV_SET_FIELDS()
+}
+CvSet;
+
+
+#define CV_SET_ELEM_IDX_MASK ((1 << 26) - 1)
+#define CV_SET_ELEM_FREE_FLAG (1 << (sizeof(int)*8-1))
+
+/** Checks whether the element pointed by ptr belongs to a set or not */
+#define CV_IS_SET_ELEM( ptr ) (((CvSetElem*)(ptr))->flags >= 0)
+
+/************************************* Graph ********************************************/
+
+/** @name Graph
+
+We represent a graph as a set of vertices. Vertices contain their adjacency lists (more exactly,
+pointers to first incoming or outcoming edge (or 0 if isolated vertex)). Edges are stored in
+another set. There is a singly-linked list of incoming/outcoming edges for each vertex.
+
+Each edge consists of:
+
+- Two pointers to the starting and ending vertices (vtx[0] and vtx[1] respectively).
+
+ A graph may be oriented or not. In the latter case, edges between vertex i to vertex j are not
+distinguished during search operations.
+
+- Two pointers to next edges for the starting and ending vertices, where next[0] points to the
+next edge in the vtx[0] adjacency list and next[1] points to the next edge in the vtx[1]
+adjacency list.
+
+@see CvGraphEdge, CvGraphVtx, CvGraphVtx2D, CvGraph
+@{
+*/
+#define CV_GRAPH_EDGE_FIELDS() \
+ int flags; \
+ float weight; \
+ struct CvGraphEdge* next[2]; \
+ struct CvGraphVtx* vtx[2];
+
+
+#define CV_GRAPH_VERTEX_FIELDS() \
+ int flags; \
+ struct CvGraphEdge* first;
+
+
+typedef struct CvGraphEdge
+{
+ CV_GRAPH_EDGE_FIELDS()
+}
+CvGraphEdge;
+
+typedef struct CvGraphVtx
+{
+ CV_GRAPH_VERTEX_FIELDS()
+}
+CvGraphVtx;
+
+typedef struct CvGraphVtx2D
+{
+ CV_GRAPH_VERTEX_FIELDS()
+ CvPoint2D32f* ptr;
+}
+CvGraphVtx2D;
+
+/**
+ Graph is "derived" from the set (this is set a of vertices)
+ and includes another set (edges)
+*/
+#define CV_GRAPH_FIELDS() \
+ CV_SET_FIELDS() \
+ CvSet* edges;
+
+typedef struct CvGraph
+{
+ CV_GRAPH_FIELDS()
+}
+CvGraph;
+
+#define CV_TYPE_NAME_GRAPH "opencv-graph"
+
+/** @} */
+
+/*********************************** Chain/Countour *************************************/
+
+typedef struct CvChain
+{
+ CV_SEQUENCE_FIELDS()
+ CvPoint origin;
+}
+CvChain;
+
+#define CV_CONTOUR_FIELDS() \
+ CV_SEQUENCE_FIELDS() \
+ CvRect rect; \
+ int color; \
+ int reserved[3];
+
+typedef struct CvContour
+{
+ CV_CONTOUR_FIELDS()
+}
+CvContour;
+
+typedef CvContour CvPoint2DSeq;
+
+/****************************************************************************************\
+* Sequence types *
+\****************************************************************************************/
+
+#define CV_SEQ_MAGIC_VAL 0x42990000
+
+#define CV_IS_SEQ(seq) \
+ ((seq) != NULL && (((CvSeq*)(seq))->flags & CV_MAGIC_MASK) == CV_SEQ_MAGIC_VAL)
+
+#define CV_SET_MAGIC_VAL 0x42980000
+#define CV_IS_SET(set) \
+ ((set) != NULL && (((CvSeq*)(set))->flags & CV_MAGIC_MASK) == CV_SET_MAGIC_VAL)
+
+#define CV_SEQ_ELTYPE_BITS 12
+#define CV_SEQ_ELTYPE_MASK ((1 << CV_SEQ_ELTYPE_BITS) - 1)
+
+#define CV_SEQ_ELTYPE_POINT CV_32SC2 /**< (x,y) */
+#define CV_SEQ_ELTYPE_CODE CV_8UC1 /**< freeman code: 0..7 */
+#define CV_SEQ_ELTYPE_GENERIC 0
+#define CV_SEQ_ELTYPE_PTR CV_USRTYPE1
+#define CV_SEQ_ELTYPE_PPOINT CV_SEQ_ELTYPE_PTR /**< &(x,y) */
+#define CV_SEQ_ELTYPE_INDEX CV_32SC1 /**< #(x,y) */
+#define CV_SEQ_ELTYPE_GRAPH_EDGE 0 /**< &next_o, &next_d, &vtx_o, &vtx_d */
+#define CV_SEQ_ELTYPE_GRAPH_VERTEX 0 /**< first_edge, &(x,y) */
+#define CV_SEQ_ELTYPE_TRIAN_ATR 0 /**< vertex of the binary tree */
+#define CV_SEQ_ELTYPE_CONNECTED_COMP 0 /**< connected component */
+#define CV_SEQ_ELTYPE_POINT3D CV_32FC3 /**< (x,y,z) */
+
+#define CV_SEQ_KIND_BITS 2
+#define CV_SEQ_KIND_MASK (((1 << CV_SEQ_KIND_BITS) - 1)<<CV_SEQ_ELTYPE_BITS)
+
+/** types of sequences */
+#define CV_SEQ_KIND_GENERIC (0 << CV_SEQ_ELTYPE_BITS)
+#define CV_SEQ_KIND_CURVE (1 << CV_SEQ_ELTYPE_BITS)
+#define CV_SEQ_KIND_BIN_TREE (2 << CV_SEQ_ELTYPE_BITS)
+
+/** types of sparse sequences (sets) */
+#define CV_SEQ_KIND_GRAPH (1 << CV_SEQ_ELTYPE_BITS)
+#define CV_SEQ_KIND_SUBDIV2D (2 << CV_SEQ_ELTYPE_BITS)
+
+#define CV_SEQ_FLAG_SHIFT (CV_SEQ_KIND_BITS + CV_SEQ_ELTYPE_BITS)
+
+/** flags for curves */
+#define CV_SEQ_FLAG_CLOSED (1 << CV_SEQ_FLAG_SHIFT)
+#define CV_SEQ_FLAG_SIMPLE (0 << CV_SEQ_FLAG_SHIFT)
+#define CV_SEQ_FLAG_CONVEX (0 << CV_SEQ_FLAG_SHIFT)
+#define CV_SEQ_FLAG_HOLE (2 << CV_SEQ_FLAG_SHIFT)
+
+/** flags for graphs */
+#define CV_GRAPH_FLAG_ORIENTED (1 << CV_SEQ_FLAG_SHIFT)
+
+#define CV_GRAPH CV_SEQ_KIND_GRAPH
+#define CV_ORIENTED_GRAPH (CV_SEQ_KIND_GRAPH|CV_GRAPH_FLAG_ORIENTED)
+
+/** point sets */
+#define CV_SEQ_POINT_SET (CV_SEQ_KIND_GENERIC| CV_SEQ_ELTYPE_POINT)
+#define CV_SEQ_POINT3D_SET (CV_SEQ_KIND_GENERIC| CV_SEQ_ELTYPE_POINT3D)
+#define CV_SEQ_POLYLINE (CV_SEQ_KIND_CURVE | CV_SEQ_ELTYPE_POINT)
+#define CV_SEQ_POLYGON (CV_SEQ_FLAG_CLOSED | CV_SEQ_POLYLINE )
+#define CV_SEQ_CONTOUR CV_SEQ_POLYGON
+#define CV_SEQ_SIMPLE_POLYGON (CV_SEQ_FLAG_SIMPLE | CV_SEQ_POLYGON )
+
+/** chain-coded curves */
+#define CV_SEQ_CHAIN (CV_SEQ_KIND_CURVE | CV_SEQ_ELTYPE_CODE)
+#define CV_SEQ_CHAIN_CONTOUR (CV_SEQ_FLAG_CLOSED | CV_SEQ_CHAIN)
+
+/** binary tree for the contour */
+#define CV_SEQ_POLYGON_TREE (CV_SEQ_KIND_BIN_TREE | CV_SEQ_ELTYPE_TRIAN_ATR)
+
+/** sequence of the connected components */
+#define CV_SEQ_CONNECTED_COMP (CV_SEQ_KIND_GENERIC | CV_SEQ_ELTYPE_CONNECTED_COMP)
+
+/** sequence of the integer numbers */
+#define CV_SEQ_INDEX (CV_SEQ_KIND_GENERIC | CV_SEQ_ELTYPE_INDEX)
+
+#define CV_SEQ_ELTYPE( seq ) ((seq)->flags & CV_SEQ_ELTYPE_MASK)
+#define CV_SEQ_KIND( seq ) ((seq)->flags & CV_SEQ_KIND_MASK )
+
+/** flag checking */
+#define CV_IS_SEQ_INDEX( seq ) ((CV_SEQ_ELTYPE(seq) == CV_SEQ_ELTYPE_INDEX) && \
+ (CV_SEQ_KIND(seq) == CV_SEQ_KIND_GENERIC))
+
+#define CV_IS_SEQ_CURVE( seq ) (CV_SEQ_KIND(seq) == CV_SEQ_KIND_CURVE)
+#define CV_IS_SEQ_CLOSED( seq ) (((seq)->flags & CV_SEQ_FLAG_CLOSED) != 0)
+#define CV_IS_SEQ_CONVEX( seq ) 0
+#define CV_IS_SEQ_HOLE( seq ) (((seq)->flags & CV_SEQ_FLAG_HOLE) != 0)
+#define CV_IS_SEQ_SIMPLE( seq ) 1
+
+/** type checking macros */
+#define CV_IS_SEQ_POINT_SET( seq ) \
+ ((CV_SEQ_ELTYPE(seq) == CV_32SC2 || CV_SEQ_ELTYPE(seq) == CV_32FC2))
+
+#define CV_IS_SEQ_POINT_SUBSET( seq ) \
+ (CV_IS_SEQ_INDEX( seq ) || CV_SEQ_ELTYPE(seq) == CV_SEQ_ELTYPE_PPOINT)
+
+#define CV_IS_SEQ_POLYLINE( seq ) \
+ (CV_SEQ_KIND(seq) == CV_SEQ_KIND_CURVE && CV_IS_SEQ_POINT_SET(seq))
+
+#define CV_IS_SEQ_POLYGON( seq ) \
+ (CV_IS_SEQ_POLYLINE(seq) && CV_IS_SEQ_CLOSED(seq))
+
+#define CV_IS_SEQ_CHAIN( seq ) \
+ (CV_SEQ_KIND(seq) == CV_SEQ_KIND_CURVE && (seq)->elem_size == 1)
+
+#define CV_IS_SEQ_CONTOUR( seq ) \
+ (CV_IS_SEQ_CLOSED(seq) && (CV_IS_SEQ_POLYLINE(seq) || CV_IS_SEQ_CHAIN(seq)))
+
+#define CV_IS_SEQ_CHAIN_CONTOUR( seq ) \
+ (CV_IS_SEQ_CHAIN( seq ) && CV_IS_SEQ_CLOSED( seq ))
+
+#define CV_IS_SEQ_POLYGON_TREE( seq ) \
+ (CV_SEQ_ELTYPE (seq) == CV_SEQ_ELTYPE_TRIAN_ATR && \
+ CV_SEQ_KIND( seq ) == CV_SEQ_KIND_BIN_TREE )
+
+#define CV_IS_GRAPH( seq ) \
+ (CV_IS_SET(seq) && CV_SEQ_KIND((CvSet*)(seq)) == CV_SEQ_KIND_GRAPH)
+
+#define CV_IS_GRAPH_ORIENTED( seq ) \
+ (((seq)->flags & CV_GRAPH_FLAG_ORIENTED) != 0)
+
+#define CV_IS_SUBDIV2D( seq ) \
+ (CV_IS_SET(seq) && CV_SEQ_KIND((CvSet*)(seq)) == CV_SEQ_KIND_SUBDIV2D)
+
+/****************************************************************************************/
+/* Sequence writer & reader */
+/****************************************************************************************/
+
+#define CV_SEQ_WRITER_FIELDS() \
+ int header_size; \
+ CvSeq* seq; /**< the sequence written */ \
+ CvSeqBlock* block; /**< current block */ \
+ schar* ptr; /**< pointer to free space */ \
+ schar* block_min; /**< pointer to the beginning of block*/\
+ schar* block_max; /**< pointer to the end of block */
+
+typedef struct CvSeqWriter
+{
+ CV_SEQ_WRITER_FIELDS()
+}
+CvSeqWriter;
+
+
+#define CV_SEQ_READER_FIELDS() \
+ int header_size; \
+ CvSeq* seq; /**< sequence, beign read */ \
+ CvSeqBlock* block; /**< current block */ \
+ schar* ptr; /**< pointer to element be read next */ \
+ schar* block_min; /**< pointer to the beginning of block */\
+ schar* block_max; /**< pointer to the end of block */ \
+ int delta_index;/**< = seq->first->start_index */ \
+ schar* prev_elem; /**< pointer to previous element */
+
+typedef struct CvSeqReader
+{
+ CV_SEQ_READER_FIELDS()
+}
+CvSeqReader;
+
+/****************************************************************************************/
+/* Operations on sequences */
+/****************************************************************************************/
+
+#define CV_SEQ_ELEM( seq, elem_type, index ) \
+/** assert gives some guarantee that <seq> parameter is valid */ \
+( assert(sizeof((seq)->first[0]) == sizeof(CvSeqBlock) && \
+ (seq)->elem_size == sizeof(elem_type)), \
+ (elem_type*)((seq)->first && (unsigned)index < \
+ (unsigned)((seq)->first->count) ? \
+ (seq)->first->data + (index) * sizeof(elem_type) : \
+ cvGetSeqElem( (CvSeq*)(seq), (index) )))
+#define CV_GET_SEQ_ELEM( elem_type, seq, index ) CV_SEQ_ELEM( (seq), elem_type, (index) )
+
+/** Add element to sequence: */
+#define CV_WRITE_SEQ_ELEM_VAR( elem_ptr, writer ) \
+{ \
+ if( (writer).ptr >= (writer).block_max ) \
+ { \
+ cvCreateSeqBlock( &writer); \
+ } \
+ memcpy((writer).ptr, elem_ptr, (writer).seq->elem_size);\
+ (writer).ptr += (writer).seq->elem_size; \
+}
+
+#define CV_WRITE_SEQ_ELEM( elem, writer ) \
+{ \
+ assert( (writer).seq->elem_size == sizeof(elem)); \
+ if( (writer).ptr >= (writer).block_max ) \
+ { \
+ cvCreateSeqBlock( &writer); \
+ } \
+ assert( (writer).ptr <= (writer).block_max - sizeof(elem));\
+ memcpy((writer).ptr, &(elem), sizeof(elem)); \
+ (writer).ptr += sizeof(elem); \
+}
+
+
+/** Move reader position forward: */
+#define CV_NEXT_SEQ_ELEM( elem_size, reader ) \
+{ \
+ if( ((reader).ptr += (elem_size)) >= (reader).block_max ) \
+ { \
+ cvChangeSeqBlock( &(reader), 1 ); \
+ } \
+}
+
+
+/** Move reader position backward: */
+#define CV_PREV_SEQ_ELEM( elem_size, reader ) \
+{ \
+ if( ((reader).ptr -= (elem_size)) < (reader).block_min ) \
+ { \
+ cvChangeSeqBlock( &(reader), -1 ); \
+ } \
+}
+
+/** Read element and move read position forward: */
+#define CV_READ_SEQ_ELEM( elem, reader ) \
+{ \
+ assert( (reader).seq->elem_size == sizeof(elem)); \
+ memcpy( &(elem), (reader).ptr, sizeof((elem))); \
+ CV_NEXT_SEQ_ELEM( sizeof(elem), reader ) \
+}
+
+/** Read element and move read position backward: */
+#define CV_REV_READ_SEQ_ELEM( elem, reader ) \
+{ \
+ assert( (reader).seq->elem_size == sizeof(elem)); \
+ memcpy(&(elem), (reader).ptr, sizeof((elem))); \
+ CV_PREV_SEQ_ELEM( sizeof(elem), reader ) \
+}
+
+
+#define CV_READ_CHAIN_POINT( _pt, reader ) \
+{ \
+ (_pt) = (reader).pt; \
+ if( (reader).ptr ) \
+ { \
+ CV_READ_SEQ_ELEM( (reader).code, (reader)); \
+ assert( ((reader).code & ~7) == 0 ); \
+ (reader).pt.x += (reader).deltas[(int)(reader).code][0]; \
+ (reader).pt.y += (reader).deltas[(int)(reader).code][1]; \
+ } \
+}
+
+#define CV_CURRENT_POINT( reader ) (*((CvPoint*)((reader).ptr)))
+#define CV_PREV_POINT( reader ) (*((CvPoint*)((reader).prev_elem)))
+
+#define CV_READ_EDGE( pt1, pt2, reader ) \
+{ \
+ assert( sizeof(pt1) == sizeof(CvPoint) && \
+ sizeof(pt2) == sizeof(CvPoint) && \
+ reader.seq->elem_size == sizeof(CvPoint)); \
+ (pt1) = CV_PREV_POINT( reader ); \
+ (pt2) = CV_CURRENT_POINT( reader ); \
+ (reader).prev_elem = (reader).ptr; \
+ CV_NEXT_SEQ_ELEM( sizeof(CvPoint), (reader)); \
+}
+
+/************ Graph macros ************/
+
+/** Return next graph edge for given vertex: */
+#define CV_NEXT_GRAPH_EDGE( edge, vertex ) \
+ (assert((edge)->vtx[0] == (vertex) || (edge)->vtx[1] == (vertex)), \
+ (edge)->next[(edge)->vtx[1] == (vertex)])
+
+
+
+/****************************************************************************************\
+* Data structures for persistence (a.k.a serialization) functionality *
+\****************************************************************************************/
+
+/** "black box" file storage */
+typedef struct CvFileStorage CvFileStorage;
+
+/** Storage flags: */
+#define CV_STORAGE_READ 0
+#define CV_STORAGE_WRITE 1
+#define CV_STORAGE_WRITE_TEXT CV_STORAGE_WRITE
+#define CV_STORAGE_WRITE_BINARY CV_STORAGE_WRITE
+#define CV_STORAGE_APPEND 2
+#define CV_STORAGE_MEMORY 4
+#define CV_STORAGE_FORMAT_MASK (7<<3)
+#define CV_STORAGE_FORMAT_AUTO 0
+#define CV_STORAGE_FORMAT_XML 8
+#define CV_STORAGE_FORMAT_YAML 16
+#define CV_STORAGE_FORMAT_JSON 24
+#define CV_STORAGE_BASE64 64
+#define CV_STORAGE_WRITE_BASE64 (CV_STORAGE_BASE64 | CV_STORAGE_WRITE)
+
+/** @brief List of attributes. :
+
+In the current implementation, attributes are used to pass extra parameters when writing user
+objects (see cvWrite). XML attributes inside tags are not supported, aside from the object type
+specification (type_id attribute).
+@see cvAttrList, cvAttrValue
+ */
+typedef struct CvAttrList
+{
+ const char** attr; /**< NULL-terminated array of (attribute_name,attribute_value) pairs. */
+ struct CvAttrList* next; /**< Pointer to next chunk of the attributes list. */
+}
+CvAttrList;
+
+/** initializes CvAttrList structure */
+CV_INLINE CvAttrList cvAttrList( const char** attr CV_DEFAULT(NULL),
+ CvAttrList* next CV_DEFAULT(NULL) )
+{
+ CvAttrList l;
+ l.attr = attr;
+ l.next = next;
+
+ return l;
+}
+
+struct CvTypeInfo;
+
+#define CV_NODE_NONE 0
+#define CV_NODE_INT 1
+#define CV_NODE_INTEGER CV_NODE_INT
+#define CV_NODE_REAL 2
+#define CV_NODE_FLOAT CV_NODE_REAL
+#define CV_NODE_STR 3
+#define CV_NODE_STRING CV_NODE_STR
+#define CV_NODE_REF 4 /**< not used */
+#define CV_NODE_SEQ 5
+#define CV_NODE_MAP 6
+#define CV_NODE_TYPE_MASK 7
+
+#define CV_NODE_TYPE(flags) ((flags) & CV_NODE_TYPE_MASK)
+
+/** file node flags */
+#define CV_NODE_FLOW 8 /**<Used only for writing structures in YAML format. */
+#define CV_NODE_USER 16
+#define CV_NODE_EMPTY 32
+#define CV_NODE_NAMED 64
+
+#define CV_NODE_IS_INT(flags) (CV_NODE_TYPE(flags) == CV_NODE_INT)
+#define CV_NODE_IS_REAL(flags) (CV_NODE_TYPE(flags) == CV_NODE_REAL)
+#define CV_NODE_IS_STRING(flags) (CV_NODE_TYPE(flags) == CV_NODE_STRING)
+#define CV_NODE_IS_SEQ(flags) (CV_NODE_TYPE(flags) == CV_NODE_SEQ)
+#define CV_NODE_IS_MAP(flags) (CV_NODE_TYPE(flags) == CV_NODE_MAP)
+#define CV_NODE_IS_COLLECTION(flags) (CV_NODE_TYPE(flags) >= CV_NODE_SEQ)
+#define CV_NODE_IS_FLOW(flags) (((flags) & CV_NODE_FLOW) != 0)
+#define CV_NODE_IS_EMPTY(flags) (((flags) & CV_NODE_EMPTY) != 0)
+#define CV_NODE_IS_USER(flags) (((flags) & CV_NODE_USER) != 0)
+#define CV_NODE_HAS_NAME(flags) (((flags) & CV_NODE_NAMED) != 0)
+
+#define CV_NODE_SEQ_SIMPLE 256
+#define CV_NODE_SEQ_IS_SIMPLE(seq) (((seq)->flags & CV_NODE_SEQ_SIMPLE) != 0)
+
+typedef struct CvString
+{
+ int len;
+ char* ptr;
+}
+CvString;
+
+/** All the keys (names) of elements in the readed file storage
+ are stored in the hash to speed up the lookup operations: */
+typedef struct CvStringHashNode
+{
+ unsigned hashval;
+ CvString str;
+ struct CvStringHashNode* next;
+}
+CvStringHashNode;
+
+typedef struct CvGenericHash CvFileNodeHash;
+
+/** Basic element of the file storage - scalar or collection: */
+typedef struct CvFileNode
+{
+ int tag;
+ struct CvTypeInfo* info; /**< type information
+ (only for user-defined object, for others it is 0) */
+ union
+ {
+ double f; /**< scalar floating-point number */
+ int i; /**< scalar integer number */
+ CvString str; /**< text string */
+ CvSeq* seq; /**< sequence (ordered collection of file nodes) */
+ CvFileNodeHash* map; /**< map (collection of named file nodes) */
+ } data;
+}
+CvFileNode;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+typedef int (CV_CDECL *CvIsInstanceFunc)( const void* struct_ptr );
+typedef void (CV_CDECL *CvReleaseFunc)( void** struct_dblptr );
+typedef void* (CV_CDECL *CvReadFunc)( CvFileStorage* storage, CvFileNode* node );
+typedef void (CV_CDECL *CvWriteFunc)( CvFileStorage* storage, const char* name,
+ const void* struct_ptr, CvAttrList attributes );
+typedef void* (CV_CDECL *CvCloneFunc)( const void* struct_ptr );
+#ifdef __cplusplus
+}
+#endif
+
+/** @brief Type information
+
+The structure contains information about one of the standard or user-defined types. Instances of the
+type may or may not contain a pointer to the corresponding CvTypeInfo structure. In any case, there
+is a way to find the type info structure for a given object using the cvTypeOf function.
+Alternatively, type info can be found by type name using cvFindType, which is used when an object
+is read from file storage. The user can register a new type with cvRegisterType that adds the type
+information structure into the beginning of the type list. Thus, it is possible to create
+specialized types from generic standard types and override the basic methods.
+ */
+typedef struct CvTypeInfo
+{
+ int flags; /**< not used */
+ int header_size; /**< sizeof(CvTypeInfo) */
+ struct CvTypeInfo* prev; /**< previous registered type in the list */
+ struct CvTypeInfo* next; /**< next registered type in the list */
+ const char* type_name; /**< type name, written to file storage */
+ CvIsInstanceFunc is_instance; /**< checks if the passed object belongs to the type */
+ CvReleaseFunc release; /**< releases object (memory etc.) */
+ CvReadFunc read; /**< reads object from file storage */
+ CvWriteFunc write; /**< writes object to file storage */
+ CvCloneFunc clone; /**< creates a copy of the object */
+}
+CvTypeInfo;
+
+
+/**** System data types ******/
+
+typedef struct CvPluginFuncInfo
+{
+ void** func_addr;
+ void* default_func_addr;
+ const char* func_names;
+ int search_modules;
+ int loaded_from;
+}
+CvPluginFuncInfo;
+
+typedef struct CvModuleInfo
+{
+ struct CvModuleInfo* next;
+ const char* name;
+ const char* version;
+ CvPluginFuncInfo* func_tab;
+}
+CvModuleInfo;
+
+/** @} */
+
+#endif /*OPENCV_CORE_TYPES_H*/
+
+/* End of file. */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/core/utility.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,1171 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
+// Copyright (C) 2015, Itseez Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_CORE_UTILITY_H
+#define OPENCV_CORE_UTILITY_H
+
+#ifndef __cplusplus
+# error utility.hpp header must be compiled as C++
+#endif
+
+#if defined(check)
+# warning Detected Apple 'check' macro definition, it can cause build conflicts. Please, include this header before any Apple headers.
+#endif
+
+#include "opencv2/core.hpp"
+
+namespace cv
+{
+
+#ifdef CV_COLLECT_IMPL_DATA
+CV_EXPORTS void setImpl(int flags); // set implementation flags and reset storage arrays
+CV_EXPORTS void addImpl(int flag, const char* func = 0); // add implementation and function name to storage arrays
+// Get stored implementation flags and fucntions names arrays
+// Each implementation entry correspond to function name entry, so you can find which implementation was executed in which fucntion
+CV_EXPORTS int getImpl(std::vector<int> &impl, std::vector<String> &funName);
+
+CV_EXPORTS bool useCollection(); // return implementation collection state
+CV_EXPORTS void setUseCollection(bool flag); // set implementation collection state
+
+#define CV_IMPL_PLAIN 0x01 // native CPU OpenCV implementation
+#define CV_IMPL_OCL 0x02 // OpenCL implementation
+#define CV_IMPL_IPP 0x04 // IPP implementation
+#define CV_IMPL_MT 0x10 // multithreaded implementation
+
+#define CV_IMPL_ADD(impl) \
+ if(cv::useCollection()) \
+ { \
+ cv::addImpl(impl, CV_Func); \
+ }
+#else
+#define CV_IMPL_ADD(impl)
+#endif
+
+//! @addtogroup core_utils
+//! @{
+
+/** @brief Automatically Allocated Buffer Class
+
+ The class is used for temporary buffers in functions and methods.
+ If a temporary buffer is usually small (a few K's of memory),
+ but its size depends on the parameters, it makes sense to create a small
+ fixed-size array on stack and use it if it's large enough. If the required buffer size
+ is larger than the fixed size, another buffer of sufficient size is allocated dynamically
+ and released after the processing. Therefore, in typical cases, when the buffer size is small,
+ there is no overhead associated with malloc()/free().
+ At the same time, there is no limit on the size of processed data.
+
+ This is what AutoBuffer does. The template takes 2 parameters - type of the buffer elements and
+ the number of stack-allocated elements. Here is how the class is used:
+
+ \code
+ void my_func(const cv::Mat& m)
+ {
+ cv::AutoBuffer<float> buf; // create automatic buffer containing 1000 floats
+
+ buf.allocate(m.rows); // if m.rows <= 1000, the pre-allocated buffer is used,
+ // otherwise the buffer of "m.rows" floats will be allocated
+ // dynamically and deallocated in cv::AutoBuffer destructor
+ ...
+ }
+ \endcode
+*/
+template<typename _Tp, size_t fixed_size = 1024/sizeof(_Tp)+8> class AutoBuffer
+{
+public:
+ typedef _Tp value_type;
+
+ //! the default constructor
+ AutoBuffer();
+ //! constructor taking the real buffer size
+ AutoBuffer(size_t _size);
+
+ //! the copy constructor
+ AutoBuffer(const AutoBuffer<_Tp, fixed_size>& buf);
+ //! the assignment operator
+ AutoBuffer<_Tp, fixed_size>& operator = (const AutoBuffer<_Tp, fixed_size>& buf);
+
+ //! destructor. calls deallocate()
+ ~AutoBuffer();
+
+ //! allocates the new buffer of size _size. if the _size is small enough, stack-allocated buffer is used
+ void allocate(size_t _size);
+ //! deallocates the buffer if it was dynamically allocated
+ void deallocate();
+ //! resizes the buffer and preserves the content
+ void resize(size_t _size);
+ //! returns the current buffer size
+ size_t size() const;
+ //! returns pointer to the real buffer, stack-allocated or head-allocated
+ operator _Tp* ();
+ //! returns read-only pointer to the real buffer, stack-allocated or head-allocated
+ operator const _Tp* () const;
+
+protected:
+ //! pointer to the real buffer, can point to buf if the buffer is small enough
+ _Tp* ptr;
+ //! size of the real buffer
+ size_t sz;
+ //! pre-allocated buffer. At least 1 element to confirm C++ standard reqirements
+ _Tp buf[(fixed_size > 0) ? fixed_size : 1];
+};
+
+/** @brief Sets/resets the break-on-error mode.
+
+When the break-on-error mode is set, the default error handler issues a hardware exception, which
+can make debugging more convenient.
+
+\return the previous state
+ */
+CV_EXPORTS bool setBreakOnError(bool flag);
+
+extern "C" typedef int (*ErrorCallback)( int status, const char* func_name,
+ const char* err_msg, const char* file_name,
+ int line, void* userdata );
+
+
+/** @brief Sets the new error handler and the optional user data.
+
+ The function sets the new error handler, called from cv::error().
+
+ \param errCallback the new error handler. If NULL, the default error handler is used.
+ \param userdata the optional user data pointer, passed to the callback.
+ \param prevUserdata the optional output parameter where the previous user data pointer is stored
+
+ \return the previous error handler
+*/
+CV_EXPORTS ErrorCallback redirectError( ErrorCallback errCallback, void* userdata=0, void** prevUserdata=0);
+
+/** @brief Returns a text string formatted using the printf-like expression.
+
+The function acts like sprintf but forms and returns an STL string. It can be used to form an error
+message in the Exception constructor.
+@param fmt printf-compatible formatting specifiers.
+ */
+CV_EXPORTS String format( const char* fmt, ... );
+CV_EXPORTS String tempfile( const char* suffix = 0);
+CV_EXPORTS void glob(String pattern, std::vector<String>& result, bool recursive = false);
+
+/** @brief OpenCV will try to set the number of threads for the next parallel region.
+
+If threads == 0, OpenCV will disable threading optimizations and run all it's functions
+sequentially. Passing threads \< 0 will reset threads number to system default. This function must
+be called outside of parallel region.
+
+OpenCV will try to run it's functions with specified threads number, but some behaviour differs from
+framework:
+- `TBB` – User-defined parallel constructions will run with the same threads number, if
+ another does not specified. If late on user creates own scheduler, OpenCV will be use it.
+- `OpenMP` – No special defined behaviour.
+- `Concurrency` – If threads == 1, OpenCV will disable threading optimizations and run it's
+ functions sequentially.
+- `GCD` – Supports only values \<= 0.
+- `C=` – No special defined behaviour.
+@param nthreads Number of threads used by OpenCV.
+@sa getNumThreads, getThreadNum
+ */
+CV_EXPORTS_W void setNumThreads(int nthreads);
+
+/** @brief Returns the number of threads used by OpenCV for parallel regions.
+
+Always returns 1 if OpenCV is built without threading support.
+
+The exact meaning of return value depends on the threading framework used by OpenCV library:
+- `TBB` – The number of threads, that OpenCV will try to use for parallel regions. If there is
+ any tbb::thread_scheduler_init in user code conflicting with OpenCV, then function returns
+ default number of threads used by TBB library.
+- `OpenMP` – An upper bound on the number of threads that could be used to form a new team.
+- `Concurrency` – The number of threads, that OpenCV will try to use for parallel regions.
+- `GCD` – Unsupported; returns the GCD thread pool limit (512) for compatibility.
+- `C=` – The number of threads, that OpenCV will try to use for parallel regions, if before
+ called setNumThreads with threads \> 0, otherwise returns the number of logical CPUs,
+ available for the process.
+@sa setNumThreads, getThreadNum
+ */
+CV_EXPORTS_W int getNumThreads();
+
+/** @brief Returns the index of the currently executed thread within the current parallel region. Always
+returns 0 if called outside of parallel region.
+
+The exact meaning of return value depends on the threading framework used by OpenCV library:
+- `TBB` – Unsupported with current 4.1 TBB release. May be will be supported in future.
+- `OpenMP` – The thread number, within the current team, of the calling thread.
+- `Concurrency` – An ID for the virtual processor that the current context is executing on (0
+ for master thread and unique number for others, but not necessary 1,2,3,...).
+- `GCD` – System calling thread's ID. Never returns 0 inside parallel region.
+- `C=` – The index of the current parallel task.
+@sa setNumThreads, getNumThreads
+ */
+CV_EXPORTS_W int getThreadNum();
+
+/** @brief Returns full configuration time cmake output.
+
+Returned value is raw cmake output including version control system revision, compiler version,
+compiler flags, enabled modules and third party libraries, etc. Output format depends on target
+architecture.
+ */
+CV_EXPORTS_W const String& getBuildInformation();
+
+/** @brief Returns the number of ticks.
+
+The function returns the number of ticks after the certain event (for example, when the machine was
+turned on). It can be used to initialize RNG or to measure a function execution time by reading the
+tick count before and after the function call.
+@sa getTickFrequency, TickMeter
+ */
+CV_EXPORTS_W int64 getTickCount();
+
+/** @brief Returns the number of ticks per second.
+
+The function returns the number of ticks per second. That is, the following code computes the
+execution time in seconds:
+@code
+ double t = (double)getTickCount();
+ // do something ...
+ t = ((double)getTickCount() - t)/getTickFrequency();
+@endcode
+@sa getTickCount, TickMeter
+ */
+CV_EXPORTS_W double getTickFrequency();
+
+/** @brief a Class to measure passing time.
+
+The class computes passing time by counting the number of ticks per second. That is, the following code computes the
+execution time in seconds:
+@code
+TickMeter tm;
+tm.start();
+// do something ...
+tm.stop();
+std::cout << tm.getTimeSec();
+@endcode
+@sa getTickCount, getTickFrequency
+*/
+
+class CV_EXPORTS_W TickMeter
+{
+public:
+ //! the default constructor
+ CV_WRAP TickMeter()
+ {
+ reset();
+ }
+
+ /**
+ starts counting ticks.
+ */
+ CV_WRAP void start()
+ {
+ startTime = cv::getTickCount();
+ }
+
+ /**
+ stops counting ticks.
+ */
+ CV_WRAP void stop()
+ {
+ int64 time = cv::getTickCount();
+ if (startTime == 0)
+ return;
+ ++counter;
+ sumTime += (time - startTime);
+ startTime = 0;
+ }
+
+ /**
+ returns counted ticks.
+ */
+ CV_WRAP int64 getTimeTicks() const
+ {
+ return sumTime;
+ }
+
+ /**
+ returns passed time in microseconds.
+ */
+ CV_WRAP double getTimeMicro() const
+ {
+ return getTimeMilli()*1e3;
+ }
+
+ /**
+ returns passed time in milliseconds.
+ */
+ CV_WRAP double getTimeMilli() const
+ {
+ return getTimeSec()*1e3;
+ }
+
+ /**
+ returns passed time in seconds.
+ */
+ CV_WRAP double getTimeSec() const
+ {
+ return (double)getTimeTicks() / getTickFrequency();
+ }
+
+ /**
+ returns internal counter value.
+ */
+ CV_WRAP int64 getCounter() const
+ {
+ return counter;
+ }
+
+ /**
+ resets internal values.
+ */
+ CV_WRAP void reset()
+ {
+ startTime = 0;
+ sumTime = 0;
+ counter = 0;
+ }
+
+private:
+ int64 counter;
+ int64 sumTime;
+ int64 startTime;
+};
+
+/** @brief output operator
+@code
+TickMeter tm;
+tm.start();
+// do something ...
+tm.stop();
+std::cout << tm;
+@endcode
+*/
+
+static inline
+std::ostream& operator << (std::ostream& out, const TickMeter& tm)
+{
+ return out << tm.getTimeSec() << "sec";
+}
+
+/** @brief Returns the number of CPU ticks.
+
+The function returns the current number of CPU ticks on some architectures (such as x86, x64,
+PowerPC). On other platforms the function is equivalent to getTickCount. It can also be used for
+very accurate time measurements, as well as for RNG initialization. Note that in case of multi-CPU
+systems a thread, from which getCPUTickCount is called, can be suspended and resumed at another CPU
+with its own counter. So, theoretically (and practically) the subsequent calls to the function do
+not necessary return the monotonously increasing values. Also, since a modern CPU varies the CPU
+frequency depending on the load, the number of CPU clocks spent in some code cannot be directly
+converted to time units. Therefore, getTickCount is generally a preferable solution for measuring
+execution time.
+ */
+CV_EXPORTS_W int64 getCPUTickCount();
+
+/** @brief Returns true if the specified feature is supported by the host hardware.
+
+The function returns true if the host hardware supports the specified feature. When user calls
+setUseOptimized(false), the subsequent calls to checkHardwareSupport() will return false until
+setUseOptimized(true) is called. This way user can dynamically switch on and off the optimized code
+in OpenCV.
+@param feature The feature of interest, one of cv::CpuFeatures
+ */
+CV_EXPORTS_W bool checkHardwareSupport(int feature);
+
+/** @brief Returns the number of logical CPUs available for the process.
+ */
+CV_EXPORTS_W int getNumberOfCPUs();
+
+
+/** @brief Aligns a pointer to the specified number of bytes.
+
+The function returns the aligned pointer of the same type as the input pointer:
+\f[\texttt{(_Tp*)(((size_t)ptr + n-1) & -n)}\f]
+@param ptr Aligned pointer.
+@param n Alignment size that must be a power of two.
+ */
+template<typename _Tp> static inline _Tp* alignPtr(_Tp* ptr, int n=(int)sizeof(_Tp))
+{
+ return (_Tp*)(((size_t)ptr + n-1) & -n);
+}
+
+/** @brief Aligns a buffer size to the specified number of bytes.
+
+The function returns the minimum number that is greater or equal to sz and is divisible by n :
+\f[\texttt{(sz + n-1) & -n}\f]
+@param sz Buffer size to align.
+@param n Alignment size that must be a power of two.
+ */
+static inline size_t alignSize(size_t sz, int n)
+{
+ CV_DbgAssert((n & (n - 1)) == 0); // n is a power of 2
+ return (sz + n-1) & -n;
+}
+
+/** @brief Enables or disables the optimized code.
+
+The function can be used to dynamically turn on and off optimized code (code that uses SSE2, AVX,
+and other instructions on the platforms that support it). It sets a global flag that is further
+checked by OpenCV functions. Since the flag is not checked in the inner OpenCV loops, it is only
+safe to call the function on the very top level in your application where you can be sure that no
+other OpenCV function is currently executed.
+
+By default, the optimized code is enabled unless you disable it in CMake. The current status can be
+retrieved using useOptimized.
+@param onoff The boolean flag specifying whether the optimized code should be used (onoff=true)
+or not (onoff=false).
+ */
+CV_EXPORTS_W void setUseOptimized(bool onoff);
+
+/** @brief Returns the status of optimized code usage.
+
+The function returns true if the optimized code is enabled. Otherwise, it returns false.
+ */
+CV_EXPORTS_W bool useOptimized();
+
+static inline size_t getElemSize(int type) { return CV_ELEM_SIZE(type); }
+
+/////////////////////////////// Parallel Primitives //////////////////////////////////
+
+/** @brief Base class for parallel data processors
+*/
+class CV_EXPORTS ParallelLoopBody
+{
+public:
+ virtual ~ParallelLoopBody();
+ virtual void operator() (const Range& range) const = 0;
+};
+
+/** @brief Parallel data processor
+*/
+CV_EXPORTS void parallel_for_(const Range& range, const ParallelLoopBody& body, double nstripes=-1.);
+
+/////////////////////////////// forEach method of cv::Mat ////////////////////////////
+template<typename _Tp, typename Functor> inline
+void Mat::forEach_impl(const Functor& operation) {
+ if (false) {
+ operation(*reinterpret_cast<_Tp*>(0), reinterpret_cast<int*>(0));
+ // If your compiler fail in this line.
+ // Please check that your functor signature is
+ // (_Tp&, const int*) <- multidimential
+ // or (_Tp&, void*) <- in case of you don't need current idx.
+ }
+
+ CV_Assert(this->total() / this->size[this->dims - 1] <= INT_MAX);
+ const int LINES = static_cast<int>(this->total() / this->size[this->dims - 1]);
+
+ class PixelOperationWrapper :public ParallelLoopBody
+ {
+ public:
+ PixelOperationWrapper(Mat_<_Tp>* const frame, const Functor& _operation)
+ : mat(frame), op(_operation) {}
+ virtual ~PixelOperationWrapper(){}
+ // ! Overloaded virtual operator
+ // convert range call to row call.
+ virtual void operator()(const Range &range) const {
+ const int DIMS = mat->dims;
+ const int COLS = mat->size[DIMS - 1];
+ if (DIMS <= 2) {
+ for (int row = range.start; row < range.end; ++row) {
+ this->rowCall2(row, COLS);
+ }
+ } else {
+ std::vector<int> idx(COLS); /// idx is modified in this->rowCall
+ idx[DIMS - 2] = range.start - 1;
+
+ for (int line_num = range.start; line_num < range.end; ++line_num) {
+ idx[DIMS - 2]++;
+ for (int i = DIMS - 2; i >= 0; --i) {
+ if (idx[i] >= mat->size[i]) {
+ idx[i - 1] += idx[i] / mat->size[i];
+ idx[i] %= mat->size[i];
+ continue; // carry-over;
+ }
+ else {
+ break;
+ }
+ }
+ this->rowCall(&idx[0], COLS, DIMS);
+ }
+ }
+ }
+ private:
+ Mat_<_Tp>* const mat;
+ const Functor op;
+ // ! Call operator for each elements in this row.
+ inline void rowCall(int* const idx, const int COLS, const int DIMS) const {
+ int &col = idx[DIMS - 1];
+ col = 0;
+ _Tp* pixel = &(mat->template at<_Tp>(idx));
+
+ while (col < COLS) {
+ op(*pixel, const_cast<const int*>(idx));
+ pixel++; col++;
+ }
+ col = 0;
+ }
+ // ! Call operator for each elements in this row. 2d mat special version.
+ inline void rowCall2(const int row, const int COLS) const {
+ union Index{
+ int body[2];
+ operator const int*() const {
+ return reinterpret_cast<const int*>(this);
+ }
+ int& operator[](const int i) {
+ return body[i];
+ }
+ } idx = {{row, 0}};
+ // Special union is needed to avoid
+ // "error: array subscript is above array bounds [-Werror=array-bounds]"
+ // when call the functor `op` such that access idx[3].
+
+ _Tp* pixel = &(mat->template at<_Tp>(idx));
+ const _Tp* const pixel_end = pixel + COLS;
+ while(pixel < pixel_end) {
+ op(*pixel++, static_cast<const int*>(idx));
+ idx[1]++;
+ }
+ }
+ PixelOperationWrapper& operator=(const PixelOperationWrapper &) {
+ CV_Assert(false);
+ // We can not remove this implementation because Visual Studio warning C4822.
+ return *this;
+ }
+ };
+
+ parallel_for_(cv::Range(0, LINES), PixelOperationWrapper(reinterpret_cast<Mat_<_Tp>*>(this), operation));
+}
+
+/////////////////////////// Synchronization Primitives ///////////////////////////////
+
+class CV_EXPORTS Mutex
+{
+public:
+ Mutex();
+ ~Mutex();
+ Mutex(const Mutex& m);
+ Mutex& operator = (const Mutex& m);
+
+ void lock();
+ bool trylock();
+ void unlock();
+
+ struct Impl;
+protected:
+ Impl* impl;
+};
+
+class CV_EXPORTS AutoLock
+{
+public:
+ AutoLock(Mutex& m) : mutex(&m) { mutex->lock(); }
+ ~AutoLock() { mutex->unlock(); }
+protected:
+ Mutex* mutex;
+private:
+ AutoLock(const AutoLock&);
+ AutoLock& operator = (const AutoLock&);
+};
+
+// TLS interface
+class CV_EXPORTS TLSDataContainer
+{
+protected:
+ TLSDataContainer();
+ virtual ~TLSDataContainer();
+
+ void gatherData(std::vector<void*> &data) const;
+#if OPENCV_ABI_COMPATIBILITY > 300
+ void* getData() const;
+ void release();
+
+private:
+#else
+ void release();
+
+public:
+ void* getData() const;
+#endif
+ virtual void* createDataInstance() const = 0;
+ virtual void deleteDataInstance(void* pData) const = 0;
+
+ int key_;
+};
+
+// Main TLS data class
+template <typename T>
+class TLSData : protected TLSDataContainer
+{
+public:
+ inline TLSData() {}
+ inline ~TLSData() { release(); } // Release key and delete associated data
+ inline T* get() const { return (T*)getData(); } // Get data assosiated with key
+
+ // Get data from all threads
+ inline void gather(std::vector<T*> &data) const
+ {
+ std::vector<void*> &dataVoid = reinterpret_cast<std::vector<void*>&>(data);
+ gatherData(dataVoid);
+ }
+
+private:
+ virtual void* createDataInstance() const {return new T;} // Wrapper to allocate data by template
+ virtual void deleteDataInstance(void* pData) const {delete (T*)pData;} // Wrapper to release data by template
+
+ // Disable TLS copy operations
+ TLSData(TLSData &) {}
+ TLSData& operator =(const TLSData &) {return *this;}
+};
+
+/** @brief Designed for command line parsing
+
+The sample below demonstrates how to use CommandLineParser:
+@code
+ CommandLineParser parser(argc, argv, keys);
+ parser.about("Application name v1.0.0");
+
+ if (parser.has("help"))
+ {
+ parser.printMessage();
+ return 0;
+ }
+
+ int N = parser.get<int>("N");
+ double fps = parser.get<double>("fps");
+ String path = parser.get<String>("path");
+
+ use_time_stamp = parser.has("timestamp");
+
+ String img1 = parser.get<String>(0);
+ String img2 = parser.get<String>(1);
+
+ int repeat = parser.get<int>(2);
+
+ if (!parser.check())
+ {
+ parser.printErrors();
+ return 0;
+ }
+@endcode
+
+### Keys syntax
+
+The keys parameter is a string containing several blocks, each one is enclosed in curley braces and
+describes one argument. Each argument contains three parts separated by the `|` symbol:
+
+-# argument names is a space-separated list of option synonyms (to mark argument as positional, prefix it with the `@` symbol)
+-# default value will be used if the argument was not provided (can be empty)
+-# help message (can be empty)
+
+For example:
+
+@code{.cpp}
+ const String keys =
+ "{help h usage ? | | print this message }"
+ "{@image1 | | image1 for compare }"
+ "{@image2 |<none>| image2 for compare }"
+ "{@repeat |1 | number }"
+ "{path |. | path to file }"
+ "{fps | -1.0 | fps for output video }"
+ "{N count |100 | count of objects }"
+ "{ts timestamp | | use time stamp }"
+ ;
+}
+@endcode
+
+Note that there are no default values for `help` and `timestamp` so we can check their presence using the `has()` method.
+Arguments with default values are considered to be always present. Use the `get()` method in these cases to check their
+actual value instead.
+
+String keys like `get<String>("@image1")` return the empty string `""` by default - even with an empty default value.
+Use the special `<none>` default value to enforce that the returned string must not be empty. (like in `get<String>("@image2")`)
+
+### Usage
+
+For the described keys:
+
+@code{.sh}
+ # Good call (3 positional parameters: image1, image2 and repeat; N is 200, ts is true)
+ $ ./app -N=200 1.png 2.jpg 19 -ts
+
+ # Bad call
+ $ ./app -fps=aaa
+ ERRORS:
+ Parameter 'fps': can not convert: [aaa] to [double]
+@endcode
+ */
+class CV_EXPORTS CommandLineParser
+{
+public:
+
+ /** @brief Constructor
+
+ Initializes command line parser object
+
+ @param argc number of command line arguments (from main())
+ @param argv array of command line arguments (from main())
+ @param keys string describing acceptable command line parameters (see class description for syntax)
+ */
+ CommandLineParser(int argc, const char* const argv[], const String& keys);
+
+ /** @brief Copy constructor */
+ CommandLineParser(const CommandLineParser& parser);
+
+ /** @brief Assignment operator */
+ CommandLineParser& operator = (const CommandLineParser& parser);
+
+ /** @brief Destructor */
+ ~CommandLineParser();
+
+ /** @brief Returns application path
+
+ This method returns the path to the executable from the command line (`argv[0]`).
+
+ For example, if the application has been started with such command:
+ @code{.sh}
+ $ ./bin/my-executable
+ @endcode
+ this method will return `./bin`.
+ */
+ String getPathToApplication() const;
+
+ /** @brief Access arguments by name
+
+ Returns argument converted to selected type. If the argument is not known or can not be
+ converted to selected type, the error flag is set (can be checked with @ref check).
+
+ For example, define:
+ @code{.cpp}
+ String keys = "{N count||}";
+ @endcode
+
+ Call:
+ @code{.sh}
+ $ ./my-app -N=20
+ # or
+ $ ./my-app --count=20
+ @endcode
+
+ Access:
+ @code{.cpp}
+ int N = parser.get<int>("N");
+ @endcode
+
+ @param name name of the argument
+ @param space_delete remove spaces from the left and right of the string
+ @tparam T the argument will be converted to this type if possible
+
+ @note You can access positional arguments by their `@`-prefixed name:
+ @code{.cpp}
+ parser.get<String>("@image");
+ @endcode
+ */
+ template <typename T>
+ T get(const String& name, bool space_delete = true) const
+ {
+ T val = T();
+ getByName(name, space_delete, ParamType<T>::type, (void*)&val);
+ return val;
+ }
+
+ /** @brief Access positional arguments by index
+
+ Returns argument converted to selected type. Indexes are counted from zero.
+
+ For example, define:
+ @code{.cpp}
+ String keys = "{@arg1||}{@arg2||}"
+ @endcode
+
+ Call:
+ @code{.sh}
+ ./my-app abc qwe
+ @endcode
+
+ Access arguments:
+ @code{.cpp}
+ String val_1 = parser.get<String>(0); // returns "abc", arg1
+ String val_2 = parser.get<String>(1); // returns "qwe", arg2
+ @endcode
+
+ @param index index of the argument
+ @param space_delete remove spaces from the left and right of the string
+ @tparam T the argument will be converted to this type if possible
+ */
+ template <typename T>
+ T get(int index, bool space_delete = true) const
+ {
+ T val = T();
+ getByIndex(index, space_delete, ParamType<T>::type, (void*)&val);
+ return val;
+ }
+
+ /** @brief Check if field was provided in the command line
+
+ @param name argument name to check
+ */
+ bool has(const String& name) const;
+
+ /** @brief Check for parsing errors
+
+ Returns true if error occured while accessing the parameters (bad conversion, missing arguments,
+ etc.). Call @ref printErrors to print error messages list.
+ */
+ bool check() const;
+
+ /** @brief Set the about message
+
+ The about message will be shown when @ref printMessage is called, right before arguments table.
+ */
+ void about(const String& message);
+
+ /** @brief Print help message
+
+ This method will print standard help message containing the about message and arguments description.
+
+ @sa about
+ */
+ void printMessage() const;
+
+ /** @brief Print list of errors occured
+
+ @sa check
+ */
+ void printErrors() const;
+
+protected:
+ void getByName(const String& name, bool space_delete, int type, void* dst) const;
+ void getByIndex(int index, bool space_delete, int type, void* dst) const;
+
+ struct Impl;
+ Impl* impl;
+};
+
+//! @} core_utils
+
+//! @cond IGNORED
+
+/////////////////////////////// AutoBuffer implementation ////////////////////////////////////////
+
+template<typename _Tp, size_t fixed_size> inline
+AutoBuffer<_Tp, fixed_size>::AutoBuffer()
+{
+ ptr = buf;
+ sz = fixed_size;
+}
+
+template<typename _Tp, size_t fixed_size> inline
+AutoBuffer<_Tp, fixed_size>::AutoBuffer(size_t _size)
+{
+ ptr = buf;
+ sz = fixed_size;
+ allocate(_size);
+}
+
+template<typename _Tp, size_t fixed_size> inline
+AutoBuffer<_Tp, fixed_size>::AutoBuffer(const AutoBuffer<_Tp, fixed_size>& abuf )
+{
+ ptr = buf;
+ sz = fixed_size;
+ allocate(abuf.size());
+ for( size_t i = 0; i < sz; i++ )
+ ptr[i] = abuf.ptr[i];
+}
+
+template<typename _Tp, size_t fixed_size> inline AutoBuffer<_Tp, fixed_size>&
+AutoBuffer<_Tp, fixed_size>::operator = (const AutoBuffer<_Tp, fixed_size>& abuf)
+{
+ if( this != &abuf )
+ {
+ deallocate();
+ allocate(abuf.size());
+ for( size_t i = 0; i < sz; i++ )
+ ptr[i] = abuf.ptr[i];
+ }
+ return *this;
+}
+
+template<typename _Tp, size_t fixed_size> inline
+AutoBuffer<_Tp, fixed_size>::~AutoBuffer()
+{ deallocate(); }
+
+template<typename _Tp, size_t fixed_size> inline void
+AutoBuffer<_Tp, fixed_size>::allocate(size_t _size)
+{
+ if(_size <= sz)
+ {
+ sz = _size;
+ return;
+ }
+ deallocate();
+ sz = _size;
+ if(_size > fixed_size)
+ {
+ ptr = new _Tp[_size];
+ }
+}
+
+template<typename _Tp, size_t fixed_size> inline void
+AutoBuffer<_Tp, fixed_size>::deallocate()
+{
+ if( ptr != buf )
+ {
+ delete[] ptr;
+ ptr = buf;
+ sz = fixed_size;
+ }
+}
+
+template<typename _Tp, size_t fixed_size> inline void
+AutoBuffer<_Tp, fixed_size>::resize(size_t _size)
+{
+ if(_size <= sz)
+ {
+ sz = _size;
+ return;
+ }
+ size_t i, prevsize = sz, minsize = MIN(prevsize, _size);
+ _Tp* prevptr = ptr;
+
+ ptr = _size > fixed_size ? new _Tp[_size] : buf;
+ sz = _size;
+
+ if( ptr != prevptr )
+ for( i = 0; i < minsize; i++ )
+ ptr[i] = prevptr[i];
+ for( i = prevsize; i < _size; i++ )
+ ptr[i] = _Tp();
+
+ if( prevptr != buf )
+ delete[] prevptr;
+}
+
+template<typename _Tp, size_t fixed_size> inline size_t
+AutoBuffer<_Tp, fixed_size>::size() const
+{ return sz; }
+
+template<typename _Tp, size_t fixed_size> inline
+AutoBuffer<_Tp, fixed_size>::operator _Tp* ()
+{ return ptr; }
+
+template<typename _Tp, size_t fixed_size> inline
+AutoBuffer<_Tp, fixed_size>::operator const _Tp* () const
+{ return ptr; }
+
+#ifndef OPENCV_NOSTL
+template<> inline std::string CommandLineParser::get<std::string>(int index, bool space_delete) const
+{
+ return get<String>(index, space_delete);
+}
+template<> inline std::string CommandLineParser::get<std::string>(const String& name, bool space_delete) const
+{
+ return get<String>(name, space_delete);
+}
+#endif // OPENCV_NOSTL
+
+//! @endcond
+
+
+// Basic Node class for tree building
+template<class OBJECT>
+class CV_EXPORTS Node
+{
+public:
+ Node()
+ {
+ m_pParent = 0;
+ }
+ Node(OBJECT& payload) : m_payload(payload)
+ {
+ m_pParent = 0;
+ }
+ ~Node()
+ {
+ removeChilds();
+ if (m_pParent)
+ {
+ int idx = m_pParent->findChild(this);
+ if (idx >= 0)
+ m_pParent->m_childs.erase(m_pParent->m_childs.begin() + idx);
+ }
+ }
+
+ Node<OBJECT>* findChild(OBJECT& payload) const
+ {
+ for(size_t i = 0; i < this->m_childs.size(); i++)
+ {
+ if(this->m_childs[i]->m_payload == payload)
+ return this->m_childs[i];
+ }
+ return NULL;
+ }
+
+ int findChild(Node<OBJECT> *pNode) const
+ {
+ for (size_t i = 0; i < this->m_childs.size(); i++)
+ {
+ if(this->m_childs[i] == pNode)
+ return (int)i;
+ }
+ return -1;
+ }
+
+ void addChild(Node<OBJECT> *pNode)
+ {
+ if(!pNode)
+ return;
+
+ CV_Assert(pNode->m_pParent == 0);
+ pNode->m_pParent = this;
+ this->m_childs.push_back(pNode);
+ }
+
+ void removeChilds()
+ {
+ for(size_t i = 0; i < m_childs.size(); i++)
+ {
+ m_childs[i]->m_pParent = 0; // avoid excessive parent vector trimming
+ delete m_childs[i];
+ }
+ m_childs.clear();
+ }
+
+ int getDepth()
+ {
+ int count = 0;
+ Node *pParent = m_pParent;
+ while(pParent) count++, pParent = pParent->m_pParent;
+ return count;
+ }
+
+public:
+ OBJECT m_payload;
+ Node<OBJECT>* m_pParent;
+ std::vector<Node<OBJECT>*> m_childs;
+};
+
+// Instrumentation external interface
+namespace instr
+{
+
+#if !defined OPENCV_ABI_CHECK
+
+enum TYPE
+{
+ TYPE_GENERAL = 0, // OpenCV API function, e.g. exported function
+ TYPE_MARKER, // Information marker
+ TYPE_WRAPPER, // Wrapper function for implementation
+ TYPE_FUN, // Simple function call
+};
+
+enum IMPL
+{
+ IMPL_PLAIN = 0,
+ IMPL_IPP,
+ IMPL_OPENCL,
+};
+
+struct NodeDataTls
+{
+ NodeDataTls()
+ {
+ m_ticksTotal = 0;
+ }
+ uint64 m_ticksTotal;
+};
+
+class CV_EXPORTS NodeData
+{
+public:
+ NodeData(const char* funName = 0, const char* fileName = NULL, int lineNum = 0, void* retAddress = NULL, bool alwaysExpand = false, cv::instr::TYPE instrType = TYPE_GENERAL, cv::instr::IMPL implType = IMPL_PLAIN);
+ NodeData(NodeData &ref);
+ ~NodeData();
+ NodeData& operator=(const NodeData&);
+
+ cv::String m_funName;
+ cv::instr::TYPE m_instrType;
+ cv::instr::IMPL m_implType;
+ const char* m_fileName;
+ int m_lineNum;
+ void* m_retAddress;
+ bool m_alwaysExpand;
+ bool m_funError;
+
+ volatile int m_counter;
+ volatile uint64 m_ticksTotal;
+ TLSData<NodeDataTls> m_tls;
+ int m_threads;
+
+ // No synchronization
+ double getTotalMs() const { return ((double)m_ticksTotal / cv::getTickFrequency()) * 1000; }
+ double getMeanMs() const { return (((double)m_ticksTotal/m_counter) / cv::getTickFrequency()) * 1000; }
+};
+bool operator==(const NodeData& lhs, const NodeData& rhs);
+
+typedef Node<NodeData> InstrNode;
+
+CV_EXPORTS InstrNode* getTrace();
+
+#endif // !defined OPENCV_ABI_CHECK
+
+
+CV_EXPORTS bool useInstrumentation();
+CV_EXPORTS void setUseInstrumentation(bool flag);
+CV_EXPORTS void resetTrace();
+
+enum FLAGS
+{
+ FLAGS_NONE = 0,
+ FLAGS_MAPPING = 0x01,
+ FLAGS_EXPAND_SAME_NAMES = 0x02,
+};
+
+CV_EXPORTS void setFlags(FLAGS modeFlags);
+static inline void setFlags(int modeFlags) { setFlags((FLAGS)modeFlags); }
+CV_EXPORTS FLAGS getFlags();
+}
+
+} //namespace cv
+
+#ifndef DISABLE_OPENCV_24_COMPATIBILITY
+#include "opencv2/core/core_c.h"
+#endif
+
+#endif //OPENCV_CORE_UTILITY_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/core/va_intel.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,77 @@
+// This file is part of OpenCV project.
+// It is subject to the license terms in the LICENSE file found in the top-level directory
+// of this distribution and at http://opencv.org/license.html.
+
+// Copyright (C) 2015, Itseez, Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+
+#ifndef OPENCV_CORE_VA_INTEL_HPP
+#define OPENCV_CORE_VA_INTEL_HPP
+
+#ifndef __cplusplus
+# error va_intel.hpp header must be compiled as C++
+#endif
+
+#include "opencv2/core.hpp"
+#include "ocl.hpp"
+
+#if defined(HAVE_VA)
+# include "va/va.h"
+#else // HAVE_VA
+# if !defined(_VA_H_)
+ typedef void* VADisplay;
+ typedef unsigned int VASurfaceID;
+# endif // !_VA_H_
+#endif // HAVE_VA
+
+namespace cv { namespace va_intel {
+
+/** @addtogroup core_va_intel
+This section describes Intel VA-API/OpenCL (CL-VA) interoperability.
+
+To enable CL-VA interoperability support, configure OpenCV using CMake with WITH_VA_INTEL=ON . Currently VA-API is
+supported on Linux only. You should also install Intel Media Server Studio (MSS) to use this feature. You may
+have to specify the path(s) to MSS components for cmake in environment variables: VA_INTEL_MSDK_ROOT for Media SDK
+(default is "/opt/intel/mediasdk"), and VA_INTEL_IOCL_ROOT for Intel OpenCL (default is "/opt/intel/opencl").
+
+To use CL-VA interoperability you should first create VADisplay (libva), and then call initializeContextFromVA()
+function to create OpenCL context and set up interoperability.
+*/
+//! @{
+
+/////////////////// CL-VA Interoperability Functions ///////////////////
+
+namespace ocl {
+using namespace cv::ocl;
+
+// TODO static functions in the Context class
+/** @brief Creates OpenCL context from VA.
+@param display - VADisplay for which CL interop should be established.
+@param tryInterop - try to set up for interoperability, if true; set up for use slow copy if false.
+@return Returns reference to OpenCL Context
+ */
+CV_EXPORTS Context& initializeContextFromVA(VADisplay display, bool tryInterop = true);
+
+} // namespace cv::va_intel::ocl
+
+/** @brief Converts InputArray to VASurfaceID object.
+@param display - VADisplay object.
+@param src - source InputArray.
+@param surface - destination VASurfaceID object.
+@param size - size of image represented by VASurfaceID object.
+ */
+CV_EXPORTS void convertToVASurface(VADisplay display, InputArray src, VASurfaceID surface, Size size);
+
+/** @brief Converts VASurfaceID object to OutputArray.
+@param display - VADisplay object.
+@param surface - source VASurfaceID object.
+@param size - size of image represented by VASurfaceID object.
+@param dst - destination OutputArray.
+ */
+CV_EXPORTS void convertFromVASurface(VADisplay display, VASurfaceID surface, Size size, OutputArray dst);
+
+//! @}
+
+}} // namespace cv::va_intel
+
+#endif /* OPENCV_CORE_VA_INTEL_HPP */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/opencv2/core/version.hpp Fri Jan 29 04:53:38 2021 +0000 @@ -0,0 +1,71 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright( C) 2000-2015, Intel Corporation, all rights reserved. +// Copyright (C) 2011-2013, NVIDIA Corporation, all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Copyright (C) 2015, Itseez Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +//(including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort(including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +/* + definition of the current version of OpenCV + Usefull to test in user programs +*/ + +#ifndef OPENCV_VERSION_HPP +#define OPENCV_VERSION_HPP + +#define CV_VERSION_MAJOR 3 +#define CV_VERSION_MINOR 2 +#define CV_VERSION_REVISION 0 +#define CV_VERSION_STATUS "" + +#define CVAUX_STR_EXP(__A) #__A +#define CVAUX_STR(__A) CVAUX_STR_EXP(__A) + +#define CVAUX_STRW_EXP(__A) L ## #__A +#define CVAUX_STRW(__A) CVAUX_STRW_EXP(__A) + +#define CV_VERSION CVAUX_STR(CV_VERSION_MAJOR) "." CVAUX_STR(CV_VERSION_MINOR) "." CVAUX_STR(CV_VERSION_REVISION) CV_VERSION_STATUS + +/* old style version constants*/ +#define CV_MAJOR_VERSION CV_VERSION_MAJOR +#define CV_MINOR_VERSION CV_VERSION_MINOR +#define CV_SUBMINOR_VERSION CV_VERSION_REVISION + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/core/wimage.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,603 @@
+/*M//////////////////////////////////////////////////////////////////////////////
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to
+// this license. If you do not agree to this license, do not download,
+// install, copy or use the software.
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2008, Google, all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of Intel Corporation or contributors may not be used to endorse
+// or promote products derived from this software without specific
+// prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is"
+// and any express or implied warranties, including, but not limited to, the
+// implied warranties of merchantability and fitness for a particular purpose
+// are disclaimed. In no event shall the Intel Corporation or contributors be
+// liable for any direct, indirect, incidental, special, exemplary, or
+// consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+/////////////////////////////////////////////////////////////////////////////////
+//M*/
+
+#ifndef OPENCV_CORE_WIMAGE_HPP
+#define OPENCV_CORE_WIMAGE_HPP
+
+#include "opencv2/core/core_c.h"
+
+#ifdef __cplusplus
+
+namespace cv {
+
+//! @addtogroup core
+//! @{
+
+template <typename T> class WImage;
+template <typename T> class WImageBuffer;
+template <typename T> class WImageView;
+
+template<typename T, int C> class WImageC;
+template<typename T, int C> class WImageBufferC;
+template<typename T, int C> class WImageViewC;
+
+// Commonly used typedefs.
+typedef WImage<uchar> WImage_b;
+typedef WImageView<uchar> WImageView_b;
+typedef WImageBuffer<uchar> WImageBuffer_b;
+
+typedef WImageC<uchar, 1> WImage1_b;
+typedef WImageViewC<uchar, 1> WImageView1_b;
+typedef WImageBufferC<uchar, 1> WImageBuffer1_b;
+
+typedef WImageC<uchar, 3> WImage3_b;
+typedef WImageViewC<uchar, 3> WImageView3_b;
+typedef WImageBufferC<uchar, 3> WImageBuffer3_b;
+
+typedef WImage<float> WImage_f;
+typedef WImageView<float> WImageView_f;
+typedef WImageBuffer<float> WImageBuffer_f;
+
+typedef WImageC<float, 1> WImage1_f;
+typedef WImageViewC<float, 1> WImageView1_f;
+typedef WImageBufferC<float, 1> WImageBuffer1_f;
+
+typedef WImageC<float, 3> WImage3_f;
+typedef WImageViewC<float, 3> WImageView3_f;
+typedef WImageBufferC<float, 3> WImageBuffer3_f;
+
+// There isn't a standard for signed and unsigned short so be more
+// explicit in the typename for these cases.
+typedef WImage<short> WImage_16s;
+typedef WImageView<short> WImageView_16s;
+typedef WImageBuffer<short> WImageBuffer_16s;
+
+typedef WImageC<short, 1> WImage1_16s;
+typedef WImageViewC<short, 1> WImageView1_16s;
+typedef WImageBufferC<short, 1> WImageBuffer1_16s;
+
+typedef WImageC<short, 3> WImage3_16s;
+typedef WImageViewC<short, 3> WImageView3_16s;
+typedef WImageBufferC<short, 3> WImageBuffer3_16s;
+
+typedef WImage<ushort> WImage_16u;
+typedef WImageView<ushort> WImageView_16u;
+typedef WImageBuffer<ushort> WImageBuffer_16u;
+
+typedef WImageC<ushort, 1> WImage1_16u;
+typedef WImageViewC<ushort, 1> WImageView1_16u;
+typedef WImageBufferC<ushort, 1> WImageBuffer1_16u;
+
+typedef WImageC<ushort, 3> WImage3_16u;
+typedef WImageViewC<ushort, 3> WImageView3_16u;
+typedef WImageBufferC<ushort, 3> WImageBuffer3_16u;
+
+/** @brief Image class which provides a thin layer around an IplImage.
+
+The goals of the class design are:
+
+ -# All the data has explicit ownership to avoid memory leaks
+ -# No hidden allocations or copies for performance.
+ -# Easy access to OpenCV methods (which will access IPP if available)
+ -# Can easily treat external data as an image
+ -# Easy to create images which are subsets of other images
+ -# Fast pixel access which can take advantage of number of channels if known at compile time.
+
+The WImage class is the image class which provides the data accessors. The 'W' comes from the fact
+that it is also a wrapper around the popular but inconvenient IplImage class. A WImage can be
+constructed either using a WImageBuffer class which allocates and frees the data, or using a
+WImageView class which constructs a subimage or a view into external data. The view class does no
+memory management. Each class actually has two versions, one when the number of channels is known
+at compile time and one when it isn't. Using the one with the number of channels specified can
+provide some compile time optimizations by using the fact that the number of channels is a
+constant.
+
+We use the convention (c,r) to refer to column c and row r with (0,0) being the upper left corner.
+This is similar to standard Euclidean coordinates with the first coordinate varying in the
+horizontal direction and the second coordinate varying in the vertical direction. Thus (c,r) is
+usually in the domain [0, width) X [0, height)
+
+Example usage:
+@code
+WImageBuffer3_b im(5,7); // Make a 5X7 3 channel image of type uchar
+WImageView3_b sub_im(im, 2,2, 3,3); // 3X3 submatrix
+vector<float> vec(10, 3.0f);
+WImageView1_f user_im(&vec[0], 2, 5); // 2X5 image w/ supplied data
+
+im.SetZero(); // same as cvSetZero(im.Ipl())
+*im(2, 3) = 15; // Modify the element at column 2, row 3
+MySetRand(&sub_im);
+
+// Copy the second row into the first. This can be done with no memory
+// allocation and will use SSE if IPP is available.
+int w = im.Width();
+im.View(0,0, w,1).CopyFrom(im.View(0,1, w,1));
+
+// Doesn't care about source of data since using WImage
+void MySetRand(WImage_b* im) { // Works with any number of channels
+for (int r = 0; r < im->Height(); ++r) {
+ float* row = im->Row(r);
+ for (int c = 0; c < im->Width(); ++c) {
+ for (int ch = 0; ch < im->Channels(); ++ch, ++row) {
+ *row = uchar(rand() & 255);
+ }
+ }
+}
+}
+@endcode
+
+Functions that are not part of the basic image allocation, viewing, and access should come from
+OpenCV, except some useful functions that are not part of OpenCV can be found in wimage_util.h
+*/
+template<typename T>
+class WImage
+{
+public:
+ typedef T BaseType;
+
+ // WImage is an abstract class with no other virtual methods so make the
+ // destructor virtual.
+ virtual ~WImage() = 0;
+
+ // Accessors
+ IplImage* Ipl() {return image_; }
+ const IplImage* Ipl() const {return image_; }
+ T* ImageData() { return reinterpret_cast<T*>(image_->imageData); }
+ const T* ImageData() const {
+ return reinterpret_cast<const T*>(image_->imageData);
+ }
+
+ int Width() const {return image_->width; }
+ int Height() const {return image_->height; }
+
+ // WidthStep is the number of bytes to go to the pixel with the next y coord
+ int WidthStep() const {return image_->widthStep; }
+
+ int Channels() const {return image_->nChannels; }
+ int ChannelSize() const {return sizeof(T); } // number of bytes per channel
+
+ // Number of bytes per pixel
+ int PixelSize() const {return Channels() * ChannelSize(); }
+
+ // Return depth type (e.g. IPL_DEPTH_8U, IPL_DEPTH_32F) which is the number
+ // of bits per channel and with the signed bit set.
+ // This is known at compile time using specializations.
+ int Depth() const;
+
+ inline const T* Row(int r) const {
+ return reinterpret_cast<T*>(image_->imageData + r*image_->widthStep);
+ }
+
+ inline T* Row(int r) {
+ return reinterpret_cast<T*>(image_->imageData + r*image_->widthStep);
+ }
+
+ // Pixel accessors which returns a pointer to the start of the channel
+ inline T* operator() (int c, int r) {
+ return reinterpret_cast<T*>(image_->imageData + r*image_->widthStep) +
+ c*Channels();
+ }
+
+ inline const T* operator() (int c, int r) const {
+ return reinterpret_cast<T*>(image_->imageData + r*image_->widthStep) +
+ c*Channels();
+ }
+
+ // Copy the contents from another image which is just a convenience to cvCopy
+ void CopyFrom(const WImage<T>& src) { cvCopy(src.Ipl(), image_); }
+
+ // Set contents to zero which is just a convenient to cvSetZero
+ void SetZero() { cvSetZero(image_); }
+
+ // Construct a view into a region of this image
+ WImageView<T> View(int c, int r, int width, int height);
+
+protected:
+ // Disallow copy and assignment
+ WImage(const WImage&);
+ void operator=(const WImage&);
+
+ explicit WImage(IplImage* img) : image_(img) {
+ assert(!img || img->depth == Depth());
+ }
+
+ void SetIpl(IplImage* image) {
+ assert(!image || image->depth == Depth());
+ image_ = image;
+ }
+
+ IplImage* image_;
+};
+
+
+/** Image class when both the pixel type and number of channels
+are known at compile time. This wrapper will speed up some of the operations
+like accessing individual pixels using the () operator.
+*/
+template<typename T, int C>
+class WImageC : public WImage<T>
+{
+public:
+ typedef typename WImage<T>::BaseType BaseType;
+ enum { kChannels = C };
+
+ explicit WImageC(IplImage* img) : WImage<T>(img) {
+ assert(!img || img->nChannels == Channels());
+ }
+
+ // Construct a view into a region of this image
+ WImageViewC<T, C> View(int c, int r, int width, int height);
+
+ // Copy the contents from another image which is just a convenience to cvCopy
+ void CopyFrom(const WImageC<T, C>& src) {
+ cvCopy(src.Ipl(), WImage<T>::image_);
+ }
+
+ // WImageC is an abstract class with no other virtual methods so make the
+ // destructor virtual.
+ virtual ~WImageC() = 0;
+
+ int Channels() const {return C; }
+
+protected:
+ // Disallow copy and assignment
+ WImageC(const WImageC&);
+ void operator=(const WImageC&);
+
+ void SetIpl(IplImage* image) {
+ assert(!image || image->depth == WImage<T>::Depth());
+ WImage<T>::SetIpl(image);
+ }
+};
+
+/** Image class which owns the data, so it can be allocated and is always
+freed. It cannot be copied but can be explicity cloned.
+*/
+template<typename T>
+class WImageBuffer : public WImage<T>
+{
+public:
+ typedef typename WImage<T>::BaseType BaseType;
+
+ // Default constructor which creates an object that can be
+ WImageBuffer() : WImage<T>(0) {}
+
+ WImageBuffer(int width, int height, int nchannels) : WImage<T>(0) {
+ Allocate(width, height, nchannels);
+ }
+
+ // Constructor which takes ownership of a given IplImage so releases
+ // the image on destruction.
+ explicit WImageBuffer(IplImage* img) : WImage<T>(img) {}
+
+ // Allocate an image. Does nothing if current size is the same as
+ // the new size.
+ void Allocate(int width, int height, int nchannels);
+
+ // Set the data to point to an image, releasing the old data
+ void SetIpl(IplImage* img) {
+ ReleaseImage();
+ WImage<T>::SetIpl(img);
+ }
+
+ // Clone an image which reallocates the image if of a different dimension.
+ void CloneFrom(const WImage<T>& src) {
+ Allocate(src.Width(), src.Height(), src.Channels());
+ CopyFrom(src);
+ }
+
+ ~WImageBuffer() {
+ ReleaseImage();
+ }
+
+ // Release the image if it isn't null.
+ void ReleaseImage() {
+ if (WImage<T>::image_) {
+ IplImage* image = WImage<T>::image_;
+ cvReleaseImage(&image);
+ WImage<T>::SetIpl(0);
+ }
+ }
+
+ bool IsNull() const {return WImage<T>::image_ == NULL; }
+
+private:
+ // Disallow copy and assignment
+ WImageBuffer(const WImageBuffer&);
+ void operator=(const WImageBuffer&);
+};
+
+/** Like a WImageBuffer class but when the number of channels is known at compile time.
+*/
+template<typename T, int C>
+class WImageBufferC : public WImageC<T, C>
+{
+public:
+ typedef typename WImage<T>::BaseType BaseType;
+ enum { kChannels = C };
+
+ // Default constructor which creates an object that can be
+ WImageBufferC() : WImageC<T, C>(0) {}
+
+ WImageBufferC(int width, int height) : WImageC<T, C>(0) {
+ Allocate(width, height);
+ }
+
+ // Constructor which takes ownership of a given IplImage so releases
+ // the image on destruction.
+ explicit WImageBufferC(IplImage* img) : WImageC<T, C>(img) {}
+
+ // Allocate an image. Does nothing if current size is the same as
+ // the new size.
+ void Allocate(int width, int height);
+
+ // Set the data to point to an image, releasing the old data
+ void SetIpl(IplImage* img) {
+ ReleaseImage();
+ WImageC<T, C>::SetIpl(img);
+ }
+
+ // Clone an image which reallocates the image if of a different dimension.
+ void CloneFrom(const WImageC<T, C>& src) {
+ Allocate(src.Width(), src.Height());
+ CopyFrom(src);
+ }
+
+ ~WImageBufferC() {
+ ReleaseImage();
+ }
+
+ // Release the image if it isn't null.
+ void ReleaseImage() {
+ if (WImage<T>::image_) {
+ IplImage* image = WImage<T>::image_;
+ cvReleaseImage(&image);
+ WImageC<T, C>::SetIpl(0);
+ }
+ }
+
+ bool IsNull() const {return WImage<T>::image_ == NULL; }
+
+private:
+ // Disallow copy and assignment
+ WImageBufferC(const WImageBufferC&);
+ void operator=(const WImageBufferC&);
+};
+
+/** View into an image class which allows treating a subimage as an image or treating external data
+as an image
+*/
+template<typename T> class WImageView : public WImage<T>
+{
+public:
+ typedef typename WImage<T>::BaseType BaseType;
+
+ // Construct a subimage. No checks are done that the subimage lies
+ // completely inside the original image.
+ WImageView(WImage<T>* img, int c, int r, int width, int height);
+
+ // Refer to external data.
+ // If not given width_step assumed to be same as width.
+ WImageView(T* data, int width, int height, int channels, int width_step = -1);
+
+ // Refer to external data. This does NOT take ownership
+ // of the supplied IplImage.
+ WImageView(IplImage* img) : WImage<T>(img) {}
+
+ // Copy constructor
+ WImageView(const WImage<T>& img) : WImage<T>(0) {
+ header_ = *(img.Ipl());
+ WImage<T>::SetIpl(&header_);
+ }
+
+ WImageView& operator=(const WImage<T>& img) {
+ header_ = *(img.Ipl());
+ WImage<T>::SetIpl(&header_);
+ return *this;
+ }
+
+protected:
+ IplImage header_;
+};
+
+
+template<typename T, int C>
+class WImageViewC : public WImageC<T, C>
+{
+public:
+ typedef typename WImage<T>::BaseType BaseType;
+ enum { kChannels = C };
+
+ // Default constructor needed for vectors of views.
+ WImageViewC();
+
+ virtual ~WImageViewC() {}
+
+ // Construct a subimage. No checks are done that the subimage lies
+ // completely inside the original image.
+ WImageViewC(WImageC<T, C>* img,
+ int c, int r, int width, int height);
+
+ // Refer to external data
+ WImageViewC(T* data, int width, int height, int width_step = -1);
+
+ // Refer to external data. This does NOT take ownership
+ // of the supplied IplImage.
+ WImageViewC(IplImage* img) : WImageC<T, C>(img) {}
+
+ // Copy constructor which does a shallow copy to allow multiple views
+ // of same data. gcc-4.1.1 gets confused if both versions of
+ // the constructor and assignment operator are not provided.
+ WImageViewC(const WImageC<T, C>& img) : WImageC<T, C>(0) {
+ header_ = *(img.Ipl());
+ WImageC<T, C>::SetIpl(&header_);
+ }
+ WImageViewC(const WImageViewC<T, C>& img) : WImageC<T, C>(0) {
+ header_ = *(img.Ipl());
+ WImageC<T, C>::SetIpl(&header_);
+ }
+
+ WImageViewC& operator=(const WImageC<T, C>& img) {
+ header_ = *(img.Ipl());
+ WImageC<T, C>::SetIpl(&header_);
+ return *this;
+ }
+ WImageViewC& operator=(const WImageViewC<T, C>& img) {
+ header_ = *(img.Ipl());
+ WImageC<T, C>::SetIpl(&header_);
+ return *this;
+ }
+
+protected:
+ IplImage header_;
+};
+
+
+// Specializations for depth
+template<>
+inline int WImage<uchar>::Depth() const {return IPL_DEPTH_8U; }
+template<>
+inline int WImage<signed char>::Depth() const {return IPL_DEPTH_8S; }
+template<>
+inline int WImage<short>::Depth() const {return IPL_DEPTH_16S; }
+template<>
+inline int WImage<ushort>::Depth() const {return IPL_DEPTH_16U; }
+template<>
+inline int WImage<int>::Depth() const {return IPL_DEPTH_32S; }
+template<>
+inline int WImage<float>::Depth() const {return IPL_DEPTH_32F; }
+template<>
+inline int WImage<double>::Depth() const {return IPL_DEPTH_64F; }
+
+template<typename T> inline WImage<T>::~WImage() {}
+template<typename T, int C> inline WImageC<T, C>::~WImageC() {}
+
+template<typename T>
+inline void WImageBuffer<T>::Allocate(int width, int height, int nchannels)
+{
+ if (IsNull() || WImage<T>::Width() != width ||
+ WImage<T>::Height() != height || WImage<T>::Channels() != nchannels) {
+ ReleaseImage();
+ WImage<T>::image_ = cvCreateImage(cvSize(width, height),
+ WImage<T>::Depth(), nchannels);
+ }
+}
+
+template<typename T, int C>
+inline void WImageBufferC<T, C>::Allocate(int width, int height)
+{
+ if (IsNull() || WImage<T>::Width() != width || WImage<T>::Height() != height) {
+ ReleaseImage();
+ WImageC<T, C>::SetIpl(cvCreateImage(cvSize(width, height),WImage<T>::Depth(), C));
+ }
+}
+
+template<typename T>
+WImageView<T>::WImageView(WImage<T>* img, int c, int r, int width, int height)
+ : WImage<T>(0)
+{
+ header_ = *(img->Ipl());
+ header_.imageData = reinterpret_cast<char*>((*img)(c, r));
+ header_.width = width;
+ header_.height = height;
+ WImage<T>::SetIpl(&header_);
+}
+
+template<typename T>
+WImageView<T>::WImageView(T* data, int width, int height, int nchannels, int width_step)
+ : WImage<T>(0)
+{
+ cvInitImageHeader(&header_, cvSize(width, height), WImage<T>::Depth(), nchannels);
+ header_.imageData = reinterpret_cast<char*>(data);
+ if (width_step > 0) {
+ header_.widthStep = width_step;
+ }
+ WImage<T>::SetIpl(&header_);
+}
+
+template<typename T, int C>
+WImageViewC<T, C>::WImageViewC(WImageC<T, C>* img, int c, int r, int width, int height)
+ : WImageC<T, C>(0)
+{
+ header_ = *(img->Ipl());
+ header_.imageData = reinterpret_cast<char*>((*img)(c, r));
+ header_.width = width;
+ header_.height = height;
+ WImageC<T, C>::SetIpl(&header_);
+}
+
+template<typename T, int C>
+WImageViewC<T, C>::WImageViewC() : WImageC<T, C>(0) {
+ cvInitImageHeader(&header_, cvSize(0, 0), WImage<T>::Depth(), C);
+ header_.imageData = reinterpret_cast<char*>(0);
+ WImageC<T, C>::SetIpl(&header_);
+}
+
+template<typename T, int C>
+WImageViewC<T, C>::WImageViewC(T* data, int width, int height, int width_step)
+ : WImageC<T, C>(0)
+{
+ cvInitImageHeader(&header_, cvSize(width, height), WImage<T>::Depth(), C);
+ header_.imageData = reinterpret_cast<char*>(data);
+ if (width_step > 0) {
+ header_.widthStep = width_step;
+ }
+ WImageC<T, C>::SetIpl(&header_);
+}
+
+// Construct a view into a region of an image
+template<typename T>
+WImageView<T> WImage<T>::View(int c, int r, int width, int height) {
+ return WImageView<T>(this, c, r, width, height);
+}
+
+template<typename T, int C>
+WImageViewC<T, C> WImageC<T, C>::View(int c, int r, int width, int height) {
+ return WImageViewC<T, C>(this, c, r, width, height);
+}
+
+//! @} core
+
+} // end of namespace
+
+#endif // __cplusplus
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/opencv2/custom_hal.hpp Fri Jan 29 04:53:38 2021 +0000 @@ -0,0 +1,5 @@ +#ifndef _CUSTOM_HAL_INCLUDED_ +#define _CUSTOM_HAL_INCLUDED_ + + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/opencv2/cvconfig.h Fri Jan 29 04:53:38 2021 +0000 @@ -0,0 +1,208 @@ +/* OpenCV compiled as static or dynamic libs */ +/* #undef BUILD_SHARED_LIBS */ + +/* Compile for 'real' NVIDIA GPU architectures */ +#define CUDA_ARCH_BIN "" + +/* Create PTX or BIN for 1.0 compute capability */ +/* #undef CUDA_ARCH_BIN_OR_PTX_10 */ + +/* NVIDIA GPU features are used */ +#define CUDA_ARCH_FEATURES "" + +/* Compile for 'virtual' NVIDIA PTX architectures */ +#define CUDA_ARCH_PTX "" + +/* AVFoundation video libraries */ +/* #undef HAVE_AVFOUNDATION */ + +/* V4L capturing support */ +/* #undef HAVE_CAMV4L */ + +/* V4L2 capturing support */ +/* #undef HAVE_CAMV4L2 */ + +/* Carbon windowing environment */ +/* #undef HAVE_CARBON */ + +/* AMD's Basic Linear Algebra Subprograms Library*/ +/* #undef HAVE_CLAMDBLAS */ + +/* AMD's OpenCL Fast Fourier Transform Library*/ +/* #undef HAVE_CLAMDFFT */ + +/* Clp support */ +/* #undef HAVE_CLP */ + +/* Cocoa API */ +/* #undef HAVE_COCOA */ + +/* C= */ +/* #undef HAVE_CSTRIPES */ + +/* NVidia Cuda Basic Linear Algebra Subprograms (BLAS) API*/ +/* #undef HAVE_CUBLAS */ + +/* NVidia Cuda Runtime API*/ +/* #undef HAVE_CUDA */ + +/* NVidia Cuda Fast Fourier Transform (FFT) API*/ +/* #undef HAVE_CUFFT */ + +/* IEEE1394 capturing support */ +/* #undef HAVE_DC1394 */ + +/* IEEE1394 capturing support - libdc1394 v2.x */ +/* #undef HAVE_DC1394_2 */ + +/* DirectX */ +/* #undef HAVE_DIRECTX */ +/* #undef HAVE_DIRECTX_NV12 */ +/* #undef HAVE_D3D11 */ +/* #undef HAVE_D3D10 */ +/* #undef HAVE_D3D9 */ + +/* DirectShow Video Capture library */ +/* #undef HAVE_DSHOW */ + +/* Eigen Matrix & Linear Algebra Library */ +/* #undef HAVE_EIGEN */ + +/* FFMpeg video library */ +/* #undef HAVE_FFMPEG */ + +/* Geospatial Data Abstraction Library */ +/* #undef HAVE_GDAL */ + +/* GStreamer multimedia framework */ +/* #undef HAVE_GSTREAMER */ + +/* GTK+ 2.0 Thread support */ +/* #undef HAVE_GTHREAD */ + +/* GTK+ 2.x toolkit */ +/* #undef HAVE_GTK */ + +/* Define to 1 if you have the <inttypes.h> header file. */ +/* #undef HAVE_INTTYPES_H */ + +/* Intel Perceptual Computing SDK library */ +/* #undef HAVE_INTELPERC */ + +/* Intel Integrated Performance Primitives */ +/* #undef HAVE_IPP */ +/* #undef HAVE_IPP_ICV_ONLY */ + +/* Intel IPP Async */ +/* #undef HAVE_IPP_A */ + +/* JPEG-2000 codec */ +/* #undef HAVE_JASPER */ + +/* IJG JPEG codec */ +/* #undef HAVE_JPEG */ + +/* libpng/png.h needs to be included */ +/* #undef HAVE_LIBPNG_PNG_H */ + +/* GDCM DICOM codec */ +/* #undef HAVE_GDCM */ + +/* V4L/V4L2 capturing support via libv4l */ +/* #undef HAVE_LIBV4L */ + +/* Microsoft Media Foundation Capture library */ +/* #undef HAVE_MSMF */ + +/* NVidia Video Decoding API*/ +/* #undef HAVE_NVCUVID */ + +/* NVidia Video Encoding API*/ +/* #undef HAVE_NVCUVENC */ + +/* OpenCL Support */ +/* #undef HAVE_OPENCL */ +/* #undef HAVE_OPENCL_STATIC */ +/* #undef HAVE_OPENCL_SVM */ + +/* OpenEXR codec */ +/* #undef HAVE_OPENEXR */ + +/* OpenGL support*/ +/* #undef HAVE_OPENGL */ + +/* OpenNI library */ +/* #undef HAVE_OPENNI */ + +/* OpenNI library */ +/* #undef HAVE_OPENNI2 */ + +/* PNG codec */ +/* #undef HAVE_PNG */ + +/* Posix threads (pthreads) */ +#define HAVE_PTHREADS + +/* parallel_for with pthreads */ +/* #undef HAVE_PTHREADS_PF */ + +/* Qt support */ +/* #undef HAVE_QT */ + +/* Qt OpenGL support */ +/* #undef HAVE_QT_OPENGL */ + +/* QuickTime video libraries */ +/* #undef HAVE_QUICKTIME */ + +/* QTKit video libraries */ +/* #undef HAVE_QTKIT */ + +/* Intel Threading Building Blocks */ +/* #undef HAVE_TBB */ + +/* TIFF codec */ +/* #undef HAVE_TIFF */ + +/* Unicap video capture library */ +/* #undef HAVE_UNICAP */ + +/* Video for Windows support */ +/* #undef HAVE_VFW */ + +/* V4L2 capturing support in videoio.h */ +/* #undef HAVE_VIDEOIO */ + +/* Win32 UI */ +/* #undef HAVE_WIN32UI */ + +/* XIMEA camera support */ +/* #undef HAVE_XIMEA */ + +/* Xine video library */ +/* #undef HAVE_XINE */ + +/* Define if your processor stores words with the most significant byte + first (like Motorola and SPARC, unlike Intel and VAX). */ +/* #undef WORDS_BIGENDIAN */ + +/* gPhoto2 library */ +/* #undef HAVE_GPHOTO2 */ + +/* VA library (libva) */ +/* #undef HAVE_VA */ + +/* Intel VA-API/OpenCL */ +/* #undef HAVE_VA_INTEL */ + +/* Lapack */ +/* #undef HAVE_LAPACK */ + +/* FP16 */ +/* #undef HAVE_FP16 */ + +/* Library was compiled with functions instrumentation */ +/* #undef ENABLE_INSTRUMENTATION */ + +/* OpenVX */ +/* #undef HAVE_OPENVX */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/features2d.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,1365 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_FEATURES_2D_HPP
+#define OPENCV_FEATURES_2D_HPP
+
+#include "opencv2/core.hpp"
+#include "opencv2/flann/miniflann.hpp"
+
+/**
+ @defgroup features2d 2D Features Framework
+ @{
+ @defgroup features2d_main Feature Detection and Description
+ @defgroup features2d_match Descriptor Matchers
+
+Matchers of keypoint descriptors in OpenCV have wrappers with a common interface that enables you to
+easily switch between different algorithms solving the same problem. This section is devoted to
+matching descriptors that are represented as vectors in a multidimensional space. All objects that
+implement vector descriptor matchers inherit the DescriptorMatcher interface.
+
+@note
+ - An example explaining keypoint matching can be found at
+ opencv_source_code/samples/cpp/descriptor_extractor_matcher.cpp
+ - An example on descriptor matching evaluation can be found at
+ opencv_source_code/samples/cpp/detector_descriptor_matcher_evaluation.cpp
+ - An example on one to many image matching can be found at
+ opencv_source_code/samples/cpp/matching_to_many_images.cpp
+
+ @defgroup features2d_draw Drawing Function of Keypoints and Matches
+ @defgroup features2d_category Object Categorization
+
+This section describes approaches based on local 2D features and used to categorize objects.
+
+@note
+ - A complete Bag-Of-Words sample can be found at
+ opencv_source_code/samples/cpp/bagofwords_classification.cpp
+ - (Python) An example using the features2D framework to perform object categorization can be
+ found at opencv_source_code/samples/python/find_obj.py
+
+ @}
+ */
+
+namespace cv
+{
+
+//! @addtogroup features2d
+//! @{
+
+// //! writes vector of keypoints to the file storage
+// CV_EXPORTS void write(FileStorage& fs, const String& name, const std::vector<KeyPoint>& keypoints);
+// //! reads vector of keypoints from the specified file storage node
+// CV_EXPORTS void read(const FileNode& node, CV_OUT std::vector<KeyPoint>& keypoints);
+
+/** @brief A class filters a vector of keypoints.
+
+ Because now it is difficult to provide a convenient interface for all usage scenarios of the
+ keypoints filter class, it has only several needed by now static methods.
+ */
+class CV_EXPORTS KeyPointsFilter
+{
+public:
+ KeyPointsFilter(){}
+
+ /*
+ * Remove keypoints within borderPixels of an image edge.
+ */
+ static void runByImageBorder( std::vector<KeyPoint>& keypoints, Size imageSize, int borderSize );
+ /*
+ * Remove keypoints of sizes out of range.
+ */
+ static void runByKeypointSize( std::vector<KeyPoint>& keypoints, float minSize,
+ float maxSize=FLT_MAX );
+ /*
+ * Remove keypoints from some image by mask for pixels of this image.
+ */
+ static void runByPixelsMask( std::vector<KeyPoint>& keypoints, const Mat& mask );
+ /*
+ * Remove duplicated keypoints.
+ */
+ static void removeDuplicated( std::vector<KeyPoint>& keypoints );
+
+ /*
+ * Retain the specified number of the best keypoints (according to the response)
+ */
+ static void retainBest( std::vector<KeyPoint>& keypoints, int npoints );
+};
+
+
+/************************************ Base Classes ************************************/
+
+/** @brief Abstract base class for 2D image feature detectors and descriptor extractors
+*/
+class CV_EXPORTS_W Feature2D : public virtual Algorithm
+{
+public:
+ virtual ~Feature2D();
+
+ /** @brief Detects keypoints in an image (first variant) or image set (second variant).
+
+ @param image Image.
+ @param keypoints The detected keypoints. In the second variant of the method keypoints[i] is a set
+ of keypoints detected in images[i] .
+ @param mask Mask specifying where to look for keypoints (optional). It must be a 8-bit integer
+ matrix with non-zero values in the region of interest.
+ */
+ CV_WRAP virtual void detect( InputArray image,
+ CV_OUT std::vector<KeyPoint>& keypoints,
+ InputArray mask=noArray() );
+
+ /** @overload
+ @param images Image set.
+ @param keypoints The detected keypoints. In the second variant of the method keypoints[i] is a set
+ of keypoints detected in images[i] .
+ @param masks Masks for each input image specifying where to look for keypoints (optional).
+ masks[i] is a mask for images[i].
+ */
+ CV_WRAP virtual void detect( InputArrayOfArrays images,
+ CV_OUT std::vector<std::vector<KeyPoint> >& keypoints,
+ InputArrayOfArrays masks=noArray() );
+
+ /** @brief Computes the descriptors for a set of keypoints detected in an image (first variant) or image set
+ (second variant).
+
+ @param image Image.
+ @param keypoints Input collection of keypoints. Keypoints for which a descriptor cannot be
+ computed are removed. Sometimes new keypoints can be added, for example: SIFT duplicates keypoint
+ with several dominant orientations (for each orientation).
+ @param descriptors Computed descriptors. In the second variant of the method descriptors[i] are
+ descriptors computed for a keypoints[i]. Row j is the keypoints (or keypoints[i]) is the
+ descriptor for keypoint j-th keypoint.
+ */
+ CV_WRAP virtual void compute( InputArray image,
+ CV_OUT CV_IN_OUT std::vector<KeyPoint>& keypoints,
+ OutputArray descriptors );
+
+ /** @overload
+
+ @param images Image set.
+ @param keypoints Input collection of keypoints. Keypoints for which a descriptor cannot be
+ computed are removed. Sometimes new keypoints can be added, for example: SIFT duplicates keypoint
+ with several dominant orientations (for each orientation).
+ @param descriptors Computed descriptors. In the second variant of the method descriptors[i] are
+ descriptors computed for a keypoints[i]. Row j is the keypoints (or keypoints[i]) is the
+ descriptor for keypoint j-th keypoint.
+ */
+ CV_WRAP virtual void compute( InputArrayOfArrays images,
+ CV_OUT CV_IN_OUT std::vector<std::vector<KeyPoint> >& keypoints,
+ OutputArrayOfArrays descriptors );
+
+ /** Detects keypoints and computes the descriptors */
+ CV_WRAP virtual void detectAndCompute( InputArray image, InputArray mask,
+ CV_OUT std::vector<KeyPoint>& keypoints,
+ OutputArray descriptors,
+ bool useProvidedKeypoints=false );
+
+ CV_WRAP virtual int descriptorSize() const;
+ CV_WRAP virtual int descriptorType() const;
+ CV_WRAP virtual int defaultNorm() const;
+
+ CV_WRAP void write( const String& fileName ) const;
+
+ CV_WRAP void read( const String& fileName );
+
+ virtual void write( FileStorage&) const;
+
+ virtual void read( const FileNode&);
+
+ //! Return true if detector object is empty
+ CV_WRAP virtual bool empty() const;
+};
+
+/** Feature detectors in OpenCV have wrappers with a common interface that enables you to easily switch
+between different algorithms solving the same problem. All objects that implement keypoint detectors
+inherit the FeatureDetector interface. */
+typedef Feature2D FeatureDetector;
+
+/** Extractors of keypoint descriptors in OpenCV have wrappers with a common interface that enables you
+to easily switch between different algorithms solving the same problem. This section is devoted to
+computing descriptors represented as vectors in a multidimensional space. All objects that implement
+the vector descriptor extractors inherit the DescriptorExtractor interface.
+ */
+typedef Feature2D DescriptorExtractor;
+
+//! @addtogroup features2d_main
+//! @{
+
+/** @brief Class implementing the BRISK keypoint detector and descriptor extractor, described in @cite LCS11 .
+ */
+class CV_EXPORTS_W BRISK : public Feature2D
+{
+public:
+ /** @brief The BRISK constructor
+
+ @param thresh AGAST detection threshold score.
+ @param octaves detection octaves. Use 0 to do single scale.
+ @param patternScale apply this scale to the pattern used for sampling the neighbourhood of a
+ keypoint.
+ */
+ CV_WRAP static Ptr<BRISK> create(int thresh=30, int octaves=3, float patternScale=1.0f);
+
+ /** @brief The BRISK constructor for a custom pattern
+
+ @param radiusList defines the radii (in pixels) where the samples around a keypoint are taken (for
+ keypoint scale 1).
+ @param numberList defines the number of sampling points on the sampling circle. Must be the same
+ size as radiusList..
+ @param dMax threshold for the short pairings used for descriptor formation (in pixels for keypoint
+ scale 1).
+ @param dMin threshold for the long pairings used for orientation determination (in pixels for
+ keypoint scale 1).
+ @param indexChange index remapping of the bits. */
+ CV_WRAP static Ptr<BRISK> create(const std::vector<float> &radiusList, const std::vector<int> &numberList,
+ float dMax=5.85f, float dMin=8.2f, const std::vector<int>& indexChange=std::vector<int>());
+};
+
+/** @brief Class implementing the ORB (*oriented BRIEF*) keypoint detector and descriptor extractor
+
+described in @cite RRKB11 . The algorithm uses FAST in pyramids to detect stable keypoints, selects
+the strongest features using FAST or Harris response, finds their orientation using first-order
+moments and computes the descriptors using BRIEF (where the coordinates of random point pairs (or
+k-tuples) are rotated according to the measured orientation).
+ */
+class CV_EXPORTS_W ORB : public Feature2D
+{
+public:
+ enum { kBytes = 32, HARRIS_SCORE=0, FAST_SCORE=1 };
+
+ /** @brief The ORB constructor
+
+ @param nfeatures The maximum number of features to retain.
+ @param scaleFactor Pyramid decimation ratio, greater than 1. scaleFactor==2 means the classical
+ pyramid, where each next level has 4x less pixels than the previous, but such a big scale factor
+ will degrade feature matching scores dramatically. On the other hand, too close to 1 scale factor
+ will mean that to cover certain scale range you will need more pyramid levels and so the speed
+ will suffer.
+ @param nlevels The number of pyramid levels. The smallest level will have linear size equal to
+ input_image_linear_size/pow(scaleFactor, nlevels).
+ @param edgeThreshold This is size of the border where the features are not detected. It should
+ roughly match the patchSize parameter.
+ @param firstLevel It should be 0 in the current implementation.
+ @param WTA_K The number of points that produce each element of the oriented BRIEF descriptor. The
+ default value 2 means the BRIEF where we take a random point pair and compare their brightnesses,
+ so we get 0/1 response. Other possible values are 3 and 4. For example, 3 means that we take 3
+ random points (of course, those point coordinates are random, but they are generated from the
+ pre-defined seed, so each element of BRIEF descriptor is computed deterministically from the pixel
+ rectangle), find point of maximum brightness and output index of the winner (0, 1 or 2). Such
+ output will occupy 2 bits, and therefore it will need a special variant of Hamming distance,
+ denoted as NORM_HAMMING2 (2 bits per bin). When WTA_K=4, we take 4 random points to compute each
+ bin (that will also occupy 2 bits with possible values 0, 1, 2 or 3).
+ @param scoreType The default HARRIS_SCORE means that Harris algorithm is used to rank features
+ (the score is written to KeyPoint::score and is used to retain best nfeatures features);
+ FAST_SCORE is alternative value of the parameter that produces slightly less stable keypoints,
+ but it is a little faster to compute.
+ @param patchSize size of the patch used by the oriented BRIEF descriptor. Of course, on smaller
+ pyramid layers the perceived image area covered by a feature will be larger.
+ @param fastThreshold
+ */
+ CV_WRAP static Ptr<ORB> create(int nfeatures=500, float scaleFactor=1.2f, int nlevels=8, int edgeThreshold=31,
+ int firstLevel=0, int WTA_K=2, int scoreType=ORB::HARRIS_SCORE, int patchSize=31, int fastThreshold=20);
+
+ CV_WRAP virtual void setMaxFeatures(int maxFeatures) = 0;
+ CV_WRAP virtual int getMaxFeatures() const = 0;
+
+ CV_WRAP virtual void setScaleFactor(double scaleFactor) = 0;
+ CV_WRAP virtual double getScaleFactor() const = 0;
+
+ CV_WRAP virtual void setNLevels(int nlevels) = 0;
+ CV_WRAP virtual int getNLevels() const = 0;
+
+ CV_WRAP virtual void setEdgeThreshold(int edgeThreshold) = 0;
+ CV_WRAP virtual int getEdgeThreshold() const = 0;
+
+ CV_WRAP virtual void setFirstLevel(int firstLevel) = 0;
+ CV_WRAP virtual int getFirstLevel() const = 0;
+
+ CV_WRAP virtual void setWTA_K(int wta_k) = 0;
+ CV_WRAP virtual int getWTA_K() const = 0;
+
+ CV_WRAP virtual void setScoreType(int scoreType) = 0;
+ CV_WRAP virtual int getScoreType() const = 0;
+
+ CV_WRAP virtual void setPatchSize(int patchSize) = 0;
+ CV_WRAP virtual int getPatchSize() const = 0;
+
+ CV_WRAP virtual void setFastThreshold(int fastThreshold) = 0;
+ CV_WRAP virtual int getFastThreshold() const = 0;
+};
+
+/** @brief Maximally stable extremal region extractor
+
+The class encapsulates all the parameters of the %MSER extraction algorithm (see [wiki
+article](http://en.wikipedia.org/wiki/Maximally_stable_extremal_regions)).
+
+- there are two different implementation of %MSER: one for grey image, one for color image
+
+- the grey image algorithm is taken from: @cite nister2008linear ; the paper claims to be faster
+than union-find method; it actually get 1.5~2m/s on my centrino L7200 1.2GHz laptop.
+
+- the color image algorithm is taken from: @cite forssen2007maximally ; it should be much slower
+than grey image method ( 3~4 times ); the chi_table.h file is taken directly from paper's source
+code which is distributed under GPL.
+
+- (Python) A complete example showing the use of the %MSER detector can be found at samples/python/mser.py
+*/
+class CV_EXPORTS_W MSER : public Feature2D
+{
+public:
+ /** @brief Full consturctor for %MSER detector
+
+ @param _delta it compares \f$(size_{i}-size_{i-delta})/size_{i-delta}\f$
+ @param _min_area prune the area which smaller than minArea
+ @param _max_area prune the area which bigger than maxArea
+ @param _max_variation prune the area have simliar size to its children
+ @param _min_diversity for color image, trace back to cut off mser with diversity less than min_diversity
+ @param _max_evolution for color image, the evolution steps
+ @param _area_threshold for color image, the area threshold to cause re-initialize
+ @param _min_margin for color image, ignore too small margin
+ @param _edge_blur_size for color image, the aperture size for edge blur
+ */
+ CV_WRAP static Ptr<MSER> create( int _delta=5, int _min_area=60, int _max_area=14400,
+ double _max_variation=0.25, double _min_diversity=.2,
+ int _max_evolution=200, double _area_threshold=1.01,
+ double _min_margin=0.003, int _edge_blur_size=5 );
+
+ /** @brief Detect %MSER regions
+
+ @param image input image (8UC1, 8UC3 or 8UC4, must be greater or equal than 3x3)
+ @param msers resulting list of point sets
+ @param bboxes resulting bounding boxes
+ */
+ CV_WRAP virtual void detectRegions( InputArray image,
+ CV_OUT std::vector<std::vector<Point> >& msers,
+ CV_OUT std::vector<Rect>& bboxes ) = 0;
+
+ CV_WRAP virtual void setDelta(int delta) = 0;
+ CV_WRAP virtual int getDelta() const = 0;
+
+ CV_WRAP virtual void setMinArea(int minArea) = 0;
+ CV_WRAP virtual int getMinArea() const = 0;
+
+ CV_WRAP virtual void setMaxArea(int maxArea) = 0;
+ CV_WRAP virtual int getMaxArea() const = 0;
+
+ CV_WRAP virtual void setPass2Only(bool f) = 0;
+ CV_WRAP virtual bool getPass2Only() const = 0;
+};
+
+/** @overload */
+CV_EXPORTS void FAST( InputArray image, CV_OUT std::vector<KeyPoint>& keypoints,
+ int threshold, bool nonmaxSuppression=true );
+
+/** @brief Detects corners using the FAST algorithm
+
+@param image grayscale image where keypoints (corners) are detected.
+@param keypoints keypoints detected on the image.
+@param threshold threshold on difference between intensity of the central pixel and pixels of a
+circle around this pixel.
+@param nonmaxSuppression if true, non-maximum suppression is applied to detected corners
+(keypoints).
+@param type one of the three neighborhoods as defined in the paper:
+FastFeatureDetector::TYPE_9_16, FastFeatureDetector::TYPE_7_12,
+FastFeatureDetector::TYPE_5_8
+
+Detects corners using the FAST algorithm by @cite Rosten06 .
+
+@note In Python API, types are given as cv2.FAST_FEATURE_DETECTOR_TYPE_5_8,
+cv2.FAST_FEATURE_DETECTOR_TYPE_7_12 and cv2.FAST_FEATURE_DETECTOR_TYPE_9_16. For corner
+detection, use cv2.FAST.detect() method.
+ */
+CV_EXPORTS void FAST( InputArray image, CV_OUT std::vector<KeyPoint>& keypoints,
+ int threshold, bool nonmaxSuppression, int type );
+
+//! @} features2d_main
+
+//! @addtogroup features2d_main
+//! @{
+
+/** @brief Wrapping class for feature detection using the FAST method. :
+ */
+class CV_EXPORTS_W FastFeatureDetector : public Feature2D
+{
+public:
+ enum
+ {
+ TYPE_5_8 = 0, TYPE_7_12 = 1, TYPE_9_16 = 2,
+ THRESHOLD = 10000, NONMAX_SUPPRESSION=10001, FAST_N=10002,
+ };
+
+ CV_WRAP static Ptr<FastFeatureDetector> create( int threshold=10,
+ bool nonmaxSuppression=true,
+ int type=FastFeatureDetector::TYPE_9_16 );
+
+ CV_WRAP virtual void setThreshold(int threshold) = 0;
+ CV_WRAP virtual int getThreshold() const = 0;
+
+ CV_WRAP virtual void setNonmaxSuppression(bool f) = 0;
+ CV_WRAP virtual bool getNonmaxSuppression() const = 0;
+
+ CV_WRAP virtual void setType(int type) = 0;
+ CV_WRAP virtual int getType() const = 0;
+};
+
+/** @overload */
+CV_EXPORTS void AGAST( InputArray image, CV_OUT std::vector<KeyPoint>& keypoints,
+ int threshold, bool nonmaxSuppression=true );
+
+/** @brief Detects corners using the AGAST algorithm
+
+@param image grayscale image where keypoints (corners) are detected.
+@param keypoints keypoints detected on the image.
+@param threshold threshold on difference between intensity of the central pixel and pixels of a
+circle around this pixel.
+@param nonmaxSuppression if true, non-maximum suppression is applied to detected corners
+(keypoints).
+@param type one of the four neighborhoods as defined in the paper:
+AgastFeatureDetector::AGAST_5_8, AgastFeatureDetector::AGAST_7_12d,
+AgastFeatureDetector::AGAST_7_12s, AgastFeatureDetector::OAST_9_16
+
+For non-Intel platforms, there is a tree optimised variant of AGAST with same numerical results.
+The 32-bit binary tree tables were generated automatically from original code using perl script.
+The perl script and examples of tree generation are placed in features2d/doc folder.
+Detects corners using the AGAST algorithm by @cite mair2010_agast .
+
+ */
+CV_EXPORTS void AGAST( InputArray image, CV_OUT std::vector<KeyPoint>& keypoints,
+ int threshold, bool nonmaxSuppression, int type );
+//! @} features2d_main
+
+//! @addtogroup features2d_main
+//! @{
+
+/** @brief Wrapping class for feature detection using the AGAST method. :
+ */
+class CV_EXPORTS_W AgastFeatureDetector : public Feature2D
+{
+public:
+ enum
+ {
+ AGAST_5_8 = 0, AGAST_7_12d = 1, AGAST_7_12s = 2, OAST_9_16 = 3,
+ THRESHOLD = 10000, NONMAX_SUPPRESSION = 10001,
+ };
+
+ CV_WRAP static Ptr<AgastFeatureDetector> create( int threshold=10,
+ bool nonmaxSuppression=true,
+ int type=AgastFeatureDetector::OAST_9_16 );
+
+ CV_WRAP virtual void setThreshold(int threshold) = 0;
+ CV_WRAP virtual int getThreshold() const = 0;
+
+ CV_WRAP virtual void setNonmaxSuppression(bool f) = 0;
+ CV_WRAP virtual bool getNonmaxSuppression() const = 0;
+
+ CV_WRAP virtual void setType(int type) = 0;
+ CV_WRAP virtual int getType() const = 0;
+};
+
+/** @brief Wrapping class for feature detection using the goodFeaturesToTrack function. :
+ */
+class CV_EXPORTS_W GFTTDetector : public Feature2D
+{
+public:
+ CV_WRAP static Ptr<GFTTDetector> create( int maxCorners=1000, double qualityLevel=0.01, double minDistance=1,
+ int blockSize=3, bool useHarrisDetector=false, double k=0.04 );
+ CV_WRAP virtual void setMaxFeatures(int maxFeatures) = 0;
+ CV_WRAP virtual int getMaxFeatures() const = 0;
+
+ CV_WRAP virtual void setQualityLevel(double qlevel) = 0;
+ CV_WRAP virtual double getQualityLevel() const = 0;
+
+ CV_WRAP virtual void setMinDistance(double minDistance) = 0;
+ CV_WRAP virtual double getMinDistance() const = 0;
+
+ CV_WRAP virtual void setBlockSize(int blockSize) = 0;
+ CV_WRAP virtual int getBlockSize() const = 0;
+
+ CV_WRAP virtual void setHarrisDetector(bool val) = 0;
+ CV_WRAP virtual bool getHarrisDetector() const = 0;
+
+ CV_WRAP virtual void setK(double k) = 0;
+ CV_WRAP virtual double getK() const = 0;
+};
+
+/** @brief Class for extracting blobs from an image. :
+
+The class implements a simple algorithm for extracting blobs from an image:
+
+1. Convert the source image to binary images by applying thresholding with several thresholds from
+ minThreshold (inclusive) to maxThreshold (exclusive) with distance thresholdStep between
+ neighboring thresholds.
+2. Extract connected components from every binary image by findContours and calculate their
+ centers.
+3. Group centers from several binary images by their coordinates. Close centers form one group that
+ corresponds to one blob, which is controlled by the minDistBetweenBlobs parameter.
+4. From the groups, estimate final centers of blobs and their radiuses and return as locations and
+ sizes of keypoints.
+
+This class performs several filtrations of returned blobs. You should set filterBy\* to true/false
+to turn on/off corresponding filtration. Available filtrations:
+
+- **By color**. This filter compares the intensity of a binary image at the center of a blob to
+blobColor. If they differ, the blob is filtered out. Use blobColor = 0 to extract dark blobs
+and blobColor = 255 to extract light blobs.
+- **By area**. Extracted blobs have an area between minArea (inclusive) and maxArea (exclusive).
+- **By circularity**. Extracted blobs have circularity
+(\f$\frac{4*\pi*Area}{perimeter * perimeter}\f$) between minCircularity (inclusive) and
+maxCircularity (exclusive).
+- **By ratio of the minimum inertia to maximum inertia**. Extracted blobs have this ratio
+between minInertiaRatio (inclusive) and maxInertiaRatio (exclusive).
+- **By convexity**. Extracted blobs have convexity (area / area of blob convex hull) between
+minConvexity (inclusive) and maxConvexity (exclusive).
+
+Default values of parameters are tuned to extract dark circular blobs.
+ */
+class CV_EXPORTS_W SimpleBlobDetector : public Feature2D
+{
+public:
+ struct CV_EXPORTS_W_SIMPLE Params
+ {
+ CV_WRAP Params();
+ CV_PROP_RW float thresholdStep;
+ CV_PROP_RW float minThreshold;
+ CV_PROP_RW float maxThreshold;
+ CV_PROP_RW size_t minRepeatability;
+ CV_PROP_RW float minDistBetweenBlobs;
+
+ CV_PROP_RW bool filterByColor;
+ CV_PROP_RW uchar blobColor;
+
+ CV_PROP_RW bool filterByArea;
+ CV_PROP_RW float minArea, maxArea;
+
+ CV_PROP_RW bool filterByCircularity;
+ CV_PROP_RW float minCircularity, maxCircularity;
+
+ CV_PROP_RW bool filterByInertia;
+ CV_PROP_RW float minInertiaRatio, maxInertiaRatio;
+
+ CV_PROP_RW bool filterByConvexity;
+ CV_PROP_RW float minConvexity, maxConvexity;
+
+ void read( const FileNode& fn );
+ void write( FileStorage& fs ) const;
+ };
+
+ CV_WRAP static Ptr<SimpleBlobDetector>
+ create(const SimpleBlobDetector::Params ¶meters = SimpleBlobDetector::Params());
+};
+
+//! @} features2d_main
+
+//! @addtogroup features2d_main
+//! @{
+
+/** @brief Class implementing the KAZE keypoint detector and descriptor extractor, described in @cite ABD12 .
+
+@note AKAZE descriptor can only be used with KAZE or AKAZE keypoints .. [ABD12] KAZE Features. Pablo
+F. Alcantarilla, Adrien Bartoli and Andrew J. Davison. In European Conference on Computer Vision
+(ECCV), Fiorenze, Italy, October 2012.
+*/
+class CV_EXPORTS_W KAZE : public Feature2D
+{
+public:
+ enum
+ {
+ DIFF_PM_G1 = 0,
+ DIFF_PM_G2 = 1,
+ DIFF_WEICKERT = 2,
+ DIFF_CHARBONNIER = 3
+ };
+
+ /** @brief The KAZE constructor
+
+ @param extended Set to enable extraction of extended (128-byte) descriptor.
+ @param upright Set to enable use of upright descriptors (non rotation-invariant).
+ @param threshold Detector response threshold to accept point
+ @param nOctaves Maximum octave evolution of the image
+ @param nOctaveLayers Default number of sublevels per scale level
+ @param diffusivity Diffusivity type. DIFF_PM_G1, DIFF_PM_G2, DIFF_WEICKERT or
+ DIFF_CHARBONNIER
+ */
+ CV_WRAP static Ptr<KAZE> create(bool extended=false, bool upright=false,
+ float threshold = 0.001f,
+ int nOctaves = 4, int nOctaveLayers = 4,
+ int diffusivity = KAZE::DIFF_PM_G2);
+
+ CV_WRAP virtual void setExtended(bool extended) = 0;
+ CV_WRAP virtual bool getExtended() const = 0;
+
+ CV_WRAP virtual void setUpright(bool upright) = 0;
+ CV_WRAP virtual bool getUpright() const = 0;
+
+ CV_WRAP virtual void setThreshold(double threshold) = 0;
+ CV_WRAP virtual double getThreshold() const = 0;
+
+ CV_WRAP virtual void setNOctaves(int octaves) = 0;
+ CV_WRAP virtual int getNOctaves() const = 0;
+
+ CV_WRAP virtual void setNOctaveLayers(int octaveLayers) = 0;
+ CV_WRAP virtual int getNOctaveLayers() const = 0;
+
+ CV_WRAP virtual void setDiffusivity(int diff) = 0;
+ CV_WRAP virtual int getDiffusivity() const = 0;
+};
+
+/** @brief Class implementing the AKAZE keypoint detector and descriptor extractor, described in @cite ANB13 . :
+
+@note AKAZE descriptors can only be used with KAZE or AKAZE keypoints. Try to avoid using *extract*
+and *detect* instead of *operator()* due to performance reasons. .. [ANB13] Fast Explicit Diffusion
+for Accelerated Features in Nonlinear Scale Spaces. Pablo F. Alcantarilla, Jesús Nuevo and Adrien
+Bartoli. In British Machine Vision Conference (BMVC), Bristol, UK, September 2013.
+ */
+class CV_EXPORTS_W AKAZE : public Feature2D
+{
+public:
+ // AKAZE descriptor type
+ enum
+ {
+ DESCRIPTOR_KAZE_UPRIGHT = 2, ///< Upright descriptors, not invariant to rotation
+ DESCRIPTOR_KAZE = 3,
+ DESCRIPTOR_MLDB_UPRIGHT = 4, ///< Upright descriptors, not invariant to rotation
+ DESCRIPTOR_MLDB = 5
+ };
+
+ /** @brief The AKAZE constructor
+
+ @param descriptor_type Type of the extracted descriptor: DESCRIPTOR_KAZE,
+ DESCRIPTOR_KAZE_UPRIGHT, DESCRIPTOR_MLDB or DESCRIPTOR_MLDB_UPRIGHT.
+ @param descriptor_size Size of the descriptor in bits. 0 -\> Full size
+ @param descriptor_channels Number of channels in the descriptor (1, 2, 3)
+ @param threshold Detector response threshold to accept point
+ @param nOctaves Maximum octave evolution of the image
+ @param nOctaveLayers Default number of sublevels per scale level
+ @param diffusivity Diffusivity type. DIFF_PM_G1, DIFF_PM_G2, DIFF_WEICKERT or
+ DIFF_CHARBONNIER
+ */
+ CV_WRAP static Ptr<AKAZE> create(int descriptor_type=AKAZE::DESCRIPTOR_MLDB,
+ int descriptor_size = 0, int descriptor_channels = 3,
+ float threshold = 0.001f, int nOctaves = 4,
+ int nOctaveLayers = 4, int diffusivity = KAZE::DIFF_PM_G2);
+
+ CV_WRAP virtual void setDescriptorType(int dtype) = 0;
+ CV_WRAP virtual int getDescriptorType() const = 0;
+
+ CV_WRAP virtual void setDescriptorSize(int dsize) = 0;
+ CV_WRAP virtual int getDescriptorSize() const = 0;
+
+ CV_WRAP virtual void setDescriptorChannels(int dch) = 0;
+ CV_WRAP virtual int getDescriptorChannels() const = 0;
+
+ CV_WRAP virtual void setThreshold(double threshold) = 0;
+ CV_WRAP virtual double getThreshold() const = 0;
+
+ CV_WRAP virtual void setNOctaves(int octaves) = 0;
+ CV_WRAP virtual int getNOctaves() const = 0;
+
+ CV_WRAP virtual void setNOctaveLayers(int octaveLayers) = 0;
+ CV_WRAP virtual int getNOctaveLayers() const = 0;
+
+ CV_WRAP virtual void setDiffusivity(int diff) = 0;
+ CV_WRAP virtual int getDiffusivity() const = 0;
+};
+
+//! @} features2d_main
+
+/****************************************************************************************\
+* Distance *
+\****************************************************************************************/
+
+template<typename T>
+struct CV_EXPORTS Accumulator
+{
+ typedef T Type;
+};
+
+template<> struct Accumulator<unsigned char> { typedef float Type; };
+template<> struct Accumulator<unsigned short> { typedef float Type; };
+template<> struct Accumulator<char> { typedef float Type; };
+template<> struct Accumulator<short> { typedef float Type; };
+
+/*
+ * Squared Euclidean distance functor
+ */
+template<class T>
+struct CV_EXPORTS SL2
+{
+ enum { normType = NORM_L2SQR };
+ typedef T ValueType;
+ typedef typename Accumulator<T>::Type ResultType;
+
+ ResultType operator()( const T* a, const T* b, int size ) const
+ {
+ return normL2Sqr<ValueType, ResultType>(a, b, size);
+ }
+};
+
+/*
+ * Euclidean distance functor
+ */
+template<class T>
+struct CV_EXPORTS L2
+{
+ enum { normType = NORM_L2 };
+ typedef T ValueType;
+ typedef typename Accumulator<T>::Type ResultType;
+
+ ResultType operator()( const T* a, const T* b, int size ) const
+ {
+ return (ResultType)std::sqrt((double)normL2Sqr<ValueType, ResultType>(a, b, size));
+ }
+};
+
+/*
+ * Manhattan distance (city block distance) functor
+ */
+template<class T>
+struct CV_EXPORTS L1
+{
+ enum { normType = NORM_L1 };
+ typedef T ValueType;
+ typedef typename Accumulator<T>::Type ResultType;
+
+ ResultType operator()( const T* a, const T* b, int size ) const
+ {
+ return normL1<ValueType, ResultType>(a, b, size);
+ }
+};
+
+/****************************************************************************************\
+* DescriptorMatcher *
+\****************************************************************************************/
+
+//! @addtogroup features2d_match
+//! @{
+
+/** @brief Abstract base class for matching keypoint descriptors.
+
+It has two groups of match methods: for matching descriptors of an image with another image or with
+an image set.
+ */
+class CV_EXPORTS_W DescriptorMatcher : public Algorithm
+{
+public:
+ enum
+ {
+ FLANNBASED = 1,
+ BRUTEFORCE = 2,
+ BRUTEFORCE_L1 = 3,
+ BRUTEFORCE_HAMMING = 4,
+ BRUTEFORCE_HAMMINGLUT = 5,
+ BRUTEFORCE_SL2 = 6
+ };
+ virtual ~DescriptorMatcher();
+
+ /** @brief Adds descriptors to train a CPU(trainDescCollectionis) or GPU(utrainDescCollectionis) descriptor
+ collection.
+
+ If the collection is not empty, the new descriptors are added to existing train descriptors.
+
+ @param descriptors Descriptors to add. Each descriptors[i] is a set of descriptors from the same
+ train image.
+ */
+ CV_WRAP virtual void add( InputArrayOfArrays descriptors );
+
+ /** @brief Returns a constant link to the train descriptor collection trainDescCollection .
+ */
+ CV_WRAP const std::vector<Mat>& getTrainDescriptors() const;
+
+ /** @brief Clears the train descriptor collections.
+ */
+ CV_WRAP virtual void clear();
+
+ /** @brief Returns true if there are no train descriptors in the both collections.
+ */
+ CV_WRAP virtual bool empty() const;
+
+ /** @brief Returns true if the descriptor matcher supports masking permissible matches.
+ */
+ CV_WRAP virtual bool isMaskSupported() const = 0;
+
+ /** @brief Trains a descriptor matcher
+
+ Trains a descriptor matcher (for example, the flann index). In all methods to match, the method
+ train() is run every time before matching. Some descriptor matchers (for example, BruteForceMatcher)
+ have an empty implementation of this method. Other matchers really train their inner structures (for
+ example, FlannBasedMatcher trains flann::Index ).
+ */
+ CV_WRAP virtual void train();
+
+ /** @brief Finds the best match for each descriptor from a query set.
+
+ @param queryDescriptors Query set of descriptors.
+ @param trainDescriptors Train set of descriptors. This set is not added to the train descriptors
+ collection stored in the class object.
+ @param matches Matches. If a query descriptor is masked out in mask , no match is added for this
+ descriptor. So, matches size may be smaller than the query descriptors count.
+ @param mask Mask specifying permissible matches between an input query and train matrices of
+ descriptors.
+
+ In the first variant of this method, the train descriptors are passed as an input argument. In the
+ second variant of the method, train descriptors collection that was set by DescriptorMatcher::add is
+ used. Optional mask (or masks) can be passed to specify which query and training descriptors can be
+ matched. Namely, queryDescriptors[i] can be matched with trainDescriptors[j] only if
+ mask.at\<uchar\>(i,j) is non-zero.
+ */
+ CV_WRAP void match( InputArray queryDescriptors, InputArray trainDescriptors,
+ CV_OUT std::vector<DMatch>& matches, InputArray mask=noArray() ) const;
+
+ /** @brief Finds the k best matches for each descriptor from a query set.
+
+ @param queryDescriptors Query set of descriptors.
+ @param trainDescriptors Train set of descriptors. This set is not added to the train descriptors
+ collection stored in the class object.
+ @param mask Mask specifying permissible matches between an input query and train matrices of
+ descriptors.
+ @param matches Matches. Each matches[i] is k or less matches for the same query descriptor.
+ @param k Count of best matches found per each query descriptor or less if a query descriptor has
+ less than k possible matches in total.
+ @param compactResult Parameter used when the mask (or masks) is not empty. If compactResult is
+ false, the matches vector has the same size as queryDescriptors rows. If compactResult is true,
+ the matches vector does not contain matches for fully masked-out query descriptors.
+
+ These extended variants of DescriptorMatcher::match methods find several best matches for each query
+ descriptor. The matches are returned in the distance increasing order. See DescriptorMatcher::match
+ for the details about query and train descriptors.
+ */
+ CV_WRAP void knnMatch( InputArray queryDescriptors, InputArray trainDescriptors,
+ CV_OUT std::vector<std::vector<DMatch> >& matches, int k,
+ InputArray mask=noArray(), bool compactResult=false ) const;
+
+ /** @brief For each query descriptor, finds the training descriptors not farther than the specified distance.
+
+ @param queryDescriptors Query set of descriptors.
+ @param trainDescriptors Train set of descriptors. This set is not added to the train descriptors
+ collection stored in the class object.
+ @param matches Found matches.
+ @param compactResult Parameter used when the mask (or masks) is not empty. If compactResult is
+ false, the matches vector has the same size as queryDescriptors rows. If compactResult is true,
+ the matches vector does not contain matches for fully masked-out query descriptors.
+ @param maxDistance Threshold for the distance between matched descriptors. Distance means here
+ metric distance (e.g. Hamming distance), not the distance between coordinates (which is measured
+ in Pixels)!
+ @param mask Mask specifying permissible matches between an input query and train matrices of
+ descriptors.
+
+ For each query descriptor, the methods find such training descriptors that the distance between the
+ query descriptor and the training descriptor is equal or smaller than maxDistance. Found matches are
+ returned in the distance increasing order.
+ */
+ CV_WRAP void radiusMatch( InputArray queryDescriptors, InputArray trainDescriptors,
+ CV_OUT std::vector<std::vector<DMatch> >& matches, float maxDistance,
+ InputArray mask=noArray(), bool compactResult=false ) const;
+
+ /** @overload
+ @param queryDescriptors Query set of descriptors.
+ @param matches Matches. If a query descriptor is masked out in mask , no match is added for this
+ descriptor. So, matches size may be smaller than the query descriptors count.
+ @param masks Set of masks. Each masks[i] specifies permissible matches between the input query
+ descriptors and stored train descriptors from the i-th image trainDescCollection[i].
+ */
+ CV_WRAP void match( InputArray queryDescriptors, CV_OUT std::vector<DMatch>& matches,
+ InputArrayOfArrays masks=noArray() );
+ /** @overload
+ @param queryDescriptors Query set of descriptors.
+ @param matches Matches. Each matches[i] is k or less matches for the same query descriptor.
+ @param k Count of best matches found per each query descriptor or less if a query descriptor has
+ less than k possible matches in total.
+ @param masks Set of masks. Each masks[i] specifies permissible matches between the input query
+ descriptors and stored train descriptors from the i-th image trainDescCollection[i].
+ @param compactResult Parameter used when the mask (or masks) is not empty. If compactResult is
+ false, the matches vector has the same size as queryDescriptors rows. If compactResult is true,
+ the matches vector does not contain matches for fully masked-out query descriptors.
+ */
+ CV_WRAP void knnMatch( InputArray queryDescriptors, CV_OUT std::vector<std::vector<DMatch> >& matches, int k,
+ InputArrayOfArrays masks=noArray(), bool compactResult=false );
+ /** @overload
+ @param queryDescriptors Query set of descriptors.
+ @param matches Found matches.
+ @param maxDistance Threshold for the distance between matched descriptors. Distance means here
+ metric distance (e.g. Hamming distance), not the distance between coordinates (which is measured
+ in Pixels)!
+ @param masks Set of masks. Each masks[i] specifies permissible matches between the input query
+ descriptors and stored train descriptors from the i-th image trainDescCollection[i].
+ @param compactResult Parameter used when the mask (or masks) is not empty. If compactResult is
+ false, the matches vector has the same size as queryDescriptors rows. If compactResult is true,
+ the matches vector does not contain matches for fully masked-out query descriptors.
+ */
+ CV_WRAP void radiusMatch( InputArray queryDescriptors, CV_OUT std::vector<std::vector<DMatch> >& matches, float maxDistance,
+ InputArrayOfArrays masks=noArray(), bool compactResult=false );
+
+
+ CV_WRAP void write( const String& fileName ) const
+ {
+ FileStorage fs(fileName, FileStorage::WRITE);
+ write(fs);
+ }
+
+ CV_WRAP void read( const String& fileName )
+ {
+ FileStorage fs(fileName, FileStorage::READ);
+ read(fs.root());
+ }
+ // Reads matcher object from a file node
+ virtual void read( const FileNode& );
+ // Writes matcher object to a file storage
+ virtual void write( FileStorage& ) const;
+
+ /** @brief Clones the matcher.
+
+ @param emptyTrainData If emptyTrainData is false, the method creates a deep copy of the object,
+ that is, copies both parameters and train data. If emptyTrainData is true, the method creates an
+ object copy with the current parameters but with empty train data.
+ */
+ CV_WRAP virtual Ptr<DescriptorMatcher> clone( bool emptyTrainData=false ) const = 0;
+
+ /** @brief Creates a descriptor matcher of a given type with the default parameters (using default
+ constructor).
+
+ @param descriptorMatcherType Descriptor matcher type. Now the following matcher types are
+ supported:
+ - `BruteForce` (it uses L2 )
+ - `BruteForce-L1`
+ - `BruteForce-Hamming`
+ - `BruteForce-Hamming(2)`
+ - `FlannBased`
+ */
+ CV_WRAP static Ptr<DescriptorMatcher> create( const String& descriptorMatcherType );
+
+ CV_WRAP static Ptr<DescriptorMatcher> create( int matcherType );
+
+protected:
+ /**
+ * Class to work with descriptors from several images as with one merged matrix.
+ * It is used e.g. in FlannBasedMatcher.
+ */
+ class CV_EXPORTS DescriptorCollection
+ {
+ public:
+ DescriptorCollection();
+ DescriptorCollection( const DescriptorCollection& collection );
+ virtual ~DescriptorCollection();
+
+ // Vector of matrices "descriptors" will be merged to one matrix "mergedDescriptors" here.
+ void set( const std::vector<Mat>& descriptors );
+ virtual void clear();
+
+ const Mat& getDescriptors() const;
+ const Mat getDescriptor( int imgIdx, int localDescIdx ) const;
+ const Mat getDescriptor( int globalDescIdx ) const;
+ void getLocalIdx( int globalDescIdx, int& imgIdx, int& localDescIdx ) const;
+
+ int size() const;
+
+ protected:
+ Mat mergedDescriptors;
+ std::vector<int> startIdxs;
+ };
+
+ //! In fact the matching is implemented only by the following two methods. These methods suppose
+ //! that the class object has been trained already. Public match methods call these methods
+ //! after calling train().
+ virtual void knnMatchImpl( InputArray queryDescriptors, std::vector<std::vector<DMatch> >& matches, int k,
+ InputArrayOfArrays masks=noArray(), bool compactResult=false ) = 0;
+ virtual void radiusMatchImpl( InputArray queryDescriptors, std::vector<std::vector<DMatch> >& matches, float maxDistance,
+ InputArrayOfArrays masks=noArray(), bool compactResult=false ) = 0;
+
+ static bool isPossibleMatch( InputArray mask, int queryIdx, int trainIdx );
+ static bool isMaskedOut( InputArrayOfArrays masks, int queryIdx );
+
+ static Mat clone_op( Mat m ) { return m.clone(); }
+ void checkMasks( InputArrayOfArrays masks, int queryDescriptorsCount ) const;
+
+ //! Collection of descriptors from train images.
+ std::vector<Mat> trainDescCollection;
+ std::vector<UMat> utrainDescCollection;
+};
+
+/** @brief Brute-force descriptor matcher.
+
+For each descriptor in the first set, this matcher finds the closest descriptor in the second set
+by trying each one. This descriptor matcher supports masking permissible matches of descriptor
+sets.
+ */
+class CV_EXPORTS_W BFMatcher : public DescriptorMatcher
+{
+public:
+ /** @brief Brute-force matcher constructor (obsolete). Please use BFMatcher.create()
+ *
+ *
+ */
+ CV_WRAP BFMatcher( int normType=NORM_L2, bool crossCheck=false );
+
+ virtual ~BFMatcher() {}
+
+ virtual bool isMaskSupported() const { return true; }
+
+ /* @brief Brute-force matcher create method.
+ @param normType One of NORM_L1, NORM_L2, NORM_HAMMING, NORM_HAMMING2. L1 and L2 norms are
+ preferable choices for SIFT and SURF descriptors, NORM_HAMMING should be used with ORB, BRISK and
+ BRIEF, NORM_HAMMING2 should be used with ORB when WTA_K==3 or 4 (see ORB::ORB constructor
+ description).
+ @param crossCheck If it is false, this is will be default BFMatcher behaviour when it finds the k
+ nearest neighbors for each query descriptor. If crossCheck==true, then the knnMatch() method with
+ k=1 will only return pairs (i,j) such that for i-th query descriptor the j-th descriptor in the
+ matcher's collection is the nearest and vice versa, i.e. the BFMatcher will only return consistent
+ pairs. Such technique usually produces best results with minimal number of outliers when there are
+ enough matches. This is alternative to the ratio test, used by D. Lowe in SIFT paper.
+ */
+ CV_WRAP static Ptr<BFMatcher> create( int normType=NORM_L2, bool crossCheck=false ) ;
+
+ virtual Ptr<DescriptorMatcher> clone( bool emptyTrainData=false ) const;
+protected:
+ virtual void knnMatchImpl( InputArray queryDescriptors, std::vector<std::vector<DMatch> >& matches, int k,
+ InputArrayOfArrays masks=noArray(), bool compactResult=false );
+ virtual void radiusMatchImpl( InputArray queryDescriptors, std::vector<std::vector<DMatch> >& matches, float maxDistance,
+ InputArrayOfArrays masks=noArray(), bool compactResult=false );
+
+ int normType;
+ bool crossCheck;
+};
+
+
+/** @brief Flann-based descriptor matcher.
+
+This matcher trains cv::flann::Index on a train descriptor collection and calls its nearest search
+methods to find the best matches. So, this matcher may be faster when matching a large train
+collection than the brute force matcher. FlannBasedMatcher does not support masking permissible
+matches of descriptor sets because flann::Index does not support this. :
+ */
+class CV_EXPORTS_W FlannBasedMatcher : public DescriptorMatcher
+{
+public:
+ CV_WRAP FlannBasedMatcher( const Ptr<flann::IndexParams>& indexParams=makePtr<flann::KDTreeIndexParams>(),
+ const Ptr<flann::SearchParams>& searchParams=makePtr<flann::SearchParams>() );
+
+ virtual void add( InputArrayOfArrays descriptors );
+ virtual void clear();
+
+ // Reads matcher object from a file node
+ virtual void read( const FileNode& );
+ // Writes matcher object to a file storage
+ virtual void write( FileStorage& ) const;
+
+ virtual void train();
+ virtual bool isMaskSupported() const;
+
+ CV_WRAP static Ptr<FlannBasedMatcher> create();
+
+ virtual Ptr<DescriptorMatcher> clone( bool emptyTrainData=false ) const;
+protected:
+ static void convertToDMatches( const DescriptorCollection& descriptors,
+ const Mat& indices, const Mat& distances,
+ std::vector<std::vector<DMatch> >& matches );
+
+ virtual void knnMatchImpl( InputArray queryDescriptors, std::vector<std::vector<DMatch> >& matches, int k,
+ InputArrayOfArrays masks=noArray(), bool compactResult=false );
+ virtual void radiusMatchImpl( InputArray queryDescriptors, std::vector<std::vector<DMatch> >& matches, float maxDistance,
+ InputArrayOfArrays masks=noArray(), bool compactResult=false );
+
+ Ptr<flann::IndexParams> indexParams;
+ Ptr<flann::SearchParams> searchParams;
+ Ptr<flann::Index> flannIndex;
+
+ DescriptorCollection mergedDescriptors;
+ int addedDescCount;
+};
+
+//! @} features2d_match
+
+/****************************************************************************************\
+* Drawing functions *
+\****************************************************************************************/
+
+//! @addtogroup features2d_draw
+//! @{
+
+struct CV_EXPORTS DrawMatchesFlags
+{
+ enum{ DEFAULT = 0, //!< Output image matrix will be created (Mat::create),
+ //!< i.e. existing memory of output image may be reused.
+ //!< Two source image, matches and single keypoints will be drawn.
+ //!< For each keypoint only the center point will be drawn (without
+ //!< the circle around keypoint with keypoint size and orientation).
+ DRAW_OVER_OUTIMG = 1, //!< Output image matrix will not be created (Mat::create).
+ //!< Matches will be drawn on existing content of output image.
+ NOT_DRAW_SINGLE_POINTS = 2, //!< Single keypoints will not be drawn.
+ DRAW_RICH_KEYPOINTS = 4 //!< For each keypoint the circle around keypoint with keypoint size and
+ //!< orientation will be drawn.
+ };
+};
+
+/** @brief Draws keypoints.
+
+@param image Source image.
+@param keypoints Keypoints from the source image.
+@param outImage Output image. Its content depends on the flags value defining what is drawn in the
+output image. See possible flags bit values below.
+@param color Color of keypoints.
+@param flags Flags setting drawing features. Possible flags bit values are defined by
+DrawMatchesFlags. See details above in drawMatches .
+
+@note
+For Python API, flags are modified as cv2.DRAW_MATCHES_FLAGS_DEFAULT,
+cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS, cv2.DRAW_MATCHES_FLAGS_DRAW_OVER_OUTIMG,
+cv2.DRAW_MATCHES_FLAGS_NOT_DRAW_SINGLE_POINTS
+ */
+CV_EXPORTS_W void drawKeypoints( InputArray image, const std::vector<KeyPoint>& keypoints, InputOutputArray outImage,
+ const Scalar& color=Scalar::all(-1), int flags=DrawMatchesFlags::DEFAULT );
+
+/** @brief Draws the found matches of keypoints from two images.
+
+@param img1 First source image.
+@param keypoints1 Keypoints from the first source image.
+@param img2 Second source image.
+@param keypoints2 Keypoints from the second source image.
+@param matches1to2 Matches from the first image to the second one, which means that keypoints1[i]
+has a corresponding point in keypoints2[matches[i]] .
+@param outImg Output image. Its content depends on the flags value defining what is drawn in the
+output image. See possible flags bit values below.
+@param matchColor Color of matches (lines and connected keypoints). If matchColor==Scalar::all(-1)
+, the color is generated randomly.
+@param singlePointColor Color of single keypoints (circles), which means that keypoints do not
+have the matches. If singlePointColor==Scalar::all(-1) , the color is generated randomly.
+@param matchesMask Mask determining which matches are drawn. If the mask is empty, all matches are
+drawn.
+@param flags Flags setting drawing features. Possible flags bit values are defined by
+DrawMatchesFlags.
+
+This function draws matches of keypoints from two images in the output image. Match is a line
+connecting two keypoints (circles). See cv::DrawMatchesFlags.
+ */
+CV_EXPORTS_W void drawMatches( InputArray img1, const std::vector<KeyPoint>& keypoints1,
+ InputArray img2, const std::vector<KeyPoint>& keypoints2,
+ const std::vector<DMatch>& matches1to2, InputOutputArray outImg,
+ const Scalar& matchColor=Scalar::all(-1), const Scalar& singlePointColor=Scalar::all(-1),
+ const std::vector<char>& matchesMask=std::vector<char>(), int flags=DrawMatchesFlags::DEFAULT );
+
+/** @overload */
+CV_EXPORTS_AS(drawMatchesKnn) void drawMatches( InputArray img1, const std::vector<KeyPoint>& keypoints1,
+ InputArray img2, const std::vector<KeyPoint>& keypoints2,
+ const std::vector<std::vector<DMatch> >& matches1to2, InputOutputArray outImg,
+ const Scalar& matchColor=Scalar::all(-1), const Scalar& singlePointColor=Scalar::all(-1),
+ const std::vector<std::vector<char> >& matchesMask=std::vector<std::vector<char> >(), int flags=DrawMatchesFlags::DEFAULT );
+
+//! @} features2d_draw
+
+/****************************************************************************************\
+* Functions to evaluate the feature detectors and [generic] descriptor extractors *
+\****************************************************************************************/
+
+CV_EXPORTS void evaluateFeatureDetector( const Mat& img1, const Mat& img2, const Mat& H1to2,
+ std::vector<KeyPoint>* keypoints1, std::vector<KeyPoint>* keypoints2,
+ float& repeatability, int& correspCount,
+ const Ptr<FeatureDetector>& fdetector=Ptr<FeatureDetector>() );
+
+CV_EXPORTS void computeRecallPrecisionCurve( const std::vector<std::vector<DMatch> >& matches1to2,
+ const std::vector<std::vector<uchar> >& correctMatches1to2Mask,
+ std::vector<Point2f>& recallPrecisionCurve );
+
+CV_EXPORTS float getRecall( const std::vector<Point2f>& recallPrecisionCurve, float l_precision );
+CV_EXPORTS int getNearestPoint( const std::vector<Point2f>& recallPrecisionCurve, float l_precision );
+
+/****************************************************************************************\
+* Bag of visual words *
+\****************************************************************************************/
+
+//! @addtogroup features2d_category
+//! @{
+
+/** @brief Abstract base class for training the *bag of visual words* vocabulary from a set of descriptors.
+
+For details, see, for example, *Visual Categorization with Bags of Keypoints* by Gabriella Csurka,
+Christopher R. Dance, Lixin Fan, Jutta Willamowski, Cedric Bray, 2004. :
+ */
+class CV_EXPORTS_W BOWTrainer
+{
+public:
+ BOWTrainer();
+ virtual ~BOWTrainer();
+
+ /** @brief Adds descriptors to a training set.
+
+ @param descriptors Descriptors to add to a training set. Each row of the descriptors matrix is a
+ descriptor.
+
+ The training set is clustered using clustermethod to construct the vocabulary.
+ */
+ CV_WRAP void add( const Mat& descriptors );
+
+ /** @brief Returns a training set of descriptors.
+ */
+ CV_WRAP const std::vector<Mat>& getDescriptors() const;
+
+ /** @brief Returns the count of all descriptors stored in the training set.
+ */
+ CV_WRAP int descriptorsCount() const;
+
+ CV_WRAP virtual void clear();
+
+ /** @overload */
+ CV_WRAP virtual Mat cluster() const = 0;
+
+ /** @brief Clusters train descriptors.
+
+ @param descriptors Descriptors to cluster. Each row of the descriptors matrix is a descriptor.
+ Descriptors are not added to the inner train descriptor set.
+
+ The vocabulary consists of cluster centers. So, this method returns the vocabulary. In the first
+ variant of the method, train descriptors stored in the object are clustered. In the second variant,
+ input descriptors are clustered.
+ */
+ CV_WRAP virtual Mat cluster( const Mat& descriptors ) const = 0;
+
+protected:
+ std::vector<Mat> descriptors;
+ int size;
+};
+
+/** @brief kmeans -based class to train visual vocabulary using the *bag of visual words* approach. :
+ */
+class CV_EXPORTS_W BOWKMeansTrainer : public BOWTrainer
+{
+public:
+ /** @brief The constructor.
+
+ @see cv::kmeans
+ */
+ CV_WRAP BOWKMeansTrainer( int clusterCount, const TermCriteria& termcrit=TermCriteria(),
+ int attempts=3, int flags=KMEANS_PP_CENTERS );
+ virtual ~BOWKMeansTrainer();
+
+ // Returns trained vocabulary (i.e. cluster centers).
+ CV_WRAP virtual Mat cluster() const;
+ CV_WRAP virtual Mat cluster( const Mat& descriptors ) const;
+
+protected:
+
+ int clusterCount;
+ TermCriteria termcrit;
+ int attempts;
+ int flags;
+};
+
+/** @brief Class to compute an image descriptor using the *bag of visual words*.
+
+Such a computation consists of the following steps:
+
+1. Compute descriptors for a given image and its keypoints set.
+2. Find the nearest visual words from the vocabulary for each keypoint descriptor.
+3. Compute the bag-of-words image descriptor as is a normalized histogram of vocabulary words
+encountered in the image. The i-th bin of the histogram is a frequency of i-th word of the
+vocabulary in the given image.
+ */
+class CV_EXPORTS_W BOWImgDescriptorExtractor
+{
+public:
+ /** @brief The constructor.
+
+ @param dextractor Descriptor extractor that is used to compute descriptors for an input image and
+ its keypoints.
+ @param dmatcher Descriptor matcher that is used to find the nearest word of the trained vocabulary
+ for each keypoint descriptor of the image.
+ */
+ CV_WRAP BOWImgDescriptorExtractor( const Ptr<DescriptorExtractor>& dextractor,
+ const Ptr<DescriptorMatcher>& dmatcher );
+ /** @overload */
+ BOWImgDescriptorExtractor( const Ptr<DescriptorMatcher>& dmatcher );
+ virtual ~BOWImgDescriptorExtractor();
+
+ /** @brief Sets a visual vocabulary.
+
+ @param vocabulary Vocabulary (can be trained using the inheritor of BOWTrainer ). Each row of the
+ vocabulary is a visual word (cluster center).
+ */
+ CV_WRAP void setVocabulary( const Mat& vocabulary );
+
+ /** @brief Returns the set vocabulary.
+ */
+ CV_WRAP const Mat& getVocabulary() const;
+
+ /** @brief Computes an image descriptor using the set visual vocabulary.
+
+ @param image Image, for which the descriptor is computed.
+ @param keypoints Keypoints detected in the input image.
+ @param imgDescriptor Computed output image descriptor.
+ @param pointIdxsOfClusters Indices of keypoints that belong to the cluster. This means that
+ pointIdxsOfClusters[i] are keypoint indices that belong to the i -th cluster (word of vocabulary)
+ returned if it is non-zero.
+ @param descriptors Descriptors of the image keypoints that are returned if they are non-zero.
+ */
+ void compute( InputArray image, std::vector<KeyPoint>& keypoints, OutputArray imgDescriptor,
+ std::vector<std::vector<int> >* pointIdxsOfClusters=0, Mat* descriptors=0 );
+ /** @overload
+ @param keypointDescriptors Computed descriptors to match with vocabulary.
+ @param imgDescriptor Computed output image descriptor.
+ @param pointIdxsOfClusters Indices of keypoints that belong to the cluster. This means that
+ pointIdxsOfClusters[i] are keypoint indices that belong to the i -th cluster (word of vocabulary)
+ returned if it is non-zero.
+ */
+ void compute( InputArray keypointDescriptors, OutputArray imgDescriptor,
+ std::vector<std::vector<int> >* pointIdxsOfClusters=0 );
+ // compute() is not constant because DescriptorMatcher::match is not constant
+
+ CV_WRAP_AS(compute) void compute2( const Mat& image, std::vector<KeyPoint>& keypoints, CV_OUT Mat& imgDescriptor )
+ { compute(image,keypoints,imgDescriptor); }
+
+ /** @brief Returns an image descriptor size if the vocabulary is set. Otherwise, it returns 0.
+ */
+ CV_WRAP int descriptorSize() const;
+
+ /** @brief Returns an image descriptor type.
+ */
+ CV_WRAP int descriptorType() const;
+
+protected:
+ Mat vocabulary;
+ Ptr<DescriptorExtractor> dextractor;
+ Ptr<DescriptorMatcher> dmatcher;
+};
+
+//! @} features2d_category
+
+//! @} features2d
+
+} /* namespace cv */
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/opencv2/features2d/features2d.hpp Fri Jan 29 04:53:38 2021 +0000 @@ -0,0 +1,48 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifdef __OPENCV_BUILD +#error this is a compatibility header which should not be used inside the OpenCV library +#endif + +#include "opencv2/features2d.hpp"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/flann.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,531 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_FLANN_HPP
+#define OPENCV_FLANN_HPP
+
+#include "opencv2/core.hpp"
+#include "opencv2/flann/miniflann.hpp"
+#include "opencv2/flann/flann_base.hpp"
+
+/**
+@defgroup flann Clustering and Search in Multi-Dimensional Spaces
+
+This section documents OpenCV's interface to the FLANN library. FLANN (Fast Library for Approximate
+Nearest Neighbors) is a library that contains a collection of algorithms optimized for fast nearest
+neighbor search in large datasets and for high dimensional features. More information about FLANN
+can be found in @cite Muja2009 .
+*/
+
+namespace cvflann
+{
+ CV_EXPORTS flann_distance_t flann_distance_type();
+ FLANN_DEPRECATED CV_EXPORTS void set_distance_type(flann_distance_t distance_type, int order);
+}
+
+
+namespace cv
+{
+namespace flann
+{
+
+
+//! @addtogroup flann
+//! @{
+
+template <typename T> struct CvType {};
+template <> struct CvType<unsigned char> { static int type() { return CV_8U; } };
+template <> struct CvType<char> { static int type() { return CV_8S; } };
+template <> struct CvType<unsigned short> { static int type() { return CV_16U; } };
+template <> struct CvType<short> { static int type() { return CV_16S; } };
+template <> struct CvType<int> { static int type() { return CV_32S; } };
+template <> struct CvType<float> { static int type() { return CV_32F; } };
+template <> struct CvType<double> { static int type() { return CV_64F; } };
+
+
+// bring the flann parameters into this namespace
+using ::cvflann::get_param;
+using ::cvflann::print_params;
+
+// bring the flann distances into this namespace
+using ::cvflann::L2_Simple;
+using ::cvflann::L2;
+using ::cvflann::L1;
+using ::cvflann::MinkowskiDistance;
+using ::cvflann::MaxDistance;
+using ::cvflann::HammingLUT;
+using ::cvflann::Hamming;
+using ::cvflann::Hamming2;
+using ::cvflann::HistIntersectionDistance;
+using ::cvflann::HellingerDistance;
+using ::cvflann::ChiSquareDistance;
+using ::cvflann::KL_Divergence;
+
+
+/** @brief The FLANN nearest neighbor index class. This class is templated with the type of elements for which
+the index is built.
+ */
+template <typename Distance>
+class GenericIndex
+{
+public:
+ typedef typename Distance::ElementType ElementType;
+ typedef typename Distance::ResultType DistanceType;
+
+ /** @brief Constructs a nearest neighbor search index for a given dataset.
+
+ @param features Matrix of containing the features(points) to index. The size of the matrix is
+ num_features x feature_dimensionality and the data type of the elements in the matrix must
+ coincide with the type of the index.
+ @param params Structure containing the index parameters. The type of index that will be
+ constructed depends on the type of this parameter. See the description.
+ @param distance
+
+ The method constructs a fast search structure from a set of features using the specified algorithm
+ with specified parameters, as defined by params. params is a reference to one of the following class
+ IndexParams descendants:
+
+ - **LinearIndexParams** When passing an object of this type, the index will perform a linear,
+ brute-force search. :
+ @code
+ struct LinearIndexParams : public IndexParams
+ {
+ };
+ @endcode
+ - **KDTreeIndexParams** When passing an object of this type the index constructed will consist of
+ a set of randomized kd-trees which will be searched in parallel. :
+ @code
+ struct KDTreeIndexParams : public IndexParams
+ {
+ KDTreeIndexParams( int trees = 4 );
+ };
+ @endcode
+ - **KMeansIndexParams** When passing an object of this type the index constructed will be a
+ hierarchical k-means tree. :
+ @code
+ struct KMeansIndexParams : public IndexParams
+ {
+ KMeansIndexParams(
+ int branching = 32,
+ int iterations = 11,
+ flann_centers_init_t centers_init = CENTERS_RANDOM,
+ float cb_index = 0.2 );
+ };
+ @endcode
+ - **CompositeIndexParams** When using a parameters object of this type the index created
+ combines the randomized kd-trees and the hierarchical k-means tree. :
+ @code
+ struct CompositeIndexParams : public IndexParams
+ {
+ CompositeIndexParams(
+ int trees = 4,
+ int branching = 32,
+ int iterations = 11,
+ flann_centers_init_t centers_init = CENTERS_RANDOM,
+ float cb_index = 0.2 );
+ };
+ @endcode
+ - **LshIndexParams** When using a parameters object of this type the index created uses
+ multi-probe LSH (by Multi-Probe LSH: Efficient Indexing for High-Dimensional Similarity Search
+ by Qin Lv, William Josephson, Zhe Wang, Moses Charikar, Kai Li., Proceedings of the 33rd
+ International Conference on Very Large Data Bases (VLDB). Vienna, Austria. September 2007) :
+ @code
+ struct LshIndexParams : public IndexParams
+ {
+ LshIndexParams(
+ unsigned int table_number,
+ unsigned int key_size,
+ unsigned int multi_probe_level );
+ };
+ @endcode
+ - **AutotunedIndexParams** When passing an object of this type the index created is
+ automatically tuned to offer the best performance, by choosing the optimal index type
+ (randomized kd-trees, hierarchical kmeans, linear) and parameters for the dataset provided. :
+ @code
+ struct AutotunedIndexParams : public IndexParams
+ {
+ AutotunedIndexParams(
+ float target_precision = 0.9,
+ float build_weight = 0.01,
+ float memory_weight = 0,
+ float sample_fraction = 0.1 );
+ };
+ @endcode
+ - **SavedIndexParams** This object type is used for loading a previously saved index from the
+ disk. :
+ @code
+ struct SavedIndexParams : public IndexParams
+ {
+ SavedIndexParams( String filename );
+ };
+ @endcode
+ */
+ GenericIndex(const Mat& features, const ::cvflann::IndexParams& params, Distance distance = Distance());
+
+ ~GenericIndex();
+
+ /** @brief Performs a K-nearest neighbor search for a given query point using the index.
+
+ @param query The query point
+ @param indices Vector that will contain the indices of the K-nearest neighbors found. It must have
+ at least knn size.
+ @param dists Vector that will contain the distances to the K-nearest neighbors found. It must have
+ at least knn size.
+ @param knn Number of nearest neighbors to search for.
+ @param params SearchParams
+ */
+ void knnSearch(const std::vector<ElementType>& query, std::vector<int>& indices,
+ std::vector<DistanceType>& dists, int knn, const ::cvflann::SearchParams& params);
+ void knnSearch(const Mat& queries, Mat& indices, Mat& dists, int knn, const ::cvflann::SearchParams& params);
+
+ int radiusSearch(const std::vector<ElementType>& query, std::vector<int>& indices,
+ std::vector<DistanceType>& dists, DistanceType radius, const ::cvflann::SearchParams& params);
+ int radiusSearch(const Mat& query, Mat& indices, Mat& dists,
+ DistanceType radius, const ::cvflann::SearchParams& params);
+
+ void save(String filename) { nnIndex->save(filename); }
+
+ int veclen() const { return nnIndex->veclen(); }
+
+ int size() const { return nnIndex->size(); }
+
+ ::cvflann::IndexParams getParameters() { return nnIndex->getParameters(); }
+
+ FLANN_DEPRECATED const ::cvflann::IndexParams* getIndexParameters() { return nnIndex->getIndexParameters(); }
+
+private:
+ ::cvflann::Index<Distance>* nnIndex;
+};
+
+//! @cond IGNORED
+
+#define FLANN_DISTANCE_CHECK \
+ if ( ::cvflann::flann_distance_type() != cvflann::FLANN_DIST_L2) { \
+ printf("[WARNING] You are using cv::flann::Index (or cv::flann::GenericIndex) and have also changed "\
+ "the distance using cvflann::set_distance_type. This is no longer working as expected "\
+ "(cv::flann::Index always uses L2). You should create the index templated on the distance, "\
+ "for example for L1 distance use: GenericIndex< L1<float> > \n"); \
+ }
+
+
+template <typename Distance>
+GenericIndex<Distance>::GenericIndex(const Mat& dataset, const ::cvflann::IndexParams& params, Distance distance)
+{
+ CV_Assert(dataset.type() == CvType<ElementType>::type());
+ CV_Assert(dataset.isContinuous());
+ ::cvflann::Matrix<ElementType> m_dataset((ElementType*)dataset.ptr<ElementType>(0), dataset.rows, dataset.cols);
+
+ nnIndex = new ::cvflann::Index<Distance>(m_dataset, params, distance);
+
+ FLANN_DISTANCE_CHECK
+
+ nnIndex->buildIndex();
+}
+
+template <typename Distance>
+GenericIndex<Distance>::~GenericIndex()
+{
+ delete nnIndex;
+}
+
+template <typename Distance>
+void GenericIndex<Distance>::knnSearch(const std::vector<ElementType>& query, std::vector<int>& indices, std::vector<DistanceType>& dists, int knn, const ::cvflann::SearchParams& searchParams)
+{
+ ::cvflann::Matrix<ElementType> m_query((ElementType*)&query[0], 1, query.size());
+ ::cvflann::Matrix<int> m_indices(&indices[0], 1, indices.size());
+ ::cvflann::Matrix<DistanceType> m_dists(&dists[0], 1, dists.size());
+
+ FLANN_DISTANCE_CHECK
+
+ nnIndex->knnSearch(m_query,m_indices,m_dists,knn,searchParams);
+}
+
+
+template <typename Distance>
+void GenericIndex<Distance>::knnSearch(const Mat& queries, Mat& indices, Mat& dists, int knn, const ::cvflann::SearchParams& searchParams)
+{
+ CV_Assert(queries.type() == CvType<ElementType>::type());
+ CV_Assert(queries.isContinuous());
+ ::cvflann::Matrix<ElementType> m_queries((ElementType*)queries.ptr<ElementType>(0), queries.rows, queries.cols);
+
+ CV_Assert(indices.type() == CV_32S);
+ CV_Assert(indices.isContinuous());
+ ::cvflann::Matrix<int> m_indices((int*)indices.ptr<int>(0), indices.rows, indices.cols);
+
+ CV_Assert(dists.type() == CvType<DistanceType>::type());
+ CV_Assert(dists.isContinuous());
+ ::cvflann::Matrix<DistanceType> m_dists((DistanceType*)dists.ptr<DistanceType>(0), dists.rows, dists.cols);
+
+ FLANN_DISTANCE_CHECK
+
+ nnIndex->knnSearch(m_queries,m_indices,m_dists,knn, searchParams);
+}
+
+template <typename Distance>
+int GenericIndex<Distance>::radiusSearch(const std::vector<ElementType>& query, std::vector<int>& indices, std::vector<DistanceType>& dists, DistanceType radius, const ::cvflann::SearchParams& searchParams)
+{
+ ::cvflann::Matrix<ElementType> m_query((ElementType*)&query[0], 1, query.size());
+ ::cvflann::Matrix<int> m_indices(&indices[0], 1, indices.size());
+ ::cvflann::Matrix<DistanceType> m_dists(&dists[0], 1, dists.size());
+
+ FLANN_DISTANCE_CHECK
+
+ return nnIndex->radiusSearch(m_query,m_indices,m_dists,radius,searchParams);
+}
+
+template <typename Distance>
+int GenericIndex<Distance>::radiusSearch(const Mat& query, Mat& indices, Mat& dists, DistanceType radius, const ::cvflann::SearchParams& searchParams)
+{
+ CV_Assert(query.type() == CvType<ElementType>::type());
+ CV_Assert(query.isContinuous());
+ ::cvflann::Matrix<ElementType> m_query((ElementType*)query.ptr<ElementType>(0), query.rows, query.cols);
+
+ CV_Assert(indices.type() == CV_32S);
+ CV_Assert(indices.isContinuous());
+ ::cvflann::Matrix<int> m_indices((int*)indices.ptr<int>(0), indices.rows, indices.cols);
+
+ CV_Assert(dists.type() == CvType<DistanceType>::type());
+ CV_Assert(dists.isContinuous());
+ ::cvflann::Matrix<DistanceType> m_dists((DistanceType*)dists.ptr<DistanceType>(0), dists.rows, dists.cols);
+
+ FLANN_DISTANCE_CHECK
+
+ return nnIndex->radiusSearch(m_query,m_indices,m_dists,radius,searchParams);
+}
+
+//! @endcond
+
+/**
+ * @deprecated Use GenericIndex class instead
+ */
+template <typename T>
+class Index_
+{
+public:
+ typedef typename L2<T>::ElementType ElementType;
+ typedef typename L2<T>::ResultType DistanceType;
+
+ FLANN_DEPRECATED Index_(const Mat& dataset, const ::cvflann::IndexParams& params)
+ {
+ printf("[WARNING] The cv::flann::Index_<T> class is deperecated, use cv::flann::GenericIndex<Distance> instead\n");
+
+ CV_Assert(dataset.type() == CvType<ElementType>::type());
+ CV_Assert(dataset.isContinuous());
+ ::cvflann::Matrix<ElementType> m_dataset((ElementType*)dataset.ptr<ElementType>(0), dataset.rows, dataset.cols);
+
+ if ( ::cvflann::flann_distance_type() == cvflann::FLANN_DIST_L2 ) {
+ nnIndex_L1 = NULL;
+ nnIndex_L2 = new ::cvflann::Index< L2<ElementType> >(m_dataset, params);
+ }
+ else if ( ::cvflann::flann_distance_type() == cvflann::FLANN_DIST_L1 ) {
+ nnIndex_L1 = new ::cvflann::Index< L1<ElementType> >(m_dataset, params);
+ nnIndex_L2 = NULL;
+ }
+ else {
+ printf("[ERROR] cv::flann::Index_<T> only provides backwards compatibility for the L1 and L2 distances. "
+ "For other distance types you must use cv::flann::GenericIndex<Distance>\n");
+ CV_Assert(0);
+ }
+ if (nnIndex_L1) nnIndex_L1->buildIndex();
+ if (nnIndex_L2) nnIndex_L2->buildIndex();
+ }
+ FLANN_DEPRECATED ~Index_()
+ {
+ if (nnIndex_L1) delete nnIndex_L1;
+ if (nnIndex_L2) delete nnIndex_L2;
+ }
+
+ FLANN_DEPRECATED void knnSearch(const std::vector<ElementType>& query, std::vector<int>& indices, std::vector<DistanceType>& dists, int knn, const ::cvflann::SearchParams& searchParams)
+ {
+ ::cvflann::Matrix<ElementType> m_query((ElementType*)&query[0], 1, query.size());
+ ::cvflann::Matrix<int> m_indices(&indices[0], 1, indices.size());
+ ::cvflann::Matrix<DistanceType> m_dists(&dists[0], 1, dists.size());
+
+ if (nnIndex_L1) nnIndex_L1->knnSearch(m_query,m_indices,m_dists,knn,searchParams);
+ if (nnIndex_L2) nnIndex_L2->knnSearch(m_query,m_indices,m_dists,knn,searchParams);
+ }
+ FLANN_DEPRECATED void knnSearch(const Mat& queries, Mat& indices, Mat& dists, int knn, const ::cvflann::SearchParams& searchParams)
+ {
+ CV_Assert(queries.type() == CvType<ElementType>::type());
+ CV_Assert(queries.isContinuous());
+ ::cvflann::Matrix<ElementType> m_queries((ElementType*)queries.ptr<ElementType>(0), queries.rows, queries.cols);
+
+ CV_Assert(indices.type() == CV_32S);
+ CV_Assert(indices.isContinuous());
+ ::cvflann::Matrix<int> m_indices((int*)indices.ptr<int>(0), indices.rows, indices.cols);
+
+ CV_Assert(dists.type() == CvType<DistanceType>::type());
+ CV_Assert(dists.isContinuous());
+ ::cvflann::Matrix<DistanceType> m_dists((DistanceType*)dists.ptr<DistanceType>(0), dists.rows, dists.cols);
+
+ if (nnIndex_L1) nnIndex_L1->knnSearch(m_queries,m_indices,m_dists,knn, searchParams);
+ if (nnIndex_L2) nnIndex_L2->knnSearch(m_queries,m_indices,m_dists,knn, searchParams);
+ }
+
+ FLANN_DEPRECATED int radiusSearch(const std::vector<ElementType>& query, std::vector<int>& indices, std::vector<DistanceType>& dists, DistanceType radius, const ::cvflann::SearchParams& searchParams)
+ {
+ ::cvflann::Matrix<ElementType> m_query((ElementType*)&query[0], 1, query.size());
+ ::cvflann::Matrix<int> m_indices(&indices[0], 1, indices.size());
+ ::cvflann::Matrix<DistanceType> m_dists(&dists[0], 1, dists.size());
+
+ if (nnIndex_L1) return nnIndex_L1->radiusSearch(m_query,m_indices,m_dists,radius,searchParams);
+ if (nnIndex_L2) return nnIndex_L2->radiusSearch(m_query,m_indices,m_dists,radius,searchParams);
+ }
+
+ FLANN_DEPRECATED int radiusSearch(const Mat& query, Mat& indices, Mat& dists, DistanceType radius, const ::cvflann::SearchParams& searchParams)
+ {
+ CV_Assert(query.type() == CvType<ElementType>::type());
+ CV_Assert(query.isContinuous());
+ ::cvflann::Matrix<ElementType> m_query((ElementType*)query.ptr<ElementType>(0), query.rows, query.cols);
+
+ CV_Assert(indices.type() == CV_32S);
+ CV_Assert(indices.isContinuous());
+ ::cvflann::Matrix<int> m_indices((int*)indices.ptr<int>(0), indices.rows, indices.cols);
+
+ CV_Assert(dists.type() == CvType<DistanceType>::type());
+ CV_Assert(dists.isContinuous());
+ ::cvflann::Matrix<DistanceType> m_dists((DistanceType*)dists.ptr<DistanceType>(0), dists.rows, dists.cols);
+
+ if (nnIndex_L1) return nnIndex_L1->radiusSearch(m_query,m_indices,m_dists,radius,searchParams);
+ if (nnIndex_L2) return nnIndex_L2->radiusSearch(m_query,m_indices,m_dists,radius,searchParams);
+ }
+
+ FLANN_DEPRECATED void save(String filename)
+ {
+ if (nnIndex_L1) nnIndex_L1->save(filename);
+ if (nnIndex_L2) nnIndex_L2->save(filename);
+ }
+
+ FLANN_DEPRECATED int veclen() const
+ {
+ if (nnIndex_L1) return nnIndex_L1->veclen();
+ if (nnIndex_L2) return nnIndex_L2->veclen();
+ }
+
+ FLANN_DEPRECATED int size() const
+ {
+ if (nnIndex_L1) return nnIndex_L1->size();
+ if (nnIndex_L2) return nnIndex_L2->size();
+ }
+
+ FLANN_DEPRECATED ::cvflann::IndexParams getParameters()
+ {
+ if (nnIndex_L1) return nnIndex_L1->getParameters();
+ if (nnIndex_L2) return nnIndex_L2->getParameters();
+
+ }
+
+ FLANN_DEPRECATED const ::cvflann::IndexParams* getIndexParameters()
+ {
+ if (nnIndex_L1) return nnIndex_L1->getIndexParameters();
+ if (nnIndex_L2) return nnIndex_L2->getIndexParameters();
+ }
+
+private:
+ // providing backwards compatibility for L2 and L1 distances (most common)
+ ::cvflann::Index< L2<ElementType> >* nnIndex_L2;
+ ::cvflann::Index< L1<ElementType> >* nnIndex_L1;
+};
+
+
+/** @brief Clusters features using hierarchical k-means algorithm.
+
+@param features The points to be clustered. The matrix must have elements of type
+Distance::ElementType.
+@param centers The centers of the clusters obtained. The matrix must have type
+Distance::ResultType. The number of rows in this matrix represents the number of clusters desired,
+however, because of the way the cut in the hierarchical tree is chosen, the number of clusters
+computed will be the highest number of the form (branching-1)\*k+1 that's lower than the number of
+clusters desired, where branching is the tree's branching factor (see description of the
+KMeansIndexParams).
+@param params Parameters used in the construction of the hierarchical k-means tree.
+@param d Distance to be used for clustering.
+
+The method clusters the given feature vectors by constructing a hierarchical k-means tree and
+choosing a cut in the tree that minimizes the cluster's variance. It returns the number of clusters
+found.
+ */
+template <typename Distance>
+int hierarchicalClustering(const Mat& features, Mat& centers, const ::cvflann::KMeansIndexParams& params,
+ Distance d = Distance())
+{
+ typedef typename Distance::ElementType ElementType;
+ typedef typename Distance::ResultType DistanceType;
+
+ CV_Assert(features.type() == CvType<ElementType>::type());
+ CV_Assert(features.isContinuous());
+ ::cvflann::Matrix<ElementType> m_features((ElementType*)features.ptr<ElementType>(0), features.rows, features.cols);
+
+ CV_Assert(centers.type() == CvType<DistanceType>::type());
+ CV_Assert(centers.isContinuous());
+ ::cvflann::Matrix<DistanceType> m_centers((DistanceType*)centers.ptr<DistanceType>(0), centers.rows, centers.cols);
+
+ return ::cvflann::hierarchicalClustering<Distance>(m_features, m_centers, params, d);
+}
+
+/** @deprecated
+*/
+template <typename ELEM_TYPE, typename DIST_TYPE>
+FLANN_DEPRECATED int hierarchicalClustering(const Mat& features, Mat& centers, const ::cvflann::KMeansIndexParams& params)
+{
+ printf("[WARNING] cv::flann::hierarchicalClustering<ELEM_TYPE,DIST_TYPE> is deprecated, use "
+ "cv::flann::hierarchicalClustering<Distance> instead\n");
+
+ if ( ::cvflann::flann_distance_type() == cvflann::FLANN_DIST_L2 ) {
+ return hierarchicalClustering< L2<ELEM_TYPE> >(features, centers, params);
+ }
+ else if ( ::cvflann::flann_distance_type() == cvflann::FLANN_DIST_L1 ) {
+ return hierarchicalClustering< L1<ELEM_TYPE> >(features, centers, params);
+ }
+ else {
+ printf("[ERROR] cv::flann::hierarchicalClustering<ELEM_TYPE,DIST_TYPE> only provides backwards "
+ "compatibility for the L1 and L2 distances. "
+ "For other distance types you must use cv::flann::hierarchicalClustering<Distance>\n");
+ CV_Assert(0);
+ }
+}
+
+//! @} flann
+
+} } // namespace cv::flann
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/flann/all_indices.h Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,155 @@
+/***********************************************************************
+ * Software License Agreement (BSD License)
+ *
+ * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved.
+ * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *************************************************************************/
+
+
+#ifndef OPENCV_FLANN_ALL_INDICES_H_
+#define OPENCV_FLANN_ALL_INDICES_H_
+
+#include "general.h"
+
+#include "nn_index.h"
+#include "kdtree_index.h"
+#include "kdtree_single_index.h"
+#include "kmeans_index.h"
+#include "composite_index.h"
+#include "linear_index.h"
+#include "hierarchical_clustering_index.h"
+#include "lsh_index.h"
+#include "autotuned_index.h"
+
+
+namespace cvflann
+{
+
+template<typename KDTreeCapability, typename VectorSpace, typename Distance>
+struct index_creator
+{
+ static NNIndex<Distance>* create(const Matrix<typename Distance::ElementType>& dataset, const IndexParams& params, const Distance& distance)
+ {
+ flann_algorithm_t index_type = get_param<flann_algorithm_t>(params, "algorithm");
+
+ NNIndex<Distance>* nnIndex;
+ switch (index_type) {
+ case FLANN_INDEX_LINEAR:
+ nnIndex = new LinearIndex<Distance>(dataset, params, distance);
+ break;
+ case FLANN_INDEX_KDTREE_SINGLE:
+ nnIndex = new KDTreeSingleIndex<Distance>(dataset, params, distance);
+ break;
+ case FLANN_INDEX_KDTREE:
+ nnIndex = new KDTreeIndex<Distance>(dataset, params, distance);
+ break;
+ case FLANN_INDEX_KMEANS:
+ nnIndex = new KMeansIndex<Distance>(dataset, params, distance);
+ break;
+ case FLANN_INDEX_COMPOSITE:
+ nnIndex = new CompositeIndex<Distance>(dataset, params, distance);
+ break;
+ case FLANN_INDEX_AUTOTUNED:
+ nnIndex = new AutotunedIndex<Distance>(dataset, params, distance);
+ break;
+ case FLANN_INDEX_HIERARCHICAL:
+ nnIndex = new HierarchicalClusteringIndex<Distance>(dataset, params, distance);
+ break;
+ case FLANN_INDEX_LSH:
+ nnIndex = new LshIndex<Distance>(dataset, params, distance);
+ break;
+ default:
+ throw FLANNException("Unknown index type");
+ }
+
+ return nnIndex;
+ }
+};
+
+template<typename VectorSpace, typename Distance>
+struct index_creator<False,VectorSpace,Distance>
+{
+ static NNIndex<Distance>* create(const Matrix<typename Distance::ElementType>& dataset, const IndexParams& params, const Distance& distance)
+ {
+ flann_algorithm_t index_type = get_param<flann_algorithm_t>(params, "algorithm");
+
+ NNIndex<Distance>* nnIndex;
+ switch (index_type) {
+ case FLANN_INDEX_LINEAR:
+ nnIndex = new LinearIndex<Distance>(dataset, params, distance);
+ break;
+ case FLANN_INDEX_KMEANS:
+ nnIndex = new KMeansIndex<Distance>(dataset, params, distance);
+ break;
+ case FLANN_INDEX_HIERARCHICAL:
+ nnIndex = new HierarchicalClusteringIndex<Distance>(dataset, params, distance);
+ break;
+ case FLANN_INDEX_LSH:
+ nnIndex = new LshIndex<Distance>(dataset, params, distance);
+ break;
+ default:
+ throw FLANNException("Unknown index type");
+ }
+
+ return nnIndex;
+ }
+};
+
+template<typename Distance>
+struct index_creator<False,False,Distance>
+{
+ static NNIndex<Distance>* create(const Matrix<typename Distance::ElementType>& dataset, const IndexParams& params, const Distance& distance)
+ {
+ flann_algorithm_t index_type = get_param<flann_algorithm_t>(params, "algorithm");
+
+ NNIndex<Distance>* nnIndex;
+ switch (index_type) {
+ case FLANN_INDEX_LINEAR:
+ nnIndex = new LinearIndex<Distance>(dataset, params, distance);
+ break;
+ case FLANN_INDEX_HIERARCHICAL:
+ nnIndex = new HierarchicalClusteringIndex<Distance>(dataset, params, distance);
+ break;
+ case FLANN_INDEX_LSH:
+ nnIndex = new LshIndex<Distance>(dataset, params, distance);
+ break;
+ default:
+ throw FLANNException("Unknown index type");
+ }
+
+ return nnIndex;
+ }
+};
+
+template<typename Distance>
+NNIndex<Distance>* create_index_by_type(const Matrix<typename Distance::ElementType>& dataset, const IndexParams& params, const Distance& distance)
+{
+ return index_creator<typename Distance::is_kdtree_distance,
+ typename Distance::is_vector_space_distance,
+ Distance>::create(dataset, params,distance);
+}
+
+}
+
+#endif /* OPENCV_FLANN_ALL_INDICES_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/flann/allocator.h Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,188 @@
+/***********************************************************************
+ * Software License Agreement (BSD License)
+ *
+ * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved.
+ * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved.
+ *
+ * THE BSD LICENSE
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *************************************************************************/
+
+#ifndef OPENCV_FLANN_ALLOCATOR_H_
+#define OPENCV_FLANN_ALLOCATOR_H_
+
+#include <stdlib.h>
+#include <stdio.h>
+
+
+namespace cvflann
+{
+
+/**
+ * Allocates (using C's malloc) a generic type T.
+ *
+ * Params:
+ * count = number of instances to allocate.
+ * Returns: pointer (of type T*) to memory buffer
+ */
+template <typename T>
+T* allocate(size_t count = 1)
+{
+ T* mem = (T*) ::malloc(sizeof(T)*count);
+ return mem;
+}
+
+
+/**
+ * Pooled storage allocator
+ *
+ * The following routines allow for the efficient allocation of storage in
+ * small chunks from a specified pool. Rather than allowing each structure
+ * to be freed individually, an entire pool of storage is freed at once.
+ * This method has two advantages over just using malloc() and free(). First,
+ * it is far more efficient for allocating small objects, as there is
+ * no overhead for remembering all the information needed to free each
+ * object or consolidating fragmented memory. Second, the decision about
+ * how long to keep an object is made at the time of allocation, and there
+ * is no need to track down all the objects to free them.
+ *
+ */
+
+const size_t WORDSIZE=16;
+const size_t BLOCKSIZE=8192;
+
+class PooledAllocator
+{
+ /* We maintain memory alignment to word boundaries by requiring that all
+ allocations be in multiples of the machine wordsize. */
+ /* Size of machine word in bytes. Must be power of 2. */
+ /* Minimum number of bytes requested at a time from the system. Must be multiple of WORDSIZE. */
+
+
+ int remaining; /* Number of bytes left in current block of storage. */
+ void* base; /* Pointer to base of current block of storage. */
+ void* loc; /* Current location in block to next allocate memory. */
+ int blocksize;
+
+
+public:
+ int usedMemory;
+ int wastedMemory;
+
+ /**
+ Default constructor. Initializes a new pool.
+ */
+ PooledAllocator(int blockSize = BLOCKSIZE)
+ {
+ blocksize = blockSize;
+ remaining = 0;
+ base = NULL;
+
+ usedMemory = 0;
+ wastedMemory = 0;
+ }
+
+ /**
+ * Destructor. Frees all the memory allocated in this pool.
+ */
+ ~PooledAllocator()
+ {
+ void* prev;
+
+ while (base != NULL) {
+ prev = *((void**) base); /* Get pointer to prev block. */
+ ::free(base);
+ base = prev;
+ }
+ }
+
+ /**
+ * Returns a pointer to a piece of new memory of the given size in bytes
+ * allocated from the pool.
+ */
+ void* allocateMemory(int size)
+ {
+ int blockSize;
+
+ /* Round size up to a multiple of wordsize. The following expression
+ only works for WORDSIZE that is a power of 2, by masking last bits of
+ incremented size to zero.
+ */
+ size = (size + (WORDSIZE - 1)) & ~(WORDSIZE - 1);
+
+ /* Check whether a new block must be allocated. Note that the first word
+ of a block is reserved for a pointer to the previous block.
+ */
+ if (size > remaining) {
+
+ wastedMemory += remaining;
+
+ /* Allocate new storage. */
+ blockSize = (size + sizeof(void*) + (WORDSIZE-1) > BLOCKSIZE) ?
+ size + sizeof(void*) + (WORDSIZE-1) : BLOCKSIZE;
+
+ // use the standard C malloc to allocate memory
+ void* m = ::malloc(blockSize);
+ if (!m) {
+ fprintf(stderr,"Failed to allocate memory.\n");
+ return NULL;
+ }
+
+ /* Fill first word of new block with pointer to previous block. */
+ ((void**) m)[0] = base;
+ base = m;
+
+ int shift = 0;
+ //int shift = (WORDSIZE - ( (((size_t)m) + sizeof(void*)) & (WORDSIZE-1))) & (WORDSIZE-1);
+
+ remaining = blockSize - sizeof(void*) - shift;
+ loc = ((char*)m + sizeof(void*) + shift);
+ }
+ void* rloc = loc;
+ loc = (char*)loc + size;
+ remaining -= size;
+
+ usedMemory += size;
+
+ return rloc;
+ }
+
+ /**
+ * Allocates (using this pool) a generic type T.
+ *
+ * Params:
+ * count = number of instances to allocate.
+ * Returns: pointer (of type T*) to memory buffer
+ */
+ template <typename T>
+ T* allocate(size_t count = 1)
+ {
+ T* mem = (T*) this->allocateMemory((int)(sizeof(T)*count));
+ return mem;
+ }
+
+};
+
+}
+
+#endif //OPENCV_FLANN_ALLOCATOR_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/flann/any.h Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,324 @@
+#ifndef OPENCV_FLANN_ANY_H_
+#define OPENCV_FLANN_ANY_H_
+/*
+ * (C) Copyright Christopher Diggins 2005-2011
+ * (C) Copyright Pablo Aguilar 2005
+ * (C) Copyright Kevlin Henney 2001
+ *
+ * Distributed under the Boost Software License, Version 1.0. (See
+ * accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt
+ *
+ * Adapted for FLANN by Marius Muja
+ */
+
+#include "defines.h"
+#include <stdexcept>
+#include <ostream>
+#include <typeinfo>
+
+namespace cvflann
+{
+
+namespace anyimpl
+{
+
+struct bad_any_cast
+{
+};
+
+struct empty_any
+{
+};
+
+inline std::ostream& operator <<(std::ostream& out, const empty_any&)
+{
+ out << "[empty_any]";
+ return out;
+}
+
+struct base_any_policy
+{
+ virtual void static_delete(void** x) = 0;
+ virtual void copy_from_value(void const* src, void** dest) = 0;
+ virtual void clone(void* const* src, void** dest) = 0;
+ virtual void move(void* const* src, void** dest) = 0;
+ virtual void* get_value(void** src) = 0;
+ virtual const void* get_value(void* const * src) = 0;
+ virtual ::size_t get_size() = 0;
+ virtual const std::type_info& type() = 0;
+ virtual void print(std::ostream& out, void* const* src) = 0;
+ virtual ~base_any_policy() {}
+};
+
+template<typename T>
+struct typed_base_any_policy : base_any_policy
+{
+ virtual ::size_t get_size() { return sizeof(T); }
+ virtual const std::type_info& type() { return typeid(T); }
+
+};
+
+template<typename T>
+struct small_any_policy : typed_base_any_policy<T>
+{
+ virtual void static_delete(void**) { }
+ virtual void copy_from_value(void const* src, void** dest)
+ {
+ new (dest) T(* reinterpret_cast<T const*>(src));
+ }
+ virtual void clone(void* const* src, void** dest) { *dest = *src; }
+ virtual void move(void* const* src, void** dest) { *dest = *src; }
+ virtual void* get_value(void** src) { return reinterpret_cast<void*>(src); }
+ virtual const void* get_value(void* const * src) { return reinterpret_cast<const void*>(src); }
+ virtual void print(std::ostream& out, void* const* src) { out << *reinterpret_cast<T const*>(src); }
+};
+
+template<typename T>
+struct big_any_policy : typed_base_any_policy<T>
+{
+ virtual void static_delete(void** x)
+ {
+ if (* x) delete (* reinterpret_cast<T**>(x));
+ *x = NULL;
+ }
+ virtual void copy_from_value(void const* src, void** dest)
+ {
+ *dest = new T(*reinterpret_cast<T const*>(src));
+ }
+ virtual void clone(void* const* src, void** dest)
+ {
+ *dest = new T(**reinterpret_cast<T* const*>(src));
+ }
+ virtual void move(void* const* src, void** dest)
+ {
+ (*reinterpret_cast<T**>(dest))->~T();
+ **reinterpret_cast<T**>(dest) = **reinterpret_cast<T* const*>(src);
+ }
+ virtual void* get_value(void** src) { return *src; }
+ virtual const void* get_value(void* const * src) { return *src; }
+ virtual void print(std::ostream& out, void* const* src) { out << *reinterpret_cast<T const*>(*src); }
+};
+
+template<> inline void big_any_policy<flann_centers_init_t>::print(std::ostream& out, void* const* src)
+{
+ out << int(*reinterpret_cast<flann_centers_init_t const*>(*src));
+}
+
+template<> inline void big_any_policy<flann_algorithm_t>::print(std::ostream& out, void* const* src)
+{
+ out << int(*reinterpret_cast<flann_algorithm_t const*>(*src));
+}
+
+template<> inline void big_any_policy<cv::String>::print(std::ostream& out, void* const* src)
+{
+ out << (*reinterpret_cast<cv::String const*>(*src)).c_str();
+}
+
+template<typename T>
+struct choose_policy
+{
+ typedef big_any_policy<T> type;
+};
+
+template<typename T>
+struct choose_policy<T*>
+{
+ typedef small_any_policy<T*> type;
+};
+
+struct any;
+
+/// Choosing the policy for an any type is illegal, but should never happen.
+/// This is designed to throw a compiler error.
+template<>
+struct choose_policy<any>
+{
+ typedef void type;
+};
+
+/// Specializations for small types.
+#define SMALL_POLICY(TYPE) \
+ template<> \
+ struct choose_policy<TYPE> { typedef small_any_policy<TYPE> type; \
+ }
+
+SMALL_POLICY(signed char);
+SMALL_POLICY(unsigned char);
+SMALL_POLICY(signed short);
+SMALL_POLICY(unsigned short);
+SMALL_POLICY(signed int);
+SMALL_POLICY(unsigned int);
+SMALL_POLICY(signed long);
+SMALL_POLICY(unsigned long);
+SMALL_POLICY(float);
+SMALL_POLICY(bool);
+
+#undef SMALL_POLICY
+
+template <typename T>
+class SinglePolicy
+{
+ SinglePolicy();
+ SinglePolicy(const SinglePolicy& other);
+ SinglePolicy& operator=(const SinglePolicy& other);
+
+public:
+ static base_any_policy* get_policy();
+
+private:
+ static typename choose_policy<T>::type policy;
+};
+
+template <typename T>
+typename choose_policy<T>::type SinglePolicy<T>::policy;
+
+/// This function will return a different policy for each type.
+template <typename T>
+inline base_any_policy* SinglePolicy<T>::get_policy() { return &policy; }
+
+} // namespace anyimpl
+
+struct any
+{
+private:
+ // fields
+ anyimpl::base_any_policy* policy;
+ void* object;
+
+public:
+ /// Initializing constructor.
+ template <typename T>
+ any(const T& x)
+ : policy(anyimpl::SinglePolicy<anyimpl::empty_any>::get_policy()), object(NULL)
+ {
+ assign(x);
+ }
+
+ /// Empty constructor.
+ any()
+ : policy(anyimpl::SinglePolicy<anyimpl::empty_any>::get_policy()), object(NULL)
+ { }
+
+ /// Special initializing constructor for string literals.
+ any(const char* x)
+ : policy(anyimpl::SinglePolicy<anyimpl::empty_any>::get_policy()), object(NULL)
+ {
+ assign(x);
+ }
+
+ /// Copy constructor.
+ any(const any& x)
+ : policy(anyimpl::SinglePolicy<anyimpl::empty_any>::get_policy()), object(NULL)
+ {
+ assign(x);
+ }
+
+ /// Destructor.
+ ~any()
+ {
+ policy->static_delete(&object);
+ }
+
+ /// Assignment function from another any.
+ any& assign(const any& x)
+ {
+ reset();
+ policy = x.policy;
+ policy->clone(&x.object, &object);
+ return *this;
+ }
+
+ /// Assignment function.
+ template <typename T>
+ any& assign(const T& x)
+ {
+ reset();
+ policy = anyimpl::SinglePolicy<T>::get_policy();
+ policy->copy_from_value(&x, &object);
+ return *this;
+ }
+
+ /// Assignment operator.
+ template<typename T>
+ any& operator=(const T& x)
+ {
+ return assign(x);
+ }
+
+ /// Assignment operator, specialed for literal strings.
+ /// They have types like const char [6] which don't work as expected.
+ any& operator=(const char* x)
+ {
+ return assign(x);
+ }
+
+ /// Utility functions
+ any& swap(any& x)
+ {
+ std::swap(policy, x.policy);
+ std::swap(object, x.object);
+ return *this;
+ }
+
+ /// Cast operator. You can only cast to the original type.
+ template<typename T>
+ T& cast()
+ {
+ if (policy->type() != typeid(T)) throw anyimpl::bad_any_cast();
+ T* r = reinterpret_cast<T*>(policy->get_value(&object));
+ return *r;
+ }
+
+ /// Cast operator. You can only cast to the original type.
+ template<typename T>
+ const T& cast() const
+ {
+ if (policy->type() != typeid(T)) throw anyimpl::bad_any_cast();
+ const T* r = reinterpret_cast<const T*>(policy->get_value(&object));
+ return *r;
+ }
+
+ /// Returns true if the any contains no value.
+ bool empty() const
+ {
+ return policy->type() == typeid(anyimpl::empty_any);
+ }
+
+ /// Frees any allocated memory, and sets the value to NULL.
+ void reset()
+ {
+ policy->static_delete(&object);
+ policy = anyimpl::SinglePolicy<anyimpl::empty_any>::get_policy();
+ }
+
+ /// Returns true if the two types are the same.
+ bool compatible(const any& x) const
+ {
+ return policy->type() == x.policy->type();
+ }
+
+ /// Returns if the type is compatible with the policy
+ template<typename T>
+ bool has_type()
+ {
+ return policy->type() == typeid(T);
+ }
+
+ const std::type_info& type() const
+ {
+ return policy->type();
+ }
+
+ friend std::ostream& operator <<(std::ostream& out, const any& any_val);
+};
+
+inline std::ostream& operator <<(std::ostream& out, const any& any_val)
+{
+ any_val.policy->print(out,&any_val.object);
+ return out;
+}
+
+}
+
+#endif // OPENCV_FLANN_ANY_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/flann/autotuned_index.h Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,588 @@
+/***********************************************************************
+ * Software License Agreement (BSD License)
+ *
+ * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved.
+ * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved.
+ *
+ * THE BSD LICENSE
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *************************************************************************/
+#ifndef OPENCV_FLANN_AUTOTUNED_INDEX_H_
+#define OPENCV_FLANN_AUTOTUNED_INDEX_H_
+
+#include "general.h"
+#include "nn_index.h"
+#include "ground_truth.h"
+#include "index_testing.h"
+#include "sampling.h"
+#include "kdtree_index.h"
+#include "kdtree_single_index.h"
+#include "kmeans_index.h"
+#include "composite_index.h"
+#include "linear_index.h"
+#include "logger.h"
+
+namespace cvflann
+{
+
+template<typename Distance>
+NNIndex<Distance>* create_index_by_type(const Matrix<typename Distance::ElementType>& dataset, const IndexParams& params, const Distance& distance);
+
+
+struct AutotunedIndexParams : public IndexParams
+{
+ AutotunedIndexParams(float target_precision = 0.8, float build_weight = 0.01, float memory_weight = 0, float sample_fraction = 0.1)
+ {
+ (*this)["algorithm"] = FLANN_INDEX_AUTOTUNED;
+ // precision desired (used for autotuning, -1 otherwise)
+ (*this)["target_precision"] = target_precision;
+ // build tree time weighting factor
+ (*this)["build_weight"] = build_weight;
+ // index memory weighting factor
+ (*this)["memory_weight"] = memory_weight;
+ // what fraction of the dataset to use for autotuning
+ (*this)["sample_fraction"] = sample_fraction;
+ }
+};
+
+
+template <typename Distance>
+class AutotunedIndex : public NNIndex<Distance>
+{
+public:
+ typedef typename Distance::ElementType ElementType;
+ typedef typename Distance::ResultType DistanceType;
+
+ AutotunedIndex(const Matrix<ElementType>& inputData, const IndexParams& params = AutotunedIndexParams(), Distance d = Distance()) :
+ dataset_(inputData), distance_(d)
+ {
+ target_precision_ = get_param(params, "target_precision",0.8f);
+ build_weight_ = get_param(params,"build_weight", 0.01f);
+ memory_weight_ = get_param(params, "memory_weight", 0.0f);
+ sample_fraction_ = get_param(params,"sample_fraction", 0.1f);
+ bestIndex_ = NULL;
+ }
+
+ AutotunedIndex(const AutotunedIndex&);
+ AutotunedIndex& operator=(const AutotunedIndex&);
+
+ virtual ~AutotunedIndex()
+ {
+ if (bestIndex_ != NULL) {
+ delete bestIndex_;
+ bestIndex_ = NULL;
+ }
+ }
+
+ /**
+ * Method responsible with building the index.
+ */
+ virtual void buildIndex()
+ {
+ std::ostringstream stream;
+ bestParams_ = estimateBuildParams();
+ print_params(bestParams_, stream);
+ Logger::info("----------------------------------------------------\n");
+ Logger::info("Autotuned parameters:\n");
+ Logger::info("%s", stream.str().c_str());
+ Logger::info("----------------------------------------------------\n");
+
+ bestIndex_ = create_index_by_type(dataset_, bestParams_, distance_);
+ bestIndex_->buildIndex();
+ speedup_ = estimateSearchParams(bestSearchParams_);
+ stream.str(std::string());
+ print_params(bestSearchParams_, stream);
+ Logger::info("----------------------------------------------------\n");
+ Logger::info("Search parameters:\n");
+ Logger::info("%s", stream.str().c_str());
+ Logger::info("----------------------------------------------------\n");
+ }
+
+ /**
+ * Saves the index to a stream
+ */
+ virtual void saveIndex(FILE* stream)
+ {
+ save_value(stream, (int)bestIndex_->getType());
+ bestIndex_->saveIndex(stream);
+ save_value(stream, get_param<int>(bestSearchParams_, "checks"));
+ }
+
+ /**
+ * Loads the index from a stream
+ */
+ virtual void loadIndex(FILE* stream)
+ {
+ int index_type;
+
+ load_value(stream, index_type);
+ IndexParams params;
+ params["algorithm"] = (flann_algorithm_t)index_type;
+ bestIndex_ = create_index_by_type<Distance>(dataset_, params, distance_);
+ bestIndex_->loadIndex(stream);
+ int checks;
+ load_value(stream, checks);
+ bestSearchParams_["checks"] = checks;
+ }
+
+ /**
+ * Method that searches for nearest-neighbors
+ */
+ virtual void findNeighbors(ResultSet<DistanceType>& result, const ElementType* vec, const SearchParams& searchParams)
+ {
+ int checks = get_param<int>(searchParams,"checks",FLANN_CHECKS_AUTOTUNED);
+ if (checks == FLANN_CHECKS_AUTOTUNED) {
+ bestIndex_->findNeighbors(result, vec, bestSearchParams_);
+ }
+ else {
+ bestIndex_->findNeighbors(result, vec, searchParams);
+ }
+ }
+
+
+ IndexParams getParameters() const
+ {
+ return bestIndex_->getParameters();
+ }
+
+ SearchParams getSearchParameters() const
+ {
+ return bestSearchParams_;
+ }
+
+ float getSpeedup() const
+ {
+ return speedup_;
+ }
+
+
+ /**
+ * Number of features in this index.
+ */
+ virtual size_t size() const
+ {
+ return bestIndex_->size();
+ }
+
+ /**
+ * The length of each vector in this index.
+ */
+ virtual size_t veclen() const
+ {
+ return bestIndex_->veclen();
+ }
+
+ /**
+ * The amount of memory (in bytes) this index uses.
+ */
+ virtual int usedMemory() const
+ {
+ return bestIndex_->usedMemory();
+ }
+
+ /**
+ * Algorithm name
+ */
+ virtual flann_algorithm_t getType() const
+ {
+ return FLANN_INDEX_AUTOTUNED;
+ }
+
+private:
+
+ struct CostData
+ {
+ float searchTimeCost;
+ float buildTimeCost;
+ float memoryCost;
+ float totalCost;
+ IndexParams params;
+ };
+
+ void evaluate_kmeans(CostData& cost)
+ {
+ StartStopTimer t;
+ int checks;
+ const int nn = 1;
+
+ Logger::info("KMeansTree using params: max_iterations=%d, branching=%d\n",
+ get_param<int>(cost.params,"iterations"),
+ get_param<int>(cost.params,"branching"));
+ KMeansIndex<Distance> kmeans(sampledDataset_, cost.params, distance_);
+ // measure index build time
+ t.start();
+ kmeans.buildIndex();
+ t.stop();
+ float buildTime = (float)t.value;
+
+ // measure search time
+ float searchTime = test_index_precision(kmeans, sampledDataset_, testDataset_, gt_matches_, target_precision_, checks, distance_, nn);
+
+ float datasetMemory = float(sampledDataset_.rows * sampledDataset_.cols * sizeof(float));
+ cost.memoryCost = (kmeans.usedMemory() + datasetMemory) / datasetMemory;
+ cost.searchTimeCost = searchTime;
+ cost.buildTimeCost = buildTime;
+ Logger::info("KMeansTree buildTime=%g, searchTime=%g, build_weight=%g\n", buildTime, searchTime, build_weight_);
+ }
+
+
+ void evaluate_kdtree(CostData& cost)
+ {
+ StartStopTimer t;
+ int checks;
+ const int nn = 1;
+
+ Logger::info("KDTree using params: trees=%d\n", get_param<int>(cost.params,"trees"));
+ KDTreeIndex<Distance> kdtree(sampledDataset_, cost.params, distance_);
+
+ t.start();
+ kdtree.buildIndex();
+ t.stop();
+ float buildTime = (float)t.value;
+
+ //measure search time
+ float searchTime = test_index_precision(kdtree, sampledDataset_, testDataset_, gt_matches_, target_precision_, checks, distance_, nn);
+
+ float datasetMemory = float(sampledDataset_.rows * sampledDataset_.cols * sizeof(float));
+ cost.memoryCost = (kdtree.usedMemory() + datasetMemory) / datasetMemory;
+ cost.searchTimeCost = searchTime;
+ cost.buildTimeCost = buildTime;
+ Logger::info("KDTree buildTime=%g, searchTime=%g\n", buildTime, searchTime);
+ }
+
+
+ // struct KMeansSimpleDownhillFunctor {
+ //
+ // Autotune& autotuner;
+ // KMeansSimpleDownhillFunctor(Autotune& autotuner_) : autotuner(autotuner_) {}
+ //
+ // float operator()(int* params) {
+ //
+ // float maxFloat = numeric_limits<float>::max();
+ //
+ // if (params[0]<2) return maxFloat;
+ // if (params[1]<0) return maxFloat;
+ //
+ // CostData c;
+ // c.params["algorithm"] = KMEANS;
+ // c.params["centers-init"] = CENTERS_RANDOM;
+ // c.params["branching"] = params[0];
+ // c.params["max-iterations"] = params[1];
+ //
+ // autotuner.evaluate_kmeans(c);
+ //
+ // return c.timeCost;
+ //
+ // }
+ // };
+ //
+ // struct KDTreeSimpleDownhillFunctor {
+ //
+ // Autotune& autotuner;
+ // KDTreeSimpleDownhillFunctor(Autotune& autotuner_) : autotuner(autotuner_) {}
+ //
+ // float operator()(int* params) {
+ // float maxFloat = numeric_limits<float>::max();
+ //
+ // if (params[0]<1) return maxFloat;
+ //
+ // CostData c;
+ // c.params["algorithm"] = KDTREE;
+ // c.params["trees"] = params[0];
+ //
+ // autotuner.evaluate_kdtree(c);
+ //
+ // return c.timeCost;
+ //
+ // }
+ // };
+
+
+
+ void optimizeKMeans(std::vector<CostData>& costs)
+ {
+ Logger::info("KMEANS, Step 1: Exploring parameter space\n");
+
+ // explore kmeans parameters space using combinations of the parameters below
+ int maxIterations[] = { 1, 5, 10, 15 };
+ int branchingFactors[] = { 16, 32, 64, 128, 256 };
+
+ int kmeansParamSpaceSize = FLANN_ARRAY_LEN(maxIterations) * FLANN_ARRAY_LEN(branchingFactors);
+ costs.reserve(costs.size() + kmeansParamSpaceSize);
+
+ // evaluate kmeans for all parameter combinations
+ for (size_t i = 0; i < FLANN_ARRAY_LEN(maxIterations); ++i) {
+ for (size_t j = 0; j < FLANN_ARRAY_LEN(branchingFactors); ++j) {
+ CostData cost;
+ cost.params["algorithm"] = FLANN_INDEX_KMEANS;
+ cost.params["centers_init"] = FLANN_CENTERS_RANDOM;
+ cost.params["iterations"] = maxIterations[i];
+ cost.params["branching"] = branchingFactors[j];
+
+ evaluate_kmeans(cost);
+ costs.push_back(cost);
+ }
+ }
+
+ // Logger::info("KMEANS, Step 2: simplex-downhill optimization\n");
+ //
+ // const int n = 2;
+ // // choose initial simplex points as the best parameters so far
+ // int kmeansNMPoints[n*(n+1)];
+ // float kmeansVals[n+1];
+ // for (int i=0;i<n+1;++i) {
+ // kmeansNMPoints[i*n] = (int)kmeansCosts[i].params["branching"];
+ // kmeansNMPoints[i*n+1] = (int)kmeansCosts[i].params["max-iterations"];
+ // kmeansVals[i] = kmeansCosts[i].timeCost;
+ // }
+ // KMeansSimpleDownhillFunctor kmeans_cost_func(*this);
+ // // run optimization
+ // optimizeSimplexDownhill(kmeansNMPoints,n,kmeans_cost_func,kmeansVals);
+ // // store results
+ // for (int i=0;i<n+1;++i) {
+ // kmeansCosts[i].params["branching"] = kmeansNMPoints[i*2];
+ // kmeansCosts[i].params["max-iterations"] = kmeansNMPoints[i*2+1];
+ // kmeansCosts[i].timeCost = kmeansVals[i];
+ // }
+ }
+
+
+ void optimizeKDTree(std::vector<CostData>& costs)
+ {
+ Logger::info("KD-TREE, Step 1: Exploring parameter space\n");
+
+ // explore kd-tree parameters space using the parameters below
+ int testTrees[] = { 1, 4, 8, 16, 32 };
+
+ // evaluate kdtree for all parameter combinations
+ for (size_t i = 0; i < FLANN_ARRAY_LEN(testTrees); ++i) {
+ CostData cost;
+ cost.params["algorithm"] = FLANN_INDEX_KDTREE;
+ cost.params["trees"] = testTrees[i];
+
+ evaluate_kdtree(cost);
+ costs.push_back(cost);
+ }
+
+ // Logger::info("KD-TREE, Step 2: simplex-downhill optimization\n");
+ //
+ // const int n = 1;
+ // // choose initial simplex points as the best parameters so far
+ // int kdtreeNMPoints[n*(n+1)];
+ // float kdtreeVals[n+1];
+ // for (int i=0;i<n+1;++i) {
+ // kdtreeNMPoints[i] = (int)kdtreeCosts[i].params["trees"];
+ // kdtreeVals[i] = kdtreeCosts[i].timeCost;
+ // }
+ // KDTreeSimpleDownhillFunctor kdtree_cost_func(*this);
+ // // run optimization
+ // optimizeSimplexDownhill(kdtreeNMPoints,n,kdtree_cost_func,kdtreeVals);
+ // // store results
+ // for (int i=0;i<n+1;++i) {
+ // kdtreeCosts[i].params["trees"] = kdtreeNMPoints[i];
+ // kdtreeCosts[i].timeCost = kdtreeVals[i];
+ // }
+ }
+
+ /**
+ * Chooses the best nearest-neighbor algorithm and estimates the optimal
+ * parameters to use when building the index (for a given precision).
+ * Returns a dictionary with the optimal parameters.
+ */
+ IndexParams estimateBuildParams()
+ {
+ std::vector<CostData> costs;
+
+ int sampleSize = int(sample_fraction_ * dataset_.rows);
+ int testSampleSize = std::min(sampleSize / 10, 1000);
+
+ Logger::info("Entering autotuning, dataset size: %d, sampleSize: %d, testSampleSize: %d, target precision: %g\n", dataset_.rows, sampleSize, testSampleSize, target_precision_);
+
+ // For a very small dataset, it makes no sense to build any fancy index, just
+ // use linear search
+ if (testSampleSize < 10) {
+ Logger::info("Choosing linear, dataset too small\n");
+ return LinearIndexParams();
+ }
+
+ // We use a fraction of the original dataset to speedup the autotune algorithm
+ sampledDataset_ = random_sample(dataset_, sampleSize);
+ // We use a cross-validation approach, first we sample a testset from the dataset
+ testDataset_ = random_sample(sampledDataset_, testSampleSize, true);
+
+ // We compute the ground truth using linear search
+ Logger::info("Computing ground truth... \n");
+ gt_matches_ = Matrix<int>(new int[testDataset_.rows], testDataset_.rows, 1);
+ StartStopTimer t;
+ t.start();
+ compute_ground_truth<Distance>(sampledDataset_, testDataset_, gt_matches_, 0, distance_);
+ t.stop();
+
+ CostData linear_cost;
+ linear_cost.searchTimeCost = (float)t.value;
+ linear_cost.buildTimeCost = 0;
+ linear_cost.memoryCost = 0;
+ linear_cost.params["algorithm"] = FLANN_INDEX_LINEAR;
+
+ costs.push_back(linear_cost);
+
+ // Start parameter autotune process
+ Logger::info("Autotuning parameters...\n");
+
+ optimizeKMeans(costs);
+ optimizeKDTree(costs);
+
+ float bestTimeCost = costs[0].searchTimeCost;
+ for (size_t i = 0; i < costs.size(); ++i) {
+ float timeCost = costs[i].buildTimeCost * build_weight_ + costs[i].searchTimeCost;
+ if (timeCost < bestTimeCost) {
+ bestTimeCost = timeCost;
+ }
+ }
+
+ float bestCost = costs[0].searchTimeCost / bestTimeCost;
+ IndexParams bestParams = costs[0].params;
+ if (bestTimeCost > 0) {
+ for (size_t i = 0; i < costs.size(); ++i) {
+ float crtCost = (costs[i].buildTimeCost * build_weight_ + costs[i].searchTimeCost) / bestTimeCost +
+ memory_weight_ * costs[i].memoryCost;
+ if (crtCost < bestCost) {
+ bestCost = crtCost;
+ bestParams = costs[i].params;
+ }
+ }
+ }
+
+ delete[] gt_matches_.data;
+ delete[] testDataset_.data;
+ delete[] sampledDataset_.data;
+
+ return bestParams;
+ }
+
+
+
+ /**
+ * Estimates the search time parameters needed to get the desired precision.
+ * Precondition: the index is built
+ * Postcondition: the searchParams will have the optimum params set, also the speedup obtained over linear search.
+ */
+ float estimateSearchParams(SearchParams& searchParams)
+ {
+ const int nn = 1;
+ const size_t SAMPLE_COUNT = 1000;
+
+ assert(bestIndex_ != NULL); // must have a valid index
+
+ float speedup = 0;
+
+ int samples = (int)std::min(dataset_.rows / 10, SAMPLE_COUNT);
+ if (samples > 0) {
+ Matrix<ElementType> testDataset = random_sample(dataset_, samples);
+
+ Logger::info("Computing ground truth\n");
+
+ // we need to compute the ground truth first
+ Matrix<int> gt_matches(new int[testDataset.rows], testDataset.rows, 1);
+ StartStopTimer t;
+ t.start();
+ compute_ground_truth<Distance>(dataset_, testDataset, gt_matches, 1, distance_);
+ t.stop();
+ float linear = (float)t.value;
+
+ int checks;
+ Logger::info("Estimating number of checks\n");
+
+ float searchTime;
+ float cb_index;
+ if (bestIndex_->getType() == FLANN_INDEX_KMEANS) {
+ Logger::info("KMeans algorithm, estimating cluster border factor\n");
+ KMeansIndex<Distance>* kmeans = (KMeansIndex<Distance>*)bestIndex_;
+ float bestSearchTime = -1;
+ float best_cb_index = -1;
+ int best_checks = -1;
+ for (cb_index = 0; cb_index < 1.1f; cb_index += 0.2f) {
+ kmeans->set_cb_index(cb_index);
+ searchTime = test_index_precision(*kmeans, dataset_, testDataset, gt_matches, target_precision_, checks, distance_, nn, 1);
+ if ((searchTime < bestSearchTime) || (bestSearchTime == -1)) {
+ bestSearchTime = searchTime;
+ best_cb_index = cb_index;
+ best_checks = checks;
+ }
+ }
+ searchTime = bestSearchTime;
+ cb_index = best_cb_index;
+ checks = best_checks;
+
+ kmeans->set_cb_index(best_cb_index);
+ Logger::info("Optimum cb_index: %g\n", cb_index);
+ bestParams_["cb_index"] = cb_index;
+ }
+ else {
+ searchTime = test_index_precision(*bestIndex_, dataset_, testDataset, gt_matches, target_precision_, checks, distance_, nn, 1);
+ }
+
+ Logger::info("Required number of checks: %d \n", checks);
+ searchParams["checks"] = checks;
+
+ speedup = linear / searchTime;
+
+ delete[] gt_matches.data;
+ delete[] testDataset.data;
+ }
+
+ return speedup;
+ }
+
+private:
+ NNIndex<Distance>* bestIndex_;
+
+ IndexParams bestParams_;
+ SearchParams bestSearchParams_;
+
+ Matrix<ElementType> sampledDataset_;
+ Matrix<ElementType> testDataset_;
+ Matrix<int> gt_matches_;
+
+ float speedup_;
+
+ /**
+ * The dataset used by this index
+ */
+ const Matrix<ElementType> dataset_;
+
+ /**
+ * Index parameters
+ */
+ float target_precision_;
+ float build_weight_;
+ float memory_weight_;
+ float sample_fraction_;
+
+ Distance distance_;
+
+
+};
+}
+
+#endif /* OPENCV_FLANN_AUTOTUNED_INDEX_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/flann/composite_index.h Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,194 @@
+/***********************************************************************
+ * Software License Agreement (BSD License)
+ *
+ * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved.
+ * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved.
+ *
+ * THE BSD LICENSE
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *************************************************************************/
+
+#ifndef OPENCV_FLANN_COMPOSITE_INDEX_H_
+#define OPENCV_FLANN_COMPOSITE_INDEX_H_
+
+#include "general.h"
+#include "nn_index.h"
+#include "kdtree_index.h"
+#include "kmeans_index.h"
+
+namespace cvflann
+{
+
+/**
+ * Index parameters for the CompositeIndex.
+ */
+struct CompositeIndexParams : public IndexParams
+{
+ CompositeIndexParams(int trees = 4, int branching = 32, int iterations = 11,
+ flann_centers_init_t centers_init = FLANN_CENTERS_RANDOM, float cb_index = 0.2 )
+ {
+ (*this)["algorithm"] = FLANN_INDEX_KMEANS;
+ // number of randomized trees to use (for kdtree)
+ (*this)["trees"] = trees;
+ // branching factor
+ (*this)["branching"] = branching;
+ // max iterations to perform in one kmeans clustering (kmeans tree)
+ (*this)["iterations"] = iterations;
+ // algorithm used for picking the initial cluster centers for kmeans tree
+ (*this)["centers_init"] = centers_init;
+ // cluster boundary index. Used when searching the kmeans tree
+ (*this)["cb_index"] = cb_index;
+ }
+};
+
+
+/**
+ * This index builds a kd-tree index and a k-means index and performs nearest
+ * neighbour search both indexes. This gives a slight boost in search performance
+ * as some of the neighbours that are missed by one index are found by the other.
+ */
+template <typename Distance>
+class CompositeIndex : public NNIndex<Distance>
+{
+public:
+ typedef typename Distance::ElementType ElementType;
+ typedef typename Distance::ResultType DistanceType;
+
+ /**
+ * Index constructor
+ * @param inputData dataset containing the points to index
+ * @param params Index parameters
+ * @param d Distance functor
+ * @return
+ */
+ CompositeIndex(const Matrix<ElementType>& inputData, const IndexParams& params = CompositeIndexParams(),
+ Distance d = Distance()) : index_params_(params)
+ {
+ kdtree_index_ = new KDTreeIndex<Distance>(inputData, params, d);
+ kmeans_index_ = new KMeansIndex<Distance>(inputData, params, d);
+
+ }
+
+ CompositeIndex(const CompositeIndex&);
+ CompositeIndex& operator=(const CompositeIndex&);
+
+ virtual ~CompositeIndex()
+ {
+ delete kdtree_index_;
+ delete kmeans_index_;
+ }
+
+ /**
+ * @return The index type
+ */
+ flann_algorithm_t getType() const
+ {
+ return FLANN_INDEX_COMPOSITE;
+ }
+
+ /**
+ * @return Size of the index
+ */
+ size_t size() const
+ {
+ return kdtree_index_->size();
+ }
+
+ /**
+ * \returns The dimensionality of the features in this index.
+ */
+ size_t veclen() const
+ {
+ return kdtree_index_->veclen();
+ }
+
+ /**
+ * \returns The amount of memory (in bytes) used by the index.
+ */
+ int usedMemory() const
+ {
+ return kmeans_index_->usedMemory() + kdtree_index_->usedMemory();
+ }
+
+ /**
+ * \brief Builds the index
+ */
+ void buildIndex()
+ {
+ Logger::info("Building kmeans tree...\n");
+ kmeans_index_->buildIndex();
+ Logger::info("Building kdtree tree...\n");
+ kdtree_index_->buildIndex();
+ }
+
+ /**
+ * \brief Saves the index to a stream
+ * \param stream The stream to save the index to
+ */
+ void saveIndex(FILE* stream)
+ {
+ kmeans_index_->saveIndex(stream);
+ kdtree_index_->saveIndex(stream);
+ }
+
+ /**
+ * \brief Loads the index from a stream
+ * \param stream The stream from which the index is loaded
+ */
+ void loadIndex(FILE* stream)
+ {
+ kmeans_index_->loadIndex(stream);
+ kdtree_index_->loadIndex(stream);
+ }
+
+ /**
+ * \returns The index parameters
+ */
+ IndexParams getParameters() const
+ {
+ return index_params_;
+ }
+
+ /**
+ * \brief Method that searches for nearest-neighbours
+ */
+ void findNeighbors(ResultSet<DistanceType>& result, const ElementType* vec, const SearchParams& searchParams)
+ {
+ kmeans_index_->findNeighbors(result, vec, searchParams);
+ kdtree_index_->findNeighbors(result, vec, searchParams);
+ }
+
+private:
+ /** The k-means index */
+ KMeansIndex<Distance>* kmeans_index_;
+
+ /** The kd-tree index */
+ KDTreeIndex<Distance>* kdtree_index_;
+
+ /** The index parameters */
+ const IndexParams index_params_;
+};
+
+}
+
+#endif //OPENCV_FLANN_COMPOSITE_INDEX_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/opencv2/flann/config.h Fri Jan 29 04:53:38 2021 +0000 @@ -0,0 +1,38 @@ +/*********************************************************************** + * Software License Agreement (BSD License) + * + * Copyright 2008-2011 Marius Muja (mariusm@cs.ubc.ca). All rights reserved. + * Copyright 2008-2011 David G. Lowe (lowe@cs.ubc.ca). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *************************************************************************/ + + +#ifndef OPENCV_FLANN_CONFIG_H_ +#define OPENCV_FLANN_CONFIG_H_ + +#ifdef FLANN_VERSION_ +#undef FLANN_VERSION_ +#endif +#define FLANN_VERSION_ "1.6.10" + +#endif /* OPENCV_FLANN_CONFIG_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/flann/defines.h Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,177 @@
+/***********************************************************************
+ * Software License Agreement (BSD License)
+ *
+ * Copyright 2008-2011 Marius Muja (mariusm@cs.ubc.ca). All rights reserved.
+ * Copyright 2008-2011 David G. Lowe (lowe@cs.ubc.ca). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *************************************************************************/
+
+
+#ifndef OPENCV_FLANN_DEFINES_H_
+#define OPENCV_FLANN_DEFINES_H_
+
+#include "config.h"
+
+#ifdef FLANN_EXPORT
+#undef FLANN_EXPORT
+#endif
+#ifdef WIN32
+/* win32 dll export/import directives */
+ #ifdef FLANN_EXPORTS
+ #define FLANN_EXPORT __declspec(dllexport)
+ #elif defined(FLANN_STATIC)
+ #define FLANN_EXPORT
+ #else
+ #define FLANN_EXPORT __declspec(dllimport)
+ #endif
+#else
+/* unix needs nothing */
+ #define FLANN_EXPORT
+#endif
+
+
+#ifdef FLANN_DEPRECATED
+#undef FLANN_DEPRECATED
+#endif
+#ifdef __GNUC__
+#define FLANN_DEPRECATED __attribute__ ((deprecated))
+#elif defined(_MSC_VER)
+#define FLANN_DEPRECATED __declspec(deprecated)
+#else
+#pragma message("WARNING: You need to implement FLANN_DEPRECATED for this compiler")
+#define FLANN_DEPRECATED
+#endif
+
+
+#undef FLANN_PLATFORM_32_BIT
+#undef FLANN_PLATFORM_64_BIT
+#if defined __amd64__ || defined __x86_64__ || defined _WIN64 || defined _M_X64
+#define FLANN_PLATFORM_64_BIT
+#else
+#define FLANN_PLATFORM_32_BIT
+#endif
+
+
+#undef FLANN_ARRAY_LEN
+#define FLANN_ARRAY_LEN(a) (sizeof(a)/sizeof(a[0]))
+
+namespace cvflann {
+
+/* Nearest neighbour index algorithms */
+enum flann_algorithm_t
+{
+ FLANN_INDEX_LINEAR = 0,
+ FLANN_INDEX_KDTREE = 1,
+ FLANN_INDEX_KMEANS = 2,
+ FLANN_INDEX_COMPOSITE = 3,
+ FLANN_INDEX_KDTREE_SINGLE = 4,
+ FLANN_INDEX_HIERARCHICAL = 5,
+ FLANN_INDEX_LSH = 6,
+ FLANN_INDEX_SAVED = 254,
+ FLANN_INDEX_AUTOTUNED = 255,
+
+ // deprecated constants, should use the FLANN_INDEX_* ones instead
+ LINEAR = 0,
+ KDTREE = 1,
+ KMEANS = 2,
+ COMPOSITE = 3,
+ KDTREE_SINGLE = 4,
+ SAVED = 254,
+ AUTOTUNED = 255
+};
+
+
+
+enum flann_centers_init_t
+{
+ FLANN_CENTERS_RANDOM = 0,
+ FLANN_CENTERS_GONZALES = 1,
+ FLANN_CENTERS_KMEANSPP = 2,
+ FLANN_CENTERS_GROUPWISE = 3,
+
+ // deprecated constants, should use the FLANN_CENTERS_* ones instead
+ CENTERS_RANDOM = 0,
+ CENTERS_GONZALES = 1,
+ CENTERS_KMEANSPP = 2
+};
+
+enum flann_log_level_t
+{
+ FLANN_LOG_NONE = 0,
+ FLANN_LOG_FATAL = 1,
+ FLANN_LOG_ERROR = 2,
+ FLANN_LOG_WARN = 3,
+ FLANN_LOG_INFO = 4
+};
+
+enum flann_distance_t
+{
+ FLANN_DIST_EUCLIDEAN = 1,
+ FLANN_DIST_L2 = 1,
+ FLANN_DIST_MANHATTAN = 2,
+ FLANN_DIST_L1 = 2,
+ FLANN_DIST_MINKOWSKI = 3,
+ FLANN_DIST_MAX = 4,
+ FLANN_DIST_HIST_INTERSECT = 5,
+ FLANN_DIST_HELLINGER = 6,
+ FLANN_DIST_CHI_SQUARE = 7,
+ FLANN_DIST_CS = 7,
+ FLANN_DIST_KULLBACK_LEIBLER = 8,
+ FLANN_DIST_KL = 8,
+ FLANN_DIST_HAMMING = 9,
+
+ // deprecated constants, should use the FLANN_DIST_* ones instead
+ EUCLIDEAN = 1,
+ MANHATTAN = 2,
+ MINKOWSKI = 3,
+ MAX_DIST = 4,
+ HIST_INTERSECT = 5,
+ HELLINGER = 6,
+ CS = 7,
+ KL = 8,
+ KULLBACK_LEIBLER = 8
+};
+
+enum flann_datatype_t
+{
+ FLANN_INT8 = 0,
+ FLANN_INT16 = 1,
+ FLANN_INT32 = 2,
+ FLANN_INT64 = 3,
+ FLANN_UINT8 = 4,
+ FLANN_UINT16 = 5,
+ FLANN_UINT32 = 6,
+ FLANN_UINT64 = 7,
+ FLANN_FLOAT32 = 8,
+ FLANN_FLOAT64 = 9
+};
+
+enum
+{
+ FLANN_CHECKS_UNLIMITED = -1,
+ FLANN_CHECKS_AUTOTUNED = -2
+};
+
+}
+
+#endif /* OPENCV_FLANN_DEFINES_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/flann/dist.h Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,905 @@
+/***********************************************************************
+ * Software License Agreement (BSD License)
+ *
+ * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved.
+ * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved.
+ *
+ * THE BSD LICENSE
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *************************************************************************/
+
+#ifndef OPENCV_FLANN_DIST_H_
+#define OPENCV_FLANN_DIST_H_
+
+#include <cmath>
+#include <cstdlib>
+#include <string.h>
+#ifdef _MSC_VER
+typedef unsigned __int32 uint32_t;
+typedef unsigned __int64 uint64_t;
+#else
+#include <stdint.h>
+#endif
+
+#include "defines.h"
+
+#if (defined WIN32 || defined _WIN32) && defined(_M_ARM)
+# include <Intrin.h>
+#endif
+
+#ifdef __ARM_NEON__
+# include "arm_neon.h"
+#endif
+
+namespace cvflann
+{
+
+template<typename T>
+inline T abs(T x) { return (x<0) ? -x : x; }
+
+template<>
+inline int abs<int>(int x) { return ::abs(x); }
+
+template<>
+inline float abs<float>(float x) { return fabsf(x); }
+
+template<>
+inline double abs<double>(double x) { return fabs(x); }
+
+template<typename T>
+struct Accumulator { typedef T Type; };
+template<>
+struct Accumulator<unsigned char> { typedef float Type; };
+template<>
+struct Accumulator<unsigned short> { typedef float Type; };
+template<>
+struct Accumulator<unsigned int> { typedef float Type; };
+template<>
+struct Accumulator<char> { typedef float Type; };
+template<>
+struct Accumulator<short> { typedef float Type; };
+template<>
+struct Accumulator<int> { typedef float Type; };
+
+#undef True
+#undef False
+
+class True
+{
+};
+
+class False
+{
+};
+
+
+/**
+ * Squared Euclidean distance functor.
+ *
+ * This is the simpler, unrolled version. This is preferable for
+ * very low dimensionality data (eg 3D points)
+ */
+template<class T>
+struct L2_Simple
+{
+ typedef True is_kdtree_distance;
+ typedef True is_vector_space_distance;
+
+ typedef T ElementType;
+ typedef typename Accumulator<T>::Type ResultType;
+
+ template <typename Iterator1, typename Iterator2>
+ ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType /*worst_dist*/ = -1) const
+ {
+ ResultType result = ResultType();
+ ResultType diff;
+ for(size_t i = 0; i < size; ++i ) {
+ diff = *a++ - *b++;
+ result += diff*diff;
+ }
+ return result;
+ }
+
+ template <typename U, typename V>
+ inline ResultType accum_dist(const U& a, const V& b, int) const
+ {
+ return (a-b)*(a-b);
+ }
+};
+
+
+
+/**
+ * Squared Euclidean distance functor, optimized version
+ */
+template<class T>
+struct L2
+{
+ typedef True is_kdtree_distance;
+ typedef True is_vector_space_distance;
+
+ typedef T ElementType;
+ typedef typename Accumulator<T>::Type ResultType;
+
+ /**
+ * Compute the squared Euclidean distance between two vectors.
+ *
+ * This is highly optimised, with loop unrolling, as it is one
+ * of the most expensive inner loops.
+ *
+ * The computation of squared root at the end is omitted for
+ * efficiency.
+ */
+ template <typename Iterator1, typename Iterator2>
+ ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType worst_dist = -1) const
+ {
+ ResultType result = ResultType();
+ ResultType diff0, diff1, diff2, diff3;
+ Iterator1 last = a + size;
+ Iterator1 lastgroup = last - 3;
+
+ /* Process 4 items with each loop for efficiency. */
+ while (a < lastgroup) {
+ diff0 = (ResultType)(a[0] - b[0]);
+ diff1 = (ResultType)(a[1] - b[1]);
+ diff2 = (ResultType)(a[2] - b[2]);
+ diff3 = (ResultType)(a[3] - b[3]);
+ result += diff0 * diff0 + diff1 * diff1 + diff2 * diff2 + diff3 * diff3;
+ a += 4;
+ b += 4;
+
+ if ((worst_dist>0)&&(result>worst_dist)) {
+ return result;
+ }
+ }
+ /* Process last 0-3 pixels. Not needed for standard vector lengths. */
+ while (a < last) {
+ diff0 = (ResultType)(*a++ - *b++);
+ result += diff0 * diff0;
+ }
+ return result;
+ }
+
+ /**
+ * Partial euclidean distance, using just one dimension. This is used by the
+ * kd-tree when computing partial distances while traversing the tree.
+ *
+ * Squared root is omitted for efficiency.
+ */
+ template <typename U, typename V>
+ inline ResultType accum_dist(const U& a, const V& b, int) const
+ {
+ return (a-b)*(a-b);
+ }
+};
+
+
+/*
+ * Manhattan distance functor, optimized version
+ */
+template<class T>
+struct L1
+{
+ typedef True is_kdtree_distance;
+ typedef True is_vector_space_distance;
+
+ typedef T ElementType;
+ typedef typename Accumulator<T>::Type ResultType;
+
+ /**
+ * Compute the Manhattan (L_1) distance between two vectors.
+ *
+ * This is highly optimised, with loop unrolling, as it is one
+ * of the most expensive inner loops.
+ */
+ template <typename Iterator1, typename Iterator2>
+ ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType worst_dist = -1) const
+ {
+ ResultType result = ResultType();
+ ResultType diff0, diff1, diff2, diff3;
+ Iterator1 last = a + size;
+ Iterator1 lastgroup = last - 3;
+
+ /* Process 4 items with each loop for efficiency. */
+ while (a < lastgroup) {
+ diff0 = (ResultType)abs(a[0] - b[0]);
+ diff1 = (ResultType)abs(a[1] - b[1]);
+ diff2 = (ResultType)abs(a[2] - b[2]);
+ diff3 = (ResultType)abs(a[3] - b[3]);
+ result += diff0 + diff1 + diff2 + diff3;
+ a += 4;
+ b += 4;
+
+ if ((worst_dist>0)&&(result>worst_dist)) {
+ return result;
+ }
+ }
+ /* Process last 0-3 pixels. Not needed for standard vector lengths. */
+ while (a < last) {
+ diff0 = (ResultType)abs(*a++ - *b++);
+ result += diff0;
+ }
+ return result;
+ }
+
+ /**
+ * Partial distance, used by the kd-tree.
+ */
+ template <typename U, typename V>
+ inline ResultType accum_dist(const U& a, const V& b, int) const
+ {
+ return abs(a-b);
+ }
+};
+
+
+
+template<class T>
+struct MinkowskiDistance
+{
+ typedef True is_kdtree_distance;
+ typedef True is_vector_space_distance;
+
+ typedef T ElementType;
+ typedef typename Accumulator<T>::Type ResultType;
+
+ int order;
+
+ MinkowskiDistance(int order_) : order(order_) {}
+
+ /**
+ * Compute the Minkowsky (L_p) distance between two vectors.
+ *
+ * This is highly optimised, with loop unrolling, as it is one
+ * of the most expensive inner loops.
+ *
+ * The computation of squared root at the end is omitted for
+ * efficiency.
+ */
+ template <typename Iterator1, typename Iterator2>
+ ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType worst_dist = -1) const
+ {
+ ResultType result = ResultType();
+ ResultType diff0, diff1, diff2, diff3;
+ Iterator1 last = a + size;
+ Iterator1 lastgroup = last - 3;
+
+ /* Process 4 items with each loop for efficiency. */
+ while (a < lastgroup) {
+ diff0 = (ResultType)abs(a[0] - b[0]);
+ diff1 = (ResultType)abs(a[1] - b[1]);
+ diff2 = (ResultType)abs(a[2] - b[2]);
+ diff3 = (ResultType)abs(a[3] - b[3]);
+ result += pow(diff0,order) + pow(diff1,order) + pow(diff2,order) + pow(diff3,order);
+ a += 4;
+ b += 4;
+
+ if ((worst_dist>0)&&(result>worst_dist)) {
+ return result;
+ }
+ }
+ /* Process last 0-3 pixels. Not needed for standard vector lengths. */
+ while (a < last) {
+ diff0 = (ResultType)abs(*a++ - *b++);
+ result += pow(diff0,order);
+ }
+ return result;
+ }
+
+ /**
+ * Partial distance, used by the kd-tree.
+ */
+ template <typename U, typename V>
+ inline ResultType accum_dist(const U& a, const V& b, int) const
+ {
+ return pow(static_cast<ResultType>(abs(a-b)),order);
+ }
+};
+
+
+
+template<class T>
+struct MaxDistance
+{
+ typedef False is_kdtree_distance;
+ typedef True is_vector_space_distance;
+
+ typedef T ElementType;
+ typedef typename Accumulator<T>::Type ResultType;
+
+ /**
+ * Compute the max distance (L_infinity) between two vectors.
+ *
+ * This distance is not a valid kdtree distance, it's not dimensionwise additive.
+ */
+ template <typename Iterator1, typename Iterator2>
+ ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType worst_dist = -1) const
+ {
+ ResultType result = ResultType();
+ ResultType diff0, diff1, diff2, diff3;
+ Iterator1 last = a + size;
+ Iterator1 lastgroup = last - 3;
+
+ /* Process 4 items with each loop for efficiency. */
+ while (a < lastgroup) {
+ diff0 = abs(a[0] - b[0]);
+ diff1 = abs(a[1] - b[1]);
+ diff2 = abs(a[2] - b[2]);
+ diff3 = abs(a[3] - b[3]);
+ if (diff0>result) {result = diff0; }
+ if (diff1>result) {result = diff1; }
+ if (diff2>result) {result = diff2; }
+ if (diff3>result) {result = diff3; }
+ a += 4;
+ b += 4;
+
+ if ((worst_dist>0)&&(result>worst_dist)) {
+ return result;
+ }
+ }
+ /* Process last 0-3 pixels. Not needed for standard vector lengths. */
+ while (a < last) {
+ diff0 = abs(*a++ - *b++);
+ result = (diff0>result) ? diff0 : result;
+ }
+ return result;
+ }
+
+ /* This distance functor is not dimension-wise additive, which
+ * makes it an invalid kd-tree distance, not implementing the accum_dist method */
+
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Hamming distance functor - counts the bit differences between two strings - useful for the Brief descriptor
+ * bit count of A exclusive XOR'ed with B
+ */
+struct HammingLUT
+{
+ typedef False is_kdtree_distance;
+ typedef False is_vector_space_distance;
+
+ typedef unsigned char ElementType;
+ typedef int ResultType;
+
+ /** this will count the bits in a ^ b
+ */
+ ResultType operator()(const unsigned char* a, const unsigned char* b, size_t size) const
+ {
+ static const uchar popCountTable[] =
+ {
+ 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+ 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
+ };
+ ResultType result = 0;
+ for (size_t i = 0; i < size; i++) {
+ result += popCountTable[a[i] ^ b[i]];
+ }
+ return result;
+ }
+};
+
+/**
+ * Hamming distance functor (pop count between two binary vectors, i.e. xor them and count the number of bits set)
+ * That code was taken from brief.cpp in OpenCV
+ */
+template<class T>
+struct Hamming
+{
+ typedef False is_kdtree_distance;
+ typedef False is_vector_space_distance;
+
+
+ typedef T ElementType;
+ typedef int ResultType;
+
+ template<typename Iterator1, typename Iterator2>
+ ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType /*worst_dist*/ = -1) const
+ {
+ ResultType result = 0;
+#ifdef __ARM_NEON__
+ {
+ uint32x4_t bits = vmovq_n_u32(0);
+ for (size_t i = 0; i < size; i += 16) {
+ uint8x16_t A_vec = vld1q_u8 (a + i);
+ uint8x16_t B_vec = vld1q_u8 (b + i);
+ uint8x16_t AxorB = veorq_u8 (A_vec, B_vec);
+ uint8x16_t bitsSet = vcntq_u8 (AxorB);
+ uint16x8_t bitSet8 = vpaddlq_u8 (bitsSet);
+ uint32x4_t bitSet4 = vpaddlq_u16 (bitSet8);
+ bits = vaddq_u32(bits, bitSet4);
+ }
+ uint64x2_t bitSet2 = vpaddlq_u32 (bits);
+ result = vgetq_lane_s32 (vreinterpretq_s32_u64(bitSet2),0);
+ result += vgetq_lane_s32 (vreinterpretq_s32_u64(bitSet2),2);
+ }
+#elif __GNUC__
+ {
+ //for portability just use unsigned long -- and use the __builtin_popcountll (see docs for __builtin_popcountll)
+ typedef unsigned long long pop_t;
+ const size_t modulo = size % sizeof(pop_t);
+ const pop_t* a2 = reinterpret_cast<const pop_t*> (a);
+ const pop_t* b2 = reinterpret_cast<const pop_t*> (b);
+ const pop_t* a2_end = a2 + (size / sizeof(pop_t));
+
+ for (; a2 != a2_end; ++a2, ++b2) result += __builtin_popcountll((*a2) ^ (*b2));
+
+ if (modulo) {
+ //in the case where size is not dividable by sizeof(size_t)
+ //need to mask off the bits at the end
+ pop_t a_final = 0, b_final = 0;
+ memcpy(&a_final, a2, modulo);
+ memcpy(&b_final, b2, modulo);
+ result += __builtin_popcountll(a_final ^ b_final);
+ }
+ }
+#else // NO NEON and NOT GNUC
+ typedef unsigned long long pop_t;
+ HammingLUT lut;
+ result = lut(reinterpret_cast<const unsigned char*> (a),
+ reinterpret_cast<const unsigned char*> (b), size * sizeof(pop_t));
+#endif
+ return result;
+ }
+};
+
+template<typename T>
+struct Hamming2
+{
+ typedef False is_kdtree_distance;
+ typedef False is_vector_space_distance;
+
+ typedef T ElementType;
+ typedef int ResultType;
+
+ /** This is popcount_3() from:
+ * http://en.wikipedia.org/wiki/Hamming_weight */
+ unsigned int popcnt32(uint32_t n) const
+ {
+ n -= ((n >> 1) & 0x55555555);
+ n = (n & 0x33333333) + ((n >> 2) & 0x33333333);
+ return (((n + (n >> 4))& 0xF0F0F0F)* 0x1010101) >> 24;
+ }
+
+#ifdef FLANN_PLATFORM_64_BIT
+ unsigned int popcnt64(uint64_t n) const
+ {
+ n -= ((n >> 1) & 0x5555555555555555);
+ n = (n & 0x3333333333333333) + ((n >> 2) & 0x3333333333333333);
+ return (((n + (n >> 4))& 0x0f0f0f0f0f0f0f0f)* 0x0101010101010101) >> 56;
+ }
+#endif
+
+ template <typename Iterator1, typename Iterator2>
+ ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType /*worst_dist*/ = -1) const
+ {
+#ifdef FLANN_PLATFORM_64_BIT
+ const uint64_t* pa = reinterpret_cast<const uint64_t*>(a);
+ const uint64_t* pb = reinterpret_cast<const uint64_t*>(b);
+ ResultType result = 0;
+ size /= (sizeof(uint64_t)/sizeof(unsigned char));
+ for(size_t i = 0; i < size; ++i ) {
+ result += popcnt64(*pa ^ *pb);
+ ++pa;
+ ++pb;
+ }
+#else
+ const uint32_t* pa = reinterpret_cast<const uint32_t*>(a);
+ const uint32_t* pb = reinterpret_cast<const uint32_t*>(b);
+ ResultType result = 0;
+ size /= (sizeof(uint32_t)/sizeof(unsigned char));
+ for(size_t i = 0; i < size; ++i ) {
+ result += popcnt32(*pa ^ *pb);
+ ++pa;
+ ++pb;
+ }
+#endif
+ return result;
+ }
+};
+
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+template<class T>
+struct HistIntersectionDistance
+{
+ typedef True is_kdtree_distance;
+ typedef True is_vector_space_distance;
+
+ typedef T ElementType;
+ typedef typename Accumulator<T>::Type ResultType;
+
+ /**
+ * Compute the histogram intersection distance
+ */
+ template <typename Iterator1, typename Iterator2>
+ ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType worst_dist = -1) const
+ {
+ ResultType result = ResultType();
+ ResultType min0, min1, min2, min3;
+ Iterator1 last = a + size;
+ Iterator1 lastgroup = last - 3;
+
+ /* Process 4 items with each loop for efficiency. */
+ while (a < lastgroup) {
+ min0 = (ResultType)(a[0] < b[0] ? a[0] : b[0]);
+ min1 = (ResultType)(a[1] < b[1] ? a[1] : b[1]);
+ min2 = (ResultType)(a[2] < b[2] ? a[2] : b[2]);
+ min3 = (ResultType)(a[3] < b[3] ? a[3] : b[3]);
+ result += min0 + min1 + min2 + min3;
+ a += 4;
+ b += 4;
+ if ((worst_dist>0)&&(result>worst_dist)) {
+ return result;
+ }
+ }
+ /* Process last 0-3 pixels. Not needed for standard vector lengths. */
+ while (a < last) {
+ min0 = (ResultType)(*a < *b ? *a : *b);
+ result += min0;
+ ++a;
+ ++b;
+ }
+ return result;
+ }
+
+ /**
+ * Partial distance, used by the kd-tree.
+ */
+ template <typename U, typename V>
+ inline ResultType accum_dist(const U& a, const V& b, int) const
+ {
+ return a<b ? a : b;
+ }
+};
+
+
+
+template<class T>
+struct HellingerDistance
+{
+ typedef True is_kdtree_distance;
+ typedef True is_vector_space_distance;
+
+ typedef T ElementType;
+ typedef typename Accumulator<T>::Type ResultType;
+
+ /**
+ * Compute the Hellinger distance
+ */
+ template <typename Iterator1, typename Iterator2>
+ ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType /*worst_dist*/ = -1) const
+ {
+ ResultType result = ResultType();
+ ResultType diff0, diff1, diff2, diff3;
+ Iterator1 last = a + size;
+ Iterator1 lastgroup = last - 3;
+
+ /* Process 4 items with each loop for efficiency. */
+ while (a < lastgroup) {
+ diff0 = sqrt(static_cast<ResultType>(a[0])) - sqrt(static_cast<ResultType>(b[0]));
+ diff1 = sqrt(static_cast<ResultType>(a[1])) - sqrt(static_cast<ResultType>(b[1]));
+ diff2 = sqrt(static_cast<ResultType>(a[2])) - sqrt(static_cast<ResultType>(b[2]));
+ diff3 = sqrt(static_cast<ResultType>(a[3])) - sqrt(static_cast<ResultType>(b[3]));
+ result += diff0 * diff0 + diff1 * diff1 + diff2 * diff2 + diff3 * diff3;
+ a += 4;
+ b += 4;
+ }
+ while (a < last) {
+ diff0 = sqrt(static_cast<ResultType>(*a++)) - sqrt(static_cast<ResultType>(*b++));
+ result += diff0 * diff0;
+ }
+ return result;
+ }
+
+ /**
+ * Partial distance, used by the kd-tree.
+ */
+ template <typename U, typename V>
+ inline ResultType accum_dist(const U& a, const V& b, int) const
+ {
+ ResultType diff = sqrt(static_cast<ResultType>(a)) - sqrt(static_cast<ResultType>(b));
+ return diff * diff;
+ }
+};
+
+
+template<class T>
+struct ChiSquareDistance
+{
+ typedef True is_kdtree_distance;
+ typedef True is_vector_space_distance;
+
+ typedef T ElementType;
+ typedef typename Accumulator<T>::Type ResultType;
+
+ /**
+ * Compute the chi-square distance
+ */
+ template <typename Iterator1, typename Iterator2>
+ ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType worst_dist = -1) const
+ {
+ ResultType result = ResultType();
+ ResultType sum, diff;
+ Iterator1 last = a + size;
+
+ while (a < last) {
+ sum = (ResultType)(*a + *b);
+ if (sum>0) {
+ diff = (ResultType)(*a - *b);
+ result += diff*diff/sum;
+ }
+ ++a;
+ ++b;
+
+ if ((worst_dist>0)&&(result>worst_dist)) {
+ return result;
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Partial distance, used by the kd-tree.
+ */
+ template <typename U, typename V>
+ inline ResultType accum_dist(const U& a, const V& b, int) const
+ {
+ ResultType result = ResultType();
+ ResultType sum, diff;
+
+ sum = (ResultType)(a+b);
+ if (sum>0) {
+ diff = (ResultType)(a-b);
+ result = diff*diff/sum;
+ }
+ return result;
+ }
+};
+
+
+template<class T>
+struct KL_Divergence
+{
+ typedef True is_kdtree_distance;
+ typedef True is_vector_space_distance;
+
+ typedef T ElementType;
+ typedef typename Accumulator<T>::Type ResultType;
+
+ /**
+ * Compute the Kullback–Leibler divergence
+ */
+ template <typename Iterator1, typename Iterator2>
+ ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType worst_dist = -1) const
+ {
+ ResultType result = ResultType();
+ Iterator1 last = a + size;
+
+ while (a < last) {
+ if (* b != 0) {
+ ResultType ratio = (ResultType)(*a / *b);
+ if (ratio>0) {
+ result += *a * log(ratio);
+ }
+ }
+ ++a;
+ ++b;
+
+ if ((worst_dist>0)&&(result>worst_dist)) {
+ return result;
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Partial distance, used by the kd-tree.
+ */
+ template <typename U, typename V>
+ inline ResultType accum_dist(const U& a, const V& b, int) const
+ {
+ ResultType result = ResultType();
+ if( *b != 0 ) {
+ ResultType ratio = (ResultType)(a / b);
+ if (ratio>0) {
+ result = a * log(ratio);
+ }
+ }
+ return result;
+ }
+};
+
+
+
+/*
+ * This is a "zero iterator". It basically behaves like a zero filled
+ * array to all algorithms that use arrays as iterators (STL style).
+ * It's useful when there's a need to compute the distance between feature
+ * and origin it and allows for better compiler optimisation than using a
+ * zero-filled array.
+ */
+template <typename T>
+struct ZeroIterator
+{
+
+ T operator*()
+ {
+ return 0;
+ }
+
+ T operator[](int)
+ {
+ return 0;
+ }
+
+ const ZeroIterator<T>& operator ++()
+ {
+ return *this;
+ }
+
+ ZeroIterator<T> operator ++(int)
+ {
+ return *this;
+ }
+
+ ZeroIterator<T>& operator+=(int)
+ {
+ return *this;
+ }
+
+};
+
+
+/*
+ * Depending on processed distances, some of them are already squared (e.g. L2)
+ * and some are not (e.g.Hamming). In KMeans++ for instance we want to be sure
+ * we are working on ^2 distances, thus following templates to ensure that.
+ */
+template <typename Distance, typename ElementType>
+struct squareDistance
+{
+ typedef typename Distance::ResultType ResultType;
+ ResultType operator()( ResultType dist ) { return dist*dist; }
+};
+
+
+template <typename ElementType>
+struct squareDistance<L2_Simple<ElementType>, ElementType>
+{
+ typedef typename L2_Simple<ElementType>::ResultType ResultType;
+ ResultType operator()( ResultType dist ) { return dist; }
+};
+
+template <typename ElementType>
+struct squareDistance<L2<ElementType>, ElementType>
+{
+ typedef typename L2<ElementType>::ResultType ResultType;
+ ResultType operator()( ResultType dist ) { return dist; }
+};
+
+
+template <typename ElementType>
+struct squareDistance<MinkowskiDistance<ElementType>, ElementType>
+{
+ typedef typename MinkowskiDistance<ElementType>::ResultType ResultType;
+ ResultType operator()( ResultType dist ) { return dist; }
+};
+
+template <typename ElementType>
+struct squareDistance<HellingerDistance<ElementType>, ElementType>
+{
+ typedef typename HellingerDistance<ElementType>::ResultType ResultType;
+ ResultType operator()( ResultType dist ) { return dist; }
+};
+
+template <typename ElementType>
+struct squareDistance<ChiSquareDistance<ElementType>, ElementType>
+{
+ typedef typename ChiSquareDistance<ElementType>::ResultType ResultType;
+ ResultType operator()( ResultType dist ) { return dist; }
+};
+
+
+template <typename Distance>
+typename Distance::ResultType ensureSquareDistance( typename Distance::ResultType dist )
+{
+ typedef typename Distance::ElementType ElementType;
+
+ squareDistance<Distance, ElementType> dummy;
+ return dummy( dist );
+}
+
+
+/*
+ * ...and a template to ensure the user that he will process the normal distance,
+ * and not squared distance, without loosing processing time calling sqrt(ensureSquareDistance)
+ * that will result in doing actually sqrt(dist*dist) for L1 distance for instance.
+ */
+template <typename Distance, typename ElementType>
+struct simpleDistance
+{
+ typedef typename Distance::ResultType ResultType;
+ ResultType operator()( ResultType dist ) { return dist; }
+};
+
+
+template <typename ElementType>
+struct simpleDistance<L2_Simple<ElementType>, ElementType>
+{
+ typedef typename L2_Simple<ElementType>::ResultType ResultType;
+ ResultType operator()( ResultType dist ) { return sqrt(dist); }
+};
+
+template <typename ElementType>
+struct simpleDistance<L2<ElementType>, ElementType>
+{
+ typedef typename L2<ElementType>::ResultType ResultType;
+ ResultType operator()( ResultType dist ) { return sqrt(dist); }
+};
+
+
+template <typename ElementType>
+struct simpleDistance<MinkowskiDistance<ElementType>, ElementType>
+{
+ typedef typename MinkowskiDistance<ElementType>::ResultType ResultType;
+ ResultType operator()( ResultType dist ) { return sqrt(dist); }
+};
+
+template <typename ElementType>
+struct simpleDistance<HellingerDistance<ElementType>, ElementType>
+{
+ typedef typename HellingerDistance<ElementType>::ResultType ResultType;
+ ResultType operator()( ResultType dist ) { return sqrt(dist); }
+};
+
+template <typename ElementType>
+struct simpleDistance<ChiSquareDistance<ElementType>, ElementType>
+{
+ typedef typename ChiSquareDistance<ElementType>::ResultType ResultType;
+ ResultType operator()( ResultType dist ) { return sqrt(dist); }
+};
+
+
+template <typename Distance>
+typename Distance::ResultType ensureSimpleDistance( typename Distance::ResultType dist )
+{
+ typedef typename Distance::ElementType ElementType;
+
+ simpleDistance<Distance, ElementType> dummy;
+ return dummy( dist );
+}
+
+}
+
+#endif //OPENCV_FLANN_DIST_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/flann/dummy.h Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,16 @@
+
+#ifndef OPENCV_FLANN_DUMMY_H_
+#define OPENCV_FLANN_DUMMY_H_
+
+namespace cvflann
+{
+
+#if (defined WIN32 || defined _WIN32 || defined WINCE) && defined CVAPI_EXPORTS
+__declspec(dllexport)
+#endif
+void dummyfunc();
+
+}
+
+
+#endif /* OPENCV_FLANN_DUMMY_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/flann/dynamic_bitset.h Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,159 @@
+/***********************************************************************
+ * Software License Agreement (BSD License)
+ *
+ * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved.
+ * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved.
+ *
+ * THE BSD LICENSE
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *************************************************************************/
+
+/***********************************************************************
+ * Author: Vincent Rabaud
+ *************************************************************************/
+
+#ifndef OPENCV_FLANN_DYNAMIC_BITSET_H_
+#define OPENCV_FLANN_DYNAMIC_BITSET_H_
+
+#ifndef FLANN_USE_BOOST
+# define FLANN_USE_BOOST 0
+#endif
+//#define FLANN_USE_BOOST 1
+#if FLANN_USE_BOOST
+#include <boost/dynamic_bitset.hpp>
+typedef boost::dynamic_bitset<> DynamicBitset;
+#else
+
+#include <limits.h>
+
+#include "dist.h"
+
+namespace cvflann {
+
+/** Class re-implementing the boost version of it
+ * This helps not depending on boost, it also does not do the bound checks
+ * and has a way to reset a block for speed
+ */
+class DynamicBitset
+{
+public:
+ /** default constructor
+ */
+ DynamicBitset()
+ {
+ }
+
+ /** only constructor we use in our code
+ * @param sz the size of the bitset (in bits)
+ */
+ DynamicBitset(size_t sz)
+ {
+ resize(sz);
+ reset();
+ }
+
+ /** Sets all the bits to 0
+ */
+ void clear()
+ {
+ std::fill(bitset_.begin(), bitset_.end(), 0);
+ }
+
+ /** @brief checks if the bitset is empty
+ * @return true if the bitset is empty
+ */
+ bool empty() const
+ {
+ return bitset_.empty();
+ }
+
+ /** set all the bits to 0
+ */
+ void reset()
+ {
+ std::fill(bitset_.begin(), bitset_.end(), 0);
+ }
+
+ /** @brief set one bit to 0
+ * @param index
+ */
+ void reset(size_t index)
+ {
+ bitset_[index / cell_bit_size_] &= ~(size_t(1) << (index % cell_bit_size_));
+ }
+
+ /** @brief sets a specific bit to 0, and more bits too
+ * This function is useful when resetting a given set of bits so that the
+ * whole bitset ends up being 0: if that's the case, we don't care about setting
+ * other bits to 0
+ * @param index
+ */
+ void reset_block(size_t index)
+ {
+ bitset_[index / cell_bit_size_] = 0;
+ }
+
+ /** resize the bitset so that it contains at least sz bits
+ * @param sz
+ */
+ void resize(size_t sz)
+ {
+ size_ = sz;
+ bitset_.resize(sz / cell_bit_size_ + 1);
+ }
+
+ /** set a bit to true
+ * @param index the index of the bit to set to 1
+ */
+ void set(size_t index)
+ {
+ bitset_[index / cell_bit_size_] |= size_t(1) << (index % cell_bit_size_);
+ }
+
+ /** gives the number of contained bits
+ */
+ size_t size() const
+ {
+ return size_;
+ }
+
+ /** check if a bit is set
+ * @param index the index of the bit to check
+ * @return true if the bit is set
+ */
+ bool test(size_t index) const
+ {
+ return (bitset_[index / cell_bit_size_] & (size_t(1) << (index % cell_bit_size_))) != 0;
+ }
+
+private:
+ std::vector<size_t> bitset_;
+ size_t size_;
+ static const unsigned int cell_bit_size_ = CHAR_BIT * sizeof(size_t);
+};
+
+} // namespace cvflann
+
+#endif
+
+#endif // OPENCV_FLANN_DYNAMIC_BITSET_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/opencv2/flann/flann.hpp Fri Jan 29 04:53:38 2021 +0000 @@ -0,0 +1,48 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifdef __OPENCV_BUILD +#error this is a compatibility header which should not be used inside the OpenCV library +#endif + +#include "opencv2/flann.hpp"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/flann/flann_base.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,290 @@
+/***********************************************************************
+ * Software License Agreement (BSD License)
+ *
+ * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved.
+ * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved.
+ *
+ * THE BSD LICENSE
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *************************************************************************/
+
+#ifndef OPENCV_FLANN_BASE_HPP_
+#define OPENCV_FLANN_BASE_HPP_
+
+#include <vector>
+#include <cassert>
+#include <cstdio>
+
+#include "general.h"
+#include "matrix.h"
+#include "params.h"
+#include "saving.h"
+
+#include "all_indices.h"
+
+namespace cvflann
+{
+
+/**
+ * Sets the log level used for all flann functions
+ * @param level Verbosity level
+ */
+inline void log_verbosity(int level)
+{
+ if (level >= 0) {
+ Logger::setLevel(level);
+ }
+}
+
+/**
+ * (Deprecated) Index parameters for creating a saved index.
+ */
+struct SavedIndexParams : public IndexParams
+{
+ SavedIndexParams(cv::String filename)
+ {
+ (* this)["algorithm"] = FLANN_INDEX_SAVED;
+ (*this)["filename"] = filename;
+ }
+};
+
+
+template<typename Distance>
+NNIndex<Distance>* load_saved_index(const Matrix<typename Distance::ElementType>& dataset, const cv::String& filename, Distance distance)
+{
+ typedef typename Distance::ElementType ElementType;
+
+ FILE* fin = fopen(filename.c_str(), "rb");
+ if (fin == NULL) {
+ return NULL;
+ }
+ IndexHeader header = load_header(fin);
+ if (header.data_type != Datatype<ElementType>::type()) {
+ throw FLANNException("Datatype of saved index is different than of the one to be created.");
+ }
+ if ((size_t(header.rows) != dataset.rows)||(size_t(header.cols) != dataset.cols)) {
+ throw FLANNException("The index saved belongs to a different dataset");
+ }
+
+ IndexParams params;
+ params["algorithm"] = header.index_type;
+ NNIndex<Distance>* nnIndex = create_index_by_type<Distance>(dataset, params, distance);
+ nnIndex->loadIndex(fin);
+ fclose(fin);
+
+ return nnIndex;
+}
+
+
+template<typename Distance>
+class Index : public NNIndex<Distance>
+{
+public:
+ typedef typename Distance::ElementType ElementType;
+ typedef typename Distance::ResultType DistanceType;
+
+ Index(const Matrix<ElementType>& features, const IndexParams& params, Distance distance = Distance() )
+ : index_params_(params)
+ {
+ flann_algorithm_t index_type = get_param<flann_algorithm_t>(params,"algorithm");
+ loaded_ = false;
+
+ if (index_type == FLANN_INDEX_SAVED) {
+ nnIndex_ = load_saved_index<Distance>(features, get_param<cv::String>(params,"filename"), distance);
+ loaded_ = true;
+ }
+ else {
+ nnIndex_ = create_index_by_type<Distance>(features, params, distance);
+ }
+ }
+
+ ~Index()
+ {
+ delete nnIndex_;
+ }
+
+ /**
+ * Builds the index.
+ */
+ void buildIndex()
+ {
+ if (!loaded_) {
+ nnIndex_->buildIndex();
+ }
+ }
+
+ void save(cv::String filename)
+ {
+ FILE* fout = fopen(filename.c_str(), "wb");
+ if (fout == NULL) {
+ throw FLANNException("Cannot open file");
+ }
+ save_header(fout, *nnIndex_);
+ saveIndex(fout);
+ fclose(fout);
+ }
+
+ /**
+ * \brief Saves the index to a stream
+ * \param stream The stream to save the index to
+ */
+ virtual void saveIndex(FILE* stream)
+ {
+ nnIndex_->saveIndex(stream);
+ }
+
+ /**
+ * \brief Loads the index from a stream
+ * \param stream The stream from which the index is loaded
+ */
+ virtual void loadIndex(FILE* stream)
+ {
+ nnIndex_->loadIndex(stream);
+ }
+
+ /**
+ * \returns number of features in this index.
+ */
+ size_t veclen() const
+ {
+ return nnIndex_->veclen();
+ }
+
+ /**
+ * \returns The dimensionality of the features in this index.
+ */
+ size_t size() const
+ {
+ return nnIndex_->size();
+ }
+
+ /**
+ * \returns The index type (kdtree, kmeans,...)
+ */
+ flann_algorithm_t getType() const
+ {
+ return nnIndex_->getType();
+ }
+
+ /**
+ * \returns The amount of memory (in bytes) used by the index.
+ */
+ virtual int usedMemory() const
+ {
+ return nnIndex_->usedMemory();
+ }
+
+
+ /**
+ * \returns The index parameters
+ */
+ IndexParams getParameters() const
+ {
+ return nnIndex_->getParameters();
+ }
+
+ /**
+ * \brief Perform k-nearest neighbor search
+ * \param[in] queries The query points for which to find the nearest neighbors
+ * \param[out] indices The indices of the nearest neighbors found
+ * \param[out] dists Distances to the nearest neighbors found
+ * \param[in] knn Number of nearest neighbors to return
+ * \param[in] params Search parameters
+ */
+ void knnSearch(const Matrix<ElementType>& queries, Matrix<int>& indices, Matrix<DistanceType>& dists, int knn, const SearchParams& params)
+ {
+ nnIndex_->knnSearch(queries, indices, dists, knn, params);
+ }
+
+ /**
+ * \brief Perform radius search
+ * \param[in] query The query point
+ * \param[out] indices The indinces of the neighbors found within the given radius
+ * \param[out] dists The distances to the nearest neighbors found
+ * \param[in] radius The radius used for search
+ * \param[in] params Search parameters
+ * \returns Number of neighbors found
+ */
+ int radiusSearch(const Matrix<ElementType>& query, Matrix<int>& indices, Matrix<DistanceType>& dists, float radius, const SearchParams& params)
+ {
+ return nnIndex_->radiusSearch(query, indices, dists, radius, params);
+ }
+
+ /**
+ * \brief Method that searches for nearest-neighbours
+ */
+ void findNeighbors(ResultSet<DistanceType>& result, const ElementType* vec, const SearchParams& searchParams)
+ {
+ nnIndex_->findNeighbors(result, vec, searchParams);
+ }
+
+ /**
+ * \brief Returns actual index
+ */
+ FLANN_DEPRECATED NNIndex<Distance>* getIndex()
+ {
+ return nnIndex_;
+ }
+
+ /**
+ * \brief Returns index parameters.
+ * \deprecated use getParameters() instead.
+ */
+ FLANN_DEPRECATED const IndexParams* getIndexParameters()
+ {
+ return &index_params_;
+ }
+
+private:
+ /** Pointer to actual index class */
+ NNIndex<Distance>* nnIndex_;
+ /** Indices if the index was loaded from a file */
+ bool loaded_;
+ /** Parameters passed to the index */
+ IndexParams index_params_;
+};
+
+/**
+ * Performs a hierarchical clustering of the points passed as argument and then takes a cut in the
+ * the clustering tree to return a flat clustering.
+ * @param[in] points Points to be clustered
+ * @param centers The computed cluster centres. Matrix should be preallocated and centers.rows is the
+ * number of clusters requested.
+ * @param params Clustering parameters (The same as for cvflann::KMeansIndex)
+ * @param d Distance to be used for clustering (eg: cvflann::L2)
+ * @return number of clusters computed (can be different than clusters.rows and is the highest number
+ * of the form (branching-1)*K+1 smaller than clusters.rows).
+ */
+template <typename Distance>
+int hierarchicalClustering(const Matrix<typename Distance::ElementType>& points, Matrix<typename Distance::ResultType>& centers,
+ const KMeansIndexParams& params, Distance d = Distance())
+{
+ KMeansIndex<Distance> kmeans(points, params, d);
+ kmeans.buildIndex();
+
+ int clusterNum = kmeans.getClusterCenters(centers);
+ return clusterNum;
+}
+
+}
+#endif /* OPENCV_FLANN_BASE_HPP_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/flann/general.h Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,50 @@
+/***********************************************************************
+ * Software License Agreement (BSD License)
+ *
+ * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved.
+ * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved.
+ *
+ * THE BSD LICENSE
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *************************************************************************/
+
+#ifndef OPENCV_FLANN_GENERAL_H_
+#define OPENCV_FLANN_GENERAL_H_
+
+#include "opencv2/core.hpp"
+
+namespace cvflann
+{
+
+class FLANNException : public cv::Exception
+{
+public:
+ FLANNException(const char* message) : cv::Exception(0, message, "", __FILE__, __LINE__) { }
+
+ FLANNException(const cv::String& message) : cv::Exception(0, message, "", __FILE__, __LINE__) { }
+};
+
+}
+
+
+#endif /* OPENCV_FLANN_GENERAL_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/flann/ground_truth.h Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,94 @@
+/***********************************************************************
+ * Software License Agreement (BSD License)
+ *
+ * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved.
+ * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved.
+ *
+ * THE BSD LICENSE
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *************************************************************************/
+
+#ifndef OPENCV_FLANN_GROUND_TRUTH_H_
+#define OPENCV_FLANN_GROUND_TRUTH_H_
+
+#include "dist.h"
+#include "matrix.h"
+
+
+namespace cvflann
+{
+
+template <typename Distance>
+void find_nearest(const Matrix<typename Distance::ElementType>& dataset, typename Distance::ElementType* query, int* matches, int nn,
+ int skip = 0, Distance distance = Distance())
+{
+ typedef typename Distance::ResultType DistanceType;
+ int n = nn + skip;
+
+ std::vector<int> match(n);
+ std::vector<DistanceType> dists(n);
+
+ dists[0] = distance(dataset[0], query, dataset.cols);
+ match[0] = 0;
+ int dcnt = 1;
+
+ for (size_t i=1; i<dataset.rows; ++i) {
+ DistanceType tmp = distance(dataset[i], query, dataset.cols);
+
+ if (dcnt<n) {
+ match[dcnt] = (int)i;
+ dists[dcnt++] = tmp;
+ }
+ else if (tmp < dists[dcnt-1]) {
+ dists[dcnt-1] = tmp;
+ match[dcnt-1] = (int)i;
+ }
+
+ int j = dcnt-1;
+ // bubble up
+ while (j>=1 && dists[j]<dists[j-1]) {
+ std::swap(dists[j],dists[j-1]);
+ std::swap(match[j],match[j-1]);
+ j--;
+ }
+ }
+
+ for (int i=0; i<nn; ++i) {
+ matches[i] = match[i+skip];
+ }
+}
+
+
+template <typename Distance>
+void compute_ground_truth(const Matrix<typename Distance::ElementType>& dataset, const Matrix<typename Distance::ElementType>& testset, Matrix<int>& matches,
+ int skip=0, Distance d = Distance())
+{
+ for (size_t i=0; i<testset.rows; ++i) {
+ find_nearest<Distance>(dataset, testset[i], matches[i], (int)matches.cols, skip, d);
+ }
+}
+
+
+}
+
+#endif //OPENCV_FLANN_GROUND_TRUTH_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/flann/hdf5.h Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,231 @@
+/***********************************************************************
+ * Software License Agreement (BSD License)
+ *
+ * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved.
+ * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *************************************************************************/
+
+
+#ifndef OPENCV_FLANN_HDF5_H_
+#define OPENCV_FLANN_HDF5_H_
+
+#include <hdf5.h>
+
+#include "matrix.h"
+
+
+namespace cvflann
+{
+
+namespace
+{
+
+template<typename T>
+hid_t get_hdf5_type()
+{
+ throw FLANNException("Unsupported type for IO operations");
+}
+
+template<>
+hid_t get_hdf5_type<char>() { return H5T_NATIVE_CHAR; }
+template<>
+hid_t get_hdf5_type<unsigned char>() { return H5T_NATIVE_UCHAR; }
+template<>
+hid_t get_hdf5_type<short int>() { return H5T_NATIVE_SHORT; }
+template<>
+hid_t get_hdf5_type<unsigned short int>() { return H5T_NATIVE_USHORT; }
+template<>
+hid_t get_hdf5_type<int>() { return H5T_NATIVE_INT; }
+template<>
+hid_t get_hdf5_type<unsigned int>() { return H5T_NATIVE_UINT; }
+template<>
+hid_t get_hdf5_type<long>() { return H5T_NATIVE_LONG; }
+template<>
+hid_t get_hdf5_type<unsigned long>() { return H5T_NATIVE_ULONG; }
+template<>
+hid_t get_hdf5_type<float>() { return H5T_NATIVE_FLOAT; }
+template<>
+hid_t get_hdf5_type<double>() { return H5T_NATIVE_DOUBLE; }
+}
+
+
+#define CHECK_ERROR(x,y) if ((x)<0) throw FLANNException((y));
+
+template<typename T>
+void save_to_file(const cvflann::Matrix<T>& dataset, const String& filename, const String& name)
+{
+
+#if H5Eset_auto_vers == 2
+ H5Eset_auto( H5E_DEFAULT, NULL, NULL );
+#else
+ H5Eset_auto( NULL, NULL );
+#endif
+
+ herr_t status;
+ hid_t file_id;
+ file_id = H5Fopen(filename.c_str(), H5F_ACC_RDWR, H5P_DEFAULT);
+ if (file_id < 0) {
+ file_id = H5Fcreate(filename.c_str(), H5F_ACC_EXCL, H5P_DEFAULT, H5P_DEFAULT);
+ }
+ CHECK_ERROR(file_id,"Error creating hdf5 file.");
+
+ hsize_t dimsf[2]; // dataset dimensions
+ dimsf[0] = dataset.rows;
+ dimsf[1] = dataset.cols;
+
+ hid_t space_id = H5Screate_simple(2, dimsf, NULL);
+ hid_t memspace_id = H5Screate_simple(2, dimsf, NULL);
+
+ hid_t dataset_id;
+#if H5Dcreate_vers == 2
+ dataset_id = H5Dcreate2(file_id, name.c_str(), get_hdf5_type<T>(), space_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
+#else
+ dataset_id = H5Dcreate(file_id, name.c_str(), get_hdf5_type<T>(), space_id, H5P_DEFAULT);
+#endif
+
+ if (dataset_id<0) {
+#if H5Dopen_vers == 2
+ dataset_id = H5Dopen2(file_id, name.c_str(), H5P_DEFAULT);
+#else
+ dataset_id = H5Dopen(file_id, name.c_str());
+#endif
+ }
+ CHECK_ERROR(dataset_id,"Error creating or opening dataset in file.");
+
+ status = H5Dwrite(dataset_id, get_hdf5_type<T>(), memspace_id, space_id, H5P_DEFAULT, dataset.data );
+ CHECK_ERROR(status, "Error writing to dataset");
+
+ H5Sclose(memspace_id);
+ H5Sclose(space_id);
+ H5Dclose(dataset_id);
+ H5Fclose(file_id);
+
+}
+
+
+template<typename T>
+void load_from_file(cvflann::Matrix<T>& dataset, const String& filename, const String& name)
+{
+ herr_t status;
+ hid_t file_id = H5Fopen(filename.c_str(), H5F_ACC_RDWR, H5P_DEFAULT);
+ CHECK_ERROR(file_id,"Error opening hdf5 file.");
+
+ hid_t dataset_id;
+#if H5Dopen_vers == 2
+ dataset_id = H5Dopen2(file_id, name.c_str(), H5P_DEFAULT);
+#else
+ dataset_id = H5Dopen(file_id, name.c_str());
+#endif
+ CHECK_ERROR(dataset_id,"Error opening dataset in file.");
+
+ hid_t space_id = H5Dget_space(dataset_id);
+
+ hsize_t dims_out[2];
+ H5Sget_simple_extent_dims(space_id, dims_out, NULL);
+
+ dataset = cvflann::Matrix<T>(new T[dims_out[0]*dims_out[1]], dims_out[0], dims_out[1]);
+
+ status = H5Dread(dataset_id, get_hdf5_type<T>(), H5S_ALL, H5S_ALL, H5P_DEFAULT, dataset[0]);
+ CHECK_ERROR(status, "Error reading dataset");
+
+ H5Sclose(space_id);
+ H5Dclose(dataset_id);
+ H5Fclose(file_id);
+}
+
+
+#ifdef HAVE_MPI
+
+namespace mpi
+{
+/**
+ * Loads a the hyperslice corresponding to this processor from a hdf5 file.
+ * @param flann_dataset Dataset where the data is loaded
+ * @param filename HDF5 file name
+ * @param name Name of dataset inside file
+ */
+template<typename T>
+void load_from_file(cvflann::Matrix<T>& dataset, const String& filename, const String& name)
+{
+ MPI_Comm comm = MPI_COMM_WORLD;
+ MPI_Info info = MPI_INFO_NULL;
+
+ int mpi_size, mpi_rank;
+ MPI_Comm_size(comm, &mpi_size);
+ MPI_Comm_rank(comm, &mpi_rank);
+
+ herr_t status;
+
+ hid_t plist_id = H5Pcreate(H5P_FILE_ACCESS);
+ H5Pset_fapl_mpio(plist_id, comm, info);
+ hid_t file_id = H5Fopen(filename.c_str(), H5F_ACC_RDWR, plist_id);
+ CHECK_ERROR(file_id,"Error opening hdf5 file.");
+ H5Pclose(plist_id);
+ hid_t dataset_id;
+#if H5Dopen_vers == 2
+ dataset_id = H5Dopen2(file_id, name.c_str(), H5P_DEFAULT);
+#else
+ dataset_id = H5Dopen(file_id, name.c_str());
+#endif
+ CHECK_ERROR(dataset_id,"Error opening dataset in file.");
+
+ hid_t space_id = H5Dget_space(dataset_id);
+ hsize_t dims[2];
+ H5Sget_simple_extent_dims(space_id, dims, NULL);
+
+ hsize_t count[2];
+ hsize_t offset[2];
+
+ hsize_t item_cnt = dims[0]/mpi_size+(dims[0]%mpi_size==0 ? 0 : 1);
+ hsize_t cnt = (mpi_rank<mpi_size-1 ? item_cnt : dims[0]-item_cnt*(mpi_size-1));
+
+ count[0] = cnt;
+ count[1] = dims[1];
+ offset[0] = mpi_rank*item_cnt;
+ offset[1] = 0;
+
+ hid_t memspace_id = H5Screate_simple(2,count,NULL);
+
+ H5Sselect_hyperslab(space_id, H5S_SELECT_SET, offset, NULL, count, NULL);
+
+ dataset.rows = count[0];
+ dataset.cols = count[1];
+ dataset.data = new T[dataset.rows*dataset.cols];
+
+ plist_id = H5Pcreate(H5P_DATASET_XFER);
+ H5Pset_dxpl_mpio(plist_id, H5FD_MPIO_COLLECTIVE);
+ status = H5Dread(dataset_id, get_hdf5_type<T>(), memspace_id, space_id, plist_id, dataset.data);
+ CHECK_ERROR(status, "Error reading dataset");
+
+ H5Pclose(plist_id);
+ H5Sclose(space_id);
+ H5Sclose(memspace_id);
+ H5Dclose(dataset_id);
+ H5Fclose(file_id);
+}
+}
+#endif // HAVE_MPI
+} // namespace cvflann::mpi
+
+#endif /* OPENCV_FLANN_HDF5_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/flann/heap.h Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,165 @@
+/***********************************************************************
+ * Software License Agreement (BSD License)
+ *
+ * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved.
+ * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved.
+ *
+ * THE BSD LICENSE
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *************************************************************************/
+
+#ifndef OPENCV_FLANN_HEAP_H_
+#define OPENCV_FLANN_HEAP_H_
+
+#include <algorithm>
+#include <vector>
+
+namespace cvflann
+{
+
+/**
+ * Priority Queue Implementation
+ *
+ * The priority queue is implemented with a heap. A heap is a complete
+ * (full) binary tree in which each parent is less than both of its
+ * children, but the order of the children is unspecified.
+ */
+template <typename T>
+class Heap
+{
+
+ /**
+ * Storage array for the heap.
+ * Type T must be comparable.
+ */
+ std::vector<T> heap;
+ int length;
+
+ /**
+ * Number of element in the heap
+ */
+ int count;
+
+
+
+public:
+ /**
+ * Constructor.
+ *
+ * Params:
+ * sz = heap size
+ */
+
+ Heap(int sz)
+ {
+ length = sz;
+ heap.reserve(length);
+ count = 0;
+ }
+
+ /**
+ *
+ * Returns: heap size
+ */
+ int size()
+ {
+ return count;
+ }
+
+ /**
+ * Tests if the heap is empty
+ *
+ * Returns: true is heap empty, false otherwise
+ */
+ bool empty()
+ {
+ return size()==0;
+ }
+
+ /**
+ * Clears the heap.
+ */
+ void clear()
+ {
+ heap.clear();
+ count = 0;
+ }
+
+ struct CompareT
+ {
+ bool operator()(const T& t_1, const T& t_2) const
+ {
+ return t_2 < t_1;
+ }
+ };
+
+ /**
+ * Insert a new element in the heap.
+ *
+ * We select the next empty leaf node, and then keep moving any larger
+ * parents down until the right location is found to store this element.
+ *
+ * Params:
+ * value = the new element to be inserted in the heap
+ */
+ void insert(T value)
+ {
+ /* If heap is full, then return without adding this element. */
+ if (count == length) {
+ return;
+ }
+
+ heap.push_back(value);
+ static CompareT compareT;
+ std::push_heap(heap.begin(), heap.end(), compareT);
+ ++count;
+ }
+
+
+
+ /**
+ * Returns the node of minimum value from the heap (top of the heap).
+ *
+ * Params:
+ * value = out parameter used to return the min element
+ * Returns: false if heap empty
+ */
+ bool popMin(T& value)
+ {
+ if (count == 0) {
+ return false;
+ }
+
+ value = heap[0];
+ static CompareT compareT;
+ std::pop_heap(heap.begin(), heap.end(), compareT);
+ heap.pop_back();
+ --count;
+
+ return true; /* Return old last node. */
+ }
+};
+
+}
+
+#endif //OPENCV_FLANN_HEAP_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/flann/hierarchical_clustering_index.h Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,848 @@
+/***********************************************************************
+ * Software License Agreement (BSD License)
+ *
+ * Copyright 2008-2011 Marius Muja (mariusm@cs.ubc.ca). All rights reserved.
+ * Copyright 2008-2011 David G. Lowe (lowe@cs.ubc.ca). All rights reserved.
+ *
+ * THE BSD LICENSE
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *************************************************************************/
+
+#ifndef OPENCV_FLANN_HIERARCHICAL_CLUSTERING_INDEX_H_
+#define OPENCV_FLANN_HIERARCHICAL_CLUSTERING_INDEX_H_
+
+#include <algorithm>
+#include <map>
+#include <cassert>
+#include <limits>
+#include <cmath>
+
+#include "general.h"
+#include "nn_index.h"
+#include "dist.h"
+#include "matrix.h"
+#include "result_set.h"
+#include "heap.h"
+#include "allocator.h"
+#include "random.h"
+#include "saving.h"
+
+
+namespace cvflann
+{
+
+struct HierarchicalClusteringIndexParams : public IndexParams
+{
+ HierarchicalClusteringIndexParams(int branching = 32,
+ flann_centers_init_t centers_init = FLANN_CENTERS_RANDOM,
+ int trees = 4, int leaf_size = 100)
+ {
+ (*this)["algorithm"] = FLANN_INDEX_HIERARCHICAL;
+ // The branching factor used in the hierarchical clustering
+ (*this)["branching"] = branching;
+ // Algorithm used for picking the initial cluster centers
+ (*this)["centers_init"] = centers_init;
+ // number of parallel trees to build
+ (*this)["trees"] = trees;
+ // maximum leaf size
+ (*this)["leaf_size"] = leaf_size;
+ }
+};
+
+
+/**
+ * Hierarchical index
+ *
+ * Contains a tree constructed through a hierarchical clustering
+ * and other information for indexing a set of points for nearest-neighbour matching.
+ */
+template <typename Distance>
+class HierarchicalClusteringIndex : public NNIndex<Distance>
+{
+public:
+ typedef typename Distance::ElementType ElementType;
+ typedef typename Distance::ResultType DistanceType;
+
+private:
+
+
+ typedef void (HierarchicalClusteringIndex::* centersAlgFunction)(int, int*, int, int*, int&);
+
+ /**
+ * The function used for choosing the cluster centers.
+ */
+ centersAlgFunction chooseCenters;
+
+
+
+ /**
+ * Chooses the initial centers in the k-means clustering in a random manner.
+ *
+ * Params:
+ * k = number of centers
+ * vecs = the dataset of points
+ * indices = indices in the dataset
+ * indices_length = length of indices vector
+ *
+ */
+ void chooseCentersRandom(int k, int* dsindices, int indices_length, int* centers, int& centers_length)
+ {
+ UniqueRandom r(indices_length);
+
+ int index;
+ for (index=0; index<k; ++index) {
+ bool duplicate = true;
+ int rnd;
+ while (duplicate) {
+ duplicate = false;
+ rnd = r.next();
+ if (rnd<0) {
+ centers_length = index;
+ return;
+ }
+
+ centers[index] = dsindices[rnd];
+
+ for (int j=0; j<index; ++j) {
+ DistanceType sq = distance(dataset[centers[index]], dataset[centers[j]], dataset.cols);
+ if (sq<1e-16) {
+ duplicate = true;
+ }
+ }
+ }
+ }
+
+ centers_length = index;
+ }
+
+
+ /**
+ * Chooses the initial centers in the k-means using Gonzales' algorithm
+ * so that the centers are spaced apart from each other.
+ *
+ * Params:
+ * k = number of centers
+ * vecs = the dataset of points
+ * indices = indices in the dataset
+ * Returns:
+ */
+ void chooseCentersGonzales(int k, int* dsindices, int indices_length, int* centers, int& centers_length)
+ {
+ int n = indices_length;
+
+ int rnd = rand_int(n);
+ assert(rnd >=0 && rnd < n);
+
+ centers[0] = dsindices[rnd];
+
+ int index;
+ for (index=1; index<k; ++index) {
+
+ int best_index = -1;
+ DistanceType best_val = 0;
+ for (int j=0; j<n; ++j) {
+ DistanceType dist = distance(dataset[centers[0]],dataset[dsindices[j]],dataset.cols);
+ for (int i=1; i<index; ++i) {
+ DistanceType tmp_dist = distance(dataset[centers[i]],dataset[dsindices[j]],dataset.cols);
+ if (tmp_dist<dist) {
+ dist = tmp_dist;
+ }
+ }
+ if (dist>best_val) {
+ best_val = dist;
+ best_index = j;
+ }
+ }
+ if (best_index!=-1) {
+ centers[index] = dsindices[best_index];
+ }
+ else {
+ break;
+ }
+ }
+ centers_length = index;
+ }
+
+
+ /**
+ * Chooses the initial centers in the k-means using the algorithm
+ * proposed in the KMeans++ paper:
+ * Arthur, David; Vassilvitskii, Sergei - k-means++: The Advantages of Careful Seeding
+ *
+ * Implementation of this function was converted from the one provided in Arthur's code.
+ *
+ * Params:
+ * k = number of centers
+ * vecs = the dataset of points
+ * indices = indices in the dataset
+ * Returns:
+ */
+ void chooseCentersKMeanspp(int k, int* dsindices, int indices_length, int* centers, int& centers_length)
+ {
+ int n = indices_length;
+
+ double currentPot = 0;
+ DistanceType* closestDistSq = new DistanceType[n];
+
+ // Choose one random center and set the closestDistSq values
+ int index = rand_int(n);
+ assert(index >=0 && index < n);
+ centers[0] = dsindices[index];
+
+ // Computing distance^2 will have the advantage of even higher probability further to pick new centers
+ // far from previous centers (and this complies to "k-means++: the advantages of careful seeding" article)
+ for (int i = 0; i < n; i++) {
+ closestDistSq[i] = distance(dataset[dsindices[i]], dataset[dsindices[index]], dataset.cols);
+ closestDistSq[i] = ensureSquareDistance<Distance>( closestDistSq[i] );
+ currentPot += closestDistSq[i];
+ }
+
+
+ const int numLocalTries = 1;
+
+ // Choose each center
+ int centerCount;
+ for (centerCount = 1; centerCount < k; centerCount++) {
+
+ // Repeat several trials
+ double bestNewPot = -1;
+ int bestNewIndex = 0;
+ for (int localTrial = 0; localTrial < numLocalTries; localTrial++) {
+
+ // Choose our center - have to be slightly careful to return a valid answer even accounting
+ // for possible rounding errors
+ double randVal = rand_double(currentPot);
+ for (index = 0; index < n-1; index++) {
+ if (randVal <= closestDistSq[index]) break;
+ else randVal -= closestDistSq[index];
+ }
+
+ // Compute the new potential
+ double newPot = 0;
+ for (int i = 0; i < n; i++) {
+ DistanceType dist = distance(dataset[dsindices[i]], dataset[dsindices[index]], dataset.cols);
+ newPot += std::min( ensureSquareDistance<Distance>(dist), closestDistSq[i] );
+ }
+
+ // Store the best result
+ if ((bestNewPot < 0)||(newPot < bestNewPot)) {
+ bestNewPot = newPot;
+ bestNewIndex = index;
+ }
+ }
+
+ // Add the appropriate center
+ centers[centerCount] = dsindices[bestNewIndex];
+ currentPot = bestNewPot;
+ for (int i = 0; i < n; i++) {
+ DistanceType dist = distance(dataset[dsindices[i]], dataset[dsindices[bestNewIndex]], dataset.cols);
+ closestDistSq[i] = std::min( ensureSquareDistance<Distance>(dist), closestDistSq[i] );
+ }
+ }
+
+ centers_length = centerCount;
+
+ delete[] closestDistSq;
+ }
+
+
+ /**
+ * Chooses the initial centers in a way inspired by Gonzales (by Pierre-Emmanuel Viel):
+ * select the first point of the list as a candidate, then parse the points list. If another
+ * point is further than current candidate from the other centers, test if it is a good center
+ * of a local aggregation. If it is, replace current candidate by this point. And so on...
+ *
+ * Used with KMeansIndex that computes centers coordinates by averaging positions of clusters points,
+ * this doesn't make a real difference with previous methods. But used with HierarchicalClusteringIndex
+ * class that pick centers among existing points instead of computing the barycenters, there is a real
+ * improvement.
+ *
+ * Params:
+ * k = number of centers
+ * vecs = the dataset of points
+ * indices = indices in the dataset
+ * Returns:
+ */
+ void GroupWiseCenterChooser(int k, int* dsindices, int indices_length, int* centers, int& centers_length)
+ {
+ const float kSpeedUpFactor = 1.3f;
+
+ int n = indices_length;
+
+ DistanceType* closestDistSq = new DistanceType[n];
+
+ // Choose one random center and set the closestDistSq values
+ int index = rand_int(n);
+ assert(index >=0 && index < n);
+ centers[0] = dsindices[index];
+
+ for (int i = 0; i < n; i++) {
+ closestDistSq[i] = distance(dataset[dsindices[i]], dataset[dsindices[index]], dataset.cols);
+ }
+
+
+ // Choose each center
+ int centerCount;
+ for (centerCount = 1; centerCount < k; centerCount++) {
+
+ // Repeat several trials
+ double bestNewPot = -1;
+ int bestNewIndex = 0;
+ DistanceType furthest = 0;
+ for (index = 0; index < n; index++) {
+
+ // We will test only the potential of the points further than current candidate
+ if( closestDistSq[index] > kSpeedUpFactor * (float)furthest ) {
+
+ // Compute the new potential
+ double newPot = 0;
+ for (int i = 0; i < n; i++) {
+ newPot += std::min( distance(dataset[dsindices[i]], dataset[dsindices[index]], dataset.cols)
+ , closestDistSq[i] );
+ }
+
+ // Store the best result
+ if ((bestNewPot < 0)||(newPot <= bestNewPot)) {
+ bestNewPot = newPot;
+ bestNewIndex = index;
+ furthest = closestDistSq[index];
+ }
+ }
+ }
+
+ // Add the appropriate center
+ centers[centerCount] = dsindices[bestNewIndex];
+ for (int i = 0; i < n; i++) {
+ closestDistSq[i] = std::min( distance(dataset[dsindices[i]], dataset[dsindices[bestNewIndex]], dataset.cols)
+ , closestDistSq[i] );
+ }
+ }
+
+ centers_length = centerCount;
+
+ delete[] closestDistSq;
+ }
+
+
+public:
+
+
+ /**
+ * Index constructor
+ *
+ * Params:
+ * inputData = dataset with the input features
+ * params = parameters passed to the hierarchical k-means algorithm
+ */
+ HierarchicalClusteringIndex(const Matrix<ElementType>& inputData, const IndexParams& index_params = HierarchicalClusteringIndexParams(),
+ Distance d = Distance())
+ : dataset(inputData), params(index_params), root(NULL), indices(NULL), distance(d)
+ {
+ memoryCounter = 0;
+
+ size_ = dataset.rows;
+ veclen_ = dataset.cols;
+
+ branching_ = get_param(params,"branching",32);
+ centers_init_ = get_param(params,"centers_init", FLANN_CENTERS_RANDOM);
+ trees_ = get_param(params,"trees",4);
+ leaf_size_ = get_param(params,"leaf_size",100);
+
+ if (centers_init_==FLANN_CENTERS_RANDOM) {
+ chooseCenters = &HierarchicalClusteringIndex::chooseCentersRandom;
+ }
+ else if (centers_init_==FLANN_CENTERS_GONZALES) {
+ chooseCenters = &HierarchicalClusteringIndex::chooseCentersGonzales;
+ }
+ else if (centers_init_==FLANN_CENTERS_KMEANSPP) {
+ chooseCenters = &HierarchicalClusteringIndex::chooseCentersKMeanspp;
+ }
+ else if (centers_init_==FLANN_CENTERS_GROUPWISE) {
+ chooseCenters = &HierarchicalClusteringIndex::GroupWiseCenterChooser;
+ }
+ else {
+ throw FLANNException("Unknown algorithm for choosing initial centers.");
+ }
+
+ trees_ = get_param(params,"trees",4);
+ root = new NodePtr[trees_];
+ indices = new int*[trees_];
+
+ for (int i=0; i<trees_; ++i) {
+ root[i] = NULL;
+ indices[i] = NULL;
+ }
+ }
+
+ HierarchicalClusteringIndex(const HierarchicalClusteringIndex&);
+ HierarchicalClusteringIndex& operator=(const HierarchicalClusteringIndex&);
+
+ /**
+ * Index destructor.
+ *
+ * Release the memory used by the index.
+ */
+ virtual ~HierarchicalClusteringIndex()
+ {
+ free_elements();
+
+ if (root!=NULL) {
+ delete[] root;
+ }
+
+ if (indices!=NULL) {
+ delete[] indices;
+ }
+ }
+
+
+ /**
+ * Release the inner elements of indices[]
+ */
+ void free_elements()
+ {
+ if (indices!=NULL) {
+ for(int i=0; i<trees_; ++i) {
+ if (indices[i]!=NULL) {
+ delete[] indices[i];
+ indices[i] = NULL;
+ }
+ }
+ }
+ }
+
+
+ /**
+ * Returns size of index.
+ */
+ size_t size() const
+ {
+ return size_;
+ }
+
+ /**
+ * Returns the length of an index feature.
+ */
+ size_t veclen() const
+ {
+ return veclen_;
+ }
+
+
+ /**
+ * Computes the inde memory usage
+ * Returns: memory used by the index
+ */
+ int usedMemory() const
+ {
+ return pool.usedMemory+pool.wastedMemory+memoryCounter;
+ }
+
+ /**
+ * Builds the index
+ */
+ void buildIndex()
+ {
+ if (branching_<2) {
+ throw FLANNException("Branching factor must be at least 2");
+ }
+
+ free_elements();
+
+ for (int i=0; i<trees_; ++i) {
+ indices[i] = new int[size_];
+ for (size_t j=0; j<size_; ++j) {
+ indices[i][j] = (int)j;
+ }
+ root[i] = pool.allocate<Node>();
+ computeClustering(root[i], indices[i], (int)size_, branching_,0);
+ }
+ }
+
+
+ flann_algorithm_t getType() const
+ {
+ return FLANN_INDEX_HIERARCHICAL;
+ }
+
+
+ void saveIndex(FILE* stream)
+ {
+ save_value(stream, branching_);
+ save_value(stream, trees_);
+ save_value(stream, centers_init_);
+ save_value(stream, leaf_size_);
+ save_value(stream, memoryCounter);
+ for (int i=0; i<trees_; ++i) {
+ save_value(stream, *indices[i], size_);
+ save_tree(stream, root[i], i);
+ }
+
+ }
+
+
+ void loadIndex(FILE* stream)
+ {
+ free_elements();
+
+ if (root!=NULL) {
+ delete[] root;
+ }
+
+ if (indices!=NULL) {
+ delete[] indices;
+ }
+
+ load_value(stream, branching_);
+ load_value(stream, trees_);
+ load_value(stream, centers_init_);
+ load_value(stream, leaf_size_);
+ load_value(stream, memoryCounter);
+
+ indices = new int*[trees_];
+ root = new NodePtr[trees_];
+ for (int i=0; i<trees_; ++i) {
+ indices[i] = new int[size_];
+ load_value(stream, *indices[i], size_);
+ load_tree(stream, root[i], i);
+ }
+
+ params["algorithm"] = getType();
+ params["branching"] = branching_;
+ params["trees"] = trees_;
+ params["centers_init"] = centers_init_;
+ params["leaf_size"] = leaf_size_;
+ }
+
+
+ /**
+ * Find set of nearest neighbors to vec. Their indices are stored inside
+ * the result object.
+ *
+ * Params:
+ * result = the result object in which the indices of the nearest-neighbors are stored
+ * vec = the vector for which to search the nearest neighbors
+ * searchParams = parameters that influence the search algorithm (checks)
+ */
+ void findNeighbors(ResultSet<DistanceType>& result, const ElementType* vec, const SearchParams& searchParams)
+ {
+
+ int maxChecks = get_param(searchParams,"checks",32);
+
+ // Priority queue storing intermediate branches in the best-bin-first search
+ Heap<BranchSt>* heap = new Heap<BranchSt>((int)size_);
+
+ std::vector<bool> checked(size_,false);
+ int checks = 0;
+ for (int i=0; i<trees_; ++i) {
+ findNN(root[i], result, vec, checks, maxChecks, heap, checked);
+ }
+
+ BranchSt branch;
+ while (heap->popMin(branch) && (checks<maxChecks || !result.full())) {
+ NodePtr node = branch.node;
+ findNN(node, result, vec, checks, maxChecks, heap, checked);
+ }
+ assert(result.full());
+
+ delete heap;
+
+ }
+
+ IndexParams getParameters() const
+ {
+ return params;
+ }
+
+
+private:
+
+ /**
+ * Struture representing a node in the hierarchical k-means tree.
+ */
+ struct Node
+ {
+ /**
+ * The cluster center index
+ */
+ int pivot;
+ /**
+ * The cluster size (number of points in the cluster)
+ */
+ int size;
+ /**
+ * Child nodes (only for non-terminal nodes)
+ */
+ Node** childs;
+ /**
+ * Node points (only for terminal nodes)
+ */
+ int* indices;
+ /**
+ * Level
+ */
+ int level;
+ };
+ typedef Node* NodePtr;
+
+
+
+ /**
+ * Alias definition for a nicer syntax.
+ */
+ typedef BranchStruct<NodePtr, DistanceType> BranchSt;
+
+
+
+ void save_tree(FILE* stream, NodePtr node, int num)
+ {
+ save_value(stream, *node);
+ if (node->childs==NULL) {
+ int indices_offset = (int)(node->indices - indices[num]);
+ save_value(stream, indices_offset);
+ }
+ else {
+ for(int i=0; i<branching_; ++i) {
+ save_tree(stream, node->childs[i], num);
+ }
+ }
+ }
+
+
+ void load_tree(FILE* stream, NodePtr& node, int num)
+ {
+ node = pool.allocate<Node>();
+ load_value(stream, *node);
+ if (node->childs==NULL) {
+ int indices_offset;
+ load_value(stream, indices_offset);
+ node->indices = indices[num] + indices_offset;
+ }
+ else {
+ node->childs = pool.allocate<NodePtr>(branching_);
+ for(int i=0; i<branching_; ++i) {
+ load_tree(stream, node->childs[i], num);
+ }
+ }
+ }
+
+
+
+
+ void computeLabels(int* dsindices, int indices_length, int* centers, int centers_length, int* labels, DistanceType& cost)
+ {
+ cost = 0;
+ for (int i=0; i<indices_length; ++i) {
+ ElementType* point = dataset[dsindices[i]];
+ DistanceType dist = distance(point, dataset[centers[0]], veclen_);
+ labels[i] = 0;
+ for (int j=1; j<centers_length; ++j) {
+ DistanceType new_dist = distance(point, dataset[centers[j]], veclen_);
+ if (dist>new_dist) {
+ labels[i] = j;
+ dist = new_dist;
+ }
+ }
+ cost += dist;
+ }
+ }
+
+ /**
+ * The method responsible with actually doing the recursive hierarchical
+ * clustering
+ *
+ * Params:
+ * node = the node to cluster
+ * indices = indices of the points belonging to the current node
+ * branching = the branching factor to use in the clustering
+ *
+ * TODO: for 1-sized clusters don't store a cluster center (it's the same as the single cluster point)
+ */
+ void computeClustering(NodePtr node, int* dsindices, int indices_length, int branching, int level)
+ {
+ node->size = indices_length;
+ node->level = level;
+
+ if (indices_length < leaf_size_) { // leaf node
+ node->indices = dsindices;
+ std::sort(node->indices,node->indices+indices_length);
+ node->childs = NULL;
+ return;
+ }
+
+ std::vector<int> centers(branching);
+ std::vector<int> labels(indices_length);
+
+ int centers_length;
+ (this->*chooseCenters)(branching, dsindices, indices_length, ¢ers[0], centers_length);
+
+ if (centers_length<branching) {
+ node->indices = dsindices;
+ std::sort(node->indices,node->indices+indices_length);
+ node->childs = NULL;
+ return;
+ }
+
+
+ // assign points to clusters
+ DistanceType cost;
+ computeLabels(dsindices, indices_length, ¢ers[0], centers_length, &labels[0], cost);
+
+ node->childs = pool.allocate<NodePtr>(branching);
+ int start = 0;
+ int end = start;
+ for (int i=0; i<branching; ++i) {
+ for (int j=0; j<indices_length; ++j) {
+ if (labels[j]==i) {
+ std::swap(dsindices[j],dsindices[end]);
+ std::swap(labels[j],labels[end]);
+ end++;
+ }
+ }
+
+ node->childs[i] = pool.allocate<Node>();
+ node->childs[i]->pivot = centers[i];
+ node->childs[i]->indices = NULL;
+ computeClustering(node->childs[i],dsindices+start, end-start, branching, level+1);
+ start=end;
+ }
+ }
+
+
+
+ /**
+ * Performs one descent in the hierarchical k-means tree. The branches not
+ * visited are stored in a priority queue.
+ *
+ * Params:
+ * node = node to explore
+ * result = container for the k-nearest neighbors found
+ * vec = query points
+ * checks = how many points in the dataset have been checked so far
+ * maxChecks = maximum dataset points to checks
+ */
+
+
+ void findNN(NodePtr node, ResultSet<DistanceType>& result, const ElementType* vec, int& checks, int maxChecks,
+ Heap<BranchSt>* heap, std::vector<bool>& checked)
+ {
+ if (node->childs==NULL) {
+ if (checks>=maxChecks) {
+ if (result.full()) return;
+ }
+ for (int i=0; i<node->size; ++i) {
+ int index = node->indices[i];
+ if (!checked[index]) {
+ DistanceType dist = distance(dataset[index], vec, veclen_);
+ result.addPoint(dist, index);
+ checked[index] = true;
+ ++checks;
+ }
+ }
+ }
+ else {
+ DistanceType* domain_distances = new DistanceType[branching_];
+ int best_index = 0;
+ domain_distances[best_index] = distance(vec, dataset[node->childs[best_index]->pivot], veclen_);
+ for (int i=1; i<branching_; ++i) {
+ domain_distances[i] = distance(vec, dataset[node->childs[i]->pivot], veclen_);
+ if (domain_distances[i]<domain_distances[best_index]) {
+ best_index = i;
+ }
+ }
+ for (int i=0; i<branching_; ++i) {
+ if (i!=best_index) {
+ heap->insert(BranchSt(node->childs[i],domain_distances[i]));
+ }
+ }
+ delete[] domain_distances;
+ findNN(node->childs[best_index],result,vec, checks, maxChecks, heap, checked);
+ }
+ }
+
+private:
+
+
+ /**
+ * The dataset used by this index
+ */
+ const Matrix<ElementType> dataset;
+
+ /**
+ * Parameters used by this index
+ */
+ IndexParams params;
+
+
+ /**
+ * Number of features in the dataset.
+ */
+ size_t size_;
+
+ /**
+ * Length of each feature.
+ */
+ size_t veclen_;
+
+ /**
+ * The root node in the tree.
+ */
+ NodePtr* root;
+
+ /**
+ * Array of indices to vectors in the dataset.
+ */
+ int** indices;
+
+
+ /**
+ * The distance
+ */
+ Distance distance;
+
+ /**
+ * Pooled memory allocator.
+ *
+ * Using a pooled memory allocator is more efficient
+ * than allocating memory directly when there is a large
+ * number small of memory allocations.
+ */
+ PooledAllocator pool;
+
+ /**
+ * Memory occupied by the index.
+ */
+ int memoryCounter;
+
+ /** index parameters */
+ int branching_;
+ int trees_;
+ flann_centers_init_t centers_init_;
+ int leaf_size_;
+
+
+};
+
+}
+
+#endif /* OPENCV_FLANN_HIERARCHICAL_CLUSTERING_INDEX_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/flann/index_testing.h Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,318 @@
+/***********************************************************************
+ * Software License Agreement (BSD License)
+ *
+ * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved.
+ * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved.
+ *
+ * THE BSD LICENSE
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *************************************************************************/
+
+#ifndef OPENCV_FLANN_INDEX_TESTING_H_
+#define OPENCV_FLANN_INDEX_TESTING_H_
+
+#include <cstring>
+#include <cassert>
+#include <cmath>
+
+#include "matrix.h"
+#include "nn_index.h"
+#include "result_set.h"
+#include "logger.h"
+#include "timer.h"
+
+
+namespace cvflann
+{
+
+inline int countCorrectMatches(int* neighbors, int* groundTruth, int n)
+{
+ int count = 0;
+ for (int i=0; i<n; ++i) {
+ for (int k=0; k<n; ++k) {
+ if (neighbors[i]==groundTruth[k]) {
+ count++;
+ break;
+ }
+ }
+ }
+ return count;
+}
+
+
+template <typename Distance>
+typename Distance::ResultType computeDistanceRaport(const Matrix<typename Distance::ElementType>& inputData, typename Distance::ElementType* target,
+ int* neighbors, int* groundTruth, int veclen, int n, const Distance& distance)
+{
+ typedef typename Distance::ResultType DistanceType;
+
+ DistanceType ret = 0;
+ for (int i=0; i<n; ++i) {
+ DistanceType den = distance(inputData[groundTruth[i]], target, veclen);
+ DistanceType num = distance(inputData[neighbors[i]], target, veclen);
+
+ if ((den==0)&&(num==0)) {
+ ret += 1;
+ }
+ else {
+ ret += num/den;
+ }
+ }
+
+ return ret;
+}
+
+template <typename Distance>
+float search_with_ground_truth(NNIndex<Distance>& index, const Matrix<typename Distance::ElementType>& inputData,
+ const Matrix<typename Distance::ElementType>& testData, const Matrix<int>& matches, int nn, int checks,
+ float& time, typename Distance::ResultType& dist, const Distance& distance, int skipMatches)
+{
+ typedef typename Distance::ResultType DistanceType;
+
+ if (matches.cols<size_t(nn)) {
+ Logger::info("matches.cols=%d, nn=%d\n",matches.cols,nn);
+
+ throw FLANNException("Ground truth is not computed for as many neighbors as requested");
+ }
+
+ KNNResultSet<DistanceType> resultSet(nn+skipMatches);
+ SearchParams searchParams(checks);
+
+ std::vector<int> indices(nn+skipMatches);
+ std::vector<DistanceType> dists(nn+skipMatches);
+ int* neighbors = &indices[skipMatches];
+
+ int correct = 0;
+ DistanceType distR = 0;
+ StartStopTimer t;
+ int repeats = 0;
+ while (t.value<0.2) {
+ repeats++;
+ t.start();
+ correct = 0;
+ distR = 0;
+ for (size_t i = 0; i < testData.rows; i++) {
+ resultSet.init(&indices[0], &dists[0]);
+ index.findNeighbors(resultSet, testData[i], searchParams);
+
+ correct += countCorrectMatches(neighbors,matches[i], nn);
+ distR += computeDistanceRaport<Distance>(inputData, testData[i], neighbors, matches[i], (int)testData.cols, nn, distance);
+ }
+ t.stop();
+ }
+ time = float(t.value/repeats);
+
+ float precicion = (float)correct/(nn*testData.rows);
+
+ dist = distR/(testData.rows*nn);
+
+ Logger::info("%8d %10.4g %10.5g %10.5g %10.5g\n",
+ checks, precicion, time, 1000.0 * time / testData.rows, dist);
+
+ return precicion;
+}
+
+
+template <typename Distance>
+float test_index_checks(NNIndex<Distance>& index, const Matrix<typename Distance::ElementType>& inputData,
+ const Matrix<typename Distance::ElementType>& testData, const Matrix<int>& matches,
+ int checks, float& precision, const Distance& distance, int nn = 1, int skipMatches = 0)
+{
+ typedef typename Distance::ResultType DistanceType;
+
+ Logger::info(" Nodes Precision(%) Time(s) Time/vec(ms) Mean dist\n");
+ Logger::info("---------------------------------------------------------\n");
+
+ float time = 0;
+ DistanceType dist = 0;
+ precision = search_with_ground_truth(index, inputData, testData, matches, nn, checks, time, dist, distance, skipMatches);
+
+ return time;
+}
+
+template <typename Distance>
+float test_index_precision(NNIndex<Distance>& index, const Matrix<typename Distance::ElementType>& inputData,
+ const Matrix<typename Distance::ElementType>& testData, const Matrix<int>& matches,
+ float precision, int& checks, const Distance& distance, int nn = 1, int skipMatches = 0)
+{
+ typedef typename Distance::ResultType DistanceType;
+ const float SEARCH_EPS = 0.001f;
+
+ Logger::info(" Nodes Precision(%) Time(s) Time/vec(ms) Mean dist\n");
+ Logger::info("---------------------------------------------------------\n");
+
+ int c2 = 1;
+ float p2;
+ int c1 = 1;
+ //float p1;
+ float time;
+ DistanceType dist;
+
+ p2 = search_with_ground_truth(index, inputData, testData, matches, nn, c2, time, dist, distance, skipMatches);
+
+ if (p2>precision) {
+ Logger::info("Got as close as I can\n");
+ checks = c2;
+ return time;
+ }
+
+ while (p2<precision) {
+ c1 = c2;
+ //p1 = p2;
+ c2 *=2;
+ p2 = search_with_ground_truth(index, inputData, testData, matches, nn, c2, time, dist, distance, skipMatches);
+ }
+
+ int cx;
+ float realPrecision;
+ if (fabs(p2-precision)>SEARCH_EPS) {
+ Logger::info("Start linear estimation\n");
+ // after we got to values in the vecinity of the desired precision
+ // use linear approximation get a better estimation
+
+ cx = (c1+c2)/2;
+ realPrecision = search_with_ground_truth(index, inputData, testData, matches, nn, cx, time, dist, distance, skipMatches);
+ while (fabs(realPrecision-precision)>SEARCH_EPS) {
+
+ if (realPrecision<precision) {
+ c1 = cx;
+ }
+ else {
+ c2 = cx;
+ }
+ cx = (c1+c2)/2;
+ if (cx==c1) {
+ Logger::info("Got as close as I can\n");
+ break;
+ }
+ realPrecision = search_with_ground_truth(index, inputData, testData, matches, nn, cx, time, dist, distance, skipMatches);
+ }
+
+ c2 = cx;
+ p2 = realPrecision;
+
+ }
+ else {
+ Logger::info("No need for linear estimation\n");
+ cx = c2;
+ realPrecision = p2;
+ }
+
+ checks = cx;
+ return time;
+}
+
+
+template <typename Distance>
+void test_index_precisions(NNIndex<Distance>& index, const Matrix<typename Distance::ElementType>& inputData,
+ const Matrix<typename Distance::ElementType>& testData, const Matrix<int>& matches,
+ float* precisions, int precisions_length, const Distance& distance, int nn = 1, int skipMatches = 0, float maxTime = 0)
+{
+ typedef typename Distance::ResultType DistanceType;
+
+ const float SEARCH_EPS = 0.001;
+
+ // make sure precisions array is sorted
+ std::sort(precisions, precisions+precisions_length);
+
+ int pindex = 0;
+ float precision = precisions[pindex];
+
+ Logger::info(" Nodes Precision(%) Time(s) Time/vec(ms) Mean dist\n");
+ Logger::info("---------------------------------------------------------\n");
+
+ int c2 = 1;
+ float p2;
+
+ int c1 = 1;
+ float p1;
+
+ float time;
+ DistanceType dist;
+
+ p2 = search_with_ground_truth(index, inputData, testData, matches, nn, c2, time, dist, distance, skipMatches);
+
+ // if precision for 1 run down the tree is already
+ // better then some of the requested precisions, then
+ // skip those
+ while (precisions[pindex]<p2 && pindex<precisions_length) {
+ pindex++;
+ }
+
+ if (pindex==precisions_length) {
+ Logger::info("Got as close as I can\n");
+ return;
+ }
+
+ for (int i=pindex; i<precisions_length; ++i) {
+
+ precision = precisions[i];
+ while (p2<precision) {
+ c1 = c2;
+ p1 = p2;
+ c2 *=2;
+ p2 = search_with_ground_truth(index, inputData, testData, matches, nn, c2, time, dist, distance, skipMatches);
+ if ((maxTime> 0)&&(time > maxTime)&&(p2<precision)) return;
+ }
+
+ int cx;
+ float realPrecision;
+ if (fabs(p2-precision)>SEARCH_EPS) {
+ Logger::info("Start linear estimation\n");
+ // after we got to values in the vecinity of the desired precision
+ // use linear approximation get a better estimation
+
+ cx = (c1+c2)/2;
+ realPrecision = search_with_ground_truth(index, inputData, testData, matches, nn, cx, time, dist, distance, skipMatches);
+ while (fabs(realPrecision-precision)>SEARCH_EPS) {
+
+ if (realPrecision<precision) {
+ c1 = cx;
+ }
+ else {
+ c2 = cx;
+ }
+ cx = (c1+c2)/2;
+ if (cx==c1) {
+ Logger::info("Got as close as I can\n");
+ break;
+ }
+ realPrecision = search_with_ground_truth(index, inputData, testData, matches, nn, cx, time, dist, distance, skipMatches);
+ }
+
+ c2 = cx;
+ p2 = realPrecision;
+
+ }
+ else {
+ Logger::info("No need for linear estimation\n");
+ cx = c2;
+ realPrecision = p2;
+ }
+
+ }
+}
+
+}
+
+#endif //OPENCV_FLANN_INDEX_TESTING_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/flann/kdtree_index.h Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,621 @@
+/***********************************************************************
+ * Software License Agreement (BSD License)
+ *
+ * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved.
+ * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved.
+ *
+ * THE BSD LICENSE
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *************************************************************************/
+
+#ifndef OPENCV_FLANN_KDTREE_INDEX_H_
+#define OPENCV_FLANN_KDTREE_INDEX_H_
+
+#include <algorithm>
+#include <map>
+#include <cassert>
+#include <cstring>
+
+#include "general.h"
+#include "nn_index.h"
+#include "dynamic_bitset.h"
+#include "matrix.h"
+#include "result_set.h"
+#include "heap.h"
+#include "allocator.h"
+#include "random.h"
+#include "saving.h"
+
+
+namespace cvflann
+{
+
+struct KDTreeIndexParams : public IndexParams
+{
+ KDTreeIndexParams(int trees = 4)
+ {
+ (*this)["algorithm"] = FLANN_INDEX_KDTREE;
+ (*this)["trees"] = trees;
+ }
+};
+
+
+/**
+ * Randomized kd-tree index
+ *
+ * Contains the k-d trees and other information for indexing a set of points
+ * for nearest-neighbor matching.
+ */
+template <typename Distance>
+class KDTreeIndex : public NNIndex<Distance>
+{
+public:
+ typedef typename Distance::ElementType ElementType;
+ typedef typename Distance::ResultType DistanceType;
+
+
+ /**
+ * KDTree constructor
+ *
+ * Params:
+ * inputData = dataset with the input features
+ * params = parameters passed to the kdtree algorithm
+ */
+ KDTreeIndex(const Matrix<ElementType>& inputData, const IndexParams& params = KDTreeIndexParams(),
+ Distance d = Distance() ) :
+ dataset_(inputData), index_params_(params), distance_(d)
+ {
+ size_ = dataset_.rows;
+ veclen_ = dataset_.cols;
+
+ trees_ = get_param(index_params_,"trees",4);
+ tree_roots_ = new NodePtr[trees_];
+
+ // Create a permutable array of indices to the input vectors.
+ vind_.resize(size_);
+ for (size_t i = 0; i < size_; ++i) {
+ vind_[i] = int(i);
+ }
+
+ mean_ = new DistanceType[veclen_];
+ var_ = new DistanceType[veclen_];
+ }
+
+
+ KDTreeIndex(const KDTreeIndex&);
+ KDTreeIndex& operator=(const KDTreeIndex&);
+
+ /**
+ * Standard destructor
+ */
+ ~KDTreeIndex()
+ {
+ if (tree_roots_!=NULL) {
+ delete[] tree_roots_;
+ }
+ delete[] mean_;
+ delete[] var_;
+ }
+
+ /**
+ * Builds the index
+ */
+ void buildIndex()
+ {
+ /* Construct the randomized trees. */
+ for (int i = 0; i < trees_; i++) {
+ /* Randomize the order of vectors to allow for unbiased sampling. */
+ std::random_shuffle(vind_.begin(), vind_.end());
+ tree_roots_[i] = divideTree(&vind_[0], int(size_) );
+ }
+ }
+
+
+ flann_algorithm_t getType() const
+ {
+ return FLANN_INDEX_KDTREE;
+ }
+
+
+ void saveIndex(FILE* stream)
+ {
+ save_value(stream, trees_);
+ for (int i=0; i<trees_; ++i) {
+ save_tree(stream, tree_roots_[i]);
+ }
+ }
+
+
+
+ void loadIndex(FILE* stream)
+ {
+ load_value(stream, trees_);
+ if (tree_roots_!=NULL) {
+ delete[] tree_roots_;
+ }
+ tree_roots_ = new NodePtr[trees_];
+ for (int i=0; i<trees_; ++i) {
+ load_tree(stream,tree_roots_[i]);
+ }
+
+ index_params_["algorithm"] = getType();
+ index_params_["trees"] = tree_roots_;
+ }
+
+ /**
+ * Returns size of index.
+ */
+ size_t size() const
+ {
+ return size_;
+ }
+
+ /**
+ * Returns the length of an index feature.
+ */
+ size_t veclen() const
+ {
+ return veclen_;
+ }
+
+ /**
+ * Computes the inde memory usage
+ * Returns: memory used by the index
+ */
+ int usedMemory() const
+ {
+ return int(pool_.usedMemory+pool_.wastedMemory+dataset_.rows*sizeof(int)); // pool memory and vind array memory
+ }
+
+ /**
+ * Find set of nearest neighbors to vec. Their indices are stored inside
+ * the result object.
+ *
+ * Params:
+ * result = the result object in which the indices of the nearest-neighbors are stored
+ * vec = the vector for which to search the nearest neighbors
+ * maxCheck = the maximum number of restarts (in a best-bin-first manner)
+ */
+ void findNeighbors(ResultSet<DistanceType>& result, const ElementType* vec, const SearchParams& searchParams)
+ {
+ int maxChecks = get_param(searchParams,"checks", 32);
+ float epsError = 1+get_param(searchParams,"eps",0.0f);
+
+ if (maxChecks==FLANN_CHECKS_UNLIMITED) {
+ getExactNeighbors(result, vec, epsError);
+ }
+ else {
+ getNeighbors(result, vec, maxChecks, epsError);
+ }
+ }
+
+ IndexParams getParameters() const
+ {
+ return index_params_;
+ }
+
+private:
+
+
+ /*--------------------- Internal Data Structures --------------------------*/
+ struct Node
+ {
+ /**
+ * Dimension used for subdivision.
+ */
+ int divfeat;
+ /**
+ * The values used for subdivision.
+ */
+ DistanceType divval;
+ /**
+ * The child nodes.
+ */
+ Node* child1, * child2;
+ };
+ typedef Node* NodePtr;
+ typedef BranchStruct<NodePtr, DistanceType> BranchSt;
+ typedef BranchSt* Branch;
+
+
+
+ void save_tree(FILE* stream, NodePtr tree)
+ {
+ save_value(stream, *tree);
+ if (tree->child1!=NULL) {
+ save_tree(stream, tree->child1);
+ }
+ if (tree->child2!=NULL) {
+ save_tree(stream, tree->child2);
+ }
+ }
+
+
+ void load_tree(FILE* stream, NodePtr& tree)
+ {
+ tree = pool_.allocate<Node>();
+ load_value(stream, *tree);
+ if (tree->child1!=NULL) {
+ load_tree(stream, tree->child1);
+ }
+ if (tree->child2!=NULL) {
+ load_tree(stream, tree->child2);
+ }
+ }
+
+
+ /**
+ * Create a tree node that subdivides the list of vecs from vind[first]
+ * to vind[last]. The routine is called recursively on each sublist.
+ * Place a pointer to this new tree node in the location pTree.
+ *
+ * Params: pTree = the new node to create
+ * first = index of the first vector
+ * last = index of the last vector
+ */
+ NodePtr divideTree(int* ind, int count)
+ {
+ NodePtr node = pool_.allocate<Node>(); // allocate memory
+
+ /* If too few exemplars remain, then make this a leaf node. */
+ if ( count == 1) {
+ node->child1 = node->child2 = NULL; /* Mark as leaf node. */
+ node->divfeat = *ind; /* Store index of this vec. */
+ }
+ else {
+ int idx;
+ int cutfeat;
+ DistanceType cutval;
+ meanSplit(ind, count, idx, cutfeat, cutval);
+
+ node->divfeat = cutfeat;
+ node->divval = cutval;
+ node->child1 = divideTree(ind, idx);
+ node->child2 = divideTree(ind+idx, count-idx);
+ }
+
+ return node;
+ }
+
+
+ /**
+ * Choose which feature to use in order to subdivide this set of vectors.
+ * Make a random choice among those with the highest variance, and use
+ * its variance as the threshold value.
+ */
+ void meanSplit(int* ind, int count, int& index, int& cutfeat, DistanceType& cutval)
+ {
+ memset(mean_,0,veclen_*sizeof(DistanceType));
+ memset(var_,0,veclen_*sizeof(DistanceType));
+
+ /* Compute mean values. Only the first SAMPLE_MEAN values need to be
+ sampled to get a good estimate.
+ */
+ int cnt = std::min((int)SAMPLE_MEAN+1, count);
+ for (int j = 0; j < cnt; ++j) {
+ ElementType* v = dataset_[ind[j]];
+ for (size_t k=0; k<veclen_; ++k) {
+ mean_[k] += v[k];
+ }
+ }
+ for (size_t k=0; k<veclen_; ++k) {
+ mean_[k] /= cnt;
+ }
+
+ /* Compute variances (no need to divide by count). */
+ for (int j = 0; j < cnt; ++j) {
+ ElementType* v = dataset_[ind[j]];
+ for (size_t k=0; k<veclen_; ++k) {
+ DistanceType dist = v[k] - mean_[k];
+ var_[k] += dist * dist;
+ }
+ }
+ /* Select one of the highest variance indices at random. */
+ cutfeat = selectDivision(var_);
+ cutval = mean_[cutfeat];
+
+ int lim1, lim2;
+ planeSplit(ind, count, cutfeat, cutval, lim1, lim2);
+
+ if (lim1>count/2) index = lim1;
+ else if (lim2<count/2) index = lim2;
+ else index = count/2;
+
+ /* If either list is empty, it means that all remaining features
+ * are identical. Split in the middle to maintain a balanced tree.
+ */
+ if ((lim1==count)||(lim2==0)) index = count/2;
+ }
+
+
+ /**
+ * Select the top RAND_DIM largest values from v and return the index of
+ * one of these selected at random.
+ */
+ int selectDivision(DistanceType* v)
+ {
+ int num = 0;
+ size_t topind[RAND_DIM];
+
+ /* Create a list of the indices of the top RAND_DIM values. */
+ for (size_t i = 0; i < veclen_; ++i) {
+ if ((num < RAND_DIM)||(v[i] > v[topind[num-1]])) {
+ /* Put this element at end of topind. */
+ if (num < RAND_DIM) {
+ topind[num++] = i; /* Add to list. */
+ }
+ else {
+ topind[num-1] = i; /* Replace last element. */
+ }
+ /* Bubble end value down to right location by repeated swapping. */
+ int j = num - 1;
+ while (j > 0 && v[topind[j]] > v[topind[j-1]]) {
+ std::swap(topind[j], topind[j-1]);
+ --j;
+ }
+ }
+ }
+ /* Select a random integer in range [0,num-1], and return that index. */
+ int rnd = rand_int(num);
+ return (int)topind[rnd];
+ }
+
+
+ /**
+ * Subdivide the list of points by a plane perpendicular on axe corresponding
+ * to the 'cutfeat' dimension at 'cutval' position.
+ *
+ * On return:
+ * dataset[ind[0..lim1-1]][cutfeat]<cutval
+ * dataset[ind[lim1..lim2-1]][cutfeat]==cutval
+ * dataset[ind[lim2..count]][cutfeat]>cutval
+ */
+ void planeSplit(int* ind, int count, int cutfeat, DistanceType cutval, int& lim1, int& lim2)
+ {
+ /* Move vector indices for left subtree to front of list. */
+ int left = 0;
+ int right = count-1;
+ for (;; ) {
+ while (left<=right && dataset_[ind[left]][cutfeat]<cutval) ++left;
+ while (left<=right && dataset_[ind[right]][cutfeat]>=cutval) --right;
+ if (left>right) break;
+ std::swap(ind[left], ind[right]); ++left; --right;
+ }
+ lim1 = left;
+ right = count-1;
+ for (;; ) {
+ while (left<=right && dataset_[ind[left]][cutfeat]<=cutval) ++left;
+ while (left<=right && dataset_[ind[right]][cutfeat]>cutval) --right;
+ if (left>right) break;
+ std::swap(ind[left], ind[right]); ++left; --right;
+ }
+ lim2 = left;
+ }
+
+ /**
+ * Performs an exact nearest neighbor search. The exact search performs a full
+ * traversal of the tree.
+ */
+ void getExactNeighbors(ResultSet<DistanceType>& result, const ElementType* vec, float epsError)
+ {
+ // checkID -= 1; /* Set a different unique ID for each search. */
+
+ if (trees_ > 1) {
+ fprintf(stderr,"It doesn't make any sense to use more than one tree for exact search");
+ }
+ if (trees_>0) {
+ searchLevelExact(result, vec, tree_roots_[0], 0.0, epsError);
+ }
+ assert(result.full());
+ }
+
+ /**
+ * Performs the approximate nearest-neighbor search. The search is approximate
+ * because the tree traversal is abandoned after a given number of descends in
+ * the tree.
+ */
+ void getNeighbors(ResultSet<DistanceType>& result, const ElementType* vec, int maxCheck, float epsError)
+ {
+ int i;
+ BranchSt branch;
+
+ int checkCount = 0;
+ Heap<BranchSt>* heap = new Heap<BranchSt>((int)size_);
+ DynamicBitset checked(size_);
+
+ /* Search once through each tree down to root. */
+ for (i = 0; i < trees_; ++i) {
+ searchLevel(result, vec, tree_roots_[i], 0, checkCount, maxCheck, epsError, heap, checked);
+ }
+
+ /* Keep searching other branches from heap until finished. */
+ while ( heap->popMin(branch) && (checkCount < maxCheck || !result.full() )) {
+ searchLevel(result, vec, branch.node, branch.mindist, checkCount, maxCheck, epsError, heap, checked);
+ }
+
+ delete heap;
+
+ assert(result.full());
+ }
+
+
+ /**
+ * Search starting from a given node of the tree. Based on any mismatches at
+ * higher levels, all exemplars below this level must have a distance of
+ * at least "mindistsq".
+ */
+ void searchLevel(ResultSet<DistanceType>& result_set, const ElementType* vec, NodePtr node, DistanceType mindist, int& checkCount, int maxCheck,
+ float epsError, Heap<BranchSt>* heap, DynamicBitset& checked)
+ {
+ if (result_set.worstDist()<mindist) {
+ // printf("Ignoring branch, too far\n");
+ return;
+ }
+
+ /* If this is a leaf node, then do check and return. */
+ if ((node->child1 == NULL)&&(node->child2 == NULL)) {
+ /* Do not check same node more than once when searching multiple trees.
+ Once a vector is checked, we set its location in vind to the
+ current checkID.
+ */
+ int index = node->divfeat;
+ if ( checked.test(index) || ((checkCount>=maxCheck)&& result_set.full()) ) return;
+ checked.set(index);
+ checkCount++;
+
+ DistanceType dist = distance_(dataset_[index], vec, veclen_);
+ result_set.addPoint(dist,index);
+
+ return;
+ }
+
+ /* Which child branch should be taken first? */
+ ElementType val = vec[node->divfeat];
+ DistanceType diff = val - node->divval;
+ NodePtr bestChild = (diff < 0) ? node->child1 : node->child2;
+ NodePtr otherChild = (diff < 0) ? node->child2 : node->child1;
+
+ /* Create a branch record for the branch not taken. Add distance
+ of this feature boundary (we don't attempt to correct for any
+ use of this feature in a parent node, which is unlikely to
+ happen and would have only a small effect). Don't bother
+ adding more branches to heap after halfway point, as cost of
+ adding exceeds their value.
+ */
+
+ DistanceType new_distsq = mindist + distance_.accum_dist(val, node->divval, node->divfeat);
+ // if (2 * checkCount < maxCheck || !result.full()) {
+ if ((new_distsq*epsError < result_set.worstDist())|| !result_set.full()) {
+ heap->insert( BranchSt(otherChild, new_distsq) );
+ }
+
+ /* Call recursively to search next level down. */
+ searchLevel(result_set, vec, bestChild, mindist, checkCount, maxCheck, epsError, heap, checked);
+ }
+
+ /**
+ * Performs an exact search in the tree starting from a node.
+ */
+ void searchLevelExact(ResultSet<DistanceType>& result_set, const ElementType* vec, const NodePtr node, DistanceType mindist, const float epsError)
+ {
+ /* If this is a leaf node, then do check and return. */
+ if ((node->child1 == NULL)&&(node->child2 == NULL)) {
+ int index = node->divfeat;
+ DistanceType dist = distance_(dataset_[index], vec, veclen_);
+ result_set.addPoint(dist,index);
+ return;
+ }
+
+ /* Which child branch should be taken first? */
+ ElementType val = vec[node->divfeat];
+ DistanceType diff = val - node->divval;
+ NodePtr bestChild = (diff < 0) ? node->child1 : node->child2;
+ NodePtr otherChild = (diff < 0) ? node->child2 : node->child1;
+
+ /* Create a branch record for the branch not taken. Add distance
+ of this feature boundary (we don't attempt to correct for any
+ use of this feature in a parent node, which is unlikely to
+ happen and would have only a small effect). Don't bother
+ adding more branches to heap after halfway point, as cost of
+ adding exceeds their value.
+ */
+
+ DistanceType new_distsq = mindist + distance_.accum_dist(val, node->divval, node->divfeat);
+
+ /* Call recursively to search next level down. */
+ searchLevelExact(result_set, vec, bestChild, mindist, epsError);
+
+ if (new_distsq*epsError<=result_set.worstDist()) {
+ searchLevelExact(result_set, vec, otherChild, new_distsq, epsError);
+ }
+ }
+
+
+private:
+
+ enum
+ {
+ /**
+ * To improve efficiency, only SAMPLE_MEAN random values are used to
+ * compute the mean and variance at each level when building a tree.
+ * A value of 100 seems to perform as well as using all values.
+ */
+ SAMPLE_MEAN = 100,
+ /**
+ * Top random dimensions to consider
+ *
+ * When creating random trees, the dimension on which to subdivide is
+ * selected at random from among the top RAND_DIM dimensions with the
+ * highest variance. A value of 5 works well.
+ */
+ RAND_DIM=5
+ };
+
+
+ /**
+ * Number of randomized trees that are used
+ */
+ int trees_;
+
+ /**
+ * Array of indices to vectors in the dataset.
+ */
+ std::vector<int> vind_;
+
+ /**
+ * The dataset used by this index
+ */
+ const Matrix<ElementType> dataset_;
+
+ IndexParams index_params_;
+
+ size_t size_;
+ size_t veclen_;
+
+
+ DistanceType* mean_;
+ DistanceType* var_;
+
+
+ /**
+ * Array of k-d trees used to find neighbours.
+ */
+ NodePtr* tree_roots_;
+
+ /**
+ * Pooled memory allocator.
+ *
+ * Using a pooled memory allocator is more efficient
+ * than allocating memory directly when there is a large
+ * number small of memory allocations.
+ */
+ PooledAllocator pool_;
+
+ Distance distance_;
+
+
+}; // class KDTreeForest
+
+}
+
+#endif //OPENCV_FLANN_KDTREE_INDEX_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/flann/kdtree_single_index.h Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,634 @@
+/***********************************************************************
+ * Software License Agreement (BSD License)
+ *
+ * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved.
+ * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved.
+ *
+ * THE BSD LICENSE
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *************************************************************************/
+
+#ifndef OPENCV_FLANN_KDTREE_SINGLE_INDEX_H_
+#define OPENCV_FLANN_KDTREE_SINGLE_INDEX_H_
+
+#include <algorithm>
+#include <map>
+#include <cassert>
+#include <cstring>
+
+#include "general.h"
+#include "nn_index.h"
+#include "matrix.h"
+#include "result_set.h"
+#include "heap.h"
+#include "allocator.h"
+#include "random.h"
+#include "saving.h"
+
+namespace cvflann
+{
+
+struct KDTreeSingleIndexParams : public IndexParams
+{
+ KDTreeSingleIndexParams(int leaf_max_size = 10, bool reorder = true, int dim = -1)
+ {
+ (*this)["algorithm"] = FLANN_INDEX_KDTREE_SINGLE;
+ (*this)["leaf_max_size"] = leaf_max_size;
+ (*this)["reorder"] = reorder;
+ (*this)["dim"] = dim;
+ }
+};
+
+
+/**
+ * Randomized kd-tree index
+ *
+ * Contains the k-d trees and other information for indexing a set of points
+ * for nearest-neighbor matching.
+ */
+template <typename Distance>
+class KDTreeSingleIndex : public NNIndex<Distance>
+{
+public:
+ typedef typename Distance::ElementType ElementType;
+ typedef typename Distance::ResultType DistanceType;
+
+
+ /**
+ * KDTree constructor
+ *
+ * Params:
+ * inputData = dataset with the input features
+ * params = parameters passed to the kdtree algorithm
+ */
+ KDTreeSingleIndex(const Matrix<ElementType>& inputData, const IndexParams& params = KDTreeSingleIndexParams(),
+ Distance d = Distance() ) :
+ dataset_(inputData), index_params_(params), distance_(d)
+ {
+ size_ = dataset_.rows;
+ dim_ = dataset_.cols;
+ int dim_param = get_param(params,"dim",-1);
+ if (dim_param>0) dim_ = dim_param;
+ leaf_max_size_ = get_param(params,"leaf_max_size",10);
+ reorder_ = get_param(params,"reorder",true);
+
+ // Create a permutable array of indices to the input vectors.
+ vind_.resize(size_);
+ for (size_t i = 0; i < size_; i++) {
+ vind_[i] = (int)i;
+ }
+ }
+
+ KDTreeSingleIndex(const KDTreeSingleIndex&);
+ KDTreeSingleIndex& operator=(const KDTreeSingleIndex&);
+
+ /**
+ * Standard destructor
+ */
+ ~KDTreeSingleIndex()
+ {
+ if (reorder_) delete[] data_.data;
+ }
+
+ /**
+ * Builds the index
+ */
+ void buildIndex()
+ {
+ computeBoundingBox(root_bbox_);
+ root_node_ = divideTree(0, (int)size_, root_bbox_ ); // construct the tree
+
+ if (reorder_) {
+ delete[] data_.data;
+ data_ = cvflann::Matrix<ElementType>(new ElementType[size_*dim_], size_, dim_);
+ for (size_t i=0; i<size_; ++i) {
+ for (size_t j=0; j<dim_; ++j) {
+ data_[i][j] = dataset_[vind_[i]][j];
+ }
+ }
+ }
+ else {
+ data_ = dataset_;
+ }
+ }
+
+ flann_algorithm_t getType() const
+ {
+ return FLANN_INDEX_KDTREE_SINGLE;
+ }
+
+
+ void saveIndex(FILE* stream)
+ {
+ save_value(stream, size_);
+ save_value(stream, dim_);
+ save_value(stream, root_bbox_);
+ save_value(stream, reorder_);
+ save_value(stream, leaf_max_size_);
+ save_value(stream, vind_);
+ if (reorder_) {
+ save_value(stream, data_);
+ }
+ save_tree(stream, root_node_);
+ }
+
+
+ void loadIndex(FILE* stream)
+ {
+ load_value(stream, size_);
+ load_value(stream, dim_);
+ load_value(stream, root_bbox_);
+ load_value(stream, reorder_);
+ load_value(stream, leaf_max_size_);
+ load_value(stream, vind_);
+ if (reorder_) {
+ load_value(stream, data_);
+ }
+ else {
+ data_ = dataset_;
+ }
+ load_tree(stream, root_node_);
+
+
+ index_params_["algorithm"] = getType();
+ index_params_["leaf_max_size"] = leaf_max_size_;
+ index_params_["reorder"] = reorder_;
+ }
+
+ /**
+ * Returns size of index.
+ */
+ size_t size() const
+ {
+ return size_;
+ }
+
+ /**
+ * Returns the length of an index feature.
+ */
+ size_t veclen() const
+ {
+ return dim_;
+ }
+
+ /**
+ * Computes the inde memory usage
+ * Returns: memory used by the index
+ */
+ int usedMemory() const
+ {
+ return (int)(pool_.usedMemory+pool_.wastedMemory+dataset_.rows*sizeof(int)); // pool memory and vind array memory
+ }
+
+
+ /**
+ * \brief Perform k-nearest neighbor search
+ * \param[in] queries The query points for which to find the nearest neighbors
+ * \param[out] indices The indices of the nearest neighbors found
+ * \param[out] dists Distances to the nearest neighbors found
+ * \param[in] knn Number of nearest neighbors to return
+ * \param[in] params Search parameters
+ */
+ void knnSearch(const Matrix<ElementType>& queries, Matrix<int>& indices, Matrix<DistanceType>& dists, int knn, const SearchParams& params)
+ {
+ assert(queries.cols == veclen());
+ assert(indices.rows >= queries.rows);
+ assert(dists.rows >= queries.rows);
+ assert(int(indices.cols) >= knn);
+ assert(int(dists.cols) >= knn);
+
+ KNNSimpleResultSet<DistanceType> resultSet(knn);
+ for (size_t i = 0; i < queries.rows; i++) {
+ resultSet.init(indices[i], dists[i]);
+ findNeighbors(resultSet, queries[i], params);
+ }
+ }
+
+ IndexParams getParameters() const
+ {
+ return index_params_;
+ }
+
+ /**
+ * Find set of nearest neighbors to vec. Their indices are stored inside
+ * the result object.
+ *
+ * Params:
+ * result = the result object in which the indices of the nearest-neighbors are stored
+ * vec = the vector for which to search the nearest neighbors
+ * maxCheck = the maximum number of restarts (in a best-bin-first manner)
+ */
+ void findNeighbors(ResultSet<DistanceType>& result, const ElementType* vec, const SearchParams& searchParams)
+ {
+ float epsError = 1+get_param(searchParams,"eps",0.0f);
+
+ std::vector<DistanceType> dists(dim_,0);
+ DistanceType distsq = computeInitialDistances(vec, dists);
+ searchLevel(result, vec, root_node_, distsq, dists, epsError);
+ }
+
+private:
+
+
+ /*--------------------- Internal Data Structures --------------------------*/
+ struct Node
+ {
+ /**
+ * Indices of points in leaf node
+ */
+ int left, right;
+ /**
+ * Dimension used for subdivision.
+ */
+ int divfeat;
+ /**
+ * The values used for subdivision.
+ */
+ DistanceType divlow, divhigh;
+ /**
+ * The child nodes.
+ */
+ Node* child1, * child2;
+ };
+ typedef Node* NodePtr;
+
+
+ struct Interval
+ {
+ DistanceType low, high;
+ };
+
+ typedef std::vector<Interval> BoundingBox;
+
+ typedef BranchStruct<NodePtr, DistanceType> BranchSt;
+ typedef BranchSt* Branch;
+
+
+
+
+ void save_tree(FILE* stream, NodePtr tree)
+ {
+ save_value(stream, *tree);
+ if (tree->child1!=NULL) {
+ save_tree(stream, tree->child1);
+ }
+ if (tree->child2!=NULL) {
+ save_tree(stream, tree->child2);
+ }
+ }
+
+
+ void load_tree(FILE* stream, NodePtr& tree)
+ {
+ tree = pool_.allocate<Node>();
+ load_value(stream, *tree);
+ if (tree->child1!=NULL) {
+ load_tree(stream, tree->child1);
+ }
+ if (tree->child2!=NULL) {
+ load_tree(stream, tree->child2);
+ }
+ }
+
+
+ void computeBoundingBox(BoundingBox& bbox)
+ {
+ bbox.resize(dim_);
+ for (size_t i=0; i<dim_; ++i) {
+ bbox[i].low = (DistanceType)dataset_[0][i];
+ bbox[i].high = (DistanceType)dataset_[0][i];
+ }
+ for (size_t k=1; k<dataset_.rows; ++k) {
+ for (size_t i=0; i<dim_; ++i) {
+ if (dataset_[k][i]<bbox[i].low) bbox[i].low = (DistanceType)dataset_[k][i];
+ if (dataset_[k][i]>bbox[i].high) bbox[i].high = (DistanceType)dataset_[k][i];
+ }
+ }
+ }
+
+
+ /**
+ * Create a tree node that subdivides the list of vecs from vind[first]
+ * to vind[last]. The routine is called recursively on each sublist.
+ * Place a pointer to this new tree node in the location pTree.
+ *
+ * Params: pTree = the new node to create
+ * first = index of the first vector
+ * last = index of the last vector
+ */
+ NodePtr divideTree(int left, int right, BoundingBox& bbox)
+ {
+ NodePtr node = pool_.allocate<Node>(); // allocate memory
+
+ /* If too few exemplars remain, then make this a leaf node. */
+ if ( (right-left) <= leaf_max_size_) {
+ node->child1 = node->child2 = NULL; /* Mark as leaf node. */
+ node->left = left;
+ node->right = right;
+
+ // compute bounding-box of leaf points
+ for (size_t i=0; i<dim_; ++i) {
+ bbox[i].low = (DistanceType)dataset_[vind_[left]][i];
+ bbox[i].high = (DistanceType)dataset_[vind_[left]][i];
+ }
+ for (int k=left+1; k<right; ++k) {
+ for (size_t i=0; i<dim_; ++i) {
+ if (bbox[i].low>dataset_[vind_[k]][i]) bbox[i].low=(DistanceType)dataset_[vind_[k]][i];
+ if (bbox[i].high<dataset_[vind_[k]][i]) bbox[i].high=(DistanceType)dataset_[vind_[k]][i];
+ }
+ }
+ }
+ else {
+ int idx;
+ int cutfeat;
+ DistanceType cutval;
+ middleSplit_(&vind_[0]+left, right-left, idx, cutfeat, cutval, bbox);
+
+ node->divfeat = cutfeat;
+
+ BoundingBox left_bbox(bbox);
+ left_bbox[cutfeat].high = cutval;
+ node->child1 = divideTree(left, left+idx, left_bbox);
+
+ BoundingBox right_bbox(bbox);
+ right_bbox[cutfeat].low = cutval;
+ node->child2 = divideTree(left+idx, right, right_bbox);
+
+ node->divlow = left_bbox[cutfeat].high;
+ node->divhigh = right_bbox[cutfeat].low;
+
+ for (size_t i=0; i<dim_; ++i) {
+ bbox[i].low = std::min(left_bbox[i].low, right_bbox[i].low);
+ bbox[i].high = std::max(left_bbox[i].high, right_bbox[i].high);
+ }
+ }
+
+ return node;
+ }
+
+ void computeMinMax(int* ind, int count, int dim, ElementType& min_elem, ElementType& max_elem)
+ {
+ min_elem = dataset_[ind[0]][dim];
+ max_elem = dataset_[ind[0]][dim];
+ for (int i=1; i<count; ++i) {
+ ElementType val = dataset_[ind[i]][dim];
+ if (val<min_elem) min_elem = val;
+ if (val>max_elem) max_elem = val;
+ }
+ }
+
+ void middleSplit(int* ind, int count, int& index, int& cutfeat, DistanceType& cutval, const BoundingBox& bbox)
+ {
+ // find the largest span from the approximate bounding box
+ ElementType max_span = bbox[0].high-bbox[0].low;
+ cutfeat = 0;
+ cutval = (bbox[0].high+bbox[0].low)/2;
+ for (size_t i=1; i<dim_; ++i) {
+ ElementType span = bbox[i].high-bbox[i].low;
+ if (span>max_span) {
+ max_span = span;
+ cutfeat = i;
+ cutval = (bbox[i].high+bbox[i].low)/2;
+ }
+ }
+
+ // compute exact span on the found dimension
+ ElementType min_elem, max_elem;
+ computeMinMax(ind, count, cutfeat, min_elem, max_elem);
+ cutval = (min_elem+max_elem)/2;
+ max_span = max_elem - min_elem;
+
+ // check if a dimension of a largest span exists
+ size_t k = cutfeat;
+ for (size_t i=0; i<dim_; ++i) {
+ if (i==k) continue;
+ ElementType span = bbox[i].high-bbox[i].low;
+ if (span>max_span) {
+ computeMinMax(ind, count, i, min_elem, max_elem);
+ span = max_elem - min_elem;
+ if (span>max_span) {
+ max_span = span;
+ cutfeat = i;
+ cutval = (min_elem+max_elem)/2;
+ }
+ }
+ }
+ int lim1, lim2;
+ planeSplit(ind, count, cutfeat, cutval, lim1, lim2);
+
+ if (lim1>count/2) index = lim1;
+ else if (lim2<count/2) index = lim2;
+ else index = count/2;
+ }
+
+
+ void middleSplit_(int* ind, int count, int& index, int& cutfeat, DistanceType& cutval, const BoundingBox& bbox)
+ {
+ const float EPS=0.00001f;
+ DistanceType max_span = bbox[0].high-bbox[0].low;
+ for (size_t i=1; i<dim_; ++i) {
+ DistanceType span = bbox[i].high-bbox[i].low;
+ if (span>max_span) {
+ max_span = span;
+ }
+ }
+ DistanceType max_spread = -1;
+ cutfeat = 0;
+ for (size_t i=0; i<dim_; ++i) {
+ DistanceType span = bbox[i].high-bbox[i].low;
+ if (span>(DistanceType)((1-EPS)*max_span)) {
+ ElementType min_elem, max_elem;
+ computeMinMax(ind, count, cutfeat, min_elem, max_elem);
+ DistanceType spread = (DistanceType)(max_elem-min_elem);
+ if (spread>max_spread) {
+ cutfeat = (int)i;
+ max_spread = spread;
+ }
+ }
+ }
+ // split in the middle
+ DistanceType split_val = (bbox[cutfeat].low+bbox[cutfeat].high)/2;
+ ElementType min_elem, max_elem;
+ computeMinMax(ind, count, cutfeat, min_elem, max_elem);
+
+ if (split_val<min_elem) cutval = (DistanceType)min_elem;
+ else if (split_val>max_elem) cutval = (DistanceType)max_elem;
+ else cutval = split_val;
+
+ int lim1, lim2;
+ planeSplit(ind, count, cutfeat, cutval, lim1, lim2);
+
+ if (lim1>count/2) index = lim1;
+ else if (lim2<count/2) index = lim2;
+ else index = count/2;
+ }
+
+
+ /**
+ * Subdivide the list of points by a plane perpendicular on axe corresponding
+ * to the 'cutfeat' dimension at 'cutval' position.
+ *
+ * On return:
+ * dataset[ind[0..lim1-1]][cutfeat]<cutval
+ * dataset[ind[lim1..lim2-1]][cutfeat]==cutval
+ * dataset[ind[lim2..count]][cutfeat]>cutval
+ */
+ void planeSplit(int* ind, int count, int cutfeat, DistanceType cutval, int& lim1, int& lim2)
+ {
+ /* Move vector indices for left subtree to front of list. */
+ int left = 0;
+ int right = count-1;
+ for (;; ) {
+ while (left<=right && dataset_[ind[left]][cutfeat]<cutval) ++left;
+ while (left<=right && dataset_[ind[right]][cutfeat]>=cutval) --right;
+ if (left>right) break;
+ std::swap(ind[left], ind[right]); ++left; --right;
+ }
+ /* If either list is empty, it means that all remaining features
+ * are identical. Split in the middle to maintain a balanced tree.
+ */
+ lim1 = left;
+ right = count-1;
+ for (;; ) {
+ while (left<=right && dataset_[ind[left]][cutfeat]<=cutval) ++left;
+ while (left<=right && dataset_[ind[right]][cutfeat]>cutval) --right;
+ if (left>right) break;
+ std::swap(ind[left], ind[right]); ++left; --right;
+ }
+ lim2 = left;
+ }
+
+ DistanceType computeInitialDistances(const ElementType* vec, std::vector<DistanceType>& dists)
+ {
+ DistanceType distsq = 0.0;
+
+ for (size_t i = 0; i < dim_; ++i) {
+ if (vec[i] < root_bbox_[i].low) {
+ dists[i] = distance_.accum_dist(vec[i], root_bbox_[i].low, (int)i);
+ distsq += dists[i];
+ }
+ if (vec[i] > root_bbox_[i].high) {
+ dists[i] = distance_.accum_dist(vec[i], root_bbox_[i].high, (int)i);
+ distsq += dists[i];
+ }
+ }
+
+ return distsq;
+ }
+
+ /**
+ * Performs an exact search in the tree starting from a node.
+ */
+ void searchLevel(ResultSet<DistanceType>& result_set, const ElementType* vec, const NodePtr node, DistanceType mindistsq,
+ std::vector<DistanceType>& dists, const float epsError)
+ {
+ /* If this is a leaf node, then do check and return. */
+ if ((node->child1 == NULL)&&(node->child2 == NULL)) {
+ DistanceType worst_dist = result_set.worstDist();
+ for (int i=node->left; i<node->right; ++i) {
+ int index = reorder_ ? i : vind_[i];
+ DistanceType dist = distance_(vec, data_[index], dim_, worst_dist);
+ if (dist<worst_dist) {
+ result_set.addPoint(dist,vind_[i]);
+ }
+ }
+ return;
+ }
+
+ /* Which child branch should be taken first? */
+ int idx = node->divfeat;
+ ElementType val = vec[idx];
+ DistanceType diff1 = val - node->divlow;
+ DistanceType diff2 = val - node->divhigh;
+
+ NodePtr bestChild;
+ NodePtr otherChild;
+ DistanceType cut_dist;
+ if ((diff1+diff2)<0) {
+ bestChild = node->child1;
+ otherChild = node->child2;
+ cut_dist = distance_.accum_dist(val, node->divhigh, idx);
+ }
+ else {
+ bestChild = node->child2;
+ otherChild = node->child1;
+ cut_dist = distance_.accum_dist( val, node->divlow, idx);
+ }
+
+ /* Call recursively to search next level down. */
+ searchLevel(result_set, vec, bestChild, mindistsq, dists, epsError);
+
+ DistanceType dst = dists[idx];
+ mindistsq = mindistsq + cut_dist - dst;
+ dists[idx] = cut_dist;
+ if (mindistsq*epsError<=result_set.worstDist()) {
+ searchLevel(result_set, vec, otherChild, mindistsq, dists, epsError);
+ }
+ dists[idx] = dst;
+ }
+
+private:
+
+ /**
+ * The dataset used by this index
+ */
+ const Matrix<ElementType> dataset_;
+
+ IndexParams index_params_;
+
+ int leaf_max_size_;
+ bool reorder_;
+
+
+ /**
+ * Array of indices to vectors in the dataset.
+ */
+ std::vector<int> vind_;
+
+ Matrix<ElementType> data_;
+
+ size_t size_;
+ size_t dim_;
+
+ /**
+ * Array of k-d trees used to find neighbours.
+ */
+ NodePtr root_node_;
+
+ BoundingBox root_bbox_;
+
+ /**
+ * Pooled memory allocator.
+ *
+ * Using a pooled memory allocator is more efficient
+ * than allocating memory directly when there is a large
+ * number small of memory allocations.
+ */
+ PooledAllocator pool_;
+
+ Distance distance_;
+}; // class KDTree
+
+}
+
+#endif //OPENCV_FLANN_KDTREE_SINGLE_INDEX_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/flann/kmeans_index.h Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,1171 @@
+/***********************************************************************
+ * Software License Agreement (BSD License)
+ *
+ * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved.
+ * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved.
+ *
+ * THE BSD LICENSE
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *************************************************************************/
+
+#ifndef OPENCV_FLANN_KMEANS_INDEX_H_
+#define OPENCV_FLANN_KMEANS_INDEX_H_
+
+#include <algorithm>
+#include <map>
+#include <cassert>
+#include <limits>
+#include <cmath>
+
+#include "general.h"
+#include "nn_index.h"
+#include "dist.h"
+#include "matrix.h"
+#include "result_set.h"
+#include "heap.h"
+#include "allocator.h"
+#include "random.h"
+#include "saving.h"
+#include "logger.h"
+
+
+namespace cvflann
+{
+
+struct KMeansIndexParams : public IndexParams
+{
+ KMeansIndexParams(int branching = 32, int iterations = 11,
+ flann_centers_init_t centers_init = FLANN_CENTERS_RANDOM, float cb_index = 0.2 )
+ {
+ (*this)["algorithm"] = FLANN_INDEX_KMEANS;
+ // branching factor
+ (*this)["branching"] = branching;
+ // max iterations to perform in one kmeans clustering (kmeans tree)
+ (*this)["iterations"] = iterations;
+ // algorithm used for picking the initial cluster centers for kmeans tree
+ (*this)["centers_init"] = centers_init;
+ // cluster boundary index. Used when searching the kmeans tree
+ (*this)["cb_index"] = cb_index;
+ }
+};
+
+
+/**
+ * Hierarchical kmeans index
+ *
+ * Contains a tree constructed through a hierarchical kmeans clustering
+ * and other information for indexing a set of points for nearest-neighbour matching.
+ */
+template <typename Distance>
+class KMeansIndex : public NNIndex<Distance>
+{
+public:
+ typedef typename Distance::ElementType ElementType;
+ typedef typename Distance::ResultType DistanceType;
+
+
+
+ typedef void (KMeansIndex::* centersAlgFunction)(int, int*, int, int*, int&);
+
+ /**
+ * The function used for choosing the cluster centers.
+ */
+ centersAlgFunction chooseCenters;
+
+
+
+ /**
+ * Chooses the initial centers in the k-means clustering in a random manner.
+ *
+ * Params:
+ * k = number of centers
+ * vecs = the dataset of points
+ * indices = indices in the dataset
+ * indices_length = length of indices vector
+ *
+ */
+ void chooseCentersRandom(int k, int* indices, int indices_length, int* centers, int& centers_length)
+ {
+ UniqueRandom r(indices_length);
+
+ int index;
+ for (index=0; index<k; ++index) {
+ bool duplicate = true;
+ int rnd;
+ while (duplicate) {
+ duplicate = false;
+ rnd = r.next();
+ if (rnd<0) {
+ centers_length = index;
+ return;
+ }
+
+ centers[index] = indices[rnd];
+
+ for (int j=0; j<index; ++j) {
+ DistanceType sq = distance_(dataset_[centers[index]], dataset_[centers[j]], dataset_.cols);
+ if (sq<1e-16) {
+ duplicate = true;
+ }
+ }
+ }
+ }
+
+ centers_length = index;
+ }
+
+
+ /**
+ * Chooses the initial centers in the k-means using Gonzales' algorithm
+ * so that the centers are spaced apart from each other.
+ *
+ * Params:
+ * k = number of centers
+ * vecs = the dataset of points
+ * indices = indices in the dataset
+ * Returns:
+ */
+ void chooseCentersGonzales(int k, int* indices, int indices_length, int* centers, int& centers_length)
+ {
+ int n = indices_length;
+
+ int rnd = rand_int(n);
+ assert(rnd >=0 && rnd < n);
+
+ centers[0] = indices[rnd];
+
+ int index;
+ for (index=1; index<k; ++index) {
+
+ int best_index = -1;
+ DistanceType best_val = 0;
+ for (int j=0; j<n; ++j) {
+ DistanceType dist = distance_(dataset_[centers[0]],dataset_[indices[j]],dataset_.cols);
+ for (int i=1; i<index; ++i) {
+ DistanceType tmp_dist = distance_(dataset_[centers[i]],dataset_[indices[j]],dataset_.cols);
+ if (tmp_dist<dist) {
+ dist = tmp_dist;
+ }
+ }
+ if (dist>best_val) {
+ best_val = dist;
+ best_index = j;
+ }
+ }
+ if (best_index!=-1) {
+ centers[index] = indices[best_index];
+ }
+ else {
+ break;
+ }
+ }
+ centers_length = index;
+ }
+
+
+ /**
+ * Chooses the initial centers in the k-means using the algorithm
+ * proposed in the KMeans++ paper:
+ * Arthur, David; Vassilvitskii, Sergei - k-means++: The Advantages of Careful Seeding
+ *
+ * Implementation of this function was converted from the one provided in Arthur's code.
+ *
+ * Params:
+ * k = number of centers
+ * vecs = the dataset of points
+ * indices = indices in the dataset
+ * Returns:
+ */
+ void chooseCentersKMeanspp(int k, int* indices, int indices_length, int* centers, int& centers_length)
+ {
+ int n = indices_length;
+
+ double currentPot = 0;
+ DistanceType* closestDistSq = new DistanceType[n];
+
+ // Choose one random center and set the closestDistSq values
+ int index = rand_int(n);
+ assert(index >=0 && index < n);
+ centers[0] = indices[index];
+
+ for (int i = 0; i < n; i++) {
+ closestDistSq[i] = distance_(dataset_[indices[i]], dataset_[indices[index]], dataset_.cols);
+ closestDistSq[i] = ensureSquareDistance<Distance>( closestDistSq[i] );
+ currentPot += closestDistSq[i];
+ }
+
+
+ const int numLocalTries = 1;
+
+ // Choose each center
+ int centerCount;
+ for (centerCount = 1; centerCount < k; centerCount++) {
+
+ // Repeat several trials
+ double bestNewPot = -1;
+ int bestNewIndex = -1;
+ for (int localTrial = 0; localTrial < numLocalTries; localTrial++) {
+
+ // Choose our center - have to be slightly careful to return a valid answer even accounting
+ // for possible rounding errors
+ double randVal = rand_double(currentPot);
+ for (index = 0; index < n-1; index++) {
+ if (randVal <= closestDistSq[index]) break;
+ else randVal -= closestDistSq[index];
+ }
+
+ // Compute the new potential
+ double newPot = 0;
+ for (int i = 0; i < n; i++) {
+ DistanceType dist = distance_(dataset_[indices[i]], dataset_[indices[index]], dataset_.cols);
+ newPot += std::min( ensureSquareDistance<Distance>(dist), closestDistSq[i] );
+ }
+
+ // Store the best result
+ if ((bestNewPot < 0)||(newPot < bestNewPot)) {
+ bestNewPot = newPot;
+ bestNewIndex = index;
+ }
+ }
+
+ // Add the appropriate center
+ centers[centerCount] = indices[bestNewIndex];
+ currentPot = bestNewPot;
+ for (int i = 0; i < n; i++) {
+ DistanceType dist = distance_(dataset_[indices[i]], dataset_[indices[bestNewIndex]], dataset_.cols);
+ closestDistSq[i] = std::min( ensureSquareDistance<Distance>(dist), closestDistSq[i] );
+ }
+ }
+
+ centers_length = centerCount;
+
+ delete[] closestDistSq;
+ }
+
+
+
+public:
+
+ flann_algorithm_t getType() const
+ {
+ return FLANN_INDEX_KMEANS;
+ }
+
+ class KMeansDistanceComputer : public cv::ParallelLoopBody
+ {
+ public:
+ KMeansDistanceComputer(Distance _distance, const Matrix<ElementType>& _dataset,
+ const int _branching, const int* _indices, const Matrix<double>& _dcenters, const size_t _veclen,
+ int* _count, int* _belongs_to, std::vector<DistanceType>& _radiuses, bool& _converged, cv::Mutex& _mtx)
+ : distance(_distance)
+ , dataset(_dataset)
+ , branching(_branching)
+ , indices(_indices)
+ , dcenters(_dcenters)
+ , veclen(_veclen)
+ , count(_count)
+ , belongs_to(_belongs_to)
+ , radiuses(_radiuses)
+ , converged(_converged)
+ , mtx(_mtx)
+ {
+ }
+
+ void operator()(const cv::Range& range) const
+ {
+ const int begin = range.start;
+ const int end = range.end;
+
+ for( int i = begin; i<end; ++i)
+ {
+ DistanceType sq_dist = distance(dataset[indices[i]], dcenters[0], veclen);
+ int new_centroid = 0;
+ for (int j=1; j<branching; ++j) {
+ DistanceType new_sq_dist = distance(dataset[indices[i]], dcenters[j], veclen);
+ if (sq_dist>new_sq_dist) {
+ new_centroid = j;
+ sq_dist = new_sq_dist;
+ }
+ }
+ if (sq_dist > radiuses[new_centroid]) {
+ radiuses[new_centroid] = sq_dist;
+ }
+ if (new_centroid != belongs_to[i]) {
+ count[belongs_to[i]]--;
+ count[new_centroid]++;
+ belongs_to[i] = new_centroid;
+ mtx.lock();
+ converged = false;
+ mtx.unlock();
+ }
+ }
+ }
+
+ private:
+ Distance distance;
+ const Matrix<ElementType>& dataset;
+ const int branching;
+ const int* indices;
+ const Matrix<double>& dcenters;
+ const size_t veclen;
+ int* count;
+ int* belongs_to;
+ std::vector<DistanceType>& radiuses;
+ bool& converged;
+ cv::Mutex& mtx;
+ KMeansDistanceComputer& operator=( const KMeansDistanceComputer & ) { return *this; }
+ };
+
+ /**
+ * Index constructor
+ *
+ * Params:
+ * inputData = dataset with the input features
+ * params = parameters passed to the hierarchical k-means algorithm
+ */
+ KMeansIndex(const Matrix<ElementType>& inputData, const IndexParams& params = KMeansIndexParams(),
+ Distance d = Distance())
+ : dataset_(inputData), index_params_(params), root_(NULL), indices_(NULL), distance_(d)
+ {
+ memoryCounter_ = 0;
+
+ size_ = dataset_.rows;
+ veclen_ = dataset_.cols;
+
+ branching_ = get_param(params,"branching",32);
+ iterations_ = get_param(params,"iterations",11);
+ if (iterations_<0) {
+ iterations_ = (std::numeric_limits<int>::max)();
+ }
+ centers_init_ = get_param(params,"centers_init",FLANN_CENTERS_RANDOM);
+
+ if (centers_init_==FLANN_CENTERS_RANDOM) {
+ chooseCenters = &KMeansIndex::chooseCentersRandom;
+ }
+ else if (centers_init_==FLANN_CENTERS_GONZALES) {
+ chooseCenters = &KMeansIndex::chooseCentersGonzales;
+ }
+ else if (centers_init_==FLANN_CENTERS_KMEANSPP) {
+ chooseCenters = &KMeansIndex::chooseCentersKMeanspp;
+ }
+ else {
+ throw FLANNException("Unknown algorithm for choosing initial centers.");
+ }
+ cb_index_ = 0.4f;
+
+ }
+
+
+ KMeansIndex(const KMeansIndex&);
+ KMeansIndex& operator=(const KMeansIndex&);
+
+
+ /**
+ * Index destructor.
+ *
+ * Release the memory used by the index.
+ */
+ virtual ~KMeansIndex()
+ {
+ if (root_ != NULL) {
+ free_centers(root_);
+ }
+ if (indices_!=NULL) {
+ delete[] indices_;
+ }
+ }
+
+ /**
+ * Returns size of index.
+ */
+ size_t size() const
+ {
+ return size_;
+ }
+
+ /**
+ * Returns the length of an index feature.
+ */
+ size_t veclen() const
+ {
+ return veclen_;
+ }
+
+
+ void set_cb_index( float index)
+ {
+ cb_index_ = index;
+ }
+
+ /**
+ * Computes the inde memory usage
+ * Returns: memory used by the index
+ */
+ int usedMemory() const
+ {
+ return pool_.usedMemory+pool_.wastedMemory+memoryCounter_;
+ }
+
+ /**
+ * Builds the index
+ */
+ void buildIndex()
+ {
+ if (branching_<2) {
+ throw FLANNException("Branching factor must be at least 2");
+ }
+
+ indices_ = new int[size_];
+ for (size_t i=0; i<size_; ++i) {
+ indices_[i] = int(i);
+ }
+
+ root_ = pool_.allocate<KMeansNode>();
+ std::memset(root_, 0, sizeof(KMeansNode));
+
+ computeNodeStatistics(root_, indices_, (int)size_);
+ computeClustering(root_, indices_, (int)size_, branching_,0);
+ }
+
+
+ void saveIndex(FILE* stream)
+ {
+ save_value(stream, branching_);
+ save_value(stream, iterations_);
+ save_value(stream, memoryCounter_);
+ save_value(stream, cb_index_);
+ save_value(stream, *indices_, (int)size_);
+
+ save_tree(stream, root_);
+ }
+
+
+ void loadIndex(FILE* stream)
+ {
+ load_value(stream, branching_);
+ load_value(stream, iterations_);
+ load_value(stream, memoryCounter_);
+ load_value(stream, cb_index_);
+ if (indices_!=NULL) {
+ delete[] indices_;
+ }
+ indices_ = new int[size_];
+ load_value(stream, *indices_, size_);
+
+ if (root_!=NULL) {
+ free_centers(root_);
+ }
+ load_tree(stream, root_);
+
+ index_params_["algorithm"] = getType();
+ index_params_["branching"] = branching_;
+ index_params_["iterations"] = iterations_;
+ index_params_["centers_init"] = centers_init_;
+ index_params_["cb_index"] = cb_index_;
+
+ }
+
+
+ /**
+ * Find set of nearest neighbors to vec. Their indices are stored inside
+ * the result object.
+ *
+ * Params:
+ * result = the result object in which the indices of the nearest-neighbors are stored
+ * vec = the vector for which to search the nearest neighbors
+ * searchParams = parameters that influence the search algorithm (checks, cb_index)
+ */
+ void findNeighbors(ResultSet<DistanceType>& result, const ElementType* vec, const SearchParams& searchParams)
+ {
+
+ int maxChecks = get_param(searchParams,"checks",32);
+
+ if (maxChecks==FLANN_CHECKS_UNLIMITED) {
+ findExactNN(root_, result, vec);
+ }
+ else {
+ // Priority queue storing intermediate branches in the best-bin-first search
+ Heap<BranchSt>* heap = new Heap<BranchSt>((int)size_);
+
+ int checks = 0;
+ findNN(root_, result, vec, checks, maxChecks, heap);
+
+ BranchSt branch;
+ while (heap->popMin(branch) && (checks<maxChecks || !result.full())) {
+ KMeansNodePtr node = branch.node;
+ findNN(node, result, vec, checks, maxChecks, heap);
+ }
+ assert(result.full());
+
+ delete heap;
+ }
+
+ }
+
+ /**
+ * Clustering function that takes a cut in the hierarchical k-means
+ * tree and return the clusters centers of that clustering.
+ * Params:
+ * numClusters = number of clusters to have in the clustering computed
+ * Returns: number of cluster centers
+ */
+ int getClusterCenters(Matrix<DistanceType>& centers)
+ {
+ int numClusters = centers.rows;
+ if (numClusters<1) {
+ throw FLANNException("Number of clusters must be at least 1");
+ }
+
+ DistanceType variance;
+ KMeansNodePtr* clusters = new KMeansNodePtr[numClusters];
+
+ int clusterCount = getMinVarianceClusters(root_, clusters, numClusters, variance);
+
+ Logger::info("Clusters requested: %d, returning %d\n",numClusters, clusterCount);
+
+ for (int i=0; i<clusterCount; ++i) {
+ DistanceType* center = clusters[i]->pivot;
+ for (size_t j=0; j<veclen_; ++j) {
+ centers[i][j] = center[j];
+ }
+ }
+ delete[] clusters;
+
+ return clusterCount;
+ }
+
+ IndexParams getParameters() const
+ {
+ return index_params_;
+ }
+
+
+private:
+ /**
+ * Struture representing a node in the hierarchical k-means tree.
+ */
+ struct KMeansNode
+ {
+ /**
+ * The cluster center.
+ */
+ DistanceType* pivot;
+ /**
+ * The cluster radius.
+ */
+ DistanceType radius;
+ /**
+ * The cluster mean radius.
+ */
+ DistanceType mean_radius;
+ /**
+ * The cluster variance.
+ */
+ DistanceType variance;
+ /**
+ * The cluster size (number of points in the cluster)
+ */
+ int size;
+ /**
+ * Child nodes (only for non-terminal nodes)
+ */
+ KMeansNode** childs;
+ /**
+ * Node points (only for terminal nodes)
+ */
+ int* indices;
+ /**
+ * Level
+ */
+ int level;
+ };
+ typedef KMeansNode* KMeansNodePtr;
+
+ /**
+ * Alias definition for a nicer syntax.
+ */
+ typedef BranchStruct<KMeansNodePtr, DistanceType> BranchSt;
+
+
+
+
+ void save_tree(FILE* stream, KMeansNodePtr node)
+ {
+ save_value(stream, *node);
+ save_value(stream, *(node->pivot), (int)veclen_);
+ if (node->childs==NULL) {
+ int indices_offset = (int)(node->indices - indices_);
+ save_value(stream, indices_offset);
+ }
+ else {
+ for(int i=0; i<branching_; ++i) {
+ save_tree(stream, node->childs[i]);
+ }
+ }
+ }
+
+
+ void load_tree(FILE* stream, KMeansNodePtr& node)
+ {
+ node = pool_.allocate<KMeansNode>();
+ load_value(stream, *node);
+ node->pivot = new DistanceType[veclen_];
+ load_value(stream, *(node->pivot), (int)veclen_);
+ if (node->childs==NULL) {
+ int indices_offset;
+ load_value(stream, indices_offset);
+ node->indices = indices_ + indices_offset;
+ }
+ else {
+ node->childs = pool_.allocate<KMeansNodePtr>(branching_);
+ for(int i=0; i<branching_; ++i) {
+ load_tree(stream, node->childs[i]);
+ }
+ }
+ }
+
+
+ /**
+ * Helper function
+ */
+ void free_centers(KMeansNodePtr node)
+ {
+ delete[] node->pivot;
+ if (node->childs!=NULL) {
+ for (int k=0; k<branching_; ++k) {
+ free_centers(node->childs[k]);
+ }
+ }
+ }
+
+ /**
+ * Computes the statistics of a node (mean, radius, variance).
+ *
+ * Params:
+ * node = the node to use
+ * indices = the indices of the points belonging to the node
+ */
+ void computeNodeStatistics(KMeansNodePtr node, int* indices, int indices_length)
+ {
+
+ DistanceType radius = 0;
+ DistanceType variance = 0;
+ DistanceType* mean = new DistanceType[veclen_];
+ memoryCounter_ += int(veclen_*sizeof(DistanceType));
+
+ memset(mean,0,veclen_*sizeof(DistanceType));
+
+ for (size_t i=0; i<size_; ++i) {
+ ElementType* vec = dataset_[indices[i]];
+ for (size_t j=0; j<veclen_; ++j) {
+ mean[j] += vec[j];
+ }
+ variance += distance_(vec, ZeroIterator<ElementType>(), veclen_);
+ }
+ for (size_t j=0; j<veclen_; ++j) {
+ mean[j] /= size_;
+ }
+ variance /= size_;
+ variance -= distance_(mean, ZeroIterator<ElementType>(), veclen_);
+
+ DistanceType tmp = 0;
+ for (int i=0; i<indices_length; ++i) {
+ tmp = distance_(mean, dataset_[indices[i]], veclen_);
+ if (tmp>radius) {
+ radius = tmp;
+ }
+ }
+
+ node->variance = variance;
+ node->radius = radius;
+ node->pivot = mean;
+ }
+
+
+ /**
+ * The method responsible with actually doing the recursive hierarchical
+ * clustering
+ *
+ * Params:
+ * node = the node to cluster
+ * indices = indices of the points belonging to the current node
+ * branching = the branching factor to use in the clustering
+ *
+ * TODO: for 1-sized clusters don't store a cluster center (it's the same as the single cluster point)
+ */
+ void computeClustering(KMeansNodePtr node, int* indices, int indices_length, int branching, int level)
+ {
+ node->size = indices_length;
+ node->level = level;
+
+ if (indices_length < branching) {
+ node->indices = indices;
+ std::sort(node->indices,node->indices+indices_length);
+ node->childs = NULL;
+ return;
+ }
+
+ cv::AutoBuffer<int> centers_idx_buf(branching);
+ int* centers_idx = (int*)centers_idx_buf;
+ int centers_length;
+ (this->*chooseCenters)(branching, indices, indices_length, centers_idx, centers_length);
+
+ if (centers_length<branching) {
+ node->indices = indices;
+ std::sort(node->indices,node->indices+indices_length);
+ node->childs = NULL;
+ return;
+ }
+
+
+ cv::AutoBuffer<double> dcenters_buf(branching*veclen_);
+ Matrix<double> dcenters((double*)dcenters_buf,branching,veclen_);
+ for (int i=0; i<centers_length; ++i) {
+ ElementType* vec = dataset_[centers_idx[i]];
+ for (size_t k=0; k<veclen_; ++k) {
+ dcenters[i][k] = double(vec[k]);
+ }
+ }
+
+ std::vector<DistanceType> radiuses(branching);
+ cv::AutoBuffer<int> count_buf(branching);
+ int* count = (int*)count_buf;
+ for (int i=0; i<branching; ++i) {
+ radiuses[i] = 0;
+ count[i] = 0;
+ }
+
+ // assign points to clusters
+ cv::AutoBuffer<int> belongs_to_buf(indices_length);
+ int* belongs_to = (int*)belongs_to_buf;
+ for (int i=0; i<indices_length; ++i) {
+
+ DistanceType sq_dist = distance_(dataset_[indices[i]], dcenters[0], veclen_);
+ belongs_to[i] = 0;
+ for (int j=1; j<branching; ++j) {
+ DistanceType new_sq_dist = distance_(dataset_[indices[i]], dcenters[j], veclen_);
+ if (sq_dist>new_sq_dist) {
+ belongs_to[i] = j;
+ sq_dist = new_sq_dist;
+ }
+ }
+ if (sq_dist>radiuses[belongs_to[i]]) {
+ radiuses[belongs_to[i]] = sq_dist;
+ }
+ count[belongs_to[i]]++;
+ }
+
+ bool converged = false;
+ int iteration = 0;
+ while (!converged && iteration<iterations_) {
+ converged = true;
+ iteration++;
+
+ // compute the new cluster centers
+ for (int i=0; i<branching; ++i) {
+ memset(dcenters[i],0,sizeof(double)*veclen_);
+ radiuses[i] = 0;
+ }
+ for (int i=0; i<indices_length; ++i) {
+ ElementType* vec = dataset_[indices[i]];
+ double* center = dcenters[belongs_to[i]];
+ for (size_t k=0; k<veclen_; ++k) {
+ center[k] += vec[k];
+ }
+ }
+ for (int i=0; i<branching; ++i) {
+ int cnt = count[i];
+ for (size_t k=0; k<veclen_; ++k) {
+ dcenters[i][k] /= cnt;
+ }
+ }
+
+ // reassign points to clusters
+ cv::Mutex mtx;
+ KMeansDistanceComputer invoker(distance_, dataset_, branching, indices, dcenters, veclen_, count, belongs_to, radiuses, converged, mtx);
+ parallel_for_(cv::Range(0, (int)indices_length), invoker);
+
+ for (int i=0; i<branching; ++i) {
+ // if one cluster converges to an empty cluster,
+ // move an element into that cluster
+ if (count[i]==0) {
+ int j = (i+1)%branching;
+ while (count[j]<=1) {
+ j = (j+1)%branching;
+ }
+
+ for (int k=0; k<indices_length; ++k) {
+ if (belongs_to[k]==j) {
+ // for cluster j, we move the furthest element from the center to the empty cluster i
+ if ( distance_(dataset_[indices[k]], dcenters[j], veclen_) == radiuses[j] ) {
+ belongs_to[k] = i;
+ count[j]--;
+ count[i]++;
+ break;
+ }
+ }
+ }
+ converged = false;
+ }
+ }
+
+ }
+
+ DistanceType** centers = new DistanceType*[branching];
+
+ for (int i=0; i<branching; ++i) {
+ centers[i] = new DistanceType[veclen_];
+ memoryCounter_ += (int)(veclen_*sizeof(DistanceType));
+ for (size_t k=0; k<veclen_; ++k) {
+ centers[i][k] = (DistanceType)dcenters[i][k];
+ }
+ }
+
+
+ // compute kmeans clustering for each of the resulting clusters
+ node->childs = pool_.allocate<KMeansNodePtr>(branching);
+ int start = 0;
+ int end = start;
+ for (int c=0; c<branching; ++c) {
+ int s = count[c];
+
+ DistanceType variance = 0;
+ DistanceType mean_radius =0;
+ for (int i=0; i<indices_length; ++i) {
+ if (belongs_to[i]==c) {
+ DistanceType d = distance_(dataset_[indices[i]], ZeroIterator<ElementType>(), veclen_);
+ variance += d;
+ mean_radius += sqrt(d);
+ std::swap(indices[i],indices[end]);
+ std::swap(belongs_to[i],belongs_to[end]);
+ end++;
+ }
+ }
+ variance /= s;
+ mean_radius /= s;
+ variance -= distance_(centers[c], ZeroIterator<ElementType>(), veclen_);
+
+ node->childs[c] = pool_.allocate<KMeansNode>();
+ std::memset(node->childs[c], 0, sizeof(KMeansNode));
+ node->childs[c]->radius = radiuses[c];
+ node->childs[c]->pivot = centers[c];
+ node->childs[c]->variance = variance;
+ node->childs[c]->mean_radius = mean_radius;
+ computeClustering(node->childs[c],indices+start, end-start, branching, level+1);
+ start=end;
+ }
+
+ delete[] centers;
+ }
+
+
+
+ /**
+ * Performs one descent in the hierarchical k-means tree. The branches not
+ * visited are stored in a priority queue.
+ *
+ * Params:
+ * node = node to explore
+ * result = container for the k-nearest neighbors found
+ * vec = query points
+ * checks = how many points in the dataset have been checked so far
+ * maxChecks = maximum dataset points to checks
+ */
+
+
+ void findNN(KMeansNodePtr node, ResultSet<DistanceType>& result, const ElementType* vec, int& checks, int maxChecks,
+ Heap<BranchSt>* heap)
+ {
+ // Ignore those clusters that are too far away
+ {
+ DistanceType bsq = distance_(vec, node->pivot, veclen_);
+ DistanceType rsq = node->radius;
+ DistanceType wsq = result.worstDist();
+
+ DistanceType val = bsq-rsq-wsq;
+ DistanceType val2 = val*val-4*rsq*wsq;
+
+ //if (val>0) {
+ if ((val>0)&&(val2>0)) {
+ return;
+ }
+ }
+
+ if (node->childs==NULL) {
+ if (checks>=maxChecks) {
+ if (result.full()) return;
+ }
+ checks += node->size;
+ for (int i=0; i<node->size; ++i) {
+ int index = node->indices[i];
+ DistanceType dist = distance_(dataset_[index], vec, veclen_);
+ result.addPoint(dist, index);
+ }
+ }
+ else {
+ DistanceType* domain_distances = new DistanceType[branching_];
+ int closest_center = exploreNodeBranches(node, vec, domain_distances, heap);
+ delete[] domain_distances;
+ findNN(node->childs[closest_center],result,vec, checks, maxChecks, heap);
+ }
+ }
+
+ /**
+ * Helper function that computes the nearest childs of a node to a given query point.
+ * Params:
+ * node = the node
+ * q = the query point
+ * distances = array with the distances to each child node.
+ * Returns:
+ */
+ int exploreNodeBranches(KMeansNodePtr node, const ElementType* q, DistanceType* domain_distances, Heap<BranchSt>* heap)
+ {
+
+ int best_index = 0;
+ domain_distances[best_index] = distance_(q, node->childs[best_index]->pivot, veclen_);
+ for (int i=1; i<branching_; ++i) {
+ domain_distances[i] = distance_(q, node->childs[i]->pivot, veclen_);
+ if (domain_distances[i]<domain_distances[best_index]) {
+ best_index = i;
+ }
+ }
+
+ // float* best_center = node->childs[best_index]->pivot;
+ for (int i=0; i<branching_; ++i) {
+ if (i != best_index) {
+ domain_distances[i] -= cb_index_*node->childs[i]->variance;
+
+ // float dist_to_border = getDistanceToBorder(node.childs[i].pivot,best_center,q);
+ // if (domain_distances[i]<dist_to_border) {
+ // domain_distances[i] = dist_to_border;
+ // }
+ heap->insert(BranchSt(node->childs[i],domain_distances[i]));
+ }
+ }
+
+ return best_index;
+ }
+
+
+ /**
+ * Function the performs exact nearest neighbor search by traversing the entire tree.
+ */
+ void findExactNN(KMeansNodePtr node, ResultSet<DistanceType>& result, const ElementType* vec)
+ {
+ // Ignore those clusters that are too far away
+ {
+ DistanceType bsq = distance_(vec, node->pivot, veclen_);
+ DistanceType rsq = node->radius;
+ DistanceType wsq = result.worstDist();
+
+ DistanceType val = bsq-rsq-wsq;
+ DistanceType val2 = val*val-4*rsq*wsq;
+
+ // if (val>0) {
+ if ((val>0)&&(val2>0)) {
+ return;
+ }
+ }
+
+
+ if (node->childs==NULL) {
+ for (int i=0; i<node->size; ++i) {
+ int index = node->indices[i];
+ DistanceType dist = distance_(dataset_[index], vec, veclen_);
+ result.addPoint(dist, index);
+ }
+ }
+ else {
+ int* sort_indices = new int[branching_];
+
+ getCenterOrdering(node, vec, sort_indices);
+
+ for (int i=0; i<branching_; ++i) {
+ findExactNN(node->childs[sort_indices[i]],result,vec);
+ }
+
+ delete[] sort_indices;
+ }
+ }
+
+
+ /**
+ * Helper function.
+ *
+ * I computes the order in which to traverse the child nodes of a particular node.
+ */
+ void getCenterOrdering(KMeansNodePtr node, const ElementType* q, int* sort_indices)
+ {
+ DistanceType* domain_distances = new DistanceType[branching_];
+ for (int i=0; i<branching_; ++i) {
+ DistanceType dist = distance_(q, node->childs[i]->pivot, veclen_);
+
+ int j=0;
+ while (domain_distances[j]<dist && j<i) j++;
+ for (int k=i; k>j; --k) {
+ domain_distances[k] = domain_distances[k-1];
+ sort_indices[k] = sort_indices[k-1];
+ }
+ domain_distances[j] = dist;
+ sort_indices[j] = i;
+ }
+ delete[] domain_distances;
+ }
+
+ /**
+ * Method that computes the squared distance from the query point q
+ * from inside region with center c to the border between this
+ * region and the region with center p
+ */
+ DistanceType getDistanceToBorder(DistanceType* p, DistanceType* c, DistanceType* q)
+ {
+ DistanceType sum = 0;
+ DistanceType sum2 = 0;
+
+ for (int i=0; i<veclen_; ++i) {
+ DistanceType t = c[i]-p[i];
+ sum += t*(q[i]-(c[i]+p[i])/2);
+ sum2 += t*t;
+ }
+
+ return sum*sum/sum2;
+ }
+
+
+ /**
+ * Helper function the descends in the hierarchical k-means tree by spliting those clusters that minimize
+ * the overall variance of the clustering.
+ * Params:
+ * root = root node
+ * clusters = array with clusters centers (return value)
+ * varianceValue = variance of the clustering (return value)
+ * Returns:
+ */
+ int getMinVarianceClusters(KMeansNodePtr root, KMeansNodePtr* clusters, int clusters_length, DistanceType& varianceValue)
+ {
+ int clusterCount = 1;
+ clusters[0] = root;
+
+ DistanceType meanVariance = root->variance*root->size;
+
+ while (clusterCount<clusters_length) {
+ DistanceType minVariance = (std::numeric_limits<DistanceType>::max)();
+ int splitIndex = -1;
+
+ for (int i=0; i<clusterCount; ++i) {
+ if (clusters[i]->childs != NULL) {
+
+ DistanceType variance = meanVariance - clusters[i]->variance*clusters[i]->size;
+
+ for (int j=0; j<branching_; ++j) {
+ variance += clusters[i]->childs[j]->variance*clusters[i]->childs[j]->size;
+ }
+ if (variance<minVariance) {
+ minVariance = variance;
+ splitIndex = i;
+ }
+ }
+ }
+
+ if (splitIndex==-1) break;
+ if ( (branching_+clusterCount-1) > clusters_length) break;
+
+ meanVariance = minVariance;
+
+ // split node
+ KMeansNodePtr toSplit = clusters[splitIndex];
+ clusters[splitIndex] = toSplit->childs[0];
+ for (int i=1; i<branching_; ++i) {
+ clusters[clusterCount++] = toSplit->childs[i];
+ }
+ }
+
+ varianceValue = meanVariance/root->size;
+ return clusterCount;
+ }
+
+private:
+ /** The branching factor used in the hierarchical k-means clustering */
+ int branching_;
+
+ /** Maximum number of iterations to use when performing k-means clustering */
+ int iterations_;
+
+ /** Algorithm for choosing the cluster centers */
+ flann_centers_init_t centers_init_;
+
+ /**
+ * Cluster border index. This is used in the tree search phase when determining
+ * the closest cluster to explore next. A zero value takes into account only
+ * the cluster centres, a value greater then zero also take into account the size
+ * of the cluster.
+ */
+ float cb_index_;
+
+ /**
+ * The dataset used by this index
+ */
+ const Matrix<ElementType> dataset_;
+
+ /** Index parameters */
+ IndexParams index_params_;
+
+ /**
+ * Number of features in the dataset.
+ */
+ size_t size_;
+
+ /**
+ * Length of each feature.
+ */
+ size_t veclen_;
+
+ /**
+ * The root node in the tree.
+ */
+ KMeansNodePtr root_;
+
+ /**
+ * Array of indices to vectors in the dataset.
+ */
+ int* indices_;
+
+ /**
+ * The distance
+ */
+ Distance distance_;
+
+ /**
+ * Pooled memory allocator.
+ */
+ PooledAllocator pool_;
+
+ /**
+ * Memory occupied by the index.
+ */
+ int memoryCounter_;
+};
+
+}
+
+#endif //OPENCV_FLANN_KMEANS_INDEX_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/flann/linear_index.h Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,132 @@
+/***********************************************************************
+ * Software License Agreement (BSD License)
+ *
+ * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved.
+ * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved.
+ *
+ * THE BSD LICENSE
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *************************************************************************/
+
+#ifndef OPENCV_FLANN_LINEAR_INDEX_H_
+#define OPENCV_FLANN_LINEAR_INDEX_H_
+
+#include "general.h"
+#include "nn_index.h"
+
+namespace cvflann
+{
+
+struct LinearIndexParams : public IndexParams
+{
+ LinearIndexParams()
+ {
+ (* this)["algorithm"] = FLANN_INDEX_LINEAR;
+ }
+};
+
+template <typename Distance>
+class LinearIndex : public NNIndex<Distance>
+{
+public:
+
+ typedef typename Distance::ElementType ElementType;
+ typedef typename Distance::ResultType DistanceType;
+
+
+ LinearIndex(const Matrix<ElementType>& inputData, const IndexParams& params = LinearIndexParams(),
+ Distance d = Distance()) :
+ dataset_(inputData), index_params_(params), distance_(d)
+ {
+ }
+
+ LinearIndex(const LinearIndex&);
+ LinearIndex& operator=(const LinearIndex&);
+
+ flann_algorithm_t getType() const
+ {
+ return FLANN_INDEX_LINEAR;
+ }
+
+
+ size_t size() const
+ {
+ return dataset_.rows;
+ }
+
+ size_t veclen() const
+ {
+ return dataset_.cols;
+ }
+
+
+ int usedMemory() const
+ {
+ return 0;
+ }
+
+ void buildIndex()
+ {
+ /* nothing to do here for linear search */
+ }
+
+ void saveIndex(FILE*)
+ {
+ /* nothing to do here for linear search */
+ }
+
+
+ void loadIndex(FILE*)
+ {
+ /* nothing to do here for linear search */
+
+ index_params_["algorithm"] = getType();
+ }
+
+ void findNeighbors(ResultSet<DistanceType>& resultSet, const ElementType* vec, const SearchParams& /*searchParams*/)
+ {
+ ElementType* data = dataset_.data;
+ for (size_t i = 0; i < dataset_.rows; ++i, data += dataset_.cols) {
+ DistanceType dist = distance_(data, vec, dataset_.cols);
+ resultSet.addPoint(dist, (int)i);
+ }
+ }
+
+ IndexParams getParameters() const
+ {
+ return index_params_;
+ }
+
+private:
+ /** The dataset */
+ const Matrix<ElementType> dataset_;
+ /** Index parameters */
+ IndexParams index_params_;
+ /** Index distance */
+ Distance distance_;
+
+};
+
+}
+
+#endif // OPENCV_FLANN_LINEAR_INDEX_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/flann/logger.h Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,130 @@
+/***********************************************************************
+ * Software License Agreement (BSD License)
+ *
+ * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved.
+ * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved.
+ *
+ * THE BSD LICENSE
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *************************************************************************/
+
+#ifndef OPENCV_FLANN_LOGGER_H
+#define OPENCV_FLANN_LOGGER_H
+
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "defines.h"
+
+
+namespace cvflann
+{
+
+class Logger
+{
+ Logger() : stream(stdout), logLevel(FLANN_LOG_WARN) {}
+
+ ~Logger()
+ {
+ if ((stream!=NULL)&&(stream!=stdout)) {
+ fclose(stream);
+ }
+ }
+
+ static Logger& instance()
+ {
+ static Logger logger;
+ return logger;
+ }
+
+ void _setDestination(const char* name)
+ {
+ if (name==NULL) {
+ stream = stdout;
+ }
+ else {
+ stream = fopen(name,"w");
+ if (stream == NULL) {
+ stream = stdout;
+ }
+ }
+ }
+
+ int _log(int level, const char* fmt, va_list arglist)
+ {
+ if (level > logLevel ) return -1;
+ int ret = vfprintf(stream, fmt, arglist);
+ return ret;
+ }
+
+public:
+ /**
+ * Sets the logging level. All messages with lower priority will be ignored.
+ * @param level Logging level
+ */
+ static void setLevel(int level) { instance().logLevel = level; }
+
+ /**
+ * Sets the logging destination
+ * @param name Filename or NULL for console
+ */
+ static void setDestination(const char* name) { instance()._setDestination(name); }
+
+ /**
+ * Print log message
+ * @param level Log level
+ * @param fmt Message format
+ * @return
+ */
+ static int log(int level, const char* fmt, ...)
+ {
+ va_list arglist;
+ va_start(arglist, fmt);
+ int ret = instance()._log(level,fmt,arglist);
+ va_end(arglist);
+ return ret;
+ }
+
+#define LOG_METHOD(NAME,LEVEL) \
+ static int NAME(const char* fmt, ...) \
+ { \
+ va_list ap; \
+ va_start(ap, fmt); \
+ int ret = instance()._log(LEVEL, fmt, ap); \
+ va_end(ap); \
+ return ret; \
+ }
+
+ LOG_METHOD(fatal, FLANN_LOG_FATAL)
+ LOG_METHOD(error, FLANN_LOG_ERROR)
+ LOG_METHOD(warn, FLANN_LOG_WARN)
+ LOG_METHOD(info, FLANN_LOG_INFO)
+
+private:
+ FILE* stream;
+ int logLevel;
+};
+
+}
+
+#endif //OPENCV_FLANN_LOGGER_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/flann/lsh_index.h Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,392 @@
+/***********************************************************************
+ * Software License Agreement (BSD License)
+ *
+ * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved.
+ * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved.
+ *
+ * THE BSD LICENSE
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *************************************************************************/
+
+/***********************************************************************
+ * Author: Vincent Rabaud
+ *************************************************************************/
+
+#ifndef OPENCV_FLANN_LSH_INDEX_H_
+#define OPENCV_FLANN_LSH_INDEX_H_
+
+#include <algorithm>
+#include <cassert>
+#include <cstring>
+#include <map>
+#include <vector>
+
+#include "general.h"
+#include "nn_index.h"
+#include "matrix.h"
+#include "result_set.h"
+#include "heap.h"
+#include "lsh_table.h"
+#include "allocator.h"
+#include "random.h"
+#include "saving.h"
+
+namespace cvflann
+{
+
+struct LshIndexParams : public IndexParams
+{
+ LshIndexParams(unsigned int table_number = 12, unsigned int key_size = 20, unsigned int multi_probe_level = 2)
+ {
+ (* this)["algorithm"] = FLANN_INDEX_LSH;
+ // The number of hash tables to use
+ (*this)["table_number"] = table_number;
+ // The length of the key in the hash tables
+ (*this)["key_size"] = key_size;
+ // Number of levels to use in multi-probe (0 for standard LSH)
+ (*this)["multi_probe_level"] = multi_probe_level;
+ }
+};
+
+/**
+ * Randomized kd-tree index
+ *
+ * Contains the k-d trees and other information for indexing a set of points
+ * for nearest-neighbor matching.
+ */
+template<typename Distance>
+class LshIndex : public NNIndex<Distance>
+{
+public:
+ typedef typename Distance::ElementType ElementType;
+ typedef typename Distance::ResultType DistanceType;
+
+ /** Constructor
+ * @param input_data dataset with the input features
+ * @param params parameters passed to the LSH algorithm
+ * @param d the distance used
+ */
+ LshIndex(const Matrix<ElementType>& input_data, const IndexParams& params = LshIndexParams(),
+ Distance d = Distance()) :
+ dataset_(input_data), index_params_(params), distance_(d)
+ {
+ // cv::flann::IndexParams sets integer params as 'int', so it is used with get_param
+ // in place of 'unsigned int'
+ table_number_ = (unsigned int)get_param<int>(index_params_,"table_number",12);
+ key_size_ = (unsigned int)get_param<int>(index_params_,"key_size",20);
+ multi_probe_level_ = (unsigned int)get_param<int>(index_params_,"multi_probe_level",2);
+
+ feature_size_ = (unsigned)dataset_.cols;
+ fill_xor_mask(0, key_size_, multi_probe_level_, xor_masks_);
+ }
+
+
+ LshIndex(const LshIndex&);
+ LshIndex& operator=(const LshIndex&);
+
+ /**
+ * Builds the index
+ */
+ void buildIndex()
+ {
+ tables_.resize(table_number_);
+ for (unsigned int i = 0; i < table_number_; ++i) {
+ lsh::LshTable<ElementType>& table = tables_[i];
+ table = lsh::LshTable<ElementType>(feature_size_, key_size_);
+
+ // Add the features to the table
+ table.add(dataset_);
+ }
+ }
+
+ flann_algorithm_t getType() const
+ {
+ return FLANN_INDEX_LSH;
+ }
+
+
+ void saveIndex(FILE* stream)
+ {
+ save_value(stream,table_number_);
+ save_value(stream,key_size_);
+ save_value(stream,multi_probe_level_);
+ save_value(stream, dataset_);
+ }
+
+ void loadIndex(FILE* stream)
+ {
+ load_value(stream, table_number_);
+ load_value(stream, key_size_);
+ load_value(stream, multi_probe_level_);
+ load_value(stream, dataset_);
+ // Building the index is so fast we can afford not storing it
+ buildIndex();
+
+ index_params_["algorithm"] = getType();
+ index_params_["table_number"] = table_number_;
+ index_params_["key_size"] = key_size_;
+ index_params_["multi_probe_level"] = multi_probe_level_;
+ }
+
+ /**
+ * Returns size of index.
+ */
+ size_t size() const
+ {
+ return dataset_.rows;
+ }
+
+ /**
+ * Returns the length of an index feature.
+ */
+ size_t veclen() const
+ {
+ return feature_size_;
+ }
+
+ /**
+ * Computes the index memory usage
+ * Returns: memory used by the index
+ */
+ int usedMemory() const
+ {
+ return (int)(dataset_.rows * sizeof(int));
+ }
+
+
+ IndexParams getParameters() const
+ {
+ return index_params_;
+ }
+
+ /**
+ * \brief Perform k-nearest neighbor search
+ * \param[in] queries The query points for which to find the nearest neighbors
+ * \param[out] indices The indices of the nearest neighbors found
+ * \param[out] dists Distances to the nearest neighbors found
+ * \param[in] knn Number of nearest neighbors to return
+ * \param[in] params Search parameters
+ */
+ virtual void knnSearch(const Matrix<ElementType>& queries, Matrix<int>& indices, Matrix<DistanceType>& dists, int knn, const SearchParams& params)
+ {
+ assert(queries.cols == veclen());
+ assert(indices.rows >= queries.rows);
+ assert(dists.rows >= queries.rows);
+ assert(int(indices.cols) >= knn);
+ assert(int(dists.cols) >= knn);
+
+
+ KNNUniqueResultSet<DistanceType> resultSet(knn);
+ for (size_t i = 0; i < queries.rows; i++) {
+ resultSet.clear();
+ std::fill_n(indices[i], knn, -1);
+ std::fill_n(dists[i], knn, std::numeric_limits<DistanceType>::max());
+ findNeighbors(resultSet, queries[i], params);
+ if (get_param(params,"sorted",true)) resultSet.sortAndCopy(indices[i], dists[i], knn);
+ else resultSet.copy(indices[i], dists[i], knn);
+ }
+ }
+
+
+ /**
+ * Find set of nearest neighbors to vec. Their indices are stored inside
+ * the result object.
+ *
+ * Params:
+ * result = the result object in which the indices of the nearest-neighbors are stored
+ * vec = the vector for which to search the nearest neighbors
+ * maxCheck = the maximum number of restarts (in a best-bin-first manner)
+ */
+ void findNeighbors(ResultSet<DistanceType>& result, const ElementType* vec, const SearchParams& /*searchParams*/)
+ {
+ getNeighbors(vec, result);
+ }
+
+private:
+ /** Defines the comparator on score and index
+ */
+ typedef std::pair<float, unsigned int> ScoreIndexPair;
+ struct SortScoreIndexPairOnSecond
+ {
+ bool operator()(const ScoreIndexPair& left, const ScoreIndexPair& right) const
+ {
+ return left.second < right.second;
+ }
+ };
+
+ /** Fills the different xor masks to use when getting the neighbors in multi-probe LSH
+ * @param key the key we build neighbors from
+ * @param lowest_index the lowest index of the bit set
+ * @param level the multi-probe level we are at
+ * @param xor_masks all the xor mask
+ */
+ void fill_xor_mask(lsh::BucketKey key, int lowest_index, unsigned int level,
+ std::vector<lsh::BucketKey>& xor_masks)
+ {
+ xor_masks.push_back(key);
+ if (level == 0) return;
+ for (int index = lowest_index - 1; index >= 0; --index) {
+ // Create a new key
+ lsh::BucketKey new_key = key | (1 << index);
+ fill_xor_mask(new_key, index, level - 1, xor_masks);
+ }
+ }
+
+ /** Performs the approximate nearest-neighbor search.
+ * @param vec the feature to analyze
+ * @param do_radius flag indicating if we check the radius too
+ * @param radius the radius if it is a radius search
+ * @param do_k flag indicating if we limit the number of nn
+ * @param k_nn the number of nearest neighbors
+ * @param checked_average used for debugging
+ */
+ void getNeighbors(const ElementType* vec, bool /*do_radius*/, float radius, bool do_k, unsigned int k_nn,
+ float& /*checked_average*/)
+ {
+ static std::vector<ScoreIndexPair> score_index_heap;
+
+ if (do_k) {
+ unsigned int worst_score = std::numeric_limits<unsigned int>::max();
+ typename std::vector<lsh::LshTable<ElementType> >::const_iterator table = tables_.begin();
+ typename std::vector<lsh::LshTable<ElementType> >::const_iterator table_end = tables_.end();
+ for (; table != table_end; ++table) {
+ size_t key = table->getKey(vec);
+ std::vector<lsh::BucketKey>::const_iterator xor_mask = xor_masks_.begin();
+ std::vector<lsh::BucketKey>::const_iterator xor_mask_end = xor_masks_.end();
+ for (; xor_mask != xor_mask_end; ++xor_mask) {
+ size_t sub_key = key ^ (*xor_mask);
+ const lsh::Bucket* bucket = table->getBucketFromKey(sub_key);
+ if (bucket == 0) continue;
+
+ // Go over each descriptor index
+ std::vector<lsh::FeatureIndex>::const_iterator training_index = bucket->begin();
+ std::vector<lsh::FeatureIndex>::const_iterator last_training_index = bucket->end();
+ DistanceType hamming_distance;
+
+ // Process the rest of the candidates
+ for (; training_index < last_training_index; ++training_index) {
+ hamming_distance = distance_(vec, dataset_[*training_index], dataset_.cols);
+
+ if (hamming_distance < worst_score) {
+ // Insert the new element
+ score_index_heap.push_back(ScoreIndexPair(hamming_distance, training_index));
+ std::push_heap(score_index_heap.begin(), score_index_heap.end());
+
+ if (score_index_heap.size() > (unsigned int)k_nn) {
+ // Remove the highest distance value as we have too many elements
+ std::pop_heap(score_index_heap.begin(), score_index_heap.end());
+ score_index_heap.pop_back();
+ // Keep track of the worst score
+ worst_score = score_index_heap.front().first;
+ }
+ }
+ }
+ }
+ }
+ }
+ else {
+ typename std::vector<lsh::LshTable<ElementType> >::const_iterator table = tables_.begin();
+ typename std::vector<lsh::LshTable<ElementType> >::const_iterator table_end = tables_.end();
+ for (; table != table_end; ++table) {
+ size_t key = table->getKey(vec);
+ std::vector<lsh::BucketKey>::const_iterator xor_mask = xor_masks_.begin();
+ std::vector<lsh::BucketKey>::const_iterator xor_mask_end = xor_masks_.end();
+ for (; xor_mask != xor_mask_end; ++xor_mask) {
+ size_t sub_key = key ^ (*xor_mask);
+ const lsh::Bucket* bucket = table->getBucketFromKey(sub_key);
+ if (bucket == 0) continue;
+
+ // Go over each descriptor index
+ std::vector<lsh::FeatureIndex>::const_iterator training_index = bucket->begin();
+ std::vector<lsh::FeatureIndex>::const_iterator last_training_index = bucket->end();
+ DistanceType hamming_distance;
+
+ // Process the rest of the candidates
+ for (; training_index < last_training_index; ++training_index) {
+ // Compute the Hamming distance
+ hamming_distance = distance_(vec, dataset_[*training_index], dataset_.cols);
+ if (hamming_distance < radius) score_index_heap.push_back(ScoreIndexPair(hamming_distance, training_index));
+ }
+ }
+ }
+ }
+ }
+
+ /** Performs the approximate nearest-neighbor search.
+ * This is a slower version than the above as it uses the ResultSet
+ * @param vec the feature to analyze
+ */
+ void getNeighbors(const ElementType* vec, ResultSet<DistanceType>& result)
+ {
+ typename std::vector<lsh::LshTable<ElementType> >::const_iterator table = tables_.begin();
+ typename std::vector<lsh::LshTable<ElementType> >::const_iterator table_end = tables_.end();
+ for (; table != table_end; ++table) {
+ size_t key = table->getKey(vec);
+ std::vector<lsh::BucketKey>::const_iterator xor_mask = xor_masks_.begin();
+ std::vector<lsh::BucketKey>::const_iterator xor_mask_end = xor_masks_.end();
+ for (; xor_mask != xor_mask_end; ++xor_mask) {
+ size_t sub_key = key ^ (*xor_mask);
+ const lsh::Bucket* bucket = table->getBucketFromKey((lsh::BucketKey)sub_key);
+ if (bucket == 0) continue;
+
+ // Go over each descriptor index
+ std::vector<lsh::FeatureIndex>::const_iterator training_index = bucket->begin();
+ std::vector<lsh::FeatureIndex>::const_iterator last_training_index = bucket->end();
+ DistanceType hamming_distance;
+
+ // Process the rest of the candidates
+ for (; training_index < last_training_index; ++training_index) {
+ // Compute the Hamming distance
+ hamming_distance = distance_(vec, dataset_[*training_index], (int)dataset_.cols);
+ result.addPoint(hamming_distance, *training_index);
+ }
+ }
+ }
+ }
+
+ /** The different hash tables */
+ std::vector<lsh::LshTable<ElementType> > tables_;
+
+ /** The data the LSH tables where built from */
+ Matrix<ElementType> dataset_;
+
+ /** The size of the features (as ElementType[]) */
+ unsigned int feature_size_;
+
+ IndexParams index_params_;
+
+ /** table number */
+ unsigned int table_number_;
+ /** key size */
+ unsigned int key_size_;
+ /** How far should we look for neighbors in multi-probe LSH */
+ unsigned int multi_probe_level_;
+
+ /** The XOR masks to apply to a key to get the neighboring buckets */
+ std::vector<lsh::BucketKey> xor_masks_;
+
+ Distance distance_;
+};
+}
+
+#endif //OPENCV_FLANN_LSH_INDEX_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/flann/lsh_table.h Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,492 @@
+/***********************************************************************
+ * Software License Agreement (BSD License)
+ *
+ * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved.
+ * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved.
+ *
+ * THE BSD LICENSE
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *************************************************************************/
+
+/***********************************************************************
+ * Author: Vincent Rabaud
+ *************************************************************************/
+
+#ifndef OPENCV_FLANN_LSH_TABLE_H_
+#define OPENCV_FLANN_LSH_TABLE_H_
+
+#include <algorithm>
+#include <iostream>
+#include <iomanip>
+#include <limits.h>
+// TODO as soon as we use C++0x, use the code in USE_UNORDERED_MAP
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+# define USE_UNORDERED_MAP 1
+#else
+# define USE_UNORDERED_MAP 0
+#endif
+#if USE_UNORDERED_MAP
+#include <unordered_map>
+#else
+#include <map>
+#endif
+#include <math.h>
+#include <stddef.h>
+
+#include "dynamic_bitset.h"
+#include "matrix.h"
+
+namespace cvflann
+{
+
+namespace lsh
+{
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+/** What is stored in an LSH bucket
+ */
+typedef uint32_t FeatureIndex;
+/** The id from which we can get a bucket back in an LSH table
+ */
+typedef unsigned int BucketKey;
+
+/** A bucket in an LSH table
+ */
+typedef std::vector<FeatureIndex> Bucket;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+/** POD for stats about an LSH table
+ */
+struct LshStats
+{
+ std::vector<unsigned int> bucket_sizes_;
+ size_t n_buckets_;
+ size_t bucket_size_mean_;
+ size_t bucket_size_median_;
+ size_t bucket_size_min_;
+ size_t bucket_size_max_;
+ size_t bucket_size_std_dev;
+ /** Each contained vector contains three value: beginning/end for interval, number of elements in the bin
+ */
+ std::vector<std::vector<unsigned int> > size_histogram_;
+};
+
+/** Overload the << operator for LshStats
+ * @param out the streams
+ * @param stats the stats to display
+ * @return the streams
+ */
+inline std::ostream& operator <<(std::ostream& out, const LshStats& stats)
+{
+ int w = 20;
+ out << "Lsh Table Stats:\n" << std::setw(w) << std::setiosflags(std::ios::right) << "N buckets : "
+ << stats.n_buckets_ << "\n" << std::setw(w) << std::setiosflags(std::ios::right) << "mean size : "
+ << std::setiosflags(std::ios::left) << stats.bucket_size_mean_ << "\n" << std::setw(w)
+ << std::setiosflags(std::ios::right) << "median size : " << stats.bucket_size_median_ << "\n" << std::setw(w)
+ << std::setiosflags(std::ios::right) << "min size : " << std::setiosflags(std::ios::left)
+ << stats.bucket_size_min_ << "\n" << std::setw(w) << std::setiosflags(std::ios::right) << "max size : "
+ << std::setiosflags(std::ios::left) << stats.bucket_size_max_;
+
+ // Display the histogram
+ out << std::endl << std::setw(w) << std::setiosflags(std::ios::right) << "histogram : "
+ << std::setiosflags(std::ios::left);
+ for (std::vector<std::vector<unsigned int> >::const_iterator iterator = stats.size_histogram_.begin(), end =
+ stats.size_histogram_.end(); iterator != end; ++iterator) out << (*iterator)[0] << "-" << (*iterator)[1] << ": " << (*iterator)[2] << ", ";
+
+ return out;
+}
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+/** Lsh hash table. As its key is a sub-feature, and as usually
+ * the size of it is pretty small, we keep it as a continuous memory array.
+ * The value is an index in the corpus of features (we keep it as an unsigned
+ * int for pure memory reasons, it could be a size_t)
+ */
+template<typename ElementType>
+class LshTable
+{
+public:
+ /** A container of all the feature indices. Optimized for space
+ */
+#if USE_UNORDERED_MAP
+ typedef std::unordered_map<BucketKey, Bucket> BucketsSpace;
+#else
+ typedef std::map<BucketKey, Bucket> BucketsSpace;
+#endif
+
+ /** A container of all the feature indices. Optimized for speed
+ */
+ typedef std::vector<Bucket> BucketsSpeed;
+
+ /** Default constructor
+ */
+ LshTable()
+ {
+ }
+
+ /** Default constructor
+ * Create the mask and allocate the memory
+ * @param feature_size is the size of the feature (considered as a ElementType[])
+ * @param key_size is the number of bits that are turned on in the feature
+ */
+ LshTable(unsigned int feature_size, unsigned int key_size)
+ {
+ (void)feature_size;
+ (void)key_size;
+ std::cerr << "LSH is not implemented for that type" << std::endl;
+ assert(0);
+ }
+
+ /** Add a feature to the table
+ * @param value the value to store for that feature
+ * @param feature the feature itself
+ */
+ void add(unsigned int value, const ElementType* feature)
+ {
+ // Add the value to the corresponding bucket
+ BucketKey key = (lsh::BucketKey)getKey(feature);
+
+ switch (speed_level_) {
+ case kArray:
+ // That means we get the buckets from an array
+ buckets_speed_[key].push_back(value);
+ break;
+ case kBitsetHash:
+ // That means we can check the bitset for the presence of a key
+ key_bitset_.set(key);
+ buckets_space_[key].push_back(value);
+ break;
+ case kHash:
+ {
+ // That means we have to check for the hash table for the presence of a key
+ buckets_space_[key].push_back(value);
+ break;
+ }
+ }
+ }
+
+ /** Add a set of features to the table
+ * @param dataset the values to store
+ */
+ void add(Matrix<ElementType> dataset)
+ {
+#if USE_UNORDERED_MAP
+ buckets_space_.rehash((buckets_space_.size() + dataset.rows) * 1.2);
+#endif
+ // Add the features to the table
+ for (unsigned int i = 0; i < dataset.rows; ++i) add(i, dataset[i]);
+ // Now that the table is full, optimize it for speed/space
+ optimize();
+ }
+
+ /** Get a bucket given the key
+ * @param key
+ * @return
+ */
+ inline const Bucket* getBucketFromKey(BucketKey key) const
+ {
+ // Generate other buckets
+ switch (speed_level_) {
+ case kArray:
+ // That means we get the buckets from an array
+ return &buckets_speed_[key];
+ break;
+ case kBitsetHash:
+ // That means we can check the bitset for the presence of a key
+ if (key_bitset_.test(key)) return &buckets_space_.find(key)->second;
+ else return 0;
+ break;
+ case kHash:
+ {
+ // That means we have to check for the hash table for the presence of a key
+ BucketsSpace::const_iterator bucket_it, bucket_end = buckets_space_.end();
+ bucket_it = buckets_space_.find(key);
+ // Stop here if that bucket does not exist
+ if (bucket_it == bucket_end) return 0;
+ else return &bucket_it->second;
+ break;
+ }
+ }
+ return 0;
+ }
+
+ /** Compute the sub-signature of a feature
+ */
+ size_t getKey(const ElementType* /*feature*/) const
+ {
+ std::cerr << "LSH is not implemented for that type" << std::endl;
+ assert(0);
+ return 1;
+ }
+
+ /** Get statistics about the table
+ * @return
+ */
+ LshStats getStats() const;
+
+private:
+ /** defines the speed fo the implementation
+ * kArray uses a vector for storing data
+ * kBitsetHash uses a hash map but checks for the validity of a key with a bitset
+ * kHash uses a hash map only
+ */
+ enum SpeedLevel
+ {
+ kArray, kBitsetHash, kHash
+ };
+
+ /** Initialize some variables
+ */
+ void initialize(size_t key_size)
+ {
+ const size_t key_size_lower_bound = 1;
+ //a value (size_t(1) << key_size) must fit the size_t type so key_size has to be strictly less than size of size_t
+ const size_t key_size_upper_bound = (std::min)(sizeof(BucketKey) * CHAR_BIT + 1, sizeof(size_t) * CHAR_BIT);
+ if (key_size < key_size_lower_bound || key_size >= key_size_upper_bound)
+ {
+ CV_Error(cv::Error::StsBadArg, cv::format("Invalid key_size (=%d). Valid values for your system are %d <= key_size < %d.", (int)key_size, (int)key_size_lower_bound, (int)key_size_upper_bound));
+ }
+
+ speed_level_ = kHash;
+ key_size_ = (unsigned)key_size;
+ }
+
+ /** Optimize the table for speed/space
+ */
+ void optimize()
+ {
+ // If we are already using the fast storage, no need to do anything
+ if (speed_level_ == kArray) return;
+
+ // Use an array if it will be more than half full
+ if (buckets_space_.size() > ((size_t(1) << key_size_) / 2)) {
+ speed_level_ = kArray;
+ // Fill the array version of it
+ buckets_speed_.resize(size_t(1) << key_size_);
+ for (BucketsSpace::const_iterator key_bucket = buckets_space_.begin(); key_bucket != buckets_space_.end(); ++key_bucket) buckets_speed_[key_bucket->first] = key_bucket->second;
+
+ // Empty the hash table
+ buckets_space_.clear();
+ return;
+ }
+
+ // If the bitset is going to use less than 10% of the RAM of the hash map (at least 1 size_t for the key and two
+ // for the vector) or less than 512MB (key_size_ <= 30)
+ if (((std::max(buckets_space_.size(), buckets_speed_.size()) * CHAR_BIT * 3 * sizeof(BucketKey)) / 10
+ >= (size_t(1) << key_size_)) || (key_size_ <= 32)) {
+ speed_level_ = kBitsetHash;
+ key_bitset_.resize(size_t(1) << key_size_);
+ key_bitset_.reset();
+ // Try with the BucketsSpace
+ for (BucketsSpace::const_iterator key_bucket = buckets_space_.begin(); key_bucket != buckets_space_.end(); ++key_bucket) key_bitset_.set(key_bucket->first);
+ }
+ else {
+ speed_level_ = kHash;
+ key_bitset_.clear();
+ }
+ }
+
+ /** The vector of all the buckets if they are held for speed
+ */
+ BucketsSpeed buckets_speed_;
+
+ /** The hash table of all the buckets in case we cannot use the speed version
+ */
+ BucketsSpace buckets_space_;
+
+ /** What is used to store the data */
+ SpeedLevel speed_level_;
+
+ /** If the subkey is small enough, it will keep track of which subkeys are set through that bitset
+ * That is just a speedup so that we don't look in the hash table (which can be mush slower that checking a bitset)
+ */
+ DynamicBitset key_bitset_;
+
+ /** The size of the sub-signature in bits
+ */
+ unsigned int key_size_;
+
+ // Members only used for the unsigned char specialization
+ /** The mask to apply to a feature to get the hash key
+ * Only used in the unsigned char case
+ */
+ std::vector<size_t> mask_;
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Specialization for unsigned char
+
+template<>
+inline LshTable<unsigned char>::LshTable(unsigned int feature_size, unsigned int subsignature_size)
+{
+ initialize(subsignature_size);
+ // Allocate the mask
+ mask_ = std::vector<size_t>((size_t)ceil((float)(feature_size * sizeof(char)) / (float)sizeof(size_t)), 0);
+
+ // A bit brutal but fast to code
+ std::vector<size_t> indices(feature_size * CHAR_BIT);
+ for (size_t i = 0; i < feature_size * CHAR_BIT; ++i) indices[i] = i;
+ std::random_shuffle(indices.begin(), indices.end());
+
+ // Generate a random set of order of subsignature_size_ bits
+ for (unsigned int i = 0; i < key_size_; ++i) {
+ size_t index = indices[i];
+
+ // Set that bit in the mask
+ size_t divisor = CHAR_BIT * sizeof(size_t);
+ size_t idx = index / divisor; //pick the right size_t index
+ mask_[idx] |= size_t(1) << (index % divisor); //use modulo to find the bit offset
+ }
+
+ // Set to 1 if you want to display the mask for debug
+#if 0
+ {
+ size_t bcount = 0;
+ BOOST_FOREACH(size_t mask_block, mask_){
+ out << std::setw(sizeof(size_t) * CHAR_BIT / 4) << std::setfill('0') << std::hex << mask_block
+ << std::endl;
+ bcount += __builtin_popcountll(mask_block);
+ }
+ out << "bit count : " << std::dec << bcount << std::endl;
+ out << "mask size : " << mask_.size() << std::endl;
+ return out;
+ }
+#endif
+}
+
+/** Return the Subsignature of a feature
+ * @param feature the feature to analyze
+ */
+template<>
+inline size_t LshTable<unsigned char>::getKey(const unsigned char* feature) const
+{
+ // no need to check if T is dividable by sizeof(size_t) like in the Hamming
+ // distance computation as we have a mask
+ const size_t* feature_block_ptr = reinterpret_cast<const size_t*> ((const void*)feature);
+
+ // Figure out the subsignature of the feature
+ // Given the feature ABCDEF, and the mask 001011, the output will be
+ // 000CEF
+ size_t subsignature = 0;
+ size_t bit_index = 1;
+
+ for (std::vector<size_t>::const_iterator pmask_block = mask_.begin(); pmask_block != mask_.end(); ++pmask_block) {
+ // get the mask and signature blocks
+ size_t feature_block = *feature_block_ptr;
+ size_t mask_block = *pmask_block;
+ while (mask_block) {
+ // Get the lowest set bit in the mask block
+ size_t lowest_bit = mask_block & (-(ptrdiff_t)mask_block);
+ // Add it to the current subsignature if necessary
+ subsignature += (feature_block & lowest_bit) ? bit_index : 0;
+ // Reset the bit in the mask block
+ mask_block ^= lowest_bit;
+ // increment the bit index for the subsignature
+ bit_index <<= 1;
+ }
+ // Check the next feature block
+ ++feature_block_ptr;
+ }
+ return subsignature;
+}
+
+template<>
+inline LshStats LshTable<unsigned char>::getStats() const
+{
+ LshStats stats;
+ stats.bucket_size_mean_ = 0;
+ if ((buckets_speed_.empty()) && (buckets_space_.empty())) {
+ stats.n_buckets_ = 0;
+ stats.bucket_size_median_ = 0;
+ stats.bucket_size_min_ = 0;
+ stats.bucket_size_max_ = 0;
+ return stats;
+ }
+
+ if (!buckets_speed_.empty()) {
+ for (BucketsSpeed::const_iterator pbucket = buckets_speed_.begin(); pbucket != buckets_speed_.end(); ++pbucket) {
+ stats.bucket_sizes_.push_back((lsh::FeatureIndex)pbucket->size());
+ stats.bucket_size_mean_ += pbucket->size();
+ }
+ stats.bucket_size_mean_ /= buckets_speed_.size();
+ stats.n_buckets_ = buckets_speed_.size();
+ }
+ else {
+ for (BucketsSpace::const_iterator x = buckets_space_.begin(); x != buckets_space_.end(); ++x) {
+ stats.bucket_sizes_.push_back((lsh::FeatureIndex)x->second.size());
+ stats.bucket_size_mean_ += x->second.size();
+ }
+ stats.bucket_size_mean_ /= buckets_space_.size();
+ stats.n_buckets_ = buckets_space_.size();
+ }
+
+ std::sort(stats.bucket_sizes_.begin(), stats.bucket_sizes_.end());
+
+ // BOOST_FOREACH(int size, stats.bucket_sizes_)
+ // std::cout << size << " ";
+ // std::cout << std::endl;
+ stats.bucket_size_median_ = stats.bucket_sizes_[stats.bucket_sizes_.size() / 2];
+ stats.bucket_size_min_ = stats.bucket_sizes_.front();
+ stats.bucket_size_max_ = stats.bucket_sizes_.back();
+
+ // TODO compute mean and std
+ /*float mean, stddev;
+ stats.bucket_size_mean_ = mean;
+ stats.bucket_size_std_dev = stddev;*/
+
+ // Include a histogram of the buckets
+ unsigned int bin_start = 0;
+ unsigned int bin_end = 20;
+ bool is_new_bin = true;
+ for (std::vector<unsigned int>::iterator iterator = stats.bucket_sizes_.begin(), end = stats.bucket_sizes_.end(); iterator
+ != end; )
+ if (*iterator < bin_end) {
+ if (is_new_bin) {
+ stats.size_histogram_.push_back(std::vector<unsigned int>(3, 0));
+ stats.size_histogram_.back()[0] = bin_start;
+ stats.size_histogram_.back()[1] = bin_end - 1;
+ is_new_bin = false;
+ }
+ ++stats.size_histogram_.back()[2];
+ ++iterator;
+ }
+ else {
+ bin_start += 20;
+ bin_end += 20;
+ is_new_bin = true;
+ }
+
+ return stats;
+}
+
+// End the two namespaces
+}
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#endif /* OPENCV_FLANN_LSH_TABLE_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/flann/matrix.h Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,116 @@
+/***********************************************************************
+ * Software License Agreement (BSD License)
+ *
+ * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved.
+ * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved.
+ *
+ * THE BSD LICENSE
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *************************************************************************/
+
+#ifndef OPENCV_FLANN_DATASET_H_
+#define OPENCV_FLANN_DATASET_H_
+
+#include <stdio.h>
+
+#include "general.h"
+
+namespace cvflann
+{
+
+/**
+ * Class that implements a simple rectangular matrix stored in a memory buffer and
+ * provides convenient matrix-like access using the [] operators.
+ */
+template <typename T>
+class Matrix
+{
+public:
+ typedef T type;
+
+ size_t rows;
+ size_t cols;
+ size_t stride;
+ T* data;
+
+ Matrix() : rows(0), cols(0), stride(0), data(NULL)
+ {
+ }
+
+ Matrix(T* data_, size_t rows_, size_t cols_, size_t stride_ = 0) :
+ rows(rows_), cols(cols_), stride(stride_), data(data_)
+ {
+ if (stride==0) stride = cols;
+ }
+
+ /**
+ * Convenience function for deallocating the storage data.
+ */
+ FLANN_DEPRECATED void free()
+ {
+ fprintf(stderr, "The cvflann::Matrix<T>::free() method is deprecated "
+ "and it does not do any memory deallocation any more. You are"
+ "responsible for deallocating the matrix memory (by doing"
+ "'delete[] matrix.data' for example)");
+ }
+
+ /**
+ * Operator that return a (pointer to a) row of the data.
+ */
+ T* operator[](size_t index) const
+ {
+ return data+index*stride;
+ }
+};
+
+
+class UntypedMatrix
+{
+public:
+ size_t rows;
+ size_t cols;
+ void* data;
+ flann_datatype_t type;
+
+ UntypedMatrix(void* data_, long rows_, long cols_) :
+ rows(rows_), cols(cols_), data(data_)
+ {
+ }
+
+ ~UntypedMatrix()
+ {
+ }
+
+
+ template<typename T>
+ Matrix<T> as()
+ {
+ return Matrix<T>((T*)data, rows, cols);
+ }
+};
+
+
+
+}
+
+#endif //OPENCV_FLANN_DATASET_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/flann/miniflann.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,158 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_MINIFLANN_HPP
+#define OPENCV_MINIFLANN_HPP
+
+#include "opencv2/core.hpp"
+#include "opencv2/flann/defines.h"
+
+namespace cv
+{
+
+namespace flann
+{
+
+struct CV_EXPORTS IndexParams
+{
+ IndexParams();
+ ~IndexParams();
+
+ String getString(const String& key, const String& defaultVal=String()) const;
+ int getInt(const String& key, int defaultVal=-1) const;
+ double getDouble(const String& key, double defaultVal=-1) const;
+
+ void setString(const String& key, const String& value);
+ void setInt(const String& key, int value);
+ void setDouble(const String& key, double value);
+ void setFloat(const String& key, float value);
+ void setBool(const String& key, bool value);
+ void setAlgorithm(int value);
+
+ void getAll(std::vector<String>& names,
+ std::vector<int>& types,
+ std::vector<String>& strValues,
+ std::vector<double>& numValues) const;
+
+ void* params;
+};
+
+struct CV_EXPORTS KDTreeIndexParams : public IndexParams
+{
+ KDTreeIndexParams(int trees=4);
+};
+
+struct CV_EXPORTS LinearIndexParams : public IndexParams
+{
+ LinearIndexParams();
+};
+
+struct CV_EXPORTS CompositeIndexParams : public IndexParams
+{
+ CompositeIndexParams(int trees = 4, int branching = 32, int iterations = 11,
+ cvflann::flann_centers_init_t centers_init = cvflann::FLANN_CENTERS_RANDOM, float cb_index = 0.2f );
+};
+
+struct CV_EXPORTS AutotunedIndexParams : public IndexParams
+{
+ AutotunedIndexParams(float target_precision = 0.8f, float build_weight = 0.01f,
+ float memory_weight = 0, float sample_fraction = 0.1f);
+};
+
+struct CV_EXPORTS HierarchicalClusteringIndexParams : public IndexParams
+{
+ HierarchicalClusteringIndexParams(int branching = 32,
+ cvflann::flann_centers_init_t centers_init = cvflann::FLANN_CENTERS_RANDOM, int trees = 4, int leaf_size = 100 );
+};
+
+struct CV_EXPORTS KMeansIndexParams : public IndexParams
+{
+ KMeansIndexParams(int branching = 32, int iterations = 11,
+ cvflann::flann_centers_init_t centers_init = cvflann::FLANN_CENTERS_RANDOM, float cb_index = 0.2f );
+};
+
+struct CV_EXPORTS LshIndexParams : public IndexParams
+{
+ LshIndexParams(int table_number, int key_size, int multi_probe_level);
+};
+
+struct CV_EXPORTS SavedIndexParams : public IndexParams
+{
+ SavedIndexParams(const String& filename);
+};
+
+struct CV_EXPORTS SearchParams : public IndexParams
+{
+ SearchParams( int checks = 32, float eps = 0, bool sorted = true );
+};
+
+class CV_EXPORTS_W Index
+{
+public:
+ CV_WRAP Index();
+ CV_WRAP Index(InputArray features, const IndexParams& params, cvflann::flann_distance_t distType=cvflann::FLANN_DIST_L2);
+ virtual ~Index();
+
+ CV_WRAP virtual void build(InputArray features, const IndexParams& params, cvflann::flann_distance_t distType=cvflann::FLANN_DIST_L2);
+ CV_WRAP virtual void knnSearch(InputArray query, OutputArray indices,
+ OutputArray dists, int knn, const SearchParams& params=SearchParams());
+
+ CV_WRAP virtual int radiusSearch(InputArray query, OutputArray indices,
+ OutputArray dists, double radius, int maxResults,
+ const SearchParams& params=SearchParams());
+
+ CV_WRAP virtual void save(const String& filename) const;
+ CV_WRAP virtual bool load(InputArray features, const String& filename);
+ CV_WRAP virtual void release();
+ CV_WRAP cvflann::flann_distance_t getDistance() const;
+ CV_WRAP cvflann::flann_algorithm_t getAlgorithm() const;
+
+protected:
+ cvflann::flann_distance_t distType;
+ cvflann::flann_algorithm_t algo;
+ int featureType;
+ void* index;
+};
+
+} } // namespace cv::flann
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/flann/nn_index.h Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,177 @@
+/***********************************************************************
+ * Software License Agreement (BSD License)
+ *
+ * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved.
+ * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved.
+ *
+ * THE BSD LICENSE
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *************************************************************************/
+
+#ifndef OPENCV_FLANN_NNINDEX_H
+#define OPENCV_FLANN_NNINDEX_H
+
+#include "general.h"
+#include "matrix.h"
+#include "result_set.h"
+#include "params.h"
+
+namespace cvflann
+{
+
+/**
+ * Nearest-neighbour index base class
+ */
+template <typename Distance>
+class NNIndex
+{
+ typedef typename Distance::ElementType ElementType;
+ typedef typename Distance::ResultType DistanceType;
+
+public:
+
+ virtual ~NNIndex() {}
+
+ /**
+ * \brief Builds the index
+ */
+ virtual void buildIndex() = 0;
+
+ /**
+ * \brief Perform k-nearest neighbor search
+ * \param[in] queries The query points for which to find the nearest neighbors
+ * \param[out] indices The indices of the nearest neighbors found
+ * \param[out] dists Distances to the nearest neighbors found
+ * \param[in] knn Number of nearest neighbors to return
+ * \param[in] params Search parameters
+ */
+ virtual void knnSearch(const Matrix<ElementType>& queries, Matrix<int>& indices, Matrix<DistanceType>& dists, int knn, const SearchParams& params)
+ {
+ assert(queries.cols == veclen());
+ assert(indices.rows >= queries.rows);
+ assert(dists.rows >= queries.rows);
+ assert(int(indices.cols) >= knn);
+ assert(int(dists.cols) >= knn);
+
+#if 0
+ KNNResultSet<DistanceType> resultSet(knn);
+ for (size_t i = 0; i < queries.rows; i++) {
+ resultSet.init(indices[i], dists[i]);
+ findNeighbors(resultSet, queries[i], params);
+ }
+#else
+ KNNUniqueResultSet<DistanceType> resultSet(knn);
+ for (size_t i = 0; i < queries.rows; i++) {
+ resultSet.clear();
+ findNeighbors(resultSet, queries[i], params);
+ if (get_param(params,"sorted",true)) resultSet.sortAndCopy(indices[i], dists[i], knn);
+ else resultSet.copy(indices[i], dists[i], knn);
+ }
+#endif
+ }
+
+ /**
+ * \brief Perform radius search
+ * \param[in] query The query point
+ * \param[out] indices The indinces of the neighbors found within the given radius
+ * \param[out] dists The distances to the nearest neighbors found
+ * \param[in] radius The radius used for search
+ * \param[in] params Search parameters
+ * \returns Number of neighbors found
+ */
+ virtual int radiusSearch(const Matrix<ElementType>& query, Matrix<int>& indices, Matrix<DistanceType>& dists, float radius, const SearchParams& params)
+ {
+ if (query.rows != 1) {
+ fprintf(stderr, "I can only search one feature at a time for range search\n");
+ return -1;
+ }
+ assert(query.cols == veclen());
+ assert(indices.cols == dists.cols);
+
+ int n = 0;
+ int* indices_ptr = NULL;
+ DistanceType* dists_ptr = NULL;
+ if (indices.cols > 0) {
+ n = (int)indices.cols;
+ indices_ptr = indices[0];
+ dists_ptr = dists[0];
+ }
+
+ RadiusUniqueResultSet<DistanceType> resultSet((DistanceType)radius);
+ resultSet.clear();
+ findNeighbors(resultSet, query[0], params);
+ if (n>0) {
+ if (get_param(params,"sorted",true)) resultSet.sortAndCopy(indices_ptr, dists_ptr, n);
+ else resultSet.copy(indices_ptr, dists_ptr, n);
+ }
+
+ return (int)resultSet.size();
+ }
+
+ /**
+ * \brief Saves the index to a stream
+ * \param stream The stream to save the index to
+ */
+ virtual void saveIndex(FILE* stream) = 0;
+
+ /**
+ * \brief Loads the index from a stream
+ * \param stream The stream from which the index is loaded
+ */
+ virtual void loadIndex(FILE* stream) = 0;
+
+ /**
+ * \returns number of features in this index.
+ */
+ virtual size_t size() const = 0;
+
+ /**
+ * \returns The dimensionality of the features in this index.
+ */
+ virtual size_t veclen() const = 0;
+
+ /**
+ * \returns The amount of memory (in bytes) used by the index.
+ */
+ virtual int usedMemory() const = 0;
+
+ /**
+ * \returns The index type (kdtree, kmeans,...)
+ */
+ virtual flann_algorithm_t getType() const = 0;
+
+ /**
+ * \returns The index parameters
+ */
+ virtual IndexParams getParameters() const = 0;
+
+
+ /**
+ * \brief Method that searches for nearest-neighbours
+ */
+ virtual void findNeighbors(ResultSet<DistanceType>& result, const ElementType* vec, const SearchParams& searchParams) = 0;
+};
+
+}
+
+#endif //OPENCV_FLANN_NNINDEX_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/flann/object_factory.h Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,91 @@
+/***********************************************************************
+ * Software License Agreement (BSD License)
+ *
+ * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved.
+ * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved.
+ *
+ * THE BSD LICENSE
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *************************************************************************/
+
+#ifndef OPENCV_FLANN_OBJECT_FACTORY_H_
+#define OPENCV_FLANN_OBJECT_FACTORY_H_
+
+#include <map>
+
+namespace cvflann
+{
+
+class CreatorNotFound
+{
+};
+
+template<typename BaseClass,
+ typename UniqueIdType,
+ typename ObjectCreator = BaseClass* (*)()>
+class ObjectFactory
+{
+ typedef ObjectFactory<BaseClass,UniqueIdType,ObjectCreator> ThisClass;
+ typedef std::map<UniqueIdType, ObjectCreator> ObjectRegistry;
+
+ // singleton class, private constructor
+ ObjectFactory() {}
+
+public:
+
+ bool subscribe(UniqueIdType id, ObjectCreator creator)
+ {
+ if (object_registry.find(id) != object_registry.end()) return false;
+
+ object_registry[id] = creator;
+ return true;
+ }
+
+ bool unregister(UniqueIdType id)
+ {
+ return object_registry.erase(id) == 1;
+ }
+
+ ObjectCreator create(UniqueIdType id)
+ {
+ typename ObjectRegistry::const_iterator iter = object_registry.find(id);
+
+ if (iter == object_registry.end()) {
+ throw CreatorNotFound();
+ }
+
+ return iter->second;
+ }
+
+ static ThisClass& instance()
+ {
+ static ThisClass the_factory;
+ return the_factory;
+ }
+private:
+ ObjectRegistry object_registry;
+};
+
+}
+
+#endif /* OPENCV_FLANN_OBJECT_FACTORY_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/flann/params.h Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,99 @@
+/***********************************************************************
+ * Software License Agreement (BSD License)
+ *
+ * Copyright 2008-2011 Marius Muja (mariusm@cs.ubc.ca). All rights reserved.
+ * Copyright 2008-2011 David G. Lowe (lowe@cs.ubc.ca). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *************************************************************************/
+
+
+#ifndef OPENCV_FLANN_PARAMS_H_
+#define OPENCV_FLANN_PARAMS_H_
+
+#include "any.h"
+#include "general.h"
+#include <iostream>
+#include <map>
+
+
+namespace cvflann
+{
+
+typedef std::map<cv::String, any> IndexParams;
+
+struct SearchParams : public IndexParams
+{
+ SearchParams(int checks = 32, float eps = 0, bool sorted = true )
+ {
+ // how many leafs to visit when searching for neighbours (-1 for unlimited)
+ (*this)["checks"] = checks;
+ // search for eps-approximate neighbours (default: 0)
+ (*this)["eps"] = eps;
+ // only for radius search, require neighbours sorted by distance (default: true)
+ (*this)["sorted"] = sorted;
+ }
+};
+
+
+template<typename T>
+T get_param(const IndexParams& params, cv::String name, const T& default_value)
+{
+ IndexParams::const_iterator it = params.find(name);
+ if (it != params.end()) {
+ return it->second.cast<T>();
+ }
+ else {
+ return default_value;
+ }
+}
+
+template<typename T>
+T get_param(const IndexParams& params, cv::String name)
+{
+ IndexParams::const_iterator it = params.find(name);
+ if (it != params.end()) {
+ return it->second.cast<T>();
+ }
+ else {
+ throw FLANNException(cv::String("Missing parameter '")+name+cv::String("' in the parameters given"));
+ }
+}
+
+inline void print_params(const IndexParams& params, std::ostream& stream)
+{
+ IndexParams::const_iterator it;
+
+ for(it=params.begin(); it!=params.end(); ++it) {
+ stream << it->first << " : " << it->second << std::endl;
+ }
+}
+
+inline void print_params(const IndexParams& params)
+{
+ print_params(params, std::cout);
+}
+
+}
+
+
+#endif /* OPENCV_FLANN_PARAMS_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/flann/random.h Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,133 @@
+/***********************************************************************
+ * Software License Agreement (BSD License)
+ *
+ * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved.
+ * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved.
+ *
+ * THE BSD LICENSE
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *************************************************************************/
+
+#ifndef OPENCV_FLANN_RANDOM_H
+#define OPENCV_FLANN_RANDOM_H
+
+#include <algorithm>
+#include <cstdlib>
+#include <vector>
+
+#include "general.h"
+
+namespace cvflann
+{
+
+/**
+ * Seeds the random number generator
+ * @param seed Random seed
+ */
+inline void seed_random(unsigned int seed)
+{
+ srand(seed);
+}
+
+/*
+ * Generates a random double value.
+ */
+/**
+ * Generates a random double value.
+ * @param high Upper limit
+ * @param low Lower limit
+ * @return Random double value
+ */
+inline double rand_double(double high = 1.0, double low = 0)
+{
+ return low + ((high-low) * (std::rand() / (RAND_MAX + 1.0)));
+}
+
+/**
+ * Generates a random integer value.
+ * @param high Upper limit
+ * @param low Lower limit
+ * @return Random integer value
+ */
+inline int rand_int(int high = RAND_MAX, int low = 0)
+{
+ return low + (int) ( double(high-low) * (std::rand() / (RAND_MAX + 1.0)));
+}
+
+/**
+ * Random number generator that returns a distinct number from
+ * the [0,n) interval each time.
+ */
+class UniqueRandom
+{
+ std::vector<int> vals_;
+ int size_;
+ int counter_;
+
+public:
+ /**
+ * Constructor.
+ * @param n Size of the interval from which to generate
+ * @return
+ */
+ UniqueRandom(int n)
+ {
+ init(n);
+ }
+
+ /**
+ * Initializes the number generator.
+ * @param n the size of the interval from which to generate random numbers.
+ */
+ void init(int n)
+ {
+ // create and initialize an array of size n
+ vals_.resize(n);
+ size_ = n;
+ for (int i = 0; i < size_; ++i) vals_[i] = i;
+
+ // shuffle the elements in the array
+ std::random_shuffle(vals_.begin(), vals_.end());
+
+ counter_ = 0;
+ }
+
+ /**
+ * Return a distinct random integer in greater or equal to 0 and less
+ * than 'n' on each call. It should be called maximum 'n' times.
+ * Returns: a random integer
+ */
+ int next()
+ {
+ if (counter_ == size_) {
+ return -1;
+ }
+ else {
+ return vals_[counter_++];
+ }
+ }
+};
+
+}
+
+#endif //OPENCV_FLANN_RANDOM_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/flann/result_set.h Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,543 @@
+/***********************************************************************
+ * Software License Agreement (BSD License)
+ *
+ * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved.
+ * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved.
+ *
+ * THE BSD LICENSE
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *************************************************************************/
+
+#ifndef OPENCV_FLANN_RESULTSET_H
+#define OPENCV_FLANN_RESULTSET_H
+
+#include <algorithm>
+#include <cstring>
+#include <iostream>
+#include <limits>
+#include <set>
+#include <vector>
+
+namespace cvflann
+{
+
+/* This record represents a branch point when finding neighbors in
+ the tree. It contains a record of the minimum distance to the query
+ point, as well as the node at which the search resumes.
+ */
+
+template <typename T, typename DistanceType>
+struct BranchStruct
+{
+ T node; /* Tree node at which search resumes */
+ DistanceType mindist; /* Minimum distance to query for all nodes below. */
+
+ BranchStruct() {}
+ BranchStruct(const T& aNode, DistanceType dist) : node(aNode), mindist(dist) {}
+
+ bool operator<(const BranchStruct<T, DistanceType>& rhs) const
+ {
+ return mindist<rhs.mindist;
+ }
+};
+
+
+template <typename DistanceType>
+class ResultSet
+{
+public:
+ virtual ~ResultSet() {}
+
+ virtual bool full() const = 0;
+
+ virtual void addPoint(DistanceType dist, int index) = 0;
+
+ virtual DistanceType worstDist() const = 0;
+
+};
+
+/**
+ * KNNSimpleResultSet does not ensure that the element it holds are unique.
+ * Is used in those cases where the nearest neighbour algorithm used does not
+ * attempt to insert the same element multiple times.
+ */
+template <typename DistanceType>
+class KNNSimpleResultSet : public ResultSet<DistanceType>
+{
+ int* indices;
+ DistanceType* dists;
+ int capacity;
+ int count;
+ DistanceType worst_distance_;
+
+public:
+ KNNSimpleResultSet(int capacity_) : capacity(capacity_), count(0)
+ {
+ }
+
+ void init(int* indices_, DistanceType* dists_)
+ {
+ indices = indices_;
+ dists = dists_;
+ count = 0;
+ worst_distance_ = (std::numeric_limits<DistanceType>::max)();
+ dists[capacity-1] = worst_distance_;
+ }
+
+ size_t size() const
+ {
+ return count;
+ }
+
+ bool full() const
+ {
+ return count == capacity;
+ }
+
+
+ void addPoint(DistanceType dist, int index)
+ {
+ if (dist >= worst_distance_) return;
+ int i;
+ for (i=count; i>0; --i) {
+#ifdef FLANN_FIRST_MATCH
+ if ( (dists[i-1]>dist) || ((dist==dists[i-1])&&(indices[i-1]>index)) )
+#else
+ if (dists[i-1]>dist)
+#endif
+ {
+ if (i<capacity) {
+ dists[i] = dists[i-1];
+ indices[i] = indices[i-1];
+ }
+ }
+ else break;
+ }
+ if (count < capacity) ++count;
+ dists[i] = dist;
+ indices[i] = index;
+ worst_distance_ = dists[capacity-1];
+ }
+
+ DistanceType worstDist() const
+ {
+ return worst_distance_;
+ }
+};
+
+/**
+ * K-Nearest neighbour result set. Ensures that the elements inserted are unique
+ */
+template <typename DistanceType>
+class KNNResultSet : public ResultSet<DistanceType>
+{
+ int* indices;
+ DistanceType* dists;
+ int capacity;
+ int count;
+ DistanceType worst_distance_;
+
+public:
+ KNNResultSet(int capacity_) : capacity(capacity_), count(0)
+ {
+ }
+
+ void init(int* indices_, DistanceType* dists_)
+ {
+ indices = indices_;
+ dists = dists_;
+ count = 0;
+ worst_distance_ = (std::numeric_limits<DistanceType>::max)();
+ dists[capacity-1] = worst_distance_;
+ }
+
+ size_t size() const
+ {
+ return count;
+ }
+
+ bool full() const
+ {
+ return count == capacity;
+ }
+
+
+ void addPoint(DistanceType dist, int index)
+ {
+ if (dist >= worst_distance_) return;
+ int i;
+ for (i = count; i > 0; --i) {
+#ifdef FLANN_FIRST_MATCH
+ if ( (dists[i-1]<=dist) && ((dist!=dists[i-1])||(indices[i-1]<=index)) )
+#else
+ if (dists[i-1]<=dist)
+#endif
+ {
+ // Check for duplicate indices
+ int j = i - 1;
+ while ((j >= 0) && (dists[j] == dist)) {
+ if (indices[j] == index) {
+ return;
+ }
+ --j;
+ }
+ break;
+ }
+ }
+
+ if (count < capacity) ++count;
+ for (int j = count-1; j > i; --j) {
+ dists[j] = dists[j-1];
+ indices[j] = indices[j-1];
+ }
+ dists[i] = dist;
+ indices[i] = index;
+ worst_distance_ = dists[capacity-1];
+ }
+
+ DistanceType worstDist() const
+ {
+ return worst_distance_;
+ }
+};
+
+
+/**
+ * A result-set class used when performing a radius based search.
+ */
+template <typename DistanceType>
+class RadiusResultSet : public ResultSet<DistanceType>
+{
+ DistanceType radius;
+ int* indices;
+ DistanceType* dists;
+ size_t capacity;
+ size_t count;
+
+public:
+ RadiusResultSet(DistanceType radius_, int* indices_, DistanceType* dists_, int capacity_) :
+ radius(radius_), indices(indices_), dists(dists_), capacity(capacity_)
+ {
+ init();
+ }
+
+ ~RadiusResultSet()
+ {
+ }
+
+ void init()
+ {
+ count = 0;
+ }
+
+ size_t size() const
+ {
+ return count;
+ }
+
+ bool full() const
+ {
+ return true;
+ }
+
+ void addPoint(DistanceType dist, int index)
+ {
+ if (dist<radius) {
+ if ((capacity>0)&&(count < capacity)) {
+ dists[count] = dist;
+ indices[count] = index;
+ }
+ count++;
+ }
+ }
+
+ DistanceType worstDist() const
+ {
+ return radius;
+ }
+
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+/** Class that holds the k NN neighbors
+ * Faster than KNNResultSet as it uses a binary heap and does not maintain two arrays
+ */
+template<typename DistanceType>
+class UniqueResultSet : public ResultSet<DistanceType>
+{
+public:
+ struct DistIndex
+ {
+ DistIndex(DistanceType dist, unsigned int index) :
+ dist_(dist), index_(index)
+ {
+ }
+ bool operator<(const DistIndex dist_index) const
+ {
+ return (dist_ < dist_index.dist_) || ((dist_ == dist_index.dist_) && index_ < dist_index.index_);
+ }
+ DistanceType dist_;
+ unsigned int index_;
+ };
+
+ /** Default cosntructor */
+ UniqueResultSet() :
+ worst_distance_(std::numeric_limits<DistanceType>::max())
+ {
+ }
+
+ /** Check the status of the set
+ * @return true if we have k NN
+ */
+ inline bool full() const
+ {
+ return is_full_;
+ }
+
+ /** Remove all elements in the set
+ */
+ virtual void clear() = 0;
+
+ /** Copy the set to two C arrays
+ * @param indices pointer to a C array of indices
+ * @param dist pointer to a C array of distances
+ * @param n_neighbors the number of neighbors to copy
+ */
+ virtual void copy(int* indices, DistanceType* dist, int n_neighbors = -1) const
+ {
+ if (n_neighbors < 0) {
+ for (typename std::set<DistIndex>::const_iterator dist_index = dist_indices_.begin(), dist_index_end =
+ dist_indices_.end(); dist_index != dist_index_end; ++dist_index, ++indices, ++dist) {
+ *indices = dist_index->index_;
+ *dist = dist_index->dist_;
+ }
+ }
+ else {
+ int i = 0;
+ for (typename std::set<DistIndex>::const_iterator dist_index = dist_indices_.begin(), dist_index_end =
+ dist_indices_.end(); (dist_index != dist_index_end) && (i < n_neighbors); ++dist_index, ++indices, ++dist, ++i) {
+ *indices = dist_index->index_;
+ *dist = dist_index->dist_;
+ }
+ }
+ }
+
+ /** Copy the set to two C arrays but sort it according to the distance first
+ * @param indices pointer to a C array of indices
+ * @param dist pointer to a C array of distances
+ * @param n_neighbors the number of neighbors to copy
+ */
+ virtual void sortAndCopy(int* indices, DistanceType* dist, int n_neighbors = -1) const
+ {
+ copy(indices, dist, n_neighbors);
+ }
+
+ /** The number of neighbors in the set
+ * @return
+ */
+ size_t size() const
+ {
+ return dist_indices_.size();
+ }
+
+ /** The distance of the furthest neighbor
+ * If we don't have enough neighbors, it returns the max possible value
+ * @return
+ */
+ inline DistanceType worstDist() const
+ {
+ return worst_distance_;
+ }
+protected:
+ /** Flag to say if the set is full */
+ bool is_full_;
+
+ /** The worst distance found so far */
+ DistanceType worst_distance_;
+
+ /** The best candidates so far */
+ std::set<DistIndex> dist_indices_;
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+/** Class that holds the k NN neighbors
+ * Faster than KNNResultSet as it uses a binary heap and does not maintain two arrays
+ */
+template<typename DistanceType>
+class KNNUniqueResultSet : public UniqueResultSet<DistanceType>
+{
+public:
+ /** Constructor
+ * @param capacity the number of neighbors to store at max
+ */
+ KNNUniqueResultSet(unsigned int capacity) : capacity_(capacity)
+ {
+ this->is_full_ = false;
+ this->clear();
+ }
+
+ /** Add a possible candidate to the best neighbors
+ * @param dist distance for that neighbor
+ * @param index index of that neighbor
+ */
+ inline void addPoint(DistanceType dist, int index)
+ {
+ // Don't do anything if we are worse than the worst
+ if (dist >= worst_distance_) return;
+ dist_indices_.insert(DistIndex(dist, index));
+
+ if (is_full_) {
+ if (dist_indices_.size() > capacity_) {
+ dist_indices_.erase(*dist_indices_.rbegin());
+ worst_distance_ = dist_indices_.rbegin()->dist_;
+ }
+ }
+ else if (dist_indices_.size() == capacity_) {
+ is_full_ = true;
+ worst_distance_ = dist_indices_.rbegin()->dist_;
+ }
+ }
+
+ /** Remove all elements in the set
+ */
+ void clear()
+ {
+ dist_indices_.clear();
+ worst_distance_ = std::numeric_limits<DistanceType>::max();
+ is_full_ = false;
+ }
+
+protected:
+ typedef typename UniqueResultSet<DistanceType>::DistIndex DistIndex;
+ using UniqueResultSet<DistanceType>::is_full_;
+ using UniqueResultSet<DistanceType>::worst_distance_;
+ using UniqueResultSet<DistanceType>::dist_indices_;
+
+ /** The number of neighbors to keep */
+ unsigned int capacity_;
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+/** Class that holds the radius nearest neighbors
+ * It is more accurate than RadiusResult as it is not limited in the number of neighbors
+ */
+template<typename DistanceType>
+class RadiusUniqueResultSet : public UniqueResultSet<DistanceType>
+{
+public:
+ /** Constructor
+ * @param radius the maximum distance of a neighbor
+ */
+ RadiusUniqueResultSet(DistanceType radius) :
+ radius_(radius)
+ {
+ is_full_ = true;
+ }
+
+ /** Add a possible candidate to the best neighbors
+ * @param dist distance for that neighbor
+ * @param index index of that neighbor
+ */
+ void addPoint(DistanceType dist, int index)
+ {
+ if (dist <= radius_) dist_indices_.insert(DistIndex(dist, index));
+ }
+
+ /** Remove all elements in the set
+ */
+ inline void clear()
+ {
+ dist_indices_.clear();
+ }
+
+
+ /** Check the status of the set
+ * @return alwys false
+ */
+ inline bool full() const
+ {
+ return true;
+ }
+
+ /** The distance of the furthest neighbor
+ * If we don't have enough neighbors, it returns the max possible value
+ * @return
+ */
+ inline DistanceType worstDist() const
+ {
+ return radius_;
+ }
+private:
+ typedef typename UniqueResultSet<DistanceType>::DistIndex DistIndex;
+ using UniqueResultSet<DistanceType>::dist_indices_;
+ using UniqueResultSet<DistanceType>::is_full_;
+
+ /** The furthest distance a neighbor can be */
+ DistanceType radius_;
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+/** Class that holds the k NN neighbors within a radius distance
+ */
+template<typename DistanceType>
+class KNNRadiusUniqueResultSet : public KNNUniqueResultSet<DistanceType>
+{
+public:
+ /** Constructor
+ * @param capacity the number of neighbors to store at max
+ * @param radius the maximum distance of a neighbor
+ */
+ KNNRadiusUniqueResultSet(unsigned int capacity, DistanceType radius)
+ {
+ this->capacity_ = capacity;
+ this->radius_ = radius;
+ this->dist_indices_.reserve(capacity_);
+ this->clear();
+ }
+
+ /** Remove all elements in the set
+ */
+ void clear()
+ {
+ dist_indices_.clear();
+ worst_distance_ = radius_;
+ is_full_ = false;
+ }
+private:
+ using KNNUniqueResultSet<DistanceType>::dist_indices_;
+ using KNNUniqueResultSet<DistanceType>::is_full_;
+ using KNNUniqueResultSet<DistanceType>::worst_distance_;
+
+ /** The maximum number of neighbors to consider */
+ unsigned int capacity_;
+
+ /** The maximum distance of a neighbor */
+ DistanceType radius_;
+};
+}
+
+#endif //OPENCV_FLANN_RESULTSET_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/flann/sampling.h Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,81 @@
+/***********************************************************************
+ * Software License Agreement (BSD License)
+ *
+ * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved.
+ * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *************************************************************************/
+
+
+#ifndef OPENCV_FLANN_SAMPLING_H_
+#define OPENCV_FLANN_SAMPLING_H_
+
+#include "matrix.h"
+#include "random.h"
+
+namespace cvflann
+{
+
+template<typename T>
+Matrix<T> random_sample(Matrix<T>& srcMatrix, long size, bool remove = false)
+{
+ Matrix<T> newSet(new T[size * srcMatrix.cols], size,srcMatrix.cols);
+
+ T* src,* dest;
+ for (long i=0; i<size; ++i) {
+ long r = rand_int((int)(srcMatrix.rows-i));
+ dest = newSet[i];
+ src = srcMatrix[r];
+ std::copy(src, src+srcMatrix.cols, dest);
+ if (remove) {
+ src = srcMatrix[srcMatrix.rows-i-1];
+ dest = srcMatrix[r];
+ std::copy(src, src+srcMatrix.cols, dest);
+ }
+ }
+ if (remove) {
+ srcMatrix.rows -= size;
+ }
+ return newSet;
+}
+
+template<typename T>
+Matrix<T> random_sample(const Matrix<T>& srcMatrix, size_t size)
+{
+ UniqueRandom rand((int)srcMatrix.rows);
+ Matrix<T> newSet(new T[size * srcMatrix.cols], size,srcMatrix.cols);
+
+ T* src,* dest;
+ for (size_t i=0; i<size; ++i) {
+ long r = rand.next();
+ dest = newSet[i];
+ src = srcMatrix[r];
+ std::copy(src, src+srcMatrix.cols, dest);
+ }
+ return newSet;
+}
+
+} // namespace
+
+
+#endif /* OPENCV_FLANN_SAMPLING_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/flann/saving.h Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,187 @@
+/***********************************************************************
+ * Software License Agreement (BSD License)
+ *
+ * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved.
+ * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE NNIndexGOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *************************************************************************/
+
+#ifndef OPENCV_FLANN_SAVING_H_
+#define OPENCV_FLANN_SAVING_H_
+
+#include <cstring>
+#include <vector>
+
+#include "general.h"
+#include "nn_index.h"
+
+#ifdef FLANN_SIGNATURE_
+#undef FLANN_SIGNATURE_
+#endif
+#define FLANN_SIGNATURE_ "FLANN_INDEX"
+
+namespace cvflann
+{
+
+template <typename T>
+struct Datatype {};
+template<>
+struct Datatype<char> { static flann_datatype_t type() { return FLANN_INT8; } };
+template<>
+struct Datatype<short> { static flann_datatype_t type() { return FLANN_INT16; } };
+template<>
+struct Datatype<int> { static flann_datatype_t type() { return FLANN_INT32; } };
+template<>
+struct Datatype<unsigned char> { static flann_datatype_t type() { return FLANN_UINT8; } };
+template<>
+struct Datatype<unsigned short> { static flann_datatype_t type() { return FLANN_UINT16; } };
+template<>
+struct Datatype<unsigned int> { static flann_datatype_t type() { return FLANN_UINT32; } };
+template<>
+struct Datatype<float> { static flann_datatype_t type() { return FLANN_FLOAT32; } };
+template<>
+struct Datatype<double> { static flann_datatype_t type() { return FLANN_FLOAT64; } };
+
+
+/**
+ * Structure representing the index header.
+ */
+struct IndexHeader
+{
+ char signature[16];
+ char version[16];
+ flann_datatype_t data_type;
+ flann_algorithm_t index_type;
+ size_t rows;
+ size_t cols;
+};
+
+/**
+ * Saves index header to stream
+ *
+ * @param stream - Stream to save to
+ * @param index - The index to save
+ */
+template<typename Distance>
+void save_header(FILE* stream, const NNIndex<Distance>& index)
+{
+ IndexHeader header;
+ memset(header.signature, 0, sizeof(header.signature));
+ strcpy(header.signature, FLANN_SIGNATURE_);
+ memset(header.version, 0, sizeof(header.version));
+ strcpy(header.version, FLANN_VERSION_);
+ header.data_type = Datatype<typename Distance::ElementType>::type();
+ header.index_type = index.getType();
+ header.rows = index.size();
+ header.cols = index.veclen();
+
+ std::fwrite(&header, sizeof(header),1,stream);
+}
+
+
+/**
+ *
+ * @param stream - Stream to load from
+ * @return Index header
+ */
+inline IndexHeader load_header(FILE* stream)
+{
+ IndexHeader header;
+ size_t read_size = fread(&header,sizeof(header),1,stream);
+
+ if (read_size!=(size_t)1) {
+ throw FLANNException("Invalid index file, cannot read");
+ }
+
+ if (strcmp(header.signature,FLANN_SIGNATURE_)!=0) {
+ throw FLANNException("Invalid index file, wrong signature");
+ }
+
+ return header;
+
+}
+
+
+template<typename T>
+void save_value(FILE* stream, const T& value, size_t count = 1)
+{
+ fwrite(&value, sizeof(value),count, stream);
+}
+
+template<typename T>
+void save_value(FILE* stream, const cvflann::Matrix<T>& value)
+{
+ fwrite(&value, sizeof(value),1, stream);
+ fwrite(value.data, sizeof(T),value.rows*value.cols, stream);
+}
+
+template<typename T>
+void save_value(FILE* stream, const std::vector<T>& value)
+{
+ size_t size = value.size();
+ fwrite(&size, sizeof(size_t), 1, stream);
+ fwrite(&value[0], sizeof(T), size, stream);
+}
+
+template<typename T>
+void load_value(FILE* stream, T& value, size_t count = 1)
+{
+ size_t read_cnt = fread(&value, sizeof(value), count, stream);
+ if (read_cnt != count) {
+ throw FLANNException("Cannot read from file");
+ }
+}
+
+template<typename T>
+void load_value(FILE* stream, cvflann::Matrix<T>& value)
+{
+ size_t read_cnt = fread(&value, sizeof(value), 1, stream);
+ if (read_cnt != 1) {
+ throw FLANNException("Cannot read from file");
+ }
+ value.data = new T[value.rows*value.cols];
+ read_cnt = fread(value.data, sizeof(T), value.rows*value.cols, stream);
+ if (read_cnt != (size_t)(value.rows*value.cols)) {
+ throw FLANNException("Cannot read from file");
+ }
+}
+
+
+template<typename T>
+void load_value(FILE* stream, std::vector<T>& value)
+{
+ size_t size;
+ size_t read_cnt = fread(&size, sizeof(size_t), 1, stream);
+ if (read_cnt!=1) {
+ throw FLANNException("Cannot read from file");
+ }
+ value.resize(size);
+ read_cnt = fread(&value[0], sizeof(T), size, stream);
+ if (read_cnt != size) {
+ throw FLANNException("Cannot read from file");
+ }
+}
+
+}
+
+#endif /* OPENCV_FLANN_SAVING_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/flann/simplex_downhill.h Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,186 @@
+/***********************************************************************
+ * Software License Agreement (BSD License)
+ *
+ * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved.
+ * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved.
+ *
+ * THE BSD LICENSE
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *************************************************************************/
+
+#ifndef OPENCV_FLANN_SIMPLEX_DOWNHILL_H_
+#define OPENCV_FLANN_SIMPLEX_DOWNHILL_H_
+
+namespace cvflann
+{
+
+/**
+ Adds val to array vals (and point to array points) and keeping the arrays sorted by vals.
+ */
+template <typename T>
+void addValue(int pos, float val, float* vals, T* point, T* points, int n)
+{
+ vals[pos] = val;
+ for (int i=0; i<n; ++i) {
+ points[pos*n+i] = point[i];
+ }
+
+ // bubble down
+ int j=pos;
+ while (j>0 && vals[j]<vals[j-1]) {
+ swap(vals[j],vals[j-1]);
+ for (int i=0; i<n; ++i) {
+ swap(points[j*n+i],points[(j-1)*n+i]);
+ }
+ --j;
+ }
+}
+
+
+/**
+ Simplex downhill optimization function.
+ Preconditions: points is a 2D mattrix of size (n+1) x n
+ func is the cost function taking n an array of n params and returning float
+ vals is the cost function in the n+1 simplex points, if NULL it will be computed
+
+ Postcondition: returns optimum value and points[0..n] are the optimum parameters
+ */
+template <typename T, typename F>
+float optimizeSimplexDownhill(T* points, int n, F func, float* vals = NULL )
+{
+ const int MAX_ITERATIONS = 10;
+
+ assert(n>0);
+
+ T* p_o = new T[n];
+ T* p_r = new T[n];
+ T* p_e = new T[n];
+
+ int alpha = 1;
+
+ int iterations = 0;
+
+ bool ownVals = false;
+ if (vals == NULL) {
+ ownVals = true;
+ vals = new float[n+1];
+ for (int i=0; i<n+1; ++i) {
+ float val = func(points+i*n);
+ addValue(i, val, vals, points+i*n, points, n);
+ }
+ }
+ int nn = n*n;
+
+ while (true) {
+
+ if (iterations++ > MAX_ITERATIONS) break;
+
+ // compute average of simplex points (except the highest point)
+ for (int j=0; j<n; ++j) {
+ p_o[j] = 0;
+ for (int i=0; i<n; ++i) {
+ p_o[i] += points[j*n+i];
+ }
+ }
+ for (int i=0; i<n; ++i) {
+ p_o[i] /= n;
+ }
+
+ bool converged = true;
+ for (int i=0; i<n; ++i) {
+ if (p_o[i] != points[nn+i]) {
+ converged = false;
+ }
+ }
+ if (converged) break;
+
+ // trying a reflection
+ for (int i=0; i<n; ++i) {
+ p_r[i] = p_o[i] + alpha*(p_o[i]-points[nn+i]);
+ }
+ float val_r = func(p_r);
+
+ if ((val_r>=vals[0])&&(val_r<vals[n])) {
+ // reflection between second highest and lowest
+ // add it to the simplex
+ Logger::info("Choosing reflection\n");
+ addValue(n, val_r,vals, p_r, points, n);
+ continue;
+ }
+
+ if (val_r<vals[0]) {
+ // value is smaller than smalest in simplex
+
+ // expand some more to see if it drops further
+ for (int i=0; i<n; ++i) {
+ p_e[i] = 2*p_r[i]-p_o[i];
+ }
+ float val_e = func(p_e);
+
+ if (val_e<val_r) {
+ Logger::info("Choosing reflection and expansion\n");
+ addValue(n, val_e,vals,p_e,points,n);
+ }
+ else {
+ Logger::info("Choosing reflection\n");
+ addValue(n, val_r,vals,p_r,points,n);
+ }
+ continue;
+ }
+ if (val_r>=vals[n]) {
+ for (int i=0; i<n; ++i) {
+ p_e[i] = (p_o[i]+points[nn+i])/2;
+ }
+ float val_e = func(p_e);
+
+ if (val_e<vals[n]) {
+ Logger::info("Choosing contraction\n");
+ addValue(n,val_e,vals,p_e,points,n);
+ continue;
+ }
+ }
+ {
+ Logger::info("Full contraction\n");
+ for (int j=1; j<=n; ++j) {
+ for (int i=0; i<n; ++i) {
+ points[j*n+i] = (points[j*n+i]+points[i])/2;
+ }
+ float val = func(points+j*n);
+ addValue(j,val,vals,points+j*n,points,n);
+ }
+ }
+ }
+
+ float bestVal = vals[0];
+
+ delete[] p_r;
+ delete[] p_o;
+ delete[] p_e;
+ if (ownVals) delete[] vals;
+
+ return bestVal;
+}
+
+}
+
+#endif //OPENCV_FLANN_SIMPLEX_DOWNHILL_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/flann/timer.h Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,94 @@
+/***********************************************************************
+ * Software License Agreement (BSD License)
+ *
+ * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved.
+ * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved.
+ *
+ * THE BSD LICENSE
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *************************************************************************/
+
+#ifndef OPENCV_FLANN_TIMER_H
+#define OPENCV_FLANN_TIMER_H
+
+#include <time.h>
+#include "opencv2/core.hpp"
+#include "opencv2/core/utility.hpp"
+
+namespace cvflann
+{
+
+/**
+ * A start-stop timer class.
+ *
+ * Can be used to time portions of code.
+ */
+class StartStopTimer
+{
+ int64 startTime;
+
+public:
+ /**
+ * Value of the timer.
+ */
+ double value;
+
+
+ /**
+ * Constructor.
+ */
+ StartStopTimer()
+ {
+ reset();
+ }
+
+ /**
+ * Starts the timer.
+ */
+ void start()
+ {
+ startTime = cv::getTickCount();
+ }
+
+ /**
+ * Stops the timer and updates timer value.
+ */
+ void stop()
+ {
+ int64 stopTime = cv::getTickCount();
+ value += ( (double)stopTime - startTime) / cv::getTickFrequency();
+ }
+
+ /**
+ * Resets the timer value to 0.
+ */
+ void reset()
+ {
+ value = 0;
+ }
+
+};
+
+}
+
+#endif // FLANN_TIMER_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/imgcodecs.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,281 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_IMGCODECS_HPP
+#define OPENCV_IMGCODECS_HPP
+
+#include "opencv2/core.hpp"
+
+/**
+ @defgroup imgcodecs Image file reading and writing
+ @{
+ @defgroup imgcodecs_c C API
+ @defgroup imgcodecs_ios iOS glue
+ @}
+*/
+
+//////////////////////////////// image codec ////////////////////////////////
+namespace cv
+{
+
+//! @addtogroup imgcodecs
+//! @{
+
+//! Imread flags
+enum ImreadModes {
+ IMREAD_UNCHANGED = -1, //!< If set, return the loaded image as is (with alpha channel, otherwise it gets cropped).
+ IMREAD_GRAYSCALE = 0, //!< If set, always convert image to the single channel grayscale image.
+ IMREAD_COLOR = 1, //!< If set, always convert image to the 3 channel BGR color image.
+ IMREAD_ANYDEPTH = 2, //!< If set, return 16-bit/32-bit image when the input has the corresponding depth, otherwise convert it to 8-bit.
+ IMREAD_ANYCOLOR = 4, //!< If set, the image is read in any possible color format.
+ IMREAD_LOAD_GDAL = 8, //!< If set, use the gdal driver for loading the image.
+ IMREAD_REDUCED_GRAYSCALE_2 = 16, //!< If set, always convert image to the single channel grayscale image and the image size reduced 1/2.
+ IMREAD_REDUCED_COLOR_2 = 17, //!< If set, always convert image to the 3 channel BGR color image and the image size reduced 1/2.
+ IMREAD_REDUCED_GRAYSCALE_4 = 32, //!< If set, always convert image to the single channel grayscale image and the image size reduced 1/4.
+ IMREAD_REDUCED_COLOR_4 = 33, //!< If set, always convert image to the 3 channel BGR color image and the image size reduced 1/4.
+ IMREAD_REDUCED_GRAYSCALE_8 = 64, //!< If set, always convert image to the single channel grayscale image and the image size reduced 1/8.
+ IMREAD_REDUCED_COLOR_8 = 65, //!< If set, always convert image to the 3 channel BGR color image and the image size reduced 1/8.
+ IMREAD_IGNORE_ORIENTATION = 128 //!< If set, do not rotate the image according to EXIF's orientation flag.
+ };
+
+//! Imwrite flags
+enum ImwriteFlags {
+ IMWRITE_JPEG_QUALITY = 1, //!< For JPEG, it can be a quality from 0 to 100 (the higher is the better). Default value is 95.
+ IMWRITE_JPEG_PROGRESSIVE = 2, //!< Enable JPEG features, 0 or 1, default is False.
+ IMWRITE_JPEG_OPTIMIZE = 3, //!< Enable JPEG features, 0 or 1, default is False.
+ IMWRITE_JPEG_RST_INTERVAL = 4, //!< JPEG restart interval, 0 - 65535, default is 0 - no restart.
+ IMWRITE_JPEG_LUMA_QUALITY = 5, //!< Separate luma quality level, 0 - 100, default is 0 - don't use.
+ IMWRITE_JPEG_CHROMA_QUALITY = 6, //!< Separate chroma quality level, 0 - 100, default is 0 - don't use.
+ IMWRITE_PNG_COMPRESSION = 16, //!< For PNG, it can be the compression level from 0 to 9. A higher value means a smaller size and longer compression time. Default value is 3. Also strategy is changed to IMWRITE_PNG_STRATEGY_DEFAULT (Z_DEFAULT_STRATEGY).
+ IMWRITE_PNG_STRATEGY = 17, //!< One of cv::ImwritePNGFlags, default is IMWRITE_PNG_STRATEGY_DEFAULT.
+ IMWRITE_PNG_BILEVEL = 18, //!< Binary level PNG, 0 or 1, default is 0.
+ IMWRITE_PXM_BINARY = 32, //!< For PPM, PGM, or PBM, it can be a binary format flag, 0 or 1. Default value is 1.
+ IMWRITE_WEBP_QUALITY = 64, //!< For WEBP, it can be a quality from 1 to 100 (the higher is the better). By default (without any parameter) and for quality above 100 the lossless compression is used.
+ IMWRITE_PAM_TUPLETYPE = 128,//!< For PAM, sets the TUPLETYPE field to the corresponding string value that is defined for the format
+ };
+
+//! Imwrite PNG specific flags used to tune the compression algorithm.
+/** These flags will be modify the way of PNG image compression and will be passed to the underlying zlib processing stage.
+
+- The effect of IMWRITE_PNG_STRATEGY_FILTERED is to force more Huffman coding and less string matching; it is somewhat intermediate between IMWRITE_PNG_STRATEGY_DEFAULT and IMWRITE_PNG_STRATEGY_HUFFMAN_ONLY.
+- IMWRITE_PNG_STRATEGY_RLE is designed to be almost as fast as IMWRITE_PNG_STRATEGY_HUFFMAN_ONLY, but give better compression for PNG image data.
+- The strategy parameter only affects the compression ratio but not the correctness of the compressed output even if it is not set appropriately.
+- IMWRITE_PNG_STRATEGY_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler decoder for special applications.
+*/
+enum ImwritePNGFlags {
+ IMWRITE_PNG_STRATEGY_DEFAULT = 0, //!< Use this value for normal data.
+ IMWRITE_PNG_STRATEGY_FILTERED = 1, //!< Use this value for data produced by a filter (or predictor).Filtered data consists mostly of small values with a somewhat random distribution. In this case, the compression algorithm is tuned to compress them better.
+ IMWRITE_PNG_STRATEGY_HUFFMAN_ONLY = 2, //!< Use this value to force Huffman encoding only (no string match).
+ IMWRITE_PNG_STRATEGY_RLE = 3, //!< Use this value to limit match distances to one (run-length encoding).
+ IMWRITE_PNG_STRATEGY_FIXED = 4 //!< Using this value prevents the use of dynamic Huffman codes, allowing for a simpler decoder for special applications.
+ };
+
+//! Imwrite PAM specific tupletype flags used to define the 'TUPETYPE' field of a PAM file.
+enum ImwritePAMFlags {
+ IMWRITE_PAM_FORMAT_NULL = 0,
+ IMWRITE_PAM_FORMAT_BLACKANDWHITE = 1,
+ IMWRITE_PAM_FORMAT_GRAYSCALE = 2,
+ IMWRITE_PAM_FORMAT_GRAYSCALE_ALPHA = 3,
+ IMWRITE_PAM_FORMAT_RGB = 4,
+ IMWRITE_PAM_FORMAT_RGB_ALPHA = 5,
+ };
+
+/** @brief Loads an image from a file.
+
+@anchor imread
+
+The function imread loads an image from the specified file and returns it. If the image cannot be
+read (because of missing file, improper permissions, unsupported or invalid format), the function
+returns an empty matrix ( Mat::data==NULL ).
+
+Currently, the following file formats are supported:
+
+- Windows bitmaps - \*.bmp, \*.dib (always supported)
+- JPEG files - \*.jpeg, \*.jpg, \*.jpe (see the *Notes* section)
+- JPEG 2000 files - \*.jp2 (see the *Notes* section)
+- Portable Network Graphics - \*.png (see the *Notes* section)
+- WebP - \*.webp (see the *Notes* section)
+- Portable image format - \*.pbm, \*.pgm, \*.ppm \*.pxm, \*.pnm (always supported)
+- Sun rasters - \*.sr, \*.ras (always supported)
+- TIFF files - \*.tiff, \*.tif (see the *Notes* section)
+- OpenEXR Image files - \*.exr (see the *Notes* section)
+- Radiance HDR - \*.hdr, \*.pic (always supported)
+- Raster and Vector geospatial data supported by Gdal (see the *Notes* section)
+
+@note
+
+- The function determines the type of an image by the content, not by the file extension.
+- In the case of color images, the decoded images will have the channels stored in **B G R** order.
+- On Microsoft Windows\* OS and MacOSX\*, the codecs shipped with an OpenCV image (libjpeg,
+ libpng, libtiff, and libjasper) are used by default. So, OpenCV can always read JPEGs, PNGs,
+ and TIFFs. On MacOSX, there is also an option to use native MacOSX image readers. But beware
+ that currently these native image loaders give images with different pixel values because of
+ the color management embedded into MacOSX.
+- On Linux\*, BSD flavors and other Unix-like open-source operating systems, OpenCV looks for
+ codecs supplied with an OS image. Install the relevant packages (do not forget the development
+ files, for example, "libjpeg-dev", in Debian\* and Ubuntu\*) to get the codec support or turn
+ on the OPENCV_BUILD_3RDPARTY_LIBS flag in CMake.
+- In the case you set *WITH_GDAL* flag to true in CMake and @ref IMREAD_LOAD_GDAL to load the image,
+ then [GDAL](http://www.gdal.org) driver will be used in order to decode the image by supporting
+ the following formats: [Raster](http://www.gdal.org/formats_list.html),
+ [Vector](http://www.gdal.org/ogr_formats.html).
+- If EXIF information are embedded in the image file, the EXIF orientation will be taken into account
+ and thus the image will be rotated accordingly except if the flag @ref IMREAD_IGNORE_ORIENTATION is passed.
+@param filename Name of file to be loaded.
+@param flags Flag that can take values of cv::ImreadModes
+*/
+CV_EXPORTS_W Mat imread( const String& filename, int flags = IMREAD_COLOR );
+
+/** @brief Loads a multi-page image from a file.
+
+The function imreadmulti loads a multi-page image from the specified file into a vector of Mat objects.
+@param filename Name of file to be loaded.
+@param flags Flag that can take values of cv::ImreadModes, default with cv::IMREAD_ANYCOLOR.
+@param mats A vector of Mat objects holding each page, if more than one.
+@sa cv::imread
+*/
+CV_EXPORTS_W bool imreadmulti(const String& filename, std::vector<Mat>& mats, int flags = IMREAD_ANYCOLOR);
+
+/** @brief Saves an image to a specified file.
+
+The function imwrite saves the image to the specified file. The image format is chosen based on the
+filename extension (see cv::imread for the list of extensions). Only 8-bit (or 16-bit unsigned (CV_16U)
+in case of PNG, JPEG 2000, and TIFF) single-channel or 3-channel (with 'BGR' channel order) images
+can be saved using this function. If the format, depth or channel order is different, use
+Mat::convertTo , and cv::cvtColor to convert it before saving. Or, use the universal FileStorage I/O
+functions to save the image to XML or YAML format.
+
+It is possible to store PNG images with an alpha channel using this function. To do this, create
+8-bit (or 16-bit) 4-channel image BGRA, where the alpha channel goes last. Fully transparent pixels
+should have alpha set to 0, fully opaque pixels should have alpha set to 255/65535.
+
+The sample below shows how to create such a BGRA image and store to PNG file. It also demonstrates how to set custom
+compression parameters :
+@code
+ #include <opencv2/opencv.hpp>
+
+ using namespace cv;
+ using namespace std;
+
+ void createAlphaMat(Mat &mat)
+ {
+ CV_Assert(mat.channels() == 4);
+ for (int i = 0; i < mat.rows; ++i) {
+ for (int j = 0; j < mat.cols; ++j) {
+ Vec4b& bgra = mat.at<Vec4b>(i, j);
+ bgra[0] = UCHAR_MAX; // Blue
+ bgra[1] = saturate_cast<uchar>((float (mat.cols - j)) / ((float)mat.cols) * UCHAR_MAX); // Green
+ bgra[2] = saturate_cast<uchar>((float (mat.rows - i)) / ((float)mat.rows) * UCHAR_MAX); // Red
+ bgra[3] = saturate_cast<uchar>(0.5 * (bgra[1] + bgra[2])); // Alpha
+ }
+ }
+ }
+
+ int main(int argv, char **argc)
+ {
+ // Create mat with alpha channel
+ Mat mat(480, 640, CV_8UC4);
+ createAlphaMat(mat);
+
+ vector<int> compression_params;
+ compression_params.push_back(IMWRITE_PNG_COMPRESSION);
+ compression_params.push_back(9);
+
+ try {
+ imwrite("alpha.png", mat, compression_params);
+ }
+ catch (cv::Exception& ex) {
+ fprintf(stderr, "Exception converting image to PNG format: %s\n", ex.what());
+ return 1;
+ }
+
+ fprintf(stdout, "Saved PNG file with alpha data.\n");
+ return 0;
+ }
+@endcode
+@param filename Name of the file.
+@param img Image to be saved.
+@param params Format-specific parameters encoded as pairs (paramId_1, paramValue_1, paramId_2, paramValue_2, ... .) see cv::ImwriteFlags
+*/
+CV_EXPORTS_W bool imwrite( const String& filename, InputArray img,
+ const std::vector<int>& params = std::vector<int>());
+
+/** @brief Reads an image from a buffer in memory.
+
+The function imdecode reads an image from the specified buffer in the memory. If the buffer is too short or
+contains invalid data, the function returns an empty matrix ( Mat::data==NULL ).
+
+See cv::imread for the list of supported formats and flags description.
+
+@note In the case of color images, the decoded images will have the channels stored in **B G R** order.
+@param buf Input array or vector of bytes.
+@param flags The same flags as in cv::imread, see cv::ImreadModes.
+*/
+CV_EXPORTS_W Mat imdecode( InputArray buf, int flags );
+
+/** @overload
+@param buf
+@param flags
+@param dst The optional output placeholder for the decoded matrix. It can save the image
+reallocations when the function is called repeatedly for images of the same size.
+*/
+CV_EXPORTS Mat imdecode( InputArray buf, int flags, Mat* dst);
+
+/** @brief Encodes an image into a memory buffer.
+
+The function imencode compresses the image and stores it in the memory buffer that is resized to fit the
+result. See cv::imwrite for the list of supported formats and flags description.
+
+@param ext File extension that defines the output format.
+@param img Image to be written.
+@param buf Output buffer resized to fit the compressed image.
+@param params Format-specific parameters. See cv::imwrite and cv::ImwriteFlags.
+*/
+CV_EXPORTS_W bool imencode( const String& ext, InputArray img,
+ CV_OUT std::vector<uchar>& buf,
+ const std::vector<int>& params = std::vector<int>());
+
+//! @} imgcodecs
+
+} // cv
+
+#endif //OPENCV_IMGCODECS_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/opencv2/imgcodecs/imgcodecs.hpp Fri Jan 29 04:53:38 2021 +0000 @@ -0,0 +1,48 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifdef __OPENCV_BUILD +#error this is a compatibility header which should not be used inside the OpenCV library +#endif + +#include "opencv2/imgcodecs.hpp"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/imgcodecs/imgcodecs_c.h Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,148 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// Intel License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000, Intel Corporation, all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of Intel Corporation may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_IMGCODECS_H
+#define OPENCV_IMGCODECS_H
+
+#include "opencv2/core/core_c.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/** @addtogroup imgcodecs_c
+ @{
+ */
+
+enum
+{
+/* 8bit, color or not */
+ CV_LOAD_IMAGE_UNCHANGED =-1,
+/* 8bit, gray */
+ CV_LOAD_IMAGE_GRAYSCALE =0,
+/* ?, color */
+ CV_LOAD_IMAGE_COLOR =1,
+/* any depth, ? */
+ CV_LOAD_IMAGE_ANYDEPTH =2,
+/* ?, any color */
+ CV_LOAD_IMAGE_ANYCOLOR =4,
+/* ?, no rotate */
+ CV_LOAD_IMAGE_IGNORE_ORIENTATION =128
+};
+
+/* load image from file
+ iscolor can be a combination of above flags where CV_LOAD_IMAGE_UNCHANGED
+ overrides the other flags
+ using CV_LOAD_IMAGE_ANYCOLOR alone is equivalent to CV_LOAD_IMAGE_UNCHANGED
+ unless CV_LOAD_IMAGE_ANYDEPTH is specified images are converted to 8bit
+*/
+CVAPI(IplImage*) cvLoadImage( const char* filename, int iscolor CV_DEFAULT(CV_LOAD_IMAGE_COLOR));
+CVAPI(CvMat*) cvLoadImageM( const char* filename, int iscolor CV_DEFAULT(CV_LOAD_IMAGE_COLOR));
+
+enum
+{
+ CV_IMWRITE_JPEG_QUALITY =1,
+ CV_IMWRITE_JPEG_PROGRESSIVE =2,
+ CV_IMWRITE_JPEG_OPTIMIZE =3,
+ CV_IMWRITE_JPEG_RST_INTERVAL =4,
+ CV_IMWRITE_JPEG_LUMA_QUALITY =5,
+ CV_IMWRITE_JPEG_CHROMA_QUALITY =6,
+ CV_IMWRITE_PNG_COMPRESSION =16,
+ CV_IMWRITE_PNG_STRATEGY =17,
+ CV_IMWRITE_PNG_BILEVEL =18,
+ CV_IMWRITE_PNG_STRATEGY_DEFAULT =0,
+ CV_IMWRITE_PNG_STRATEGY_FILTERED =1,
+ CV_IMWRITE_PNG_STRATEGY_HUFFMAN_ONLY =2,
+ CV_IMWRITE_PNG_STRATEGY_RLE =3,
+ CV_IMWRITE_PNG_STRATEGY_FIXED =4,
+ CV_IMWRITE_PXM_BINARY =32,
+ CV_IMWRITE_WEBP_QUALITY =64,
+ CV_IMWRITE_PAM_TUPLETYPE = 128,
+ CV_IMWRITE_PAM_FORMAT_NULL = 0,
+ CV_IMWRITE_PAM_FORMAT_BLACKANDWHITE = 1,
+ CV_IMWRITE_PAM_FORMAT_GRAYSCALE = 2,
+ CV_IMWRITE_PAM_FORMAT_GRAYSCALE_ALPHA = 3,
+ CV_IMWRITE_PAM_FORMAT_RGB = 4,
+ CV_IMWRITE_PAM_FORMAT_RGB_ALPHA = 5,
+};
+
+
+
+/* save image to file */
+CVAPI(int) cvSaveImage( const char* filename, const CvArr* image,
+ const int* params CV_DEFAULT(0) );
+
+/* decode image stored in the buffer */
+CVAPI(IplImage*) cvDecodeImage( const CvMat* buf, int iscolor CV_DEFAULT(CV_LOAD_IMAGE_COLOR));
+CVAPI(CvMat*) cvDecodeImageM( const CvMat* buf, int iscolor CV_DEFAULT(CV_LOAD_IMAGE_COLOR));
+
+/* encode image and store the result as a byte vector (single-row 8uC1 matrix) */
+CVAPI(CvMat*) cvEncodeImage( const char* ext, const CvArr* image,
+ const int* params CV_DEFAULT(0) );
+
+enum
+{
+ CV_CVTIMG_FLIP =1,
+ CV_CVTIMG_SWAP_RB =2
+};
+
+/* utility function: convert one image to another with optional vertical flip */
+CVAPI(void) cvConvertImage( const CvArr* src, CvArr* dst, int flags CV_DEFAULT(0));
+
+CVAPI(int) cvHaveImageReader(const char* filename);
+CVAPI(int) cvHaveImageWriter(const char* filename);
+
+
+/****************************************************************************************\
+* Obsolete functions/synonyms *
+\****************************************************************************************/
+
+#define cvvLoadImage(name) cvLoadImage((name),1)
+#define cvvSaveImage cvSaveImage
+#define cvvConvertImage cvConvertImage
+
+/** @} imgcodecs_c */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // OPENCV_IMGCODECS_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/imgcodecs/ios.h Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,57 @@
+
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#import <UIKit/UIKit.h>
+#import <Accelerate/Accelerate.h>
+#import <AVFoundation/AVFoundation.h>
+#import <ImageIO/ImageIO.h>
+#include "opencv2/core/core.hpp"
+
+//! @addtogroup imgcodecs_ios
+//! @{
+
+UIImage* MatToUIImage(const cv::Mat& image);
+void UIImageToMat(const UIImage* image,
+ cv::Mat& m, bool alphaExist = false);
+
+//! @}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/imgproc.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,4649 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_IMGPROC_HPP
+#define OPENCV_IMGPROC_HPP
+
+#include "opencv2/core.hpp"
+
+/**
+ @defgroup imgproc Image processing
+ @{
+ @defgroup imgproc_filter Image Filtering
+
+Functions and classes described in this section are used to perform various linear or non-linear
+filtering operations on 2D images (represented as Mat's). It means that for each pixel location
+\f$(x,y)\f$ in the source image (normally, rectangular), its neighborhood is considered and used to
+compute the response. In case of a linear filter, it is a weighted sum of pixel values. In case of
+morphological operations, it is the minimum or maximum values, and so on. The computed response is
+stored in the destination image at the same location \f$(x,y)\f$. It means that the output image
+will be of the same size as the input image. Normally, the functions support multi-channel arrays,
+in which case every channel is processed independently. Therefore, the output image will also have
+the same number of channels as the input one.
+
+Another common feature of the functions and classes described in this section is that, unlike
+simple arithmetic functions, they need to extrapolate values of some non-existing pixels. For
+example, if you want to smooth an image using a Gaussian \f$3 \times 3\f$ filter, then, when
+processing the left-most pixels in each row, you need pixels to the left of them, that is, outside
+of the image. You can let these pixels be the same as the left-most image pixels ("replicated
+border" extrapolation method), or assume that all the non-existing pixels are zeros ("constant
+border" extrapolation method), and so on. OpenCV enables you to specify the extrapolation method.
+For details, see cv::BorderTypes
+
+@anchor filter_depths
+### Depth combinations
+Input depth (src.depth()) | Output depth (ddepth)
+--------------------------|----------------------
+CV_8U | -1/CV_16S/CV_32F/CV_64F
+CV_16U/CV_16S | -1/CV_32F/CV_64F
+CV_32F | -1/CV_32F/CV_64F
+CV_64F | -1/CV_64F
+
+@note when ddepth=-1, the output image will have the same depth as the source.
+
+ @defgroup imgproc_transform Geometric Image Transformations
+
+The functions in this section perform various geometrical transformations of 2D images. They do not
+change the image content but deform the pixel grid and map this deformed grid to the destination
+image. In fact, to avoid sampling artifacts, the mapping is done in the reverse order, from
+destination to the source. That is, for each pixel \f$(x, y)\f$ of the destination image, the
+functions compute coordinates of the corresponding "donor" pixel in the source image and copy the
+pixel value:
+
+\f[\texttt{dst} (x,y)= \texttt{src} (f_x(x,y), f_y(x,y))\f]
+
+In case when you specify the forward mapping \f$\left<g_x, g_y\right>: \texttt{src} \rightarrow
+\texttt{dst}\f$, the OpenCV functions first compute the corresponding inverse mapping
+\f$\left<f_x, f_y\right>: \texttt{dst} \rightarrow \texttt{src}\f$ and then use the above formula.
+
+The actual implementations of the geometrical transformations, from the most generic remap and to
+the simplest and the fastest resize, need to solve two main problems with the above formula:
+
+- Extrapolation of non-existing pixels. Similarly to the filtering functions described in the
+previous section, for some \f$(x,y)\f$, either one of \f$f_x(x,y)\f$, or \f$f_y(x,y)\f$, or both
+of them may fall outside of the image. In this case, an extrapolation method needs to be used.
+OpenCV provides the same selection of extrapolation methods as in the filtering functions. In
+addition, it provides the method BORDER_TRANSPARENT. This means that the corresponding pixels in
+the destination image will not be modified at all.
+
+- Interpolation of pixel values. Usually \f$f_x(x,y)\f$ and \f$f_y(x,y)\f$ are floating-point
+numbers. This means that \f$\left<f_x, f_y\right>\f$ can be either an affine or perspective
+transformation, or radial lens distortion correction, and so on. So, a pixel value at fractional
+coordinates needs to be retrieved. In the simplest case, the coordinates can be just rounded to the
+nearest integer coordinates and the corresponding pixel can be used. This is called a
+nearest-neighbor interpolation. However, a better result can be achieved by using more
+sophisticated [interpolation methods](http://en.wikipedia.org/wiki/Multivariate_interpolation) ,
+where a polynomial function is fit into some neighborhood of the computed pixel \f$(f_x(x,y),
+f_y(x,y))\f$, and then the value of the polynomial at \f$(f_x(x,y), f_y(x,y))\f$ is taken as the
+interpolated pixel value. In OpenCV, you can choose between several interpolation methods. See
+resize for details.
+
+ @defgroup imgproc_misc Miscellaneous Image Transformations
+ @defgroup imgproc_draw Drawing Functions
+
+Drawing functions work with matrices/images of arbitrary depth. The boundaries of the shapes can be
+rendered with antialiasing (implemented only for 8-bit images for now). All the functions include
+the parameter color that uses an RGB value (that may be constructed with the Scalar constructor )
+for color images and brightness for grayscale images. For color images, the channel ordering is
+normally *Blue, Green, Red*. This is what imshow, imread, and imwrite expect. So, if you form a
+color using the Scalar constructor, it should look like:
+
+\f[\texttt{Scalar} (blue \_ component, green \_ component, red \_ component[, alpha \_ component])\f]
+
+If you are using your own image rendering and I/O functions, you can use any channel ordering. The
+drawing functions process each channel independently and do not depend on the channel order or even
+on the used color space. The whole image can be converted from BGR to RGB or to a different color
+space using cvtColor .
+
+If a drawn figure is partially or completely outside the image, the drawing functions clip it. Also,
+many drawing functions can handle pixel coordinates specified with sub-pixel accuracy. This means
+that the coordinates can be passed as fixed-point numbers encoded as integers. The number of
+fractional bits is specified by the shift parameter and the real point coordinates are calculated as
+\f$\texttt{Point}(x,y)\rightarrow\texttt{Point2f}(x*2^{-shift},y*2^{-shift})\f$ . This feature is
+especially effective when rendering antialiased shapes.
+
+@note The functions do not support alpha-transparency when the target image is 4-channel. In this
+case, the color[3] is simply copied to the repainted pixels. Thus, if you want to paint
+semi-transparent shapes, you can paint them in a separate buffer and then blend it with the main
+image.
+
+ @defgroup imgproc_colormap ColorMaps in OpenCV
+
+The human perception isn't built for observing fine changes in grayscale images. Human eyes are more
+sensitive to observing changes between colors, so you often need to recolor your grayscale images to
+get a clue about them. OpenCV now comes with various colormaps to enhance the visualization in your
+computer vision application.
+
+In OpenCV you only need applyColorMap to apply a colormap on a given image. The following sample
+code reads the path to an image from command line, applies a Jet colormap on it and shows the
+result:
+
+@code
+#include <opencv2/core.hpp>
+#include <opencv2/imgproc.hpp>
+#include <opencv2/imgcodecs.hpp>
+#include <opencv2/highgui.hpp>
+using namespace cv;
+
+#include <iostream>
+using namespace std;
+
+int main(int argc, const char *argv[])
+{
+ // We need an input image. (can be grayscale or color)
+ if (argc < 2)
+ {
+ cerr << "We need an image to process here. Please run: colorMap [path_to_image]" << endl;
+ return -1;
+ }
+ Mat img_in = imread(argv[1]);
+ if(img_in.empty())
+ {
+ cerr << "Sample image (" << argv[1] << ") is empty. Please adjust your path, so it points to a valid input image!" << endl;
+ return -1;
+ }
+ // Holds the colormap version of the image:
+ Mat img_color;
+ // Apply the colormap:
+ applyColorMap(img_in, img_color, COLORMAP_JET);
+ // Show the result:
+ imshow("colorMap", img_color);
+ waitKey(0);
+ return 0;
+}
+@endcode
+
+@see cv::ColormapTypes
+
+ @defgroup imgproc_subdiv2d Planar Subdivision
+
+The Subdiv2D class described in this section is used to perform various planar subdivision on
+a set of 2D points (represented as vector of Point2f). OpenCV subdivides a plane into triangles
+using the Delaunay’s algorithm, which corresponds to the dual graph of the Voronoi diagram.
+In the figure below, the Delaunay’s triangulation is marked with black lines and the Voronoi
+diagram with red lines.
+
+
+
+The subdivisions can be used for the 3D piece-wise transformation of a plane, morphing, fast
+location of points on the plane, building special graphs (such as NNG,RNG), and so forth.
+
+ @defgroup imgproc_hist Histograms
+ @defgroup imgproc_shape Structural Analysis and Shape Descriptors
+ @defgroup imgproc_motion Motion Analysis and Object Tracking
+ @defgroup imgproc_feature Feature Detection
+ @defgroup imgproc_object Object Detection
+ @defgroup imgproc_c C API
+ @defgroup imgproc_hal Hardware Acceleration Layer
+ @{
+ @defgroup imgproc_hal_functions Functions
+ @defgroup imgproc_hal_interface Interface
+ @}
+ @}
+*/
+
+namespace cv
+{
+
+/** @addtogroup imgproc
+@{
+*/
+
+//! @addtogroup imgproc_filter
+//! @{
+
+//! type of morphological operation
+enum MorphTypes{
+ MORPH_ERODE = 0, //!< see cv::erode
+ MORPH_DILATE = 1, //!< see cv::dilate
+ MORPH_OPEN = 2, //!< an opening operation
+ //!< \f[\texttt{dst} = \mathrm{open} ( \texttt{src} , \texttt{element} )= \mathrm{dilate} ( \mathrm{erode} ( \texttt{src} , \texttt{element} ))\f]
+ MORPH_CLOSE = 3, //!< a closing operation
+ //!< \f[\texttt{dst} = \mathrm{close} ( \texttt{src} , \texttt{element} )= \mathrm{erode} ( \mathrm{dilate} ( \texttt{src} , \texttt{element} ))\f]
+ MORPH_GRADIENT = 4, //!< a morphological gradient
+ //!< \f[\texttt{dst} = \mathrm{morph\_grad} ( \texttt{src} , \texttt{element} )= \mathrm{dilate} ( \texttt{src} , \texttt{element} )- \mathrm{erode} ( \texttt{src} , \texttt{element} )\f]
+ MORPH_TOPHAT = 5, //!< "top hat"
+ //!< \f[\texttt{dst} = \mathrm{tophat} ( \texttt{src} , \texttt{element} )= \texttt{src} - \mathrm{open} ( \texttt{src} , \texttt{element} )\f]
+ MORPH_BLACKHAT = 6, //!< "black hat"
+ //!< \f[\texttt{dst} = \mathrm{blackhat} ( \texttt{src} , \texttt{element} )= \mathrm{close} ( \texttt{src} , \texttt{element} )- \texttt{src}\f]
+ MORPH_HITMISS = 7 //!< "hit and miss"
+ //!< .- Only supported for CV_8UC1 binary images. Tutorial can be found in [this page](https://web.archive.org/web/20160316070407/http://opencv-code.com/tutorials/hit-or-miss-transform-in-opencv/)
+};
+
+//! shape of the structuring element
+enum MorphShapes {
+ MORPH_RECT = 0, //!< a rectangular structuring element: \f[E_{ij}=1\f]
+ MORPH_CROSS = 1, //!< a cross-shaped structuring element:
+ //!< \f[E_{ij} = \fork{1}{if i=\texttt{anchor.y} or j=\texttt{anchor.x}}{0}{otherwise}\f]
+ MORPH_ELLIPSE = 2 //!< an elliptic structuring element, that is, a filled ellipse inscribed
+ //!< into the rectangle Rect(0, 0, esize.width, 0.esize.height)
+};
+
+//! @} imgproc_filter
+
+//! @addtogroup imgproc_transform
+//! @{
+
+//! interpolation algorithm
+enum InterpolationFlags{
+ /** nearest neighbor interpolation */
+ INTER_NEAREST = 0,
+ /** bilinear interpolation */
+ INTER_LINEAR = 1,
+ /** bicubic interpolation */
+ INTER_CUBIC = 2,
+ /** resampling using pixel area relation. It may be a preferred method for image decimation, as
+ it gives moire'-free results. But when the image is zoomed, it is similar to the INTER_NEAREST
+ method. */
+ INTER_AREA = 3,
+ /** Lanczos interpolation over 8x8 neighborhood */
+ INTER_LANCZOS4 = 4,
+ /** mask for interpolation codes */
+ INTER_MAX = 7,
+ /** flag, fills all of the destination image pixels. If some of them correspond to outliers in the
+ source image, they are set to zero */
+ WARP_FILL_OUTLIERS = 8,
+ /** flag, inverse transformation
+
+ For example, @ref cv::linearPolar or @ref cv::logPolar transforms:
+ - flag is __not__ set: \f$dst( \rho , \phi ) = src(x,y)\f$
+ - flag is set: \f$dst(x,y) = src( \rho , \phi )\f$
+ */
+ WARP_INVERSE_MAP = 16
+};
+
+enum InterpolationMasks {
+ INTER_BITS = 5,
+ INTER_BITS2 = INTER_BITS * 2,
+ INTER_TAB_SIZE = 1 << INTER_BITS,
+ INTER_TAB_SIZE2 = INTER_TAB_SIZE * INTER_TAB_SIZE
+ };
+
+//! @} imgproc_transform
+
+//! @addtogroup imgproc_misc
+//! @{
+
+//! Distance types for Distance Transform and M-estimators
+//! @see cv::distanceTransform, cv::fitLine
+enum DistanceTypes {
+ DIST_USER = -1, //!< User defined distance
+ DIST_L1 = 1, //!< distance = |x1-x2| + |y1-y2|
+ DIST_L2 = 2, //!< the simple euclidean distance
+ DIST_C = 3, //!< distance = max(|x1-x2|,|y1-y2|)
+ DIST_L12 = 4, //!< L1-L2 metric: distance = 2(sqrt(1+x*x/2) - 1))
+ DIST_FAIR = 5, //!< distance = c^2(|x|/c-log(1+|x|/c)), c = 1.3998
+ DIST_WELSCH = 6, //!< distance = c^2/2(1-exp(-(x/c)^2)), c = 2.9846
+ DIST_HUBER = 7 //!< distance = |x|<c ? x^2/2 : c(|x|-c/2), c=1.345
+};
+
+//! Mask size for distance transform
+enum DistanceTransformMasks {
+ DIST_MASK_3 = 3, //!< mask=3
+ DIST_MASK_5 = 5, //!< mask=5
+ DIST_MASK_PRECISE = 0 //!<
+};
+
+//! type of the threshold operation
+//! 
+enum ThresholdTypes {
+ THRESH_BINARY = 0, //!< \f[\texttt{dst} (x,y) = \fork{\texttt{maxval}}{if \(\texttt{src}(x,y) > \texttt{thresh}\)}{0}{otherwise}\f]
+ THRESH_BINARY_INV = 1, //!< \f[\texttt{dst} (x,y) = \fork{0}{if \(\texttt{src}(x,y) > \texttt{thresh}\)}{\texttt{maxval}}{otherwise}\f]
+ THRESH_TRUNC = 2, //!< \f[\texttt{dst} (x,y) = \fork{\texttt{threshold}}{if \(\texttt{src}(x,y) > \texttt{thresh}\)}{\texttt{src}(x,y)}{otherwise}\f]
+ THRESH_TOZERO = 3, //!< \f[\texttt{dst} (x,y) = \fork{\texttt{src}(x,y)}{if \(\texttt{src}(x,y) > \texttt{thresh}\)}{0}{otherwise}\f]
+ THRESH_TOZERO_INV = 4, //!< \f[\texttt{dst} (x,y) = \fork{0}{if \(\texttt{src}(x,y) > \texttt{thresh}\)}{\texttt{src}(x,y)}{otherwise}\f]
+ THRESH_MASK = 7,
+ THRESH_OTSU = 8, //!< flag, use Otsu algorithm to choose the optimal threshold value
+ THRESH_TRIANGLE = 16 //!< flag, use Triangle algorithm to choose the optimal threshold value
+};
+
+//! adaptive threshold algorithm
+//! see cv::adaptiveThreshold
+enum AdaptiveThresholdTypes {
+ /** the threshold value \f$T(x,y)\f$ is a mean of the \f$\texttt{blockSize} \times
+ \texttt{blockSize}\f$ neighborhood of \f$(x, y)\f$ minus C */
+ ADAPTIVE_THRESH_MEAN_C = 0,
+ /** the threshold value \f$T(x, y)\f$ is a weighted sum (cross-correlation with a Gaussian
+ window) of the \f$\texttt{blockSize} \times \texttt{blockSize}\f$ neighborhood of \f$(x, y)\f$
+ minus C . The default sigma (standard deviation) is used for the specified blockSize . See
+ cv::getGaussianKernel*/
+ ADAPTIVE_THRESH_GAUSSIAN_C = 1
+};
+
+//! cv::undistort mode
+enum UndistortTypes {
+ PROJ_SPHERICAL_ORTHO = 0,
+ PROJ_SPHERICAL_EQRECT = 1
+ };
+
+//! class of the pixel in GrabCut algorithm
+enum GrabCutClasses {
+ GC_BGD = 0, //!< an obvious background pixels
+ GC_FGD = 1, //!< an obvious foreground (object) pixel
+ GC_PR_BGD = 2, //!< a possible background pixel
+ GC_PR_FGD = 3 //!< a possible foreground pixel
+};
+
+//! GrabCut algorithm flags
+enum GrabCutModes {
+ /** The function initializes the state and the mask using the provided rectangle. After that it
+ runs iterCount iterations of the algorithm. */
+ GC_INIT_WITH_RECT = 0,
+ /** The function initializes the state using the provided mask. Note that GC_INIT_WITH_RECT
+ and GC_INIT_WITH_MASK can be combined. Then, all the pixels outside of the ROI are
+ automatically initialized with GC_BGD .*/
+ GC_INIT_WITH_MASK = 1,
+ /** The value means that the algorithm should just resume. */
+ GC_EVAL = 2
+};
+
+//! distanceTransform algorithm flags
+enum DistanceTransformLabelTypes {
+ /** each connected component of zeros in src (as well as all the non-zero pixels closest to the
+ connected component) will be assigned the same label */
+ DIST_LABEL_CCOMP = 0,
+ /** each zero pixel (and all the non-zero pixels closest to it) gets its own label. */
+ DIST_LABEL_PIXEL = 1
+};
+
+//! floodfill algorithm flags
+enum FloodFillFlags {
+ /** If set, the difference between the current pixel and seed pixel is considered. Otherwise,
+ the difference between neighbor pixels is considered (that is, the range is floating). */
+ FLOODFILL_FIXED_RANGE = 1 << 16,
+ /** If set, the function does not change the image ( newVal is ignored), and only fills the
+ mask with the value specified in bits 8-16 of flags as described above. This option only make
+ sense in function variants that have the mask parameter. */
+ FLOODFILL_MASK_ONLY = 1 << 17
+};
+
+//! @} imgproc_misc
+
+//! @addtogroup imgproc_shape
+//! @{
+
+//! connected components algorithm output formats
+enum ConnectedComponentsTypes {
+ CC_STAT_LEFT = 0, //!< The leftmost (x) coordinate which is the inclusive start of the bounding
+ //!< box in the horizontal direction.
+ CC_STAT_TOP = 1, //!< The topmost (y) coordinate which is the inclusive start of the bounding
+ //!< box in the vertical direction.
+ CC_STAT_WIDTH = 2, //!< The horizontal size of the bounding box
+ CC_STAT_HEIGHT = 3, //!< The vertical size of the bounding box
+ CC_STAT_AREA = 4, //!< The total area (in pixels) of the connected component
+ CC_STAT_MAX = 5
+};
+
+//! connected components algorithm
+enum ConnectedComponentsAlgorithmsTypes {
+ CCL_WU = 0, //!< SAUF algorithm for 8-way connectivity, SAUF algorithm for 4-way connectivity
+ CCL_DEFAULT = -1, //!< BBDT algortihm for 8-way connectivity, SAUF algorithm for 4-way connectivity
+ CCL_GRANA = 1 //!< BBDT algorithm for 8-way connectivity, SAUF algorithm for 4-way connectivity
+};
+
+//! mode of the contour retrieval algorithm
+enum RetrievalModes {
+ /** retrieves only the extreme outer contours. It sets `hierarchy[i][2]=hierarchy[i][3]=-1` for
+ all the contours. */
+ RETR_EXTERNAL = 0,
+ /** retrieves all of the contours without establishing any hierarchical relationships. */
+ RETR_LIST = 1,
+ /** retrieves all of the contours and organizes them into a two-level hierarchy. At the top
+ level, there are external boundaries of the components. At the second level, there are
+ boundaries of the holes. If there is another contour inside a hole of a connected component, it
+ is still put at the top level. */
+ RETR_CCOMP = 2,
+ /** retrieves all of the contours and reconstructs a full hierarchy of nested contours.*/
+ RETR_TREE = 3,
+ RETR_FLOODFILL = 4 //!<
+};
+
+//! the contour approximation algorithm
+enum ContourApproximationModes {
+ /** stores absolutely all the contour points. That is, any 2 subsequent points (x1,y1) and
+ (x2,y2) of the contour will be either horizontal, vertical or diagonal neighbors, that is,
+ max(abs(x1-x2),abs(y2-y1))==1. */
+ CHAIN_APPROX_NONE = 1,
+ /** compresses horizontal, vertical, and diagonal segments and leaves only their end points.
+ For example, an up-right rectangular contour is encoded with 4 points. */
+ CHAIN_APPROX_SIMPLE = 2,
+ /** applies one of the flavors of the Teh-Chin chain approximation algorithm @cite TehChin89 */
+ CHAIN_APPROX_TC89_L1 = 3,
+ /** applies one of the flavors of the Teh-Chin chain approximation algorithm @cite TehChin89 */
+ CHAIN_APPROX_TC89_KCOS = 4
+};
+
+//! @} imgproc_shape
+
+//! Variants of a Hough transform
+enum HoughModes {
+
+ /** classical or standard Hough transform. Every line is represented by two floating-point
+ numbers \f$(\rho, \theta)\f$ , where \f$\rho\f$ is a distance between (0,0) point and the line,
+ and \f$\theta\f$ is the angle between x-axis and the normal to the line. Thus, the matrix must
+ be (the created sequence will be) of CV_32FC2 type */
+ HOUGH_STANDARD = 0,
+ /** probabilistic Hough transform (more efficient in case if the picture contains a few long
+ linear segments). It returns line segments rather than the whole line. Each segment is
+ represented by starting and ending points, and the matrix must be (the created sequence will
+ be) of the CV_32SC4 type. */
+ HOUGH_PROBABILISTIC = 1,
+ /** multi-scale variant of the classical Hough transform. The lines are encoded the same way as
+ HOUGH_STANDARD. */
+ HOUGH_MULTI_SCALE = 2,
+ HOUGH_GRADIENT = 3 //!< basically *21HT*, described in @cite Yuen90
+};
+
+//! Variants of Line Segment %Detector
+//! @ingroup imgproc_feature
+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.
+};
+
+/** Histogram comparison methods
+ @ingroup imgproc_hist
+*/
+enum HistCompMethods {
+ /** Correlation
+ \f[d(H_1,H_2) = \frac{\sum_I (H_1(I) - \bar{H_1}) (H_2(I) - \bar{H_2})}{\sqrt{\sum_I(H_1(I) - \bar{H_1})^2 \sum_I(H_2(I) - \bar{H_2})^2}}\f]
+ where
+ \f[\bar{H_k} = \frac{1}{N} \sum _J H_k(J)\f]
+ and \f$N\f$ is a total number of histogram bins. */
+ HISTCMP_CORREL = 0,
+ /** Chi-Square
+ \f[d(H_1,H_2) = \sum _I \frac{\left(H_1(I)-H_2(I)\right)^2}{H_1(I)}\f] */
+ HISTCMP_CHISQR = 1,
+ /** Intersection
+ \f[d(H_1,H_2) = \sum _I \min (H_1(I), H_2(I))\f] */
+ HISTCMP_INTERSECT = 2,
+ /** Bhattacharyya distance
+ (In fact, OpenCV computes Hellinger distance, which is related to Bhattacharyya coefficient.)
+ \f[d(H_1,H_2) = \sqrt{1 - \frac{1}{\sqrt{\bar{H_1} \bar{H_2} N^2}} \sum_I \sqrt{H_1(I) \cdot H_2(I)}}\f] */
+ HISTCMP_BHATTACHARYYA = 3,
+ HISTCMP_HELLINGER = HISTCMP_BHATTACHARYYA, //!< Synonym for HISTCMP_BHATTACHARYYA
+ /** Alternative Chi-Square
+ \f[d(H_1,H_2) = 2 * \sum _I \frac{\left(H_1(I)-H_2(I)\right)^2}{H_1(I)+H_2(I)}\f]
+ This alternative formula is regularly used for texture comparison. See e.g. @cite Puzicha1997 */
+ HISTCMP_CHISQR_ALT = 4,
+ /** Kullback-Leibler divergence
+ \f[d(H_1,H_2) = \sum _I H_1(I) \log \left(\frac{H_1(I)}{H_2(I)}\right)\f] */
+ HISTCMP_KL_DIV = 5
+};
+
+/** the color conversion code
+@see @ref imgproc_color_conversions
+@ingroup imgproc_misc
+ */
+enum ColorConversionCodes {
+ COLOR_BGR2BGRA = 0, //!< add alpha channel to RGB or BGR image
+ COLOR_RGB2RGBA = COLOR_BGR2BGRA,
+
+ COLOR_BGRA2BGR = 1, //!< remove alpha channel from RGB or BGR image
+ COLOR_RGBA2RGB = COLOR_BGRA2BGR,
+
+ COLOR_BGR2RGBA = 2, //!< convert between RGB and BGR color spaces (with or without alpha channel)
+ COLOR_RGB2BGRA = COLOR_BGR2RGBA,
+
+ COLOR_RGBA2BGR = 3,
+ COLOR_BGRA2RGB = COLOR_RGBA2BGR,
+
+ COLOR_BGR2RGB = 4,
+ COLOR_RGB2BGR = COLOR_BGR2RGB,
+
+ COLOR_BGRA2RGBA = 5,
+ COLOR_RGBA2BGRA = COLOR_BGRA2RGBA,
+
+ COLOR_BGR2GRAY = 6, //!< convert between RGB/BGR and grayscale, @ref color_convert_rgb_gray "color conversions"
+ COLOR_RGB2GRAY = 7,
+ COLOR_GRAY2BGR = 8,
+ COLOR_GRAY2RGB = COLOR_GRAY2BGR,
+ COLOR_GRAY2BGRA = 9,
+ COLOR_GRAY2RGBA = COLOR_GRAY2BGRA,
+ COLOR_BGRA2GRAY = 10,
+ COLOR_RGBA2GRAY = 11,
+
+ COLOR_BGR2BGR565 = 12, //!< convert between RGB/BGR and BGR565 (16-bit images)
+ COLOR_RGB2BGR565 = 13,
+ COLOR_BGR5652BGR = 14,
+ COLOR_BGR5652RGB = 15,
+ COLOR_BGRA2BGR565 = 16,
+ COLOR_RGBA2BGR565 = 17,
+ COLOR_BGR5652BGRA = 18,
+ COLOR_BGR5652RGBA = 19,
+
+ COLOR_GRAY2BGR565 = 20, //!< convert between grayscale to BGR565 (16-bit images)
+ COLOR_BGR5652GRAY = 21,
+
+ COLOR_BGR2BGR555 = 22, //!< convert between RGB/BGR and BGR555 (16-bit images)
+ COLOR_RGB2BGR555 = 23,
+ COLOR_BGR5552BGR = 24,
+ COLOR_BGR5552RGB = 25,
+ COLOR_BGRA2BGR555 = 26,
+ COLOR_RGBA2BGR555 = 27,
+ COLOR_BGR5552BGRA = 28,
+ COLOR_BGR5552RGBA = 29,
+
+ COLOR_GRAY2BGR555 = 30, //!< convert between grayscale and BGR555 (16-bit images)
+ COLOR_BGR5552GRAY = 31,
+
+ COLOR_BGR2XYZ = 32, //!< convert RGB/BGR to CIE XYZ, @ref color_convert_rgb_xyz "color conversions"
+ COLOR_RGB2XYZ = 33,
+ COLOR_XYZ2BGR = 34,
+ COLOR_XYZ2RGB = 35,
+
+ COLOR_BGR2YCrCb = 36, //!< convert RGB/BGR to luma-chroma (aka YCC), @ref color_convert_rgb_ycrcb "color conversions"
+ COLOR_RGB2YCrCb = 37,
+ COLOR_YCrCb2BGR = 38,
+ COLOR_YCrCb2RGB = 39,
+
+ COLOR_BGR2HSV = 40, //!< convert RGB/BGR to HSV (hue saturation value), @ref color_convert_rgb_hsv "color conversions"
+ COLOR_RGB2HSV = 41,
+
+ COLOR_BGR2Lab = 44, //!< convert RGB/BGR to CIE Lab, @ref color_convert_rgb_lab "color conversions"
+ COLOR_RGB2Lab = 45,
+
+ COLOR_BGR2Luv = 50, //!< convert RGB/BGR to CIE Luv, @ref color_convert_rgb_luv "color conversions"
+ COLOR_RGB2Luv = 51,
+ COLOR_BGR2HLS = 52, //!< convert RGB/BGR to HLS (hue lightness saturation), @ref color_convert_rgb_hls "color conversions"
+ COLOR_RGB2HLS = 53,
+
+ COLOR_HSV2BGR = 54, //!< backward conversions to RGB/BGR
+ COLOR_HSV2RGB = 55,
+
+ COLOR_Lab2BGR = 56,
+ COLOR_Lab2RGB = 57,
+ COLOR_Luv2BGR = 58,
+ COLOR_Luv2RGB = 59,
+ COLOR_HLS2BGR = 60,
+ COLOR_HLS2RGB = 61,
+
+ COLOR_BGR2HSV_FULL = 66, //!<
+ COLOR_RGB2HSV_FULL = 67,
+ COLOR_BGR2HLS_FULL = 68,
+ COLOR_RGB2HLS_FULL = 69,
+
+ COLOR_HSV2BGR_FULL = 70,
+ COLOR_HSV2RGB_FULL = 71,
+ COLOR_HLS2BGR_FULL = 72,
+ COLOR_HLS2RGB_FULL = 73,
+
+ COLOR_LBGR2Lab = 74,
+ COLOR_LRGB2Lab = 75,
+ COLOR_LBGR2Luv = 76,
+ COLOR_LRGB2Luv = 77,
+
+ COLOR_Lab2LBGR = 78,
+ COLOR_Lab2LRGB = 79,
+ COLOR_Luv2LBGR = 80,
+ COLOR_Luv2LRGB = 81,
+
+ COLOR_BGR2YUV = 82, //!< convert between RGB/BGR and YUV
+ COLOR_RGB2YUV = 83,
+ COLOR_YUV2BGR = 84,
+ COLOR_YUV2RGB = 85,
+
+ //! YUV 4:2:0 family to RGB
+ COLOR_YUV2RGB_NV12 = 90,
+ COLOR_YUV2BGR_NV12 = 91,
+ COLOR_YUV2RGB_NV21 = 92,
+ COLOR_YUV2BGR_NV21 = 93,
+ COLOR_YUV420sp2RGB = COLOR_YUV2RGB_NV21,
+ COLOR_YUV420sp2BGR = COLOR_YUV2BGR_NV21,
+
+ COLOR_YUV2RGBA_NV12 = 94,
+ COLOR_YUV2BGRA_NV12 = 95,
+ COLOR_YUV2RGBA_NV21 = 96,
+ COLOR_YUV2BGRA_NV21 = 97,
+ COLOR_YUV420sp2RGBA = COLOR_YUV2RGBA_NV21,
+ COLOR_YUV420sp2BGRA = COLOR_YUV2BGRA_NV21,
+
+ COLOR_YUV2RGB_YV12 = 98,
+ COLOR_YUV2BGR_YV12 = 99,
+ COLOR_YUV2RGB_IYUV = 100,
+ COLOR_YUV2BGR_IYUV = 101,
+ COLOR_YUV2RGB_I420 = COLOR_YUV2RGB_IYUV,
+ COLOR_YUV2BGR_I420 = COLOR_YUV2BGR_IYUV,
+ COLOR_YUV420p2RGB = COLOR_YUV2RGB_YV12,
+ COLOR_YUV420p2BGR = COLOR_YUV2BGR_YV12,
+
+ COLOR_YUV2RGBA_YV12 = 102,
+ COLOR_YUV2BGRA_YV12 = 103,
+ COLOR_YUV2RGBA_IYUV = 104,
+ COLOR_YUV2BGRA_IYUV = 105,
+ COLOR_YUV2RGBA_I420 = COLOR_YUV2RGBA_IYUV,
+ COLOR_YUV2BGRA_I420 = COLOR_YUV2BGRA_IYUV,
+ COLOR_YUV420p2RGBA = COLOR_YUV2RGBA_YV12,
+ COLOR_YUV420p2BGRA = COLOR_YUV2BGRA_YV12,
+
+ COLOR_YUV2GRAY_420 = 106,
+ COLOR_YUV2GRAY_NV21 = COLOR_YUV2GRAY_420,
+ COLOR_YUV2GRAY_NV12 = COLOR_YUV2GRAY_420,
+ COLOR_YUV2GRAY_YV12 = COLOR_YUV2GRAY_420,
+ COLOR_YUV2GRAY_IYUV = COLOR_YUV2GRAY_420,
+ COLOR_YUV2GRAY_I420 = COLOR_YUV2GRAY_420,
+ COLOR_YUV420sp2GRAY = COLOR_YUV2GRAY_420,
+ COLOR_YUV420p2GRAY = COLOR_YUV2GRAY_420,
+
+ //! YUV 4:2:2 family to RGB
+ COLOR_YUV2RGB_UYVY = 107,
+ COLOR_YUV2BGR_UYVY = 108,
+ //COLOR_YUV2RGB_VYUY = 109,
+ //COLOR_YUV2BGR_VYUY = 110,
+ COLOR_YUV2RGB_Y422 = COLOR_YUV2RGB_UYVY,
+ COLOR_YUV2BGR_Y422 = COLOR_YUV2BGR_UYVY,
+ COLOR_YUV2RGB_UYNV = COLOR_YUV2RGB_UYVY,
+ COLOR_YUV2BGR_UYNV = COLOR_YUV2BGR_UYVY,
+
+ COLOR_YUV2RGBA_UYVY = 111,
+ COLOR_YUV2BGRA_UYVY = 112,
+ //COLOR_YUV2RGBA_VYUY = 113,
+ //COLOR_YUV2BGRA_VYUY = 114,
+ COLOR_YUV2RGBA_Y422 = COLOR_YUV2RGBA_UYVY,
+ COLOR_YUV2BGRA_Y422 = COLOR_YUV2BGRA_UYVY,
+ COLOR_YUV2RGBA_UYNV = COLOR_YUV2RGBA_UYVY,
+ COLOR_YUV2BGRA_UYNV = COLOR_YUV2BGRA_UYVY,
+
+ COLOR_YUV2RGB_YUY2 = 115,
+ COLOR_YUV2BGR_YUY2 = 116,
+ COLOR_YUV2RGB_YVYU = 117,
+ COLOR_YUV2BGR_YVYU = 118,
+ COLOR_YUV2RGB_YUYV = COLOR_YUV2RGB_YUY2,
+ COLOR_YUV2BGR_YUYV = COLOR_YUV2BGR_YUY2,
+ COLOR_YUV2RGB_YUNV = COLOR_YUV2RGB_YUY2,
+ COLOR_YUV2BGR_YUNV = COLOR_YUV2BGR_YUY2,
+
+ COLOR_YUV2RGBA_YUY2 = 119,
+ COLOR_YUV2BGRA_YUY2 = 120,
+ COLOR_YUV2RGBA_YVYU = 121,
+ COLOR_YUV2BGRA_YVYU = 122,
+ COLOR_YUV2RGBA_YUYV = COLOR_YUV2RGBA_YUY2,
+ COLOR_YUV2BGRA_YUYV = COLOR_YUV2BGRA_YUY2,
+ COLOR_YUV2RGBA_YUNV = COLOR_YUV2RGBA_YUY2,
+ COLOR_YUV2BGRA_YUNV = COLOR_YUV2BGRA_YUY2,
+
+ COLOR_YUV2GRAY_UYVY = 123,
+ COLOR_YUV2GRAY_YUY2 = 124,
+ //CV_YUV2GRAY_VYUY = CV_YUV2GRAY_UYVY,
+ COLOR_YUV2GRAY_Y422 = COLOR_YUV2GRAY_UYVY,
+ COLOR_YUV2GRAY_UYNV = COLOR_YUV2GRAY_UYVY,
+ COLOR_YUV2GRAY_YVYU = COLOR_YUV2GRAY_YUY2,
+ COLOR_YUV2GRAY_YUYV = COLOR_YUV2GRAY_YUY2,
+ COLOR_YUV2GRAY_YUNV = COLOR_YUV2GRAY_YUY2,
+
+ //! alpha premultiplication
+ COLOR_RGBA2mRGBA = 125,
+ COLOR_mRGBA2RGBA = 126,
+
+ //! RGB to YUV 4:2:0 family
+ COLOR_RGB2YUV_I420 = 127,
+ COLOR_BGR2YUV_I420 = 128,
+ COLOR_RGB2YUV_IYUV = COLOR_RGB2YUV_I420,
+ COLOR_BGR2YUV_IYUV = COLOR_BGR2YUV_I420,
+
+ COLOR_RGBA2YUV_I420 = 129,
+ COLOR_BGRA2YUV_I420 = 130,
+ COLOR_RGBA2YUV_IYUV = COLOR_RGBA2YUV_I420,
+ COLOR_BGRA2YUV_IYUV = COLOR_BGRA2YUV_I420,
+ COLOR_RGB2YUV_YV12 = 131,
+ COLOR_BGR2YUV_YV12 = 132,
+ COLOR_RGBA2YUV_YV12 = 133,
+ COLOR_BGRA2YUV_YV12 = 134,
+
+ //! Demosaicing
+ COLOR_BayerBG2BGR = 46,
+ COLOR_BayerGB2BGR = 47,
+ COLOR_BayerRG2BGR = 48,
+ COLOR_BayerGR2BGR = 49,
+
+ COLOR_BayerBG2RGB = COLOR_BayerRG2BGR,
+ COLOR_BayerGB2RGB = COLOR_BayerGR2BGR,
+ COLOR_BayerRG2RGB = COLOR_BayerBG2BGR,
+ COLOR_BayerGR2RGB = COLOR_BayerGB2BGR,
+
+ COLOR_BayerBG2GRAY = 86,
+ COLOR_BayerGB2GRAY = 87,
+ COLOR_BayerRG2GRAY = 88,
+ COLOR_BayerGR2GRAY = 89,
+
+ //! Demosaicing using Variable Number of Gradients
+ COLOR_BayerBG2BGR_VNG = 62,
+ COLOR_BayerGB2BGR_VNG = 63,
+ COLOR_BayerRG2BGR_VNG = 64,
+ COLOR_BayerGR2BGR_VNG = 65,
+
+ COLOR_BayerBG2RGB_VNG = COLOR_BayerRG2BGR_VNG,
+ COLOR_BayerGB2RGB_VNG = COLOR_BayerGR2BGR_VNG,
+ COLOR_BayerRG2RGB_VNG = COLOR_BayerBG2BGR_VNG,
+ COLOR_BayerGR2RGB_VNG = COLOR_BayerGB2BGR_VNG,
+
+ //! Edge-Aware Demosaicing
+ COLOR_BayerBG2BGR_EA = 135,
+ COLOR_BayerGB2BGR_EA = 136,
+ COLOR_BayerRG2BGR_EA = 137,
+ COLOR_BayerGR2BGR_EA = 138,
+
+ COLOR_BayerBG2RGB_EA = COLOR_BayerRG2BGR_EA,
+ COLOR_BayerGB2RGB_EA = COLOR_BayerGR2BGR_EA,
+ COLOR_BayerRG2RGB_EA = COLOR_BayerBG2BGR_EA,
+ COLOR_BayerGR2RGB_EA = COLOR_BayerGB2BGR_EA,
+
+
+ COLOR_COLORCVT_MAX = 139
+};
+
+/** types of intersection between rectangles
+@ingroup imgproc_shape
+*/
+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
+};
+
+//! finds arbitrary template in the grayscale image using Generalized Hough Transform
+class CV_EXPORTS GeneralizedHough : public Algorithm
+{
+public:
+ //! set template to search
+ virtual void setTemplate(InputArray templ, Point templCenter = Point(-1, -1)) = 0;
+ virtual void setTemplate(InputArray edges, InputArray dx, InputArray dy, Point templCenter = Point(-1, -1)) = 0;
+
+ //! find template on image
+ virtual void detect(InputArray image, OutputArray positions, OutputArray votes = noArray()) = 0;
+ virtual void detect(InputArray edges, InputArray dx, InputArray dy, OutputArray positions, OutputArray votes = noArray()) = 0;
+
+ //! Canny low threshold.
+ virtual void setCannyLowThresh(int cannyLowThresh) = 0;
+ virtual int getCannyLowThresh() const = 0;
+
+ //! Canny high threshold.
+ virtual void setCannyHighThresh(int cannyHighThresh) = 0;
+ virtual int getCannyHighThresh() const = 0;
+
+ //! Minimum distance between the centers of the detected objects.
+ virtual void setMinDist(double minDist) = 0;
+ virtual double getMinDist() const = 0;
+
+ //! Inverse ratio of the accumulator resolution to the image resolution.
+ virtual void setDp(double dp) = 0;
+ virtual double getDp() const = 0;
+
+ //! Maximal size of inner buffers.
+ virtual void setMaxBufferSize(int maxBufferSize) = 0;
+ virtual int getMaxBufferSize() const = 0;
+};
+
+//! Ballard, D.H. (1981). Generalizing the Hough transform to detect arbitrary shapes. Pattern Recognition 13 (2): 111-122.
+//! Detects position only without traslation and rotation
+class CV_EXPORTS GeneralizedHoughBallard : public GeneralizedHough
+{
+public:
+ //! R-Table levels.
+ virtual void setLevels(int levels) = 0;
+ virtual int getLevels() const = 0;
+
+ //! The accumulator threshold for the template centers at the detection stage. The smaller it is, the more false positions may be detected.
+ virtual void setVotesThreshold(int votesThreshold) = 0;
+ virtual int getVotesThreshold() const = 0;
+};
+
+//! Guil, N., González-Linares, J.M. and Zapata, E.L. (1999). Bidimensional shape detection using an invariant approach. Pattern Recognition 32 (6): 1025-1038.
+//! Detects position, traslation and rotation
+class CV_EXPORTS GeneralizedHoughGuil : public GeneralizedHough
+{
+public:
+ //! Angle difference in degrees between two points in feature.
+ virtual void setXi(double xi) = 0;
+ virtual double getXi() const = 0;
+
+ //! Feature table levels.
+ virtual void setLevels(int levels) = 0;
+ virtual int getLevels() const = 0;
+
+ //! Maximal difference between angles that treated as equal.
+ virtual void setAngleEpsilon(double angleEpsilon) = 0;
+ virtual double getAngleEpsilon() const = 0;
+
+ //! Minimal rotation angle to detect in degrees.
+ virtual void setMinAngle(double minAngle) = 0;
+ virtual double getMinAngle() const = 0;
+
+ //! Maximal rotation angle to detect in degrees.
+ virtual void setMaxAngle(double maxAngle) = 0;
+ virtual double getMaxAngle() const = 0;
+
+ //! Angle step in degrees.
+ virtual void setAngleStep(double angleStep) = 0;
+ virtual double getAngleStep() const = 0;
+
+ //! Angle votes threshold.
+ virtual void setAngleThresh(int angleThresh) = 0;
+ virtual int getAngleThresh() const = 0;
+
+ //! Minimal scale to detect.
+ virtual void setMinScale(double minScale) = 0;
+ virtual double getMinScale() const = 0;
+
+ //! Maximal scale to detect.
+ virtual void setMaxScale(double maxScale) = 0;
+ virtual double getMaxScale() const = 0;
+
+ //! Scale step.
+ virtual void setScaleStep(double scaleStep) = 0;
+ virtual double getScaleStep() const = 0;
+
+ //! Scale votes threshold.
+ virtual void setScaleThresh(int scaleThresh) = 0;
+ virtual int getScaleThresh() const = 0;
+
+ //! Position votes threshold.
+ virtual void setPosThresh(int posThresh) = 0;
+ virtual int getPosThresh() const = 0;
+};
+
+
+class CV_EXPORTS_W CLAHE : public Algorithm
+{
+public:
+ CV_WRAP virtual void apply(InputArray src, OutputArray dst) = 0;
+
+ CV_WRAP virtual void setClipLimit(double clipLimit) = 0;
+ CV_WRAP virtual double getClipLimit() const = 0;
+
+ CV_WRAP virtual void setTilesGridSize(Size tileGridSize) = 0;
+ CV_WRAP virtual Size getTilesGridSize() const = 0;
+
+ CV_WRAP virtual void collectGarbage() = 0;
+};
+
+
+//! @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);
+
+ /** @brief Creates a new empty Delaunay subdivision
+
+ @param rect – Rectangle that includes all of the 2D points that are to be added to the subdivision.
+
+ */
+ CV_WRAP void initDelaunay(Rect rect);
+
+ /** @brief Insert a single point into a Delaunay triangulation.
+
+ @param pt – Point to insert.
+
+ The function inserts a single point into a subdivision and modifies the subdivision topology
+ appropriately. If a point with the same coordinates exists already, no new point is added.
+ @returns the ID of the point.
+
+ @note If the point is outside of the triangulation specified rect a runtime error is raised.
+ */
+ CV_WRAP int insert(Point2f pt);
+
+ /** @brief Insert multiple points into a Delaunay triangulation.
+
+ @param ptvec – Points to insert.
+
+ The function inserts a vector of points into a subdivision and modifies the subdivision topology
+ appropriately.
+ */
+ CV_WRAP void insert(const std::vector<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, CV_PTLOC_ERROR is returnd.
+ */
+ CV_WRAP int locate(Point2f pt, CV_OUT int& edge, CV_OUT int& vertex);
+
+ /** @brief Finds the subdivision vertex closest to the given point.
+
+ @param pt – Input point.
+ @param nearestPt – Output subdivision vertex point.
+
+ The function is another function that locates the input point within the subdivision. It finds the
+ subdivision vertex that is the closest to the input point. It is not necessarily one of vertices
+ of the facet containing the input point, though the facet (located using locate() ) is used as a
+ starting point.
+
+ @returns vertex ID.
+ */
+ CV_WRAP int findNearest(Point2f pt, CV_OUT Point2f* nearestPt = 0);
+
+ /** @brief Returns a list of all edges.
+
+ @param edgeList – Output vector.
+
+ The function gives each edge as a 4 numbers vector, where each two are one of the edge
+ vertices. i.e. org_x = v[0], org_y = v[1], dst_x = v[2], dst_y = v[3].
+ */
+ CV_WRAP void getEdgeList(CV_OUT std::vector<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 Voroni facets.
+
+ @param idx – Vector of vertices IDs to consider. For all vertices you can pass empty vector.
+ @param facetList – Output vector of the Voroni facets.
+ @param facetCenters – Output vector of the Voroni facets center points.
+
+ */
+ CV_WRAP void getVoronoiFacetList(const std::vector<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 lsd_lines.cpp
+An example using the LineSegmentDetector
+*/
+
+/** @brief Line segment detector class
+
+following the algorithm described at @cite Rafael12 .
+*/
+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 Vec4i or Vec4f elements specifying the beginning and ending point of a line. Where
+ Vec4i/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 liens 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 cv::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 advancent 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(
+ int _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
+//! @{
+
+/** @brief Returns Gaussian filter coefficients.
+
+The function computes and returns the \f$\texttt{ksize} \times 1\f$ matrix of Gaussian filter
+coefficients:
+
+\f[G_i= \alpha *e^{-(i-( \texttt{ksize} -1)/2)^2/(2* \texttt{sigma}^2)},\f]
+
+where \f$i=0..\texttt{ksize}-1\f$ and \f$\alpha\f$ is the scale factor chosen so that \f$\sum_i G_i=1\f$.
+
+Two of such generated kernels can be passed to sepFilter2D. Those functions automatically recognize
+smoothing kernels (a symmetrical kernel with sum of weights equal to 1) and handle them accordingly.
+You may also use the higher-level GaussianBlur.
+@param ksize Aperture size. It should be odd ( \f$\texttt{ksize} \mod 2 = 1\f$ ) and positive.
+@param sigma Gaussian standard deviation. If it is non-positive, it is computed from ksize as
+`sigma = 0.3\*((ksize-1)\*0.5 - 1) + 0.8`.
+@param ktype Type of filter coefficients. It can be CV_32F or CV_64F .
+@sa sepFilter2D, getDerivKernels, getStructuringElement, GaussianBlur
+ */
+CV_EXPORTS_W Mat getGaussianKernel( int ksize, double sigma, int ktype = CV_64F );
+
+/** @brief Returns filter coefficients for computing spatial image derivatives.
+
+The function computes and returns the filter coefficients for spatial image derivatives. When
+`ksize=CV_SCHARR`, the Scharr \f$3 \times 3\f$ kernels are generated (see cv::Scharr). Otherwise, Sobel
+kernels are generated (see cv::Sobel). The filters are normally passed to sepFilter2D or to
+
+@param kx Output matrix of row filter coefficients. It has the type ktype .
+@param ky Output matrix of column filter coefficients. It has the type ktype .
+@param dx Derivative order in respect of x.
+@param dy Derivative order in respect of y.
+@param ksize Aperture size. It can be CV_SCHARR, 1, 3, 5, or 7.
+@param normalize Flag indicating whether to normalize (scale down) the filter coefficients or not.
+Theoretically, the coefficients should have the denominator \f$=2^{ksize*2-dx-dy-2}\f$. If you are
+going to filter floating-point images, you are likely to use the normalized kernels. But if you
+compute derivatives of an 8-bit image, store the results in a 16-bit image, and wish to preserve
+all the fractional bits, you may want to set normalize=false .
+@param ktype Type of filter coefficients. It can be CV_32f or CV_64F .
+ */
+CV_EXPORTS_W void getDerivKernels( OutputArray kx, OutputArray ky,
+ int dx, int dy, int ksize,
+ bool normalize = false, int ktype = CV_32F );
+
+/** @brief Returns Gabor filter coefficients.
+
+For more details about gabor filter equations and parameters, see: [Gabor
+Filter](http://en.wikipedia.org/wiki/Gabor_filter).
+
+@param ksize Size of the filter returned.
+@param sigma Standard deviation of the gaussian envelope.
+@param theta Orientation of the normal to the parallel stripes of a Gabor function.
+@param lambd Wavelength of the sinusoidal factor.
+@param gamma Spatial aspect ratio.
+@param psi Phase offset.
+@param ktype Type of filter coefficients. It can be CV_32F or CV_64F .
+ */
+CV_EXPORTS_W Mat getGaborKernel( Size ksize, double sigma, double theta, double lambd,
+ double gamma, double psi = CV_PI*0.5, int ktype = CV_64F );
+
+//! returns "magic" border value for erosion and dilation. It is automatically transformed to Scalar::all(-DBL_MAX) for dilation.
+static inline Scalar morphologyDefaultBorderValue() { return Scalar::all(DBL_MAX); }
+
+/** @brief Returns a structuring element of the specified size and shape for morphological operations.
+
+The function constructs and returns the structuring element that can be further passed to cv::erode,
+cv::dilate or cv::morphologyEx. But you can also construct an arbitrary binary mask yourself and use it as
+the structuring element.
+
+@param shape Element shape that could be one of cv::MorphShapes
+@param ksize Size of the structuring element.
+@param anchor Anchor position within the element. The default value \f$(-1, -1)\f$ means that the
+anchor is at the center. Note that only the shape of a cross-shaped element depends on the anchor
+position. In other cases the anchor just regulates how much the result of the morphological
+operation is shifted.
+ */
+CV_EXPORTS_W Mat getStructuringElement(int shape, Size ksize, Point anchor = Point(-1,-1));
+
+/** @brief Blurs an image using the median filter.
+
+The function smoothes an image using the median filter with the \f$\texttt{ksize} \times
+\texttt{ksize}\f$ aperture. Each channel of a multi-channel image is processed independently.
+In-place operation is supported.
+
+@note The median filter uses BORDER_REPLICATE internally to cope with border pixels, see cv::BorderTypes
+
+@param src input 1-, 3-, or 4-channel image; when ksize is 3 or 5, the image depth should be
+CV_8U, CV_16U, or CV_32F, for larger aperture sizes, it can only be CV_8U.
+@param dst destination array of the same size and type as src.
+@param ksize aperture linear size; it must be odd and greater than 1, for example: 3, 5, 7 ...
+@sa bilateralFilter, blur, boxFilter, GaussianBlur
+ */
+CV_EXPORTS_W void medianBlur( InputArray src, OutputArray dst, int ksize );
+
+/** @brief Blurs an image using a Gaussian filter.
+
+The function convolves the source image with the specified Gaussian kernel. In-place filtering is
+supported.
+
+@param src input image; the image can have any number of channels, which are processed
+independently, but the depth should be CV_8U, CV_16U, CV_16S, CV_32F or CV_64F.
+@param dst output image of the same size and type as src.
+@param ksize Gaussian kernel size. ksize.width and ksize.height can differ but they both must be
+positive and odd. Or, they can be zero's and then they are computed from sigma.
+@param sigmaX Gaussian kernel standard deviation in X direction.
+@param sigmaY Gaussian kernel standard deviation in Y direction; if sigmaY is zero, it is set to be
+equal to sigmaX, if both sigmas are zeros, they are computed from ksize.width and ksize.height,
+respectively (see cv::getGaussianKernel for details); to fully control the result regardless of
+possible future modifications of all this semantics, it is recommended to specify all of ksize,
+sigmaX, and sigmaY.
+@param borderType pixel extrapolation method, see cv::BorderTypes
+
+@sa sepFilter2D, filter2D, blur, boxFilter, bilateralFilter, medianBlur
+ */
+CV_EXPORTS_W void GaussianBlur( InputArray src, OutputArray dst, Size ksize,
+ double sigmaX, double sigmaY = 0,
+ int borderType = BORDER_DEFAULT );
+
+/** @brief Applies the bilateral filter to an image.
+
+The function applies bilateral filtering to the input image, as described in
+http://www.dai.ed.ac.uk/CVonline/LOCAL_COPIES/MANDUCHI1/Bilateral_Filtering.html
+bilateralFilter can reduce unwanted noise very well while keeping edges fairly sharp. However, it is
+very slow compared to most filters.
+
+_Sigma values_: For simplicity, you can set the 2 sigma values to be the same. If they are small (\<
+10), the filter will not have much effect, whereas if they are large (\> 150), they will have a very
+strong effect, making the image look "cartoonish".
+
+_Filter size_: Large filters (d \> 5) are very slow, so it is recommended to use d=5 for real-time
+applications, and perhaps d=9 for offline applications that need heavy noise filtering.
+
+This filter does not work inplace.
+@param src Source 8-bit or floating-point, 1-channel or 3-channel image.
+@param dst Destination image of the same size and type as src .
+@param d Diameter of each pixel neighborhood that is used during filtering. If it is non-positive,
+it is computed from sigmaSpace.
+@param sigmaColor Filter sigma in the color space. A larger value of the parameter means that
+farther colors within the pixel neighborhood (see sigmaSpace) will be mixed together, resulting
+in larger areas of semi-equal color.
+@param sigmaSpace Filter sigma in the coordinate space. A larger value of the parameter means that
+farther pixels will influence each other as long as their colors are close enough (see sigmaColor
+). When d\>0, it specifies the neighborhood size regardless of sigmaSpace. Otherwise, d is
+proportional to sigmaSpace.
+@param borderType border mode used to extrapolate pixels outside of the image, see cv::BorderTypes
+ */
+CV_EXPORTS_W void bilateralFilter( InputArray src, OutputArray dst, int d,
+ double sigmaColor, double sigmaSpace,
+ int borderType = BORDER_DEFAULT );
+
+/** @brief Blurs an image using the box filter.
+
+The function smoothes an image using the kernel:
+
+\f[\texttt{K} = \alpha \begin{bmatrix} 1 & 1 & 1 & \cdots & 1 & 1 \\ 1 & 1 & 1 & \cdots & 1 & 1 \\ \hdotsfor{6} \\ 1 & 1 & 1 & \cdots & 1 & 1 \end{bmatrix}\f]
+
+where
+
+\f[\alpha = \fork{\frac{1}{\texttt{ksize.width*ksize.height}}}{when \texttt{normalize=true}}{1}{otherwise}\f]
+
+Unnormalized box filter is useful for computing various integral characteristics over each pixel
+neighborhood, such as covariance matrices of image derivatives (used in dense optical flow
+algorithms, and so on). If you need to compute pixel sums over variable-size windows, use cv::integral.
+
+@param src input image.
+@param dst output image of the same size and type as src.
+@param ddepth the output image depth (-1 to use src.depth()).
+@param ksize blurring kernel size.
+@param anchor anchor point; default value Point(-1,-1) means that the anchor is at the kernel
+center.
+@param normalize flag, specifying whether the kernel is normalized by its area or not.
+@param borderType border mode used to extrapolate pixels outside of the image, see cv::BorderTypes
+@sa blur, bilateralFilter, GaussianBlur, medianBlur, integral
+ */
+CV_EXPORTS_W void boxFilter( InputArray src, OutputArray dst, int ddepth,
+ Size ksize, Point anchor = Point(-1,-1),
+ bool normalize = true,
+ int borderType = BORDER_DEFAULT );
+
+/** @brief Calculates the normalized sum of squares of the pixel values overlapping the filter.
+
+For every pixel \f$ (x, y) \f$ in the source image, the function calculates the sum of squares of those neighboring
+pixel values which overlap the filter placed over the pixel \f$ (x, y) \f$.
+
+The unnormalized square box filter can be useful in computing local image statistics such as the the local
+variance and standard deviation around the neighborhood of a pixel.
+
+@param _src input image
+@param _dst output image of the same size and type as _src
+@param ddepth the output image depth (-1 to use src.depth())
+@param ksize kernel size
+@param anchor kernel anchor point. The default value of Point(-1, -1) denotes that the anchor is at the kernel
+center.
+@param normalize flag, specifying whether the kernel is to be normalized by it's area or not.
+@param borderType border mode used to extrapolate pixels outside of the image, see cv::BorderTypes
+@sa boxFilter
+*/
+CV_EXPORTS_W void sqrBoxFilter( InputArray _src, OutputArray _dst, int ddepth,
+ Size ksize, Point anchor = Point(-1, -1),
+ bool normalize = true,
+ int borderType = BORDER_DEFAULT );
+
+/** @brief Blurs an image using the normalized box filter.
+
+The function smoothes an image using the kernel:
+
+\f[\texttt{K} = \frac{1}{\texttt{ksize.width*ksize.height}} \begin{bmatrix} 1 & 1 & 1 & \cdots & 1 & 1 \\ 1 & 1 & 1 & \cdots & 1 & 1 \\ \hdotsfor{6} \\ 1 & 1 & 1 & \cdots & 1 & 1 \\ \end{bmatrix}\f]
+
+The call `blur(src, dst, ksize, anchor, borderType)` is equivalent to `boxFilter(src, dst, src.type(),
+anchor, true, borderType)`.
+
+@param src input image; it can have any number of channels, which are processed independently, but
+the depth should be CV_8U, CV_16U, CV_16S, CV_32F or CV_64F.
+@param dst output image of the same size and type as src.
+@param ksize blurring kernel size.
+@param anchor anchor point; default value Point(-1,-1) means that the anchor is at the kernel
+center.
+@param borderType border mode used to extrapolate pixels outside of the image, see cv::BorderTypes
+@sa boxFilter, bilateralFilter, GaussianBlur, medianBlur
+ */
+CV_EXPORTS_W void blur( InputArray src, OutputArray dst,
+ Size ksize, Point anchor = Point(-1,-1),
+ int borderType = BORDER_DEFAULT );
+
+/** @brief Convolves an image with the kernel.
+
+The function applies an arbitrary linear filter to an image. In-place operation is supported. When
+the aperture is partially outside the image, the function interpolates outlier pixel values
+according to the specified border mode.
+
+The function does actually compute correlation, not the convolution:
+
+\f[\texttt{dst} (x,y) = \sum _{ \stackrel{0\leq x' < \texttt{kernel.cols},}{0\leq y' < \texttt{kernel.rows}} } \texttt{kernel} (x',y')* \texttt{src} (x+x'- \texttt{anchor.x} ,y+y'- \texttt{anchor.y} )\f]
+
+That is, the kernel is not mirrored around the anchor point. If you need a real convolution, flip
+the kernel using cv::flip and set the new anchor to `(kernel.cols - anchor.x - 1, kernel.rows -
+anchor.y - 1)`.
+
+The function uses the DFT-based algorithm in case of sufficiently large kernels (~`11 x 11` or
+larger) and the direct algorithm for small kernels.
+
+@param src input image.
+@param dst output image of the same size and the same number of channels as src.
+@param ddepth desired depth of the destination image, see @ref filter_depths "combinations"
+@param kernel convolution kernel (or rather a correlation kernel), a single-channel floating point
+matrix; if you want to apply different kernels to different channels, split the image into
+separate color planes using split and process them individually.
+@param anchor anchor of the kernel that indicates the relative position of a filtered point within
+the kernel; the anchor should lie within the kernel; default value (-1,-1) means that the anchor
+is at the kernel center.
+@param delta optional value added to the filtered pixels before storing them in dst.
+@param borderType pixel extrapolation method, see cv::BorderTypes
+@sa sepFilter2D, dft, matchTemplate
+ */
+CV_EXPORTS_W void filter2D( InputArray src, OutputArray dst, int ddepth,
+ InputArray kernel, Point anchor = Point(-1,-1),
+ double delta = 0, int borderType = BORDER_DEFAULT );
+
+/** @brief Applies a separable linear filter to an image.
+
+The function applies a separable linear filter to the image. That is, first, every row of src is
+filtered with the 1D kernel kernelX. Then, every column of the result is filtered with the 1D
+kernel kernelY. The final result shifted by delta is stored in dst .
+
+@param src Source image.
+@param dst Destination image of the same size and the same number of channels as src .
+@param ddepth Destination image depth, see @ref filter_depths "combinations"
+@param kernelX Coefficients for filtering each row.
+@param kernelY Coefficients for filtering each column.
+@param anchor Anchor position within the kernel. The default value \f$(-1,-1)\f$ means that the anchor
+is at the kernel center.
+@param delta Value added to the filtered results before storing them.
+@param borderType Pixel extrapolation method, see cv::BorderTypes
+@sa filter2D, Sobel, GaussianBlur, boxFilter, blur
+ */
+CV_EXPORTS_W void sepFilter2D( InputArray src, OutputArray dst, int ddepth,
+ InputArray kernelX, InputArray kernelY,
+ Point anchor = Point(-1,-1),
+ double delta = 0, int borderType = BORDER_DEFAULT );
+
+/** @brief Calculates the first, second, third, or mixed image derivatives using an extended Sobel operator.
+
+In all cases except one, the \f$\texttt{ksize} \times \texttt{ksize}\f$ separable kernel is used to
+calculate the derivative. When \f$\texttt{ksize = 1}\f$, the \f$3 \times 1\f$ or \f$1 \times 3\f$
+kernel is used (that is, no Gaussian smoothing is done). `ksize = 1` can only be used for the first
+or the second x- or y- derivatives.
+
+There is also the special value `ksize = CV_SCHARR (-1)` that corresponds to the \f$3\times3\f$ Scharr
+filter that may give more accurate results than the \f$3\times3\f$ Sobel. The Scharr aperture is
+
+\f[\vecthreethree{-3}{0}{3}{-10}{0}{10}{-3}{0}{3}\f]
+
+for the x-derivative, or transposed for the y-derivative.
+
+The function calculates an image derivative by convolving the image with the appropriate kernel:
+
+\f[\texttt{dst} = \frac{\partial^{xorder+yorder} \texttt{src}}{\partial x^{xorder} \partial y^{yorder}}\f]
+
+The Sobel operators combine Gaussian smoothing and differentiation, so the result is more or less
+resistant to the noise. Most often, the function is called with ( xorder = 1, yorder = 0, ksize = 3)
+or ( xorder = 0, yorder = 1, ksize = 3) to calculate the first x- or y- image derivative. The first
+case corresponds to a kernel of:
+
+\f[\vecthreethree{-1}{0}{1}{-2}{0}{2}{-1}{0}{1}\f]
+
+The second case corresponds to a kernel of:
+
+\f[\vecthreethree{-1}{-2}{-1}{0}{0}{0}{1}{2}{1}\f]
+
+@param src input image.
+@param dst output image of the same size and the same number of channels as src .
+@param ddepth output image depth, see @ref filter_depths "combinations"; in the case of
+ 8-bit input images it will result in truncated derivatives.
+@param dx order of the derivative x.
+@param dy order of the derivative y.
+@param ksize size of the extended Sobel kernel; it must be 1, 3, 5, or 7.
+@param scale optional scale factor for the computed derivative values; by default, no scaling is
+applied (see cv::getDerivKernels for details).
+@param delta optional delta value that is added to the results prior to storing them in dst.
+@param borderType pixel extrapolation method, see cv::BorderTypes
+@sa Scharr, Laplacian, sepFilter2D, filter2D, GaussianBlur, cartToPolar
+ */
+CV_EXPORTS_W void Sobel( InputArray src, OutputArray dst, int ddepth,
+ int dx, int dy, int ksize = 3,
+ double scale = 1, double delta = 0,
+ int borderType = BORDER_DEFAULT );
+
+/** @brief Calculates the first order image derivative in both x and y using a Sobel operator
+
+Equivalent to calling:
+
+@code
+Sobel( src, dx, CV_16SC1, 1, 0, 3 );
+Sobel( src, dy, CV_16SC1, 0, 1, 3 );
+@endcode
+
+@param src input image.
+@param dx output image with first-order derivative in x.
+@param dy output image with first-order derivative in y.
+@param ksize size of Sobel kernel. It must be 3.
+@param borderType pixel extrapolation method, see cv::BorderTypes
+
+@sa Sobel
+ */
+
+CV_EXPORTS_W void spatialGradient( InputArray src, OutputArray dx,
+ OutputArray dy, int ksize = 3,
+ int borderType = BORDER_DEFAULT );
+
+/** @brief Calculates the first x- or y- image derivative using Scharr operator.
+
+The function computes the first x- or y- spatial image derivative using the Scharr operator. The
+call
+
+\f[\texttt{Scharr(src, dst, ddepth, dx, dy, scale, delta, borderType)}\f]
+
+is equivalent to
+
+\f[\texttt{Sobel(src, dst, ddepth, dx, dy, CV\_SCHARR, scale, delta, borderType)} .\f]
+
+@param src input image.
+@param dst output image of the same size and the same number of channels as src.
+@param ddepth output image depth, see @ref filter_depths "combinations"
+@param dx order of the derivative x.
+@param dy order of the derivative y.
+@param scale optional scale factor for the computed derivative values; by default, no scaling is
+applied (see getDerivKernels for details).
+@param delta optional delta value that is added to the results prior to storing them in dst.
+@param borderType pixel extrapolation method, see cv::BorderTypes
+@sa cartToPolar
+ */
+CV_EXPORTS_W void Scharr( InputArray src, OutputArray dst, int ddepth,
+ int dx, int dy, double scale = 1, double delta = 0,
+ int borderType = BORDER_DEFAULT );
+
+/** @example laplace.cpp
+ An example using Laplace transformations for edge detection
+*/
+
+/** @brief Calculates the Laplacian of an image.
+
+The function calculates the Laplacian of the source image by adding up the second x and y
+derivatives calculated using the Sobel operator:
+
+\f[\texttt{dst} = \Delta \texttt{src} = \frac{\partial^2 \texttt{src}}{\partial x^2} + \frac{\partial^2 \texttt{src}}{\partial y^2}\f]
+
+This is done when `ksize > 1`. When `ksize == 1`, the Laplacian is computed by filtering the image
+with the following \f$3 \times 3\f$ aperture:
+
+\f[\vecthreethree {0}{1}{0}{1}{-4}{1}{0}{1}{0}\f]
+
+@param src Source image.
+@param dst Destination image of the same size and the same number of channels as src .
+@param ddepth Desired depth of the destination image.
+@param ksize Aperture size used to compute the second-derivative filters. See getDerivKernels for
+details. The size must be positive and odd.
+@param scale Optional scale factor for the computed Laplacian values. By default, no scaling is
+applied. See getDerivKernels for details.
+@param delta Optional delta value that is added to the results prior to storing them in dst .
+@param borderType Pixel extrapolation method, see cv::BorderTypes
+@sa Sobel, Scharr
+ */
+CV_EXPORTS_W void Laplacian( InputArray src, OutputArray dst, int ddepth,
+ int ksize = 1, double scale = 1, double delta = 0,
+ int borderType = BORDER_DEFAULT );
+
+//! @} imgproc_filter
+
+//! @addtogroup imgproc_feature
+//! @{
+
+/** @example edge.cpp
+ An example on using the canny edge detector
+*/
+
+/** @brief Finds edges in an image using the Canny algorithm @cite Canny86 .
+
+The function finds edges in the input image image and marks them in the output map edges using the
+Canny algorithm. The smallest value between threshold1 and threshold2 is used for edge linking. The
+largest value is used to find initial segments of strong edges. See
+<http://en.wikipedia.org/wiki/Canny_edge_detector>
+
+@param image 8-bit input image.
+@param edges output edge map; single channels 8-bit image, which has the same size as image .
+@param threshold1 first threshold for the hysteresis procedure.
+@param threshold2 second threshold for the hysteresis procedure.
+@param apertureSize aperture size for the Sobel operator.
+@param L2gradient a flag, indicating whether a more accurate \f$L_2\f$ norm
+\f$=\sqrt{(dI/dx)^2 + (dI/dy)^2}\f$ should be used to calculate the image gradient magnitude (
+L2gradient=true ), or whether the default \f$L_1\f$ norm \f$=|dI/dx|+|dI/dy|\f$ is enough (
+L2gradient=false ).
+ */
+CV_EXPORTS_W void Canny( InputArray image, OutputArray edges,
+ double threshold1, double threshold2,
+ int apertureSize = 3, bool L2gradient = false );
+
+/** \overload
+
+Finds edges in an image using the Canny algorithm with custom image gradient.
+
+@param dx 16-bit x derivative of input image (CV_16SC1 or CV_16SC3).
+@param dy 16-bit y derivative of input image (same type as dx).
+@param edges,threshold1,threshold2,L2gradient See cv::Canny
+ */
+CV_EXPORTS_W void Canny( InputArray dx, InputArray dy,
+ OutputArray edges,
+ double threshold1, double threshold2,
+ bool L2gradient = false );
+
+/** @brief Calculates the minimal eigenvalue of gradient matrices for corner detection.
+
+The function is similar to cornerEigenValsAndVecs but it calculates and stores only the minimal
+eigenvalue of the covariance matrix of derivatives, that is, \f$\min(\lambda_1, \lambda_2)\f$ in terms
+of the formulae in the cornerEigenValsAndVecs description.
+
+@param src Input single-channel 8-bit or floating-point image.
+@param dst Image to store the minimal eigenvalues. It has the type CV_32FC1 and the same size as
+src .
+@param blockSize Neighborhood size (see the details on cornerEigenValsAndVecs ).
+@param ksize Aperture parameter for the Sobel operator.
+@param borderType Pixel extrapolation method. See cv::BorderTypes.
+ */
+CV_EXPORTS_W void cornerMinEigenVal( InputArray src, OutputArray dst,
+ int blockSize, int ksize = 3,
+ int borderType = BORDER_DEFAULT );
+
+/** @brief Harris corner detector.
+
+The function runs the Harris corner detector on the image. Similarly to cornerMinEigenVal and
+cornerEigenValsAndVecs , for each pixel \f$(x, y)\f$ it calculates a \f$2\times2\f$ gradient covariance
+matrix \f$M^{(x,y)}\f$ over a \f$\texttt{blockSize} \times \texttt{blockSize}\f$ neighborhood. Then, it
+computes the following characteristic:
+
+\f[\texttt{dst} (x,y) = \mathrm{det} M^{(x,y)} - k \cdot \left ( \mathrm{tr} M^{(x,y)} \right )^2\f]
+
+Corners in the image can be found as the local maxima of this response map.
+
+@param src Input single-channel 8-bit or floating-point image.
+@param dst Image to store the Harris detector responses. It has the type CV_32FC1 and the same
+size as src .
+@param blockSize Neighborhood size (see the details on cornerEigenValsAndVecs ).
+@param ksize Aperture parameter for the Sobel operator.
+@param k Harris detector free parameter. See the formula below.
+@param borderType Pixel extrapolation method. See cv::BorderTypes.
+ */
+CV_EXPORTS_W void cornerHarris( InputArray src, OutputArray dst, int blockSize,
+ int ksize, double k,
+ int borderType = BORDER_DEFAULT );
+
+/** @brief Calculates eigenvalues and eigenvectors of image blocks for corner detection.
+
+For every pixel \f$p\f$ , the function cornerEigenValsAndVecs considers a blockSize \f$\times\f$ blockSize
+neighborhood \f$S(p)\f$ . It calculates the covariation matrix of derivatives over the neighborhood as:
+
+\f[M = \begin{bmatrix} \sum _{S(p)}(dI/dx)^2 & \sum _{S(p)}dI/dx dI/dy \\ \sum _{S(p)}dI/dx dI/dy & \sum _{S(p)}(dI/dy)^2 \end{bmatrix}\f]
+
+where the derivatives are computed using the Sobel operator.
+
+After that, it finds eigenvectors and eigenvalues of \f$M\f$ and stores them in the destination image as
+\f$(\lambda_1, \lambda_2, x_1, y_1, x_2, y_2)\f$ where
+
+- \f$\lambda_1, \lambda_2\f$ are the non-sorted eigenvalues of \f$M\f$
+- \f$x_1, y_1\f$ are the eigenvectors corresponding to \f$\lambda_1\f$
+- \f$x_2, y_2\f$ are the eigenvectors corresponding to \f$\lambda_2\f$
+
+The output of the function can be used for robust edge or corner detection.
+
+@param src Input single-channel 8-bit or floating-point image.
+@param dst Image to store the results. It has the same size as src and the type CV_32FC(6) .
+@param blockSize Neighborhood size (see details below).
+@param ksize Aperture parameter for the Sobel operator.
+@param borderType Pixel extrapolation method. See cv::BorderTypes.
+
+@sa cornerMinEigenVal, cornerHarris, preCornerDetect
+ */
+CV_EXPORTS_W void cornerEigenValsAndVecs( InputArray src, OutputArray dst,
+ int blockSize, int ksize,
+ int borderType = BORDER_DEFAULT );
+
+/** @brief Calculates a feature map for corner detection.
+
+The function calculates the complex spatial derivative-based function of the source image
+
+\f[\texttt{dst} = (D_x \texttt{src} )^2 \cdot D_{yy} \texttt{src} + (D_y \texttt{src} )^2 \cdot D_{xx} \texttt{src} - 2 D_x \texttt{src} \cdot D_y \texttt{src} \cdot D_{xy} \texttt{src}\f]
+
+where \f$D_x\f$,\f$D_y\f$ are the first image derivatives, \f$D_{xx}\f$,\f$D_{yy}\f$ are the second image
+derivatives, and \f$D_{xy}\f$ is the mixed derivative.
+
+The corners can be found as local maximums of the functions, as shown below:
+@code
+ Mat corners, dilated_corners;
+ preCornerDetect(image, corners, 3);
+ // dilation with 3x3 rectangular structuring element
+ dilate(corners, dilated_corners, Mat(), 1);
+ Mat corner_mask = corners == dilated_corners;
+@endcode
+
+@param src Source single-channel 8-bit of floating-point image.
+@param dst Output image that has the type CV_32F and the same size as src .
+@param ksize %Aperture size of the Sobel .
+@param borderType Pixel extrapolation method. See cv::BorderTypes.
+ */
+CV_EXPORTS_W void preCornerDetect( InputArray src, OutputArray dst, int ksize,
+ int borderType = BORDER_DEFAULT );
+
+/** @brief Refines the corner locations.
+
+The function iterates to find the sub-pixel accurate location of corners or radial saddle points, as
+shown on the figure below.
+
+
+
+Sub-pixel accurate corner locator is based on the observation that every vector from the center \f$q\f$
+to a point \f$p\f$ located within a neighborhood of \f$q\f$ is orthogonal to the image gradient at \f$p\f$
+subject to image and measurement noise. Consider the expression:
+
+\f[\epsilon _i = {DI_{p_i}}^T \cdot (q - p_i)\f]
+
+where \f${DI_{p_i}}\f$ is an image gradient at one of the points \f$p_i\f$ in a neighborhood of \f$q\f$ . The
+value of \f$q\f$ is to be found so that \f$\epsilon_i\f$ is minimized. A system of equations may be set up
+with \f$\epsilon_i\f$ set to zero:
+
+\f[\sum _i(DI_{p_i} \cdot {DI_{p_i}}^T) - \sum _i(DI_{p_i} \cdot {DI_{p_i}}^T \cdot p_i)\f]
+
+where the gradients are summed within a neighborhood ("search window") of \f$q\f$ . Calling the first
+gradient term \f$G\f$ and the second gradient term \f$b\f$ gives:
+
+\f[q = G^{-1} \cdot b\f]
+
+The algorithm sets the center of the neighborhood window at this new center \f$q\f$ and then iterates
+until the center stays within a set threshold.
+
+@param image Input image.
+@param corners Initial coordinates of the input corners and refined coordinates provided for
+output.
+@param winSize Half of the side length of the search window. For example, if winSize=Size(5,5) ,
+then a \f$5*2+1 \times 5*2+1 = 11 \times 11\f$ search window is used.
+@param zeroZone Half of the size of the dead region in the middle of the search zone over which
+the summation in the formula below is not done. It is used sometimes to avoid possible
+singularities of the autocorrelation matrix. The value of (-1,-1) indicates that there is no such
+a size.
+@param criteria Criteria for termination of the iterative process of corner refinement. That is,
+the process of corner position refinement stops either after criteria.maxCount iterations or when
+the corner position moves by less than criteria.epsilon on some iteration.
+ */
+CV_EXPORTS_W void cornerSubPix( InputArray image, InputOutputArray corners,
+ Size winSize, Size zeroZone,
+ TermCriteria criteria );
+
+/** @brief Determines strong corners on an image.
+
+The function finds the most prominent corners in the image or in the specified image region, as
+described in @cite Shi94
+
+- Function calculates the corner quality measure at every source image pixel using the
+ cornerMinEigenVal or cornerHarris .
+- Function performs a non-maximum suppression (the local maximums in *3 x 3* neighborhood are
+ retained).
+- The corners with the minimal eigenvalue less than
+ \f$\texttt{qualityLevel} \cdot \max_{x,y} qualityMeasureMap(x,y)\f$ are rejected.
+- The remaining corners are sorted by the quality measure in the descending order.
+- Function throws away each corner for which there is a stronger corner at a distance less than
+ maxDistance.
+
+The function can be used to initialize a point-based tracker of an object.
+
+@note If the function is called with different values A and B of the parameter qualityLevel , and
+A \> B, the vector of returned corners with qualityLevel=A will be the prefix of the output vector
+with qualityLevel=B .
+
+@param image Input 8-bit or floating-point 32-bit, single-channel image.
+@param corners Output vector of detected corners.
+@param maxCorners Maximum number of corners to return. If there are more corners than are found,
+the strongest of them is returned. `maxCorners <= 0` implies that no limit on the maximum is set
+and all detected corners are returned.
+@param qualityLevel Parameter characterizing the minimal accepted quality of image corners. The
+parameter value is multiplied by the best corner quality measure, which is the minimal eigenvalue
+(see cornerMinEigenVal ) or the Harris function response (see cornerHarris ). The corners with the
+quality measure less than the product are rejected. For example, if the best corner has the
+quality measure = 1500, and the qualityLevel=0.01 , then all the corners with the quality measure
+less than 15 are rejected.
+@param minDistance Minimum possible Euclidean distance between the returned corners.
+@param mask Optional region of interest. If the image is not empty (it needs to have the type
+CV_8UC1 and the same size as image ), it specifies the region in which the corners are detected.
+@param blockSize Size of an average block for computing a derivative covariation matrix over each
+pixel neighborhood. See cornerEigenValsAndVecs .
+@param useHarrisDetector Parameter indicating whether to use a Harris detector (see cornerHarris)
+or cornerMinEigenVal.
+@param k Free parameter of the Harris detector.
+
+@sa cornerMinEigenVal, cornerHarris, calcOpticalFlowPyrLK, estimateRigidTransform,
+ */
+CV_EXPORTS_W void goodFeaturesToTrack( InputArray image, OutputArray corners,
+ int maxCorners, double qualityLevel, double minDistance,
+ InputArray mask = noArray(), int blockSize = 3,
+ bool useHarrisDetector = false, double k = 0.04 );
+
+/** @example houghlines.cpp
+An example using the Hough line detector
+*/
+
+/** @brief Finds lines in a binary image using the standard Hough transform.
+
+The function implements the standard or standard multi-scale Hough transform algorithm for line
+detection. See <http://homepages.inf.ed.ac.uk/rbf/HIPR2/hough.htm> for a good explanation of Hough
+transform.
+
+@param image 8-bit, single-channel binary source image. The image may be modified by the function.
+@param lines Output vector of lines. Each line is represented by a two-element vector
+\f$(\rho, \theta)\f$ . \f$\rho\f$ is the distance from the coordinate origin \f$(0,0)\f$ (top-left corner of
+the image). \f$\theta\f$ is the line rotation angle in radians (
+\f$0 \sim \textrm{vertical line}, \pi/2 \sim \textrm{horizontal line}\f$ ).
+@param rho Distance resolution of the accumulator in pixels.
+@param theta Angle resolution of the accumulator in radians.
+@param threshold Accumulator threshold parameter. Only those lines are returned that get enough
+votes ( \f$>\texttt{threshold}\f$ ).
+@param srn For the multi-scale Hough transform, it is a divisor for the distance resolution rho .
+The coarse accumulator distance resolution is rho and the accurate accumulator resolution is
+rho/srn . If both srn=0 and stn=0 , the classical Hough transform is used. Otherwise, both these
+parameters should be positive.
+@param stn For the multi-scale Hough transform, it is a divisor for the distance resolution theta.
+@param min_theta For standard and multi-scale Hough transform, minimum angle to check for lines.
+Must fall between 0 and max_theta.
+@param max_theta For standard and multi-scale Hough transform, maximum angle to check for lines.
+Must fall between min_theta and CV_PI.
+ */
+CV_EXPORTS_W void HoughLines( InputArray image, OutputArray lines,
+ double rho, double theta, int threshold,
+ double srn = 0, double stn = 0,
+ double min_theta = 0, double max_theta = CV_PI );
+
+/** @brief Finds line segments in a binary image using the probabilistic Hough transform.
+
+The function implements the probabilistic Hough transform algorithm for line detection, described
+in @cite Matas00
+
+See the line detection example below:
+
+@code
+ #include <opencv2/imgproc.hpp>
+ #include <opencv2/highgui.hpp>
+
+ using namespace cv;
+ using namespace std;
+
+ int main(int argc, char** argv)
+ {
+ Mat src, dst, color_dst;
+ if( argc != 2 || !(src=imread(argv[1], 0)).data)
+ return -1;
+
+ Canny( src, dst, 50, 200, 3 );
+ cvtColor( dst, color_dst, COLOR_GRAY2BGR );
+
+ #if 0
+ vector<Vec2f> lines;
+ HoughLines( dst, lines, 1, CV_PI/180, 100 );
+
+ for( size_t i = 0; i < lines.size(); i++ )
+ {
+ float rho = lines[i][0];
+ float theta = lines[i][1];
+ double a = cos(theta), b = sin(theta);
+ double x0 = a*rho, y0 = b*rho;
+ Point pt1(cvRound(x0 + 1000*(-b)),
+ cvRound(y0 + 1000*(a)));
+ Point pt2(cvRound(x0 - 1000*(-b)),
+ cvRound(y0 - 1000*(a)));
+ line( color_dst, pt1, pt2, Scalar(0,0,255), 3, 8 );
+ }
+ #else
+ vector<Vec4i> lines;
+ HoughLinesP( dst, lines, 1, CV_PI/180, 80, 30, 10 );
+ for( size_t i = 0; i < lines.size(); i++ )
+ {
+ line( color_dst, Point(lines[i][0], lines[i][1]),
+ Point(lines[i][2], lines[i][3]), Scalar(0,0,255), 3, 8 );
+ }
+ #endif
+ namedWindow( "Source", 1 );
+ imshow( "Source", src );
+
+ namedWindow( "Detected Lines", 1 );
+ imshow( "Detected Lines", color_dst );
+
+ waitKey(0);
+ return 0;
+ }
+@endcode
+This is a sample picture the function parameters have been tuned for:
+
+
+
+And this is the output of the above program in case of the probabilistic Hough transform:
+
+
+
+@param image 8-bit, single-channel binary source image. The image may be modified by the function.
+@param lines Output vector of lines. Each line is represented by a 4-element vector
+\f$(x_1, y_1, x_2, y_2)\f$ , where \f$(x_1,y_1)\f$ and \f$(x_2, y_2)\f$ are the ending points of each detected
+line segment.
+@param rho Distance resolution of the accumulator in pixels.
+@param theta Angle resolution of the accumulator in radians.
+@param threshold Accumulator threshold parameter. Only those lines are returned that get enough
+votes ( \f$>\texttt{threshold}\f$ ).
+@param minLineLength Minimum line length. Line segments shorter than that are rejected.
+@param maxLineGap Maximum allowed gap between points on the same line to link them.
+
+@sa LineSegmentDetector
+ */
+CV_EXPORTS_W void HoughLinesP( InputArray image, OutputArray lines,
+ double rho, double theta, int threshold,
+ double minLineLength = 0, double maxLineGap = 0 );
+
+/** @example houghcircles.cpp
+An example using the Hough circle detector
+*/
+
+/** @brief Finds circles in a grayscale image using the Hough transform.
+
+The function finds circles in a grayscale image using a modification of the Hough transform.
+
+Example: :
+@code
+ #include <opencv2/imgproc.hpp>
+ #include <opencv2/highgui.hpp>
+ #include <math.h>
+
+ using namespace cv;
+ using namespace std;
+
+ int main(int argc, char** argv)
+ {
+ Mat img, gray;
+ if( argc != 2 || !(img=imread(argv[1], 1)).data)
+ return -1;
+ cvtColor(img, gray, COLOR_BGR2GRAY);
+ // smooth it, otherwise a lot of false circles may be detected
+ GaussianBlur( gray, gray, Size(9, 9), 2, 2 );
+ vector<Vec3f> circles;
+ HoughCircles(gray, circles, HOUGH_GRADIENT,
+ 2, gray.rows/4, 200, 100 );
+ for( size_t i = 0; i < circles.size(); i++ )
+ {
+ Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
+ int radius = cvRound(circles[i][2]);
+ // draw the circle center
+ circle( img, center, 3, Scalar(0,255,0), -1, 8, 0 );
+ // draw the circle outline
+ circle( img, center, radius, Scalar(0,0,255), 3, 8, 0 );
+ }
+ namedWindow( "circles", 1 );
+ imshow( "circles", img );
+
+ waitKey(0);
+ return 0;
+ }
+@endcode
+
+@note Usually the function detects the centers of circles well. However, it may fail to find correct
+radii. You can assist to the function by specifying the radius range ( minRadius and maxRadius ) if
+you know it. Or, you may ignore the returned radius, use only the center, and find the correct
+radius using an additional procedure.
+
+@param image 8-bit, single-channel, grayscale input image.
+@param circles Output vector of found circles. Each vector is encoded as a 3-element
+floating-point vector \f$(x, y, radius)\f$ .
+@param method Detection method, see cv::HoughModes. Currently, the only implemented method is HOUGH_GRADIENT
+@param dp Inverse ratio of the accumulator resolution to the image resolution. For example, if
+dp=1 , the accumulator has the same resolution as the input image. If dp=2 , the accumulator has
+half as big width and height.
+@param minDist Minimum distance between the centers of the detected circles. If the parameter is
+too small, multiple neighbor circles may be falsely detected in addition to a true one. If it is
+too large, some circles may be missed.
+@param param1 First method-specific parameter. In case of CV_HOUGH_GRADIENT , it is the higher
+threshold of the two passed to the Canny edge detector (the lower one is twice smaller).
+@param param2 Second method-specific parameter. In case of CV_HOUGH_GRADIENT , it is the
+accumulator threshold for the circle centers at the detection stage. The smaller it is, the more
+false circles may be detected. Circles, corresponding to the larger accumulator values, will be
+returned first.
+@param minRadius Minimum circle radius.
+@param maxRadius Maximum circle radius.
+
+@sa fitEllipse, minEnclosingCircle
+ */
+CV_EXPORTS_W void HoughCircles( InputArray image, OutputArray circles,
+ int method, double dp, double minDist,
+ double param1 = 100, double param2 = 100,
+ int minRadius = 0, int maxRadius = 0 );
+
+//! @} imgproc_feature
+
+//! @addtogroup imgproc_filter
+//! @{
+
+/** @example morphology2.cpp
+ An example using the morphological operations
+*/
+
+/** @brief Erodes an image by using a specific structuring element.
+
+The function erodes the source image using the specified structuring element that determines the
+shape of a pixel neighborhood over which the minimum is taken:
+
+\f[\texttt{dst} (x,y) = \min _{(x',y'): \, \texttt{element} (x',y') \ne0 } \texttt{src} (x+x',y+y')\f]
+
+The function supports the in-place mode. Erosion can be applied several ( iterations ) times. In
+case of multi-channel images, each channel is processed independently.
+
+@param src input image; the number of channels can be arbitrary, but the depth should be one of
+CV_8U, CV_16U, CV_16S, CV_32F or CV_64F.
+@param dst output image of the same size and type as src.
+@param kernel structuring element used for erosion; if `element=Mat()`, a `3 x 3` rectangular
+structuring element is used. Kernel can be created using getStructuringElement.
+@param anchor position of the anchor within the element; default value (-1, -1) means that the
+anchor is at the element center.
+@param iterations number of times erosion is applied.
+@param borderType pixel extrapolation method, see cv::BorderTypes
+@param borderValue border value in case of a constant border
+@sa dilate, morphologyEx, getStructuringElement
+ */
+CV_EXPORTS_W void erode( InputArray src, OutputArray dst, InputArray kernel,
+ Point anchor = Point(-1,-1), int iterations = 1,
+ int borderType = BORDER_CONSTANT,
+ const Scalar& borderValue = morphologyDefaultBorderValue() );
+
+/** @brief Dilates an image by using a specific structuring element.
+
+The function dilates the source image using the specified structuring element that determines the
+shape of a pixel neighborhood over which the maximum is taken:
+\f[\texttt{dst} (x,y) = \max _{(x',y'): \, \texttt{element} (x',y') \ne0 } \texttt{src} (x+x',y+y')\f]
+
+The function supports the in-place mode. Dilation can be applied several ( iterations ) times. In
+case of multi-channel images, each channel is processed independently.
+
+@param src input image; the number of channels can be arbitrary, but the depth should be one of
+CV_8U, CV_16U, CV_16S, CV_32F or CV_64F.
+@param dst output image of the same size and type as src\`.
+@param kernel structuring element used for dilation; if elemenat=Mat(), a 3 x 3 rectangular
+structuring element is used. Kernel can be created using getStructuringElement
+@param anchor position of the anchor within the element; default value (-1, -1) means that the
+anchor is at the element center.
+@param iterations number of times dilation is applied.
+@param borderType pixel extrapolation method, see cv::BorderTypes
+@param borderValue border value in case of a constant border
+@sa erode, morphologyEx, getStructuringElement
+ */
+CV_EXPORTS_W void dilate( InputArray src, OutputArray dst, InputArray kernel,
+ Point anchor = Point(-1,-1), int iterations = 1,
+ int borderType = BORDER_CONSTANT,
+ const Scalar& borderValue = morphologyDefaultBorderValue() );
+
+/** @brief Performs advanced morphological transformations.
+
+The function morphologyEx can perform advanced morphological transformations using an erosion and dilation as
+basic operations.
+
+Any of the operations can be done in-place. In case of multi-channel images, each channel is
+processed independently.
+
+@param src Source image. The number of channels can be arbitrary. The depth should be one of
+CV_8U, CV_16U, CV_16S, CV_32F or CV_64F.
+@param dst Destination image of the same size and type as source image.
+@param op Type of a morphological operation, see cv::MorphTypes
+@param kernel Structuring element. It can be created using cv::getStructuringElement.
+@param anchor Anchor position with the kernel. Negative values mean that the anchor is at the
+kernel center.
+@param iterations Number of times erosion and dilation are applied.
+@param borderType Pixel extrapolation method, see cv::BorderTypes
+@param borderValue Border value in case of a constant border. The default value has a special
+meaning.
+@sa dilate, erode, getStructuringElement
+ */
+CV_EXPORTS_W void morphologyEx( InputArray src, OutputArray dst,
+ int op, InputArray kernel,
+ Point anchor = Point(-1,-1), int iterations = 1,
+ int borderType = BORDER_CONSTANT,
+ const Scalar& borderValue = morphologyDefaultBorderValue() );
+
+//! @} imgproc_filter
+
+//! @addtogroup imgproc_transform
+//! @{
+
+/** @brief Resizes an image.
+
+The function resize resizes the image src down to or up to the specified size. Note that the
+initial dst type or size are not taken into account. Instead, the size and type are derived from
+the `src`,`dsize`,`fx`, and `fy`. If you want to resize src so that it fits the pre-created dst,
+you may call the function as follows:
+@code
+ // explicitly specify dsize=dst.size(); fx and fy will be computed from that.
+ resize(src, dst, dst.size(), 0, 0, interpolation);
+@endcode
+If you want to decimate the image by factor of 2 in each direction, you can call the function this
+way:
+@code
+ // specify fx and fy and let the function compute the destination image size.
+ resize(src, dst, Size(), 0.5, 0.5, interpolation);
+@endcode
+To shrink an image, it will generally look best with cv::INTER_AREA interpolation, whereas to
+enlarge an image, it will generally look best with cv::INTER_CUBIC (slow) or cv::INTER_LINEAR
+(faster but still looks OK).
+
+@param src input image.
+@param dst output image; it has the size dsize (when it is non-zero) or the size computed from
+src.size(), fx, and fy; the type of dst is the same as of src.
+@param dsize output image size; if it equals zero, it is computed as:
+ \f[\texttt{dsize = Size(round(fx*src.cols), round(fy*src.rows))}\f]
+ Either dsize or both fx and fy must be non-zero.
+@param fx scale factor along the horizontal axis; when it equals 0, it is computed as
+\f[\texttt{(double)dsize.width/src.cols}\f]
+@param fy scale factor along the vertical axis; when it equals 0, it is computed as
+\f[\texttt{(double)dsize.height/src.rows}\f]
+@param interpolation interpolation method, see cv::InterpolationFlags
+
+@sa warpAffine, warpPerspective, remap
+ */
+CV_EXPORTS_W void resize( InputArray src, OutputArray dst,
+ Size dsize, double fx = 0, double fy = 0,
+ int interpolation = INTER_LINEAR );
+
+/** @brief Applies an affine transformation to an image.
+
+The function warpAffine transforms the source image using the specified matrix:
+
+\f[\texttt{dst} (x,y) = \texttt{src} ( \texttt{M} _{11} x + \texttt{M} _{12} y + \texttt{M} _{13}, \texttt{M} _{21} x + \texttt{M} _{22} y + \texttt{M} _{23})\f]
+
+when the flag WARP_INVERSE_MAP is set. Otherwise, the transformation is first inverted
+with cv::invertAffineTransform and then put in the formula above instead of M. The function cannot
+operate in-place.
+
+@param src input image.
+@param dst output image that has the size dsize and the same type as src .
+@param M \f$2\times 3\f$ transformation matrix.
+@param dsize size of the output image.
+@param flags combination of interpolation methods (see cv::InterpolationFlags) and the optional
+flag WARP_INVERSE_MAP that means that M is the inverse transformation (
+\f$\texttt{dst}\rightarrow\texttt{src}\f$ ).
+@param borderMode pixel extrapolation method (see cv::BorderTypes); when
+borderMode=BORDER_TRANSPARENT, it means that the pixels in the destination image corresponding to
+the "outliers" in the source image are not modified by the function.
+@param borderValue value used in case of a constant border; by default, it is 0.
+
+@sa warpPerspective, resize, remap, getRectSubPix, transform
+ */
+CV_EXPORTS_W void warpAffine( InputArray src, OutputArray dst,
+ InputArray M, Size dsize,
+ int flags = INTER_LINEAR,
+ int borderMode = BORDER_CONSTANT,
+ const Scalar& borderValue = Scalar());
+
+/** @brief Applies a perspective transformation to an image.
+
+The function warpPerspective transforms the source image using the specified matrix:
+
+\f[\texttt{dst} (x,y) = \texttt{src} \left ( \frac{M_{11} x + M_{12} y + M_{13}}{M_{31} x + M_{32} y + M_{33}} ,
+ \frac{M_{21} x + M_{22} y + M_{23}}{M_{31} x + M_{32} y + M_{33}} \right )\f]
+
+when the flag WARP_INVERSE_MAP is set. Otherwise, the transformation is first inverted with invert
+and then put in the formula above instead of M. The function cannot operate in-place.
+
+@param src input image.
+@param dst output image that has the size dsize and the same type as src .
+@param M \f$3\times 3\f$ transformation matrix.
+@param dsize size of the output image.
+@param flags combination of interpolation methods (INTER_LINEAR or INTER_NEAREST) and the
+optional flag WARP_INVERSE_MAP, that sets M as the inverse transformation (
+\f$\texttt{dst}\rightarrow\texttt{src}\f$ ).
+@param borderMode pixel extrapolation method (BORDER_CONSTANT or BORDER_REPLICATE).
+@param borderValue value used in case of a constant border; by default, it equals 0.
+
+@sa warpAffine, resize, remap, getRectSubPix, perspectiveTransform
+ */
+CV_EXPORTS_W void warpPerspective( InputArray src, OutputArray dst,
+ InputArray M, Size dsize,
+ int flags = INTER_LINEAR,
+ int borderMode = BORDER_CONSTANT,
+ const Scalar& borderValue = Scalar());
+
+/** @brief Applies a generic geometrical transformation to an image.
+
+The function remap transforms the source image using the specified map:
+
+\f[\texttt{dst} (x,y) = \texttt{src} (map_x(x,y),map_y(x,y))\f]
+
+where values of pixels with non-integer coordinates are computed using one of available
+interpolation methods. \f$map_x\f$ and \f$map_y\f$ can be encoded as separate floating-point maps
+in \f$map_1\f$ and \f$map_2\f$ respectively, or interleaved floating-point maps of \f$(x,y)\f$ in
+\f$map_1\f$, or fixed-point maps created by using convertMaps. The reason you might want to
+convert from floating to fixed-point representations of a map is that they can yield much faster
+(\~2x) remapping operations. In the converted case, \f$map_1\f$ contains pairs (cvFloor(x),
+cvFloor(y)) and \f$map_2\f$ contains indices in a table of interpolation coefficients.
+
+This function cannot operate in-place.
+
+@param src Source image.
+@param dst Destination image. It has the same size as map1 and the same type as src .
+@param map1 The first map of either (x,y) points or just x values having the type CV_16SC2 ,
+CV_32FC1, or CV_32FC2. See convertMaps for details on converting a floating point
+representation to fixed-point for speed.
+@param map2 The second map of y values having the type CV_16UC1, CV_32FC1, or none (empty map
+if map1 is (x,y) points), respectively.
+@param interpolation Interpolation method (see cv::InterpolationFlags). The method INTER_AREA is
+not supported by this function.
+@param borderMode Pixel extrapolation method (see cv::BorderTypes). When
+borderMode=BORDER_TRANSPARENT, it means that the pixels in the destination image that
+corresponds to the "outliers" in the source image are not modified by the function.
+@param borderValue Value used in case of a constant border. By default, it is 0.
+@note
+Due to current implementaion limitations the size of an input and output images should be less than 32767x32767.
+ */
+CV_EXPORTS_W void remap( InputArray src, OutputArray dst,
+ InputArray map1, InputArray map2,
+ int interpolation, int borderMode = BORDER_CONSTANT,
+ const Scalar& borderValue = Scalar());
+
+/** @brief Converts image transformation maps from one representation to another.
+
+The function converts a pair of maps for remap from one representation to another. The following
+options ( (map1.type(), map2.type()) \f$\rightarrow\f$ (dstmap1.type(), dstmap2.type()) ) are
+supported:
+
+- \f$\texttt{(CV_32FC1, CV_32FC1)} \rightarrow \texttt{(CV_16SC2, CV_16UC1)}\f$. This is the
+most frequently used conversion operation, in which the original floating-point maps (see remap )
+are converted to a more compact and much faster fixed-point representation. The first output array
+contains the rounded coordinates and the second array (created only when nninterpolation=false )
+contains indices in the interpolation tables.
+
+- \f$\texttt{(CV_32FC2)} \rightarrow \texttt{(CV_16SC2, CV_16UC1)}\f$. The same as above but
+the original maps are stored in one 2-channel matrix.
+
+- Reverse conversion. Obviously, the reconstructed floating-point maps will not be exactly the same
+as the originals.
+
+@param map1 The first input map of type CV_16SC2, CV_32FC1, or CV_32FC2 .
+@param map2 The second input map of type CV_16UC1, CV_32FC1, or none (empty matrix),
+respectively.
+@param dstmap1 The first output map that has the type dstmap1type and the same size as src .
+@param dstmap2 The second output map.
+@param dstmap1type Type of the first output map that should be CV_16SC2, CV_32FC1, or
+CV_32FC2 .
+@param nninterpolation Flag indicating whether the fixed-point maps are used for the
+nearest-neighbor or for a more complex interpolation.
+
+@sa remap, undistort, initUndistortRectifyMap
+ */
+CV_EXPORTS_W void convertMaps( InputArray map1, InputArray map2,
+ OutputArray dstmap1, OutputArray dstmap2,
+ int dstmap1type, bool nninterpolation = false );
+
+/** @brief Calculates an affine matrix of 2D rotation.
+
+The function calculates the following matrix:
+
+\f[\begin{bmatrix} \alpha & \beta & (1- \alpha ) \cdot \texttt{center.x} - \beta \cdot \texttt{center.y} \\ - \beta & \alpha & \beta \cdot \texttt{center.x} + (1- \alpha ) \cdot \texttt{center.y} \end{bmatrix}\f]
+
+where
+
+\f[\begin{array}{l} \alpha = \texttt{scale} \cdot \cos \texttt{angle} , \\ \beta = \texttt{scale} \cdot \sin \texttt{angle} \end{array}\f]
+
+The transformation maps the rotation center to itself. If this is not the target, adjust the shift.
+
+@param center Center of the rotation in the source image.
+@param angle Rotation angle in degrees. Positive values mean counter-clockwise rotation (the
+coordinate origin is assumed to be the top-left corner).
+@param scale Isotropic scale factor.
+
+@sa getAffineTransform, warpAffine, transform
+ */
+CV_EXPORTS_W Mat getRotationMatrix2D( Point2f center, double angle, double scale );
+
+//! returns 3x3 perspective transformation for the corresponding 4 point pairs.
+CV_EXPORTS Mat getPerspectiveTransform( const Point2f src[], const Point2f dst[] );
+
+/** @brief Calculates an affine transform from three pairs of the corresponding points.
+
+The function calculates the \f$2 \times 3\f$ matrix of an affine transform so that:
+
+\f[\begin{bmatrix} x'_i \\ y'_i \end{bmatrix} = \texttt{map_matrix} \cdot \begin{bmatrix} x_i \\ y_i \\ 1 \end{bmatrix}\f]
+
+where
+
+\f[dst(i)=(x'_i,y'_i), src(i)=(x_i, y_i), i=0,1,2\f]
+
+@param src Coordinates of triangle vertices in the source image.
+@param dst Coordinates of the corresponding triangle vertices in the destination image.
+
+@sa warpAffine, transform
+ */
+CV_EXPORTS Mat getAffineTransform( const Point2f src[], const Point2f dst[] );
+
+/** @brief Inverts an affine transformation.
+
+The function computes an inverse affine transformation represented by \f$2 \times 3\f$ matrix M:
+
+\f[\begin{bmatrix} a_{11} & a_{12} & b_1 \\ a_{21} & a_{22} & b_2 \end{bmatrix}\f]
+
+The result is also a \f$2 \times 3\f$ matrix of the same type as M.
+
+@param M Original affine transformation.
+@param iM Output reverse affine transformation.
+ */
+CV_EXPORTS_W void invertAffineTransform( InputArray M, OutputArray iM );
+
+/** @brief Calculates a perspective transform from four pairs of the corresponding points.
+
+The function calculates the \f$3 \times 3\f$ matrix of a perspective transform so that:
+
+\f[\begin{bmatrix} t_i x'_i \\ t_i y'_i \\ t_i \end{bmatrix} = \texttt{map_matrix} \cdot \begin{bmatrix} x_i \\ y_i \\ 1 \end{bmatrix}\f]
+
+where
+
+\f[dst(i)=(x'_i,y'_i), src(i)=(x_i, y_i), i=0,1,2,3\f]
+
+@param src Coordinates of quadrangle vertices in the source image.
+@param dst Coordinates of the corresponding quadrangle vertices in the destination image.
+
+@sa findHomography, warpPerspective, perspectiveTransform
+ */
+CV_EXPORTS_W Mat getPerspectiveTransform( InputArray src, InputArray dst );
+
+CV_EXPORTS_W Mat getAffineTransform( InputArray src, InputArray dst );
+
+/** @brief Retrieves a pixel rectangle from an image with sub-pixel accuracy.
+
+The function getRectSubPix extracts pixels from src:
+
+\f[dst(x, y) = src(x + \texttt{center.x} - ( \texttt{dst.cols} -1)*0.5, y + \texttt{center.y} - ( \texttt{dst.rows} -1)*0.5)\f]
+
+where the values of the pixels at non-integer coordinates are retrieved using bilinear
+interpolation. Every channel of multi-channel images is processed independently. While the center of
+the rectangle must be inside the image, parts of the rectangle may be outside. In this case, the
+replication border mode (see cv::BorderTypes) is used to extrapolate the pixel values outside of
+the image.
+
+@param image Source image.
+@param patchSize Size of the extracted patch.
+@param center Floating point coordinates of the center of the extracted rectangle within the
+source image. The center must be inside the image.
+@param patch Extracted patch that has the size patchSize and the same number of channels as src .
+@param patchType Depth of the extracted pixels. By default, they have the same depth as src .
+
+@sa warpAffine, warpPerspective
+ */
+CV_EXPORTS_W void getRectSubPix( InputArray image, Size patchSize,
+ Point2f center, OutputArray patch, int patchType = -1 );
+
+/** @example polar_transforms.cpp
+An example using the cv::linearPolar and cv::logPolar operations
+*/
+
+/** @brief Remaps an image to semilog-polar coordinates space.
+
+Transform the source image using the following transformation (See @ref polar_remaps_reference_image "Polar remaps reference image"):
+\f[\begin{array}{l}
+ dst( \rho , \phi ) = src(x,y) \\
+ dst.size() \leftarrow src.size()
+\end{array}\f]
+
+where
+\f[\begin{array}{l}
+ I = (dx,dy) = (x - center.x,y - center.y) \\
+ \rho = M \cdot log_e(\texttt{magnitude} (I)) ,\\
+ \phi = Ky \cdot \texttt{angle} (I)_{0..360 deg} \\
+\end{array}\f]
+
+and
+\f[\begin{array}{l}
+ M = src.cols / log_e(maxRadius) \\
+ Ky = src.rows / 360 \\
+\end{array}\f]
+
+The function emulates the human "foveal" vision and can be used for fast scale and
+rotation-invariant template matching, for object tracking and so forth.
+@param src Source image
+@param dst Destination image. It will have same size and type as src.
+@param center The transformation center; where the output precision is maximal
+@param M Magnitude scale parameter. It determines the radius of the bounding circle to transform too.
+@param flags A combination of interpolation methods, see cv::InterpolationFlags
+
+@note
+- The function can not operate in-place.
+- To calculate magnitude and angle in degrees @ref cv::cartToPolar is used internally thus angles are measured from 0 to 360 with accuracy about 0.3 degrees.
+*/
+CV_EXPORTS_W void logPolar( InputArray src, OutputArray dst,
+ Point2f center, double M, int flags );
+
+/** @brief Remaps an image to polar coordinates space.
+
+@anchor polar_remaps_reference_image
+
+
+Transform the source image using the following transformation:
+\f[\begin{array}{l}
+ dst( \rho , \phi ) = src(x,y) \\
+ dst.size() \leftarrow src.size()
+\end{array}\f]
+
+where
+\f[\begin{array}{l}
+ I = (dx,dy) = (x - center.x,y - center.y) \\
+ \rho = Kx \cdot \texttt{magnitude} (I) ,\\
+ \phi = Ky \cdot \texttt{angle} (I)_{0..360 deg}
+\end{array}\f]
+
+and
+\f[\begin{array}{l}
+ Kx = src.cols / maxRadius \\
+ Ky = src.rows / 360
+\end{array}\f]
+
+
+@param src Source image
+@param dst Destination image. It will have same size and type as src.
+@param center The transformation center;
+@param maxRadius The radius of the bounding circle to transform. It determines the inverse magnitude scale parameter too.
+@param flags A combination of interpolation methods, see cv::InterpolationFlags
+
+@note
+- The function can not operate in-place.
+- To calculate magnitude and angle in degrees @ref cv::cartToPolar is used internally thus angles are measured from 0 to 360 with accuracy about 0.3 degrees.
+
+*/
+CV_EXPORTS_W void linearPolar( InputArray src, OutputArray dst,
+ Point2f center, double maxRadius, int flags );
+
+//! @} imgproc_transform
+
+//! @addtogroup imgproc_misc
+//! @{
+
+/** @overload */
+CV_EXPORTS_W void integral( InputArray src, OutputArray sum, int sdepth = -1 );
+
+/** @overload */
+CV_EXPORTS_AS(integral2) void integral( InputArray src, OutputArray sum,
+ OutputArray sqsum, int sdepth = -1, int sqdepth = -1 );
+
+/** @brief Calculates the integral of an image.
+
+The function calculates one or more integral images for the source image as follows:
+
+\f[\texttt{sum} (X,Y) = \sum _{x<X,y<Y} \texttt{image} (x,y)\f]
+
+\f[\texttt{sqsum} (X,Y) = \sum _{x<X,y<Y} \texttt{image} (x,y)^2\f]
+
+\f[\texttt{tilted} (X,Y) = \sum _{y<Y,abs(x-X+1) \leq Y-y-1} \texttt{image} (x,y)\f]
+
+Using these integral images, you can calculate sum, mean, and standard deviation over a specific
+up-right or rotated rectangular region of the image in a constant time, for example:
+
+\f[\sum _{x_1 \leq x < x_2, \, y_1 \leq y < y_2} \texttt{image} (x,y) = \texttt{sum} (x_2,y_2)- \texttt{sum} (x_1,y_2)- \texttt{sum} (x_2,y_1)+ \texttt{sum} (x_1,y_1)\f]
+
+It makes possible to do a fast blurring or fast block correlation with a variable window size, for
+example. In case of multi-channel images, sums for each channel are accumulated independently.
+
+As a practical example, the next figure shows the calculation of the integral of a straight
+rectangle Rect(3,3,3,2) and of a tilted rectangle Rect(5,1,2,3) . The selected pixels in the
+original image are shown, as well as the relative pixels in the integral images sum and tilted .
+
+
+
+@param src input image as \f$W \times H\f$, 8-bit or floating-point (32f or 64f).
+@param sum integral image as \f$(W+1)\times (H+1)\f$ , 32-bit integer or floating-point (32f or 64f).
+@param sqsum integral image for squared pixel values; it is \f$(W+1)\times (H+1)\f$, double-precision
+floating-point (64f) array.
+@param tilted integral for the image rotated by 45 degrees; it is \f$(W+1)\times (H+1)\f$ array with
+the same data type as sum.
+@param sdepth desired depth of the integral and the tilted integral images, CV_32S, CV_32F, or
+CV_64F.
+@param sqdepth desired depth of the integral image of squared pixel values, CV_32F or CV_64F.
+ */
+CV_EXPORTS_AS(integral3) void integral( InputArray src, OutputArray sum,
+ OutputArray sqsum, OutputArray tilted,
+ int sdepth = -1, int sqdepth = -1 );
+
+//! @} imgproc_misc
+
+//! @addtogroup imgproc_motion
+//! @{
+
+/** @brief Adds an image to the accumulator.
+
+The function adds src or some of its elements to dst :
+
+\f[\texttt{dst} (x,y) \leftarrow \texttt{dst} (x,y) + \texttt{src} (x,y) \quad \text{if} \quad \texttt{mask} (x,y) \ne 0\f]
+
+The function supports multi-channel images. Each channel is processed independently.
+
+The functions accumulate\* can be used, for example, to collect statistics of a scene background
+viewed by a still camera and for the further foreground-background segmentation.
+
+@param src Input image as 1- or 3-channel, 8-bit or 32-bit floating point.
+@param dst %Accumulator image with the same number of channels as input image, 32-bit or 64-bit
+floating-point.
+@param mask Optional operation mask.
+
+@sa accumulateSquare, accumulateProduct, accumulateWeighted
+ */
+CV_EXPORTS_W void accumulate( InputArray src, InputOutputArray dst,
+ InputArray mask = noArray() );
+
+/** @brief Adds the square of a source image to the accumulator.
+
+The function adds the input image src or its selected region, raised to a power of 2, to the
+accumulator dst :
+
+\f[\texttt{dst} (x,y) \leftarrow \texttt{dst} (x,y) + \texttt{src} (x,y)^2 \quad \text{if} \quad \texttt{mask} (x,y) \ne 0\f]
+
+The function supports multi-channel images. Each channel is processed independently.
+
+@param src Input image as 1- or 3-channel, 8-bit or 32-bit floating point.
+@param dst %Accumulator image with the same number of channels as input image, 32-bit or 64-bit
+floating-point.
+@param mask Optional operation mask.
+
+@sa accumulateSquare, accumulateProduct, accumulateWeighted
+ */
+CV_EXPORTS_W void accumulateSquare( InputArray src, InputOutputArray dst,
+ InputArray mask = noArray() );
+
+/** @brief Adds the per-element product of two input images to the accumulator.
+
+The function adds the product of two images or their selected regions to the accumulator dst :
+
+\f[\texttt{dst} (x,y) \leftarrow \texttt{dst} (x,y) + \texttt{src1} (x,y) \cdot \texttt{src2} (x,y) \quad \text{if} \quad \texttt{mask} (x,y) \ne 0\f]
+
+The function supports multi-channel images. Each channel is processed independently.
+
+@param src1 First input image, 1- or 3-channel, 8-bit or 32-bit floating point.
+@param src2 Second input image of the same type and the same size as src1 .
+@param dst %Accumulator with the same number of channels as input images, 32-bit or 64-bit
+floating-point.
+@param mask Optional operation mask.
+
+@sa accumulate, accumulateSquare, accumulateWeighted
+ */
+CV_EXPORTS_W void accumulateProduct( InputArray src1, InputArray src2,
+ InputOutputArray dst, InputArray mask=noArray() );
+
+/** @brief Updates a running average.
+
+The function calculates the weighted sum of the input image src and the accumulator dst so that dst
+becomes a running average of a frame sequence:
+
+\f[\texttt{dst} (x,y) \leftarrow (1- \texttt{alpha} ) \cdot \texttt{dst} (x,y) + \texttt{alpha} \cdot \texttt{src} (x,y) \quad \text{if} \quad \texttt{mask} (x,y) \ne 0\f]
+
+That is, alpha regulates the update speed (how fast the accumulator "forgets" about earlier images).
+The function supports multi-channel images. Each channel is processed independently.
+
+@param src Input image as 1- or 3-channel, 8-bit or 32-bit floating point.
+@param dst %Accumulator image with the same number of channels as input image, 32-bit or 64-bit
+floating-point.
+@param alpha Weight of the input image.
+@param mask Optional operation mask.
+
+@sa accumulate, accumulateSquare, accumulateProduct
+ */
+CV_EXPORTS_W void accumulateWeighted( InputArray src, InputOutputArray dst,
+ double alpha, InputArray mask = noArray() );
+
+/** @brief The function is used to detect translational shifts that occur between two images.
+
+The operation takes advantage of the Fourier shift theorem for detecting the translational shift in
+the frequency domain. It can be used for fast image registration as well as motion estimation. For
+more information please see <http://en.wikipedia.org/wiki/Phase_correlation>
+
+Calculates the cross-power spectrum of two supplied source arrays. The arrays are padded if needed
+with getOptimalDFTSize.
+
+The function performs the following equations:
+- First it applies a Hanning window (see <http://en.wikipedia.org/wiki/Hann_function>) to each
+image to remove possible edge effects. This window is cached until the array size changes to speed
+up processing time.
+- Next it computes the forward DFTs of each source array:
+\f[\mathbf{G}_a = \mathcal{F}\{src_1\}, \; \mathbf{G}_b = \mathcal{F}\{src_2\}\f]
+where \f$\mathcal{F}\f$ is the forward DFT.
+- It then computes the cross-power spectrum of each frequency domain array:
+\f[R = \frac{ \mathbf{G}_a \mathbf{G}_b^*}{|\mathbf{G}_a \mathbf{G}_b^*|}\f]
+- Next the cross-correlation is converted back into the time domain via the inverse DFT:
+\f[r = \mathcal{F}^{-1}\{R\}\f]
+- Finally, it computes the peak location and computes a 5x5 weighted centroid around the peak to
+achieve sub-pixel accuracy.
+\f[(\Delta x, \Delta y) = \texttt{weightedCentroid} \{\arg \max_{(x, y)}\{r\}\}\f]
+- If non-zero, the response parameter is computed as the sum of the elements of r within the 5x5
+centroid around the peak location. It is normalized to a maximum of 1 (meaning there is a single
+peak) and will be smaller when there are multiple peaks.
+
+@param src1 Source floating point array (CV_32FC1 or CV_64FC1)
+@param src2 Source floating point array (CV_32FC1 or CV_64FC1)
+@param window Floating point array with windowing coefficients to reduce edge effects (optional).
+@param response Signal power within the 5x5 centroid around the peak, between 0 and 1 (optional).
+@returns detected phase shift (sub-pixel) between the two arrays.
+
+@sa dft, getOptimalDFTSize, idft, mulSpectrums createHanningWindow
+ */
+CV_EXPORTS_W Point2d phaseCorrelate(InputArray src1, InputArray src2,
+ InputArray window = noArray(), CV_OUT double* response = 0);
+
+/** @brief This function computes a Hanning window coefficients in two dimensions.
+
+See (http://en.wikipedia.org/wiki/Hann_function) and (http://en.wikipedia.org/wiki/Window_function)
+for more information.
+
+An example is shown below:
+@code
+ // create hanning window of size 100x100 and type CV_32F
+ Mat hann;
+ createHanningWindow(hann, Size(100, 100), CV_32F);
+@endcode
+@param dst Destination array to place Hann coefficients in
+@param winSize The window size specifications
+@param type Created array type
+ */
+CV_EXPORTS_W void createHanningWindow(OutputArray dst, Size winSize, int type);
+
+//! @} imgproc_motion
+
+//! @addtogroup imgproc_misc
+//! @{
+
+/** @brief Applies a fixed-level threshold to each array element.
+
+The function applies fixed-level thresholding to a single-channel array. The function is typically
+used to get a bi-level (binary) image out of a grayscale image ( cv::compare could be also used for
+this purpose) or for removing a noise, that is, filtering out pixels with too small or too large
+values. There are several types of thresholding supported by the function. They are determined by
+type parameter.
+
+Also, the special values cv::THRESH_OTSU or cv::THRESH_TRIANGLE may be combined with one of the
+above values. In these cases, the function determines the optimal threshold value using the Otsu's
+or Triangle algorithm and uses it instead of the specified thresh . The function returns the
+computed threshold value. Currently, the Otsu's and Triangle methods are implemented only for 8-bit
+images.
+
+@param src input array (single-channel, 8-bit or 32-bit floating point).
+@param dst output array of the same size and type as src.
+@param thresh threshold value.
+@param maxval maximum value to use with the THRESH_BINARY and THRESH_BINARY_INV thresholding
+types.
+@param type thresholding type (see the cv::ThresholdTypes).
+
+@sa adaptiveThreshold, findContours, compare, min, max
+ */
+CV_EXPORTS_W double threshold( InputArray src, OutputArray dst,
+ double thresh, double maxval, int type );
+
+
+/** @brief Applies an adaptive threshold to an array.
+
+The function transforms a grayscale image to a binary image according to the formulae:
+- **THRESH_BINARY**
+ \f[dst(x,y) = \fork{\texttt{maxValue}}{if \(src(x,y) > T(x,y)\)}{0}{otherwise}\f]
+- **THRESH_BINARY_INV**
+ \f[dst(x,y) = \fork{0}{if \(src(x,y) > T(x,y)\)}{\texttt{maxValue}}{otherwise}\f]
+where \f$T(x,y)\f$ is a threshold calculated individually for each pixel (see adaptiveMethod parameter).
+
+The function can process the image in-place.
+
+@param src Source 8-bit single-channel image.
+@param dst Destination image of the same size and the same type as src.
+@param maxValue Non-zero value assigned to the pixels for which the condition is satisfied
+@param adaptiveMethod Adaptive thresholding algorithm to use, see cv::AdaptiveThresholdTypes
+@param thresholdType Thresholding type that must be either THRESH_BINARY or THRESH_BINARY_INV,
+see cv::ThresholdTypes.
+@param blockSize Size of a pixel neighborhood that is used to calculate a threshold value for the
+pixel: 3, 5, 7, and so on.
+@param C Constant subtracted from the mean or weighted mean (see the details below). Normally, it
+is positive but may be zero or negative as well.
+
+@sa threshold, blur, GaussianBlur
+ */
+CV_EXPORTS_W void adaptiveThreshold( InputArray src, OutputArray dst,
+ double maxValue, int adaptiveMethod,
+ int thresholdType, int blockSize, double C );
+
+//! @} imgproc_misc
+
+//! @addtogroup imgproc_filter
+//! @{
+
+/** @brief Blurs an image and downsamples it.
+
+By default, size of the output image is computed as `Size((src.cols+1)/2, (src.rows+1)/2)`, but in
+any case, the following conditions should be satisfied:
+
+\f[\begin{array}{l} | \texttt{dstsize.width} *2-src.cols| \leq 2 \\ | \texttt{dstsize.height} *2-src.rows| \leq 2 \end{array}\f]
+
+The function performs the downsampling step of the Gaussian pyramid construction. First, it
+convolves the source image with the kernel:
+
+\f[\frac{1}{256} \begin{bmatrix} 1 & 4 & 6 & 4 & 1 \\ 4 & 16 & 24 & 16 & 4 \\ 6 & 24 & 36 & 24 & 6 \\ 4 & 16 & 24 & 16 & 4 \\ 1 & 4 & 6 & 4 & 1 \end{bmatrix}\f]
+
+Then, it downsamples the image by rejecting even rows and columns.
+
+@param src input image.
+@param dst output image; it has the specified size and the same type as src.
+@param dstsize size of the output image.
+@param borderType Pixel extrapolation method, see cv::BorderTypes (BORDER_CONSTANT isn't supported)
+ */
+CV_EXPORTS_W void pyrDown( InputArray src, OutputArray dst,
+ const Size& dstsize = Size(), int borderType = BORDER_DEFAULT );
+
+/** @brief Upsamples an image and then blurs it.
+
+By default, size of the output image is computed as `Size(src.cols\*2, (src.rows\*2)`, but in any
+case, the following conditions should be satisfied:
+
+\f[\begin{array}{l} | \texttt{dstsize.width} -src.cols*2| \leq ( \texttt{dstsize.width} \mod 2) \\ | \texttt{dstsize.height} -src.rows*2| \leq ( \texttt{dstsize.height} \mod 2) \end{array}\f]
+
+The function performs the upsampling step of the Gaussian pyramid construction, though it can
+actually be used to construct the Laplacian pyramid. First, it upsamples the source image by
+injecting even zero rows and columns and then convolves the result with the same kernel as in
+pyrDown multiplied by 4.
+
+@param src input image.
+@param dst output image. It has the specified size and the same type as src .
+@param dstsize size of the output image.
+@param borderType Pixel extrapolation method, see cv::BorderTypes (only BORDER_DEFAULT is supported)
+ */
+CV_EXPORTS_W void pyrUp( InputArray src, OutputArray dst,
+ const Size& dstsize = Size(), int borderType = BORDER_DEFAULT );
+
+/** @brief Constructs the Gaussian pyramid for an image.
+
+The function constructs a vector of images and builds the Gaussian pyramid by recursively applying
+pyrDown to the previously built pyramid layers, starting from `dst[0]==src`.
+
+@param src Source image. Check pyrDown for the list of supported types.
+@param dst Destination vector of maxlevel+1 images of the same type as src. dst[0] will be the
+same as src. dst[1] is the next pyramid layer, a smoothed and down-sized src, and so on.
+@param maxlevel 0-based index of the last (the smallest) pyramid layer. It must be non-negative.
+@param borderType Pixel extrapolation method, see cv::BorderTypes (BORDER_CONSTANT isn't supported)
+ */
+CV_EXPORTS void buildPyramid( InputArray src, OutputArrayOfArrays dst,
+ int maxlevel, int borderType = BORDER_DEFAULT );
+
+//! @} imgproc_filter
+
+//! @addtogroup imgproc_transform
+//! @{
+
+/** @brief Transforms an image to compensate for lens distortion.
+
+The function transforms an image to compensate radial and tangential lens distortion.
+
+The function is simply a combination of cv::initUndistortRectifyMap (with unity R ) and cv::remap
+(with bilinear interpolation). See the former function for details of the transformation being
+performed.
+
+Those pixels in the destination image, for which there is no correspondent pixels in the source
+image, are filled with zeros (black color).
+
+A particular subset of the source image that will be visible in the corrected image can be regulated
+by newCameraMatrix. You can use cv::getOptimalNewCameraMatrix to compute the appropriate
+newCameraMatrix depending on your requirements.
+
+The camera matrix and the distortion parameters can be determined using cv::calibrateCamera. If
+the resolution of images is different from the resolution used at the calibration stage, \f$f_x,
+f_y, c_x\f$ and \f$c_y\f$ need to be scaled accordingly, while the distortion coefficients remain
+the same.
+
+@param src Input (distorted) image.
+@param dst Output (corrected) image that has the same size and type as src .
+@param cameraMatrix Input camera matrix \f$A = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}\f$ .
+@param distCoeffs Input vector of distortion coefficients
+\f$(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6[, s_1, s_2, s_3, s_4[, \tau_x, \tau_y]]]])\f$
+of 4, 5, 8, 12 or 14 elements. If the vector is NULL/empty, the zero distortion coefficients are assumed.
+@param newCameraMatrix Camera matrix of the distorted image. By default, it is the same as
+cameraMatrix but you may additionally scale and shift the result by using a different matrix.
+ */
+CV_EXPORTS_W void undistort( InputArray src, OutputArray dst,
+ InputArray cameraMatrix,
+ InputArray distCoeffs,
+ InputArray newCameraMatrix = noArray() );
+
+/** @brief Computes the undistortion and rectification transformation map.
+
+The function computes the joint undistortion and rectification transformation and represents the
+result in the form of maps for remap. The undistorted image looks like original, as if it is
+captured with a camera using the camera matrix =newCameraMatrix and zero distortion. In case of a
+monocular camera, newCameraMatrix is usually equal to cameraMatrix, or it can be computed by
+cv::getOptimalNewCameraMatrix for a better control over scaling. In case of a stereo camera,
+newCameraMatrix is normally set to P1 or P2 computed by cv::stereoRectify .
+
+Also, this new camera is oriented differently in the coordinate space, according to R. That, for
+example, helps to align two heads of a stereo camera so that the epipolar lines on both images
+become horizontal and have the same y- coordinate (in case of a horizontally aligned stereo camera).
+
+The function actually builds the maps for the inverse mapping algorithm that is used by remap. That
+is, for each pixel \f$(u, v)\f$ in the destination (corrected and rectified) image, the function
+computes the corresponding coordinates in the source image (that is, in the original image from
+camera). The following process is applied:
+\f[
+\begin{array}{l}
+x \leftarrow (u - {c'}_x)/{f'}_x \\
+y \leftarrow (v - {c'}_y)/{f'}_y \\
+{[X\,Y\,W]} ^T \leftarrow R^{-1}*[x \, y \, 1]^T \\
+x' \leftarrow X/W \\
+y' \leftarrow Y/W \\
+r^2 \leftarrow x'^2 + y'^2 \\
+x'' \leftarrow x' \frac{1 + k_1 r^2 + k_2 r^4 + k_3 r^6}{1 + k_4 r^2 + k_5 r^4 + k_6 r^6}
++ 2p_1 x' y' + p_2(r^2 + 2 x'^2) + s_1 r^2 + s_2 r^4\\
+y'' \leftarrow y' \frac{1 + k_1 r^2 + k_2 r^4 + k_3 r^6}{1 + k_4 r^2 + k_5 r^4 + k_6 r^6}
++ p_1 (r^2 + 2 y'^2) + 2 p_2 x' y' + s_3 r^2 + s_4 r^4 \\
+s\vecthree{x'''}{y'''}{1} =
+\vecthreethree{R_{33}(\tau_x, \tau_y)}{0}{-R_{13}((\tau_x, \tau_y)}
+{0}{R_{33}(\tau_x, \tau_y)}{-R_{23}(\tau_x, \tau_y)}
+{0}{0}{1} R(\tau_x, \tau_y) \vecthree{x''}{y''}{1}\\
+map_x(u,v) \leftarrow x''' f_x + c_x \\
+map_y(u,v) \leftarrow y''' f_y + c_y
+\end{array}
+\f]
+where \f$(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6[, s_1, s_2, s_3, s_4[, \tau_x, \tau_y]]]])\f$
+are the distortion coefficients.
+
+In case of a stereo camera, this function is called twice: once for each camera head, after
+stereoRectify, which in its turn is called after cv::stereoCalibrate. But if the stereo camera
+was not calibrated, it is still possible to compute the rectification transformations directly from
+the fundamental matrix using cv::stereoRectifyUncalibrated. For each camera, the function computes
+homography H as the rectification transformation in a pixel domain, not a rotation matrix R in 3D
+space. R can be computed from H as
+\f[\texttt{R} = \texttt{cameraMatrix} ^{-1} \cdot \texttt{H} \cdot \texttt{cameraMatrix}\f]
+where cameraMatrix can be chosen arbitrarily.
+
+@param cameraMatrix Input camera matrix \f$A=\vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}\f$ .
+@param distCoeffs Input vector of distortion coefficients
+\f$(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6[, s_1, s_2, s_3, s_4[, \tau_x, \tau_y]]]])\f$
+of 4, 5, 8, 12 or 14 elements. If the vector is NULL/empty, the zero distortion coefficients are assumed.
+@param R Optional rectification transformation in the object space (3x3 matrix). R1 or R2 ,
+computed by stereoRectify can be passed here. If the matrix is empty, the identity transformation
+is assumed. In cvInitUndistortMap R assumed to be an identity matrix.
+@param newCameraMatrix New camera matrix \f$A'=\vecthreethree{f_x'}{0}{c_x'}{0}{f_y'}{c_y'}{0}{0}{1}\f$.
+@param size Undistorted image size.
+@param m1type Type of the first output map that can be CV_32FC1 or CV_16SC2, see cv::convertMaps
+@param map1 The first output map.
+@param map2 The second output map.
+ */
+CV_EXPORTS_W void initUndistortRectifyMap( InputArray cameraMatrix, InputArray distCoeffs,
+ InputArray R, InputArray newCameraMatrix,
+ Size size, int m1type, OutputArray map1, OutputArray map2 );
+
+//! initializes maps for cv::remap() for wide-angle
+CV_EXPORTS_W float initWideAngleProjMap( InputArray cameraMatrix, InputArray distCoeffs,
+ Size imageSize, int destImageWidth,
+ int m1type, OutputArray map1, OutputArray map2,
+ int projType = PROJ_SPHERICAL_EQRECT, double alpha = 0);
+
+/** @brief Returns the default new camera matrix.
+
+The function returns the camera matrix that is either an exact copy of the input cameraMatrix (when
+centerPrinicipalPoint=false ), or the modified one (when centerPrincipalPoint=true).
+
+In the latter case, the new camera matrix will be:
+
+\f[\begin{bmatrix} f_x && 0 && ( \texttt{imgSize.width} -1)*0.5 \\ 0 && f_y && ( \texttt{imgSize.height} -1)*0.5 \\ 0 && 0 && 1 \end{bmatrix} ,\f]
+
+where \f$f_x\f$ and \f$f_y\f$ are \f$(0,0)\f$ and \f$(1,1)\f$ elements of cameraMatrix, respectively.
+
+By default, the undistortion functions in OpenCV (see initUndistortRectifyMap, undistort) do not
+move the principal point. However, when you work with stereo, it is important to move the principal
+points in both views to the same y-coordinate (which is required by most of stereo correspondence
+algorithms), and may be to the same x-coordinate too. So, you can form the new camera matrix for
+each view where the principal points are located at the center.
+
+@param cameraMatrix Input camera matrix.
+@param imgsize Camera view image size in pixels.
+@param centerPrincipalPoint Location of the principal point in the new camera matrix. The
+parameter indicates whether this location should be at the image center or not.
+ */
+CV_EXPORTS_W Mat getDefaultNewCameraMatrix( InputArray cameraMatrix, Size imgsize = Size(),
+ bool centerPrincipalPoint = false );
+
+/** @brief Computes the ideal point coordinates from the observed point coordinates.
+
+The function is similar to cv::undistort and cv::initUndistortRectifyMap but it operates on a
+sparse set of points instead of a raster image. Also the function performs a reverse transformation
+to projectPoints. In case of a 3D object, it does not reconstruct its 3D coordinates, but for a
+planar object, it does, up to a translation vector, if the proper R is specified.
+
+For each observed point coordinate \f$(u, v)\f$ the function computes:
+\f[
+\begin{array}{l}
+x^{"} \leftarrow (u - c_x)/f_x \\
+y^{"} \leftarrow (v - c_y)/f_y \\
+(x',y') = undistort(x^{"},y^{"}, \texttt{distCoeffs}) \\
+{[X\,Y\,W]} ^T \leftarrow R*[x' \, y' \, 1]^T \\
+x \leftarrow X/W \\
+y \leftarrow Y/W \\
+\text{only performed if P is specified:} \\
+u' \leftarrow x {f'}_x + {c'}_x \\
+v' \leftarrow y {f'}_y + {c'}_y
+\end{array}
+\f]
+
+where *undistort* is an approximate iterative algorithm that estimates the normalized original
+point coordinates out of the normalized distorted point coordinates ("normalized" means that the
+coordinates do not depend on the camera matrix).
+
+The function can be used for both a stereo camera head or a monocular camera (when R is empty).
+
+@param src Observed point coordinates, 1xN or Nx1 2-channel (CV_32FC2 or CV_64FC2).
+@param dst Output ideal point coordinates after undistortion and reverse perspective
+transformation. If matrix P is identity or omitted, dst will contain normalized point coordinates.
+@param cameraMatrix Camera matrix \f$\vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}\f$ .
+@param distCoeffs Input vector of distortion coefficients
+\f$(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6[, s_1, s_2, s_3, s_4[, \tau_x, \tau_y]]]])\f$
+of 4, 5, 8, 12 or 14 elements. If the vector is NULL/empty, the zero distortion coefficients are assumed.
+@param R Rectification transformation in the object space (3x3 matrix). R1 or R2 computed by
+cv::stereoRectify can be passed here. If the matrix is empty, the identity transformation is used.
+@param P New camera matrix (3x3) or new projection matrix (3x4) \f$\begin{bmatrix} {f'}_x & 0 & {c'}_x & t_x \\ 0 & {f'}_y & {c'}_y & t_y \\ 0 & 0 & 1 & t_z \end{bmatrix}\f$. P1 or P2 computed by
+cv::stereoRectify can be passed here. If the matrix is empty, the identity new camera matrix is used.
+ */
+CV_EXPORTS_W void undistortPoints( InputArray src, OutputArray dst,
+ InputArray cameraMatrix, InputArray distCoeffs,
+ InputArray R = noArray(), InputArray P = noArray());
+
+//! @} imgproc_transform
+
+//! @addtogroup imgproc_hist
+//! @{
+
+/** @example demhist.cpp
+An example for creating histograms of an image
+*/
+
+/** @brief Calculates a histogram of a set of arrays.
+
+The function cv::calcHist calculates the histogram of one or more arrays. The elements of a tuple used
+to increment a histogram bin are taken from the corresponding input arrays at the same location. The
+sample below shows how to compute a 2D Hue-Saturation histogram for a color image. :
+@code
+ #include <opencv2/imgproc.hpp>
+ #include <opencv2/highgui.hpp>
+
+ using namespace cv;
+
+ int main( int argc, char** argv )
+ {
+ Mat src, hsv;
+ if( argc != 2 || !(src=imread(argv[1], 1)).data )
+ return -1;
+
+ cvtColor(src, hsv, COLOR_BGR2HSV);
+
+ // Quantize the hue to 30 levels
+ // and the saturation to 32 levels
+ int hbins = 30, sbins = 32;
+ int histSize[] = {hbins, sbins};
+ // hue varies from 0 to 179, see cvtColor
+ float hranges[] = { 0, 180 };
+ // saturation varies from 0 (black-gray-white) to
+ // 255 (pure spectrum color)
+ float sranges[] = { 0, 256 };
+ const float* ranges[] = { hranges, sranges };
+ MatND hist;
+ // we compute the histogram from the 0-th and 1-st channels
+ int channels[] = {0, 1};
+
+ calcHist( &hsv, 1, channels, Mat(), // do not use mask
+ hist, 2, histSize, ranges,
+ true, // the histogram is uniform
+ false );
+ double maxVal=0;
+ minMaxLoc(hist, 0, &maxVal, 0, 0);
+
+ int scale = 10;
+ Mat histImg = Mat::zeros(sbins*scale, hbins*10, CV_8UC3);
+
+ for( int h = 0; h < hbins; h++ )
+ for( int s = 0; s < sbins; s++ )
+ {
+ float binVal = hist.at<float>(h, s);
+ int intensity = cvRound(binVal*255/maxVal);
+ rectangle( histImg, Point(h*scale, s*scale),
+ Point( (h+1)*scale - 1, (s+1)*scale - 1),
+ Scalar::all(intensity),
+ CV_FILLED );
+ }
+
+ namedWindow( "Source", 1 );
+ imshow( "Source", src );
+
+ namedWindow( "H-S Histogram", 1 );
+ imshow( "H-S Histogram", histImg );
+ waitKey();
+ }
+@endcode
+
+@param images Source arrays. They all should have the same depth, CV_8U, CV_16U or CV_32F , and the same
+size. Each of them can have an arbitrary number of channels.
+@param nimages Number of source images.
+@param channels List of the dims channels used to compute the histogram. The first array channels
+are numerated from 0 to images[0].channels()-1 , the second array channels are counted from
+images[0].channels() to images[0].channels() + images[1].channels()-1, and so on.
+@param mask Optional mask. If the matrix is not empty, it must be an 8-bit array of the same size
+as images[i] . The non-zero mask elements mark the array elements counted in the histogram.
+@param hist Output histogram, which is a dense or sparse dims -dimensional array.
+@param dims Histogram dimensionality that must be positive and not greater than CV_MAX_DIMS
+(equal to 32 in the current OpenCV version).
+@param histSize Array of histogram sizes in each dimension.
+@param ranges Array of the dims arrays of the histogram bin boundaries in each dimension. When the
+histogram is uniform ( uniform =true), then for each dimension i it is enough to specify the lower
+(inclusive) boundary \f$L_0\f$ of the 0-th histogram bin and the upper (exclusive) boundary
+\f$U_{\texttt{histSize}[i]-1}\f$ for the last histogram bin histSize[i]-1 . That is, in case of a
+uniform histogram each of ranges[i] is an array of 2 elements. When the histogram is not uniform (
+uniform=false ), then each of ranges[i] contains histSize[i]+1 elements:
+\f$L_0, U_0=L_1, U_1=L_2, ..., U_{\texttt{histSize[i]}-2}=L_{\texttt{histSize[i]}-1}, U_{\texttt{histSize[i]}-1}\f$
+. The array elements, that are not between \f$L_0\f$ and \f$U_{\texttt{histSize[i]}-1}\f$ , are not
+counted in the histogram.
+@param uniform Flag indicating whether the histogram is uniform or not (see above).
+@param accumulate Accumulation flag. If it is set, the histogram is not cleared in the beginning
+when it is allocated. This feature enables you to compute a single histogram from several sets of
+arrays, or to update the histogram in time.
+*/
+CV_EXPORTS void calcHist( const Mat* images, int nimages,
+ const int* channels, InputArray mask,
+ OutputArray hist, int dims, const int* histSize,
+ const float** ranges, bool uniform = true, bool accumulate = false );
+
+/** @overload
+
+this variant uses cv::SparseMat for output
+*/
+CV_EXPORTS void calcHist( const Mat* images, int nimages,
+ const int* channels, InputArray mask,
+ SparseMat& hist, int dims,
+ const int* histSize, const float** ranges,
+ bool uniform = true, bool accumulate = false );
+
+/** @overload */
+CV_EXPORTS_W void calcHist( InputArrayOfArrays images,
+ const std::vector<int>& channels,
+ InputArray mask, OutputArray hist,
+ const std::vector<int>& histSize,
+ const std::vector<float>& ranges,
+ bool accumulate = false );
+
+/** @brief Calculates the back projection of a histogram.
+
+The function cv::calcBackProject calculates the back project of the histogram. That is, similarly to
+cv::calcHist , at each location (x, y) the function collects the values from the selected channels
+in the input images and finds the corresponding histogram bin. But instead of incrementing it, the
+function reads the bin value, scales it by scale , and stores in backProject(x,y) . In terms of
+statistics, the function computes probability of each element value in respect with the empirical
+probability distribution represented by the histogram. See how, for example, you can find and track
+a bright-colored object in a scene:
+
+- Before tracking, show the object to the camera so that it covers almost the whole frame.
+Calculate a hue histogram. The histogram may have strong maximums, corresponding to the dominant
+colors in the object.
+
+- When tracking, calculate a back projection of a hue plane of each input video frame using that
+pre-computed histogram. Threshold the back projection to suppress weak colors. It may also make
+sense to suppress pixels with non-sufficient color saturation and too dark or too bright pixels.
+
+- Find connected components in the resulting picture and choose, for example, the largest
+component.
+
+This is an approximate algorithm of the CamShift color object tracker.
+
+@param images Source arrays. They all should have the same depth, CV_8U, CV_16U or CV_32F , and the same
+size. Each of them can have an arbitrary number of channels.
+@param nimages Number of source images.
+@param channels The list of channels used to compute the back projection. The number of channels
+must match the histogram dimensionality. The first array channels are numerated from 0 to
+images[0].channels()-1 , the second array channels are counted from images[0].channels() to
+images[0].channels() + images[1].channels()-1, and so on.
+@param hist Input histogram that can be dense or sparse.
+@param backProject Destination back projection array that is a single-channel array of the same
+size and depth as images[0] .
+@param ranges Array of arrays of the histogram bin boundaries in each dimension. See cv::calcHist .
+@param scale Optional scale factor for the output back projection.
+@param uniform Flag indicating whether the histogram is uniform or not (see above).
+
+@sa cv::calcHist, cv::compareHist
+ */
+CV_EXPORTS void calcBackProject( const Mat* images, int nimages,
+ const int* channels, InputArray hist,
+ OutputArray backProject, const float** ranges,
+ double scale = 1, bool uniform = true );
+
+/** @overload */
+CV_EXPORTS void calcBackProject( const Mat* images, int nimages,
+ const int* channels, const SparseMat& hist,
+ OutputArray backProject, const float** ranges,
+ double scale = 1, bool uniform = true );
+
+/** @overload */
+CV_EXPORTS_W void calcBackProject( InputArrayOfArrays images, const std::vector<int>& channels,
+ InputArray hist, OutputArray dst,
+ const std::vector<float>& ranges,
+ double scale );
+
+/** @brief Compares two histograms.
+
+The function cv::compareHist compares two dense or two sparse histograms using the specified method.
+
+The function returns \f$d(H_1, H_2)\f$ .
+
+While the function works well with 1-, 2-, 3-dimensional dense histograms, it may not be suitable
+for high-dimensional sparse histograms. In such histograms, because of aliasing and sampling
+problems, the coordinates of non-zero histogram bins can slightly shift. To compare such histograms
+or more general sparse configurations of weighted points, consider using the cv::EMD function.
+
+@param H1 First compared histogram.
+@param H2 Second compared histogram of the same size as H1 .
+@param method Comparison method, see cv::HistCompMethods
+ */
+CV_EXPORTS_W double compareHist( InputArray H1, InputArray H2, int method );
+
+/** @overload */
+CV_EXPORTS double compareHist( const SparseMat& H1, const SparseMat& H2, int method );
+
+/** @brief Equalizes the histogram of a grayscale image.
+
+The function equalizes the histogram of the input image using the following algorithm:
+
+- Calculate the histogram \f$H\f$ for src .
+- Normalize the histogram so that the sum of histogram bins is 255.
+- Compute the integral of the histogram:
+\f[H'_i = \sum _{0 \le j < i} H(j)\f]
+- Transform the image using \f$H'\f$ as a look-up table: \f$\texttt{dst}(x,y) = H'(\texttt{src}(x,y))\f$
+
+The algorithm normalizes the brightness and increases the contrast of the image.
+
+@param src Source 8-bit single channel image.
+@param dst Destination image of the same size and type as src .
+ */
+CV_EXPORTS_W void equalizeHist( InputArray src, OutputArray dst );
+
+/** @brief Computes the "minimal work" distance between two weighted point configurations.
+
+The function computes the earth mover distance and/or a lower boundary of the distance between the
+two weighted point configurations. One of the applications described in @cite RubnerSept98,
+@cite Rubner2000 is multi-dimensional histogram comparison for image retrieval. EMD is a transportation
+problem that is solved using some modification of a simplex algorithm, thus the complexity is
+exponential in the worst case, though, on average it is much faster. In the case of a real metric
+the lower boundary can be calculated even faster (using linear-time algorithm) and it can be used
+to determine roughly whether the two signatures are far enough so that they cannot relate to the
+same object.
+
+@param signature1 First signature, a \f$\texttt{size1}\times \texttt{dims}+1\f$ floating-point matrix.
+Each row stores the point weight followed by the point coordinates. The matrix is allowed to have
+a single column (weights only) if the user-defined cost matrix is used. The weights must be
+non-negative and have at least one non-zero value.
+@param signature2 Second signature of the same format as signature1 , though the number of rows
+may be different. The total weights may be different. In this case an extra "dummy" point is added
+to either signature1 or signature2. The weights must be non-negative and have at least one non-zero
+value.
+@param distType Used metric. See cv::DistanceTypes.
+@param cost User-defined \f$\texttt{size1}\times \texttt{size2}\f$ cost matrix. Also, if a cost matrix
+is used, lower boundary lowerBound cannot be calculated because it needs a metric function.
+@param lowerBound Optional input/output parameter: lower boundary of a distance between the two
+signatures that is a distance between mass centers. The lower boundary may not be calculated if
+the user-defined cost matrix is used, the total weights of point configurations are not equal, or
+if the signatures consist of weights only (the signature matrices have a single column). You
+**must** initialize \*lowerBound . If the calculated distance between mass centers is greater or
+equal to \*lowerBound (it means that the signatures are far enough), the function does not
+calculate EMD. In any case \*lowerBound is set to the calculated distance between mass centers on
+return. Thus, if you want to calculate both distance between mass centers and EMD, \*lowerBound
+should be set to 0.
+@param flow Resultant \f$\texttt{size1} \times \texttt{size2}\f$ flow matrix: \f$\texttt{flow}_{i,j}\f$ is
+a flow from \f$i\f$ -th point of signature1 to \f$j\f$ -th point of signature2 .
+ */
+CV_EXPORTS float EMD( InputArray signature1, InputArray signature2,
+ int distType, InputArray cost=noArray(),
+ float* lowerBound = 0, OutputArray flow = noArray() );
+
+//! @} imgproc_hist
+
+/** @example watershed.cpp
+An example using the watershed algorithm
+ */
+
+/** @brief Performs a marker-based image segmentation using the watershed algorithm.
+
+The function implements one of the variants of watershed, non-parametric marker-based segmentation
+algorithm, described in @cite Meyer92 .
+
+Before passing the image to the function, you have to roughly outline the desired regions in the
+image markers with positive (\>0) indices. So, every region is represented as one or more connected
+components with the pixel values 1, 2, 3, and so on. Such markers can be retrieved from a binary
+mask using findContours and drawContours (see the watershed.cpp demo). The markers are "seeds" of
+the future image regions. All the other pixels in markers , whose relation to the outlined regions
+is not known and should be defined by the algorithm, should be set to 0's. In the function output,
+each pixel in markers is set to a value of the "seed" components or to -1 at boundaries between the
+regions.
+
+@note Any two neighbor connected components are not necessarily separated by a watershed boundary
+(-1's pixels); for example, they can touch each other in the initial marker image passed to the
+function.
+
+@param image Input 8-bit 3-channel image.
+@param markers Input/output 32-bit single-channel image (map) of markers. It should have the same
+size as image .
+
+@sa findContours
+
+@ingroup imgproc_misc
+ */
+CV_EXPORTS_W void watershed( InputArray image, InputOutputArray markers );
+
+//! @addtogroup imgproc_filter
+//! @{
+
+/** @brief Performs initial step of meanshift segmentation of an image.
+
+The function implements the filtering stage of meanshift segmentation, that is, the output of the
+function is the filtered "posterized" image with color gradients and fine-grain texture flattened.
+At every pixel (X,Y) of the input image (or down-sized input image, see below) the function executes
+meanshift iterations, that is, the pixel (X,Y) neighborhood in the joint space-color hyperspace is
+considered:
+
+\f[(x,y): X- \texttt{sp} \le x \le X+ \texttt{sp} , Y- \texttt{sp} \le y \le Y+ \texttt{sp} , ||(R,G,B)-(r,g,b)|| \le \texttt{sr}\f]
+
+where (R,G,B) and (r,g,b) are the vectors of color components at (X,Y) and (x,y), respectively
+(though, the algorithm does not depend on the color space used, so any 3-component color space can
+be used instead). Over the neighborhood the average spatial value (X',Y') and average color vector
+(R',G',B') are found and they act as the neighborhood center on the next iteration:
+
+\f[(X,Y)~(X',Y'), (R,G,B)~(R',G',B').\f]
+
+After the iterations over, the color components of the initial pixel (that is, the pixel from where
+the iterations started) are set to the final value (average color at the last iteration):
+
+\f[I(X,Y) <- (R*,G*,B*)\f]
+
+When maxLevel \> 0, the gaussian pyramid of maxLevel+1 levels is built, and the above procedure is
+run on the smallest layer first. After that, the results are propagated to the larger layer and the
+iterations are run again only on those pixels where the layer colors differ by more than sr from the
+lower-resolution layer of the pyramid. That makes boundaries of color regions sharper. Note that the
+results will be actually different from the ones obtained by running the meanshift procedure on the
+whole original image (i.e. when maxLevel==0).
+
+@param src The source 8-bit, 3-channel image.
+@param dst The destination image of the same format and the same size as the source.
+@param sp The spatial window radius.
+@param sr The color window radius.
+@param maxLevel Maximum level of the pyramid for the segmentation.
+@param termcrit Termination criteria: when to stop meanshift iterations.
+ */
+CV_EXPORTS_W void pyrMeanShiftFiltering( InputArray src, OutputArray dst,
+ double sp, double sr, int maxLevel = 1,
+ TermCriteria termcrit=TermCriteria(TermCriteria::MAX_ITER+TermCriteria::EPS,5,1) );
+
+//! @}
+
+//! @addtogroup imgproc_misc
+//! @{
+
+/** @example grabcut.cpp
+An example using the GrabCut algorithm
+ */
+
+/** @brief Runs the GrabCut algorithm.
+
+The function implements the [GrabCut image segmentation algorithm](http://en.wikipedia.org/wiki/GrabCut).
+
+@param img Input 8-bit 3-channel image.
+@param mask Input/output 8-bit single-channel mask. The mask is initialized by the function when
+mode is set to GC_INIT_WITH_RECT. Its elements may have one of the cv::GrabCutClasses.
+@param rect ROI containing a segmented object. The pixels outside of the ROI are marked as
+"obvious background". The parameter is only used when mode==GC_INIT_WITH_RECT .
+@param bgdModel Temporary array for the background model. Do not modify it while you are
+processing the same image.
+@param fgdModel Temporary arrays for the foreground model. Do not modify it while you are
+processing the same image.
+@param iterCount Number of iterations the algorithm should make before returning the result. Note
+that the result can be refined with further calls with mode==GC_INIT_WITH_MASK or
+mode==GC_EVAL .
+@param mode Operation mode that could be one of the cv::GrabCutModes
+ */
+CV_EXPORTS_W void grabCut( InputArray img, InputOutputArray mask, Rect rect,
+ InputOutputArray bgdModel, InputOutputArray fgdModel,
+ int iterCount, int mode = GC_EVAL );
+
+/** @example distrans.cpp
+An example on using the distance transform\
+*/
+
+
+/** @brief Calculates the distance to the closest zero pixel for each pixel of the source image.
+
+The function cv::distanceTransform calculates the approximate or precise distance from every binary
+image pixel to the nearest zero pixel. For zero image pixels, the distance will obviously be zero.
+
+When maskSize == DIST_MASK_PRECISE and distanceType == DIST_L2 , the function runs the
+algorithm described in @cite Felzenszwalb04 . This algorithm is parallelized with the TBB library.
+
+In other cases, the algorithm @cite Borgefors86 is used. This means that for a pixel the function
+finds the shortest path to the nearest zero pixel consisting of basic shifts: horizontal, vertical,
+diagonal, or knight's move (the latest is available for a \f$5\times 5\f$ mask). The overall
+distance is calculated as a sum of these basic distances. Since the distance function should be
+symmetric, all of the horizontal and vertical shifts must have the same cost (denoted as a ), all
+the diagonal shifts must have the same cost (denoted as `b`), and all knight's moves must have the
+same cost (denoted as `c`). For the cv::DIST_C and cv::DIST_L1 types, the distance is calculated
+precisely, whereas for cv::DIST_L2 (Euclidean distance) the distance can be calculated only with a
+relative error (a \f$5\times 5\f$ mask gives more accurate results). For `a`,`b`, and `c`, OpenCV
+uses the values suggested in the original paper:
+- DIST_L1: `a = 1, b = 2`
+- DIST_L2:
+ - `3 x 3`: `a=0.955, b=1.3693`
+ - `5 x 5`: `a=1, b=1.4, c=2.1969`
+- DIST_C: `a = 1, b = 1`
+
+Typically, for a fast, coarse distance estimation DIST_L2, a \f$3\times 3\f$ mask is used. For a
+more accurate distance estimation DIST_L2, a \f$5\times 5\f$ mask or the precise algorithm is used.
+Note that both the precise and the approximate algorithms are linear on the number of pixels.
+
+This variant of the function does not only compute the minimum distance for each pixel \f$(x, y)\f$
+but also identifies the nearest connected component consisting of zero pixels
+(labelType==DIST_LABEL_CCOMP) or the nearest zero pixel (labelType==DIST_LABEL_PIXEL). Index of the
+component/pixel is stored in `labels(x, y)`. When labelType==DIST_LABEL_CCOMP, the function
+automatically finds connected components of zero pixels in the input image and marks them with
+distinct labels. When labelType==DIST_LABEL_CCOMP, the function scans through the input image and
+marks all the zero pixels with distinct labels.
+
+In this mode, the complexity is still linear. That is, the function provides a very fast way to
+compute the Voronoi diagram for a binary image. Currently, the second variant can use only the
+approximate distance transform algorithm, i.e. maskSize=DIST_MASK_PRECISE is not supported
+yet.
+
+@param src 8-bit, single-channel (binary) source image.
+@param dst Output image with calculated distances. It is a 8-bit or 32-bit floating-point,
+single-channel image of the same size as src.
+@param labels Output 2D array of labels (the discrete Voronoi diagram). It has the type
+CV_32SC1 and the same size as src.
+@param distanceType Type of distance, see cv::DistanceTypes
+@param maskSize Size of the distance transform mask, see cv::DistanceTransformMasks.
+DIST_MASK_PRECISE is not supported by this variant. In case of the DIST_L1 or DIST_C distance type,
+the parameter is forced to 3 because a \f$3\times 3\f$ mask gives the same result as \f$5\times
+5\f$ or any larger aperture.
+@param labelType Type of the label array to build, see cv::DistanceTransformLabelTypes.
+ */
+CV_EXPORTS_AS(distanceTransformWithLabels) void distanceTransform( InputArray src, OutputArray dst,
+ OutputArray labels, int distanceType, int maskSize,
+ int labelType = DIST_LABEL_CCOMP );
+
+/** @overload
+@param src 8-bit, single-channel (binary) source image.
+@param dst Output image with calculated distances. It is a 8-bit or 32-bit floating-point,
+single-channel image of the same size as src .
+@param distanceType Type of distance, see cv::DistanceTypes
+@param maskSize Size of the distance transform mask, see cv::DistanceTransformMasks. In case of the
+DIST_L1 or DIST_C distance type, the parameter is forced to 3 because a \f$3\times 3\f$ mask gives
+the same result as \f$5\times 5\f$ or any larger aperture.
+@param dstType Type of output image. It can be CV_8U or CV_32F. Type CV_8U can be used only for
+the first variant of the function and distanceType == DIST_L1.
+*/
+CV_EXPORTS_W void distanceTransform( InputArray src, OutputArray dst,
+ int distanceType, int maskSize, int dstType=CV_32F);
+
+/** @example ffilldemo.cpp
+ An example using the FloodFill technique
+*/
+
+/** @overload
+
+variant without `mask` parameter
+*/
+CV_EXPORTS int floodFill( InputOutputArray image,
+ Point seedPoint, Scalar newVal, CV_OUT Rect* rect = 0,
+ Scalar loDiff = Scalar(), Scalar upDiff = Scalar(),
+ int flags = 4 );
+
+/** @brief Fills a connected component with the given color.
+
+The function cv::floodFill fills a connected component starting from the seed point with the specified
+color. The connectivity is determined by the color/brightness closeness of the neighbor pixels. The
+pixel at \f$(x,y)\f$ is considered to belong to the repainted domain if:
+
+- in case of a grayscale image and floating range
+\f[\texttt{src} (x',y')- \texttt{loDiff} \leq \texttt{src} (x,y) \leq \texttt{src} (x',y')+ \texttt{upDiff}\f]
+
+
+- in case of a grayscale image and fixed range
+\f[\texttt{src} ( \texttt{seedPoint} .x, \texttt{seedPoint} .y)- \texttt{loDiff} \leq \texttt{src} (x,y) \leq \texttt{src} ( \texttt{seedPoint} .x, \texttt{seedPoint} .y)+ \texttt{upDiff}\f]
+
+
+- in case of a color image and floating range
+\f[\texttt{src} (x',y')_r- \texttt{loDiff} _r \leq \texttt{src} (x,y)_r \leq \texttt{src} (x',y')_r+ \texttt{upDiff} _r,\f]
+\f[\texttt{src} (x',y')_g- \texttt{loDiff} _g \leq \texttt{src} (x,y)_g \leq \texttt{src} (x',y')_g+ \texttt{upDiff} _g\f]
+and
+\f[\texttt{src} (x',y')_b- \texttt{loDiff} _b \leq \texttt{src} (x,y)_b \leq \texttt{src} (x',y')_b+ \texttt{upDiff} _b\f]
+
+
+- in case of a color image and fixed range
+\f[\texttt{src} ( \texttt{seedPoint} .x, \texttt{seedPoint} .y)_r- \texttt{loDiff} _r \leq \texttt{src} (x,y)_r \leq \texttt{src} ( \texttt{seedPoint} .x, \texttt{seedPoint} .y)_r+ \texttt{upDiff} _r,\f]
+\f[\texttt{src} ( \texttt{seedPoint} .x, \texttt{seedPoint} .y)_g- \texttt{loDiff} _g \leq \texttt{src} (x,y)_g \leq \texttt{src} ( \texttt{seedPoint} .x, \texttt{seedPoint} .y)_g+ \texttt{upDiff} _g\f]
+and
+\f[\texttt{src} ( \texttt{seedPoint} .x, \texttt{seedPoint} .y)_b- \texttt{loDiff} _b \leq \texttt{src} (x,y)_b \leq \texttt{src} ( \texttt{seedPoint} .x, \texttt{seedPoint} .y)_b+ \texttt{upDiff} _b\f]
+
+
+where \f$src(x',y')\f$ is the value of one of pixel neighbors that is already known to belong to the
+component. That is, to be added to the connected component, a color/brightness of the pixel should
+be close enough to:
+- Color/brightness of one of its neighbors that already belong to the connected component in case
+of a floating range.
+- Color/brightness of the seed point in case of a fixed range.
+
+Use these functions to either mark a connected component with the specified color in-place, or build
+a mask and then extract the contour, or copy the region to another image, and so on.
+
+@param image Input/output 1- or 3-channel, 8-bit, or floating-point image. It is modified by the
+function unless the FLOODFILL_MASK_ONLY flag is set in the second variant of the function. See
+the details below.
+@param mask Operation mask that should be a single-channel 8-bit image, 2 pixels wider and 2 pixels
+taller than image. Since this is both an input and output parameter, you must take responsibility
+of initializing it. Flood-filling cannot go across non-zero pixels in the input mask. For example,
+an edge detector output can be used as a mask to stop filling at edges. On output, pixels in the
+mask corresponding to filled pixels in the image are set to 1 or to the a value specified in flags
+as described below. It is therefore possible to use the same mask in multiple calls to the function
+to make sure the filled areas do not overlap.
+@param seedPoint Starting point.
+@param newVal New value of the repainted domain pixels.
+@param loDiff Maximal lower brightness/color difference between the currently observed pixel and
+one of its neighbors belonging to the component, or a seed pixel being added to the component.
+@param upDiff Maximal upper brightness/color difference between the currently observed pixel and
+one of its neighbors belonging to the component, or a seed pixel being added to the component.
+@param rect Optional output parameter set by the function to the minimum bounding rectangle of the
+repainted domain.
+@param flags Operation flags. The first 8 bits contain a connectivity value. The default value of
+4 means that only the four nearest neighbor pixels (those that share an edge) are considered. A
+connectivity value of 8 means that the eight nearest neighbor pixels (those that share a corner)
+will be considered. The next 8 bits (8-16) contain a value between 1 and 255 with which to fill
+the mask (the default value is 1). For example, 4 | ( 255 \<\< 8 ) will consider 4 nearest
+neighbours and fill the mask with a value of 255. The following additional options occupy higher
+bits and therefore may be further combined with the connectivity and mask fill values using
+bit-wise or (|), see cv::FloodFillFlags.
+
+@note Since the mask is larger than the filled image, a pixel \f$(x, y)\f$ in image corresponds to the
+pixel \f$(x+1, y+1)\f$ in the mask .
+
+@sa findContours
+ */
+CV_EXPORTS_W int floodFill( InputOutputArray image, InputOutputArray mask,
+ Point seedPoint, Scalar newVal, CV_OUT Rect* rect=0,
+ Scalar loDiff = Scalar(), Scalar upDiff = Scalar(),
+ int flags = 4 );
+
+/** @brief Converts an image from one color space to another.
+
+The function converts an input image from one color space to another. In case of a transformation
+to-from RGB color space, the order of the channels should be specified explicitly (RGB or BGR). Note
+that the default color format in OpenCV is often referred to as RGB but it is actually BGR (the
+bytes are reversed). So the first byte in a standard (24-bit) color image will be an 8-bit Blue
+component, the second byte will be Green, and the third byte will be Red. The fourth, fifth, and
+sixth bytes would then be the second pixel (Blue, then Green, then Red), and so on.
+
+The conventional ranges for R, G, and B channel values are:
+- 0 to 255 for CV_8U images
+- 0 to 65535 for CV_16U images
+- 0 to 1 for CV_32F images
+
+In case of linear transformations, the range does not matter. But in case of a non-linear
+transformation, an input RGB image should be normalized to the proper value range to get the correct
+results, for example, for RGB \f$\rightarrow\f$ L\*u\*v\* transformation. For example, if you have a
+32-bit floating-point image directly converted from an 8-bit image without any scaling, then it will
+have the 0..255 value range instead of 0..1 assumed by the function. So, before calling cvtColor ,
+you need first to scale the image down:
+@code
+ img *= 1./255;
+ cvtColor(img, img, COLOR_BGR2Luv);
+@endcode
+If you use cvtColor with 8-bit images, the conversion will have some information lost. For many
+applications, this will not be noticeable but it is recommended to use 32-bit images in applications
+that need the full range of colors or that convert an image before an operation and then convert
+back.
+
+If conversion adds the alpha channel, its value will set to the maximum of corresponding channel
+range: 255 for CV_8U, 65535 for CV_16U, 1 for CV_32F.
+
+@param src input image: 8-bit unsigned, 16-bit unsigned ( CV_16UC... ), or single-precision
+floating-point.
+@param dst output image of the same size and depth as src.
+@param code color space conversion code (see cv::ColorConversionCodes).
+@param dstCn number of channels in the destination image; if the parameter is 0, the number of the
+channels is derived automatically from src and code.
+
+@see @ref imgproc_color_conversions
+ */
+CV_EXPORTS_W void cvtColor( InputArray src, OutputArray dst, int code, int dstCn = 0 );
+
+//! @} imgproc_misc
+
+// main function for all demosaicing procceses
+CV_EXPORTS_W void demosaicing(InputArray _src, OutputArray _dst, int code, int dcn = 0);
+
+//! @addtogroup imgproc_shape
+//! @{
+
+/** @brief Calculates all of the moments up to the third order of a polygon or rasterized shape.
+
+The function computes moments, up to the 3rd order, of a vector shape or a rasterized shape. The
+results are returned in the structure cv::Moments.
+
+@param array Raster image (single-channel, 8-bit or floating-point 2D array) or an array (
+\f$1 \times N\f$ or \f$N \times 1\f$ ) of 2D points (Point or Point2f ).
+@param binaryImage If it is true, all non-zero image pixels are treated as 1's. The parameter is
+used for images only.
+@returns moments.
+
+@note Only applicable to contour moments calculations from Python bindings: Note that the numpy
+type for the input array should be either np.int32 or np.float32.
+
+@sa contourArea, arcLength
+ */
+CV_EXPORTS_W Moments moments( InputArray array, bool binaryImage = false );
+
+/** @brief Calculates seven Hu invariants.
+
+The function calculates seven Hu invariants (introduced in @cite Hu62; see also
+<http://en.wikipedia.org/wiki/Image_moment>) defined as:
+
+\f[\begin{array}{l} hu[0]= \eta _{20}+ \eta _{02} \\ hu[1]=( \eta _{20}- \eta _{02})^{2}+4 \eta _{11}^{2} \\ hu[2]=( \eta _{30}-3 \eta _{12})^{2}+ (3 \eta _{21}- \eta _{03})^{2} \\ hu[3]=( \eta _{30}+ \eta _{12})^{2}+ ( \eta _{21}+ \eta _{03})^{2} \\ hu[4]=( \eta _{30}-3 \eta _{12})( \eta _{30}+ \eta _{12})[( \eta _{30}+ \eta _{12})^{2}-3( \eta _{21}+ \eta _{03})^{2}]+(3 \eta _{21}- \eta _{03})( \eta _{21}+ \eta _{03})[3( \eta _{30}+ \eta _{12})^{2}-( \eta _{21}+ \eta _{03})^{2}] \\ hu[5]=( \eta _{20}- \eta _{02})[( \eta _{30}+ \eta _{12})^{2}- ( \eta _{21}+ \eta _{03})^{2}]+4 \eta _{11}( \eta _{30}+ \eta _{12})( \eta _{21}+ \eta _{03}) \\ hu[6]=(3 \eta _{21}- \eta _{03})( \eta _{21}+ \eta _{03})[3( \eta _{30}+ \eta _{12})^{2}-( \eta _{21}+ \eta _{03})^{2}]-( \eta _{30}-3 \eta _{12})( \eta _{21}+ \eta _{03})[3( \eta _{30}+ \eta _{12})^{2}-( \eta _{21}+ \eta _{03})^{2}] \\ \end{array}\f]
+
+where \f$\eta_{ji}\f$ stands for \f$\texttt{Moments::nu}_{ji}\f$ .
+
+These values are proved to be invariants to the image scale, rotation, and reflection except the
+seventh one, whose sign is changed by reflection. This invariance is proved with the assumption of
+infinite image resolution. In case of raster images, the computed Hu invariants for the original and
+transformed images are a bit different.
+
+@param moments Input moments computed with moments .
+@param hu Output Hu invariants.
+
+@sa matchShapes
+ */
+CV_EXPORTS void HuMoments( const Moments& moments, double hu[7] );
+
+/** @overload */
+CV_EXPORTS_W void HuMoments( const Moments& m, OutputArray hu );
+
+//! @} imgproc_shape
+
+//! @addtogroup imgproc_object
+//! @{
+
+//! type of the template matching operation
+enum TemplateMatchModes {
+ TM_SQDIFF = 0, //!< \f[R(x,y)= \sum _{x',y'} (T(x',y')-I(x+x',y+y'))^2\f]
+ TM_SQDIFF_NORMED = 1, //!< \f[R(x,y)= \frac{\sum_{x',y'} (T(x',y')-I(x+x',y+y'))^2}{\sqrt{\sum_{x',y'}T(x',y')^2 \cdot \sum_{x',y'} I(x+x',y+y')^2}}\f]
+ TM_CCORR = 2, //!< \f[R(x,y)= \sum _{x',y'} (T(x',y') \cdot I(x+x',y+y'))\f]
+ TM_CCORR_NORMED = 3, //!< \f[R(x,y)= \frac{\sum_{x',y'} (T(x',y') \cdot I(x+x',y+y'))}{\sqrt{\sum_{x',y'}T(x',y')^2 \cdot \sum_{x',y'} I(x+x',y+y')^2}}\f]
+ TM_CCOEFF = 4, //!< \f[R(x,y)= \sum _{x',y'} (T'(x',y') \cdot I'(x+x',y+y'))\f]
+ //!< where
+ //!< \f[\begin{array}{l} T'(x',y')=T(x',y') - 1/(w \cdot h) \cdot \sum _{x'',y''} T(x'',y'') \\ I'(x+x',y+y')=I(x+x',y+y') - 1/(w \cdot h) \cdot \sum _{x'',y''} I(x+x'',y+y'') \end{array}\f]
+ TM_CCOEFF_NORMED = 5 //!< \f[R(x,y)= \frac{ \sum_{x',y'} (T'(x',y') \cdot I'(x+x',y+y')) }{ \sqrt{\sum_{x',y'}T'(x',y')^2 \cdot \sum_{x',y'} I'(x+x',y+y')^2} }\f]
+};
+
+/** @brief Compares a template against overlapped image regions.
+
+The function slides through image , compares the overlapped patches of size \f$w \times h\f$ against
+templ using the specified method and stores the comparison results in result . Here are the formulae
+for the available comparison methods ( \f$I\f$ denotes image, \f$T\f$ template, \f$R\f$ result ). The summation
+is done over template and/or the image patch: \f$x' = 0...w-1, y' = 0...h-1\f$
+
+After the function finishes the comparison, the best matches can be found as global minimums (when
+TM_SQDIFF was used) or maximums (when TM_CCORR or TM_CCOEFF was used) using the
+minMaxLoc function. In case of a color image, template summation in the numerator and each sum in
+the denominator is done over all of the channels and separate mean values are used for each channel.
+That is, the function can take a color template and a color image. The result will still be a
+single-channel image, which is easier to analyze.
+
+@param image Image where the search is running. It must be 8-bit or 32-bit floating-point.
+@param templ Searched template. It must be not greater than the source image and have the same
+data type.
+@param result Map of comparison results. It must be single-channel 32-bit floating-point. If image
+is \f$W \times H\f$ and templ is \f$w \times h\f$ , then result is \f$(W-w+1) \times (H-h+1)\f$ .
+@param method Parameter specifying the comparison method, see cv::TemplateMatchModes
+@param mask Mask of searched template. It must have the same datatype and size with templ. It is
+not set by default.
+ */
+CV_EXPORTS_W void matchTemplate( InputArray image, InputArray templ,
+ OutputArray result, int method, InputArray mask = noArray() );
+
+//! @}
+
+//! @addtogroup imgproc_shape
+//! @{
+
+/** @brief computes the connected components labeled image of boolean image
+
+image with 4 or 8 way connectivity - returns N, the total number of labels [0, N-1] where 0
+represents the background label. ltype specifies the output label image type, an important
+consideration based on the total number of labels or alternatively the total number of pixels in
+the source image. ccltype specifies the connected components labeling algorithm to use, currently
+Grana's (BBDT) and Wu's (SAUF) algorithms are supported, see the cv::ConnectedComponentsAlgorithmsTypes
+for details. Note that SAUF algorithm forces a row major ordering of labels while BBDT does not.
+
+@param image the 8-bit single-channel image to be labeled
+@param labels destination labeled image
+@param connectivity 8 or 4 for 8-way or 4-way connectivity respectively
+@param ltype output image label type. Currently CV_32S and CV_16U are supported.
+@param ccltype connected components algorithm type (see the cv::ConnectedComponentsAlgorithmsTypes).
+*/
+CV_EXPORTS_AS(connectedComponentsWithAlgorithm) int connectedComponents(InputArray image, OutputArray labels,
+ int connectivity, int ltype, int ccltype);
+
+
+/** @overload
+
+@param image the 8-bit single-channel image to be labeled
+@param labels destination labeled image
+@param connectivity 8 or 4 for 8-way or 4-way connectivity respectively
+@param ltype output image label type. Currently CV_32S and CV_16U are supported.
+*/
+CV_EXPORTS_W int connectedComponents(InputArray image, OutputArray labels,
+ int connectivity = 8, int ltype = CV_32S);
+
+
+/** @brief computes the connected components labeled image of boolean image and also produces a statistics output for each label
+
+image with 4 or 8 way connectivity - returns N, the total number of labels [0, N-1] where 0
+represents the background label. ltype specifies the output label image type, an important
+consideration based on the total number of labels or alternatively the total number of pixels in
+the source image. ccltype specifies the connected components labeling algorithm to use, currently
+Grana's (BBDT) and Wu's (SAUF) algorithms are supported, see the cv::ConnectedComponentsAlgorithmsTypes
+for details. Note that SAUF algorithm forces a row major ordering of labels while BBDT does not.
+
+
+@param image the 8-bit single-channel image to be labeled
+@param labels destination labeled image
+@param stats statistics output for each label, including the background label, see below for
+available statistics. Statistics are accessed via stats(label, COLUMN) where COLUMN is one of
+cv::ConnectedComponentsTypes. The data type is CV_32S.
+@param centroids centroid output for each label, including the background label. Centroids are
+accessed via centroids(label, 0) for x and centroids(label, 1) for y. The data type CV_64F.
+@param connectivity 8 or 4 for 8-way or 4-way connectivity respectively
+@param ltype output image label type. Currently CV_32S and CV_16U are supported.
+@param ccltype connected components algorithm type (see the cv::ConnectedComponentsAlgorithmsTypes).
+*/
+CV_EXPORTS_AS(connectedComponentsWithStatsWithAlgorithm) int connectedComponentsWithStats(InputArray image, OutputArray labels,
+ OutputArray stats, OutputArray centroids,
+ int connectivity, int ltype, int ccltype);
+
+/** @overload
+@param image the 8-bit single-channel image to be labeled
+@param labels destination labeled image
+@param stats statistics output for each label, including the background label, see below for
+available statistics. Statistics are accessed via stats(label, COLUMN) where COLUMN is one of
+cv::ConnectedComponentsTypes. The data type is CV_32S.
+@param centroids centroid output for each label, including the background label. Centroids are
+accessed via centroids(label, 0) for x and centroids(label, 1) for y. The data type CV_64F.
+@param connectivity 8 or 4 for 8-way or 4-way connectivity respectively
+@param ltype output image label type. Currently CV_32S and CV_16U are supported.
+*/
+CV_EXPORTS_W int connectedComponentsWithStats(InputArray image, OutputArray labels,
+ OutputArray stats, OutputArray centroids,
+ int connectivity = 8, int ltype = CV_32S);
+
+
+/** @brief Finds contours in a binary image.
+
+The function retrieves contours from the binary image using the algorithm @cite Suzuki85 . The contours
+are a useful tool for shape analysis and object detection and recognition. See squares.cpp in the
+OpenCV sample directory.
+
+@param image Source, an 8-bit single-channel image. Non-zero pixels are treated as 1's. Zero
+pixels remain 0's, so the image is treated as binary . You can use cv::compare, cv::inRange, cv::threshold ,
+cv::adaptiveThreshold, cv::Canny, and others to create a binary image out of a grayscale or color one.
+If mode equals to cv::RETR_CCOMP or cv::RETR_FLOODFILL, the input can also be a 32-bit integer image of labels (CV_32SC1).
+@param contours Detected contours. Each contour is stored as a vector of points (e.g.
+std::vector<std::vector<cv::Point> >).
+@param hierarchy Optional output vector (e.g. std::vector<cv::Vec4i>), containing information about the image topology. It has
+as many elements as the number of contours. For each i-th contour contours[i], the elements
+hierarchy[i][0] , hiearchy[i][1] , hiearchy[i][2] , and hiearchy[i][3] are set to 0-based indices
+in contours of the next and previous contours at the same hierarchical level, the first child
+contour and the parent contour, respectively. If for the contour i there are no next, previous,
+parent, or nested contours, the corresponding elements of hierarchy[i] will be negative.
+@param mode Contour retrieval mode, see cv::RetrievalModes
+@param method Contour approximation method, see cv::ContourApproximationModes
+@param offset Optional offset by which every contour point is shifted. This is useful if the
+contours are extracted from the image ROI and then they should be analyzed in the whole image
+context.
+ */
+CV_EXPORTS_W void findContours( InputOutputArray image, OutputArrayOfArrays contours,
+ OutputArray hierarchy, int mode,
+ int method, Point offset = Point());
+
+/** @overload */
+CV_EXPORTS void findContours( InputOutputArray image, OutputArrayOfArrays contours,
+ int mode, int method, Point offset = Point());
+
+/** @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 <http://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 Calculates a contour perimeter or a curve length.
+
+The function computes a curve length or a closed contour perimeter.
+
+@param curve Input vector of 2D points, stored in std::vector or Mat.
+@param closed Flag indicating whether the curve is closed or not.
+ */
+CV_EXPORTS_W double arcLength( InputArray curve, bool closed );
+
+/** @brief Calculates the up-right bounding rectangle of a point set.
+
+The function calculates and returns the minimal up-right bounding rectangle for the specified point set.
+
+@param points Input 2D point set, stored in std::vector or Mat.
+ */
+CV_EXPORTS_W Rect boundingRect( InputArray points );
+
+/** @brief Calculates a contour area.
+
+The function computes a contour area. Similarly to moments , the area is computed using the Green
+formula. Thus, the returned area and the number of non-zero pixels, if you draw the contour using
+drawContours or fillPoly , can be different. Also, the function will most certainly give a wrong
+results for contours with self-intersections.
+
+Example:
+@code
+ vector<Point> contour;
+ contour.push_back(Point2f(0, 0));
+ contour.push_back(Point2f(10, 0));
+ contour.push_back(Point2f(10, 10));
+ contour.push_back(Point2f(5, 4));
+
+ double area0 = contourArea(contour);
+ vector<Point> approx;
+ approxPolyDP(contour, approx, 5, true);
+ double area1 = contourArea(approx);
+
+ cout << "area0 =" << area0 << endl <<
+ "area1 =" << area1 << endl <<
+ "approx poly vertices" << approx.size() << endl;
+@endcode
+@param contour Input vector of 2D points (contour vertices), stored in std::vector or Mat.
+@param oriented Oriented area flag. If it is true, the function returns a signed area value,
+depending on the contour orientation (clockwise or counter-clockwise). Using this feature you can
+determine orientation of a contour by taking the sign of an area. By default, the parameter is
+false, which means that the absolute value is returned.
+ */
+CV_EXPORTS_W double contourArea( InputArray contour, bool oriented = false );
+
+/** @brief 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. See the OpenCV sample minarea.cpp . 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. This function is useful to draw the
+rectangle. In C++, instead of using this function, you can directly use box.points() method. Please
+visit the [tutorial on bounding
+rectangle](http://docs.opencv.org/doc/tutorials/imgproc/shapedescriptors/bounding_rects_circles/bounding_rects_circles.html#bounding-rects-circles)
+for more information.
+
+@param box The input rotated rectangle. It may be the output of
+@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. See
+the OpenCV sample minarea.cpp .
+
+@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 );
+
+/** @example minarea.cpp
+ */
+
+/** @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 Compares two shapes.
+
+The function compares two shapes. All three implemented methods use the Hu invariants (see cv::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 convexhull.cpp
+An example using the convexHull functionality
+*/
+
+/** @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. See the OpenCV sample convexhull.cpp
+that demonstrates the usage of different function variants.
+
+@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.
+ */
+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. cv::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 );
+
+//! finds intersection of two convex polygons
+CV_EXPORTS_W float intersectConvexConvex( InputArray _p1, InputArray _p2,
+ OutputArray _p12, bool handleNested = true );
+
+/** @example fitellipse.cpp
+ An example using the fitEllipse technique
+*/
+
+/** @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
+ */
+CV_EXPORTS_W RotatedRect fitEllipse( InputArray points );
+
+/** @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 ( <http://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 cv::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 interesecting 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 verticies 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 cv::RectanglesIntersectTypes
+ */
+CV_EXPORTS_W int rotatedRectangleIntersection( const RotatedRect& rect1, const RotatedRect& rect2, OutputArray intersectingRegion );
+
+//! @} imgproc_shape
+
+CV_EXPORTS_W Ptr<CLAHE> createCLAHE(double clipLimit = 40.0, Size tileGridSize = Size(8, 8));
+
+//! Ballard, D.H. (1981). Generalizing the Hough transform to detect arbitrary shapes. Pattern Recognition 13 (2): 111-122.
+//! Detects position only without traslation and rotation
+CV_EXPORTS Ptr<GeneralizedHoughBallard> createGeneralizedHoughBallard();
+
+//! Guil, N., González-Linares, J.M. and Zapata, E.L. (1999). Bidimensional shape detection using an invariant approach. Pattern Recognition 32 (6): 1025-1038.
+//! Detects position, traslation and rotation
+CV_EXPORTS Ptr<GeneralizedHoughGuil> createGeneralizedHoughGuil();
+
+//! Performs linear blending of two images
+CV_EXPORTS void blendLinear(InputArray src1, InputArray src2, InputArray weights1, InputArray weights2, OutputArray dst);
+
+//! @addtogroup imgproc_colormap
+//! @{
+
+//! GNU Octave/MATLAB equivalent colormaps
+enum ColormapTypes
+{
+ COLORMAP_AUTUMN = 0, //!< 
+ COLORMAP_BONE = 1, //!< 
+ COLORMAP_JET = 2, //!< 
+ COLORMAP_WINTER = 3, //!< 
+ COLORMAP_RAINBOW = 4, //!< 
+ COLORMAP_OCEAN = 5, //!< 
+ COLORMAP_SUMMER = 6, //!< 
+ COLORMAP_SPRING = 7, //!< 
+ COLORMAP_COOL = 8, //!< 
+ COLORMAP_HSV = 9, //!< 
+ COLORMAP_PINK = 10, //!< 
+ COLORMAP_HOT = 11, //!< 
+ COLORMAP_PARULA = 12 //!< 
+};
+
+/** @brief Applies a GNU Octave/MATLAB equivalent colormap on a given image.
+
+@param src The source image, grayscale or colored of type CV_8UC1 or CV_8UC3.
+@param dst The result is the colormapped source image. Note: Mat::create is called on dst.
+@param colormap The colormap to apply, see cv::ColormapTypes
+ */
+CV_EXPORTS_W void applyColorMap(InputArray src, OutputArray dst, int colormap);
+
+//! @} imgproc_colormap
+
+//! @addtogroup imgproc_draw
+//! @{
+
+/** @brief Draws a line segment connecting two points.
+
+The function line draws the line segment between pt1 and pt2 points in the image. The line is
+clipped by the image boundaries. For non-antialiased lines with integer coordinates, the 8-connected
+or 4-connected Bresenham algorithm is used. Thick lines are drawn with rounding endings. Antialiased
+lines are drawn using Gaussian filtering.
+
+@param img Image.
+@param pt1 First point of the line segment.
+@param pt2 Second point of the line segment.
+@param color Line color.
+@param thickness Line thickness.
+@param lineType Type of the line, see cv::LineTypes.
+@param shift Number of fractional bits in the point coordinates.
+ */
+CV_EXPORTS_W void line(InputOutputArray img, Point pt1, Point pt2, const Scalar& color,
+ int thickness = 1, int lineType = LINE_8, int shift = 0);
+
+/** @brief Draws a arrow segment pointing from the first point to the second one.
+
+The function arrowedLine draws an arrow between pt1 and pt2 points in the image. See also cv::line.
+
+@param img Image.
+@param pt1 The point the arrow starts from.
+@param pt2 The point the arrow points to.
+@param color Line color.
+@param thickness Line thickness.
+@param line_type Type of the line, see cv::LineTypes
+@param shift Number of fractional bits in the point coordinates.
+@param tipLength The length of the arrow tip in relation to the arrow length
+ */
+CV_EXPORTS_W void arrowedLine(InputOutputArray img, Point pt1, Point pt2, const Scalar& color,
+ int thickness=1, int line_type=8, int shift=0, double tipLength=0.1);
+
+/** @brief Draws a simple, thick, or filled up-right rectangle.
+
+The function rectangle draws a rectangle outline or a filled rectangle whose two opposite corners
+are pt1 and pt2.
+
+@param img Image.
+@param pt1 Vertex of the rectangle.
+@param pt2 Vertex of the rectangle opposite to pt1 .
+@param color Rectangle color or brightness (grayscale image).
+@param thickness Thickness of lines that make up the rectangle. Negative values, like CV_FILLED ,
+mean that the function has to draw a filled rectangle.
+@param lineType Type of the line. See the line description.
+@param shift Number of fractional bits in the point coordinates.
+ */
+CV_EXPORTS_W void rectangle(InputOutputArray img, Point pt1, Point pt2,
+ const Scalar& color, int thickness = 1,
+ int lineType = LINE_8, int shift = 0);
+
+/** @overload
+
+use `rec` parameter as alternative specification of the drawn rectangle: `r.tl() and
+r.br()-Point(1,1)` are opposite corners
+*/
+CV_EXPORTS void rectangle(CV_IN_OUT Mat& img, Rect rec,
+ const Scalar& color, int thickness = 1,
+ int lineType = LINE_8, int shift = 0);
+
+/** @brief Draws a circle.
+
+The function circle draws a simple or filled circle with a given center and radius.
+@param img Image where the circle is drawn.
+@param center Center of the circle.
+@param radius Radius of the circle.
+@param color Circle color.
+@param thickness Thickness of the circle outline, if positive. Negative thickness means that a
+filled circle is to be drawn.
+@param lineType Type of the circle boundary. See the line description.
+@param shift Number of fractional bits in the coordinates of the center and in the radius value.
+ */
+CV_EXPORTS_W void circle(InputOutputArray img, Point center, int radius,
+ const Scalar& color, int thickness = 1,
+ int lineType = LINE_8, int shift = 0);
+
+/** @brief Draws a simple or thick elliptic arc or fills an ellipse sector.
+
+The function cv::ellipse with less parameters draws an ellipse outline, a filled ellipse, an elliptic
+arc, or a filled ellipse sector. A piecewise-linear curve is used to approximate the elliptic arc
+boundary. If you need more control of the ellipse rendering, you can retrieve the curve using
+ellipse2Poly and then render it with polylines or fill it with fillPoly . If you use the first
+variant of the function and want to draw the whole ellipse, not an arc, pass startAngle=0 and
+endAngle=360 . The figure below explains the meaning of the parameters.
+
+
+
+@param img Image.
+@param center Center of the ellipse.
+@param axes Half of the size of the ellipse main axes.
+@param angle Ellipse rotation angle in degrees.
+@param startAngle Starting angle of the elliptic arc in degrees.
+@param endAngle Ending angle of the elliptic arc in degrees.
+@param color Ellipse color.
+@param thickness Thickness of the ellipse arc outline, if positive. Otherwise, this indicates that
+a filled ellipse sector is to be drawn.
+@param lineType Type of the ellipse boundary. See the line description.
+@param shift Number of fractional bits in the coordinates of the center and values of axes.
+ */
+CV_EXPORTS_W void ellipse(InputOutputArray img, Point center, Size axes,
+ double angle, double startAngle, double endAngle,
+ const Scalar& color, int thickness = 1,
+ int lineType = LINE_8, int shift = 0);
+
+/** @overload
+@param img Image.
+@param box Alternative ellipse representation via RotatedRect. This means that the function draws
+an ellipse inscribed in the rotated rectangle.
+@param color Ellipse color.
+@param thickness Thickness of the ellipse arc outline, if positive. Otherwise, this indicates that
+a filled ellipse sector is to be drawn.
+@param lineType Type of the ellipse boundary. See the line description.
+*/
+CV_EXPORTS_W void ellipse(InputOutputArray img, const RotatedRect& box, const Scalar& color,
+ int thickness = 1, int lineType = LINE_8);
+
+/* ----------------------------------------------------------------------------------------- */
+/* ADDING A SET OF PREDEFINED MARKERS WHICH COULD BE USED TO HIGHLIGHT POSITIONS IN AN IMAGE */
+/* ----------------------------------------------------------------------------------------- */
+
+//! Possible set of marker types used for the cv::drawMarker function
+enum MarkerTypes
+{
+ MARKER_CROSS = 0, //!< A crosshair marker shape
+ MARKER_TILTED_CROSS = 1, //!< A 45 degree tilted crosshair marker shape
+ MARKER_STAR = 2, //!< A star marker shape, combination of cross and tilted cross
+ MARKER_DIAMOND = 3, //!< A diamond marker shape
+ MARKER_SQUARE = 4, //!< A square marker shape
+ MARKER_TRIANGLE_UP = 5, //!< An upwards pointing triangle marker shape
+ MARKER_TRIANGLE_DOWN = 6 //!< A downwards pointing triangle marker shape
+};
+
+/** @brief Draws a marker on a predefined position in an image.
+
+The function drawMarker draws a marker on a given position in the image. For the moment several
+marker types are supported, see cv::MarkerTypes for more information.
+
+@param img Image.
+@param position The point where the crosshair is positioned.
+@param color Line color.
+@param markerType The specific type of marker you want to use, see cv::MarkerTypes
+@param thickness Line thickness.
+@param line_type Type of the line, see cv::LineTypes
+@param markerSize The length of the marker axis [default = 20 pixels]
+ */
+CV_EXPORTS_W void drawMarker(CV_IN_OUT Mat& img, Point position, const Scalar& color,
+ int markerType = MARKER_CROSS, int markerSize=20, int thickness=1,
+ int line_type=8);
+
+/* ----------------------------------------------------------------------------------------- */
+/* END OF MARKER SECTION */
+/* ----------------------------------------------------------------------------------------- */
+
+/** @overload */
+CV_EXPORTS void fillConvexPoly(Mat& img, const Point* pts, int npts,
+ const Scalar& color, int lineType = LINE_8,
+ int shift = 0);
+
+/** @brief Fills a convex polygon.
+
+The function fillConvexPoly draws a filled convex polygon. This function is much faster than the
+function cv::fillPoly . It can fill not only convex polygons but any monotonic polygon without
+self-intersections, that is, a polygon whose contour intersects every horizontal line (scan line)
+twice at the most (though, its top-most and/or the bottom edge could be horizontal).
+
+@param img Image.
+@param points Polygon vertices.
+@param color Polygon color.
+@param lineType Type of the polygon boundaries. See the line description.
+@param shift Number of fractional bits in the vertex coordinates.
+ */
+CV_EXPORTS_W void fillConvexPoly(InputOutputArray img, InputArray points,
+ const Scalar& color, int lineType = LINE_8,
+ int shift = 0);
+
+/** @overload */
+CV_EXPORTS void fillPoly(Mat& img, const Point** pts,
+ const int* npts, int ncontours,
+ const Scalar& color, int lineType = LINE_8, int shift = 0,
+ Point offset = Point() );
+
+/** @brief Fills the area bounded by one or more polygons.
+
+The function fillPoly fills an area bounded by several polygonal contours. The function can fill
+complex areas, for example, areas with holes, contours with self-intersections (some of their
+parts), and so forth.
+
+@param img Image.
+@param pts Array of polygons where each polygon is represented as an array of points.
+@param color Polygon color.
+@param lineType Type of the polygon boundaries. See the line description.
+@param shift Number of fractional bits in the vertex coordinates.
+@param offset Optional offset of all points of the contours.
+ */
+CV_EXPORTS_W void fillPoly(InputOutputArray img, InputArrayOfArrays pts,
+ const Scalar& color, int lineType = LINE_8, int shift = 0,
+ Point offset = Point() );
+
+/** @overload */
+CV_EXPORTS void polylines(Mat& img, const Point* const* pts, const int* npts,
+ int ncontours, bool isClosed, const Scalar& color,
+ int thickness = 1, int lineType = LINE_8, int shift = 0 );
+
+/** @brief Draws several polygonal curves.
+
+@param img Image.
+@param pts Array of polygonal curves.
+@param isClosed Flag indicating whether the drawn polylines are closed or not. If they are closed,
+the function draws a line from the last vertex of each curve to its first vertex.
+@param color Polyline color.
+@param thickness Thickness of the polyline edges.
+@param lineType Type of the line segments. See the line description.
+@param shift Number of fractional bits in the vertex coordinates.
+
+The function polylines draws one or more polygonal curves.
+ */
+CV_EXPORTS_W void polylines(InputOutputArray img, InputArrayOfArrays pts,
+ bool isClosed, const Scalar& color,
+ int thickness = 1, int lineType = LINE_8, int shift = 0 );
+
+/** @example contours2.cpp
+ An example using the drawContour functionality
+*/
+
+/** @example segment_objects.cpp
+An example using drawContours to clean up a background segmentation result
+ */
+
+/** @brief Draws contours outlines or filled contours.
+
+The function draws contour outlines in the image if \f$\texttt{thickness} \ge 0\f$ or fills the area
+bounded by the contours if \f$\texttt{thickness}<0\f$ . The example below shows how to retrieve
+connected components from the binary image and label them: :
+@code
+ #include "opencv2/imgproc.hpp"
+ #include "opencv2/highgui.hpp"
+
+ using namespace cv;
+ using namespace std;
+
+ int main( int argc, char** argv )
+ {
+ Mat src;
+ // the first command-line parameter must be a filename of the binary
+ // (black-n-white) image
+ if( argc != 2 || !(src=imread(argv[1], 0)).data)
+ return -1;
+
+ Mat dst = Mat::zeros(src.rows, src.cols, CV_8UC3);
+
+ src = src > 1;
+ namedWindow( "Source", 1 );
+ imshow( "Source", src );
+
+ vector<vector<Point> > contours;
+ vector<Vec4i> hierarchy;
+
+ findContours( src, contours, hierarchy,
+ RETR_CCOMP, CHAIN_APPROX_SIMPLE );
+
+ // iterate through all the top-level contours,
+ // draw each connected component with its own random color
+ int idx = 0;
+ for( ; idx >= 0; idx = hierarchy[idx][0] )
+ {
+ Scalar color( rand()&255, rand()&255, rand()&255 );
+ drawContours( dst, contours, idx, color, FILLED, 8, hierarchy );
+ }
+
+ namedWindow( "Components", 1 );
+ imshow( "Components", dst );
+ waitKey(0);
+ }
+@endcode
+
+@param image Destination image.
+@param contours All the input contours. Each contour is stored as a point vector.
+@param contourIdx Parameter indicating a contour to draw. If it is negative, all the contours are drawn.
+@param color Color of the contours.
+@param thickness Thickness of lines the contours are drawn with. If it is negative (for example,
+thickness=CV_FILLED ), the contour interiors are drawn.
+@param lineType Line connectivity. See cv::LineTypes.
+@param hierarchy Optional information about hierarchy. It is only needed if you want to draw only
+some of the contours (see maxLevel ).
+@param maxLevel Maximal level for drawn contours. If it is 0, only the specified contour is drawn.
+If it is 1, the function draws the contour(s) and all the nested contours. If it is 2, the function
+draws the contours, all the nested contours, all the nested-to-nested contours, and so on. This
+parameter is only taken into account when there is hierarchy available.
+@param offset Optional contour shift parameter. Shift all the drawn contours by the specified
+\f$\texttt{offset}=(dx,dy)\f$ .
+ */
+CV_EXPORTS_W void drawContours( InputOutputArray image, InputArrayOfArrays contours,
+ int contourIdx, const Scalar& color,
+ int thickness = 1, int lineType = LINE_8,
+ InputArray hierarchy = noArray(),
+ int maxLevel = INT_MAX, Point offset = Point() );
+
+/** @brief Clips the line against the image rectangle.
+
+The function cv::clipLine calculates a part of the line segment that is entirely within the specified
+rectangle. it returns false if the line segment is completely outside the rectangle. Otherwise,
+it returns true .
+@param imgSize Image size. The image rectangle is Rect(0, 0, imgSize.width, imgSize.height) .
+@param pt1 First line point.
+@param pt2 Second line point.
+ */
+CV_EXPORTS bool clipLine(Size imgSize, CV_IN_OUT Point& pt1, CV_IN_OUT Point& pt2);
+
+/** @overload
+@param imgSize Image size. The image rectangle is Rect(0, 0, imgSize.width, imgSize.height) .
+@param pt1 First line point.
+@param pt2 Second line point.
+*/
+CV_EXPORTS bool clipLine(Size2l imgSize, CV_IN_OUT Point2l& pt1, CV_IN_OUT Point2l& pt2);
+
+/** @overload
+@param imgRect Image rectangle.
+@param pt1 First line point.
+@param pt2 Second line point.
+*/
+CV_EXPORTS_W bool clipLine(Rect imgRect, CV_OUT CV_IN_OUT Point& pt1, CV_OUT CV_IN_OUT Point& pt2);
+
+/** @brief Approximates an elliptic arc with a polyline.
+
+The function ellipse2Poly computes the vertices of a polyline that approximates the specified
+elliptic arc. It is used by cv::ellipse.
+
+@param center Center of the arc.
+@param axes Half of the size of the ellipse main axes. See the ellipse for details.
+@param angle Rotation angle of the ellipse in degrees. See the ellipse for details.
+@param arcStart Starting angle of the elliptic arc in degrees.
+@param arcEnd Ending angle of the elliptic arc in degrees.
+@param delta Angle between the subsequent polyline vertices. It defines the approximation
+accuracy.
+@param pts Output vector of polyline vertices.
+ */
+CV_EXPORTS_W void ellipse2Poly( Point center, Size axes, int angle,
+ int arcStart, int arcEnd, int delta,
+ CV_OUT std::vector<Point>& pts );
+
+/** @overload
+@param center Center of the arc.
+@param axes Half of the size of the ellipse main axes. See the ellipse for details.
+@param angle Rotation angle of the ellipse in degrees. See the ellipse for details.
+@param arcStart Starting angle of the elliptic arc in degrees.
+@param arcEnd Ending angle of the elliptic arc in degrees.
+@param delta Angle between the subsequent polyline vertices. It defines the approximation
+accuracy.
+@param pts Output vector of polyline vertices.
+*/
+CV_EXPORTS void ellipse2Poly(Point2d center, Size2d axes, int angle,
+ int arcStart, int arcEnd, int delta,
+ CV_OUT std::vector<Point2d>& pts);
+
+/** @brief Draws a text string.
+
+The function putText renders the specified text string in the image. Symbols that cannot be rendered
+using the specified font are replaced by question marks. See getTextSize for a text rendering code
+example.
+
+@param img Image.
+@param text Text string to be drawn.
+@param org Bottom-left corner of the text string in the image.
+@param fontFace Font type, see cv::HersheyFonts.
+@param fontScale Font scale factor that is multiplied by the font-specific base size.
+@param color Text color.
+@param thickness Thickness of the lines used to draw a text.
+@param lineType Line type. See the line for details.
+@param bottomLeftOrigin When true, the image data origin is at the bottom-left corner. Otherwise,
+it is at the top-left corner.
+ */
+CV_EXPORTS_W void putText( InputOutputArray img, const String& text, Point org,
+ int fontFace, double fontScale, Scalar color,
+ int thickness = 1, int lineType = LINE_8,
+ bool bottomLeftOrigin = false );
+
+/** @brief Calculates the width and height of a text string.
+
+The function getTextSize calculates and returns the size of a box that contains the specified text.
+That is, the following code renders some text, the tight box surrounding it, and the baseline: :
+@code
+ String text = "Funny text inside the box";
+ int fontFace = FONT_HERSHEY_SCRIPT_SIMPLEX;
+ double fontScale = 2;
+ int thickness = 3;
+
+ Mat img(600, 800, CV_8UC3, Scalar::all(0));
+
+ int baseline=0;
+ Size textSize = getTextSize(text, fontFace,
+ fontScale, thickness, &baseline);
+ baseline += thickness;
+
+ // center the text
+ Point textOrg((img.cols - textSize.width)/2,
+ (img.rows + textSize.height)/2);
+
+ // draw the box
+ rectangle(img, textOrg + Point(0, baseline),
+ textOrg + Point(textSize.width, -textSize.height),
+ Scalar(0,0,255));
+ // ... and the baseline first
+ line(img, textOrg + Point(0, thickness),
+ textOrg + Point(textSize.width, thickness),
+ Scalar(0, 0, 255));
+
+ // then put the text itself
+ putText(img, text, textOrg, fontFace, fontScale,
+ Scalar::all(255), thickness, 8);
+@endcode
+
+@param text Input text string.
+@param fontFace Font to use, see cv::HersheyFonts.
+@param fontScale Font scale factor that is multiplied by the font-specific base size.
+@param thickness Thickness of lines used to render the text. See putText for details.
+@param[out] baseLine y-coordinate of the baseline relative to the bottom-most text
+point.
+@return The size of a box that contains the specified text.
+
+@see cv::putText
+ */
+CV_EXPORTS_W Size getTextSize(const String& text, int fontFace,
+ double fontScale, int thickness,
+ CV_OUT int* baseLine);
+
+/** @brief Line iterator
+
+The class is used to iterate over all the pixels on the raster line
+segment connecting two specified points.
+
+The class LineIterator is used to get each pixel of a raster line. It
+can be treated as versatile implementation of the Bresenham algorithm
+where you can stop at each pixel and do some extra processing, for
+example, grab pixel values along the line or draw a line with an effect
+(for example, with XOR operation).
+
+The number of pixels along the line is stored in LineIterator::count.
+The method LineIterator::pos returns the current position in the image:
+
+@code{.cpp}
+// grabs pixels along the line (pt1, pt2)
+// from 8-bit 3-channel image to the buffer
+LineIterator it(img, pt1, pt2, 8);
+LineIterator it2 = it;
+vector<Vec3b> buf(it.count);
+
+for(int i = 0; i < it.count; i++, ++it)
+ buf[i] = *(const Vec3b)*it;
+
+// alternative way of iterating through the line
+for(int i = 0; i < it2.count; i++, ++it2)
+{
+ Vec3b val = img.at<Vec3b>(it2.pos());
+ CV_Assert(buf[i] == val);
+}
+@endcode
+*/
+class CV_EXPORTS LineIterator
+{
+public:
+ /** @brief intializes the iterator
+
+ creates iterators for the line connecting pt1 and pt2
+ the line will be clipped on the image boundaries
+ the line is 8-connected or 4-connected
+ If leftToRight=true, then the iteration is always done
+ from the left-most point to the right most,
+ not to depend on the ordering of pt1 and pt2 parameters
+ */
+ LineIterator( const Mat& img, Point pt1, Point pt2,
+ int connectivity = 8, bool leftToRight = false );
+ /** @brief returns pointer to the current pixel
+ */
+ uchar* operator *();
+ /** @brief prefix increment operator (++it). shifts iterator to the next pixel
+ */
+ LineIterator& operator ++();
+ /** @brief postfix increment operator (it++). shifts iterator to the next pixel
+ */
+ LineIterator operator ++(int);
+ /** @brief returns coordinates of the current pixel
+ */
+ Point pos() const;
+
+ uchar* ptr;
+ const uchar* ptr0;
+ int step, elemSize;
+ int err, count;
+ int minusDelta, plusDelta;
+ int minusStep, plusStep;
+};
+
+//! @cond IGNORED
+
+// === LineIterator implementation ===
+
+inline
+uchar* LineIterator::operator *()
+{
+ return ptr;
+}
+
+inline
+LineIterator& LineIterator::operator ++()
+{
+ int mask = err < 0 ? -1 : 0;
+ err += minusDelta + (plusDelta & mask);
+ ptr += minusStep + (plusStep & mask);
+ return *this;
+}
+
+inline
+LineIterator LineIterator::operator ++(int)
+{
+ LineIterator it = *this;
+ ++(*this);
+ return it;
+}
+
+inline
+Point LineIterator::pos() const
+{
+ Point p;
+ p.y = (int)((ptr - ptr0)/step);
+ p.x = (int)(((ptr - ptr0) - p.y*step)/elemSize);
+ return p;
+}
+
+//! @endcond
+
+//! @} imgproc_draw
+
+//! @} imgproc
+
+} // cv
+
+#ifndef DISABLE_OPENCV_24_COMPATIBILITY
+#include "opencv2/imgproc/imgproc_c.h"
+#endif
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/imgproc/detail/distortion_model.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,123 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_IMGPROC_DETAIL_DISTORTION_MODEL_HPP
+#define OPENCV_IMGPROC_DETAIL_DISTORTION_MODEL_HPP
+
+//! @cond IGNORED
+
+namespace cv { namespace detail {
+/**
+Computes the matrix for the projection onto a tilted image sensor
+\param tauX angular parameter rotation around x-axis
+\param tauY angular parameter rotation around y-axis
+\param matTilt if not NULL returns the matrix
+\f[
+\vecthreethree{R_{33}(\tau_x, \tau_y)}{0}{-R_{13}((\tau_x, \tau_y)}
+{0}{R_{33}(\tau_x, \tau_y)}{-R_{23}(\tau_x, \tau_y)}
+{0}{0}{1} R(\tau_x, \tau_y)
+\f]
+where
+\f[
+R(\tau_x, \tau_y) =
+\vecthreethree{\cos(\tau_y)}{0}{-\sin(\tau_y)}{0}{1}{0}{\sin(\tau_y)}{0}{\cos(\tau_y)}
+\vecthreethree{1}{0}{0}{0}{\cos(\tau_x)}{\sin(\tau_x)}{0}{-\sin(\tau_x)}{\cos(\tau_x)} =
+\vecthreethree{\cos(\tau_y)}{\sin(\tau_y)\sin(\tau_x)}{-\sin(\tau_y)\cos(\tau_x)}
+{0}{\cos(\tau_x)}{\sin(\tau_x)}
+{\sin(\tau_y)}{-\cos(\tau_y)\sin(\tau_x)}{\cos(\tau_y)\cos(\tau_x)}.
+\f]
+\param dMatTiltdTauX if not NULL it returns the derivative of matTilt with
+respect to \f$\tau_x\f$.
+\param dMatTiltdTauY if not NULL it returns the derivative of matTilt with
+respect to \f$\tau_y\f$.
+\param invMatTilt if not NULL it returns the inverse of matTilt
+**/
+template <typename FLOAT>
+void computeTiltProjectionMatrix(FLOAT tauX,
+ FLOAT tauY,
+ Matx<FLOAT, 3, 3>* matTilt = 0,
+ Matx<FLOAT, 3, 3>* dMatTiltdTauX = 0,
+ Matx<FLOAT, 3, 3>* dMatTiltdTauY = 0,
+ Matx<FLOAT, 3, 3>* invMatTilt = 0)
+{
+ FLOAT cTauX = cos(tauX);
+ FLOAT sTauX = sin(tauX);
+ FLOAT cTauY = cos(tauY);
+ FLOAT sTauY = sin(tauY);
+ Matx<FLOAT, 3, 3> matRotX = Matx<FLOAT, 3, 3>(1,0,0,0,cTauX,sTauX,0,-sTauX,cTauX);
+ Matx<FLOAT, 3, 3> matRotY = Matx<FLOAT, 3, 3>(cTauY,0,-sTauY,0,1,0,sTauY,0,cTauY);
+ Matx<FLOAT, 3, 3> matRotXY = matRotY * matRotX;
+ Matx<FLOAT, 3, 3> matProjZ = Matx<FLOAT, 3, 3>(matRotXY(2,2),0,-matRotXY(0,2),0,matRotXY(2,2),-matRotXY(1,2),0,0,1);
+ if (matTilt)
+ {
+ // Matrix for trapezoidal distortion of tilted image sensor
+ *matTilt = matProjZ * matRotXY;
+ }
+ if (dMatTiltdTauX)
+ {
+ // Derivative with respect to tauX
+ Matx<FLOAT, 3, 3> dMatRotXYdTauX = matRotY * Matx<FLOAT, 3, 3>(0,0,0,0,-sTauX,cTauX,0,-cTauX,-sTauX);
+ Matx<FLOAT, 3, 3> dMatProjZdTauX = Matx<FLOAT, 3, 3>(dMatRotXYdTauX(2,2),0,-dMatRotXYdTauX(0,2),
+ 0,dMatRotXYdTauX(2,2),-dMatRotXYdTauX(1,2),0,0,0);
+ *dMatTiltdTauX = (matProjZ * dMatRotXYdTauX) + (dMatProjZdTauX * matRotXY);
+ }
+ if (dMatTiltdTauY)
+ {
+ // Derivative with respect to tauY
+ Matx<FLOAT, 3, 3> dMatRotXYdTauY = Matx<FLOAT, 3, 3>(-sTauY,0,-cTauY,0,0,0,cTauY,0,-sTauY) * matRotX;
+ Matx<FLOAT, 3, 3> dMatProjZdTauY = Matx<FLOAT, 3, 3>(dMatRotXYdTauY(2,2),0,-dMatRotXYdTauY(0,2),
+ 0,dMatRotXYdTauY(2,2),-dMatRotXYdTauY(1,2),0,0,0);
+ *dMatTiltdTauY = (matProjZ * dMatRotXYdTauY) + (dMatProjZdTauY * matRotXY);
+ }
+ if (invMatTilt)
+ {
+ FLOAT inv = 1./matRotXY(2,2);
+ Matx<FLOAT, 3, 3> invMatProjZ = Matx<FLOAT, 3, 3>(inv,0,inv*matRotXY(0,2),0,inv,inv*matRotXY(1,2),0,0,1);
+ *invMatTilt = matRotXY.t()*invMatProjZ;
+ }
+}
+}} // namespace detail, cv
+
+
+//! @endcond
+
+#endif // OPENCV_IMGPROC_DETAIL_DISTORTION_MODEL_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/imgproc/hal/hal.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,189 @@
+#ifndef CV_IMGPROC_HAL_HPP
+#define CV_IMGPROC_HAL_HPP
+
+#include "opencv2/core/cvdef.h"
+#include "opencv2/core/cvstd.hpp"
+#include "opencv2/core/hal/interface.h"
+
+namespace cv { namespace hal {
+
+//! @addtogroup imgproc_hal_functions
+//! @{
+
+struct CV_EXPORTS Filter2D
+{
+ static Ptr<hal::Filter2D> create(uchar * kernel_data, size_t kernel_step, int kernel_type,
+ int kernel_width, int kernel_height,
+ int max_width, int max_height,
+ int stype, int dtype,
+ int borderType, double delta,
+ int anchor_x, int anchor_y,
+ bool isSubmatrix, bool isInplace);
+ virtual void apply(uchar * src_data, size_t src_step,
+ uchar * dst_data, size_t dst_step,
+ int width, int height,
+ int full_width, int full_height,
+ int offset_x, int offset_y) = 0;
+ virtual ~Filter2D() {}
+};
+
+struct CV_EXPORTS SepFilter2D
+{
+ static Ptr<hal::SepFilter2D> create(int stype, int dtype, int ktype,
+ uchar * kernelx_data, int kernelx_len,
+ uchar * kernely_data, int kernely_len,
+ int anchor_x, int anchor_y,
+ double delta, int borderType);
+ virtual void apply(uchar * src_data, size_t src_step,
+ uchar * dst_data, size_t dst_step,
+ int width, int height,
+ int full_width, int full_height,
+ int offset_x, int offset_y) = 0;
+ virtual ~SepFilter2D() {}
+};
+
+
+struct CV_EXPORTS Morph
+{
+ static Ptr<Morph> create(int op, int src_type, int dst_type, int max_width, int max_height,
+ int kernel_type, uchar * kernel_data, size_t kernel_step,
+ int kernel_width, int kernel_height,
+ int anchor_x, int anchor_y,
+ int borderType, const double borderValue[4],
+ int iterations, bool isSubmatrix, bool allowInplace);
+ virtual void apply(uchar * src_data, size_t src_step, uchar * dst_data, size_t dst_step, int width, int height,
+ int roi_width, int roi_height, int roi_x, int roi_y,
+ int roi_width2, int roi_height2, int roi_x2, int roi_y2) = 0;
+ virtual ~Morph() {}
+};
+
+
+CV_EXPORTS void resize(int src_type,
+ const uchar * src_data, size_t src_step, int src_width, int src_height,
+ uchar * dst_data, size_t dst_step, int dst_width, int dst_height,
+ double inv_scale_x, double inv_scale_y, int interpolation);
+
+CV_EXPORTS void warpAffine(int src_type,
+ const uchar * src_data, size_t src_step, int src_width, int src_height,
+ uchar * dst_data, size_t dst_step, int dst_width, int dst_height,
+ const double M[6], int interpolation, int borderType, const double borderValue[4]);
+
+CV_EXPORTS void warpPerspectve(int src_type,
+ const uchar * src_data, size_t src_step, int src_width, int src_height,
+ uchar * dst_data, size_t dst_step, int dst_width, int dst_height,
+ const double M[9], int interpolation, int borderType, const double borderValue[4]);
+
+CV_EXPORTS void cvtBGRtoBGR(const uchar * src_data, size_t src_step,
+ uchar * dst_data, size_t dst_step,
+ int width, int height,
+ int depth, int scn, int dcn, bool swapBlue);
+
+CV_EXPORTS void cvtBGRtoBGR5x5(const uchar * src_data, size_t src_step,
+ uchar * dst_data, size_t dst_step,
+ int width, int height,
+ int scn, bool swapBlue, int greenBits);
+
+CV_EXPORTS void cvtBGR5x5toBGR(const uchar * src_data, size_t src_step,
+ uchar * dst_data, size_t dst_step,
+ int width, int height,
+ int dcn, bool swapBlue, int greenBits);
+
+CV_EXPORTS void cvtBGRtoGray(const uchar * src_data, size_t src_step,
+ uchar * dst_data, size_t dst_step,
+ int width, int height,
+ int depth, int scn, bool swapBlue);
+
+CV_EXPORTS void cvtGraytoBGR(const uchar * src_data, size_t src_step,
+ uchar * dst_data, size_t dst_step,
+ int width, int height,
+ int depth, int dcn);
+
+CV_EXPORTS void cvtBGR5x5toGray(const uchar * src_data, size_t src_step,
+ uchar * dst_data, size_t dst_step,
+ int width, int height,
+ int greenBits);
+
+CV_EXPORTS void cvtGraytoBGR5x5(const uchar * src_data, size_t src_step,
+ uchar * dst_data, size_t dst_step,
+ int width, int height,
+ int greenBits);
+CV_EXPORTS void cvtBGRtoYUV(const uchar * src_data, size_t src_step,
+ uchar * dst_data, size_t dst_step,
+ int width, int height,
+ int depth, int scn, bool swapBlue, bool isCbCr);
+
+CV_EXPORTS void cvtYUVtoBGR(const uchar * src_data, size_t src_step,
+ uchar * dst_data, size_t dst_step,
+ int width, int height,
+ int depth, int dcn, bool swapBlue, bool isCbCr);
+
+CV_EXPORTS void cvtBGRtoXYZ(const uchar * src_data, size_t src_step,
+ uchar * dst_data, size_t dst_step,
+ int width, int height,
+ int depth, int scn, bool swapBlue);
+
+CV_EXPORTS void cvtXYZtoBGR(const uchar * src_data, size_t src_step,
+ uchar * dst_data, size_t dst_step,
+ int width, int height,
+ int depth, int dcn, bool swapBlue);
+
+CV_EXPORTS void cvtBGRtoHSV(const uchar * src_data, size_t src_step,
+ uchar * dst_data, size_t dst_step,
+ int width, int height,
+ int depth, int scn, bool swapBlue, bool isFullRange, bool isHSV);
+
+CV_EXPORTS void cvtHSVtoBGR(const uchar * src_data, size_t src_step,
+ uchar * dst_data, size_t dst_step,
+ int width, int height,
+ int depth, int dcn, bool swapBlue, bool isFullRange, bool isHSV);
+
+CV_EXPORTS void cvtBGRtoLab(const uchar * src_data, size_t src_step,
+ uchar * dst_data, size_t dst_step,
+ int width, int height,
+ int depth, int scn, bool swapBlue, bool isLab, bool srgb);
+
+CV_EXPORTS void cvtLabtoBGR(const uchar * src_data, size_t src_step,
+ uchar * dst_data, size_t dst_step,
+ int width, int height,
+ int depth, int dcn, bool swapBlue, bool isLab, bool srgb);
+
+CV_EXPORTS void cvtTwoPlaneYUVtoBGR(const uchar * src_data, size_t src_step,
+ uchar * dst_data, size_t dst_step,
+ int dst_width, int dst_height,
+ int dcn, bool swapBlue, int uIdx);
+
+CV_EXPORTS void cvtThreePlaneYUVtoBGR(const uchar * src_data, size_t src_step,
+ uchar * dst_data, size_t dst_step,
+ int dst_width, int dst_height,
+ int dcn, bool swapBlue, int uIdx);
+
+CV_EXPORTS void cvtBGRtoThreePlaneYUV(const uchar * src_data, size_t src_step,
+ uchar * dst_data, size_t dst_step,
+ int width, int height,
+ int scn, bool swapBlue, int uIdx);
+
+CV_EXPORTS void cvtOnePlaneYUVtoBGR(const uchar * src_data, size_t src_step,
+ uchar * dst_data, size_t dst_step,
+ int width, int height,
+ int dcn, bool swapBlue, int uIdx, int ycn);
+
+CV_EXPORTS void cvtRGBAtoMultipliedRGBA(const uchar * src_data, size_t src_step,
+ uchar * dst_data, size_t dst_step,
+ int width, int height);
+
+CV_EXPORTS void cvtMultipliedRGBAtoRGBA(const uchar * src_data, size_t src_step,
+ uchar * dst_data, size_t dst_step,
+ int width, int height);
+
+CV_EXPORTS void integral(int depth, int sdepth, int sqdepth,
+ const uchar* src, size_t srcstep,
+ uchar* sum, size_t sumstep,
+ uchar* sqsum, size_t sqsumstep,
+ uchar* tilted, size_t tstep,
+ int width, int height, int cn);
+
+//! @}
+
+}}
+
+#endif // CV_IMGPROC_HAL_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/imgproc/hal/interface.h Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,26 @@
+#ifndef OPENCV_IMGPROC_HAL_INTERFACE_H
+#define OPENCV_IMGPROC_HAL_INTERFACE_H
+
+//! @addtogroup imgproc_hal_interface
+//! @{
+
+//! @name Interpolation modes
+//! @sa cv::InterpolationFlags
+//! @{
+#define CV_HAL_INTER_NEAREST 0
+#define CV_HAL_INTER_LINEAR 1
+#define CV_HAL_INTER_CUBIC 2
+#define CV_HAL_INTER_AREA 3
+#define CV_HAL_INTER_LANCZOS4 4
+//! @}
+
+//! @name Morphology operations
+//! @sa cv::MorphTypes
+//! @{
+#define MORPH_ERODE 0
+#define MORPH_DILATE 1
+//! @}
+
+//! @}
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/opencv2/imgproc/imgproc.hpp Fri Jan 29 04:53:38 2021 +0000 @@ -0,0 +1,48 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifdef __OPENCV_BUILD +#error this is a compatibility header which should not be used inside the OpenCV library +#endif + +#include "opencv2/imgproc.hpp"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/imgproc/imgproc_c.h Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,1210 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_IMGPROC_IMGPROC_C_H
+#define OPENCV_IMGPROC_IMGPROC_C_H
+
+#include "opencv2/imgproc/types_c.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @addtogroup imgproc_c
+@{
+*/
+
+/*********************** Background statistics accumulation *****************************/
+
+/** @brief Adds image to accumulator
+@see cv::accumulate
+*/
+CVAPI(void) cvAcc( const CvArr* image, CvArr* sum,
+ const CvArr* mask CV_DEFAULT(NULL) );
+
+/** @brief Adds squared image to accumulator
+@see cv::accumulateSquare
+*/
+CVAPI(void) cvSquareAcc( const CvArr* image, CvArr* sqsum,
+ const CvArr* mask CV_DEFAULT(NULL) );
+
+/** @brief Adds a product of two images to accumulator
+@see cv::accumulateProduct
+*/
+CVAPI(void) cvMultiplyAcc( const CvArr* image1, const CvArr* image2, CvArr* acc,
+ const CvArr* mask CV_DEFAULT(NULL) );
+
+/** @brief Adds image to accumulator with weights: acc = acc*(1-alpha) + image*alpha
+@see cv::accumulateWeighted
+*/
+CVAPI(void) cvRunningAvg( const CvArr* image, CvArr* acc, double alpha,
+ const CvArr* mask CV_DEFAULT(NULL) );
+
+/****************************************************************************************\
+* Image Processing *
+\****************************************************************************************/
+
+/** Copies source 2D array inside of the larger destination array and
+ makes a border of the specified type (IPL_BORDER_*) around the copied area. */
+CVAPI(void) cvCopyMakeBorder( const CvArr* src, CvArr* dst, CvPoint offset,
+ int bordertype, CvScalar value CV_DEFAULT(cvScalarAll(0)));
+
+/** @brief Smooths the image in one of several ways.
+
+@param src The source image
+@param dst The destination image
+@param smoothtype Type of the smoothing, see SmoothMethod_c
+@param size1 The first parameter of the smoothing operation, the aperture width. Must be a
+positive odd number (1, 3, 5, ...)
+@param size2 The second parameter of the smoothing operation, the aperture height. Ignored by
+CV_MEDIAN and CV_BILATERAL methods. In the case of simple scaled/non-scaled and Gaussian blur if
+size2 is zero, it is set to size1. Otherwise it must be a positive odd number.
+@param sigma1 In the case of a Gaussian parameter this parameter may specify Gaussian \f$\sigma\f$
+(standard deviation). If it is zero, it is calculated from the kernel size:
+\f[\sigma = 0.3 (n/2 - 1) + 0.8 \quad \text{where} \quad n= \begin{array}{l l} \mbox{\texttt{size1} for horizontal kernel} \\ \mbox{\texttt{size2} for vertical kernel} \end{array}\f]
+Using standard sigma for small kernels ( \f$3\times 3\f$ to \f$7\times 7\f$ ) gives better speed. If
+sigma1 is not zero, while size1 and size2 are zeros, the kernel size is calculated from the
+sigma (to provide accurate enough operation).
+@param sigma2 additional parameter for bilateral filtering
+
+@see cv::GaussianBlur, cv::blur, cv::medianBlur, cv::bilateralFilter.
+ */
+CVAPI(void) cvSmooth( const CvArr* src, CvArr* dst,
+ int smoothtype CV_DEFAULT(CV_GAUSSIAN),
+ int size1 CV_DEFAULT(3),
+ int size2 CV_DEFAULT(0),
+ double sigma1 CV_DEFAULT(0),
+ double sigma2 CV_DEFAULT(0));
+
+/** @brief Convolves an image with the kernel.
+
+@param src input image.
+@param dst output image of the same size and the same number of channels as src.
+@param kernel convolution kernel (or rather a correlation kernel), a single-channel floating point
+matrix; if you want to apply different kernels to different channels, split the image into
+separate color planes using split and process them individually.
+@param anchor anchor of the kernel that indicates the relative position of a filtered point within
+the kernel; the anchor should lie within the kernel; default value (-1,-1) means that the anchor
+is at the kernel center.
+
+@see cv::filter2D
+ */
+CVAPI(void) cvFilter2D( const CvArr* src, CvArr* dst, const CvMat* kernel,
+ CvPoint anchor CV_DEFAULT(cvPoint(-1,-1)));
+
+/** @brief Finds integral image: SUM(X,Y) = sum(x<X,y<Y)I(x,y)
+@see cv::integral
+*/
+CVAPI(void) cvIntegral( const CvArr* image, CvArr* sum,
+ CvArr* sqsum CV_DEFAULT(NULL),
+ CvArr* tilted_sum CV_DEFAULT(NULL));
+
+/** @brief Smoothes the input image with gaussian kernel and then down-samples it.
+
+ dst_width = floor(src_width/2)[+1],
+ dst_height = floor(src_height/2)[+1]
+ @see cv::pyrDown
+*/
+CVAPI(void) cvPyrDown( const CvArr* src, CvArr* dst,
+ int filter CV_DEFAULT(CV_GAUSSIAN_5x5) );
+
+/** @brief Up-samples image and smoothes the result with gaussian kernel.
+
+ dst_width = src_width*2,
+ dst_height = src_height*2
+ @see cv::pyrUp
+*/
+CVAPI(void) cvPyrUp( const CvArr* src, CvArr* dst,
+ int filter CV_DEFAULT(CV_GAUSSIAN_5x5) );
+
+/** @brief Builds pyramid for an image
+@see buildPyramid
+*/
+CVAPI(CvMat**) cvCreatePyramid( const CvArr* img, int extra_layers, double rate,
+ const CvSize* layer_sizes CV_DEFAULT(0),
+ CvArr* bufarr CV_DEFAULT(0),
+ int calc CV_DEFAULT(1),
+ int filter CV_DEFAULT(CV_GAUSSIAN_5x5) );
+
+/** @brief Releases pyramid */
+CVAPI(void) cvReleasePyramid( CvMat*** pyramid, int extra_layers );
+
+
+/** @brief Filters image using meanshift algorithm
+@see cv::pyrMeanShiftFiltering
+*/
+CVAPI(void) cvPyrMeanShiftFiltering( const CvArr* src, CvArr* dst,
+ double sp, double sr, int max_level CV_DEFAULT(1),
+ CvTermCriteria termcrit CV_DEFAULT(cvTermCriteria(CV_TERMCRIT_ITER+CV_TERMCRIT_EPS,5,1)));
+
+/** @brief Segments image using seed "markers"
+@see cv::watershed
+*/
+CVAPI(void) cvWatershed( const CvArr* image, CvArr* markers );
+
+/** @brief Calculates an image derivative using generalized Sobel
+
+ (aperture_size = 1,3,5,7) or Scharr (aperture_size = -1) operator.
+ Scharr can be used only for the first dx or dy derivative
+@see cv::Sobel
+*/
+CVAPI(void) cvSobel( const CvArr* src, CvArr* dst,
+ int xorder, int yorder,
+ int aperture_size CV_DEFAULT(3));
+
+/** @brief Calculates the image Laplacian: (d2/dx + d2/dy)I
+@see cv::Laplacian
+*/
+CVAPI(void) cvLaplace( const CvArr* src, CvArr* dst,
+ int aperture_size CV_DEFAULT(3) );
+
+/** @brief Converts input array pixels from one color space to another
+@see cv::cvtColor
+*/
+CVAPI(void) cvCvtColor( const CvArr* src, CvArr* dst, int code );
+
+
+/** @brief Resizes image (input array is resized to fit the destination array)
+@see cv::resize
+*/
+CVAPI(void) cvResize( const CvArr* src, CvArr* dst,
+ int interpolation CV_DEFAULT( CV_INTER_LINEAR ));
+
+/** @brief Warps image with affine transform
+@note ::cvGetQuadrangleSubPix is similar to ::cvWarpAffine, but the outliers are extrapolated using
+replication border mode.
+@see cv::warpAffine
+*/
+CVAPI(void) cvWarpAffine( const CvArr* src, CvArr* dst, const CvMat* map_matrix,
+ int flags CV_DEFAULT(CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS),
+ CvScalar fillval CV_DEFAULT(cvScalarAll(0)) );
+
+/** @brief Computes affine transform matrix for mapping src[i] to dst[i] (i=0,1,2)
+@see cv::getAffineTransform
+*/
+CVAPI(CvMat*) cvGetAffineTransform( const CvPoint2D32f * src,
+ const CvPoint2D32f * dst,
+ CvMat * map_matrix );
+
+/** @brief Computes rotation_matrix matrix
+@see cv::getRotationMatrix2D
+*/
+CVAPI(CvMat*) cv2DRotationMatrix( CvPoint2D32f center, double angle,
+ double scale, CvMat* map_matrix );
+
+/** @brief Warps image with perspective (projective) transform
+@see cv::warpPerspective
+*/
+CVAPI(void) cvWarpPerspective( const CvArr* src, CvArr* dst, const CvMat* map_matrix,
+ int flags CV_DEFAULT(CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS),
+ CvScalar fillval CV_DEFAULT(cvScalarAll(0)) );
+
+/** @brief Computes perspective transform matrix for mapping src[i] to dst[i] (i=0,1,2,3)
+@see cv::getPerspectiveTransform
+*/
+CVAPI(CvMat*) cvGetPerspectiveTransform( const CvPoint2D32f* src,
+ const CvPoint2D32f* dst,
+ CvMat* map_matrix );
+
+/** @brief Performs generic geometric transformation using the specified coordinate maps
+@see cv::remap
+*/
+CVAPI(void) cvRemap( const CvArr* src, CvArr* dst,
+ const CvArr* mapx, const CvArr* mapy,
+ int flags CV_DEFAULT(CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS),
+ CvScalar fillval CV_DEFAULT(cvScalarAll(0)) );
+
+/** @brief Converts mapx & mapy from floating-point to integer formats for cvRemap
+@see cv::convertMaps
+*/
+CVAPI(void) cvConvertMaps( const CvArr* mapx, const CvArr* mapy,
+ CvArr* mapxy, CvArr* mapalpha );
+
+/** @brief Performs forward or inverse log-polar image transform
+@see cv::logPolar
+*/
+CVAPI(void) cvLogPolar( const CvArr* src, CvArr* dst,
+ CvPoint2D32f center, double M,
+ int flags CV_DEFAULT(CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS));
+
+/** Performs forward or inverse linear-polar image transform
+@see cv::linearPolar
+*/
+CVAPI(void) cvLinearPolar( const CvArr* src, CvArr* dst,
+ CvPoint2D32f center, double maxRadius,
+ int flags CV_DEFAULT(CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS));
+
+/** @brief Transforms the input image to compensate lens distortion
+@see cv::undistort
+*/
+CVAPI(void) cvUndistort2( const CvArr* src, CvArr* dst,
+ const CvMat* camera_matrix,
+ const CvMat* distortion_coeffs,
+ const CvMat* new_camera_matrix CV_DEFAULT(0) );
+
+/** @brief Computes transformation map from intrinsic camera parameters
+ that can used by cvRemap
+*/
+CVAPI(void) cvInitUndistortMap( const CvMat* camera_matrix,
+ const CvMat* distortion_coeffs,
+ CvArr* mapx, CvArr* mapy );
+
+/** @brief Computes undistortion+rectification map for a head of stereo camera
+@see cv::initUndistortRectifyMap
+*/
+CVAPI(void) cvInitUndistortRectifyMap( const CvMat* camera_matrix,
+ const CvMat* dist_coeffs,
+ const CvMat *R, const CvMat* new_camera_matrix,
+ CvArr* mapx, CvArr* mapy );
+
+/** @brief Computes the original (undistorted) feature coordinates
+ from the observed (distorted) coordinates
+@see cv::undistortPoints
+*/
+CVAPI(void) cvUndistortPoints( const CvMat* src, CvMat* dst,
+ const CvMat* camera_matrix,
+ const CvMat* dist_coeffs,
+ const CvMat* R CV_DEFAULT(0),
+ const CvMat* P CV_DEFAULT(0));
+
+/** @brief Returns a structuring element of the specified size and shape for morphological operations.
+
+@note the created structuring element IplConvKernel\* element must be released in the end using
+`cvReleaseStructuringElement(&element)`.
+
+@param cols Width of the structuring element
+@param rows Height of the structuring element
+@param anchor_x x-coordinate of the anchor
+@param anchor_y y-coordinate of the anchor
+@param shape element shape that could be one of the cv::MorphShapes_c
+@param values integer array of cols*rows elements that specifies the custom shape of the
+structuring element, when shape=CV_SHAPE_CUSTOM.
+
+@see cv::getStructuringElement
+ */
+ CVAPI(IplConvKernel*) cvCreateStructuringElementEx(
+ int cols, int rows, int anchor_x, int anchor_y,
+ int shape, int* values CV_DEFAULT(NULL) );
+
+/** @brief releases structuring element
+@see cvCreateStructuringElementEx
+*/
+CVAPI(void) cvReleaseStructuringElement( IplConvKernel** element );
+
+/** @brief erodes input image (applies minimum filter) one or more times.
+ If element pointer is NULL, 3x3 rectangular element is used
+@see cv::erode
+*/
+CVAPI(void) cvErode( const CvArr* src, CvArr* dst,
+ IplConvKernel* element CV_DEFAULT(NULL),
+ int iterations CV_DEFAULT(1) );
+
+/** @brief dilates input image (applies maximum filter) one or more times.
+
+ If element pointer is NULL, 3x3 rectangular element is used
+@see cv::dilate
+*/
+CVAPI(void) cvDilate( const CvArr* src, CvArr* dst,
+ IplConvKernel* element CV_DEFAULT(NULL),
+ int iterations CV_DEFAULT(1) );
+
+/** @brief Performs complex morphological transformation
+@see cv::morphologyEx
+*/
+CVAPI(void) cvMorphologyEx( const CvArr* src, CvArr* dst,
+ CvArr* temp, IplConvKernel* element,
+ int operation, int iterations CV_DEFAULT(1) );
+
+/** @brief Calculates all spatial and central moments up to the 3rd order
+@see cv::moments
+*/
+CVAPI(void) cvMoments( const CvArr* arr, CvMoments* moments, int binary CV_DEFAULT(0));
+
+/** @brief Retrieve spatial moments */
+CVAPI(double) cvGetSpatialMoment( CvMoments* moments, int x_order, int y_order );
+/** @brief Retrieve central moments */
+CVAPI(double) cvGetCentralMoment( CvMoments* moments, int x_order, int y_order );
+/** @brief Retrieve normalized central moments */
+CVAPI(double) cvGetNormalizedCentralMoment( CvMoments* moments,
+ int x_order, int y_order );
+
+/** @brief Calculates 7 Hu's invariants from precalculated spatial and central moments
+@see cv::HuMoments
+*/
+CVAPI(void) cvGetHuMoments( CvMoments* moments, CvHuMoments* hu_moments );
+
+/*********************************** data sampling **************************************/
+
+/** @brief Fetches pixels that belong to the specified line segment and stores them to the buffer.
+
+ Returns the number of retrieved points.
+@see cv::LineSegmentDetector
+*/
+CVAPI(int) cvSampleLine( const CvArr* image, CvPoint pt1, CvPoint pt2, void* buffer,
+ int connectivity CV_DEFAULT(8));
+
+/** @brief Retrieves the rectangular image region with specified center from the input array.
+
+ dst(x,y) <- src(x + center.x - dst_width/2, y + center.y - dst_height/2).
+ Values of pixels with fractional coordinates are retrieved using bilinear interpolation
+@see cv::getRectSubPix
+*/
+CVAPI(void) cvGetRectSubPix( const CvArr* src, CvArr* dst, CvPoint2D32f center );
+
+
+/** @brief Retrieves quadrangle from the input array.
+
+ matrixarr = ( a11 a12 | b1 ) dst(x,y) <- src(A[x y]' + b)
+ ( a21 a22 | b2 ) (bilinear interpolation is used to retrieve pixels
+ with fractional coordinates)
+@see cvWarpAffine
+*/
+CVAPI(void) cvGetQuadrangleSubPix( const CvArr* src, CvArr* dst,
+ const CvMat* map_matrix );
+
+/** @brief Measures similarity between template and overlapped windows in the source image
+ and fills the resultant image with the measurements
+@see cv::matchTemplate
+*/
+CVAPI(void) cvMatchTemplate( const CvArr* image, const CvArr* templ,
+ CvArr* result, int method );
+
+/** @brief Computes earth mover distance between
+ two weighted point sets (called signatures)
+@see cv::EMD
+*/
+CVAPI(float) cvCalcEMD2( const CvArr* signature1,
+ const CvArr* signature2,
+ int distance_type,
+ CvDistanceFunction distance_func CV_DEFAULT(NULL),
+ const CvArr* cost_matrix CV_DEFAULT(NULL),
+ CvArr* flow CV_DEFAULT(NULL),
+ float* lower_bound CV_DEFAULT(NULL),
+ void* userdata CV_DEFAULT(NULL));
+
+/****************************************************************************************\
+* Contours retrieving *
+\****************************************************************************************/
+
+/** @brief Retrieves outer and optionally inner boundaries of white (non-zero) connected
+ components in the black (zero) background
+@see cv::findContours, cvStartFindContours, cvFindNextContour, cvSubstituteContour, cvEndFindContours
+*/
+CVAPI(int) cvFindContours( CvArr* image, CvMemStorage* storage, CvSeq** first_contour,
+ int header_size CV_DEFAULT(sizeof(CvContour)),
+ int mode CV_DEFAULT(CV_RETR_LIST),
+ int method CV_DEFAULT(CV_CHAIN_APPROX_SIMPLE),
+ CvPoint offset CV_DEFAULT(cvPoint(0,0)));
+
+/** @brief Initializes contour retrieving process.
+
+ Calls cvStartFindContours.
+ Calls cvFindNextContour until null pointer is returned
+ or some other condition becomes true.
+ Calls cvEndFindContours at the end.
+@see cvFindContours
+*/
+CVAPI(CvContourScanner) cvStartFindContours( CvArr* image, CvMemStorage* storage,
+ int header_size CV_DEFAULT(sizeof(CvContour)),
+ int mode CV_DEFAULT(CV_RETR_LIST),
+ int method CV_DEFAULT(CV_CHAIN_APPROX_SIMPLE),
+ CvPoint offset CV_DEFAULT(cvPoint(0,0)));
+
+/** @brief Retrieves next contour
+@see cvFindContours
+*/
+CVAPI(CvSeq*) cvFindNextContour( CvContourScanner scanner );
+
+
+/** @brief Substitutes the last retrieved contour with the new one
+
+ (if the substitutor is null, the last retrieved contour is removed from the tree)
+@see cvFindContours
+*/
+CVAPI(void) cvSubstituteContour( CvContourScanner scanner, CvSeq* new_contour );
+
+
+/** @brief Releases contour scanner and returns pointer to the first outer contour
+@see cvFindContours
+*/
+CVAPI(CvSeq*) cvEndFindContours( CvContourScanner* scanner );
+
+/** @brief Approximates Freeman chain(s) with a polygonal curve.
+
+This is a standalone contour approximation routine, not represented in the new interface. When
+cvFindContours retrieves contours as Freeman chains, it calls the function to get approximated
+contours, represented as polygons.
+
+@param src_seq Pointer to the approximated Freeman chain that can refer to other chains.
+@param storage Storage location for the resulting polylines.
+@param method Approximation method (see the description of the function :ocvFindContours ).
+@param parameter Method parameter (not used now).
+@param minimal_perimeter Approximates only those contours whose perimeters are not less than
+minimal_perimeter . Other chains are removed from the resulting structure.
+@param recursive Recursion flag. If it is non-zero, the function approximates all chains that can
+be obtained from chain by using the h_next or v_next links. Otherwise, the single input chain is
+approximated.
+@see cvStartReadChainPoints, cvReadChainPoint
+ */
+CVAPI(CvSeq*) cvApproxChains( CvSeq* src_seq, CvMemStorage* storage,
+ int method CV_DEFAULT(CV_CHAIN_APPROX_SIMPLE),
+ double parameter CV_DEFAULT(0),
+ int minimal_perimeter CV_DEFAULT(0),
+ int recursive CV_DEFAULT(0));
+
+/** @brief Initializes Freeman chain reader.
+
+ The reader is used to iteratively get coordinates of all the chain points.
+ If the Freeman codes should be read as is, a simple sequence reader should be used
+@see cvApproxChains
+*/
+CVAPI(void) cvStartReadChainPoints( CvChain* chain, CvChainPtReader* reader );
+
+/** @brief Retrieves the next chain point
+@see cvApproxChains
+*/
+CVAPI(CvPoint) cvReadChainPoint( CvChainPtReader* reader );
+
+
+/****************************************************************************************\
+* Contour Processing and Shape Analysis *
+\****************************************************************************************/
+
+/** @brief Approximates a single polygonal curve (contour) or
+ a tree of polygonal curves (contours)
+@see cv::approxPolyDP
+*/
+CVAPI(CvSeq*) cvApproxPoly( const void* src_seq,
+ int header_size, CvMemStorage* storage,
+ int method, double eps,
+ int recursive CV_DEFAULT(0));
+
+/** @brief Calculates perimeter of a contour or length of a part of contour
+@see cv::arcLength
+*/
+CVAPI(double) cvArcLength( const void* curve,
+ CvSlice slice CV_DEFAULT(CV_WHOLE_SEQ),
+ int is_closed CV_DEFAULT(-1));
+
+/** same as cvArcLength for closed contour
+*/
+CV_INLINE double cvContourPerimeter( const void* contour )
+{
+ return cvArcLength( contour, CV_WHOLE_SEQ, 1 );
+}
+
+
+/** @brief Calculates contour bounding rectangle (update=1) or
+ just retrieves pre-calculated rectangle (update=0)
+@see cv::boundingRect
+*/
+CVAPI(CvRect) cvBoundingRect( CvArr* points, int update CV_DEFAULT(0) );
+
+/** @brief Calculates area of a contour or contour segment
+@see cv::contourArea
+*/
+CVAPI(double) cvContourArea( const CvArr* contour,
+ CvSlice slice CV_DEFAULT(CV_WHOLE_SEQ),
+ int oriented CV_DEFAULT(0));
+
+/** @brief Finds minimum area rotated rectangle bounding a set of points
+@see cv::minAreaRect
+*/
+CVAPI(CvBox2D) cvMinAreaRect2( const CvArr* points,
+ CvMemStorage* storage CV_DEFAULT(NULL));
+
+/** @brief Finds minimum enclosing circle for a set of points
+@see cv::minEnclosingCircle
+*/
+CVAPI(int) cvMinEnclosingCircle( const CvArr* points,
+ CvPoint2D32f* center, float* radius );
+
+/** @brief Compares two contours by matching their moments
+@see cv::matchShapes
+*/
+CVAPI(double) cvMatchShapes( const void* object1, const void* object2,
+ int method, double parameter CV_DEFAULT(0));
+
+/** @brief Calculates exact convex hull of 2d point set
+@see cv::convexHull
+*/
+CVAPI(CvSeq*) cvConvexHull2( const CvArr* input,
+ void* hull_storage CV_DEFAULT(NULL),
+ int orientation CV_DEFAULT(CV_CLOCKWISE),
+ int return_points CV_DEFAULT(0));
+
+/** @brief Checks whether the contour is convex or not (returns 1 if convex, 0 if not)
+@see cv::isContourConvex
+*/
+CVAPI(int) cvCheckContourConvexity( const CvArr* contour );
+
+
+/** @brief Finds convexity defects for the contour
+@see cv::convexityDefects
+*/
+CVAPI(CvSeq*) cvConvexityDefects( const CvArr* contour, const CvArr* convexhull,
+ CvMemStorage* storage CV_DEFAULT(NULL));
+
+/** @brief Fits ellipse into a set of 2d points
+@see cv::fitEllipse
+*/
+CVAPI(CvBox2D) cvFitEllipse2( const CvArr* points );
+
+/** @brief Finds minimum rectangle containing two given rectangles */
+CVAPI(CvRect) cvMaxRect( const CvRect* rect1, const CvRect* rect2 );
+
+/** @brief Finds coordinates of the box vertices */
+CVAPI(void) cvBoxPoints( CvBox2D box, CvPoint2D32f pt[4] );
+
+/** @brief Initializes sequence header for a matrix (column or row vector) of points
+
+ a wrapper for cvMakeSeqHeaderForArray (it does not initialize bounding rectangle!!!) */
+CVAPI(CvSeq*) cvPointSeqFromMat( int seq_kind, const CvArr* mat,
+ CvContour* contour_header,
+ CvSeqBlock* block );
+
+/** @brief Checks whether the point is inside polygon, outside, on an edge (at a vertex).
+
+ Returns positive, negative or zero value, correspondingly.
+ Optionally, measures a signed distance between
+ the point and the nearest polygon edge (measure_dist=1)
+@see cv::pointPolygonTest
+*/
+CVAPI(double) cvPointPolygonTest( const CvArr* contour,
+ CvPoint2D32f pt, int measure_dist );
+
+/****************************************************************************************\
+* Histogram functions *
+\****************************************************************************************/
+
+/** @brief Creates a histogram.
+
+The function creates a histogram of the specified size and returns a pointer to the created
+histogram. If the array ranges is 0, the histogram bin ranges must be specified later via the
+function cvSetHistBinRanges. Though cvCalcHist and cvCalcBackProject may process 8-bit images
+without setting bin ranges, they assume they are equally spaced in 0 to 255 bins.
+
+@param dims Number of histogram dimensions.
+@param sizes Array of the histogram dimension sizes.
+@param type Histogram representation format. CV_HIST_ARRAY means that the histogram data is
+represented as a multi-dimensional dense array CvMatND. CV_HIST_SPARSE means that histogram data
+is represented as a multi-dimensional sparse array CvSparseMat.
+@param ranges Array of ranges for the histogram bins. Its meaning depends on the uniform parameter
+value. The ranges are used when the histogram is calculated or backprojected to determine which
+histogram bin corresponds to which value/tuple of values from the input image(s).
+@param uniform Uniformity flag. If not zero, the histogram has evenly spaced bins and for every
+\f$0<=i<cDims\f$ ranges[i] is an array of two numbers: lower and upper boundaries for the i-th
+histogram dimension. The whole range [lower,upper] is then split into dims[i] equal parts to
+determine the i-th input tuple value ranges for every histogram bin. And if uniform=0 , then the
+i-th element of the ranges array contains dims[i]+1 elements: \f$\texttt{lower}_0,
+\texttt{upper}_0, \texttt{lower}_1, \texttt{upper}_1 = \texttt{lower}_2,
+...
+\texttt{upper}_{dims[i]-1}\f$ where \f$\texttt{lower}_j\f$ and \f$\texttt{upper}_j\f$ are lower
+and upper boundaries of the i-th input tuple value for the j-th bin, respectively. In either
+case, the input values that are beyond the specified range for a histogram bin are not counted
+by cvCalcHist and filled with 0 by cvCalcBackProject.
+ */
+CVAPI(CvHistogram*) cvCreateHist( int dims, int* sizes, int type,
+ float** ranges CV_DEFAULT(NULL),
+ int uniform CV_DEFAULT(1));
+
+/** @brief Sets the bounds of the histogram bins.
+
+This is a standalone function for setting bin ranges in the histogram. For a more detailed
+description of the parameters ranges and uniform, see the :ocvCalcHist function that can initialize
+the ranges as well. Ranges for the histogram bins must be set before the histogram is calculated or
+the backproject of the histogram is calculated.
+
+@param hist Histogram.
+@param ranges Array of bin ranges arrays. See :ocvCreateHist for details.
+@param uniform Uniformity flag. See :ocvCreateHist for details.
+ */
+CVAPI(void) cvSetHistBinRanges( CvHistogram* hist, float** ranges,
+ int uniform CV_DEFAULT(1));
+
+/** @brief Makes a histogram out of an array.
+
+The function initializes the histogram, whose header and bins are allocated by the user.
+cvReleaseHist does not need to be called afterwards. Only dense histograms can be initialized this
+way. The function returns hist.
+
+@param dims Number of the histogram dimensions.
+@param sizes Array of the histogram dimension sizes.
+@param hist Histogram header initialized by the function.
+@param data Array used to store histogram bins.
+@param ranges Histogram bin ranges. See cvCreateHist for details.
+@param uniform Uniformity flag. See cvCreateHist for details.
+ */
+CVAPI(CvHistogram*) cvMakeHistHeaderForArray(
+ int dims, int* sizes, CvHistogram* hist,
+ float* data, float** ranges CV_DEFAULT(NULL),
+ int uniform CV_DEFAULT(1));
+
+/** @brief Releases the histogram.
+
+The function releases the histogram (header and the data). The pointer to the histogram is cleared
+by the function. If \*hist pointer is already NULL, the function does nothing.
+
+@param hist Double pointer to the released histogram.
+ */
+CVAPI(void) cvReleaseHist( CvHistogram** hist );
+
+/** @brief Clears the histogram.
+
+The function sets all of the histogram bins to 0 in case of a dense histogram and removes all
+histogram bins in case of a sparse array.
+
+@param hist Histogram.
+ */
+CVAPI(void) cvClearHist( CvHistogram* hist );
+
+/** @brief Finds the minimum and maximum histogram bins.
+
+The function finds the minimum and maximum histogram bins and their positions. All of output
+arguments are optional. Among several extremas with the same value the ones with the minimum index
+(in the lexicographical order) are returned. In case of several maximums or minimums, the earliest
+in the lexicographical order (extrema locations) is returned.
+
+@param hist Histogram.
+@param min_value Pointer to the minimum value of the histogram.
+@param max_value Pointer to the maximum value of the histogram.
+@param min_idx Pointer to the array of coordinates for the minimum.
+@param max_idx Pointer to the array of coordinates for the maximum.
+ */
+CVAPI(void) cvGetMinMaxHistValue( const CvHistogram* hist,
+ float* min_value, float* max_value,
+ int* min_idx CV_DEFAULT(NULL),
+ int* max_idx CV_DEFAULT(NULL));
+
+
+/** @brief Normalizes the histogram.
+
+The function normalizes the histogram bins by scaling them so that the sum of the bins becomes equal
+to factor.
+
+@param hist Pointer to the histogram.
+@param factor Normalization factor.
+ */
+CVAPI(void) cvNormalizeHist( CvHistogram* hist, double factor );
+
+
+/** @brief Thresholds the histogram.
+
+The function clears histogram bins that are below the specified threshold.
+
+@param hist Pointer to the histogram.
+@param threshold Threshold level.
+ */
+CVAPI(void) cvThreshHist( CvHistogram* hist, double threshold );
+
+
+/** Compares two histogram */
+CVAPI(double) cvCompareHist( const CvHistogram* hist1,
+ const CvHistogram* hist2,
+ int method);
+
+/** @brief Copies a histogram.
+
+The function makes a copy of the histogram. If the second histogram pointer \*dst is NULL, a new
+histogram of the same size as src is created. Otherwise, both histograms must have equal types and
+sizes. Then the function copies the bin values of the source histogram to the destination histogram
+and sets the same bin value ranges as in src.
+
+@param src Source histogram.
+@param dst Pointer to the destination histogram.
+ */
+CVAPI(void) cvCopyHist( const CvHistogram* src, CvHistogram** dst );
+
+
+/** @brief Calculates bayesian probabilistic histograms
+ (each or src and dst is an array of _number_ histograms */
+CVAPI(void) cvCalcBayesianProb( CvHistogram** src, int number,
+ CvHistogram** dst);
+
+/** @brief Calculates array histogram
+@see cv::calcHist
+*/
+CVAPI(void) cvCalcArrHist( CvArr** arr, CvHistogram* hist,
+ int accumulate CV_DEFAULT(0),
+ const CvArr* mask CV_DEFAULT(NULL) );
+
+/** @overload */
+CV_INLINE void cvCalcHist( IplImage** image, CvHistogram* hist,
+ int accumulate CV_DEFAULT(0),
+ const CvArr* mask CV_DEFAULT(NULL) )
+{
+ cvCalcArrHist( (CvArr**)image, hist, accumulate, mask );
+}
+
+/** @brief Calculates back project
+@see cvCalcBackProject, cv::calcBackProject
+*/
+CVAPI(void) cvCalcArrBackProject( CvArr** image, CvArr* dst,
+ const CvHistogram* hist );
+
+#define cvCalcBackProject(image, dst, hist) cvCalcArrBackProject((CvArr**)image, dst, hist)
+
+
+/** @brief Locates a template within an image by using a histogram comparison.
+
+The function calculates the back projection by comparing histograms of the source image patches with
+the given histogram. The function is similar to matchTemplate, but instead of comparing the raster
+patch with all its possible positions within the search window, the function CalcBackProjectPatch
+compares histograms. See the algorithm diagram below:
+
+
+
+@param image Source images (though, you may pass CvMat\*\* as well).
+@param dst Destination image.
+@param range
+@param hist Histogram.
+@param method Comparison method passed to cvCompareHist (see the function description).
+@param factor Normalization factor for histograms that affects the normalization scale of the
+destination image. Pass 1 if not sure.
+
+@see cvCalcBackProjectPatch
+ */
+CVAPI(void) cvCalcArrBackProjectPatch( CvArr** image, CvArr* dst, CvSize range,
+ CvHistogram* hist, int method,
+ double factor );
+
+#define cvCalcBackProjectPatch( image, dst, range, hist, method, factor ) \
+ cvCalcArrBackProjectPatch( (CvArr**)image, dst, range, hist, method, factor )
+
+
+/** @brief Divides one histogram by another.
+
+The function calculates the object probability density from two histograms as:
+
+\f[\texttt{disthist} (I)= \forkthree{0}{if \(\texttt{hist1}(I)=0\)}{\texttt{scale}}{if \(\texttt{hist1}(I) \ne 0\) and \(\texttt{hist2}(I) > \texttt{hist1}(I)\)}{\frac{\texttt{hist2}(I) \cdot \texttt{scale}}{\texttt{hist1}(I)}}{if \(\texttt{hist1}(I) \ne 0\) and \(\texttt{hist2}(I) \le \texttt{hist1}(I)\)}\f]
+
+@param hist1 First histogram (the divisor).
+@param hist2 Second histogram.
+@param dst_hist Destination histogram.
+@param scale Scale factor for the destination histogram.
+ */
+CVAPI(void) cvCalcProbDensity( const CvHistogram* hist1, const CvHistogram* hist2,
+ CvHistogram* dst_hist, double scale CV_DEFAULT(255) );
+
+/** @brief equalizes histogram of 8-bit single-channel image
+@see cv::equalizeHist
+*/
+CVAPI(void) cvEqualizeHist( const CvArr* src, CvArr* dst );
+
+
+/** @brief Applies distance transform to binary image
+@see cv::distanceTransform
+*/
+CVAPI(void) cvDistTransform( const CvArr* src, CvArr* dst,
+ int distance_type CV_DEFAULT(CV_DIST_L2),
+ int mask_size CV_DEFAULT(3),
+ const float* mask CV_DEFAULT(NULL),
+ CvArr* labels CV_DEFAULT(NULL),
+ int labelType CV_DEFAULT(CV_DIST_LABEL_CCOMP));
+
+
+/** @brief Applies fixed-level threshold to grayscale image.
+
+ This is a basic operation applied before retrieving contours
+@see cv::threshold
+*/
+CVAPI(double) cvThreshold( const CvArr* src, CvArr* dst,
+ double threshold, double max_value,
+ int threshold_type );
+
+/** @brief Applies adaptive threshold to grayscale image.
+
+ The two parameters for methods CV_ADAPTIVE_THRESH_MEAN_C and
+ CV_ADAPTIVE_THRESH_GAUSSIAN_C are:
+ neighborhood size (3, 5, 7 etc.),
+ and a constant subtracted from mean (...,-3,-2,-1,0,1,2,3,...)
+@see cv::adaptiveThreshold
+*/
+CVAPI(void) cvAdaptiveThreshold( const CvArr* src, CvArr* dst, double max_value,
+ int adaptive_method CV_DEFAULT(CV_ADAPTIVE_THRESH_MEAN_C),
+ int threshold_type CV_DEFAULT(CV_THRESH_BINARY),
+ int block_size CV_DEFAULT(3),
+ double param1 CV_DEFAULT(5));
+
+/** @brief Fills the connected component until the color difference gets large enough
+@see cv::floodFill
+*/
+CVAPI(void) cvFloodFill( CvArr* image, CvPoint seed_point,
+ CvScalar new_val, CvScalar lo_diff CV_DEFAULT(cvScalarAll(0)),
+ CvScalar up_diff CV_DEFAULT(cvScalarAll(0)),
+ CvConnectedComp* comp CV_DEFAULT(NULL),
+ int flags CV_DEFAULT(4),
+ CvArr* mask CV_DEFAULT(NULL));
+
+/****************************************************************************************\
+* Feature detection *
+\****************************************************************************************/
+
+/** @brief Runs canny edge detector
+@see cv::Canny
+*/
+CVAPI(void) cvCanny( const CvArr* image, CvArr* edges, double threshold1,
+ double threshold2, int aperture_size CV_DEFAULT(3) );
+
+/** @brief Calculates constraint image for corner detection
+
+ Dx^2 * Dyy + Dxx * Dy^2 - 2 * Dx * Dy * Dxy.
+ Applying threshold to the result gives coordinates of corners
+@see cv::preCornerDetect
+*/
+CVAPI(void) cvPreCornerDetect( const CvArr* image, CvArr* corners,
+ int aperture_size CV_DEFAULT(3) );
+
+/** @brief Calculates eigen values and vectors of 2x2
+ gradient covariation matrix at every image pixel
+@see cv::cornerEigenValsAndVecs
+*/
+CVAPI(void) cvCornerEigenValsAndVecs( const CvArr* image, CvArr* eigenvv,
+ int block_size, int aperture_size CV_DEFAULT(3) );
+
+/** @brief Calculates minimal eigenvalue for 2x2 gradient covariation matrix at
+ every image pixel
+@see cv::cornerMinEigenVal
+*/
+CVAPI(void) cvCornerMinEigenVal( const CvArr* image, CvArr* eigenval,
+ int block_size, int aperture_size CV_DEFAULT(3) );
+
+/** @brief Harris corner detector:
+
+ Calculates det(M) - k*(trace(M)^2), where M is 2x2 gradient covariation matrix for each pixel
+@see cv::cornerHarris
+*/
+CVAPI(void) cvCornerHarris( const CvArr* image, CvArr* harris_response,
+ int block_size, int aperture_size CV_DEFAULT(3),
+ double k CV_DEFAULT(0.04) );
+
+/** @brief Adjust corner position using some sort of gradient search
+@see cv::cornerSubPix
+*/
+CVAPI(void) cvFindCornerSubPix( const CvArr* image, CvPoint2D32f* corners,
+ int count, CvSize win, CvSize zero_zone,
+ CvTermCriteria criteria );
+
+/** @brief Finds a sparse set of points within the selected region
+ that seem to be easy to track
+@see cv::goodFeaturesToTrack
+*/
+CVAPI(void) cvGoodFeaturesToTrack( const CvArr* image, CvArr* eig_image,
+ CvArr* temp_image, CvPoint2D32f* corners,
+ int* corner_count, double quality_level,
+ double min_distance,
+ const CvArr* mask CV_DEFAULT(NULL),
+ int block_size CV_DEFAULT(3),
+ int use_harris CV_DEFAULT(0),
+ double k CV_DEFAULT(0.04) );
+
+/** @brief Finds lines on binary image using one of several methods.
+
+ line_storage is either memory storage or 1 x _max number of lines_ CvMat, its
+ number of columns is changed by the function.
+ method is one of CV_HOUGH_*;
+ rho, theta and threshold are used for each of those methods;
+ param1 ~ line length, param2 ~ line gap - for probabilistic,
+ param1 ~ srn, param2 ~ stn - for multi-scale
+@see cv::HoughLines
+*/
+CVAPI(CvSeq*) cvHoughLines2( CvArr* image, void* line_storage, int method,
+ double rho, double theta, int threshold,
+ double param1 CV_DEFAULT(0), double param2 CV_DEFAULT(0),
+ double min_theta CV_DEFAULT(0), double max_theta CV_DEFAULT(CV_PI));
+
+/** @brief Finds circles in the image
+@see cv::HoughCircles
+*/
+CVAPI(CvSeq*) cvHoughCircles( CvArr* image, void* circle_storage,
+ int method, double dp, double min_dist,
+ double param1 CV_DEFAULT(100),
+ double param2 CV_DEFAULT(100),
+ int min_radius CV_DEFAULT(0),
+ int max_radius CV_DEFAULT(0));
+
+/** @brief Fits a line into set of 2d or 3d points in a robust way (M-estimator technique)
+@see cv::fitLine
+*/
+CVAPI(void) cvFitLine( const CvArr* points, int dist_type, double param,
+ double reps, double aeps, float* line );
+
+/****************************************************************************************\
+* Drawing *
+\****************************************************************************************/
+
+/****************************************************************************************\
+* Drawing functions work with images/matrices of arbitrary type. *
+* For color images the channel order is BGR[A] *
+* Antialiasing is supported only for 8-bit image now. *
+* All the functions include parameter color that means rgb value (that may be *
+* constructed with CV_RGB macro) for color images and brightness *
+* for grayscale images. *
+* If a drawn figure is partially or completely outside of the image, it is clipped.*
+\****************************************************************************************/
+
+#define CV_RGB( r, g, b ) cvScalar( (b), (g), (r), 0 )
+#define CV_FILLED -1
+
+#define CV_AA 16
+
+/** @brief Draws 4-connected, 8-connected or antialiased line segment connecting two points
+@see cv::line
+*/
+CVAPI(void) cvLine( CvArr* img, CvPoint pt1, CvPoint pt2,
+ CvScalar color, int thickness CV_DEFAULT(1),
+ int line_type CV_DEFAULT(8), int shift CV_DEFAULT(0) );
+
+/** @brief Draws a rectangle given two opposite corners of the rectangle (pt1 & pt2)
+
+ if thickness<0 (e.g. thickness == CV_FILLED), the filled box is drawn
+@see cv::rectangle
+*/
+CVAPI(void) cvRectangle( CvArr* img, CvPoint pt1, CvPoint pt2,
+ CvScalar color, int thickness CV_DEFAULT(1),
+ int line_type CV_DEFAULT(8),
+ int shift CV_DEFAULT(0));
+
+/** @brief Draws a rectangle specified by a CvRect structure
+@see cv::rectangle
+*/
+CVAPI(void) cvRectangleR( CvArr* img, CvRect r,
+ CvScalar color, int thickness CV_DEFAULT(1),
+ int line_type CV_DEFAULT(8),
+ int shift CV_DEFAULT(0));
+
+
+/** @brief Draws a circle with specified center and radius.
+
+ Thickness works in the same way as with cvRectangle
+@see cv::circle
+*/
+CVAPI(void) cvCircle( CvArr* img, CvPoint center, int radius,
+ CvScalar color, int thickness CV_DEFAULT(1),
+ int line_type CV_DEFAULT(8), int shift CV_DEFAULT(0));
+
+/** @brief Draws ellipse outline, filled ellipse, elliptic arc or filled elliptic sector
+
+ depending on _thickness_, _start_angle_ and _end_angle_ parameters. The resultant figure
+ is rotated by _angle_. All the angles are in degrees
+@see cv::ellipse
+*/
+CVAPI(void) cvEllipse( CvArr* img, CvPoint center, CvSize axes,
+ double angle, double start_angle, double end_angle,
+ CvScalar color, int thickness CV_DEFAULT(1),
+ int line_type CV_DEFAULT(8), int shift CV_DEFAULT(0));
+
+CV_INLINE void cvEllipseBox( CvArr* img, CvBox2D box, CvScalar color,
+ int thickness CV_DEFAULT(1),
+ int line_type CV_DEFAULT(8), int shift CV_DEFAULT(0) )
+{
+ CvSize axes;
+ axes.width = cvRound(box.size.width*0.5);
+ axes.height = cvRound(box.size.height*0.5);
+
+ cvEllipse( img, cvPointFrom32f( box.center ), axes, box.angle,
+ 0, 360, color, thickness, line_type, shift );
+}
+
+/** @brief Fills convex or monotonous polygon.
+@see cv::fillConvexPoly
+*/
+CVAPI(void) cvFillConvexPoly( CvArr* img, const CvPoint* pts, int npts, CvScalar color,
+ int line_type CV_DEFAULT(8), int shift CV_DEFAULT(0));
+
+/** @brief Fills an area bounded by one or more arbitrary polygons
+@see cv::fillPoly
+*/
+CVAPI(void) cvFillPoly( CvArr* img, CvPoint** pts, const int* npts,
+ int contours, CvScalar color,
+ int line_type CV_DEFAULT(8), int shift CV_DEFAULT(0) );
+
+/** @brief Draws one or more polygonal curves
+@see cv::polylines
+*/
+CVAPI(void) cvPolyLine( CvArr* img, CvPoint** pts, const int* npts, int contours,
+ int is_closed, CvScalar color, int thickness CV_DEFAULT(1),
+ int line_type CV_DEFAULT(8), int shift CV_DEFAULT(0) );
+
+#define cvDrawRect cvRectangle
+#define cvDrawLine cvLine
+#define cvDrawCircle cvCircle
+#define cvDrawEllipse cvEllipse
+#define cvDrawPolyLine cvPolyLine
+
+/** @brief Clips the line segment connecting *pt1 and *pt2
+ by the rectangular window
+
+ (0<=x<img_size.width, 0<=y<img_size.height).
+@see cv::clipLine
+*/
+CVAPI(int) cvClipLine( CvSize img_size, CvPoint* pt1, CvPoint* pt2 );
+
+/** @brief Initializes line iterator.
+
+Initially, line_iterator->ptr will point to pt1 (or pt2, see left_to_right description) location in
+the image. Returns the number of pixels on the line between the ending points.
+@see cv::LineIterator
+*/
+CVAPI(int) cvInitLineIterator( const CvArr* image, CvPoint pt1, CvPoint pt2,
+ CvLineIterator* line_iterator,
+ int connectivity CV_DEFAULT(8),
+ int left_to_right CV_DEFAULT(0));
+
+#define CV_NEXT_LINE_POINT( line_iterator ) \
+{ \
+ int _line_iterator_mask = (line_iterator).err < 0 ? -1 : 0; \
+ (line_iterator).err += (line_iterator).minus_delta + \
+ ((line_iterator).plus_delta & _line_iterator_mask); \
+ (line_iterator).ptr += (line_iterator).minus_step + \
+ ((line_iterator).plus_step & _line_iterator_mask); \
+}
+
+
+#define CV_FONT_HERSHEY_SIMPLEX 0
+#define CV_FONT_HERSHEY_PLAIN 1
+#define CV_FONT_HERSHEY_DUPLEX 2
+#define CV_FONT_HERSHEY_COMPLEX 3
+#define CV_FONT_HERSHEY_TRIPLEX 4
+#define CV_FONT_HERSHEY_COMPLEX_SMALL 5
+#define CV_FONT_HERSHEY_SCRIPT_SIMPLEX 6
+#define CV_FONT_HERSHEY_SCRIPT_COMPLEX 7
+
+#define CV_FONT_ITALIC 16
+
+#define CV_FONT_VECTOR0 CV_FONT_HERSHEY_SIMPLEX
+
+
+/** Font structure */
+typedef struct CvFont
+{
+ const char* nameFont; //Qt:nameFont
+ CvScalar color; //Qt:ColorFont -> cvScalar(blue_component, green_component, red_component[, alpha_component])
+ int font_face; //Qt: bool italic /** =CV_FONT_* */
+ const int* ascii; //!< font data and metrics
+ const int* greek;
+ const int* cyrillic;
+ float hscale, vscale;
+ float shear; //!< slope coefficient: 0 - normal, >0 - italic
+ int thickness; //!< Qt: weight /** letters thickness */
+ float dx; //!< horizontal interval between letters
+ int line_type; //!< Qt: PointSize
+}
+CvFont;
+
+/** @brief Initializes font structure (OpenCV 1.x API).
+
+The function initializes the font structure that can be passed to text rendering functions.
+
+@param font Pointer to the font structure initialized by the function
+@param font_face Font name identifier. See cv::HersheyFonts and corresponding old CV_* identifiers.
+@param hscale Horizontal scale. If equal to 1.0f , the characters have the original width
+depending on the font type. If equal to 0.5f , the characters are of half the original width.
+@param vscale Vertical scale. If equal to 1.0f , the characters have the original height depending
+on the font type. If equal to 0.5f , the characters are of half the original height.
+@param shear Approximate tangent of the character slope relative to the vertical line. A zero
+value means a non-italic font, 1.0f means about a 45 degree slope, etc.
+@param thickness Thickness of the text strokes
+@param line_type Type of the strokes, see line description
+
+@sa cvPutText
+ */
+CVAPI(void) cvInitFont( CvFont* font, int font_face,
+ double hscale, double vscale,
+ double shear CV_DEFAULT(0),
+ int thickness CV_DEFAULT(1),
+ int line_type CV_DEFAULT(8));
+
+CV_INLINE CvFont cvFont( double scale, int thickness CV_DEFAULT(1) )
+{
+ CvFont font;
+ cvInitFont( &font, CV_FONT_HERSHEY_PLAIN, scale, scale, 0, thickness, CV_AA );
+ return font;
+}
+
+/** @brief Renders text stroke with specified font and color at specified location.
+ CvFont should be initialized with cvInitFont
+@see cvInitFont, cvGetTextSize, cvFont, cv::putText
+*/
+CVAPI(void) cvPutText( CvArr* img, const char* text, CvPoint org,
+ const CvFont* font, CvScalar color );
+
+/** @brief Calculates bounding box of text stroke (useful for alignment)
+@see cv::getTextSize
+*/
+CVAPI(void) cvGetTextSize( const char* text_string, const CvFont* font,
+ CvSize* text_size, int* baseline );
+
+/** @brief Unpacks color value
+
+if arrtype is CV_8UC?, _color_ is treated as packed color value, otherwise the first channels
+(depending on arrtype) of destination scalar are set to the same value = _color_
+*/
+CVAPI(CvScalar) cvColorToScalar( double packed_color, int arrtype );
+
+/** @brief Returns the polygon points which make up the given ellipse.
+
+The ellipse is define by the box of size 'axes' rotated 'angle' around the 'center'. A partial
+sweep of the ellipse arc can be done by spcifying arc_start and arc_end to be something other than
+0 and 360, respectively. The input array 'pts' must be large enough to hold the result. The total
+number of points stored into 'pts' is returned by this function.
+@see cv::ellipse2Poly
+*/
+CVAPI(int) cvEllipse2Poly( CvPoint center, CvSize axes,
+ int angle, int arc_start, int arc_end, CvPoint * pts, int delta );
+
+/** @brief Draws contour outlines or filled interiors on the image
+@see cv::drawContours
+*/
+CVAPI(void) cvDrawContours( CvArr *img, CvSeq* contour,
+ CvScalar external_color, CvScalar hole_color,
+ int max_level, int thickness CV_DEFAULT(1),
+ int line_type CV_DEFAULT(8),
+ CvPoint offset CV_DEFAULT(cvPoint(0,0)));
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/imgproc/types_c.h Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,626 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_IMGPROC_TYPES_C_H
+#define OPENCV_IMGPROC_TYPES_C_H
+
+#include "opencv2/core/core_c.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @addtogroup imgproc_c
+ @{
+*/
+
+/** Connected component structure */
+typedef struct CvConnectedComp
+{
+ double area; /**<area of the connected component */
+ CvScalar value; /**<average color of the connected component */
+ CvRect rect; /**<ROI of the component */
+ CvSeq* contour; /**<optional component boundary
+ (the contour might have child contours corresponding to the holes)*/
+}
+CvConnectedComp;
+
+/** Image smooth methods */
+enum SmoothMethod_c
+{
+ /** linear convolution with \f$\texttt{size1}\times\texttt{size2}\f$ box kernel (all 1's). If
+ you want to smooth different pixels with different-size box kernels, you can use the integral
+ image that is computed using integral */
+ CV_BLUR_NO_SCALE =0,
+ /** linear convolution with \f$\texttt{size1}\times\texttt{size2}\f$ box kernel (all
+ 1's) with subsequent scaling by \f$1/(\texttt{size1}\cdot\texttt{size2})\f$ */
+ CV_BLUR =1,
+ /** linear convolution with a \f$\texttt{size1}\times\texttt{size2}\f$ Gaussian kernel */
+ CV_GAUSSIAN =2,
+ /** median filter with a \f$\texttt{size1}\times\texttt{size1}\f$ square aperture */
+ CV_MEDIAN =3,
+ /** bilateral filter with a \f$\texttt{size1}\times\texttt{size1}\f$ square aperture, color
+ sigma= sigma1 and spatial sigma= sigma2. If size1=0, the aperture square side is set to
+ cvRound(sigma2\*1.5)\*2+1. See cv::bilateralFilter */
+ CV_BILATERAL =4
+};
+
+/** Filters used in pyramid decomposition */
+enum
+{
+ CV_GAUSSIAN_5x5 = 7
+};
+
+/** Special filters */
+enum
+{
+ CV_SCHARR =-1,
+ CV_MAX_SOBEL_KSIZE =7
+};
+
+/** Constants for color conversion */
+enum
+{
+ CV_BGR2BGRA =0,
+ CV_RGB2RGBA =CV_BGR2BGRA,
+
+ CV_BGRA2BGR =1,
+ CV_RGBA2RGB =CV_BGRA2BGR,
+
+ CV_BGR2RGBA =2,
+ CV_RGB2BGRA =CV_BGR2RGBA,
+
+ CV_RGBA2BGR =3,
+ CV_BGRA2RGB =CV_RGBA2BGR,
+
+ CV_BGR2RGB =4,
+ CV_RGB2BGR =CV_BGR2RGB,
+
+ CV_BGRA2RGBA =5,
+ CV_RGBA2BGRA =CV_BGRA2RGBA,
+
+ CV_BGR2GRAY =6,
+ CV_RGB2GRAY =7,
+ CV_GRAY2BGR =8,
+ CV_GRAY2RGB =CV_GRAY2BGR,
+ CV_GRAY2BGRA =9,
+ CV_GRAY2RGBA =CV_GRAY2BGRA,
+ CV_BGRA2GRAY =10,
+ CV_RGBA2GRAY =11,
+
+ CV_BGR2BGR565 =12,
+ CV_RGB2BGR565 =13,
+ CV_BGR5652BGR =14,
+ CV_BGR5652RGB =15,
+ CV_BGRA2BGR565 =16,
+ CV_RGBA2BGR565 =17,
+ CV_BGR5652BGRA =18,
+ CV_BGR5652RGBA =19,
+
+ CV_GRAY2BGR565 =20,
+ CV_BGR5652GRAY =21,
+
+ CV_BGR2BGR555 =22,
+ CV_RGB2BGR555 =23,
+ CV_BGR5552BGR =24,
+ CV_BGR5552RGB =25,
+ CV_BGRA2BGR555 =26,
+ CV_RGBA2BGR555 =27,
+ CV_BGR5552BGRA =28,
+ CV_BGR5552RGBA =29,
+
+ CV_GRAY2BGR555 =30,
+ CV_BGR5552GRAY =31,
+
+ CV_BGR2XYZ =32,
+ CV_RGB2XYZ =33,
+ CV_XYZ2BGR =34,
+ CV_XYZ2RGB =35,
+
+ CV_BGR2YCrCb =36,
+ CV_RGB2YCrCb =37,
+ CV_YCrCb2BGR =38,
+ CV_YCrCb2RGB =39,
+
+ CV_BGR2HSV =40,
+ CV_RGB2HSV =41,
+
+ CV_BGR2Lab =44,
+ CV_RGB2Lab =45,
+
+ CV_BayerBG2BGR =46,
+ CV_BayerGB2BGR =47,
+ CV_BayerRG2BGR =48,
+ CV_BayerGR2BGR =49,
+
+ CV_BayerBG2RGB =CV_BayerRG2BGR,
+ CV_BayerGB2RGB =CV_BayerGR2BGR,
+ CV_BayerRG2RGB =CV_BayerBG2BGR,
+ CV_BayerGR2RGB =CV_BayerGB2BGR,
+
+ CV_BGR2Luv =50,
+ CV_RGB2Luv =51,
+ CV_BGR2HLS =52,
+ CV_RGB2HLS =53,
+
+ CV_HSV2BGR =54,
+ CV_HSV2RGB =55,
+
+ CV_Lab2BGR =56,
+ CV_Lab2RGB =57,
+ CV_Luv2BGR =58,
+ CV_Luv2RGB =59,
+ CV_HLS2BGR =60,
+ CV_HLS2RGB =61,
+
+ CV_BayerBG2BGR_VNG =62,
+ CV_BayerGB2BGR_VNG =63,
+ CV_BayerRG2BGR_VNG =64,
+ CV_BayerGR2BGR_VNG =65,
+
+ CV_BayerBG2RGB_VNG =CV_BayerRG2BGR_VNG,
+ CV_BayerGB2RGB_VNG =CV_BayerGR2BGR_VNG,
+ CV_BayerRG2RGB_VNG =CV_BayerBG2BGR_VNG,
+ CV_BayerGR2RGB_VNG =CV_BayerGB2BGR_VNG,
+
+ CV_BGR2HSV_FULL = 66,
+ CV_RGB2HSV_FULL = 67,
+ CV_BGR2HLS_FULL = 68,
+ CV_RGB2HLS_FULL = 69,
+
+ CV_HSV2BGR_FULL = 70,
+ CV_HSV2RGB_FULL = 71,
+ CV_HLS2BGR_FULL = 72,
+ CV_HLS2RGB_FULL = 73,
+
+ CV_LBGR2Lab = 74,
+ CV_LRGB2Lab = 75,
+ CV_LBGR2Luv = 76,
+ CV_LRGB2Luv = 77,
+
+ CV_Lab2LBGR = 78,
+ CV_Lab2LRGB = 79,
+ CV_Luv2LBGR = 80,
+ CV_Luv2LRGB = 81,
+
+ CV_BGR2YUV = 82,
+ CV_RGB2YUV = 83,
+ CV_YUV2BGR = 84,
+ CV_YUV2RGB = 85,
+
+ CV_BayerBG2GRAY = 86,
+ CV_BayerGB2GRAY = 87,
+ CV_BayerRG2GRAY = 88,
+ CV_BayerGR2GRAY = 89,
+
+ //YUV 4:2:0 formats family
+ CV_YUV2RGB_NV12 = 90,
+ CV_YUV2BGR_NV12 = 91,
+ CV_YUV2RGB_NV21 = 92,
+ CV_YUV2BGR_NV21 = 93,
+ CV_YUV420sp2RGB = CV_YUV2RGB_NV21,
+ CV_YUV420sp2BGR = CV_YUV2BGR_NV21,
+
+ CV_YUV2RGBA_NV12 = 94,
+ CV_YUV2BGRA_NV12 = 95,
+ CV_YUV2RGBA_NV21 = 96,
+ CV_YUV2BGRA_NV21 = 97,
+ CV_YUV420sp2RGBA = CV_YUV2RGBA_NV21,
+ CV_YUV420sp2BGRA = CV_YUV2BGRA_NV21,
+
+ CV_YUV2RGB_YV12 = 98,
+ CV_YUV2BGR_YV12 = 99,
+ CV_YUV2RGB_IYUV = 100,
+ CV_YUV2BGR_IYUV = 101,
+ CV_YUV2RGB_I420 = CV_YUV2RGB_IYUV,
+ CV_YUV2BGR_I420 = CV_YUV2BGR_IYUV,
+ CV_YUV420p2RGB = CV_YUV2RGB_YV12,
+ CV_YUV420p2BGR = CV_YUV2BGR_YV12,
+
+ CV_YUV2RGBA_YV12 = 102,
+ CV_YUV2BGRA_YV12 = 103,
+ CV_YUV2RGBA_IYUV = 104,
+ CV_YUV2BGRA_IYUV = 105,
+ CV_YUV2RGBA_I420 = CV_YUV2RGBA_IYUV,
+ CV_YUV2BGRA_I420 = CV_YUV2BGRA_IYUV,
+ CV_YUV420p2RGBA = CV_YUV2RGBA_YV12,
+ CV_YUV420p2BGRA = CV_YUV2BGRA_YV12,
+
+ CV_YUV2GRAY_420 = 106,
+ CV_YUV2GRAY_NV21 = CV_YUV2GRAY_420,
+ CV_YUV2GRAY_NV12 = CV_YUV2GRAY_420,
+ CV_YUV2GRAY_YV12 = CV_YUV2GRAY_420,
+ CV_YUV2GRAY_IYUV = CV_YUV2GRAY_420,
+ CV_YUV2GRAY_I420 = CV_YUV2GRAY_420,
+ CV_YUV420sp2GRAY = CV_YUV2GRAY_420,
+ CV_YUV420p2GRAY = CV_YUV2GRAY_420,
+
+ //YUV 4:2:2 formats family
+ CV_YUV2RGB_UYVY = 107,
+ CV_YUV2BGR_UYVY = 108,
+ //CV_YUV2RGB_VYUY = 109,
+ //CV_YUV2BGR_VYUY = 110,
+ CV_YUV2RGB_Y422 = CV_YUV2RGB_UYVY,
+ CV_YUV2BGR_Y422 = CV_YUV2BGR_UYVY,
+ CV_YUV2RGB_UYNV = CV_YUV2RGB_UYVY,
+ CV_YUV2BGR_UYNV = CV_YUV2BGR_UYVY,
+
+ CV_YUV2RGBA_UYVY = 111,
+ CV_YUV2BGRA_UYVY = 112,
+ //CV_YUV2RGBA_VYUY = 113,
+ //CV_YUV2BGRA_VYUY = 114,
+ CV_YUV2RGBA_Y422 = CV_YUV2RGBA_UYVY,
+ CV_YUV2BGRA_Y422 = CV_YUV2BGRA_UYVY,
+ CV_YUV2RGBA_UYNV = CV_YUV2RGBA_UYVY,
+ CV_YUV2BGRA_UYNV = CV_YUV2BGRA_UYVY,
+
+ CV_YUV2RGB_YUY2 = 115,
+ CV_YUV2BGR_YUY2 = 116,
+ CV_YUV2RGB_YVYU = 117,
+ CV_YUV2BGR_YVYU = 118,
+ CV_YUV2RGB_YUYV = CV_YUV2RGB_YUY2,
+ CV_YUV2BGR_YUYV = CV_YUV2BGR_YUY2,
+ CV_YUV2RGB_YUNV = CV_YUV2RGB_YUY2,
+ CV_YUV2BGR_YUNV = CV_YUV2BGR_YUY2,
+
+ CV_YUV2RGBA_YUY2 = 119,
+ CV_YUV2BGRA_YUY2 = 120,
+ CV_YUV2RGBA_YVYU = 121,
+ CV_YUV2BGRA_YVYU = 122,
+ CV_YUV2RGBA_YUYV = CV_YUV2RGBA_YUY2,
+ CV_YUV2BGRA_YUYV = CV_YUV2BGRA_YUY2,
+ CV_YUV2RGBA_YUNV = CV_YUV2RGBA_YUY2,
+ CV_YUV2BGRA_YUNV = CV_YUV2BGRA_YUY2,
+
+ CV_YUV2GRAY_UYVY = 123,
+ CV_YUV2GRAY_YUY2 = 124,
+ //CV_YUV2GRAY_VYUY = CV_YUV2GRAY_UYVY,
+ CV_YUV2GRAY_Y422 = CV_YUV2GRAY_UYVY,
+ CV_YUV2GRAY_UYNV = CV_YUV2GRAY_UYVY,
+ CV_YUV2GRAY_YVYU = CV_YUV2GRAY_YUY2,
+ CV_YUV2GRAY_YUYV = CV_YUV2GRAY_YUY2,
+ CV_YUV2GRAY_YUNV = CV_YUV2GRAY_YUY2,
+
+ // alpha premultiplication
+ CV_RGBA2mRGBA = 125,
+ CV_mRGBA2RGBA = 126,
+
+ CV_RGB2YUV_I420 = 127,
+ CV_BGR2YUV_I420 = 128,
+ CV_RGB2YUV_IYUV = CV_RGB2YUV_I420,
+ CV_BGR2YUV_IYUV = CV_BGR2YUV_I420,
+
+ CV_RGBA2YUV_I420 = 129,
+ CV_BGRA2YUV_I420 = 130,
+ CV_RGBA2YUV_IYUV = CV_RGBA2YUV_I420,
+ CV_BGRA2YUV_IYUV = CV_BGRA2YUV_I420,
+ CV_RGB2YUV_YV12 = 131,
+ CV_BGR2YUV_YV12 = 132,
+ CV_RGBA2YUV_YV12 = 133,
+ CV_BGRA2YUV_YV12 = 134,
+
+ // Edge-Aware Demosaicing
+ CV_BayerBG2BGR_EA = 135,
+ CV_BayerGB2BGR_EA = 136,
+ CV_BayerRG2BGR_EA = 137,
+ CV_BayerGR2BGR_EA = 138,
+
+ CV_BayerBG2RGB_EA = CV_BayerRG2BGR_EA,
+ CV_BayerGB2RGB_EA = CV_BayerGR2BGR_EA,
+ CV_BayerRG2RGB_EA = CV_BayerBG2BGR_EA,
+ CV_BayerGR2RGB_EA = CV_BayerGB2BGR_EA,
+
+ CV_COLORCVT_MAX = 139
+};
+
+
+/** Sub-pixel interpolation methods */
+enum
+{
+ CV_INTER_NN =0,
+ CV_INTER_LINEAR =1,
+ CV_INTER_CUBIC =2,
+ CV_INTER_AREA =3,
+ CV_INTER_LANCZOS4 =4
+};
+
+/** ... and other image warping flags */
+enum
+{
+ CV_WARP_FILL_OUTLIERS =8,
+ CV_WARP_INVERSE_MAP =16
+};
+
+/** Shapes of a structuring element for morphological operations
+@see cv::MorphShapes, cv::getStructuringElement
+*/
+enum MorphShapes_c
+{
+ CV_SHAPE_RECT =0,
+ CV_SHAPE_CROSS =1,
+ CV_SHAPE_ELLIPSE =2,
+ CV_SHAPE_CUSTOM =100 //!< custom structuring element
+};
+
+/** Morphological operations */
+enum
+{
+ CV_MOP_ERODE =0,
+ CV_MOP_DILATE =1,
+ CV_MOP_OPEN =2,
+ CV_MOP_CLOSE =3,
+ CV_MOP_GRADIENT =4,
+ CV_MOP_TOPHAT =5,
+ CV_MOP_BLACKHAT =6
+};
+
+/** Spatial and central moments */
+typedef struct CvMoments
+{
+ double m00, m10, m01, m20, m11, m02, m30, m21, m12, m03; /**< spatial moments */
+ double mu20, mu11, mu02, mu30, mu21, mu12, mu03; /**< central moments */
+ double inv_sqrt_m00; /**< m00 != 0 ? 1/sqrt(m00) : 0 */
+
+#ifdef __cplusplus
+ CvMoments(){}
+ CvMoments(const cv::Moments& m)
+ {
+ m00 = m.m00; m10 = m.m10; m01 = m.m01;
+ m20 = m.m20; m11 = m.m11; m02 = m.m02;
+ m30 = m.m30; m21 = m.m21; m12 = m.m12; m03 = m.m03;
+ mu20 = m.mu20; mu11 = m.mu11; mu02 = m.mu02;
+ mu30 = m.mu30; mu21 = m.mu21; mu12 = m.mu12; mu03 = m.mu03;
+ double am00 = std::abs(m.m00);
+ inv_sqrt_m00 = am00 > DBL_EPSILON ? 1./std::sqrt(am00) : 0;
+ }
+ operator cv::Moments() const
+ {
+ return cv::Moments(m00, m10, m01, m20, m11, m02, m30, m21, m12, m03);
+ }
+#endif
+}
+CvMoments;
+
+/** Hu invariants */
+typedef struct CvHuMoments
+{
+ double hu1, hu2, hu3, hu4, hu5, hu6, hu7; /**< Hu invariants */
+}
+CvHuMoments;
+
+/** Template matching methods */
+enum
+{
+ CV_TM_SQDIFF =0,
+ CV_TM_SQDIFF_NORMED =1,
+ CV_TM_CCORR =2,
+ CV_TM_CCORR_NORMED =3,
+ CV_TM_CCOEFF =4,
+ CV_TM_CCOEFF_NORMED =5
+};
+
+typedef float (CV_CDECL * CvDistanceFunction)( const float* a, const float* b, void* user_param );
+
+/** Contour retrieval modes */
+enum
+{
+ CV_RETR_EXTERNAL=0,
+ CV_RETR_LIST=1,
+ CV_RETR_CCOMP=2,
+ CV_RETR_TREE=3,
+ CV_RETR_FLOODFILL=4
+};
+
+/** Contour approximation methods */
+enum
+{
+ CV_CHAIN_CODE=0,
+ CV_CHAIN_APPROX_NONE=1,
+ CV_CHAIN_APPROX_SIMPLE=2,
+ CV_CHAIN_APPROX_TC89_L1=3,
+ CV_CHAIN_APPROX_TC89_KCOS=4,
+ CV_LINK_RUNS=5
+};
+
+/*
+Internal structure that is used for sequential retrieving contours from the image.
+It supports both hierarchical and plane variants of Suzuki algorithm.
+*/
+typedef struct _CvContourScanner* CvContourScanner;
+
+/** Freeman chain reader state */
+typedef struct CvChainPtReader
+{
+ CV_SEQ_READER_FIELDS()
+ char code;
+ CvPoint pt;
+ schar deltas[8][2];
+}
+CvChainPtReader;
+
+/** initializes 8-element array for fast access to 3x3 neighborhood of a pixel */
+#define CV_INIT_3X3_DELTAS( deltas, step, nch ) \
+ ((deltas)[0] = (nch), (deltas)[1] = -(step) + (nch), \
+ (deltas)[2] = -(step), (deltas)[3] = -(step) - (nch), \
+ (deltas)[4] = -(nch), (deltas)[5] = (step) - (nch), \
+ (deltas)[6] = (step), (deltas)[7] = (step) + (nch))
+
+
+/** Contour approximation algorithms */
+enum
+{
+ CV_POLY_APPROX_DP = 0
+};
+
+/** @brief Shape matching methods
+
+\f$A\f$ denotes object1,\f$B\f$ denotes object2
+
+\f$\begin{array}{l} m^A_i = \mathrm{sign} (h^A_i) \cdot \log{h^A_i} \\ m^B_i = \mathrm{sign} (h^B_i) \cdot \log{h^B_i} \end{array}\f$
+
+and \f$h^A_i, h^B_i\f$ are the Hu moments of \f$A\f$ and \f$B\f$ , respectively.
+*/
+enum ShapeMatchModes
+{
+ CV_CONTOURS_MATCH_I1 =1, //!< \f[I_1(A,B) = \sum _{i=1...7} \left | \frac{1}{m^A_i} - \frac{1}{m^B_i} \right |\f]
+ CV_CONTOURS_MATCH_I2 =2, //!< \f[I_2(A,B) = \sum _{i=1...7} \left | m^A_i - m^B_i \right |\f]
+ CV_CONTOURS_MATCH_I3 =3 //!< \f[I_3(A,B) = \max _{i=1...7} \frac{ \left| m^A_i - m^B_i \right| }{ \left| m^A_i \right| }\f]
+};
+
+/** Shape orientation */
+enum
+{
+ CV_CLOCKWISE =1,
+ CV_COUNTER_CLOCKWISE =2
+};
+
+
+/** Convexity defect */
+typedef struct CvConvexityDefect
+{
+ CvPoint* start; /**< point of the contour where the defect begins */
+ CvPoint* end; /**< point of the contour where the defect ends */
+ CvPoint* depth_point; /**< the farthest from the convex hull point within the defect */
+ float depth; /**< distance between the farthest point and the convex hull */
+} CvConvexityDefect;
+
+
+/** Histogram comparison methods */
+enum
+{
+ CV_COMP_CORREL =0,
+ CV_COMP_CHISQR =1,
+ CV_COMP_INTERSECT =2,
+ CV_COMP_BHATTACHARYYA =3,
+ CV_COMP_HELLINGER =CV_COMP_BHATTACHARYYA,
+ CV_COMP_CHISQR_ALT =4,
+ CV_COMP_KL_DIV =5
+};
+
+/** Mask size for distance transform */
+enum
+{
+ CV_DIST_MASK_3 =3,
+ CV_DIST_MASK_5 =5,
+ CV_DIST_MASK_PRECISE =0
+};
+
+/** Content of output label array: connected components or pixels */
+enum
+{
+ CV_DIST_LABEL_CCOMP = 0,
+ CV_DIST_LABEL_PIXEL = 1
+};
+
+/** Distance types for Distance Transform and M-estimators */
+enum
+{
+ CV_DIST_USER =-1, /**< User defined distance */
+ CV_DIST_L1 =1, /**< distance = |x1-x2| + |y1-y2| */
+ CV_DIST_L2 =2, /**< the simple euclidean distance */
+ CV_DIST_C =3, /**< distance = max(|x1-x2|,|y1-y2|) */
+ CV_DIST_L12 =4, /**< L1-L2 metric: distance = 2(sqrt(1+x*x/2) - 1)) */
+ CV_DIST_FAIR =5, /**< distance = c^2(|x|/c-log(1+|x|/c)), c = 1.3998 */
+ CV_DIST_WELSCH =6, /**< distance = c^2/2(1-exp(-(x/c)^2)), c = 2.9846 */
+ CV_DIST_HUBER =7 /**< distance = |x|<c ? x^2/2 : c(|x|-c/2), c=1.345 */
+};
+
+
+/** Threshold types */
+enum
+{
+ CV_THRESH_BINARY =0, /**< value = value > threshold ? max_value : 0 */
+ CV_THRESH_BINARY_INV =1, /**< value = value > threshold ? 0 : max_value */
+ CV_THRESH_TRUNC =2, /**< value = value > threshold ? threshold : value */
+ CV_THRESH_TOZERO =3, /**< value = value > threshold ? value : 0 */
+ CV_THRESH_TOZERO_INV =4, /**< value = value > threshold ? 0 : value */
+ CV_THRESH_MASK =7,
+ CV_THRESH_OTSU =8, /**< use Otsu algorithm to choose the optimal threshold value;
+ combine the flag with one of the above CV_THRESH_* values */
+ CV_THRESH_TRIANGLE =16 /**< use Triangle algorithm to choose the optimal threshold value;
+ combine the flag with one of the above CV_THRESH_* values, but not
+ with CV_THRESH_OTSU */
+};
+
+/** Adaptive threshold methods */
+enum
+{
+ CV_ADAPTIVE_THRESH_MEAN_C =0,
+ CV_ADAPTIVE_THRESH_GAUSSIAN_C =1
+};
+
+/** FloodFill flags */
+enum
+{
+ CV_FLOODFILL_FIXED_RANGE =(1 << 16),
+ CV_FLOODFILL_MASK_ONLY =(1 << 17)
+};
+
+
+/** Canny edge detector flags */
+enum
+{
+ CV_CANNY_L2_GRADIENT =(1 << 31)
+};
+
+/** Variants of a Hough transform */
+enum
+{
+ CV_HOUGH_STANDARD =0,
+ CV_HOUGH_PROBABILISTIC =1,
+ CV_HOUGH_MULTI_SCALE =2,
+ CV_HOUGH_GRADIENT =3
+};
+
+
+/* Fast search data structures */
+struct CvFeatureTree;
+struct CvLSH;
+struct CvLSHOperations;
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/ml.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,1690 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000, Intel Corporation, all rights reserved.
+// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
+// Copyright (C) 2014, Itseez Inc, all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_ML_HPP
+#define OPENCV_ML_HPP
+
+#ifdef __cplusplus
+# include "opencv2/core.hpp"
+#endif
+
+#ifdef __cplusplus
+
+#include <float.h>
+#include <map>
+#include <iostream>
+
+/**
+ @defgroup ml Machine Learning
+
+ The Machine Learning Library (MLL) is a set of classes and functions for statistical
+ classification, regression, and clustering of data.
+
+ Most of the classification and regression algorithms are implemented as C++ classes. As the
+ algorithms have different sets of features (like an ability to handle missing measurements or
+ categorical input variables), there is a little common ground between the classes. This common
+ ground is defined by the class cv::ml::StatModel that all the other ML classes are derived from.
+
+ See detailed overview here: @ref ml_intro.
+ */
+
+namespace cv
+{
+
+namespace ml
+{
+
+//! @addtogroup ml
+//! @{
+
+/** @brief Variable types */
+enum VariableTypes
+{
+ VAR_NUMERICAL =0, //!< same as VAR_ORDERED
+ VAR_ORDERED =0, //!< ordered variables
+ VAR_CATEGORICAL =1 //!< categorical variables
+};
+
+/** @brief %Error types */
+enum ErrorTypes
+{
+ TEST_ERROR = 0,
+ TRAIN_ERROR = 1
+};
+
+/** @brief Sample types */
+enum SampleTypes
+{
+ ROW_SAMPLE = 0, //!< each training sample is a row of samples
+ COL_SAMPLE = 1 //!< each training sample occupies a column of samples
+};
+
+/** @brief The structure represents the logarithmic grid range of statmodel parameters.
+
+It is used for optimizing statmodel accuracy by varying model parameters, the accuracy estimate
+being computed by cross-validation.
+ */
+class CV_EXPORTS ParamGrid
+{
+public:
+ /** @brief Default constructor */
+ ParamGrid();
+ /** @brief Constructor with parameters */
+ ParamGrid(double _minVal, double _maxVal, double _logStep);
+
+ double minVal; //!< Minimum value of the statmodel parameter. Default value is 0.
+ double maxVal; //!< Maximum value of the statmodel parameter. Default value is 0.
+ /** @brief Logarithmic step for iterating the statmodel parameter.
+
+ The grid determines the following iteration sequence of the statmodel parameter values:
+ \f[(minVal, minVal*step, minVal*{step}^2, \dots, minVal*{logStep}^n),\f]
+ where \f$n\f$ is the maximal index satisfying
+ \f[\texttt{minVal} * \texttt{logStep} ^n < \texttt{maxVal}\f]
+ The grid is logarithmic, so logStep must always be greater then 1. Default value is 1.
+ */
+ double logStep;
+};
+
+/** @brief Class encapsulating training data.
+
+Please note that the class only specifies the interface of training data, but not implementation.
+All the statistical model classes in _ml_ module accepts Ptr\<TrainData\> as parameter. In other
+words, you can create your own class derived from TrainData and pass smart pointer to the instance
+of this class into StatModel::train.
+
+@sa @ref ml_intro_data
+ */
+class CV_EXPORTS_W TrainData
+{
+public:
+ static inline float missingValue() { return FLT_MAX; }
+ virtual ~TrainData();
+
+ CV_WRAP virtual int getLayout() const = 0;
+ CV_WRAP virtual int getNTrainSamples() const = 0;
+ CV_WRAP virtual int getNTestSamples() const = 0;
+ CV_WRAP virtual int getNSamples() const = 0;
+ CV_WRAP virtual int getNVars() const = 0;
+ CV_WRAP virtual int getNAllVars() const = 0;
+
+ CV_WRAP virtual void getSample(InputArray varIdx, int sidx, float* buf) const = 0;
+ CV_WRAP virtual Mat getSamples() const = 0;
+ CV_WRAP virtual Mat getMissing() const = 0;
+
+ /** @brief Returns matrix of train samples
+
+ @param layout The requested layout. If it's different from the initial one, the matrix is
+ transposed. See ml::SampleTypes.
+ @param compressSamples if true, the function returns only the training samples (specified by
+ sampleIdx)
+ @param compressVars if true, the function returns the shorter training samples, containing only
+ the active variables.
+
+ In current implementation the function tries to avoid physical data copying and returns the
+ matrix stored inside TrainData (unless the transposition or compression is needed).
+ */
+ CV_WRAP virtual Mat getTrainSamples(int layout=ROW_SAMPLE,
+ bool compressSamples=true,
+ bool compressVars=true) const = 0;
+
+ /** @brief Returns the vector of responses
+
+ The function returns ordered or the original categorical responses. Usually it's used in
+ regression algorithms.
+ */
+ CV_WRAP virtual Mat getTrainResponses() const = 0;
+
+ /** @brief Returns the vector of normalized categorical responses
+
+ The function returns vector of responses. Each response is integer from `0` to `<number of
+ classes>-1`. The actual label value can be retrieved then from the class label vector, see
+ TrainData::getClassLabels.
+ */
+ CV_WRAP virtual Mat getTrainNormCatResponses() const = 0;
+ CV_WRAP virtual Mat getTestResponses() const = 0;
+ CV_WRAP virtual Mat getTestNormCatResponses() const = 0;
+ CV_WRAP virtual Mat getResponses() const = 0;
+ CV_WRAP virtual Mat getNormCatResponses() const = 0;
+ CV_WRAP virtual Mat getSampleWeights() const = 0;
+ CV_WRAP virtual Mat getTrainSampleWeights() const = 0;
+ CV_WRAP virtual Mat getTestSampleWeights() const = 0;
+ CV_WRAP virtual Mat getVarIdx() const = 0;
+ CV_WRAP virtual Mat getVarType() const = 0;
+ CV_WRAP Mat getVarSymbolFlags() const;
+ CV_WRAP virtual int getResponseType() const = 0;
+ CV_WRAP virtual Mat getTrainSampleIdx() const = 0;
+ CV_WRAP virtual Mat getTestSampleIdx() const = 0;
+ CV_WRAP virtual void getValues(int vi, InputArray sidx, float* values) const = 0;
+ virtual void getNormCatValues(int vi, InputArray sidx, int* values) const = 0;
+ CV_WRAP virtual Mat getDefaultSubstValues() const = 0;
+
+ CV_WRAP virtual int getCatCount(int vi) const = 0;
+
+ /** @brief Returns the vector of class labels
+
+ The function returns vector of unique labels occurred in the responses.
+ */
+ CV_WRAP virtual Mat getClassLabels() const = 0;
+
+ CV_WRAP virtual Mat getCatOfs() const = 0;
+ CV_WRAP virtual Mat getCatMap() const = 0;
+
+ /** @brief Splits the training data into the training and test parts
+ @sa TrainData::setTrainTestSplitRatio
+ */
+ CV_WRAP virtual void setTrainTestSplit(int count, bool shuffle=true) = 0;
+
+ /** @brief Splits the training data into the training and test parts
+
+ The function selects a subset of specified relative size and then returns it as the training
+ set. If the function is not called, all the data is used for training. Please, note that for
+ each of TrainData::getTrain\* there is corresponding TrainData::getTest\*, so that the test
+ subset can be retrieved and processed as well.
+ @sa TrainData::setTrainTestSplit
+ */
+ CV_WRAP virtual void setTrainTestSplitRatio(double ratio, bool shuffle=true) = 0;
+ CV_WRAP virtual void shuffleTrainTest() = 0;
+
+ /** @brief Returns matrix of test samples */
+ CV_WRAP Mat getTestSamples() const;
+
+ /** @brief Returns vector of symbolic names captured in loadFromCSV() */
+ CV_WRAP void getNames(std::vector<String>& names) const;
+
+ CV_WRAP static Mat getSubVector(const Mat& vec, const Mat& idx);
+
+ /** @brief Reads the dataset from a .csv file and returns the ready-to-use training data.
+
+ @param filename The input file name
+ @param headerLineCount The number of lines in the beginning to skip; besides the header, the
+ function also skips empty lines and lines staring with `#`
+ @param responseStartIdx Index of the first output variable. If -1, the function considers the
+ last variable as the response
+ @param responseEndIdx Index of the last output variable + 1. If -1, then there is single
+ response variable at responseStartIdx.
+ @param varTypeSpec The optional text string that specifies the variables' types. It has the
+ format `ord[n1-n2,n3,n4-n5,...]cat[n6,n7-n8,...]`. That is, variables from `n1 to n2`
+ (inclusive range), `n3`, `n4 to n5` ... are considered ordered and `n6`, `n7 to n8` ... are
+ considered as categorical. The range `[n1..n2] + [n3] + [n4..n5] + ... + [n6] + [n7..n8]`
+ should cover all the variables. If varTypeSpec is not specified, then algorithm uses the
+ following rules:
+ - all input variables are considered ordered by default. If some column contains has non-
+ numerical values, e.g. 'apple', 'pear', 'apple', 'apple', 'mango', the corresponding
+ variable is considered categorical.
+ - if there are several output variables, they are all considered as ordered. Error is
+ reported when non-numerical values are used.
+ - if there is a single output variable, then if its values are non-numerical or are all
+ integers, then it's considered categorical. Otherwise, it's considered ordered.
+ @param delimiter The character used to separate values in each line.
+ @param missch The character used to specify missing measurements. It should not be a digit.
+ Although it's a non-numerical value, it surely does not affect the decision of whether the
+ variable ordered or categorical.
+ @note If the dataset only contains input variables and no responses, use responseStartIdx = -2
+ and responseEndIdx = 0. The output variables vector will just contain zeros.
+ */
+ static Ptr<TrainData> loadFromCSV(const String& filename,
+ int headerLineCount,
+ int responseStartIdx=-1,
+ int responseEndIdx=-1,
+ const String& varTypeSpec=String(),
+ char delimiter=',',
+ char missch='?');
+
+ /** @brief Creates training data from in-memory arrays.
+
+ @param samples matrix of samples. It should have CV_32F type.
+ @param layout see ml::SampleTypes.
+ @param responses matrix of responses. If the responses are scalar, they should be stored as a
+ single row or as a single column. The matrix should have type CV_32F or CV_32S (in the
+ former case the responses are considered as ordered by default; in the latter case - as
+ categorical)
+ @param varIdx vector specifying which variables to use for training. It can be an integer vector
+ (CV_32S) containing 0-based variable indices or byte vector (CV_8U) containing a mask of
+ active variables.
+ @param sampleIdx vector specifying which samples to use for training. It can be an integer
+ vector (CV_32S) containing 0-based sample indices or byte vector (CV_8U) containing a mask
+ of training samples.
+ @param sampleWeights optional vector with weights for each sample. It should have CV_32F type.
+ @param varType optional vector of type CV_8U and size `<number_of_variables_in_samples> +
+ <number_of_variables_in_responses>`, containing types of each input and output variable. See
+ ml::VariableTypes.
+ */
+ CV_WRAP static Ptr<TrainData> create(InputArray samples, int layout, InputArray responses,
+ InputArray varIdx=noArray(), InputArray sampleIdx=noArray(),
+ InputArray sampleWeights=noArray(), InputArray varType=noArray());
+};
+
+/** @brief Base class for statistical models in OpenCV ML.
+ */
+class CV_EXPORTS_W StatModel : public Algorithm
+{
+public:
+ /** Predict options */
+ enum Flags {
+ UPDATE_MODEL = 1,
+ RAW_OUTPUT=1, //!< makes the method return the raw results (the sum), not the class label
+ COMPRESSED_INPUT=2,
+ PREPROCESSED_INPUT=4
+ };
+
+ /** @brief Returns the number of variables in training samples */
+ CV_WRAP virtual int getVarCount() const = 0;
+
+ CV_WRAP virtual bool empty() const;
+
+ /** @brief Returns true if the model is trained */
+ CV_WRAP virtual bool isTrained() const = 0;
+ /** @brief Returns true if the model is classifier */
+ CV_WRAP virtual bool isClassifier() const = 0;
+
+ /** @brief Trains the statistical model
+
+ @param trainData training data that can be loaded from file using TrainData::loadFromCSV or
+ created with TrainData::create.
+ @param flags optional flags, depending on the model. Some of the models can be updated with the
+ new training samples, not completely overwritten (such as NormalBayesClassifier or ANN_MLP).
+ */
+ CV_WRAP virtual bool train( const Ptr<TrainData>& trainData, int flags=0 );
+
+ /** @brief Trains the statistical model
+
+ @param samples training samples
+ @param layout See ml::SampleTypes.
+ @param responses vector of responses associated with the training samples.
+ */
+ CV_WRAP virtual bool train( InputArray samples, int layout, InputArray responses );
+
+ /** @brief Computes error on the training or test dataset
+
+ @param data the training data
+ @param test if true, the error is computed over the test subset of the data, otherwise it's
+ computed over the training subset of the data. Please note that if you loaded a completely
+ different dataset to evaluate already trained classifier, you will probably want not to set
+ the test subset at all with TrainData::setTrainTestSplitRatio and specify test=false, so
+ that the error is computed for the whole new set. Yes, this sounds a bit confusing.
+ @param resp the optional output responses.
+
+ The method uses StatModel::predict to compute the error. For regression models the error is
+ computed as RMS, for classifiers - as a percent of missclassified samples (0%-100%).
+ */
+ CV_WRAP virtual float calcError( const Ptr<TrainData>& data, bool test, OutputArray resp ) const;
+
+ /** @brief Predicts response(s) for the provided sample(s)
+
+ @param samples The input samples, floating-point matrix
+ @param results The optional output matrix of results.
+ @param flags The optional flags, model-dependent. See cv::ml::StatModel::Flags.
+ */
+ CV_WRAP virtual float predict( InputArray samples, OutputArray results=noArray(), int flags=0 ) const = 0;
+
+ /** @brief Create and train model with default parameters
+
+ The class must implement static `create()` method with no parameters or with all default parameter values
+ */
+ template<typename _Tp> static Ptr<_Tp> train(const Ptr<TrainData>& data, int flags=0)
+ {
+ Ptr<_Tp> model = _Tp::create();
+ return !model.empty() && model->train(data, flags) ? model : Ptr<_Tp>();
+ }
+};
+
+/****************************************************************************************\
+* Normal Bayes Classifier *
+\****************************************************************************************/
+
+/** @brief Bayes classifier for normally distributed data.
+
+@sa @ref ml_intro_bayes
+ */
+class CV_EXPORTS_W NormalBayesClassifier : public StatModel
+{
+public:
+ /** @brief Predicts the response for sample(s).
+
+ The method estimates the most probable classes for input vectors. Input vectors (one or more)
+ are stored as rows of the matrix inputs. In case of multiple input vectors, there should be one
+ output vector outputs. The predicted class for a single input vector is returned by the method.
+ The vector outputProbs contains the output probabilities corresponding to each element of
+ result.
+ */
+ CV_WRAP virtual float predictProb( InputArray inputs, OutputArray outputs,
+ OutputArray outputProbs, int flags=0 ) const = 0;
+
+ /** Creates empty model
+ Use StatModel::train to train the model after creation. */
+ CV_WRAP static Ptr<NormalBayesClassifier> create();
+};
+
+/****************************************************************************************\
+* K-Nearest Neighbour Classifier *
+\****************************************************************************************/
+
+/** @brief The class implements K-Nearest Neighbors model
+
+@sa @ref ml_intro_knn
+ */
+class CV_EXPORTS_W KNearest : public StatModel
+{
+public:
+
+ /** Default number of neighbors to use in predict method. */
+ /** @see setDefaultK */
+ CV_WRAP virtual int getDefaultK() const = 0;
+ /** @copybrief getDefaultK @see getDefaultK */
+ CV_WRAP virtual void setDefaultK(int val) = 0;
+
+ /** Whether classification or regression model should be trained. */
+ /** @see setIsClassifier */
+ CV_WRAP virtual bool getIsClassifier() const = 0;
+ /** @copybrief getIsClassifier @see getIsClassifier */
+ CV_WRAP virtual void setIsClassifier(bool val) = 0;
+
+ /** Parameter for KDTree implementation. */
+ /** @see setEmax */
+ CV_WRAP virtual int getEmax() const = 0;
+ /** @copybrief getEmax @see getEmax */
+ CV_WRAP virtual void setEmax(int val) = 0;
+
+ /** %Algorithm type, one of KNearest::Types. */
+ /** @see setAlgorithmType */
+ CV_WRAP virtual int getAlgorithmType() const = 0;
+ /** @copybrief getAlgorithmType @see getAlgorithmType */
+ CV_WRAP virtual void setAlgorithmType(int val) = 0;
+
+ /** @brief Finds the neighbors and predicts responses for input vectors.
+
+ @param samples Input samples stored by rows. It is a single-precision floating-point matrix of
+ `<number_of_samples> * k` size.
+ @param k Number of used nearest neighbors. Should be greater than 1.
+ @param results Vector with results of prediction (regression or classification) for each input
+ sample. It is a single-precision floating-point vector with `<number_of_samples>` elements.
+ @param neighborResponses Optional output values for corresponding neighbors. It is a single-
+ precision floating-point matrix of `<number_of_samples> * k` size.
+ @param dist Optional output distances from the input vectors to the corresponding neighbors. It
+ is a single-precision floating-point matrix of `<number_of_samples> * k` size.
+
+ For each input vector (a row of the matrix samples), the method finds the k nearest neighbors.
+ In case of regression, the predicted result is a mean value of the particular vector's neighbor
+ responses. In case of classification, the class is determined by voting.
+
+ For each input vector, the neighbors are sorted by their distances to the vector.
+
+ In case of C++ interface you can use output pointers to empty matrices and the function will
+ allocate memory itself.
+
+ If only a single input vector is passed, all output matrices are optional and the predicted
+ value is returned by the method.
+
+ The function is parallelized with the TBB library.
+ */
+ CV_WRAP virtual float findNearest( InputArray samples, int k,
+ OutputArray results,
+ OutputArray neighborResponses=noArray(),
+ OutputArray dist=noArray() ) const = 0;
+
+ /** @brief Implementations of KNearest algorithm
+ */
+ enum Types
+ {
+ BRUTE_FORCE=1,
+ KDTREE=2
+ };
+
+ /** @brief Creates the empty model
+
+ The static method creates empty %KNearest classifier. It should be then trained using StatModel::train method.
+ */
+ CV_WRAP static Ptr<KNearest> create();
+};
+
+/****************************************************************************************\
+* Support Vector Machines *
+\****************************************************************************************/
+
+/** @brief Support Vector Machines.
+
+@sa @ref ml_intro_svm
+ */
+class CV_EXPORTS_W SVM : public StatModel
+{
+public:
+
+ class CV_EXPORTS Kernel : public Algorithm
+ {
+ public:
+ virtual int getType() const = 0;
+ virtual void calc( int vcount, int n, const float* vecs, const float* another, float* results ) = 0;
+ };
+
+ /** Type of a %SVM formulation.
+ See SVM::Types. Default value is SVM::C_SVC. */
+ /** @see setType */
+ CV_WRAP virtual int getType() const = 0;
+ /** @copybrief getType @see getType */
+ CV_WRAP virtual void setType(int val) = 0;
+
+ /** Parameter \f$\gamma\f$ of a kernel function.
+ For SVM::POLY, SVM::RBF, SVM::SIGMOID or SVM::CHI2. Default value is 1. */
+ /** @see setGamma */
+ CV_WRAP virtual double getGamma() const = 0;
+ /** @copybrief getGamma @see getGamma */
+ CV_WRAP virtual void setGamma(double val) = 0;
+
+ /** Parameter _coef0_ of a kernel function.
+ For SVM::POLY or SVM::SIGMOID. Default value is 0.*/
+ /** @see setCoef0 */
+ CV_WRAP virtual double getCoef0() const = 0;
+ /** @copybrief getCoef0 @see getCoef0 */
+ CV_WRAP virtual void setCoef0(double val) = 0;
+
+ /** Parameter _degree_ of a kernel function.
+ For SVM::POLY. Default value is 0. */
+ /** @see setDegree */
+ CV_WRAP virtual double getDegree() const = 0;
+ /** @copybrief getDegree @see getDegree */
+ CV_WRAP virtual void setDegree(double val) = 0;
+
+ /** Parameter _C_ of a %SVM optimization problem.
+ For SVM::C_SVC, SVM::EPS_SVR or SVM::NU_SVR. Default value is 0. */
+ /** @see setC */
+ CV_WRAP virtual double getC() const = 0;
+ /** @copybrief getC @see getC */
+ CV_WRAP virtual void setC(double val) = 0;
+
+ /** Parameter \f$\nu\f$ of a %SVM optimization problem.
+ For SVM::NU_SVC, SVM::ONE_CLASS or SVM::NU_SVR. Default value is 0. */
+ /** @see setNu */
+ CV_WRAP virtual double getNu() const = 0;
+ /** @copybrief getNu @see getNu */
+ CV_WRAP virtual void setNu(double val) = 0;
+
+ /** Parameter \f$\epsilon\f$ of a %SVM optimization problem.
+ For SVM::EPS_SVR. Default value is 0. */
+ /** @see setP */
+ CV_WRAP virtual double getP() const = 0;
+ /** @copybrief getP @see getP */
+ CV_WRAP virtual void setP(double val) = 0;
+
+ /** Optional weights in the SVM::C_SVC problem, assigned to particular classes.
+ They are multiplied by _C_ so the parameter _C_ of class _i_ becomes `classWeights(i) * C`. Thus
+ these weights affect the misclassification penalty for different classes. The larger weight,
+ the larger penalty on misclassification of data from the corresponding class. Default value is
+ empty Mat. */
+ /** @see setClassWeights */
+ CV_WRAP virtual cv::Mat getClassWeights() const = 0;
+ /** @copybrief getClassWeights @see getClassWeights */
+ CV_WRAP virtual void setClassWeights(const cv::Mat &val) = 0;
+
+ /** Termination criteria of the iterative %SVM training procedure which solves a partial
+ case of constrained quadratic optimization problem.
+ You can specify tolerance and/or the maximum number of iterations. Default value is
+ `TermCriteria( TermCriteria::MAX_ITER + TermCriteria::EPS, 1000, FLT_EPSILON )`; */
+ /** @see setTermCriteria */
+ CV_WRAP virtual cv::TermCriteria getTermCriteria() const = 0;
+ /** @copybrief getTermCriteria @see getTermCriteria */
+ CV_WRAP virtual void setTermCriteria(const cv::TermCriteria &val) = 0;
+
+ /** Type of a %SVM kernel.
+ See SVM::KernelTypes. Default value is SVM::RBF. */
+ CV_WRAP virtual int getKernelType() const = 0;
+
+ /** Initialize with one of predefined kernels.
+ See SVM::KernelTypes. */
+ CV_WRAP virtual void setKernel(int kernelType) = 0;
+
+ /** Initialize with custom kernel.
+ See SVM::Kernel class for implementation details */
+ virtual void setCustomKernel(const Ptr<Kernel> &_kernel) = 0;
+
+ //! %SVM type
+ enum Types {
+ /** C-Support Vector Classification. n-class classification (n \f$\geq\f$ 2), allows
+ imperfect separation of classes with penalty multiplier C for outliers. */
+ C_SVC=100,
+ /** \f$\nu\f$-Support Vector Classification. n-class classification with possible
+ imperfect separation. Parameter \f$\nu\f$ (in the range 0..1, the larger the value, the smoother
+ the decision boundary) is used instead of C. */
+ NU_SVC=101,
+ /** Distribution Estimation (One-class %SVM). All the training data are from
+ the same class, %SVM builds a boundary that separates the class from the rest of the feature
+ space. */
+ ONE_CLASS=102,
+ /** \f$\epsilon\f$-Support Vector Regression. The distance between feature vectors
+ from the training set and the fitting hyper-plane must be less than p. For outliers the
+ penalty multiplier C is used. */
+ EPS_SVR=103,
+ /** \f$\nu\f$-Support Vector Regression. \f$\nu\f$ is used instead of p.
+ See @cite LibSVM for details. */
+ NU_SVR=104
+ };
+
+ /** @brief %SVM kernel type
+
+ A comparison of different kernels on the following 2D test case with four classes. Four
+ SVM::C_SVC SVMs have been trained (one against rest) with auto_train. Evaluation on three
+ different kernels (SVM::CHI2, SVM::INTER, SVM::RBF). The color depicts the class with max score.
+ Bright means max-score \> 0, dark means max-score \< 0.
+ 
+ */
+ enum KernelTypes {
+ /** Returned by SVM::getKernelType in case when custom kernel has been set */
+ CUSTOM=-1,
+ /** Linear kernel. No mapping is done, linear discrimination (or regression) is
+ done in the original feature space. It is the fastest option. \f$K(x_i, x_j) = x_i^T x_j\f$. */
+ LINEAR=0,
+ /** Polynomial kernel:
+ \f$K(x_i, x_j) = (\gamma x_i^T x_j + coef0)^{degree}, \gamma > 0\f$. */
+ POLY=1,
+ /** Radial basis function (RBF), a good choice in most cases.
+ \f$K(x_i, x_j) = e^{-\gamma ||x_i - x_j||^2}, \gamma > 0\f$. */
+ RBF=2,
+ /** Sigmoid kernel: \f$K(x_i, x_j) = \tanh(\gamma x_i^T x_j + coef0)\f$. */
+ SIGMOID=3,
+ /** Exponential Chi2 kernel, similar to the RBF kernel:
+ \f$K(x_i, x_j) = e^{-\gamma \chi^2(x_i,x_j)}, \chi^2(x_i,x_j) = (x_i-x_j)^2/(x_i+x_j), \gamma > 0\f$. */
+ CHI2=4,
+ /** Histogram intersection kernel. A fast kernel. \f$K(x_i, x_j) = min(x_i,x_j)\f$. */
+ INTER=5
+ };
+
+ //! %SVM params type
+ enum ParamTypes {
+ C=0,
+ GAMMA=1,
+ P=2,
+ NU=3,
+ COEF=4,
+ DEGREE=5
+ };
+
+ /** @brief Trains an %SVM with optimal parameters.
+
+ @param data the training data that can be constructed using TrainData::create or
+ TrainData::loadFromCSV.
+ @param kFold Cross-validation parameter. The training set is divided into kFold subsets. One
+ subset is used to test the model, the others form the train set. So, the %SVM algorithm is
+ executed kFold times.
+ @param Cgrid grid for C
+ @param gammaGrid grid for gamma
+ @param pGrid grid for p
+ @param nuGrid grid for nu
+ @param coeffGrid grid for coeff
+ @param degreeGrid grid for degree
+ @param balanced If true and the problem is 2-class classification then the method creates more
+ balanced cross-validation subsets that is proportions between classes in subsets are close
+ to such proportion in the whole train dataset.
+
+ The method trains the %SVM model automatically by choosing the optimal parameters C, gamma, p,
+ nu, coef0, degree. Parameters are considered optimal when the cross-validation
+ estimate of the test set error is minimal.
+
+ If there is no need to optimize a parameter, the corresponding grid step should be set to any
+ value less than or equal to 1. For example, to avoid optimization in gamma, set `gammaGrid.step
+ = 0`, `gammaGrid.minVal`, `gamma_grid.maxVal` as arbitrary numbers. In this case, the value
+ `Gamma` is taken for gamma.
+
+ And, finally, if the optimization in a parameter is required but the corresponding grid is
+ unknown, you may call the function SVM::getDefaultGrid. To generate a grid, for example, for
+ gamma, call `SVM::getDefaultGrid(SVM::GAMMA)`.
+
+ This function works for the classification (SVM::C_SVC or SVM::NU_SVC) as well as for the
+ regression (SVM::EPS_SVR or SVM::NU_SVR). If it is SVM::ONE_CLASS, no optimization is made and
+ the usual %SVM with parameters specified in params is executed.
+ */
+ virtual bool trainAuto( const Ptr<TrainData>& data, int kFold = 10,
+ ParamGrid Cgrid = SVM::getDefaultGrid(SVM::C),
+ ParamGrid gammaGrid = SVM::getDefaultGrid(SVM::GAMMA),
+ ParamGrid pGrid = SVM::getDefaultGrid(SVM::P),
+ ParamGrid nuGrid = SVM::getDefaultGrid(SVM::NU),
+ ParamGrid coeffGrid = SVM::getDefaultGrid(SVM::COEF),
+ ParamGrid degreeGrid = SVM::getDefaultGrid(SVM::DEGREE),
+ bool balanced=false) = 0;
+
+ /** @brief Retrieves all the support vectors
+
+ The method returns all the support vectors as a floating-point matrix, where support vectors are
+ stored as matrix rows.
+ */
+ CV_WRAP virtual Mat getSupportVectors() const = 0;
+
+ /** @brief Retrieves all the uncompressed support vectors of a linear %SVM
+
+ The method returns all the uncompressed support vectors of a linear %SVM that the compressed
+ support vector, used for prediction, was derived from. They are returned in a floating-point
+ matrix, where the support vectors are stored as matrix rows.
+ */
+ CV_WRAP Mat getUncompressedSupportVectors() const;
+
+ /** @brief Retrieves the decision function
+
+ @param i the index of the decision function. If the problem solved is regression, 1-class or
+ 2-class classification, then there will be just one decision function and the index should
+ always be 0. Otherwise, in the case of N-class classification, there will be \f$N(N-1)/2\f$
+ decision functions.
+ @param alpha the optional output vector for weights, corresponding to different support vectors.
+ In the case of linear %SVM all the alpha's will be 1's.
+ @param svidx the optional output vector of indices of support vectors within the matrix of
+ support vectors (which can be retrieved by SVM::getSupportVectors). In the case of linear
+ %SVM each decision function consists of a single "compressed" support vector.
+
+ The method returns rho parameter of the decision function, a scalar subtracted from the weighted
+ sum of kernel responses.
+ */
+ CV_WRAP virtual double getDecisionFunction(int i, OutputArray alpha, OutputArray svidx) const = 0;
+
+ /** @brief Generates a grid for %SVM parameters.
+
+ @param param_id %SVM parameters IDs that must be one of the SVM::ParamTypes. The grid is
+ generated for the parameter with this ID.
+
+ The function generates a grid for the specified parameter of the %SVM algorithm. The grid may be
+ passed to the function SVM::trainAuto.
+ */
+ static ParamGrid getDefaultGrid( int param_id );
+
+ /** Creates empty model.
+ Use StatModel::train to train the model. Since %SVM has several parameters, you may want to
+ find the best parameters for your problem, it can be done with SVM::trainAuto. */
+ CV_WRAP static Ptr<SVM> create();
+
+ /** @brief Loads and creates a serialized svm from a file
+ *
+ * Use SVM::save to serialize and store an SVM to disk.
+ * Load the SVM from this file again, by calling this function with the path to the file.
+ *
+ * @param filepath path to serialized svm
+ */
+ CV_WRAP static Ptr<SVM> load(const String& filepath);
+};
+
+/****************************************************************************************\
+* Expectation - Maximization *
+\****************************************************************************************/
+
+/** @brief The class implements the Expectation Maximization algorithm.
+
+@sa @ref ml_intro_em
+ */
+class CV_EXPORTS_W EM : public StatModel
+{
+public:
+ //! Type of covariation matrices
+ enum Types {
+ /** A scaled identity matrix \f$\mu_k * I\f$. There is the only
+ parameter \f$\mu_k\f$ to be estimated for each matrix. The option may be used in special cases,
+ when the constraint is relevant, or as a first step in the optimization (for example in case
+ when the data is preprocessed with PCA). The results of such preliminary estimation may be
+ passed again to the optimization procedure, this time with
+ covMatType=EM::COV_MAT_DIAGONAL. */
+ COV_MAT_SPHERICAL=0,
+ /** A diagonal matrix with positive diagonal elements. The number of
+ free parameters is d for each matrix. This is most commonly used option yielding good
+ estimation results. */
+ COV_MAT_DIAGONAL=1,
+ /** A symmetric positively defined matrix. The number of free
+ parameters in each matrix is about \f$d^2/2\f$. It is not recommended to use this option, unless
+ there is pretty accurate initial estimation of the parameters and/or a huge number of
+ training samples. */
+ COV_MAT_GENERIC=2,
+ COV_MAT_DEFAULT=COV_MAT_DIAGONAL
+ };
+
+ //! Default parameters
+ enum {DEFAULT_NCLUSTERS=5, DEFAULT_MAX_ITERS=100};
+
+ //! The initial step
+ enum {START_E_STEP=1, START_M_STEP=2, START_AUTO_STEP=0};
+
+ /** The number of mixture components in the Gaussian mixture model.
+ Default value of the parameter is EM::DEFAULT_NCLUSTERS=5. Some of %EM implementation could
+ determine the optimal number of mixtures within a specified value range, but that is not the
+ case in ML yet. */
+ /** @see setClustersNumber */
+ CV_WRAP virtual int getClustersNumber() const = 0;
+ /** @copybrief getClustersNumber @see getClustersNumber */
+ CV_WRAP virtual void setClustersNumber(int val) = 0;
+
+ /** Constraint on covariance matrices which defines type of matrices.
+ See EM::Types. */
+ /** @see setCovarianceMatrixType */
+ CV_WRAP virtual int getCovarianceMatrixType() const = 0;
+ /** @copybrief getCovarianceMatrixType @see getCovarianceMatrixType */
+ CV_WRAP virtual void setCovarianceMatrixType(int val) = 0;
+
+ /** The termination criteria of the %EM algorithm.
+ The %EM algorithm can be terminated by the number of iterations termCrit.maxCount (number of
+ M-steps) or when relative change of likelihood logarithm is less than termCrit.epsilon. Default
+ maximum number of iterations is EM::DEFAULT_MAX_ITERS=100. */
+ /** @see setTermCriteria */
+ CV_WRAP virtual TermCriteria getTermCriteria() const = 0;
+ /** @copybrief getTermCriteria @see getTermCriteria */
+ CV_WRAP virtual void setTermCriteria(const TermCriteria &val) = 0;
+
+ /** @brief Returns weights of the mixtures
+
+ Returns vector with the number of elements equal to the number of mixtures.
+ */
+ CV_WRAP virtual Mat getWeights() const = 0;
+ /** @brief Returns the cluster centers (means of the Gaussian mixture)
+
+ Returns matrix with the number of rows equal to the number of mixtures and number of columns
+ equal to the space dimensionality.
+ */
+ CV_WRAP virtual Mat getMeans() const = 0;
+ /** @brief Returns covariation matrices
+
+ Returns vector of covariation matrices. Number of matrices is the number of gaussian mixtures,
+ each matrix is a square floating-point matrix NxN, where N is the space dimensionality.
+ */
+ CV_WRAP virtual void getCovs(CV_OUT std::vector<Mat>& covs) const = 0;
+
+ /** @brief Returns a likelihood logarithm value and an index of the most probable mixture component
+ for the given sample.
+
+ @param sample A sample for classification. It should be a one-channel matrix of
+ \f$1 \times dims\f$ or \f$dims \times 1\f$ size.
+ @param probs Optional output matrix that contains posterior probabilities of each component
+ given the sample. It has \f$1 \times nclusters\f$ size and CV_64FC1 type.
+
+ The method returns a two-element double vector. Zero element is a likelihood logarithm value for
+ the sample. First element is an index of the most probable mixture component for the given
+ sample.
+ */
+ CV_WRAP virtual Vec2d predict2(InputArray sample, OutputArray probs) const = 0;
+
+ /** @brief Estimate the Gaussian mixture parameters from a samples set.
+
+ This variation starts with Expectation step. Initial values of the model parameters will be
+ estimated by the k-means algorithm.
+
+ Unlike many of the ML models, %EM is an unsupervised learning algorithm and it does not take
+ responses (class labels or function values) as input. Instead, it computes the *Maximum
+ Likelihood Estimate* of the Gaussian mixture parameters from an input sample set, stores all the
+ parameters inside the structure: \f$p_{i,k}\f$ in probs, \f$a_k\f$ in means , \f$S_k\f$ in
+ covs[k], \f$\pi_k\f$ in weights , and optionally computes the output "class label" for each
+ sample: \f$\texttt{labels}_i=\texttt{arg max}_k(p_{i,k}), i=1..N\f$ (indices of the most
+ probable mixture component for each sample).
+
+ The trained model can be used further for prediction, just like any other classifier. The
+ trained model is similar to the NormalBayesClassifier.
+
+ @param samples Samples from which the Gaussian mixture model will be estimated. It should be a
+ one-channel matrix, each row of which is a sample. If the matrix does not have CV_64F type
+ it will be converted to the inner matrix of such type for the further computing.
+ @param logLikelihoods The optional output matrix that contains a likelihood logarithm value for
+ each sample. It has \f$nsamples \times 1\f$ size and CV_64FC1 type.
+ @param labels The optional output "class label" for each sample:
+ \f$\texttt{labels}_i=\texttt{arg max}_k(p_{i,k}), i=1..N\f$ (indices of the most probable
+ mixture component for each sample). It has \f$nsamples \times 1\f$ size and CV_32SC1 type.
+ @param probs The optional output matrix that contains posterior probabilities of each Gaussian
+ mixture component given the each sample. It has \f$nsamples \times nclusters\f$ size and
+ CV_64FC1 type.
+ */
+ CV_WRAP virtual bool trainEM(InputArray samples,
+ OutputArray logLikelihoods=noArray(),
+ OutputArray labels=noArray(),
+ OutputArray probs=noArray()) = 0;
+
+ /** @brief Estimate the Gaussian mixture parameters from a samples set.
+
+ This variation starts with Expectation step. You need to provide initial means \f$a_k\f$ of
+ mixture components. Optionally you can pass initial weights \f$\pi_k\f$ and covariance matrices
+ \f$S_k\f$ of mixture components.
+
+ @param samples Samples from which the Gaussian mixture model will be estimated. It should be a
+ one-channel matrix, each row of which is a sample. If the matrix does not have CV_64F type
+ it will be converted to the inner matrix of such type for the further computing.
+ @param means0 Initial means \f$a_k\f$ of mixture components. It is a one-channel matrix of
+ \f$nclusters \times dims\f$ size. If the matrix does not have CV_64F type it will be
+ converted to the inner matrix of such type for the further computing.
+ @param covs0 The vector of initial covariance matrices \f$S_k\f$ of mixture components. Each of
+ covariance matrices is a one-channel matrix of \f$dims \times dims\f$ size. If the matrices
+ do not have CV_64F type they will be converted to the inner matrices of such type for the
+ further computing.
+ @param weights0 Initial weights \f$\pi_k\f$ of mixture components. It should be a one-channel
+ floating-point matrix with \f$1 \times nclusters\f$ or \f$nclusters \times 1\f$ size.
+ @param logLikelihoods The optional output matrix that contains a likelihood logarithm value for
+ each sample. It has \f$nsamples \times 1\f$ size and CV_64FC1 type.
+ @param labels The optional output "class label" for each sample:
+ \f$\texttt{labels}_i=\texttt{arg max}_k(p_{i,k}), i=1..N\f$ (indices of the most probable
+ mixture component for each sample). It has \f$nsamples \times 1\f$ size and CV_32SC1 type.
+ @param probs The optional output matrix that contains posterior probabilities of each Gaussian
+ mixture component given the each sample. It has \f$nsamples \times nclusters\f$ size and
+ CV_64FC1 type.
+ */
+ CV_WRAP virtual bool trainE(InputArray samples, InputArray means0,
+ InputArray covs0=noArray(),
+ InputArray weights0=noArray(),
+ OutputArray logLikelihoods=noArray(),
+ OutputArray labels=noArray(),
+ OutputArray probs=noArray()) = 0;
+
+ /** @brief Estimate the Gaussian mixture parameters from a samples set.
+
+ This variation starts with Maximization step. You need to provide initial probabilities
+ \f$p_{i,k}\f$ to use this option.
+
+ @param samples Samples from which the Gaussian mixture model will be estimated. It should be a
+ one-channel matrix, each row of which is a sample. If the matrix does not have CV_64F type
+ it will be converted to the inner matrix of such type for the further computing.
+ @param probs0
+ @param logLikelihoods The optional output matrix that contains a likelihood logarithm value for
+ each sample. It has \f$nsamples \times 1\f$ size and CV_64FC1 type.
+ @param labels The optional output "class label" for each sample:
+ \f$\texttt{labels}_i=\texttt{arg max}_k(p_{i,k}), i=1..N\f$ (indices of the most probable
+ mixture component for each sample). It has \f$nsamples \times 1\f$ size and CV_32SC1 type.
+ @param probs The optional output matrix that contains posterior probabilities of each Gaussian
+ mixture component given the each sample. It has \f$nsamples \times nclusters\f$ size and
+ CV_64FC1 type.
+ */
+ CV_WRAP virtual bool trainM(InputArray samples, InputArray probs0,
+ OutputArray logLikelihoods=noArray(),
+ OutputArray labels=noArray(),
+ OutputArray probs=noArray()) = 0;
+
+ /** Creates empty %EM model.
+ The model should be trained then using StatModel::train(traindata, flags) method. Alternatively, you
+ can use one of the EM::train\* methods or load it from file using Algorithm::load\<EM\>(filename).
+ */
+ CV_WRAP static Ptr<EM> create();
+};
+
+/****************************************************************************************\
+* Decision Tree *
+\****************************************************************************************/
+
+/** @brief The class represents a single decision tree or a collection of decision trees.
+
+The current public interface of the class allows user to train only a single decision tree, however
+the class is capable of storing multiple decision trees and using them for prediction (by summing
+responses or using a voting schemes), and the derived from DTrees classes (such as RTrees and Boost)
+use this capability to implement decision tree ensembles.
+
+@sa @ref ml_intro_trees
+*/
+class CV_EXPORTS_W DTrees : public StatModel
+{
+public:
+ /** Predict options */
+ enum Flags { PREDICT_AUTO=0, PREDICT_SUM=(1<<8), PREDICT_MAX_VOTE=(2<<8), PREDICT_MASK=(3<<8) };
+
+ /** Cluster possible values of a categorical variable into K\<=maxCategories clusters to
+ find a suboptimal split.
+ If a discrete variable, on which the training procedure tries to make a split, takes more than
+ maxCategories values, the precise best subset estimation may take a very long time because the
+ algorithm is exponential. Instead, many decision trees engines (including our implementation)
+ try to find sub-optimal split in this case by clustering all the samples into maxCategories
+ clusters that is some categories are merged together. The clustering is applied only in n \>
+ 2-class classification problems for categorical variables with N \> max_categories possible
+ values. In case of regression and 2-class classification the optimal split can be found
+ efficiently without employing clustering, thus the parameter is not used in these cases.
+ Default value is 10.*/
+ /** @see setMaxCategories */
+ CV_WRAP virtual int getMaxCategories() const = 0;
+ /** @copybrief getMaxCategories @see getMaxCategories */
+ CV_WRAP virtual void setMaxCategories(int val) = 0;
+
+ /** The maximum possible depth of the tree.
+ That is the training algorithms attempts to split a node while its depth is less than maxDepth.
+ The root node has zero depth. The actual depth may be smaller if the other termination criteria
+ are met (see the outline of the training procedure @ref ml_intro_trees "here"), and/or if the
+ tree is pruned. Default value is INT_MAX.*/
+ /** @see setMaxDepth */
+ CV_WRAP virtual int getMaxDepth() const = 0;
+ /** @copybrief getMaxDepth @see getMaxDepth */
+ CV_WRAP virtual void setMaxDepth(int val) = 0;
+
+ /** If the number of samples in a node is less than this parameter then the node will not be split.
+
+ Default value is 10.*/
+ /** @see setMinSampleCount */
+ CV_WRAP virtual int getMinSampleCount() const = 0;
+ /** @copybrief getMinSampleCount @see getMinSampleCount */
+ CV_WRAP virtual void setMinSampleCount(int val) = 0;
+
+ /** If CVFolds \> 1 then algorithms prunes the built decision tree using K-fold
+ cross-validation procedure where K is equal to CVFolds.
+ Default value is 10.*/
+ /** @see setCVFolds */
+ CV_WRAP virtual int getCVFolds() const = 0;
+ /** @copybrief getCVFolds @see getCVFolds */
+ CV_WRAP virtual void setCVFolds(int val) = 0;
+
+ /** If true then surrogate splits will be built.
+ These splits allow to work with missing data and compute variable importance correctly.
+ Default value is false.
+ @note currently it's not implemented.*/
+ /** @see setUseSurrogates */
+ CV_WRAP virtual bool getUseSurrogates() const = 0;
+ /** @copybrief getUseSurrogates @see getUseSurrogates */
+ CV_WRAP virtual void setUseSurrogates(bool val) = 0;
+
+ /** If true then a pruning will be harsher.
+ This will make a tree more compact and more resistant to the training data noise but a bit less
+ accurate. Default value is true.*/
+ /** @see setUse1SERule */
+ CV_WRAP virtual bool getUse1SERule() const = 0;
+ /** @copybrief getUse1SERule @see getUse1SERule */
+ CV_WRAP virtual void setUse1SERule(bool val) = 0;
+
+ /** If true then pruned branches are physically removed from the tree.
+ Otherwise they are retained and it is possible to get results from the original unpruned (or
+ pruned less aggressively) tree. Default value is true.*/
+ /** @see setTruncatePrunedTree */
+ CV_WRAP virtual bool getTruncatePrunedTree() const = 0;
+ /** @copybrief getTruncatePrunedTree @see getTruncatePrunedTree */
+ CV_WRAP virtual void setTruncatePrunedTree(bool val) = 0;
+
+ /** Termination criteria for regression trees.
+ If all absolute differences between an estimated value in a node and values of train samples
+ in this node are less than this parameter then the node will not be split further. Default
+ value is 0.01f*/
+ /** @see setRegressionAccuracy */
+ CV_WRAP virtual float getRegressionAccuracy() const = 0;
+ /** @copybrief getRegressionAccuracy @see getRegressionAccuracy */
+ CV_WRAP virtual void setRegressionAccuracy(float val) = 0;
+
+ /** @brief The array of a priori class probabilities, sorted by the class label value.
+
+ The parameter can be used to tune the decision tree preferences toward a certain class. For
+ example, if you want to detect some rare anomaly occurrence, the training base will likely
+ contain much more normal cases than anomalies, so a very good classification performance
+ will be achieved just by considering every case as normal. To avoid this, the priors can be
+ specified, where the anomaly probability is artificially increased (up to 0.5 or even
+ greater), so the weight of the misclassified anomalies becomes much bigger, and the tree is
+ adjusted properly.
+
+ You can also think about this parameter as weights of prediction categories which determine
+ relative weights that you give to misclassification. That is, if the weight of the first
+ category is 1 and the weight of the second category is 10, then each mistake in predicting
+ the second category is equivalent to making 10 mistakes in predicting the first category.
+ Default value is empty Mat.*/
+ /** @see setPriors */
+ CV_WRAP virtual cv::Mat getPriors() const = 0;
+ /** @copybrief getPriors @see getPriors */
+ CV_WRAP virtual void setPriors(const cv::Mat &val) = 0;
+
+ /** @brief The class represents a decision tree node.
+ */
+ class CV_EXPORTS Node
+ {
+ public:
+ Node();
+ double value; //!< Value at the node: a class label in case of classification or estimated
+ //!< function value in case of regression.
+ int classIdx; //!< Class index normalized to 0..class_count-1 range and assigned to the
+ //!< node. It is used internally in classification trees and tree ensembles.
+ int parent; //!< Index of the parent node
+ int left; //!< Index of the left child node
+ int right; //!< Index of right child node
+ int defaultDir; //!< Default direction where to go (-1: left or +1: right). It helps in the
+ //!< case of missing values.
+ int split; //!< Index of the first split
+ };
+
+ /** @brief The class represents split in a decision tree.
+ */
+ class CV_EXPORTS Split
+ {
+ public:
+ Split();
+ int varIdx; //!< Index of variable on which the split is created.
+ bool inversed; //!< If true, then the inverse split rule is used (i.e. left and right
+ //!< branches are exchanged in the rule expressions below).
+ float quality; //!< The split quality, a positive number. It is used to choose the best split.
+ int next; //!< Index of the next split in the list of splits for the node
+ float c; /**< The threshold value in case of split on an ordered variable.
+ The rule is:
+ @code{.none}
+ if var_value < c
+ then next_node <- left
+ else next_node <- right
+ @endcode */
+ int subsetOfs; /**< Offset of the bitset used by the split on a categorical variable.
+ The rule is:
+ @code{.none}
+ if bitset[var_value] == 1
+ then next_node <- left
+ else next_node <- right
+ @endcode */
+ };
+
+ /** @brief Returns indices of root nodes
+ */
+ virtual const std::vector<int>& getRoots() const = 0;
+ /** @brief Returns all the nodes
+
+ all the node indices are indices in the returned vector
+ */
+ virtual const std::vector<Node>& getNodes() const = 0;
+ /** @brief Returns all the splits
+
+ all the split indices are indices in the returned vector
+ */
+ virtual const std::vector<Split>& getSplits() const = 0;
+ /** @brief Returns all the bitsets for categorical splits
+
+ Split::subsetOfs is an offset in the returned vector
+ */
+ virtual const std::vector<int>& getSubsets() const = 0;
+
+ /** @brief Creates the empty model
+
+ The static method creates empty decision tree with the specified parameters. It should be then
+ trained using train method (see StatModel::train). Alternatively, you can load the model from
+ file using Algorithm::load\<DTrees\>(filename).
+ */
+ CV_WRAP static Ptr<DTrees> create();
+};
+
+/****************************************************************************************\
+* Random Trees Classifier *
+\****************************************************************************************/
+
+/** @brief The class implements the random forest predictor.
+
+@sa @ref ml_intro_rtrees
+ */
+class CV_EXPORTS_W RTrees : public DTrees
+{
+public:
+
+ /** If true then variable importance will be calculated and then it can be retrieved by RTrees::getVarImportance.
+ Default value is false.*/
+ /** @see setCalculateVarImportance */
+ CV_WRAP virtual bool getCalculateVarImportance() const = 0;
+ /** @copybrief getCalculateVarImportance @see getCalculateVarImportance */
+ CV_WRAP virtual void setCalculateVarImportance(bool val) = 0;
+
+ /** The size of the randomly selected subset of features at each tree node and that are used
+ to find the best split(s).
+ If you set it to 0 then the size will be set to the square root of the total number of
+ features. Default value is 0.*/
+ /** @see setActiveVarCount */
+ CV_WRAP virtual int getActiveVarCount() const = 0;
+ /** @copybrief getActiveVarCount @see getActiveVarCount */
+ CV_WRAP virtual void setActiveVarCount(int val) = 0;
+
+ /** The termination criteria that specifies when the training algorithm stops.
+ Either when the specified number of trees is trained and added to the ensemble or when
+ sufficient accuracy (measured as OOB error) is achieved. Typically the more trees you have the
+ better the accuracy. However, the improvement in accuracy generally diminishes and asymptotes
+ pass a certain number of trees. Also to keep in mind, the number of tree increases the
+ prediction time linearly. Default value is TermCriteria(TermCriteria::MAX_ITERS +
+ TermCriteria::EPS, 50, 0.1)*/
+ /** @see setTermCriteria */
+ CV_WRAP virtual TermCriteria getTermCriteria() const = 0;
+ /** @copybrief getTermCriteria @see getTermCriteria */
+ CV_WRAP virtual void setTermCriteria(const TermCriteria &val) = 0;
+
+ /** Returns the variable importance array.
+ The method returns the variable importance vector, computed at the training stage when
+ CalculateVarImportance is set to true. If this flag was set to false, the empty matrix is
+ returned.
+ */
+ CV_WRAP virtual Mat getVarImportance() const = 0;
+
+ /** Creates the empty model.
+ Use StatModel::train to train the model, StatModel::train to create and train the model,
+ Algorithm::load to load the pre-trained model.
+ */
+ CV_WRAP static Ptr<RTrees> create();
+};
+
+/****************************************************************************************\
+* Boosted tree classifier *
+\****************************************************************************************/
+
+/** @brief Boosted tree classifier derived from DTrees
+
+@sa @ref ml_intro_boost
+ */
+class CV_EXPORTS_W Boost : public DTrees
+{
+public:
+ /** Type of the boosting algorithm.
+ See Boost::Types. Default value is Boost::REAL. */
+ /** @see setBoostType */
+ CV_WRAP virtual int getBoostType() const = 0;
+ /** @copybrief getBoostType @see getBoostType */
+ CV_WRAP virtual void setBoostType(int val) = 0;
+
+ /** The number of weak classifiers.
+ Default value is 100. */
+ /** @see setWeakCount */
+ CV_WRAP virtual int getWeakCount() const = 0;
+ /** @copybrief getWeakCount @see getWeakCount */
+ CV_WRAP virtual void setWeakCount(int val) = 0;
+
+ /** A threshold between 0 and 1 used to save computational time.
+ Samples with summary weight \f$\leq 1 - weight_trim_rate\f$ do not participate in the *next*
+ iteration of training. Set this parameter to 0 to turn off this functionality. Default value is 0.95.*/
+ /** @see setWeightTrimRate */
+ CV_WRAP virtual double getWeightTrimRate() const = 0;
+ /** @copybrief getWeightTrimRate @see getWeightTrimRate */
+ CV_WRAP virtual void setWeightTrimRate(double val) = 0;
+
+ /** Boosting type.
+ Gentle AdaBoost and Real AdaBoost are often the preferable choices. */
+ enum Types {
+ DISCRETE=0, //!< Discrete AdaBoost.
+ REAL=1, //!< Real AdaBoost. It is a technique that utilizes confidence-rated predictions
+ //!< and works well with categorical data.
+ LOGIT=2, //!< LogitBoost. It can produce good regression fits.
+ GENTLE=3 //!< Gentle AdaBoost. It puts less weight on outlier data points and for that
+ //!<reason is often good with regression data.
+ };
+
+ /** Creates the empty model.
+ Use StatModel::train to train the model, Algorithm::load\<Boost\>(filename) to load the pre-trained model. */
+ CV_WRAP static Ptr<Boost> create();
+};
+
+/****************************************************************************************\
+* Gradient Boosted Trees *
+\****************************************************************************************/
+
+/*class CV_EXPORTS_W GBTrees : public DTrees
+{
+public:
+ struct CV_EXPORTS_W_MAP Params : public DTrees::Params
+ {
+ CV_PROP_RW int weakCount;
+ CV_PROP_RW int lossFunctionType;
+ CV_PROP_RW float subsamplePortion;
+ CV_PROP_RW float shrinkage;
+
+ Params();
+ Params( int lossFunctionType, int weakCount, float shrinkage,
+ float subsamplePortion, int maxDepth, bool useSurrogates );
+ };
+
+ enum {SQUARED_LOSS=0, ABSOLUTE_LOSS, HUBER_LOSS=3, DEVIANCE_LOSS};
+
+ virtual void setK(int k) = 0;
+
+ virtual float predictSerial( InputArray samples,
+ OutputArray weakResponses, int flags) const = 0;
+
+ static Ptr<GBTrees> create(const Params& p);
+};*/
+
+/****************************************************************************************\
+* Artificial Neural Networks (ANN) *
+\****************************************************************************************/
+
+/////////////////////////////////// Multi-Layer Perceptrons //////////////////////////////
+
+/** @brief Artificial Neural Networks - Multi-Layer Perceptrons.
+
+Unlike many other models in ML that are constructed and trained at once, in the MLP model these
+steps are separated. First, a network with the specified topology is created using the non-default
+constructor or the method ANN_MLP::create. All the weights are set to zeros. Then, the network is
+trained using a set of input and output vectors. The training procedure can be repeated more than
+once, that is, the weights can be adjusted based on the new training data.
+
+Additional flags for StatModel::train are available: ANN_MLP::TrainFlags.
+
+@sa @ref ml_intro_ann
+ */
+class CV_EXPORTS_W ANN_MLP : public StatModel
+{
+public:
+ /** Available training methods */
+ enum TrainingMethods {
+ BACKPROP=0, //!< The back-propagation algorithm.
+ RPROP=1 //!< The RPROP algorithm. See @cite RPROP93 for details.
+ };
+
+ /** Sets training method and common parameters.
+ @param method Default value is ANN_MLP::RPROP. See ANN_MLP::TrainingMethods.
+ @param param1 passed to setRpropDW0 for ANN_MLP::RPROP and to setBackpropWeightScale for ANN_MLP::BACKPROP
+ @param param2 passed to setRpropDWMin for ANN_MLP::RPROP and to setBackpropMomentumScale for ANN_MLP::BACKPROP.
+ */
+ CV_WRAP virtual void setTrainMethod(int method, double param1 = 0, double param2 = 0) = 0;
+
+ /** Returns current training method */
+ CV_WRAP virtual int getTrainMethod() const = 0;
+
+ /** Initialize the activation function for each neuron.
+ Currently the default and the only fully supported activation function is ANN_MLP::SIGMOID_SYM.
+ @param type The type of activation function. See ANN_MLP::ActivationFunctions.
+ @param param1 The first parameter of the activation function, \f$\alpha\f$. Default value is 0.
+ @param param2 The second parameter of the activation function, \f$\beta\f$. Default value is 0.
+ */
+ CV_WRAP virtual void setActivationFunction(int type, double param1 = 0, double param2 = 0) = 0;
+
+ /** Integer vector specifying the number of neurons in each layer including the input and output layers.
+ The very first element specifies the number of elements in the input layer.
+ The last element - number of elements in the output layer. Default value is empty Mat.
+ @sa getLayerSizes */
+ CV_WRAP virtual void setLayerSizes(InputArray _layer_sizes) = 0;
+
+ /** Integer vector specifying the number of neurons in each layer including the input and output layers.
+ The very first element specifies the number of elements in the input layer.
+ The last element - number of elements in the output layer.
+ @sa setLayerSizes */
+ CV_WRAP virtual cv::Mat getLayerSizes() const = 0;
+
+ /** Termination criteria of the training algorithm.
+ You can specify the maximum number of iterations (maxCount) and/or how much the error could
+ change between the iterations to make the algorithm continue (epsilon). Default value is
+ TermCriteria(TermCriteria::MAX_ITER + TermCriteria::EPS, 1000, 0.01).*/
+ /** @see setTermCriteria */
+ CV_WRAP virtual TermCriteria getTermCriteria() const = 0;
+ /** @copybrief getTermCriteria @see getTermCriteria */
+ CV_WRAP virtual void setTermCriteria(TermCriteria val) = 0;
+
+ /** BPROP: Strength of the weight gradient term.
+ The recommended value is about 0.1. Default value is 0.1.*/
+ /** @see setBackpropWeightScale */
+ CV_WRAP virtual double getBackpropWeightScale() const = 0;
+ /** @copybrief getBackpropWeightScale @see getBackpropWeightScale */
+ CV_WRAP virtual void setBackpropWeightScale(double val) = 0;
+
+ /** BPROP: Strength of the momentum term (the difference between weights on the 2 previous iterations).
+ This parameter provides some inertia to smooth the random fluctuations of the weights. It can
+ vary from 0 (the feature is disabled) to 1 and beyond. The value 0.1 or so is good enough.
+ Default value is 0.1.*/
+ /** @see setBackpropMomentumScale */
+ CV_WRAP virtual double getBackpropMomentumScale() const = 0;
+ /** @copybrief getBackpropMomentumScale @see getBackpropMomentumScale */
+ CV_WRAP virtual void setBackpropMomentumScale(double val) = 0;
+
+ /** RPROP: Initial value \f$\Delta_0\f$ of update-values \f$\Delta_{ij}\f$.
+ Default value is 0.1.*/
+ /** @see setRpropDW0 */
+ CV_WRAP virtual double getRpropDW0() const = 0;
+ /** @copybrief getRpropDW0 @see getRpropDW0 */
+ CV_WRAP virtual void setRpropDW0(double val) = 0;
+
+ /** RPROP: Increase factor \f$\eta^+\f$.
+ It must be \>1. Default value is 1.2.*/
+ /** @see setRpropDWPlus */
+ CV_WRAP virtual double getRpropDWPlus() const = 0;
+ /** @copybrief getRpropDWPlus @see getRpropDWPlus */
+ CV_WRAP virtual void setRpropDWPlus(double val) = 0;
+
+ /** RPROP: Decrease factor \f$\eta^-\f$.
+ It must be \<1. Default value is 0.5.*/
+ /** @see setRpropDWMinus */
+ CV_WRAP virtual double getRpropDWMinus() const = 0;
+ /** @copybrief getRpropDWMinus @see getRpropDWMinus */
+ CV_WRAP virtual void setRpropDWMinus(double val) = 0;
+
+ /** RPROP: Update-values lower limit \f$\Delta_{min}\f$.
+ It must be positive. Default value is FLT_EPSILON.*/
+ /** @see setRpropDWMin */
+ CV_WRAP virtual double getRpropDWMin() const = 0;
+ /** @copybrief getRpropDWMin @see getRpropDWMin */
+ CV_WRAP virtual void setRpropDWMin(double val) = 0;
+
+ /** RPROP: Update-values upper limit \f$\Delta_{max}\f$.
+ It must be \>1. Default value is 50.*/
+ /** @see setRpropDWMax */
+ CV_WRAP virtual double getRpropDWMax() const = 0;
+ /** @copybrief getRpropDWMax @see getRpropDWMax */
+ CV_WRAP virtual void setRpropDWMax(double val) = 0;
+
+ /** possible activation functions */
+ enum ActivationFunctions {
+ /** Identity function: \f$f(x)=x\f$ */
+ IDENTITY = 0,
+ /** Symmetrical sigmoid: \f$f(x)=\beta*(1-e^{-\alpha x})/(1+e^{-\alpha x}\f$
+ @note
+ If you are using the default sigmoid activation function with the default parameter values
+ fparam1=0 and fparam2=0 then the function used is y = 1.7159\*tanh(2/3 \* x), so the output
+ will range from [-1.7159, 1.7159], instead of [0,1].*/
+ SIGMOID_SYM = 1,
+ /** Gaussian function: \f$f(x)=\beta e^{-\alpha x*x}\f$ */
+ GAUSSIAN = 2
+ };
+
+ /** Train options */
+ enum TrainFlags {
+ /** Update the network weights, rather than compute them from scratch. In the latter case
+ the weights are initialized using the Nguyen-Widrow algorithm. */
+ UPDATE_WEIGHTS = 1,
+ /** Do not normalize the input vectors. If this flag is not set, the training algorithm
+ normalizes each input feature independently, shifting its mean value to 0 and making the
+ standard deviation equal to 1. If the network is assumed to be updated frequently, the new
+ training data could be much different from original one. In this case, you should take care
+ of proper normalization. */
+ NO_INPUT_SCALE = 2,
+ /** Do not normalize the output vectors. If the flag is not set, the training algorithm
+ normalizes each output feature independently, by transforming it to the certain range
+ depending on the used activation function. */
+ NO_OUTPUT_SCALE = 4
+ };
+
+ CV_WRAP virtual Mat getWeights(int layerIdx) const = 0;
+
+ /** @brief Creates empty model
+
+ Use StatModel::train to train the model, Algorithm::load\<ANN_MLP\>(filename) to load the pre-trained model.
+ Note that the train method has optional flags: ANN_MLP::TrainFlags.
+ */
+ CV_WRAP static Ptr<ANN_MLP> create();
+
+ /** @brief Loads and creates a serialized ANN from a file
+ *
+ * Use ANN::save to serialize and store an ANN to disk.
+ * Load the ANN from this file again, by calling this function with the path to the file.
+ *
+ * @param filepath path to serialized ANN
+ */
+ CV_WRAP static Ptr<ANN_MLP> load(const String& filepath);
+
+};
+
+/****************************************************************************************\
+* Logistic Regression *
+\****************************************************************************************/
+
+/** @brief Implements Logistic Regression classifier.
+
+@sa @ref ml_intro_lr
+ */
+class CV_EXPORTS_W LogisticRegression : public StatModel
+{
+public:
+
+ /** Learning rate. */
+ /** @see setLearningRate */
+ CV_WRAP virtual double getLearningRate() const = 0;
+ /** @copybrief getLearningRate @see getLearningRate */
+ CV_WRAP virtual void setLearningRate(double val) = 0;
+
+ /** Number of iterations. */
+ /** @see setIterations */
+ CV_WRAP virtual int getIterations() const = 0;
+ /** @copybrief getIterations @see getIterations */
+ CV_WRAP virtual void setIterations(int val) = 0;
+
+ /** Kind of regularization to be applied. See LogisticRegression::RegKinds. */
+ /** @see setRegularization */
+ CV_WRAP virtual int getRegularization() const = 0;
+ /** @copybrief getRegularization @see getRegularization */
+ CV_WRAP virtual void setRegularization(int val) = 0;
+
+ /** Kind of training method used. See LogisticRegression::Methods. */
+ /** @see setTrainMethod */
+ CV_WRAP virtual int getTrainMethod() const = 0;
+ /** @copybrief getTrainMethod @see getTrainMethod */
+ CV_WRAP virtual void setTrainMethod(int val) = 0;
+
+ /** Specifies the number of training samples taken in each step of Mini-Batch Gradient
+ Descent. Will only be used if using LogisticRegression::MINI_BATCH training algorithm. It
+ has to take values less than the total number of training samples. */
+ /** @see setMiniBatchSize */
+ CV_WRAP virtual int getMiniBatchSize() const = 0;
+ /** @copybrief getMiniBatchSize @see getMiniBatchSize */
+ CV_WRAP virtual void setMiniBatchSize(int val) = 0;
+
+ /** Termination criteria of the algorithm. */
+ /** @see setTermCriteria */
+ CV_WRAP virtual TermCriteria getTermCriteria() const = 0;
+ /** @copybrief getTermCriteria @see getTermCriteria */
+ CV_WRAP virtual void setTermCriteria(TermCriteria val) = 0;
+
+ //! Regularization kinds
+ enum RegKinds {
+ REG_DISABLE = -1, //!< Regularization disabled
+ REG_L1 = 0, //!< %L1 norm
+ REG_L2 = 1 //!< %L2 norm
+ };
+
+ //! Training methods
+ enum Methods {
+ BATCH = 0,
+ MINI_BATCH = 1 //!< Set MiniBatchSize to a positive integer when using this method.
+ };
+
+ /** @brief Predicts responses for input samples and returns a float type.
+
+ @param samples The input data for the prediction algorithm. Matrix [m x n], where each row
+ contains variables (features) of one object being classified. Should have data type CV_32F.
+ @param results Predicted labels as a column matrix of type CV_32S.
+ @param flags Not used.
+ */
+ CV_WRAP virtual float predict( InputArray samples, OutputArray results=noArray(), int flags=0 ) const = 0;
+
+ /** @brief This function returns the trained paramters arranged across rows.
+
+ For a two class classifcation problem, it returns a row matrix. It returns learnt paramters of
+ the Logistic Regression as a matrix of type CV_32F.
+ */
+ CV_WRAP virtual Mat get_learnt_thetas() const = 0;
+
+ /** @brief Creates empty model.
+
+ Creates Logistic Regression model with parameters given.
+ */
+ CV_WRAP static Ptr<LogisticRegression> create();
+};
+
+
+/****************************************************************************************\
+* Stochastic Gradient Descent SVM Classifier *
+\****************************************************************************************/
+
+/*!
+@brief Stochastic Gradient Descent SVM classifier
+
+SVMSGD provides a fast and easy-to-use implementation of the SVM classifier using the Stochastic Gradient Descent approach,
+as presented in @cite bottou2010large.
+
+The classifier has following parameters:
+- model type,
+- margin type,
+- margin regularization (\f$\lambda\f$),
+- initial step size (\f$\gamma_0\f$),
+- step decreasing power (\f$c\f$),
+- and termination criteria.
+
+The model type may have one of the following values: \ref SGD and \ref ASGD.
+
+- \ref SGD is the classic version of SVMSGD classifier: every next step is calculated by the formula
+ \f[w_{t+1} = w_t - \gamma(t) \frac{dQ_i}{dw} |_{w = w_t}\f]
+ where
+ - \f$w_t\f$ is the weights vector for decision function at step \f$t\f$,
+ - \f$\gamma(t)\f$ is the step size of model parameters at the iteration \f$t\f$, it is decreased on each step by the formula
+ \f$\gamma(t) = \gamma_0 (1 + \lambda \gamma_0 t) ^ {-c}\f$
+ - \f$Q_i\f$ is the target functional from SVM task for sample with number \f$i\f$, this sample is chosen stochastically on each step of the algorithm.
+
+- \ref ASGD is Average Stochastic Gradient Descent SVM Classifier. ASGD classifier averages weights vector on each step of algorithm by the formula
+\f$\widehat{w}_{t+1} = \frac{t}{1+t}\widehat{w}_{t} + \frac{1}{1+t}w_{t+1}\f$
+
+The recommended model type is ASGD (following @cite bottou2010large).
+
+The margin type may have one of the following values: \ref SOFT_MARGIN or \ref HARD_MARGIN.
+
+- You should use \ref HARD_MARGIN type, if you have linearly separable sets.
+- You should use \ref SOFT_MARGIN type, if you have non-linearly separable sets or sets with outliers.
+- In the general case (if you know nothing about linear separability of your sets), use SOFT_MARGIN.
+
+The other parameters may be described as follows:
+- Margin regularization parameter is responsible for weights decreasing at each step and for the strength of restrictions on outliers
+ (the less the parameter, the less probability that an outlier will be ignored).
+ Recommended value for SGD model is 0.0001, for ASGD model is 0.00001.
+
+- Initial step size parameter is the initial value for the step size \f$\gamma(t)\f$.
+ You will have to find the best initial step for your problem.
+
+- Step decreasing power is the power parameter for \f$\gamma(t)\f$ decreasing by the formula, mentioned above.
+ Recommended value for SGD model is 1, for ASGD model is 0.75.
+
+- Termination criteria can be TermCriteria::COUNT, TermCriteria::EPS or TermCriteria::COUNT + TermCriteria::EPS.
+ You will have to find the best termination criteria for your problem.
+
+Note that the parameters margin regularization, initial step size, and step decreasing power should be positive.
+
+To use SVMSGD algorithm do as follows:
+
+- first, create the SVMSGD object. The algoorithm will set optimal parameters by default, but you can set your own parameters via functions setSvmsgdType(),
+ setMarginType(), setMarginRegularization(), setInitialStepSize(), and setStepDecreasingPower().
+
+- then the SVM model can be trained using the train features and the correspondent labels by the method train().
+
+- after that, the label of a new feature vector can be predicted using the method predict().
+
+@code
+// Create empty object
+cv::Ptr<SVMSGD> svmsgd = SVMSGD::create();
+
+// Train the Stochastic Gradient Descent SVM
+svmsgd->train(trainData);
+
+// Predict labels for the new samples
+svmsgd->predict(samples, responses);
+@endcode
+
+*/
+
+class CV_EXPORTS_W SVMSGD : public cv::ml::StatModel
+{
+public:
+
+ /** SVMSGD type.
+ ASGD is often the preferable choice. */
+ enum SvmsgdType
+ {
+ SGD, //!< Stochastic Gradient Descent
+ ASGD //!< Average Stochastic Gradient Descent
+ };
+
+ /** Margin type.*/
+ enum MarginType
+ {
+ SOFT_MARGIN, //!< General case, suits to the case of non-linearly separable sets, allows outliers.
+ HARD_MARGIN //!< More accurate for the case of linearly separable sets.
+ };
+
+ /**
+ * @return the weights of the trained model (decision function f(x) = weights * x + shift).
+ */
+ CV_WRAP virtual Mat getWeights() = 0;
+
+ /**
+ * @return the shift of the trained model (decision function f(x) = weights * x + shift).
+ */
+ CV_WRAP virtual float getShift() = 0;
+
+ /** @brief Creates empty model.
+ * Use StatModel::train to train the model. Since %SVMSGD has several parameters, you may want to
+ * find the best parameters for your problem or use setOptimalParameters() to set some default parameters.
+ */
+ CV_WRAP static Ptr<SVMSGD> create();
+
+ /** @brief Function sets optimal parameters values for chosen SVM SGD model.
+ * @param svmsgdType is the type of SVMSGD classifier.
+ * @param marginType is the type of margin constraint.
+ */
+ CV_WRAP virtual void setOptimalParameters(int svmsgdType = SVMSGD::ASGD, int marginType = SVMSGD::SOFT_MARGIN) = 0;
+
+ /** @brief %Algorithm type, one of SVMSGD::SvmsgdType. */
+ /** @see setSvmsgdType */
+ CV_WRAP virtual int getSvmsgdType() const = 0;
+ /** @copybrief getSvmsgdType @see getSvmsgdType */
+ CV_WRAP virtual void setSvmsgdType(int svmsgdType) = 0;
+
+ /** @brief %Margin type, one of SVMSGD::MarginType. */
+ /** @see setMarginType */
+ CV_WRAP virtual int getMarginType() const = 0;
+ /** @copybrief getMarginType @see getMarginType */
+ CV_WRAP virtual void setMarginType(int marginType) = 0;
+
+ /** @brief Parameter marginRegularization of a %SVMSGD optimization problem. */
+ /** @see setMarginRegularization */
+ CV_WRAP virtual float getMarginRegularization() const = 0;
+ /** @copybrief getMarginRegularization @see getMarginRegularization */
+ CV_WRAP virtual void setMarginRegularization(float marginRegularization) = 0;
+
+ /** @brief Parameter initialStepSize of a %SVMSGD optimization problem. */
+ /** @see setInitialStepSize */
+ CV_WRAP virtual float getInitialStepSize() const = 0;
+ /** @copybrief getInitialStepSize @see getInitialStepSize */
+ CV_WRAP virtual void setInitialStepSize(float InitialStepSize) = 0;
+
+ /** @brief Parameter stepDecreasingPower of a %SVMSGD optimization problem. */
+ /** @see setStepDecreasingPower */
+ CV_WRAP virtual float getStepDecreasingPower() const = 0;
+ /** @copybrief getStepDecreasingPower @see getStepDecreasingPower */
+ CV_WRAP virtual void setStepDecreasingPower(float stepDecreasingPower) = 0;
+
+ /** @brief Termination criteria of the training algorithm.
+ You can specify the maximum number of iterations (maxCount) and/or how much the error could
+ change between the iterations to make the algorithm continue (epsilon).*/
+ /** @see setTermCriteria */
+ CV_WRAP virtual TermCriteria getTermCriteria() const = 0;
+ /** @copybrief getTermCriteria @see getTermCriteria */
+ CV_WRAP virtual void setTermCriteria(const cv::TermCriteria &val) = 0;
+};
+
+
+/****************************************************************************************\
+* Auxilary functions declarations *
+\****************************************************************************************/
+
+/** @brief Generates _sample_ from multivariate normal distribution
+
+@param mean an average row vector
+@param cov symmetric covariation matrix
+@param nsamples returned samples count
+@param samples returned samples array
+*/
+CV_EXPORTS void randMVNormal( InputArray mean, InputArray cov, int nsamples, OutputArray samples);
+
+/** @brief Creates test set */
+CV_EXPORTS void createConcentricSpheresTestSet( int nsamples, int nfeatures, int nclasses,
+ OutputArray samples, OutputArray responses);
+
+//! @} ml
+
+}
+}
+
+#endif // __cplusplus
+#endif // OPENCV_ML_HPP
+
+/* End of file. */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/opencv2/ml/ml.hpp Fri Jan 29 04:53:38 2021 +0000 @@ -0,0 +1,48 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifdef __OPENCV_BUILD +#error this is a compatibility header which should not be used inside the OpenCV library +#endif + +#include "opencv2/ml.hpp"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/objdetect.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,466 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_OBJDETECT_HPP
+#define OPENCV_OBJDETECT_HPP
+
+#include "opencv2/core.hpp"
+
+/**
+@defgroup objdetect Object Detection
+
+Haar Feature-based Cascade Classifier for Object Detection
+----------------------------------------------------------
+
+The object detector described below has been initially proposed by Paul Viola @cite Viola01 and
+improved by Rainer Lienhart @cite Lienhart02 .
+
+First, a classifier (namely a *cascade of boosted classifiers working with haar-like features*) is
+trained with a few hundred sample views of a particular object (i.e., a face or a car), called
+positive examples, that are scaled to the same size (say, 20x20), and negative examples - arbitrary
+images of the same size.
+
+After a classifier is trained, it can be applied to a region of interest (of the same size as used
+during the training) in an input image. The classifier outputs a "1" if the region is likely to show
+the object (i.e., face/car), and "0" otherwise. To search for the object in the whole image one can
+move the search window across the image and check every location using the classifier. The
+classifier is designed so that it can be easily "resized" in order to be able to find the objects of
+interest at different sizes, which is more efficient than resizing the image itself. So, to find an
+object of an unknown size in the image the scan procedure should be done several times at different
+scales.
+
+The word "cascade" in the classifier name means that the resultant classifier consists of several
+simpler classifiers (*stages*) that are applied subsequently to a region of interest until at some
+stage the candidate is rejected or all the stages are passed. The word "boosted" means that the
+classifiers at every stage of the cascade are complex themselves and they are built out of basic
+classifiers using one of four different boosting techniques (weighted voting). Currently Discrete
+Adaboost, Real Adaboost, Gentle Adaboost and Logitboost are supported. The basic classifiers are
+decision-tree classifiers with at least 2 leaves. Haar-like features are the input to the basic
+classifiers, and are calculated as described below. The current algorithm uses the following
+Haar-like features:
+
+
+
+The feature used in a particular classifier is specified by its shape (1a, 2b etc.), position within
+the region of interest and the scale (this scale is not the same as the scale used at the detection
+stage, though these two scales are multiplied). For example, in the case of the third line feature
+(2c) the response is calculated as the difference between the sum of image pixels under the
+rectangle covering the whole feature (including the two white stripes and the black stripe in the
+middle) and the sum of the image pixels under the black stripe multiplied by 3 in order to
+compensate for the differences in the size of areas. The sums of pixel values over a rectangular
+regions are calculated rapidly using integral images (see below and the integral description).
+
+To see the object detector at work, have a look at the facedetect demo:
+<https://github.com/opencv/opencv/tree/master/samples/cpp/dbt_face_detection.cpp>
+
+The following reference is for the detection part only. There is a separate application called
+opencv_traincascade that can train a cascade of boosted classifiers from a set of samples.
+
+@note In the new C++ interface it is also possible to use LBP (local binary pattern) features in
+addition to Haar-like features. .. [Viola01] Paul Viola and Michael J. Jones. Rapid Object Detection
+using a Boosted Cascade of Simple Features. IEEE CVPR, 2001. The paper is available online at
+<http://research.microsoft.com/en-us/um/people/viola/Pubs/Detect/violaJones_CVPR2001.pdf>
+
+@{
+ @defgroup objdetect_c C API
+@}
+ */
+
+typedef struct CvHaarClassifierCascade CvHaarClassifierCascade;
+
+namespace cv
+{
+
+//! @addtogroup objdetect
+//! @{
+
+///////////////////////////// Object Detection ////////////////////////////
+
+//! class for grouping object candidates, detected by Cascade Classifier, HOG etc.
+//! instance of the class is to be passed to cv::partition (see cxoperations.hpp)
+class CV_EXPORTS SimilarRects
+{
+public:
+ SimilarRects(double _eps) : eps(_eps) {}
+ inline bool operator()(const Rect& r1, const Rect& r2) const
+ {
+ double delta = eps * ((std::min)(r1.width, r2.width) + (std::min)(r1.height, r2.height)) * 0.5;
+ return std::abs(r1.x - r2.x) <= delta &&
+ std::abs(r1.y - r2.y) <= delta &&
+ std::abs(r1.x + r1.width - r2.x - r2.width) <= delta &&
+ std::abs(r1.y + r1.height - r2.y - r2.height) <= delta;
+ }
+ double eps;
+};
+
+/** @brief Groups the object candidate rectangles.
+
+@param rectList Input/output vector of rectangles. Output vector includes retained and grouped
+rectangles. (The Python list is not modified in place.)
+@param groupThreshold Minimum possible number of rectangles minus 1. The threshold is used in a
+group of rectangles to retain it.
+@param eps Relative difference between sides of the rectangles to merge them into a group.
+
+The function is a wrapper for the generic function partition . It clusters all the input rectangles
+using the rectangle equivalence criteria that combines rectangles with similar sizes and similar
+locations. The similarity is defined by eps. When eps=0 , no clustering is done at all. If
+\f$\texttt{eps}\rightarrow +\inf\f$ , all the rectangles are put in one cluster. Then, the small
+clusters containing less than or equal to groupThreshold rectangles are rejected. In each other
+cluster, the average rectangle is computed and put into the output rectangle list.
+ */
+CV_EXPORTS void groupRectangles(std::vector<Rect>& rectList, int groupThreshold, double eps = 0.2);
+/** @overload */
+CV_EXPORTS_W void groupRectangles(CV_IN_OUT std::vector<Rect>& rectList, CV_OUT std::vector<int>& weights,
+ int groupThreshold, double eps = 0.2);
+/** @overload */
+CV_EXPORTS void groupRectangles(std::vector<Rect>& rectList, int groupThreshold,
+ double eps, std::vector<int>* weights, std::vector<double>* levelWeights );
+/** @overload */
+CV_EXPORTS void groupRectangles(std::vector<Rect>& rectList, std::vector<int>& rejectLevels,
+ std::vector<double>& levelWeights, int groupThreshold, double eps = 0.2);
+/** @overload */
+CV_EXPORTS void groupRectangles_meanshift(std::vector<Rect>& rectList, std::vector<double>& foundWeights,
+ std::vector<double>& foundScales,
+ double detectThreshold = 0.0, Size winDetSize = Size(64, 128));
+
+template<> CV_EXPORTS void DefaultDeleter<CvHaarClassifierCascade>::operator ()(CvHaarClassifierCascade* obj) const;
+
+enum { CASCADE_DO_CANNY_PRUNING = 1,
+ CASCADE_SCALE_IMAGE = 2,
+ CASCADE_FIND_BIGGEST_OBJECT = 4,
+ CASCADE_DO_ROUGH_SEARCH = 8
+ };
+
+class CV_EXPORTS_W BaseCascadeClassifier : public Algorithm
+{
+public:
+ virtual ~BaseCascadeClassifier();
+ virtual bool empty() const = 0;
+ virtual bool load( const String& filename ) = 0;
+ virtual void detectMultiScale( InputArray image,
+ CV_OUT std::vector<Rect>& objects,
+ double scaleFactor,
+ int minNeighbors, int flags,
+ Size minSize, Size maxSize ) = 0;
+
+ virtual void detectMultiScale( InputArray image,
+ CV_OUT std::vector<Rect>& objects,
+ CV_OUT std::vector<int>& numDetections,
+ double scaleFactor,
+ int minNeighbors, int flags,
+ Size minSize, Size maxSize ) = 0;
+
+ virtual void detectMultiScale( InputArray image,
+ CV_OUT std::vector<Rect>& objects,
+ CV_OUT std::vector<int>& rejectLevels,
+ CV_OUT std::vector<double>& levelWeights,
+ double scaleFactor,
+ int minNeighbors, int flags,
+ Size minSize, Size maxSize,
+ bool outputRejectLevels ) = 0;
+
+ virtual bool isOldFormatCascade() const = 0;
+ virtual Size getOriginalWindowSize() const = 0;
+ virtual int getFeatureType() const = 0;
+ virtual void* getOldCascade() = 0;
+
+ class CV_EXPORTS MaskGenerator
+ {
+ public:
+ virtual ~MaskGenerator() {}
+ virtual Mat generateMask(const Mat& src)=0;
+ virtual void initializeMask(const Mat& /*src*/) { }
+ };
+ virtual void setMaskGenerator(const Ptr<MaskGenerator>& maskGenerator) = 0;
+ virtual Ptr<MaskGenerator> getMaskGenerator() = 0;
+};
+
+/** @brief Cascade classifier class for object detection.
+ */
+class CV_EXPORTS_W CascadeClassifier
+{
+public:
+ CV_WRAP CascadeClassifier();
+ /** @brief Loads a classifier from a file.
+
+ @param filename Name of the file from which the classifier is loaded.
+ */
+ CV_WRAP CascadeClassifier(const String& filename);
+ ~CascadeClassifier();
+ /** @brief Checks whether the classifier has been loaded.
+ */
+ CV_WRAP bool empty() const;
+ /** @brief Loads a classifier from a file.
+
+ @param filename Name of the file from which the classifier is loaded. The file may contain an old
+ HAAR classifier trained by the haartraining application or a new cascade classifier trained by the
+ traincascade application.
+ */
+ CV_WRAP bool load( const String& filename );
+ /** @brief Reads a classifier from a FileStorage node.
+
+ @note The file may contain a new cascade classifier (trained traincascade application) only.
+ */
+ CV_WRAP bool read( const FileNode& node );
+
+ /** @brief Detects objects of different sizes in the input image. The detected objects are returned as a list
+ of rectangles.
+
+ @param image Matrix of the type CV_8U containing an image where objects are detected.
+ @param objects Vector of rectangles where each rectangle contains the detected object, the
+ rectangles may be partially outside the original image.
+ @param scaleFactor Parameter specifying how much the image size is reduced at each image scale.
+ @param minNeighbors Parameter specifying how many neighbors each candidate rectangle should have
+ to retain it.
+ @param flags Parameter with the same meaning for an old cascade as in the function
+ cvHaarDetectObjects. It is not used for a new cascade.
+ @param minSize Minimum possible object size. Objects smaller than that are ignored.
+ @param maxSize Maximum possible object size. Objects larger than that are ignored. If `maxSize == minSize` model is evaluated on single scale.
+
+ The function is parallelized with the TBB library.
+
+ @note
+ - (Python) A face detection example using cascade classifiers can be found at
+ opencv_source_code/samples/python/facedetect.py
+ */
+ CV_WRAP void detectMultiScale( InputArray image,
+ CV_OUT std::vector<Rect>& objects,
+ double scaleFactor = 1.1,
+ int minNeighbors = 3, int flags = 0,
+ Size minSize = Size(),
+ Size maxSize = Size() );
+
+ /** @overload
+ @param image Matrix of the type CV_8U containing an image where objects are detected.
+ @param objects Vector of rectangles where each rectangle contains the detected object, the
+ rectangles may be partially outside the original image.
+ @param numDetections Vector of detection numbers for the corresponding objects. An object's number
+ of detections is the number of neighboring positively classified rectangles that were joined
+ together to form the object.
+ @param scaleFactor Parameter specifying how much the image size is reduced at each image scale.
+ @param minNeighbors Parameter specifying how many neighbors each candidate rectangle should have
+ to retain it.
+ @param flags Parameter with the same meaning for an old cascade as in the function
+ cvHaarDetectObjects. It is not used for a new cascade.
+ @param minSize Minimum possible object size. Objects smaller than that are ignored.
+ @param maxSize Maximum possible object size. Objects larger than that are ignored. If `maxSize == minSize` model is evaluated on single scale.
+ */
+ CV_WRAP_AS(detectMultiScale2) void detectMultiScale( InputArray image,
+ CV_OUT std::vector<Rect>& objects,
+ CV_OUT std::vector<int>& numDetections,
+ double scaleFactor=1.1,
+ int minNeighbors=3, int flags=0,
+ Size minSize=Size(),
+ Size maxSize=Size() );
+
+ /** @overload
+ if `outputRejectLevels` is `true` returns `rejectLevels` and `levelWeights`
+ */
+ CV_WRAP_AS(detectMultiScale3) void detectMultiScale( InputArray image,
+ CV_OUT std::vector<Rect>& objects,
+ CV_OUT std::vector<int>& rejectLevels,
+ CV_OUT std::vector<double>& levelWeights,
+ double scaleFactor = 1.1,
+ int minNeighbors = 3, int flags = 0,
+ Size minSize = Size(),
+ Size maxSize = Size(),
+ bool outputRejectLevels = false );
+
+ CV_WRAP bool isOldFormatCascade() const;
+ CV_WRAP Size getOriginalWindowSize() const;
+ CV_WRAP int getFeatureType() const;
+ void* getOldCascade();
+
+ CV_WRAP static bool convert(const String& oldcascade, const String& newcascade);
+
+ void setMaskGenerator(const Ptr<BaseCascadeClassifier::MaskGenerator>& maskGenerator);
+ Ptr<BaseCascadeClassifier::MaskGenerator> getMaskGenerator();
+
+ Ptr<BaseCascadeClassifier> cc;
+};
+
+CV_EXPORTS Ptr<BaseCascadeClassifier::MaskGenerator> createFaceDetectionMaskGenerator();
+
+//////////////// HOG (Histogram-of-Oriented-Gradients) Descriptor and Object Detector //////////////
+
+//! struct for detection region of interest (ROI)
+struct DetectionROI
+{
+ //! scale(size) of the bounding box
+ double scale;
+ //! set of requrested locations to be evaluated
+ std::vector<cv::Point> locations;
+ //! vector that will contain confidence values for each location
+ std::vector<double> confidences;
+};
+
+struct CV_EXPORTS_W HOGDescriptor
+{
+public:
+ enum { L2Hys = 0
+ };
+ enum { DEFAULT_NLEVELS = 64
+ };
+
+ CV_WRAP HOGDescriptor() : winSize(64,128), blockSize(16,16), blockStride(8,8),
+ cellSize(8,8), nbins(9), derivAperture(1), winSigma(-1),
+ histogramNormType(HOGDescriptor::L2Hys), L2HysThreshold(0.2), gammaCorrection(true),
+ free_coef(-1.f), nlevels(HOGDescriptor::DEFAULT_NLEVELS), signedGradient(false)
+ {}
+
+ CV_WRAP HOGDescriptor(Size _winSize, Size _blockSize, Size _blockStride,
+ Size _cellSize, int _nbins, int _derivAperture=1, double _winSigma=-1,
+ int _histogramNormType=HOGDescriptor::L2Hys,
+ double _L2HysThreshold=0.2, bool _gammaCorrection=false,
+ int _nlevels=HOGDescriptor::DEFAULT_NLEVELS, bool _signedGradient=false)
+ : winSize(_winSize), blockSize(_blockSize), blockStride(_blockStride), cellSize(_cellSize),
+ nbins(_nbins), derivAperture(_derivAperture), winSigma(_winSigma),
+ histogramNormType(_histogramNormType), L2HysThreshold(_L2HysThreshold),
+ gammaCorrection(_gammaCorrection), free_coef(-1.f), nlevels(_nlevels), signedGradient(_signedGradient)
+ {}
+
+ CV_WRAP HOGDescriptor(const String& filename)
+ {
+ load(filename);
+ }
+
+ HOGDescriptor(const HOGDescriptor& d)
+ {
+ d.copyTo(*this);
+ }
+
+ virtual ~HOGDescriptor() {}
+
+ CV_WRAP size_t getDescriptorSize() const;
+ CV_WRAP bool checkDetectorSize() const;
+ CV_WRAP double getWinSigma() const;
+
+ CV_WRAP virtual void setSVMDetector(InputArray _svmdetector);
+
+ virtual bool read(FileNode& fn);
+ virtual void write(FileStorage& fs, const String& objname) const;
+
+ CV_WRAP virtual bool load(const String& filename, const String& objname = String());
+ CV_WRAP virtual void save(const String& filename, const String& objname = String()) const;
+ virtual void copyTo(HOGDescriptor& c) const;
+
+ CV_WRAP virtual void compute(InputArray img,
+ CV_OUT std::vector<float>& descriptors,
+ Size winStride = Size(), Size padding = Size(),
+ const std::vector<Point>& locations = std::vector<Point>()) const;
+
+ //! with found weights output
+ CV_WRAP virtual void detect(const Mat& img, CV_OUT std::vector<Point>& foundLocations,
+ CV_OUT std::vector<double>& weights,
+ double hitThreshold = 0, Size winStride = Size(),
+ Size padding = Size(),
+ const std::vector<Point>& searchLocations = std::vector<Point>()) const;
+ //! without found weights output
+ virtual void detect(const Mat& img, CV_OUT std::vector<Point>& foundLocations,
+ double hitThreshold = 0, Size winStride = Size(),
+ Size padding = Size(),
+ const std::vector<Point>& searchLocations=std::vector<Point>()) const;
+
+ //! with result weights output
+ CV_WRAP virtual void detectMultiScale(InputArray img, CV_OUT std::vector<Rect>& foundLocations,
+ CV_OUT std::vector<double>& foundWeights, double hitThreshold = 0,
+ Size winStride = Size(), Size padding = Size(), double scale = 1.05,
+ double finalThreshold = 2.0,bool useMeanshiftGrouping = false) const;
+ //! without found weights output
+ virtual void detectMultiScale(InputArray img, CV_OUT std::vector<Rect>& foundLocations,
+ double hitThreshold = 0, Size winStride = Size(),
+ Size padding = Size(), double scale = 1.05,
+ double finalThreshold = 2.0, bool useMeanshiftGrouping = false) const;
+
+ CV_WRAP virtual void computeGradient(const Mat& img, CV_OUT Mat& grad, CV_OUT Mat& angleOfs,
+ Size paddingTL = Size(), Size paddingBR = Size()) const;
+
+ CV_WRAP static std::vector<float> getDefaultPeopleDetector();
+ CV_WRAP static std::vector<float> getDaimlerPeopleDetector();
+
+ CV_PROP Size winSize;
+ CV_PROP Size blockSize;
+ CV_PROP Size blockStride;
+ CV_PROP Size cellSize;
+ CV_PROP int nbins;
+ CV_PROP int derivAperture;
+ CV_PROP double winSigma;
+ CV_PROP int histogramNormType;
+ CV_PROP double L2HysThreshold;
+ CV_PROP bool gammaCorrection;
+ CV_PROP std::vector<float> svmDetector;
+ UMat oclSvmDetector;
+ float free_coef;
+ CV_PROP int nlevels;
+ CV_PROP bool signedGradient;
+
+
+ //! evaluate specified ROI and return confidence value for each location
+ virtual void detectROI(const cv::Mat& img, const std::vector<cv::Point> &locations,
+ CV_OUT std::vector<cv::Point>& foundLocations, CV_OUT std::vector<double>& confidences,
+ double hitThreshold = 0, cv::Size winStride = Size(),
+ cv::Size padding = Size()) const;
+
+ //! evaluate specified ROI and return confidence value for each location in multiple scales
+ virtual void detectMultiScaleROI(const cv::Mat& img,
+ CV_OUT std::vector<cv::Rect>& foundLocations,
+ std::vector<DetectionROI>& locations,
+ double hitThreshold = 0,
+ int groupThreshold = 0) const;
+
+ //! read/parse Dalal's alt model file
+ void readALTModel(String modelfile);
+ void groupRectangles(std::vector<cv::Rect>& rectList, std::vector<double>& weights, int groupThreshold, double eps) const;
+};
+
+//! @} objdetect
+
+}
+
+#include "opencv2/objdetect/detection_based_tracker.hpp"
+
+#ifndef DISABLE_OPENCV_24_COMPATIBILITY
+#include "opencv2/objdetect/objdetect_c.h"
+#endif
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/objdetect/detection_based_tracker.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,225 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_OBJDETECT_DBT_HPP
+#define OPENCV_OBJDETECT_DBT_HPP
+
+// After this condition removal update blacklist for bindings: modules/python/common.cmake
+#if defined(__linux__) || defined(LINUX) || defined(__APPLE__) || defined(__ANDROID__) || \
+ (defined(__cplusplus) && __cplusplus > 199711L) || (defined(_MSC_VER) && _MSC_VER >= 1700)
+
+#include <vector>
+
+namespace cv
+{
+
+//! @addtogroup objdetect
+//! @{
+
+class CV_EXPORTS DetectionBasedTracker
+{
+ public:
+ struct CV_EXPORTS Parameters
+ {
+ int maxTrackLifetime;
+ int minDetectionPeriod; //the minimal time between run of the big object detector (on the whole frame) in ms (1000 mean 1 sec), default=0
+
+ Parameters();
+ };
+
+ class IDetector
+ {
+ public:
+ IDetector():
+ minObjSize(96, 96),
+ maxObjSize(INT_MAX, INT_MAX),
+ minNeighbours(2),
+ scaleFactor(1.1f)
+ {}
+
+ virtual void detect(const cv::Mat& image, std::vector<cv::Rect>& objects) = 0;
+
+ void setMinObjectSize(const cv::Size& min)
+ {
+ minObjSize = min;
+ }
+ void setMaxObjectSize(const cv::Size& max)
+ {
+ maxObjSize = max;
+ }
+ cv::Size getMinObjectSize() const
+ {
+ return minObjSize;
+ }
+ cv::Size getMaxObjectSize() const
+ {
+ return maxObjSize;
+ }
+ float getScaleFactor()
+ {
+ return scaleFactor;
+ }
+ void setScaleFactor(float value)
+ {
+ scaleFactor = value;
+ }
+ int getMinNeighbours()
+ {
+ return minNeighbours;
+ }
+ void setMinNeighbours(int value)
+ {
+ minNeighbours = value;
+ }
+ virtual ~IDetector() {}
+
+ protected:
+ cv::Size minObjSize;
+ cv::Size maxObjSize;
+ int minNeighbours;
+ float scaleFactor;
+ };
+
+ DetectionBasedTracker(cv::Ptr<IDetector> mainDetector, cv::Ptr<IDetector> trackingDetector, const Parameters& params);
+ virtual ~DetectionBasedTracker();
+
+ virtual bool run();
+ virtual void stop();
+ virtual void resetTracking();
+
+ virtual void process(const cv::Mat& imageGray);
+
+ bool setParameters(const Parameters& params);
+ const Parameters& getParameters() const;
+
+
+ typedef std::pair<cv::Rect, int> Object;
+ virtual void getObjects(std::vector<cv::Rect>& result) const;
+ virtual void getObjects(std::vector<Object>& result) const;
+
+ enum ObjectStatus
+ {
+ DETECTED_NOT_SHOWN_YET,
+ DETECTED,
+ DETECTED_TEMPORARY_LOST,
+ WRONG_OBJECT
+ };
+ struct ExtObject
+ {
+ int id;
+ cv::Rect location;
+ ObjectStatus status;
+ ExtObject(int _id, cv::Rect _location, ObjectStatus _status)
+ :id(_id), location(_location), status(_status)
+ {
+ }
+ };
+ virtual void getObjects(std::vector<ExtObject>& result) const;
+
+
+ virtual int addObject(const cv::Rect& location); //returns id of the new object
+
+ protected:
+ class SeparateDetectionWork;
+ cv::Ptr<SeparateDetectionWork> separateDetectionWork;
+ friend void* workcycleObjectDetectorFunction(void* p);
+
+ struct InnerParameters
+ {
+ int numLastPositionsToTrack;
+ int numStepsToWaitBeforeFirstShow;
+ int numStepsToTrackWithoutDetectingIfObjectHasNotBeenShown;
+ int numStepsToShowWithoutDetecting;
+
+ float coeffTrackingWindowSize;
+ float coeffObjectSizeToTrack;
+ float coeffObjectSpeedUsingInPrediction;
+
+ InnerParameters();
+ };
+ Parameters parameters;
+ InnerParameters innerParameters;
+
+ struct TrackedObject
+ {
+ typedef std::vector<cv::Rect> PositionsVector;
+
+ PositionsVector lastPositions;
+
+ int numDetectedFrames;
+ int numFramesNotDetected;
+ int id;
+
+ TrackedObject(const cv::Rect& rect):numDetectedFrames(1), numFramesNotDetected(0)
+ {
+ lastPositions.push_back(rect);
+ id=getNextId();
+ };
+
+ static int getNextId()
+ {
+ static int _id=0;
+ return _id++;
+ }
+ };
+
+ int numTrackedSteps;
+ std::vector<TrackedObject> trackedObjects;
+
+ std::vector<float> weightsPositionsSmoothing;
+ std::vector<float> weightsSizesSmoothing;
+
+ cv::Ptr<IDetector> cascadeForTracking;
+
+ void updateTrackedObjects(const std::vector<cv::Rect>& detectedObjects);
+ cv::Rect calcTrackedObjectPositionToShow(int i) const;
+ cv::Rect calcTrackedObjectPositionToShow(int i, ObjectStatus& status) const;
+ void detectInRegion(const cv::Mat& img, const cv::Rect& r, std::vector<cv::Rect>& detectedObjectsInRegions);
+};
+
+//! @} objdetect
+
+} //end of cv namespace
+#endif
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/opencv2/objdetect/objdetect.hpp Fri Jan 29 04:53:38 2021 +0000 @@ -0,0 +1,48 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifdef __OPENCV_BUILD +#error this is a compatibility header which should not be used inside the OpenCV library +#endif + +#include "opencv2/objdetect.hpp"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/objdetect/objdetect_c.h Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,165 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_OBJDETECT_C_H
+#define OPENCV_OBJDETECT_C_H
+
+#include "opencv2/core/core_c.h"
+
+#ifdef __cplusplus
+#include <deque>
+#include <vector>
+
+extern "C" {
+#endif
+
+/** @addtogroup objdetect_c
+ @{
+ */
+
+/****************************************************************************************\
+* Haar-like Object Detection functions *
+\****************************************************************************************/
+
+#define CV_HAAR_MAGIC_VAL 0x42500000
+#define CV_TYPE_NAME_HAAR "opencv-haar-classifier"
+
+#define CV_IS_HAAR_CLASSIFIER( haar ) \
+ ((haar) != NULL && \
+ (((const CvHaarClassifierCascade*)(haar))->flags & CV_MAGIC_MASK)==CV_HAAR_MAGIC_VAL)
+
+#define CV_HAAR_FEATURE_MAX 3
+
+typedef struct CvHaarFeature
+{
+ int tilted;
+ struct
+ {
+ CvRect r;
+ float weight;
+ } rect[CV_HAAR_FEATURE_MAX];
+} CvHaarFeature;
+
+typedef struct CvHaarClassifier
+{
+ int count;
+ CvHaarFeature* haar_feature;
+ float* threshold;
+ int* left;
+ int* right;
+ float* alpha;
+} CvHaarClassifier;
+
+typedef struct CvHaarStageClassifier
+{
+ int count;
+ float threshold;
+ CvHaarClassifier* classifier;
+
+ int next;
+ int child;
+ int parent;
+} CvHaarStageClassifier;
+
+typedef struct CvHidHaarClassifierCascade CvHidHaarClassifierCascade;
+
+typedef struct CvHaarClassifierCascade
+{
+ int flags;
+ int count;
+ CvSize orig_window_size;
+ CvSize real_window_size;
+ double scale;
+ CvHaarStageClassifier* stage_classifier;
+ CvHidHaarClassifierCascade* hid_cascade;
+} CvHaarClassifierCascade;
+
+typedef struct CvAvgComp
+{
+ CvRect rect;
+ int neighbors;
+} CvAvgComp;
+
+/* Loads haar classifier cascade from a directory.
+ It is obsolete: convert your cascade to xml and use cvLoad instead */
+CVAPI(CvHaarClassifierCascade*) cvLoadHaarClassifierCascade(
+ const char* directory, CvSize orig_window_size);
+
+CVAPI(void) cvReleaseHaarClassifierCascade( CvHaarClassifierCascade** cascade );
+
+#define CV_HAAR_DO_CANNY_PRUNING 1
+#define CV_HAAR_SCALE_IMAGE 2
+#define CV_HAAR_FIND_BIGGEST_OBJECT 4
+#define CV_HAAR_DO_ROUGH_SEARCH 8
+
+CVAPI(CvSeq*) cvHaarDetectObjects( const CvArr* image,
+ CvHaarClassifierCascade* cascade, CvMemStorage* storage,
+ double scale_factor CV_DEFAULT(1.1),
+ int min_neighbors CV_DEFAULT(3), int flags CV_DEFAULT(0),
+ CvSize min_size CV_DEFAULT(cvSize(0,0)), CvSize max_size CV_DEFAULT(cvSize(0,0)));
+
+/* sets images for haar classifier cascade */
+CVAPI(void) cvSetImagesForHaarClassifierCascade( CvHaarClassifierCascade* cascade,
+ const CvArr* sum, const CvArr* sqsum,
+ const CvArr* tilted_sum, double scale );
+
+/* runs the cascade on the specified window */
+CVAPI(int) cvRunHaarClassifierCascade( const CvHaarClassifierCascade* cascade,
+ CvPoint pt, int start_stage CV_DEFAULT(0));
+
+/** @} objdetect_c */
+
+#ifdef __cplusplus
+}
+
+CV_EXPORTS CvSeq* cvHaarDetectObjectsForROC( const CvArr* image,
+ CvHaarClassifierCascade* cascade, CvMemStorage* storage,
+ std::vector<int>& rejectLevels, std::vector<double>& levelWeightds,
+ double scale_factor = 1.1,
+ int min_neighbors = 3, int flags = 0,
+ CvSize min_size = cvSize(0, 0), CvSize max_size = cvSize(0, 0),
+ bool outputRejectLevels = false );
+
+#endif
+
+#endif /* OPENCV_OBJDETECT_C_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/opencv2/opencv.hpp Fri Jan 29 04:53:38 2021 +0000 @@ -0,0 +1,136 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009-2010, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_ALL_HPP +#define OPENCV_ALL_HPP + +// File that defines what modules where included during the build of OpenCV +// These are purely the defines of the correct HAVE_OPENCV_modulename values +#include "opencv2/opencv_modules.hpp" + +// Then the list of defines is checked to include the correct headers +// Core library is always included --> without no OpenCV functionality available +#include "opencv2/core.hpp" + +// Then the optional modules are checked +#ifdef HAVE_OPENCV_CALIB3D +#include "opencv2/calib3d.hpp" +#endif +#ifdef HAVE_OPENCV_FEATURES2D +#include "opencv2/features2d.hpp" +#endif +#ifdef HAVE_OPENCV_FLANN +#include "opencv2/flann.hpp" +#endif +#ifdef HAVE_OPENCV_HIGHGUI +#include "opencv2/highgui.hpp" +#endif +#ifdef HAVE_OPENCV_IMGCODECS +#include "opencv2/imgcodecs.hpp" +#endif +#ifdef HAVE_OPENCV_IMGPROC +#include "opencv2/imgproc.hpp" +#endif +#ifdef HAVE_OPENCV_ML +#include "opencv2/ml.hpp" +#endif +#ifdef HAVE_OPENCV_OBJDETECT +#include "opencv2/objdetect.hpp" +#endif +#ifdef HAVE_OPENCV_PHOTO +#include "opencv2/photo.hpp" +#endif +#ifdef HAVE_OPENCV_SHAPE +#include "opencv2/shape.hpp" +#endif +#ifdef HAVE_OPENCV_STITCHING +#include "opencv2/stitching.hpp" +#endif +#ifdef HAVE_OPENCV_SUPERRES +#include "opencv2/superres.hpp" +#endif +#ifdef HAVE_OPENCV_VIDEO +#include "opencv2/video.hpp" +#endif +#ifdef HAVE_OPENCV_VIDEOIO +#include "opencv2/videoio.hpp" +#endif +#ifdef HAVE_OPENCV_VIDEOSTAB +#include "opencv2/videostab.hpp" +#endif +#ifdef HAVE_OPENCV_VIZ +#include "opencv2/viz.hpp" +#endif + +// Finally CUDA specific entries are checked and added +#ifdef HAVE_OPENCV_CUDAARITHM +#include "opencv2/cudaarithm.hpp" +#endif +#ifdef HAVE_OPENCV_CUDABGSEGM +#include "opencv2/cudabgsegm.hpp" +#endif +#ifdef HAVE_OPENCV_CUDACODEC +#include "opencv2/cudacodec.hpp" +#endif +#ifdef HAVE_OPENCV_CUDAFEATURES2D +#include "opencv2/cudafeatures2d.hpp" +#endif +#ifdef HAVE_OPENCV_CUDAFILTERS +#include "opencv2/cudafilters.hpp" +#endif +#ifdef HAVE_OPENCV_CUDAIMGPROC +#include "opencv2/cudaimgproc.hpp" +#endif +#ifdef HAVE_OPENCV_CUDAOBJDETECT +#include "opencv2/cudaobjdetect.hpp" +#endif +#ifdef HAVE_OPENCV_CUDAOPTFLOW +#include "opencv2/cudaoptflow.hpp" +#endif +#ifdef HAVE_OPENCV_CUDASTEREO +#include "opencv2/cudastereo.hpp" +#endif +#ifdef HAVE_OPENCV_CUDAWARPING +#include "opencv2/cudawarping.hpp" +#endif + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/opencv2/opencv_modules.hpp Fri Jan 29 04:53:38 2021 +0000 @@ -0,0 +1,23 @@ +/* + * + * This file defines the list of modules available in current build configuration + * +*/ + + +#define HAVE_OPENCV_CALIB3D +#define HAVE_OPENCV_CORE +#define HAVE_OPENCV_FEATURES2D +//#define HAVE_OPENCV_FLANN +#define HAVE_OPENCV_IMGCODECS +#define HAVE_OPENCV_IMGPROC +#define HAVE_OPENCV_ML +#define HAVE_OPENCV_OBJDETECT +#define HAVE_OPENCV_PHOTO +#define HAVE_OPENCV_SHAPE +#define HAVE_OPENCV_STITCHING +#define HAVE_OPENCV_SUPERRES +#define HAVE_OPENCV_VIDEO +#define HAVE_OPENCV_VIDEOSTAB + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/photo.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,870 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2008-2012, Willow Garage Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_PHOTO_HPP
+#define OPENCV_PHOTO_HPP
+
+#include "opencv2/core.hpp"
+#include "opencv2/imgproc.hpp"
+
+/**
+@defgroup photo Computational Photography
+@{
+ @defgroup photo_denoise Denoising
+ @defgroup photo_hdr HDR imaging
+
+This section describes high dynamic range imaging algorithms namely tonemapping, exposure alignment,
+camera calibration with multiple exposures and exposure fusion.
+
+ @defgroup photo_clone Seamless Cloning
+ @defgroup photo_render Non-Photorealistic Rendering
+ @defgroup photo_c C API
+@}
+ */
+
+namespace cv
+{
+
+//! @addtogroup photo
+//! @{
+
+//! the inpainting algorithm
+enum
+{
+ INPAINT_NS = 0, // Navier-Stokes algorithm
+ INPAINT_TELEA = 1 // A. Telea algorithm
+};
+
+enum
+{
+ NORMAL_CLONE = 1,
+ MIXED_CLONE = 2,
+ MONOCHROME_TRANSFER = 3
+};
+
+enum
+{
+ RECURS_FILTER = 1,
+ NORMCONV_FILTER = 2
+};
+
+/** @brief Restores the selected region in an image using the region neighborhood.
+
+@param src Input 8-bit 1-channel or 3-channel image.
+@param inpaintMask Inpainting mask, 8-bit 1-channel image. Non-zero pixels indicate the area that
+needs to be inpainted.
+@param dst Output image with the same size and type as src .
+@param inpaintRadius Radius of a circular neighborhood of each point inpainted that is considered
+by the algorithm.
+@param flags Inpainting method that could be one of the following:
+- **INPAINT_NS** Navier-Stokes based method [Navier01]
+- **INPAINT_TELEA** Method by Alexandru Telea @cite Telea04 .
+
+The function reconstructs the selected image area from the pixel near the area boundary. The
+function may be used to remove dust and scratches from a scanned photo, or to remove undesirable
+objects from still images or video. See <http://en.wikipedia.org/wiki/Inpainting> for more details.
+
+@note
+ - An example using the inpainting technique can be found at
+ opencv_source_code/samples/cpp/inpaint.cpp
+ - (Python) An example using the inpainting technique can be found at
+ opencv_source_code/samples/python/inpaint.py
+ */
+CV_EXPORTS_W void inpaint( InputArray src, InputArray inpaintMask,
+ OutputArray dst, double inpaintRadius, int flags );
+
+//! @addtogroup photo_denoise
+//! @{
+
+/** @brief Perform image denoising using Non-local Means Denoising algorithm
+<http://www.ipol.im/pub/algo/bcm_non_local_means_denoising/> with several computational
+optimizations. Noise expected to be a gaussian white noise
+
+@param src Input 8-bit 1-channel, 2-channel, 3-channel or 4-channel image.
+@param dst Output image with the same size and type as src .
+@param templateWindowSize Size in pixels of the template patch that is used to compute weights.
+Should be odd. Recommended value 7 pixels
+@param searchWindowSize Size in pixels of the window that is used to compute weighted average for
+given pixel. Should be odd. Affect performance linearly: greater searchWindowsSize - greater
+denoising time. Recommended value 21 pixels
+@param h Parameter regulating filter strength. Big h value perfectly removes noise but also
+removes image details, smaller h value preserves details but also preserves some noise
+
+This function expected to be applied to grayscale images. For colored images look at
+fastNlMeansDenoisingColored. Advanced usage of this functions can be manual denoising of colored
+image in different colorspaces. Such approach is used in fastNlMeansDenoisingColored by converting
+image to CIELAB colorspace and then separately denoise L and AB components with different h
+parameter.
+ */
+CV_EXPORTS_W void fastNlMeansDenoising( InputArray src, OutputArray dst, float h = 3,
+ int templateWindowSize = 7, int searchWindowSize = 21);
+
+/** @brief Perform image denoising using Non-local Means Denoising algorithm
+<http://www.ipol.im/pub/algo/bcm_non_local_means_denoising/> with several computational
+optimizations. Noise expected to be a gaussian white noise
+
+@param src Input 8-bit or 16-bit (only with NORM_L1) 1-channel,
+2-channel, 3-channel or 4-channel image.
+@param dst Output image with the same size and type as src .
+@param templateWindowSize Size in pixels of the template patch that is used to compute weights.
+Should be odd. Recommended value 7 pixels
+@param searchWindowSize Size in pixels of the window that is used to compute weighted average for
+given pixel. Should be odd. Affect performance linearly: greater searchWindowsSize - greater
+denoising time. Recommended value 21 pixels
+@param h Array of parameters regulating filter strength, either one
+parameter applied to all channels or one per channel in dst. Big h value
+perfectly removes noise but also removes image details, smaller h
+value preserves details but also preserves some noise
+@param normType Type of norm used for weight calculation. Can be either NORM_L2 or NORM_L1
+
+This function expected to be applied to grayscale images. For colored images look at
+fastNlMeansDenoisingColored. Advanced usage of this functions can be manual denoising of colored
+image in different colorspaces. Such approach is used in fastNlMeansDenoisingColored by converting
+image to CIELAB colorspace and then separately denoise L and AB components with different h
+parameter.
+ */
+CV_EXPORTS_W void fastNlMeansDenoising( InputArray src, OutputArray dst,
+ const std::vector<float>& h,
+ int templateWindowSize = 7, int searchWindowSize = 21,
+ int normType = NORM_L2);
+
+/** @brief Modification of fastNlMeansDenoising function for colored images
+
+@param src Input 8-bit 3-channel image.
+@param dst Output image with the same size and type as src .
+@param templateWindowSize Size in pixels of the template patch that is used to compute weights.
+Should be odd. Recommended value 7 pixels
+@param searchWindowSize Size in pixels of the window that is used to compute weighted average for
+given pixel. Should be odd. Affect performance linearly: greater searchWindowsSize - greater
+denoising time. Recommended value 21 pixels
+@param h Parameter regulating filter strength for luminance component. Bigger h value perfectly
+removes noise but also removes image details, smaller h value preserves details but also preserves
+some noise
+@param hColor The same as h but for color components. For most images value equals 10
+will be enough to remove colored noise and do not distort colors
+
+The function converts image to CIELAB colorspace and then separately denoise L and AB components
+with given h parameters using fastNlMeansDenoising function.
+ */
+CV_EXPORTS_W void fastNlMeansDenoisingColored( InputArray src, OutputArray dst,
+ float h = 3, float hColor = 3,
+ int templateWindowSize = 7, int searchWindowSize = 21);
+
+/** @brief Modification of fastNlMeansDenoising function for images sequence where consequtive images have been
+captured in small period of time. For example video. This version of the function is for grayscale
+images or for manual manipulation with colorspaces. For more details see
+<http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.131.6394>
+
+@param srcImgs Input 8-bit 1-channel, 2-channel, 3-channel or
+4-channel images sequence. All images should have the same type and
+size.
+@param imgToDenoiseIndex Target image to denoise index in srcImgs sequence
+@param temporalWindowSize Number of surrounding images to use for target image denoising. Should
+be odd. Images from imgToDenoiseIndex - temporalWindowSize / 2 to
+imgToDenoiseIndex - temporalWindowSize / 2 from srcImgs will be used to denoise
+srcImgs[imgToDenoiseIndex] image.
+@param dst Output image with the same size and type as srcImgs images.
+@param templateWindowSize Size in pixels of the template patch that is used to compute weights.
+Should be odd. Recommended value 7 pixels
+@param searchWindowSize Size in pixels of the window that is used to compute weighted average for
+given pixel. Should be odd. Affect performance linearly: greater searchWindowsSize - greater
+denoising time. Recommended value 21 pixels
+@param h Parameter regulating filter strength. Bigger h value
+perfectly removes noise but also removes image details, smaller h
+value preserves details but also preserves some noise
+ */
+CV_EXPORTS_W void fastNlMeansDenoisingMulti( InputArrayOfArrays srcImgs, OutputArray dst,
+ int imgToDenoiseIndex, int temporalWindowSize,
+ float h = 3, int templateWindowSize = 7, int searchWindowSize = 21);
+
+/** @brief Modification of fastNlMeansDenoising function for images sequence where consequtive images have been
+captured in small period of time. For example video. This version of the function is for grayscale
+images or for manual manipulation with colorspaces. For more details see
+<http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.131.6394>
+
+@param srcImgs Input 8-bit or 16-bit (only with NORM_L1) 1-channel,
+2-channel, 3-channel or 4-channel images sequence. All images should
+have the same type and size.
+@param imgToDenoiseIndex Target image to denoise index in srcImgs sequence
+@param temporalWindowSize Number of surrounding images to use for target image denoising. Should
+be odd. Images from imgToDenoiseIndex - temporalWindowSize / 2 to
+imgToDenoiseIndex - temporalWindowSize / 2 from srcImgs will be used to denoise
+srcImgs[imgToDenoiseIndex] image.
+@param dst Output image with the same size and type as srcImgs images.
+@param templateWindowSize Size in pixels of the template patch that is used to compute weights.
+Should be odd. Recommended value 7 pixels
+@param searchWindowSize Size in pixels of the window that is used to compute weighted average for
+given pixel. Should be odd. Affect performance linearly: greater searchWindowsSize - greater
+denoising time. Recommended value 21 pixels
+@param h Array of parameters regulating filter strength, either one
+parameter applied to all channels or one per channel in dst. Big h value
+perfectly removes noise but also removes image details, smaller h
+value preserves details but also preserves some noise
+@param normType Type of norm used for weight calculation. Can be either NORM_L2 or NORM_L1
+ */
+CV_EXPORTS_W void fastNlMeansDenoisingMulti( InputArrayOfArrays srcImgs, OutputArray dst,
+ int imgToDenoiseIndex, int temporalWindowSize,
+ const std::vector<float>& h,
+ int templateWindowSize = 7, int searchWindowSize = 21,
+ int normType = NORM_L2);
+
+/** @brief Modification of fastNlMeansDenoisingMulti function for colored images sequences
+
+@param srcImgs Input 8-bit 3-channel images sequence. All images should have the same type and
+size.
+@param imgToDenoiseIndex Target image to denoise index in srcImgs sequence
+@param temporalWindowSize Number of surrounding images to use for target image denoising. Should
+be odd. Images from imgToDenoiseIndex - temporalWindowSize / 2 to
+imgToDenoiseIndex - temporalWindowSize / 2 from srcImgs will be used to denoise
+srcImgs[imgToDenoiseIndex] image.
+@param dst Output image with the same size and type as srcImgs images.
+@param templateWindowSize Size in pixels of the template patch that is used to compute weights.
+Should be odd. Recommended value 7 pixels
+@param searchWindowSize Size in pixels of the window that is used to compute weighted average for
+given pixel. Should be odd. Affect performance linearly: greater searchWindowsSize - greater
+denoising time. Recommended value 21 pixels
+@param h Parameter regulating filter strength for luminance component. Bigger h value perfectly
+removes noise but also removes image details, smaller h value preserves details but also preserves
+some noise.
+@param hColor The same as h but for color components.
+
+The function converts images to CIELAB colorspace and then separately denoise L and AB components
+with given h parameters using fastNlMeansDenoisingMulti function.
+ */
+CV_EXPORTS_W void fastNlMeansDenoisingColoredMulti( InputArrayOfArrays srcImgs, OutputArray dst,
+ int imgToDenoiseIndex, int temporalWindowSize,
+ float h = 3, float hColor = 3,
+ int templateWindowSize = 7, int searchWindowSize = 21);
+
+/** @brief Primal-dual algorithm is an algorithm for solving special types of variational problems (that is,
+finding a function to minimize some functional). As the image denoising, in particular, may be seen
+as the variational problem, primal-dual algorithm then can be used to perform denoising and this is
+exactly what is implemented.
+
+It should be noted, that this implementation was taken from the July 2013 blog entry
+@cite MA13 , which also contained (slightly more general) ready-to-use source code on Python.
+Subsequently, that code was rewritten on C++ with the usage of openCV by Vadim Pisarevsky at the end
+of July 2013 and finally it was slightly adapted by later authors.
+
+Although the thorough discussion and justification of the algorithm involved may be found in
+@cite ChambolleEtAl, it might make sense to skim over it here, following @cite MA13 . To begin
+with, we consider the 1-byte gray-level images as the functions from the rectangular domain of
+pixels (it may be seen as set
+\f$\left\{(x,y)\in\mathbb{N}\times\mathbb{N}\mid 1\leq x\leq n,\;1\leq y\leq m\right\}\f$ for some
+\f$m,\;n\in\mathbb{N}\f$) into \f$\{0,1,\dots,255\}\f$. We shall denote the noised images as \f$f_i\f$ and with
+this view, given some image \f$x\f$ of the same size, we may measure how bad it is by the formula
+
+\f[\left\|\left\|\nabla x\right\|\right\| + \lambda\sum_i\left\|\left\|x-f_i\right\|\right\|\f]
+
+\f$\|\|\cdot\|\|\f$ here denotes \f$L_2\f$-norm and as you see, the first addend states that we want our
+image to be smooth (ideally, having zero gradient, thus being constant) and the second states that
+we want our result to be close to the observations we've got. If we treat \f$x\f$ as a function, this is
+exactly the functional what we seek to minimize and here the Primal-Dual algorithm comes into play.
+
+@param observations This array should contain one or more noised versions of the image that is to
+be restored.
+@param result Here the denoised image will be stored. There is no need to do pre-allocation of
+storage space, as it will be automatically allocated, if necessary.
+@param lambda Corresponds to \f$\lambda\f$ in the formulas above. As it is enlarged, the smooth
+(blurred) images are treated more favorably than detailed (but maybe more noised) ones. Roughly
+speaking, as it becomes smaller, the result will be more blur but more sever outliers will be
+removed.
+@param niters Number of iterations that the algorithm will run. Of course, as more iterations as
+better, but it is hard to quantitatively refine this statement, so just use the default and
+increase it if the results are poor.
+ */
+CV_EXPORTS_W void denoise_TVL1(const std::vector<Mat>& observations,Mat& result, double lambda=1.0, int niters=30);
+
+//! @} photo_denoise
+
+//! @addtogroup photo_hdr
+//! @{
+
+enum { LDR_SIZE = 256 };
+
+/** @brief Base class for tonemapping algorithms - tools that are used to map HDR image to 8-bit range.
+ */
+class CV_EXPORTS_W Tonemap : public Algorithm
+{
+public:
+ /** @brief Tonemaps image
+
+ @param src source image - 32-bit 3-channel Mat
+ @param dst destination image - 32-bit 3-channel Mat with values in [0, 1] range
+ */
+ CV_WRAP virtual void process(InputArray src, OutputArray dst) = 0;
+
+ CV_WRAP virtual float getGamma() const = 0;
+ CV_WRAP virtual void setGamma(float gamma) = 0;
+};
+
+/** @brief Creates simple linear mapper with gamma correction
+
+@param gamma positive value for gamma correction. Gamma value of 1.0 implies no correction, gamma
+equal to 2.2f is suitable for most displays.
+Generally gamma \> 1 brightens the image and gamma \< 1 darkens it.
+ */
+CV_EXPORTS_W Ptr<Tonemap> createTonemap(float gamma = 1.0f);
+
+/** @brief Adaptive logarithmic mapping is a fast global tonemapping algorithm that scales the image in
+logarithmic domain.
+
+Since it's a global operator the same function is applied to all the pixels, it is controlled by the
+bias parameter.
+
+Optional saturation enhancement is possible as described in @cite FL02 .
+
+For more information see @cite DM03 .
+ */
+class CV_EXPORTS_W TonemapDrago : public Tonemap
+{
+public:
+
+ CV_WRAP virtual float getSaturation() const = 0;
+ CV_WRAP virtual void setSaturation(float saturation) = 0;
+
+ CV_WRAP virtual float getBias() const = 0;
+ CV_WRAP virtual void setBias(float bias) = 0;
+};
+
+/** @brief Creates TonemapDrago object
+
+@param gamma gamma value for gamma correction. See createTonemap
+@param saturation positive saturation enhancement value. 1.0 preserves saturation, values greater
+than 1 increase saturation and values less than 1 decrease it.
+@param bias value for bias function in [0, 1] range. Values from 0.7 to 0.9 usually give best
+results, default value is 0.85.
+ */
+CV_EXPORTS_W Ptr<TonemapDrago> createTonemapDrago(float gamma = 1.0f, float saturation = 1.0f, float bias = 0.85f);
+
+/** @brief This algorithm decomposes image into two layers: base layer and detail layer using bilateral filter
+and compresses contrast of the base layer thus preserving all the details.
+
+This implementation uses regular bilateral filter from opencv.
+
+Saturation enhancement is possible as in ocvTonemapDrago.
+
+For more information see @cite DD02 .
+ */
+class CV_EXPORTS_W TonemapDurand : public Tonemap
+{
+public:
+
+ CV_WRAP virtual float getSaturation() const = 0;
+ CV_WRAP virtual void setSaturation(float saturation) = 0;
+
+ CV_WRAP virtual float getContrast() const = 0;
+ CV_WRAP virtual void setContrast(float contrast) = 0;
+
+ CV_WRAP virtual float getSigmaSpace() const = 0;
+ CV_WRAP virtual void setSigmaSpace(float sigma_space) = 0;
+
+ CV_WRAP virtual float getSigmaColor() const = 0;
+ CV_WRAP virtual void setSigmaColor(float sigma_color) = 0;
+};
+
+/** @brief Creates TonemapDurand object
+
+@param gamma gamma value for gamma correction. See createTonemap
+@param contrast resulting contrast on logarithmic scale, i. e. log(max / min), where max and min
+are maximum and minimum luminance values of the resulting image.
+@param saturation saturation enhancement value. See createTonemapDrago
+@param sigma_space bilateral filter sigma in color space
+@param sigma_color bilateral filter sigma in coordinate space
+ */
+CV_EXPORTS_W Ptr<TonemapDurand>
+createTonemapDurand(float gamma = 1.0f, float contrast = 4.0f, float saturation = 1.0f, float sigma_space = 2.0f, float sigma_color = 2.0f);
+
+/** @brief This is a global tonemapping operator that models human visual system.
+
+Mapping function is controlled by adaptation parameter, that is computed using light adaptation and
+color adaptation.
+
+For more information see @cite RD05 .
+ */
+class CV_EXPORTS_W TonemapReinhard : public Tonemap
+{
+public:
+ CV_WRAP virtual float getIntensity() const = 0;
+ CV_WRAP virtual void setIntensity(float intensity) = 0;
+
+ CV_WRAP virtual float getLightAdaptation() const = 0;
+ CV_WRAP virtual void setLightAdaptation(float light_adapt) = 0;
+
+ CV_WRAP virtual float getColorAdaptation() const = 0;
+ CV_WRAP virtual void setColorAdaptation(float color_adapt) = 0;
+};
+
+/** @brief Creates TonemapReinhard object
+
+@param gamma gamma value for gamma correction. See createTonemap
+@param intensity result intensity in [-8, 8] range. Greater intensity produces brighter results.
+@param light_adapt light adaptation in [0, 1] range. If 1 adaptation is based only on pixel
+value, if 0 it's global, otherwise it's a weighted mean of this two cases.
+@param color_adapt chromatic adaptation in [0, 1] range. If 1 channels are treated independently,
+if 0 adaptation level is the same for each channel.
+ */
+CV_EXPORTS_W Ptr<TonemapReinhard>
+createTonemapReinhard(float gamma = 1.0f, float intensity = 0.0f, float light_adapt = 1.0f, float color_adapt = 0.0f);
+
+/** @brief This algorithm transforms image to contrast using gradients on all levels of gaussian pyramid,
+transforms contrast values to HVS response and scales the response. After this the image is
+reconstructed from new contrast values.
+
+For more information see @cite MM06 .
+ */
+class CV_EXPORTS_W TonemapMantiuk : public Tonemap
+{
+public:
+ CV_WRAP virtual float getScale() const = 0;
+ CV_WRAP virtual void setScale(float scale) = 0;
+
+ CV_WRAP virtual float getSaturation() const = 0;
+ CV_WRAP virtual void setSaturation(float saturation) = 0;
+};
+
+/** @brief Creates TonemapMantiuk object
+
+@param gamma gamma value for gamma correction. See createTonemap
+@param scale contrast scale factor. HVS response is multiplied by this parameter, thus compressing
+dynamic range. Values from 0.6 to 0.9 produce best results.
+@param saturation saturation enhancement value. See createTonemapDrago
+ */
+CV_EXPORTS_W Ptr<TonemapMantiuk>
+createTonemapMantiuk(float gamma = 1.0f, float scale = 0.7f, float saturation = 1.0f);
+
+/** @brief The base class for algorithms that align images of the same scene with different exposures
+ */
+class CV_EXPORTS_W AlignExposures : public Algorithm
+{
+public:
+ /** @brief Aligns images
+
+ @param src vector of input images
+ @param dst vector of aligned images
+ @param times vector of exposure time values for each image
+ @param response 256x1 matrix with inverse camera response function for each pixel value, it should
+ have the same number of channels as images.
+ */
+ CV_WRAP virtual void process(InputArrayOfArrays src, std::vector<Mat>& dst,
+ InputArray times, InputArray response) = 0;
+};
+
+/** @brief This algorithm converts images to median threshold bitmaps (1 for pixels brighter than median
+luminance and 0 otherwise) and than aligns the resulting bitmaps using bit operations.
+
+It is invariant to exposure, so exposure values and camera response are not necessary.
+
+In this implementation new image regions are filled with zeros.
+
+For more information see @cite GW03 .
+ */
+class CV_EXPORTS_W AlignMTB : public AlignExposures
+{
+public:
+ CV_WRAP virtual void process(InputArrayOfArrays src, std::vector<Mat>& dst,
+ InputArray times, InputArray response) = 0;
+
+ /** @brief Short version of process, that doesn't take extra arguments.
+
+ @param src vector of input images
+ @param dst vector of aligned images
+ */
+ CV_WRAP virtual void process(InputArrayOfArrays src, std::vector<Mat>& dst) = 0;
+
+ /** @brief Calculates shift between two images, i. e. how to shift the second image to correspond it with the
+ first.
+
+ @param img0 first image
+ @param img1 second image
+ */
+ CV_WRAP virtual Point calculateShift(InputArray img0, InputArray img1) = 0;
+ /** @brief Helper function, that shift Mat filling new regions with zeros.
+
+ @param src input image
+ @param dst result image
+ @param shift shift value
+ */
+ CV_WRAP virtual void shiftMat(InputArray src, OutputArray dst, const Point shift) = 0;
+ /** @brief Computes median threshold and exclude bitmaps of given image.
+
+ @param img input image
+ @param tb median threshold bitmap
+ @param eb exclude bitmap
+ */
+ CV_WRAP virtual void computeBitmaps(InputArray img, OutputArray tb, OutputArray eb) = 0;
+
+ CV_WRAP virtual int getMaxBits() const = 0;
+ CV_WRAP virtual void setMaxBits(int max_bits) = 0;
+
+ CV_WRAP virtual int getExcludeRange() const = 0;
+ CV_WRAP virtual void setExcludeRange(int exclude_range) = 0;
+
+ CV_WRAP virtual bool getCut() const = 0;
+ CV_WRAP virtual void setCut(bool value) = 0;
+};
+
+/** @brief Creates AlignMTB object
+
+@param max_bits logarithm to the base 2 of maximal shift in each dimension. Values of 5 and 6 are
+usually good enough (31 and 63 pixels shift respectively).
+@param exclude_range range for exclusion bitmap that is constructed to suppress noise around the
+median value.
+@param cut if true cuts images, otherwise fills the new regions with zeros.
+ */
+CV_EXPORTS_W Ptr<AlignMTB> createAlignMTB(int max_bits = 6, int exclude_range = 4, bool cut = true);
+
+/** @brief The base class for camera response calibration algorithms.
+ */
+class CV_EXPORTS_W CalibrateCRF : public Algorithm
+{
+public:
+ /** @brief Recovers inverse camera response.
+
+ @param src vector of input images
+ @param dst 256x1 matrix with inverse camera response function
+ @param times vector of exposure time values for each image
+ */
+ CV_WRAP virtual void process(InputArrayOfArrays src, OutputArray dst, InputArray times) = 0;
+};
+
+/** @brief Inverse camera response function is extracted for each brightness value by minimizing an objective
+function as linear system. Objective function is constructed using pixel values on the same position
+in all images, extra term is added to make the result smoother.
+
+For more information see @cite DM97 .
+ */
+class CV_EXPORTS_W CalibrateDebevec : public CalibrateCRF
+{
+public:
+ CV_WRAP virtual float getLambda() const = 0;
+ CV_WRAP virtual void setLambda(float lambda) = 0;
+
+ CV_WRAP virtual int getSamples() const = 0;
+ CV_WRAP virtual void setSamples(int samples) = 0;
+
+ CV_WRAP virtual bool getRandom() const = 0;
+ CV_WRAP virtual void setRandom(bool random) = 0;
+};
+
+/** @brief Creates CalibrateDebevec object
+
+@param samples number of pixel locations to use
+@param lambda smoothness term weight. Greater values produce smoother results, but can alter the
+response.
+@param random if true sample pixel locations are chosen at random, otherwise the form a
+rectangular grid.
+ */
+CV_EXPORTS_W Ptr<CalibrateDebevec> createCalibrateDebevec(int samples = 70, float lambda = 10.0f, bool random = false);
+
+/** @brief Inverse camera response function is extracted for each brightness value by minimizing an objective
+function as linear system. This algorithm uses all image pixels.
+
+For more information see @cite RB99 .
+ */
+class CV_EXPORTS_W CalibrateRobertson : public CalibrateCRF
+{
+public:
+ CV_WRAP virtual int getMaxIter() const = 0;
+ CV_WRAP virtual void setMaxIter(int max_iter) = 0;
+
+ CV_WRAP virtual float getThreshold() const = 0;
+ CV_WRAP virtual void setThreshold(float threshold) = 0;
+
+ CV_WRAP virtual Mat getRadiance() const = 0;
+};
+
+/** @brief Creates CalibrateRobertson object
+
+@param max_iter maximal number of Gauss-Seidel solver iterations.
+@param threshold target difference between results of two successive steps of the minimization.
+ */
+CV_EXPORTS_W Ptr<CalibrateRobertson> createCalibrateRobertson(int max_iter = 30, float threshold = 0.01f);
+
+/** @brief The base class algorithms that can merge exposure sequence to a single image.
+ */
+class CV_EXPORTS_W MergeExposures : public Algorithm
+{
+public:
+ /** @brief Merges images.
+
+ @param src vector of input images
+ @param dst result image
+ @param times vector of exposure time values for each image
+ @param response 256x1 matrix with inverse camera response function for each pixel value, it should
+ have the same number of channels as images.
+ */
+ CV_WRAP virtual void process(InputArrayOfArrays src, OutputArray dst,
+ InputArray times, InputArray response) = 0;
+};
+
+/** @brief The resulting HDR image is calculated as weighted average of the exposures considering exposure
+values and camera response.
+
+For more information see @cite DM97 .
+ */
+class CV_EXPORTS_W MergeDebevec : public MergeExposures
+{
+public:
+ CV_WRAP virtual void process(InputArrayOfArrays src, OutputArray dst,
+ InputArray times, InputArray response) = 0;
+ CV_WRAP virtual void process(InputArrayOfArrays src, OutputArray dst, InputArray times) = 0;
+};
+
+/** @brief Creates MergeDebevec object
+ */
+CV_EXPORTS_W Ptr<MergeDebevec> createMergeDebevec();
+
+/** @brief Pixels are weighted using contrast, saturation and well-exposedness measures, than images are
+combined using laplacian pyramids.
+
+The resulting image weight is constructed as weighted average of contrast, saturation and
+well-exposedness measures.
+
+The resulting image doesn't require tonemapping and can be converted to 8-bit image by multiplying
+by 255, but it's recommended to apply gamma correction and/or linear tonemapping.
+
+For more information see @cite MK07 .
+ */
+class CV_EXPORTS_W MergeMertens : public MergeExposures
+{
+public:
+ CV_WRAP virtual void process(InputArrayOfArrays src, OutputArray dst,
+ InputArray times, InputArray response) = 0;
+ /** @brief Short version of process, that doesn't take extra arguments.
+
+ @param src vector of input images
+ @param dst result image
+ */
+ CV_WRAP virtual void process(InputArrayOfArrays src, OutputArray dst) = 0;
+
+ CV_WRAP virtual float getContrastWeight() const = 0;
+ CV_WRAP virtual void setContrastWeight(float contrast_weiht) = 0;
+
+ CV_WRAP virtual float getSaturationWeight() const = 0;
+ CV_WRAP virtual void setSaturationWeight(float saturation_weight) = 0;
+
+ CV_WRAP virtual float getExposureWeight() const = 0;
+ CV_WRAP virtual void setExposureWeight(float exposure_weight) = 0;
+};
+
+/** @brief Creates MergeMertens object
+
+@param contrast_weight contrast measure weight. See MergeMertens.
+@param saturation_weight saturation measure weight
+@param exposure_weight well-exposedness measure weight
+ */
+CV_EXPORTS_W Ptr<MergeMertens>
+createMergeMertens(float contrast_weight = 1.0f, float saturation_weight = 1.0f, float exposure_weight = 0.0f);
+
+/** @brief The resulting HDR image is calculated as weighted average of the exposures considering exposure
+values and camera response.
+
+For more information see @cite RB99 .
+ */
+class CV_EXPORTS_W MergeRobertson : public MergeExposures
+{
+public:
+ CV_WRAP virtual void process(InputArrayOfArrays src, OutputArray dst,
+ InputArray times, InputArray response) = 0;
+ CV_WRAP virtual void process(InputArrayOfArrays src, OutputArray dst, InputArray times) = 0;
+};
+
+/** @brief Creates MergeRobertson object
+ */
+CV_EXPORTS_W Ptr<MergeRobertson> createMergeRobertson();
+
+//! @} photo_hdr
+
+/** @brief Transforms a color image to a grayscale image. It is a basic tool in digital printing, stylized
+black-and-white photograph rendering, and in many single channel image processing applications
+@cite CL12 .
+
+@param src Input 8-bit 3-channel image.
+@param grayscale Output 8-bit 1-channel image.
+@param color_boost Output 8-bit 3-channel image.
+
+This function is to be applied on color images.
+ */
+CV_EXPORTS_W void decolor( InputArray src, OutputArray grayscale, OutputArray color_boost);
+
+//! @addtogroup photo_clone
+//! @{
+
+/** @brief Image editing tasks concern either global changes (color/intensity corrections, filters,
+deformations) or local changes concerned to a selection. Here we are interested in achieving local
+changes, ones that are restricted to a region manually selected (ROI), in a seamless and effortless
+manner. The extent of the changes ranges from slight distortions to complete replacement by novel
+content @cite PM03 .
+
+@param src Input 8-bit 3-channel image.
+@param dst Input 8-bit 3-channel image.
+@param mask Input 8-bit 1 or 3-channel image.
+@param p Point in dst image where object is placed.
+@param blend Output image with the same size and type as dst.
+@param flags Cloning method that could be one of the following:
+- **NORMAL_CLONE** The power of the method is fully expressed when inserting objects with
+complex outlines into a new background
+- **MIXED_CLONE** The classic method, color-based selection and alpha masking might be time
+consuming and often leaves an undesirable halo. Seamless cloning, even averaged with the
+original image, is not effective. Mixed seamless cloning based on a loose selection proves
+effective.
+- **FEATURE_EXCHANGE** Feature exchange allows the user to easily replace certain features of
+one object by alternative features.
+ */
+CV_EXPORTS_W void seamlessClone( InputArray src, InputArray dst, InputArray mask, Point p,
+ OutputArray blend, int flags);
+
+/** @brief Given an original color image, two differently colored versions of this image can be mixed
+seamlessly.
+
+@param src Input 8-bit 3-channel image.
+@param mask Input 8-bit 1 or 3-channel image.
+@param dst Output image with the same size and type as src .
+@param red_mul R-channel multiply factor.
+@param green_mul G-channel multiply factor.
+@param blue_mul B-channel multiply factor.
+
+Multiplication factor is between .5 to 2.5.
+ */
+CV_EXPORTS_W void colorChange(InputArray src, InputArray mask, OutputArray dst, float red_mul = 1.0f,
+ float green_mul = 1.0f, float blue_mul = 1.0f);
+
+/** @brief Applying an appropriate non-linear transformation to the gradient field inside the selection and
+then integrating back with a Poisson solver, modifies locally the apparent illumination of an image.
+
+@param src Input 8-bit 3-channel image.
+@param mask Input 8-bit 1 or 3-channel image.
+@param dst Output image with the same size and type as src.
+@param alpha Value ranges between 0-2.
+@param beta Value ranges between 0-2.
+
+This is useful to highlight under-exposed foreground objects or to reduce specular reflections.
+ */
+CV_EXPORTS_W void illuminationChange(InputArray src, InputArray mask, OutputArray dst,
+ float alpha = 0.2f, float beta = 0.4f);
+
+/** @brief By retaining only the gradients at edge locations, before integrating with the Poisson solver, one
+washes out the texture of the selected region, giving its contents a flat aspect. Here Canny Edge
+Detector is used.
+
+@param src Input 8-bit 3-channel image.
+@param mask Input 8-bit 1 or 3-channel image.
+@param dst Output image with the same size and type as src.
+@param low_threshold Range from 0 to 100.
+@param high_threshold Value \> 100.
+@param kernel_size The size of the Sobel kernel to be used.
+
+**NOTE:**
+
+The algorithm assumes that the color of the source image is close to that of the destination. This
+assumption means that when the colors don't match, the source image color gets tinted toward the
+color of the destination image.
+ */
+CV_EXPORTS_W void textureFlattening(InputArray src, InputArray mask, OutputArray dst,
+ float low_threshold = 30, float high_threshold = 45,
+ int kernel_size = 3);
+
+//! @} photo_clone
+
+//! @addtogroup photo_render
+//! @{
+
+/** @brief Filtering is the fundamental operation in image and video processing. Edge-preserving smoothing
+filters are used in many different applications @cite EM11 .
+
+@param src Input 8-bit 3-channel image.
+@param dst Output 8-bit 3-channel image.
+@param flags Edge preserving filters:
+- **RECURS_FILTER** = 1
+- **NORMCONV_FILTER** = 2
+@param sigma_s Range between 0 to 200.
+@param sigma_r Range between 0 to 1.
+ */
+CV_EXPORTS_W void edgePreservingFilter(InputArray src, OutputArray dst, int flags = 1,
+ float sigma_s = 60, float sigma_r = 0.4f);
+
+/** @brief This filter enhances the details of a particular image.
+
+@param src Input 8-bit 3-channel image.
+@param dst Output image with the same size and type as src.
+@param sigma_s Range between 0 to 200.
+@param sigma_r Range between 0 to 1.
+ */
+CV_EXPORTS_W void detailEnhance(InputArray src, OutputArray dst, float sigma_s = 10,
+ float sigma_r = 0.15f);
+
+/** @brief Pencil-like non-photorealistic line drawing
+
+@param src Input 8-bit 3-channel image.
+@param dst1 Output 8-bit 1-channel image.
+@param dst2 Output image with the same size and type as src.
+@param sigma_s Range between 0 to 200.
+@param sigma_r Range between 0 to 1.
+@param shade_factor Range between 0 to 0.1.
+ */
+CV_EXPORTS_W void pencilSketch(InputArray src, OutputArray dst1, OutputArray dst2,
+ float sigma_s = 60, float sigma_r = 0.07f, float shade_factor = 0.02f);
+
+/** @brief Stylization aims to produce digital imagery with a wide variety of effects not focused on
+photorealism. Edge-aware filters are ideal for stylization, as they can abstract regions of low
+contrast while preserving, or enhancing, high-contrast features.
+
+@param src Input 8-bit 3-channel image.
+@param dst Output image with the same size and type as src.
+@param sigma_s Range between 0 to 200.
+@param sigma_r Range between 0 to 1.
+ */
+CV_EXPORTS_W void stylization(InputArray src, OutputArray dst, float sigma_s = 60,
+ float sigma_r = 0.45f);
+
+//! @} photo_render
+
+//! @} photo
+
+} // cv
+
+#ifndef DISABLE_OPENCV_24_COMPATIBILITY
+#include "opencv2/photo/photo_c.h"
+#endif
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/photo/cuda.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,132 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2008-2012, Willow Garage Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_PHOTO_CUDA_HPP
+#define OPENCV_PHOTO_CUDA_HPP
+
+#include "opencv2/core/cuda.hpp"
+
+namespace cv { namespace cuda {
+
+//! @addtogroup photo_denoise
+//! @{
+
+/** @brief Performs pure non local means denoising without any simplification, and thus it is not fast.
+
+@param src Source image. Supports only CV_8UC1, CV_8UC2 and CV_8UC3.
+@param dst Destination image.
+@param h Filter sigma regulating filter strength for color.
+@param search_window Size of search window.
+@param block_size Size of block used for computing weights.
+@param borderMode Border type. See borderInterpolate for details. BORDER_REFLECT101 ,
+BORDER_REPLICATE , BORDER_CONSTANT , BORDER_REFLECT and BORDER_WRAP are supported for now.
+@param stream Stream for the asynchronous version.
+
+@sa
+ fastNlMeansDenoising
+ */
+CV_EXPORTS void nonLocalMeans(InputArray src, OutputArray dst,
+ float h,
+ int search_window = 21,
+ int block_size = 7,
+ int borderMode = BORDER_DEFAULT,
+ Stream& stream = Stream::Null());
+
+/** @brief Perform image denoising using Non-local Means Denoising algorithm
+<http://www.ipol.im/pub/algo/bcm_non_local_means_denoising> with several computational
+optimizations. Noise expected to be a gaussian white noise
+
+@param src Input 8-bit 1-channel, 2-channel or 3-channel image.
+@param dst Output image with the same size and type as src .
+@param h Parameter regulating filter strength. Big h value perfectly removes noise but also
+removes image details, smaller h value preserves details but also preserves some noise
+@param search_window Size in pixels of the window that is used to compute weighted average for
+given pixel. Should be odd. Affect performance linearly: greater search_window - greater
+denoising time. Recommended value 21 pixels
+@param block_size Size in pixels of the template patch that is used to compute weights. Should be
+odd. Recommended value 7 pixels
+@param stream Stream for the asynchronous invocations.
+
+This function expected to be applied to grayscale images. For colored images look at
+FastNonLocalMeansDenoising::labMethod.
+
+@sa
+ fastNlMeansDenoising
+ */
+CV_EXPORTS void fastNlMeansDenoising(InputArray src, OutputArray dst,
+ float h,
+ int search_window = 21,
+ int block_size = 7,
+ Stream& stream = Stream::Null());
+
+/** @brief Modification of fastNlMeansDenoising function for colored images
+
+@param src Input 8-bit 3-channel image.
+@param dst Output image with the same size and type as src .
+@param h_luminance Parameter regulating filter strength. Big h value perfectly removes noise but
+also removes image details, smaller h value preserves details but also preserves some noise
+@param photo_render float The same as h but for color components. For most images value equals 10 will be
+enough to remove colored noise and do not distort colors
+@param search_window Size in pixels of the window that is used to compute weighted average for
+given pixel. Should be odd. Affect performance linearly: greater search_window - greater
+denoising time. Recommended value 21 pixels
+@param block_size Size in pixels of the template patch that is used to compute weights. Should be
+odd. Recommended value 7 pixels
+@param stream Stream for the asynchronous invocations.
+
+The function converts image to CIELAB colorspace and then separately denoise L and AB components
+with given h parameters using FastNonLocalMeansDenoising::simpleMethod function.
+
+@sa
+ fastNlMeansDenoisingColored
+ */
+CV_EXPORTS void fastNlMeansDenoisingColored(InputArray src, OutputArray dst,
+ float h_luminance, float photo_render,
+ int search_window = 21,
+ int block_size = 7,
+ Stream& stream = Stream::Null());
+
+//! @} photo
+
+}} // namespace cv { namespace cuda {
+
+#endif /* OPENCV_PHOTO_CUDA_HPP */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/opencv2/photo/photo.hpp Fri Jan 29 04:53:38 2021 +0000 @@ -0,0 +1,48 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifdef __OPENCV_BUILD +#error this is a compatibility header which should not be used inside the OpenCV library +#endif + +#include "opencv2/photo.hpp"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/photo/photo_c.h Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,74 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2008-2012, Willow Garage Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_PHOTO_C_H
+#define OPENCV_PHOTO_C_H
+
+#include "opencv2/core/core_c.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @addtogroup photo_c
+ @{
+ */
+
+/* Inpainting algorithms */
+enum InpaintingModes
+{
+ CV_INPAINT_NS =0,
+ CV_INPAINT_TELEA =1
+};
+
+
+/* Inpaints the selected region in the image */
+CVAPI(void) cvInpaint( const CvArr* src, const CvArr* inpaint_mask,
+ CvArr* dst, double inpaintRange, int flags );
+
+/** @} */
+
+#ifdef __cplusplus
+} //extern "C"
+#endif
+
+#endif //OPENCV_PHOTO_C_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/opencv2/shape.hpp Fri Jan 29 04:53:38 2021 +0000 @@ -0,0 +1,57 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009-2012, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_SHAPE_HPP +#define OPENCV_SHAPE_HPP + +#include "opencv2/shape/emdL1.hpp" +#include "opencv2/shape/shape_transformer.hpp" +#include "opencv2/shape/hist_cost.hpp" +#include "opencv2/shape/shape_distance.hpp" + +/** + @defgroup shape Shape Distance and Matching + */ + +#endif + +/* End of file. */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/shape/emdL1.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,72 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009-2012, Willow Garage Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_EMD_L1_HPP
+#define OPENCV_EMD_L1_HPP
+
+#include "opencv2/core.hpp"
+
+namespace cv
+{
+/****************************************************************************************\
+* EMDL1 Function *
+\****************************************************************************************/
+
+//! @addtogroup shape
+//! @{
+
+/** @brief Computes the "minimal work" distance between two weighted point configurations base on the papers
+"EMD-L1: An efficient and Robust Algorithm for comparing histogram-based descriptors", by Haibin
+Ling and Kazunori Okuda; and "The Earth Mover's Distance is the Mallows Distance: Some Insights from
+Statistics", by Elizaveta Levina and Peter Bickel.
+
+@param signature1 First signature, a single column floating-point matrix. Each row is the value of
+the histogram in each bin.
+@param signature2 Second signature of the same format and size as signature1.
+ */
+CV_EXPORTS float EMDL1(InputArray signature1, InputArray signature2);
+
+//! @}
+
+}//namespace cv
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/shape/hist_cost.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,111 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_HIST_COST_HPP
+#define OPENCV_HIST_COST_HPP
+
+#include "opencv2/imgproc.hpp"
+
+namespace cv
+{
+
+//! @addtogroup shape
+//! @{
+
+/** @brief Abstract base class for histogram cost algorithms.
+ */
+class CV_EXPORTS_W HistogramCostExtractor : public Algorithm
+{
+public:
+ CV_WRAP virtual void buildCostMatrix(InputArray descriptors1, InputArray descriptors2, OutputArray costMatrix) = 0;
+
+ CV_WRAP virtual void setNDummies(int nDummies) = 0;
+ CV_WRAP virtual int getNDummies() const = 0;
+
+ CV_WRAP virtual void setDefaultCost(float defaultCost) = 0;
+ CV_WRAP virtual float getDefaultCost() const = 0;
+};
+
+/** @brief A norm based cost extraction. :
+ */
+class CV_EXPORTS_W NormHistogramCostExtractor : public HistogramCostExtractor
+{
+public:
+ CV_WRAP virtual void setNormFlag(int flag) = 0;
+ CV_WRAP virtual int getNormFlag() const = 0;
+};
+
+CV_EXPORTS_W Ptr<HistogramCostExtractor>
+ createNormHistogramCostExtractor(int flag=DIST_L2, int nDummies=25, float defaultCost=0.2f);
+
+/** @brief An EMD based cost extraction. :
+ */
+class CV_EXPORTS_W EMDHistogramCostExtractor : public HistogramCostExtractor
+{
+public:
+ CV_WRAP virtual void setNormFlag(int flag) = 0;
+ CV_WRAP virtual int getNormFlag() const = 0;
+};
+
+CV_EXPORTS_W Ptr<HistogramCostExtractor>
+ createEMDHistogramCostExtractor(int flag=DIST_L2, int nDummies=25, float defaultCost=0.2f);
+
+/** @brief An Chi based cost extraction. :
+ */
+class CV_EXPORTS_W ChiHistogramCostExtractor : public HistogramCostExtractor
+{};
+
+CV_EXPORTS_W Ptr<HistogramCostExtractor> createChiHistogramCostExtractor(int nDummies=25, float defaultCost=0.2f);
+
+/** @brief An EMD-L1 based cost extraction. :
+ */
+class CV_EXPORTS_W EMDL1HistogramCostExtractor : public HistogramCostExtractor
+{};
+
+CV_EXPORTS_W Ptr<HistogramCostExtractor>
+ createEMDL1HistogramCostExtractor(int nDummies=25, float defaultCost=0.2f);
+
+//! @}
+
+} // cv
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/opencv2/shape/shape.hpp Fri Jan 29 04:53:38 2021 +0000 @@ -0,0 +1,48 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifdef __OPENCV_BUILD +#error this is a compatibility header which should not be used inside the OpenCV library +#endif + +#include "opencv2/shape.hpp"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/shape/shape_distance.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,224 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_SHAPE_SHAPE_DISTANCE_HPP
+#define OPENCV_SHAPE_SHAPE_DISTANCE_HPP
+#include "opencv2/core.hpp"
+#include "opencv2/shape/hist_cost.hpp"
+#include "opencv2/shape/shape_transformer.hpp"
+
+namespace cv
+{
+
+//! @addtogroup shape
+//! @{
+
+/** @brief Abstract base class for shape distance algorithms.
+ */
+class CV_EXPORTS_W ShapeDistanceExtractor : public Algorithm
+{
+public:
+ /** @brief Compute the shape distance between two shapes defined by its contours.
+
+ @param contour1 Contour defining first shape.
+ @param contour2 Contour defining second shape.
+ */
+ CV_WRAP virtual float computeDistance(InputArray contour1, InputArray contour2) = 0;
+};
+
+/***********************************************************************************/
+/***********************************************************************************/
+/***********************************************************************************/
+/** @brief Implementation of the Shape Context descriptor and matching algorithm
+
+proposed by Belongie et al. in "Shape Matching and Object Recognition Using Shape Contexts" (PAMI
+2002). This implementation is packaged in a generic scheme, in order to allow you the
+implementation of the common variations of the original pipeline.
+*/
+class CV_EXPORTS_W ShapeContextDistanceExtractor : public ShapeDistanceExtractor
+{
+public:
+ /** @brief Establish the number of angular bins for the Shape Context Descriptor used in the shape matching
+ pipeline.
+
+ @param nAngularBins The number of angular bins in the shape context descriptor.
+ */
+ CV_WRAP virtual void setAngularBins(int nAngularBins) = 0;
+ CV_WRAP virtual int getAngularBins() const = 0;
+
+ /** @brief Establish the number of radial bins for the Shape Context Descriptor used in the shape matching
+ pipeline.
+
+ @param nRadialBins The number of radial bins in the shape context descriptor.
+ */
+ CV_WRAP virtual void setRadialBins(int nRadialBins) = 0;
+ CV_WRAP virtual int getRadialBins() const = 0;
+
+ /** @brief Set the inner radius of the shape context descriptor.
+
+ @param innerRadius The value of the inner radius.
+ */
+ CV_WRAP virtual void setInnerRadius(float innerRadius) = 0;
+ CV_WRAP virtual float getInnerRadius() const = 0;
+
+ /** @brief Set the outer radius of the shape context descriptor.
+
+ @param outerRadius The value of the outer radius.
+ */
+ CV_WRAP virtual void setOuterRadius(float outerRadius) = 0;
+ CV_WRAP virtual float getOuterRadius() const = 0;
+
+ CV_WRAP virtual void setRotationInvariant(bool rotationInvariant) = 0;
+ CV_WRAP virtual bool getRotationInvariant() const = 0;
+
+ /** @brief Set the weight of the shape context distance in the final value of the shape distance. The shape
+ context distance between two shapes is defined as the symmetric sum of shape context matching costs
+ over best matching points. The final value of the shape distance is a user-defined linear
+ combination of the shape context distance, an image appearance distance, and a bending energy.
+
+ @param shapeContextWeight The weight of the shape context distance in the final distance value.
+ */
+ CV_WRAP virtual void setShapeContextWeight(float shapeContextWeight) = 0;
+ CV_WRAP virtual float getShapeContextWeight() const = 0;
+
+ /** @brief Set the weight of the Image Appearance cost in the final value of the shape distance. The image
+ appearance cost is defined as the sum of squared brightness differences in Gaussian windows around
+ corresponding image points. The final value of the shape distance is a user-defined linear
+ combination of the shape context distance, an image appearance distance, and a bending energy. If
+ this value is set to a number different from 0, is mandatory to set the images that correspond to
+ each shape.
+
+ @param imageAppearanceWeight The weight of the appearance cost in the final distance value.
+ */
+ CV_WRAP virtual void setImageAppearanceWeight(float imageAppearanceWeight) = 0;
+ CV_WRAP virtual float getImageAppearanceWeight() const = 0;
+
+ /** @brief Set the weight of the Bending Energy in the final value of the shape distance. The bending energy
+ definition depends on what transformation is being used to align the shapes. The final value of the
+ shape distance is a user-defined linear combination of the shape context distance, an image
+ appearance distance, and a bending energy.
+
+ @param bendingEnergyWeight The weight of the Bending Energy in the final distance value.
+ */
+ CV_WRAP virtual void setBendingEnergyWeight(float bendingEnergyWeight) = 0;
+ CV_WRAP virtual float getBendingEnergyWeight() const = 0;
+
+ /** @brief Set the images that correspond to each shape. This images are used in the calculation of the Image
+ Appearance cost.
+
+ @param image1 Image corresponding to the shape defined by contours1.
+ @param image2 Image corresponding to the shape defined by contours2.
+ */
+ CV_WRAP virtual void setImages(InputArray image1, InputArray image2) = 0;
+ CV_WRAP virtual void getImages(OutputArray image1, OutputArray image2) const = 0;
+
+ CV_WRAP virtual void setIterations(int iterations) = 0;
+ CV_WRAP virtual int getIterations() const = 0;
+
+ /** @brief Set the algorithm used for building the shape context descriptor cost matrix.
+
+ @param comparer Smart pointer to a HistogramCostExtractor, an algorithm that defines the cost
+ matrix between descriptors.
+ */
+ CV_WRAP virtual void setCostExtractor(Ptr<HistogramCostExtractor> comparer) = 0;
+ CV_WRAP virtual Ptr<HistogramCostExtractor> getCostExtractor() const = 0;
+
+ /** @brief Set the value of the standard deviation for the Gaussian window for the image appearance cost.
+
+ @param sigma Standard Deviation.
+ */
+ CV_WRAP virtual void setStdDev(float sigma) = 0;
+ CV_WRAP virtual float getStdDev() const = 0;
+
+ /** @brief Set the algorithm used for aligning the shapes.
+
+ @param transformer Smart pointer to a ShapeTransformer, an algorithm that defines the aligning
+ transformation.
+ */
+ CV_WRAP virtual void setTransformAlgorithm(Ptr<ShapeTransformer> transformer) = 0;
+ CV_WRAP virtual Ptr<ShapeTransformer> getTransformAlgorithm() const = 0;
+};
+
+/* Complete constructor */
+CV_EXPORTS_W Ptr<ShapeContextDistanceExtractor>
+ createShapeContextDistanceExtractor(int nAngularBins=12, int nRadialBins=4,
+ float innerRadius=0.2f, float outerRadius=2, int iterations=3,
+ const Ptr<HistogramCostExtractor> &comparer = createChiHistogramCostExtractor(),
+ const Ptr<ShapeTransformer> &transformer = createThinPlateSplineShapeTransformer());
+
+/***********************************************************************************/
+/***********************************************************************************/
+/***********************************************************************************/
+/** @brief A simple Hausdorff distance measure between shapes defined by contours
+
+according to the paper "Comparing Images using the Hausdorff distance." by D.P. Huttenlocher, G.A.
+Klanderman, and W.J. Rucklidge. (PAMI 1993). :
+ */
+class CV_EXPORTS_W HausdorffDistanceExtractor : public ShapeDistanceExtractor
+{
+public:
+ /** @brief Set the norm used to compute the Hausdorff value between two shapes. It can be L1 or L2 norm.
+
+ @param distanceFlag Flag indicating which norm is used to compute the Hausdorff distance
+ (NORM_L1, NORM_L2).
+ */
+ CV_WRAP virtual void setDistanceFlag(int distanceFlag) = 0;
+ CV_WRAP virtual int getDistanceFlag() const = 0;
+
+ /** @brief This method sets the rank proportion (or fractional value) that establish the Kth ranked value of
+ the partial Hausdorff distance. Experimentally had been shown that 0.6 is a good value to compare
+ shapes.
+
+ @param rankProportion fractional value (between 0 and 1).
+ */
+ CV_WRAP virtual void setRankProportion(float rankProportion) = 0;
+ CV_WRAP virtual float getRankProportion() const = 0;
+};
+
+/* Constructor */
+CV_EXPORTS_W Ptr<HausdorffDistanceExtractor> createHausdorffDistanceExtractor(int distanceFlag=cv::NORM_L2, float rankProp=0.6f);
+
+//! @}
+
+} // cv
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/shape/shape_transformer.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,132 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_SHAPE_SHAPE_TRANSFORM_HPP
+#define OPENCV_SHAPE_SHAPE_TRANSFORM_HPP
+#include <vector>
+#include "opencv2/core.hpp"
+#include "opencv2/imgproc.hpp"
+
+namespace cv
+{
+
+//! @addtogroup shape
+//! @{
+
+/** @brief Abstract base class for shape transformation algorithms.
+ */
+class CV_EXPORTS_W ShapeTransformer : public Algorithm
+{
+public:
+ /** @brief Estimate the transformation parameters of the current transformer algorithm, based on point matches.
+
+ @param transformingShape Contour defining first shape.
+ @param targetShape Contour defining second shape (Target).
+ @param matches Standard vector of Matches between points.
+ */
+ CV_WRAP virtual void estimateTransformation(InputArray transformingShape, InputArray targetShape,
+ std::vector<DMatch>& matches) = 0;
+
+ /** @brief Apply a transformation, given a pre-estimated transformation parameters.
+
+ @param input Contour (set of points) to apply the transformation.
+ @param output Output contour.
+ */
+ CV_WRAP virtual float applyTransformation(InputArray input, OutputArray output=noArray()) = 0;
+
+ /** @brief Apply a transformation, given a pre-estimated transformation parameters, to an Image.
+
+ @param transformingImage Input image.
+ @param output Output image.
+ @param flags Image interpolation method.
+ @param borderMode border style.
+ @param borderValue border value.
+ */
+ CV_WRAP virtual void warpImage(InputArray transformingImage, OutputArray output,
+ int flags=INTER_LINEAR, int borderMode=BORDER_CONSTANT,
+ const Scalar& borderValue=Scalar()) const = 0;
+};
+
+/***********************************************************************************/
+/***********************************************************************************/
+
+/** @brief Definition of the transformation
+
+ocupied in the paper "Principal Warps: Thin-Plate Splines and Decomposition of Deformations", by
+F.L. Bookstein (PAMI 1989). :
+ */
+class CV_EXPORTS_W ThinPlateSplineShapeTransformer : public ShapeTransformer
+{
+public:
+ /** @brief Set the regularization parameter for relaxing the exact interpolation requirements of the TPS
+ algorithm.
+
+ @param beta value of the regularization parameter.
+ */
+ CV_WRAP virtual void setRegularizationParameter(double beta) = 0;
+ CV_WRAP virtual double getRegularizationParameter() const = 0;
+};
+
+/** Complete constructor */
+CV_EXPORTS_W Ptr<ThinPlateSplineShapeTransformer>
+ createThinPlateSplineShapeTransformer(double regularizationParameter=0);
+
+/***********************************************************************************/
+/***********************************************************************************/
+
+/** @brief Wrapper class for the OpenCV Affine Transformation algorithm. :
+ */
+class CV_EXPORTS_W AffineTransformer : public ShapeTransformer
+{
+public:
+ CV_WRAP virtual void setFullAffine(bool fullAffine) = 0;
+ CV_WRAP virtual bool getFullAffine() const = 0;
+};
+
+/** Complete constructor */
+CV_EXPORTS_W Ptr<AffineTransformer> createAffineTransformer(bool fullAffine);
+
+//! @}
+
+} // cv
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/stitching.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,320 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_STITCHING_STITCHER_HPP
+#define OPENCV_STITCHING_STITCHER_HPP
+
+#include "opencv2/core.hpp"
+#include "opencv2/features2d.hpp"
+#include "opencv2/stitching/warpers.hpp"
+#include "opencv2/stitching/detail/matchers.hpp"
+#include "opencv2/stitching/detail/motion_estimators.hpp"
+#include "opencv2/stitching/detail/exposure_compensate.hpp"
+#include "opencv2/stitching/detail/seam_finders.hpp"
+#include "opencv2/stitching/detail/blenders.hpp"
+#include "opencv2/stitching/detail/camera.hpp"
+
+
+#if defined(Status)
+# warning Detected X11 'Status' macro definition, it can cause build conflicts. Please, include this header before any X11 headers.
+#endif
+
+
+/**
+@defgroup stitching Images stitching
+
+This figure illustrates the stitching module pipeline implemented in the Stitcher class. Using that
+class it's possible to configure/remove some steps, i.e. adjust the stitching pipeline according to
+the particular needs. All building blocks from the pipeline are available in the detail namespace,
+one can combine and use them separately.
+
+The implemented stitching pipeline is very similar to the one proposed in @cite BL07 .
+
+
+
+Camera models
+-------------
+
+There are currently 2 camera models implemented in stitching pipeline.
+
+- _Homography model_ expecting perspective transformations between images
+ implemented in @ref cv::detail::BestOf2NearestMatcher cv::detail::HomographyBasedEstimator
+ cv::detail::BundleAdjusterReproj cv::detail::BundleAdjusterRay
+- _Affine model_ expecting affine transformation with 6 DOF or 4 DOF implemented in
+ @ref cv::detail::AffineBestOf2NearestMatcher cv::detail::AffineBasedEstimator
+ cv::detail::BundleAdjusterAffine cv::detail::BundleAdjusterAffinePartial cv::AffineWarper
+
+Homography model is useful for creating photo panoramas captured by camera,
+while affine-based model can be used to stitch scans and object captured by
+specialized devices. Use @ref cv::Stitcher::create to get preconfigured pipeline for one
+of those models.
+
+@note
+Certain detailed settings of @ref cv::Stitcher might not make sense. Especially
+you should not mix classes implementing affine model and classes implementing
+Homography model, as they work with different transformations.
+
+@{
+ @defgroup stitching_match Features Finding and Images Matching
+ @defgroup stitching_rotation Rotation Estimation
+ @defgroup stitching_autocalib Autocalibration
+ @defgroup stitching_warp Images Warping
+ @defgroup stitching_seam Seam Estimation
+ @defgroup stitching_exposure Exposure Compensation
+ @defgroup stitching_blend Image Blenders
+@}
+ */
+
+namespace cv {
+
+//! @addtogroup stitching
+//! @{
+
+/** @brief High level image stitcher.
+
+It's possible to use this class without being aware of the entire stitching pipeline. However, to
+be able to achieve higher stitching stability and quality of the final images at least being
+familiar with the theory is recommended.
+
+@note
+ - A basic example on image stitching can be found at
+ opencv_source_code/samples/cpp/stitching.cpp
+ - A detailed example on image stitching can be found at
+ opencv_source_code/samples/cpp/stitching_detailed.cpp
+ */
+class CV_EXPORTS_W Stitcher
+{
+public:
+ enum { ORIG_RESOL = -1 };
+ enum Status
+ {
+ OK = 0,
+ ERR_NEED_MORE_IMGS = 1,
+ ERR_HOMOGRAPHY_EST_FAIL = 2,
+ ERR_CAMERA_PARAMS_ADJUST_FAIL = 3
+ };
+ enum Mode
+ {
+ /** Mode for creating photo panoramas. Expects images under perspective
+ transformation and projects resulting pano to sphere.
+
+ @sa detail::BestOf2NearestMatcher SphericalWarper
+ */
+ PANORAMA = 0,
+ /** Mode for composing scans. Expects images under affine transformation does
+ not compensate exposure by default.
+
+ @sa detail::AffineBestOf2NearestMatcher AffineWarper
+ */
+ SCANS = 1,
+
+ };
+
+ // Stitcher() {}
+ /** @brief Creates a stitcher with the default parameters.
+
+ @param try_use_gpu Flag indicating whether GPU should be used whenever it's possible.
+ @return Stitcher class instance.
+ */
+ static Stitcher createDefault(bool try_use_gpu = false);
+ /** @brief Creates a Stitcher configured in one of the stitching modes.
+
+ @param mode Scenario for stitcher operation. This is usually determined by source of images
+ to stitch and their transformation. Default parameters will be chosen for operation in given
+ scenario.
+ @param try_use_gpu Flag indicating whether GPU should be used whenever it's possible.
+ @return Stitcher class instance.
+ */
+ static Ptr<Stitcher> create(Mode mode = PANORAMA, bool try_use_gpu = false);
+
+ CV_WRAP double registrationResol() const { return registr_resol_; }
+ CV_WRAP void setRegistrationResol(double resol_mpx) { registr_resol_ = resol_mpx; }
+
+ CV_WRAP double seamEstimationResol() const { return seam_est_resol_; }
+ CV_WRAP void setSeamEstimationResol(double resol_mpx) { seam_est_resol_ = resol_mpx; }
+
+ CV_WRAP double compositingResol() const { return compose_resol_; }
+ CV_WRAP void setCompositingResol(double resol_mpx) { compose_resol_ = resol_mpx; }
+
+ CV_WRAP double panoConfidenceThresh() const { return conf_thresh_; }
+ CV_WRAP void setPanoConfidenceThresh(double conf_thresh) { conf_thresh_ = conf_thresh; }
+
+ CV_WRAP bool waveCorrection() const { return do_wave_correct_; }
+ CV_WRAP void setWaveCorrection(bool flag) { do_wave_correct_ = flag; }
+
+ detail::WaveCorrectKind waveCorrectKind() const { return wave_correct_kind_; }
+ void setWaveCorrectKind(detail::WaveCorrectKind kind) { wave_correct_kind_ = kind; }
+
+ Ptr<detail::FeaturesFinder> featuresFinder() { return features_finder_; }
+ const Ptr<detail::FeaturesFinder> featuresFinder() const { return features_finder_; }
+ void setFeaturesFinder(Ptr<detail::FeaturesFinder> features_finder)
+ { features_finder_ = features_finder; }
+
+ Ptr<detail::FeaturesMatcher> featuresMatcher() { return features_matcher_; }
+ const Ptr<detail::FeaturesMatcher> featuresMatcher() const { return features_matcher_; }
+ void setFeaturesMatcher(Ptr<detail::FeaturesMatcher> features_matcher)
+ { features_matcher_ = features_matcher; }
+
+ const cv::UMat& matchingMask() const { return matching_mask_; }
+ void setMatchingMask(const cv::UMat &mask)
+ {
+ CV_Assert(mask.type() == CV_8U && mask.cols == mask.rows);
+ matching_mask_ = mask.clone();
+ }
+
+ Ptr<detail::BundleAdjusterBase> bundleAdjuster() { return bundle_adjuster_; }
+ const Ptr<detail::BundleAdjusterBase> bundleAdjuster() const { return bundle_adjuster_; }
+ void setBundleAdjuster(Ptr<detail::BundleAdjusterBase> bundle_adjuster)
+ { bundle_adjuster_ = bundle_adjuster; }
+
+ /* TODO OpenCV ABI 4.x
+ Ptr<detail::Estimator> estimator() { return estimator_; }
+ const Ptr<detail::Estimator> estimator() const { return estimator_; }
+ void setEstimator(Ptr<detail::Estimator> estimator)
+ { estimator_ = estimator; }
+ */
+
+ Ptr<WarperCreator> warper() { return warper_; }
+ const Ptr<WarperCreator> warper() const { return warper_; }
+ void setWarper(Ptr<WarperCreator> creator) { warper_ = creator; }
+
+ Ptr<detail::ExposureCompensator> exposureCompensator() { return exposure_comp_; }
+ const Ptr<detail::ExposureCompensator> exposureCompensator() const { return exposure_comp_; }
+ void setExposureCompensator(Ptr<detail::ExposureCompensator> exposure_comp)
+ { exposure_comp_ = exposure_comp; }
+
+ Ptr<detail::SeamFinder> seamFinder() { return seam_finder_; }
+ const Ptr<detail::SeamFinder> seamFinder() const { return seam_finder_; }
+ void setSeamFinder(Ptr<detail::SeamFinder> seam_finder) { seam_finder_ = seam_finder; }
+
+ Ptr<detail::Blender> blender() { return blender_; }
+ const Ptr<detail::Blender> blender() const { return blender_; }
+ void setBlender(Ptr<detail::Blender> b) { blender_ = b; }
+
+ /** @overload */
+ CV_WRAP Status estimateTransform(InputArrayOfArrays images);
+ /** @brief These functions try to match the given images and to estimate rotations of each camera.
+
+ @note Use the functions only if you're aware of the stitching pipeline, otherwise use
+ Stitcher::stitch.
+
+ @param images Input images.
+ @param rois Region of interest rectangles.
+ @return Status code.
+ */
+ Status estimateTransform(InputArrayOfArrays images, const std::vector<std::vector<Rect> > &rois);
+
+ /** @overload */
+ CV_WRAP Status composePanorama(OutputArray pano);
+ /** @brief These functions try to compose the given images (or images stored internally from the other function
+ calls) into the final pano under the assumption that the image transformations were estimated
+ before.
+
+ @note Use the functions only if you're aware of the stitching pipeline, otherwise use
+ Stitcher::stitch.
+
+ @param images Input images.
+ @param pano Final pano.
+ @return Status code.
+ */
+ Status composePanorama(InputArrayOfArrays images, OutputArray pano);
+
+ /** @overload */
+ CV_WRAP Status stitch(InputArrayOfArrays images, OutputArray pano);
+ /** @brief These functions try to stitch the given images.
+
+ @param images Input images.
+ @param rois Region of interest rectangles.
+ @param pano Final pano.
+ @return Status code.
+ */
+ Status stitch(InputArrayOfArrays images, const std::vector<std::vector<Rect> > &rois, OutputArray pano);
+
+ std::vector<int> component() const { return indices_; }
+ std::vector<detail::CameraParams> cameras() const { return cameras_; }
+ CV_WRAP double workScale() const { return work_scale_; }
+
+private:
+ //Stitcher() {}
+
+ Status matchImages();
+ Status estimateCameraParams();
+
+ double registr_resol_;
+ double seam_est_resol_;
+ double compose_resol_;
+ double conf_thresh_;
+ Ptr<detail::FeaturesFinder> features_finder_;
+ Ptr<detail::FeaturesMatcher> features_matcher_;
+ cv::UMat matching_mask_;
+ Ptr<detail::BundleAdjusterBase> bundle_adjuster_;
+ /* TODO OpenCV ABI 4.x
+ Ptr<detail::Estimator> estimator_;
+ */
+ bool do_wave_correct_;
+ detail::WaveCorrectKind wave_correct_kind_;
+ Ptr<WarperCreator> warper_;
+ Ptr<detail::ExposureCompensator> exposure_comp_;
+ Ptr<detail::SeamFinder> seam_finder_;
+ Ptr<detail::Blender> blender_;
+
+ std::vector<cv::UMat> imgs_;
+ std::vector<std::vector<cv::Rect> > rois_;
+ std::vector<cv::Size> full_img_sizes_;
+ std::vector<detail::ImageFeatures> features_;
+ std::vector<detail::MatchesInfo> pairwise_matches_;
+ std::vector<cv::UMat> seam_est_imgs_;
+ std::vector<int> indices_;
+ std::vector<detail::CameraParams> cameras_;
+ double work_scale_;
+ double seam_scale_;
+ double seam_work_aspect_;
+ double warped_image_scale_;
+};
+
+CV_EXPORTS_W Ptr<Stitcher> createStitcher(bool try_use_gpu = false);
+
+//! @} stitching
+
+} // namespace cv
+
+#endif // OPENCV_STITCHING_STITCHER_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/stitching/detail/autocalib.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,86 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_STITCHING_AUTOCALIB_HPP
+#define OPENCV_STITCHING_AUTOCALIB_HPP
+
+#include "opencv2/core.hpp"
+#include "matchers.hpp"
+
+namespace cv {
+namespace detail {
+
+//! @addtogroup stitching_autocalib
+//! @{
+
+/** @brief Tries to estimate focal lengths from the given homography under the assumption that the camera
+undergoes rotations around its centre only.
+
+@param H Homography.
+@param f0 Estimated focal length along X axis.
+@param f1 Estimated focal length along Y axis.
+@param f0_ok True, if f0 was estimated successfully, false otherwise.
+@param f1_ok True, if f1 was estimated successfully, false otherwise.
+
+See "Construction of Panoramic Image Mosaics with Global and Local Alignment"
+by Heung-Yeung Shum and Richard Szeliski.
+ */
+void CV_EXPORTS focalsFromHomography(const Mat &H, double &f0, double &f1, bool &f0_ok, bool &f1_ok);
+
+/** @brief Estimates focal lengths for each given camera.
+
+@param features Features of images.
+@param pairwise_matches Matches between all image pairs.
+@param focals Estimated focal lengths for each camera.
+ */
+void CV_EXPORTS estimateFocal(const std::vector<ImageFeatures> &features,
+ const std::vector<MatchesInfo> &pairwise_matches,
+ std::vector<double> &focals);
+
+bool CV_EXPORTS calibrateRotatingCamera(const std::vector<Mat> &Hs, Mat &K);
+
+//! @} stitching_autocalib
+
+} // namespace detail
+} // namespace cv
+
+#endif // OPENCV_STITCHING_AUTOCALIB_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/stitching/detail/blenders.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,167 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_STITCHING_BLENDERS_HPP
+#define OPENCV_STITCHING_BLENDERS_HPP
+
+#if defined(NO)
+# warning Detected Apple 'NO' macro definition, it can cause build conflicts. Please, include this header before any Apple headers.
+#endif
+
+#include "opencv2/core.hpp"
+
+namespace cv {
+namespace detail {
+
+//! @addtogroup stitching_blend
+//! @{
+
+/** @brief Base class for all blenders.
+
+Simple blender which puts one image over another
+*/
+class CV_EXPORTS Blender
+{
+public:
+ virtual ~Blender() {}
+
+ enum { NO, FEATHER, MULTI_BAND };
+ static Ptr<Blender> createDefault(int type, bool try_gpu = false);
+
+ /** @brief Prepares the blender for blending.
+
+ @param corners Source images top-left corners
+ @param sizes Source image sizes
+ */
+ void prepare(const std::vector<Point> &corners, const std::vector<Size> &sizes);
+ /** @overload */
+ virtual void prepare(Rect dst_roi);
+ /** @brief Processes the image.
+
+ @param img Source image
+ @param mask Source image mask
+ @param tl Source image top-left corners
+ */
+ virtual void feed(InputArray img, InputArray mask, Point tl);
+ /** @brief Blends and returns the final pano.
+
+ @param dst Final pano
+ @param dst_mask Final pano mask
+ */
+ virtual void blend(InputOutputArray dst, InputOutputArray dst_mask);
+
+protected:
+ UMat dst_, dst_mask_;
+ Rect dst_roi_;
+};
+
+/** @brief Simple blender which mixes images at its borders.
+ */
+class CV_EXPORTS FeatherBlender : public Blender
+{
+public:
+ FeatherBlender(float sharpness = 0.02f);
+
+ float sharpness() const { return sharpness_; }
+ void setSharpness(float val) { sharpness_ = val; }
+
+ void prepare(Rect dst_roi);
+ void feed(InputArray img, InputArray mask, Point tl);
+ void blend(InputOutputArray dst, InputOutputArray dst_mask);
+
+ //! Creates weight maps for fixed set of source images by their masks and top-left corners.
+ //! Final image can be obtained by simple weighting of the source images.
+ Rect createWeightMaps(const std::vector<UMat> &masks, const std::vector<Point> &corners,
+ std::vector<UMat> &weight_maps);
+
+private:
+ float sharpness_;
+ UMat weight_map_;
+ UMat dst_weight_map_;
+};
+
+inline FeatherBlender::FeatherBlender(float _sharpness) { setSharpness(_sharpness); }
+
+/** @brief Blender which uses multi-band blending algorithm (see @cite BA83).
+ */
+class CV_EXPORTS MultiBandBlender : public Blender
+{
+public:
+ MultiBandBlender(int try_gpu = false, int num_bands = 5, int weight_type = CV_32F);
+
+ int numBands() const { return actual_num_bands_; }
+ void setNumBands(int val) { actual_num_bands_ = val; }
+
+ void prepare(Rect dst_roi);
+ void feed(InputArray img, InputArray mask, Point tl);
+ void blend(InputOutputArray dst, InputOutputArray dst_mask);
+
+private:
+ int actual_num_bands_, num_bands_;
+ std::vector<UMat> dst_pyr_laplace_;
+ std::vector<UMat> dst_band_weights_;
+ Rect dst_roi_final_;
+ bool can_use_gpu_;
+ int weight_type_; //CV_32F or CV_16S
+};
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Auxiliary functions
+
+void CV_EXPORTS normalizeUsingWeightMap(InputArray weight, InputOutputArray src);
+
+void CV_EXPORTS createWeightMap(InputArray mask, float sharpness, InputOutputArray weight);
+
+void CV_EXPORTS createLaplacePyr(InputArray img, int num_levels, std::vector<UMat>& pyr);
+void CV_EXPORTS createLaplacePyrGpu(InputArray img, int num_levels, std::vector<UMat>& pyr);
+
+// Restores source image
+void CV_EXPORTS restoreImageFromLaplacePyr(std::vector<UMat>& pyr);
+void CV_EXPORTS restoreImageFromLaplacePyrGpu(std::vector<UMat>& pyr);
+
+//! @}
+
+} // namespace detail
+} // namespace cv
+
+#endif // OPENCV_STITCHING_BLENDERS_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/stitching/detail/camera.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,78 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_STITCHING_CAMERA_HPP
+#define OPENCV_STITCHING_CAMERA_HPP
+
+#include "opencv2/core.hpp"
+
+namespace cv {
+namespace detail {
+
+//! @addtogroup stitching
+//! @{
+
+/** @brief Describes camera parameters.
+
+@note Translation is assumed to be zero during the whole stitching pipeline. :
+ */
+struct CV_EXPORTS CameraParams
+{
+ CameraParams();
+ CameraParams(const CameraParams& other);
+ const CameraParams& operator =(const CameraParams& other);
+ Mat K() const;
+
+ double focal; // Focal length
+ double aspect; // Aspect ratio
+ double ppx; // Principal point X
+ double ppy; // Principal point Y
+ Mat R; // Rotation
+ Mat t; // Translation
+};
+
+//! @}
+
+} // namespace detail
+} // namespace cv
+
+#endif // #ifndef OPENCV_STITCHING_CAMERA_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/stitching/detail/exposure_compensate.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,136 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_STITCHING_EXPOSURE_COMPENSATE_HPP
+#define OPENCV_STITCHING_EXPOSURE_COMPENSATE_HPP
+
+#if defined(NO)
+# warning Detected Apple 'NO' macro definition, it can cause build conflicts. Please, include this header before any Apple headers.
+#endif
+
+#include "opencv2/core.hpp"
+
+namespace cv {
+namespace detail {
+
+//! @addtogroup stitching_exposure
+//! @{
+
+/** @brief Base class for all exposure compensators.
+ */
+class CV_EXPORTS ExposureCompensator
+{
+public:
+ virtual ~ExposureCompensator() {}
+
+ enum { NO, GAIN, GAIN_BLOCKS };
+ static Ptr<ExposureCompensator> createDefault(int type);
+
+ /**
+ @param corners Source image top-left corners
+ @param images Source images
+ @param masks Image masks to update (second value in pair specifies the value which should be used
+ to detect where image is)
+ */
+ void feed(const std::vector<Point> &corners, const std::vector<UMat> &images,
+ const std::vector<UMat> &masks);
+ /** @overload */
+ virtual void feed(const std::vector<Point> &corners, const std::vector<UMat> &images,
+ const std::vector<std::pair<UMat,uchar> > &masks) = 0;
+ /** @brief Compensate exposure in the specified image.
+
+ @param index Image index
+ @param corner Image top-left corner
+ @param image Image to process
+ @param mask Image mask
+ */
+ virtual void apply(int index, Point corner, InputOutputArray image, InputArray mask) = 0;
+};
+
+/** @brief Stub exposure compensator which does nothing.
+ */
+class CV_EXPORTS NoExposureCompensator : public ExposureCompensator
+{
+public:
+ void feed(const std::vector<Point> &/*corners*/, const std::vector<UMat> &/*images*/,
+ const std::vector<std::pair<UMat,uchar> > &/*masks*/) { }
+ void apply(int /*index*/, Point /*corner*/, InputOutputArray /*image*/, InputArray /*mask*/) { }
+};
+
+/** @brief Exposure compensator which tries to remove exposure related artifacts by adjusting image
+intensities, see @cite BL07 and @cite WJ10 for details.
+ */
+class CV_EXPORTS GainCompensator : public ExposureCompensator
+{
+public:
+ void feed(const std::vector<Point> &corners, const std::vector<UMat> &images,
+ const std::vector<std::pair<UMat,uchar> > &masks);
+ void apply(int index, Point corner, InputOutputArray image, InputArray mask);
+ std::vector<double> gains() const;
+
+private:
+ Mat_<double> gains_;
+};
+
+/** @brief Exposure compensator which tries to remove exposure related artifacts by adjusting image block
+intensities, see @cite UES01 for details.
+ */
+class CV_EXPORTS BlocksGainCompensator : public ExposureCompensator
+{
+public:
+ BlocksGainCompensator(int bl_width = 32, int bl_height = 32)
+ : bl_width_(bl_width), bl_height_(bl_height) {}
+ void feed(const std::vector<Point> &corners, const std::vector<UMat> &images,
+ const std::vector<std::pair<UMat,uchar> > &masks);
+ void apply(int index, Point corner, InputOutputArray image, InputArray mask);
+
+private:
+ int bl_width_, bl_height_;
+ std::vector<UMat> gain_maps_;
+};
+
+//! @}
+
+} // namespace detail
+} // namespace cv
+
+#endif // OPENCV_STITCHING_EXPOSURE_COMPENSATE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/stitching/detail/matchers.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,355 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_STITCHING_MATCHERS_HPP
+#define OPENCV_STITCHING_MATCHERS_HPP
+
+#include "opencv2/core.hpp"
+#include "opencv2/features2d.hpp"
+
+#include "opencv2/opencv_modules.hpp"
+
+#ifdef HAVE_OPENCV_XFEATURES2D
+# include "opencv2/xfeatures2d/cuda.hpp"
+#endif
+
+namespace cv {
+namespace detail {
+
+//! @addtogroup stitching_match
+//! @{
+
+/** @brief Structure containing image keypoints and descriptors. */
+struct CV_EXPORTS ImageFeatures
+{
+ int img_idx;
+ Size img_size;
+ std::vector<KeyPoint> keypoints;
+ UMat descriptors;
+};
+
+/** @brief Feature finders base class */
+class CV_EXPORTS FeaturesFinder
+{
+public:
+ virtual ~FeaturesFinder() {}
+ /** @overload */
+ void operator ()(InputArray image, ImageFeatures &features);
+ /** @brief Finds features in the given image.
+
+ @param image Source image
+ @param features Found features
+ @param rois Regions of interest
+
+ @sa detail::ImageFeatures, Rect_
+ */
+ void operator ()(InputArray image, ImageFeatures &features, const std::vector<cv::Rect> &rois);
+ /** @brief Finds features in the given images in parallel.
+
+ @param images Source images
+ @param features Found features for each image
+ @param rois Regions of interest for each image
+
+ @sa detail::ImageFeatures, Rect_
+ */
+ void operator ()(InputArrayOfArrays images, std::vector<ImageFeatures> &features,
+ const std::vector<std::vector<cv::Rect> > &rois);
+ /** @overload */
+ void operator ()(InputArrayOfArrays images, std::vector<ImageFeatures> &features);
+ /** @brief Frees unused memory allocated before if there is any. */
+ virtual void collectGarbage() {}
+
+ /* TODO OpenCV ABI 4.x
+ reimplement this as public method similar to FeaturesMatcher and remove private function hack
+ @return True, if it's possible to use the same finder instance in parallel, false otherwise
+ bool isThreadSafe() const { return is_thread_safe_; }
+ */
+
+protected:
+ /** @brief This method must implement features finding logic in order to make the wrappers
+ detail::FeaturesFinder::operator()_ work.
+
+ @param image Source image
+ @param features Found features
+
+ @sa detail::ImageFeatures */
+ virtual void find(InputArray image, ImageFeatures &features) = 0;
+ /** @brief uses dynamic_cast to determine thread-safety
+ @return True, if it's possible to use the same finder instance in parallel, false otherwise
+ */
+ bool isThreadSafe() const;
+};
+
+/** @brief SURF features finder.
+
+@sa detail::FeaturesFinder, SURF
+*/
+class CV_EXPORTS SurfFeaturesFinder : public FeaturesFinder
+{
+public:
+ SurfFeaturesFinder(double hess_thresh = 300., int num_octaves = 3, int num_layers = 4,
+ int num_octaves_descr = /*4*/3, int num_layers_descr = /*2*/4);
+
+private:
+ void find(InputArray image, ImageFeatures &features);
+
+ Ptr<FeatureDetector> detector_;
+ Ptr<DescriptorExtractor> extractor_;
+ Ptr<Feature2D> surf;
+};
+
+/** @brief ORB features finder. :
+
+@sa detail::FeaturesFinder, ORB
+*/
+class CV_EXPORTS OrbFeaturesFinder : public FeaturesFinder
+{
+public:
+ OrbFeaturesFinder(Size _grid_size = Size(3,1), int nfeatures=1500, float scaleFactor=1.3f, int nlevels=5);
+
+private:
+ void find(InputArray image, ImageFeatures &features);
+
+ Ptr<ORB> orb;
+ Size grid_size;
+};
+
+/** @brief AKAZE features finder. :
+
+@sa detail::FeaturesFinder, AKAZE
+*/
+class CV_EXPORTS AKAZEFeaturesFinder : public detail::FeaturesFinder
+{
+public:
+ AKAZEFeaturesFinder(int descriptor_type = AKAZE::DESCRIPTOR_MLDB,
+ int descriptor_size = 0,
+ int descriptor_channels = 3,
+ float threshold = 0.001f,
+ int nOctaves = 4,
+ int nOctaveLayers = 4,
+ int diffusivity = KAZE::DIFF_PM_G2);
+
+private:
+ void find(InputArray image, detail::ImageFeatures &features);
+
+ Ptr<AKAZE> akaze;
+};
+
+#ifdef HAVE_OPENCV_XFEATURES2D
+class CV_EXPORTS SurfFeaturesFinderGpu : public FeaturesFinder
+{
+public:
+ SurfFeaturesFinderGpu(double hess_thresh = 300., int num_octaves = 3, int num_layers = 4,
+ int num_octaves_descr = 4, int num_layers_descr = 2);
+
+ void collectGarbage();
+
+private:
+ void find(InputArray image, ImageFeatures &features);
+
+ cuda::GpuMat image_;
+ cuda::GpuMat gray_image_;
+ cuda::SURF_CUDA surf_;
+ cuda::GpuMat keypoints_;
+ cuda::GpuMat descriptors_;
+ int num_octaves_, num_layers_;
+ int num_octaves_descr_, num_layers_descr_;
+};
+#endif
+
+/** @brief Structure containing information about matches between two images.
+
+It's assumed that there is a transformation between those images. Transformation may be
+homography or affine transformation based on selected matcher.
+
+@sa detail::FeaturesMatcher
+*/
+struct CV_EXPORTS MatchesInfo
+{
+ MatchesInfo();
+ MatchesInfo(const MatchesInfo &other);
+ const MatchesInfo& operator =(const MatchesInfo &other);
+
+ int src_img_idx, dst_img_idx; //!< Images indices (optional)
+ std::vector<DMatch> matches;
+ std::vector<uchar> inliers_mask; //!< Geometrically consistent matches mask
+ int num_inliers; //!< Number of geometrically consistent matches
+ Mat H; //!< Estimated transformation
+ double confidence; //!< Confidence two images are from the same panorama
+};
+
+/** @brief Feature matchers base class. */
+class CV_EXPORTS FeaturesMatcher
+{
+public:
+ virtual ~FeaturesMatcher() {}
+
+ /** @overload
+ @param features1 First image features
+ @param features2 Second image features
+ @param matches_info Found matches
+ */
+ void operator ()(const ImageFeatures &features1, const ImageFeatures &features2,
+ MatchesInfo& matches_info) { match(features1, features2, matches_info); }
+
+ /** @brief Performs images matching.
+
+ @param features Features of the source images
+ @param pairwise_matches Found pairwise matches
+ @param mask Mask indicating which image pairs must be matched
+
+ The function is parallelized with the TBB library.
+
+ @sa detail::MatchesInfo
+ */
+ void operator ()(const std::vector<ImageFeatures> &features, std::vector<MatchesInfo> &pairwise_matches,
+ const cv::UMat &mask = cv::UMat());
+
+ /** @return True, if it's possible to use the same matcher instance in parallel, false otherwise
+ */
+ bool isThreadSafe() const { return is_thread_safe_; }
+
+ /** @brief Frees unused memory allocated before if there is any.
+ */
+ virtual void collectGarbage() {}
+
+protected:
+ FeaturesMatcher(bool is_thread_safe = false) : is_thread_safe_(is_thread_safe) {}
+
+ /** @brief This method must implement matching logic in order to make the wrappers
+ detail::FeaturesMatcher::operator()_ work.
+
+ @param features1 first image features
+ @param features2 second image features
+ @param matches_info found matches
+ */
+ virtual void match(const ImageFeatures &features1, const ImageFeatures &features2,
+ MatchesInfo& matches_info) = 0;
+
+ bool is_thread_safe_;
+};
+
+/** @brief Features matcher which finds two best matches for each feature and leaves the best one only if the
+ratio between descriptor distances is greater than the threshold match_conf
+
+@sa detail::FeaturesMatcher
+ */
+class CV_EXPORTS BestOf2NearestMatcher : public FeaturesMatcher
+{
+public:
+ /** @brief Constructs a "best of 2 nearest" matcher.
+
+ @param try_use_gpu Should try to use GPU or not
+ @param match_conf Match distances ration threshold
+ @param num_matches_thresh1 Minimum number of matches required for the 2D projective transform
+ estimation used in the inliers classification step
+ @param num_matches_thresh2 Minimum number of matches required for the 2D projective transform
+ re-estimation on inliers
+ */
+ BestOf2NearestMatcher(bool try_use_gpu = false, float match_conf = 0.3f, int num_matches_thresh1 = 6,
+ int num_matches_thresh2 = 6);
+
+ void collectGarbage();
+
+protected:
+ void match(const ImageFeatures &features1, const ImageFeatures &features2, MatchesInfo &matches_info);
+
+ int num_matches_thresh1_;
+ int num_matches_thresh2_;
+ Ptr<FeaturesMatcher> impl_;
+};
+
+class CV_EXPORTS BestOf2NearestRangeMatcher : public BestOf2NearestMatcher
+{
+public:
+ BestOf2NearestRangeMatcher(int range_width = 5, bool try_use_gpu = false, float match_conf = 0.3f,
+ int num_matches_thresh1 = 6, int num_matches_thresh2 = 6);
+
+ void operator ()(const std::vector<ImageFeatures> &features, std::vector<MatchesInfo> &pairwise_matches,
+ const cv::UMat &mask = cv::UMat());
+
+
+protected:
+ int range_width_;
+};
+
+/** @brief Features matcher similar to cv::detail::BestOf2NearestMatcher which
+finds two best matches for each feature and leaves the best one only if the
+ratio between descriptor distances is greater than the threshold match_conf.
+
+Unlike cv::detail::BestOf2NearestMatcher this matcher uses affine
+transformation (affine trasformation estimate will be placed in matches_info).
+
+@sa cv::detail::FeaturesMatcher cv::detail::BestOf2NearestMatcher
+ */
+class CV_EXPORTS AffineBestOf2NearestMatcher : public BestOf2NearestMatcher
+{
+public:
+ /** @brief Constructs a "best of 2 nearest" matcher that expects affine trasformation
+ between images
+
+ @param full_affine whether to use full affine transformation with 6 degress of freedom or reduced
+ transformation with 4 degrees of freedom using only rotation, translation and uniform scaling
+ @param try_use_gpu Should try to use GPU or not
+ @param match_conf Match distances ration threshold
+ @param num_matches_thresh1 Minimum number of matches required for the 2D affine transform
+ estimation used in the inliers classification step
+
+ @sa cv::estimateAffine2D cv::estimateAffinePartial2D
+ */
+ AffineBestOf2NearestMatcher(bool full_affine = false, bool try_use_gpu = false,
+ float match_conf = 0.3f, int num_matches_thresh1 = 6) :
+ BestOf2NearestMatcher(try_use_gpu, match_conf, num_matches_thresh1, num_matches_thresh1),
+ full_affine_(full_affine) {}
+
+protected:
+ void match(const ImageFeatures &features1, const ImageFeatures &features2, MatchesInfo &matches_info);
+
+ bool full_affine_;
+};
+
+//! @} stitching_match
+
+} // namespace detail
+} // namespace cv
+
+#endif // OPENCV_STITCHING_MATCHERS_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/stitching/detail/motion_estimators.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,357 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_STITCHING_MOTION_ESTIMATORS_HPP
+#define OPENCV_STITCHING_MOTION_ESTIMATORS_HPP
+
+#include "opencv2/core.hpp"
+#include "matchers.hpp"
+#include "util.hpp"
+#include "camera.hpp"
+
+namespace cv {
+namespace detail {
+
+//! @addtogroup stitching_rotation
+//! @{
+
+/** @brief Rotation estimator base class.
+
+It takes features of all images, pairwise matches between all images and estimates rotations of all
+cameras.
+
+@note The coordinate system origin is implementation-dependent, but you can always normalize the
+rotations in respect to the first camera, for instance. :
+ */
+class CV_EXPORTS Estimator
+{
+public:
+ virtual ~Estimator() {}
+
+ /** @brief Estimates camera parameters.
+
+ @param features Features of images
+ @param pairwise_matches Pairwise matches of images
+ @param cameras Estimated camera parameters
+ @return True in case of success, false otherwise
+ */
+ bool operator ()(const std::vector<ImageFeatures> &features,
+ const std::vector<MatchesInfo> &pairwise_matches,
+ std::vector<CameraParams> &cameras)
+ { return estimate(features, pairwise_matches, cameras); }
+
+protected:
+ /** @brief This method must implement camera parameters estimation logic in order to make the wrapper
+ detail::Estimator::operator()_ work.
+
+ @param features Features of images
+ @param pairwise_matches Pairwise matches of images
+ @param cameras Estimated camera parameters
+ @return True in case of success, false otherwise
+ */
+ virtual bool estimate(const std::vector<ImageFeatures> &features,
+ const std::vector<MatchesInfo> &pairwise_matches,
+ std::vector<CameraParams> &cameras) = 0;
+};
+
+/** @brief Homography based rotation estimator.
+ */
+class CV_EXPORTS HomographyBasedEstimator : public Estimator
+{
+public:
+ HomographyBasedEstimator(bool is_focals_estimated = false)
+ : is_focals_estimated_(is_focals_estimated) {}
+
+private:
+ virtual bool estimate(const std::vector<ImageFeatures> &features,
+ const std::vector<MatchesInfo> &pairwise_matches,
+ std::vector<CameraParams> &cameras);
+
+ bool is_focals_estimated_;
+};
+
+/** @brief Affine transformation based estimator.
+
+This estimator uses pairwise tranformations estimated by matcher to estimate
+final transformation for each camera.
+
+@sa cv::detail::HomographyBasedEstimator
+ */
+class CV_EXPORTS AffineBasedEstimator : public Estimator
+{
+private:
+ virtual bool estimate(const std::vector<ImageFeatures> &features,
+ const std::vector<MatchesInfo> &pairwise_matches,
+ std::vector<CameraParams> &cameras);
+};
+
+/** @brief Base class for all camera parameters refinement methods.
+ */
+class CV_EXPORTS BundleAdjusterBase : public Estimator
+{
+public:
+ const Mat refinementMask() const { return refinement_mask_.clone(); }
+ void setRefinementMask(const Mat &mask)
+ {
+ CV_Assert(mask.type() == CV_8U && mask.size() == Size(3, 3));
+ refinement_mask_ = mask.clone();
+ }
+
+ double confThresh() const { return conf_thresh_; }
+ void setConfThresh(double conf_thresh) { conf_thresh_ = conf_thresh; }
+
+ TermCriteria termCriteria() { return term_criteria_; }
+ void setTermCriteria(const TermCriteria& term_criteria) { term_criteria_ = term_criteria; }
+
+protected:
+ /** @brief Construct a bundle adjuster base instance.
+
+ @param num_params_per_cam Number of parameters per camera
+ @param num_errs_per_measurement Number of error terms (components) per match
+ */
+ BundleAdjusterBase(int num_params_per_cam, int num_errs_per_measurement)
+ : num_params_per_cam_(num_params_per_cam),
+ num_errs_per_measurement_(num_errs_per_measurement)
+ {
+ setRefinementMask(Mat::ones(3, 3, CV_8U));
+ setConfThresh(1.);
+ setTermCriteria(TermCriteria(TermCriteria::EPS + TermCriteria::COUNT, 1000, DBL_EPSILON));
+ }
+
+ // Runs bundle adjustment
+ virtual bool estimate(const std::vector<ImageFeatures> &features,
+ const std::vector<MatchesInfo> &pairwise_matches,
+ std::vector<CameraParams> &cameras);
+
+ /** @brief Sets initial camera parameter to refine.
+
+ @param cameras Camera parameters
+ */
+ virtual void setUpInitialCameraParams(const std::vector<CameraParams> &cameras) = 0;
+ /** @brief Gets the refined camera parameters.
+
+ @param cameras Refined camera parameters
+ */
+ virtual void obtainRefinedCameraParams(std::vector<CameraParams> &cameras) const = 0;
+ /** @brief Calculates error vector.
+
+ @param err Error column-vector of length total_num_matches \* num_errs_per_measurement
+ */
+ virtual void calcError(Mat &err) = 0;
+ /** @brief Calculates the cost function jacobian.
+
+ @param jac Jacobian matrix of dimensions
+ (total_num_matches \* num_errs_per_measurement) x (num_images \* num_params_per_cam)
+ */
+ virtual void calcJacobian(Mat &jac) = 0;
+
+ // 3x3 8U mask, where 0 means don't refine respective parameter, != 0 means refine
+ Mat refinement_mask_;
+
+ int num_images_;
+ int total_num_matches_;
+
+ int num_params_per_cam_;
+ int num_errs_per_measurement_;
+
+ const ImageFeatures *features_;
+ const MatchesInfo *pairwise_matches_;
+
+ // Threshold to filter out poorly matched image pairs
+ double conf_thresh_;
+
+ //Levenberg–Marquardt algorithm termination criteria
+ TermCriteria term_criteria_;
+
+ // Camera parameters matrix (CV_64F)
+ Mat cam_params_;
+
+ // Connected images pairs
+ std::vector<std::pair<int,int> > edges_;
+};
+
+
+/** @brief Stub bundle adjuster that does nothing.
+ */
+class CV_EXPORTS NoBundleAdjuster : public BundleAdjusterBase
+{
+public:
+ NoBundleAdjuster() : BundleAdjusterBase(0, 0) {}
+
+private:
+ bool estimate(const std::vector<ImageFeatures> &, const std::vector<MatchesInfo> &,
+ std::vector<CameraParams> &)
+ {
+ return true;
+ }
+ void setUpInitialCameraParams(const std::vector<CameraParams> &) {}
+ void obtainRefinedCameraParams(std::vector<CameraParams> &) const {}
+ void calcError(Mat &) {}
+ void calcJacobian(Mat &) {}
+};
+
+
+/** @brief Implementation of the camera parameters refinement algorithm which minimizes sum of the reprojection
+error squares
+
+It can estimate focal length, aspect ratio, principal point.
+You can affect only on them via the refinement mask.
+ */
+class CV_EXPORTS BundleAdjusterReproj : public BundleAdjusterBase
+{
+public:
+ BundleAdjusterReproj() : BundleAdjusterBase(7, 2) {}
+
+private:
+ void setUpInitialCameraParams(const std::vector<CameraParams> &cameras);
+ void obtainRefinedCameraParams(std::vector<CameraParams> &cameras) const;
+ void calcError(Mat &err);
+ void calcJacobian(Mat &jac);
+
+ Mat err1_, err2_;
+};
+
+
+/** @brief Implementation of the camera parameters refinement algorithm which minimizes sum of the distances
+between the rays passing through the camera center and a feature. :
+
+It can estimate focal length. It ignores the refinement mask for now.
+ */
+class CV_EXPORTS BundleAdjusterRay : public BundleAdjusterBase
+{
+public:
+ BundleAdjusterRay() : BundleAdjusterBase(4, 3) {}
+
+private:
+ void setUpInitialCameraParams(const std::vector<CameraParams> &cameras);
+ void obtainRefinedCameraParams(std::vector<CameraParams> &cameras) const;
+ void calcError(Mat &err);
+ void calcJacobian(Mat &jac);
+
+ Mat err1_, err2_;
+};
+
+
+/** @brief Bundle adjuster that expects affine transformation
+represented in homogeneous coordinates in R for each camera param. Implements
+camera parameters refinement algorithm which minimizes sum of the reprojection
+error squares
+
+It estimates all transformation parameters. Refinement mask is ignored.
+
+@sa AffineBasedEstimator AffineBestOf2NearestMatcher BundleAdjusterAffinePartial
+ */
+class CV_EXPORTS BundleAdjusterAffine : public BundleAdjusterBase
+{
+public:
+ BundleAdjusterAffine() : BundleAdjusterBase(6, 2) {}
+
+private:
+ void setUpInitialCameraParams(const std::vector<CameraParams> &cameras);
+ void obtainRefinedCameraParams(std::vector<CameraParams> &cameras) const;
+ void calcError(Mat &err);
+ void calcJacobian(Mat &jac);
+
+ Mat err1_, err2_;
+};
+
+
+/** @brief Bundle adjuster that expects affine transformation with 4 DOF
+represented in homogeneous coordinates in R for each camera param. Implements
+camera parameters refinement algorithm which minimizes sum of the reprojection
+error squares
+
+It estimates all transformation parameters. Refinement mask is ignored.
+
+@sa AffineBasedEstimator AffineBestOf2NearestMatcher BundleAdjusterAffine
+ */
+class CV_EXPORTS BundleAdjusterAffinePartial : public BundleAdjusterBase
+{
+public:
+ BundleAdjusterAffinePartial() : BundleAdjusterBase(4, 2) {}
+
+private:
+ void setUpInitialCameraParams(const std::vector<CameraParams> &cameras);
+ void obtainRefinedCameraParams(std::vector<CameraParams> &cameras) const;
+ void calcError(Mat &err);
+ void calcJacobian(Mat &jac);
+
+ Mat err1_, err2_;
+};
+
+
+enum WaveCorrectKind
+{
+ WAVE_CORRECT_HORIZ,
+ WAVE_CORRECT_VERT
+};
+
+/** @brief Tries to make panorama more horizontal (or vertical).
+
+@param rmats Camera rotation matrices.
+@param kind Correction kind, see detail::WaveCorrectKind.
+ */
+void CV_EXPORTS waveCorrect(std::vector<Mat> &rmats, WaveCorrectKind kind);
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Auxiliary functions
+
+// Returns matches graph representation in DOT language
+String CV_EXPORTS matchesGraphAsString(std::vector<String> &pathes, std::vector<MatchesInfo> &pairwise_matches,
+ float conf_threshold);
+
+std::vector<int> CV_EXPORTS leaveBiggestComponent(
+ std::vector<ImageFeatures> &features,
+ std::vector<MatchesInfo> &pairwise_matches,
+ float conf_threshold);
+
+void CV_EXPORTS findMaxSpanningTree(
+ int num_images, const std::vector<MatchesInfo> &pairwise_matches,
+ Graph &span_tree, std::vector<int> ¢ers);
+
+//! @} stitching_rotation
+
+} // namespace detail
+} // namespace cv
+
+#endif // OPENCV_STITCHING_MOTION_ESTIMATORS_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/stitching/detail/seam_finders.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,285 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_STITCHING_SEAM_FINDERS_HPP
+#define OPENCV_STITCHING_SEAM_FINDERS_HPP
+
+#include <set>
+#include "opencv2/core.hpp"
+#include "opencv2/opencv_modules.hpp"
+
+namespace cv {
+namespace detail {
+
+//! @addtogroup stitching_seam
+//! @{
+
+/** @brief Base class for a seam estimator.
+ */
+class CV_EXPORTS SeamFinder
+{
+public:
+ virtual ~SeamFinder() {}
+ /** @brief Estimates seams.
+
+ @param src Source images
+ @param corners Source image top-left corners
+ @param masks Source image masks to update
+ */
+ virtual void find(const std::vector<UMat> &src, const std::vector<Point> &corners,
+ std::vector<UMat> &masks) = 0;
+};
+
+/** @brief Stub seam estimator which does nothing.
+ */
+class CV_EXPORTS NoSeamFinder : public SeamFinder
+{
+public:
+ void find(const std::vector<UMat>&, const std::vector<Point>&, std::vector<UMat>&) {}
+};
+
+/** @brief Base class for all pairwise seam estimators.
+ */
+class CV_EXPORTS PairwiseSeamFinder : public SeamFinder
+{
+public:
+ virtual void find(const std::vector<UMat> &src, const std::vector<Point> &corners,
+ std::vector<UMat> &masks);
+
+protected:
+ void run();
+ /** @brief Resolves masks intersection of two specified images in the given ROI.
+
+ @param first First image index
+ @param second Second image index
+ @param roi Region of interest
+ */
+ virtual void findInPair(size_t first, size_t second, Rect roi) = 0;
+
+ std::vector<UMat> images_;
+ std::vector<Size> sizes_;
+ std::vector<Point> corners_;
+ std::vector<UMat> masks_;
+};
+
+/** @brief Voronoi diagram-based seam estimator.
+ */
+class CV_EXPORTS VoronoiSeamFinder : public PairwiseSeamFinder
+{
+public:
+ virtual void find(const std::vector<UMat> &src, const std::vector<Point> &corners,
+ std::vector<UMat> &masks);
+ virtual void find(const std::vector<Size> &size, const std::vector<Point> &corners,
+ std::vector<UMat> &masks);
+private:
+ void findInPair(size_t first, size_t second, Rect roi);
+};
+
+
+class CV_EXPORTS DpSeamFinder : public SeamFinder
+{
+public:
+ enum CostFunction { COLOR, COLOR_GRAD };
+
+ DpSeamFinder(CostFunction costFunc = COLOR);
+
+ CostFunction costFunction() const { return costFunc_; }
+ void setCostFunction(CostFunction val) { costFunc_ = val; }
+
+ virtual void find(const std::vector<UMat> &src, const std::vector<Point> &corners,
+ std::vector<UMat> &masks);
+
+private:
+ enum ComponentState
+ {
+ FIRST = 1, SECOND = 2, INTERS = 4,
+ INTERS_FIRST = INTERS | FIRST,
+ INTERS_SECOND = INTERS | SECOND
+ };
+
+ class ImagePairLess
+ {
+ public:
+ ImagePairLess(const std::vector<Mat> &images, const std::vector<Point> &corners)
+ : src_(&images[0]), corners_(&corners[0]) {}
+
+ bool operator() (const std::pair<size_t, size_t> &l, const std::pair<size_t, size_t> &r) const
+ {
+ Point c1 = corners_[l.first] + Point(src_[l.first].cols / 2, src_[l.first].rows / 2);
+ Point c2 = corners_[l.second] + Point(src_[l.second].cols / 2, src_[l.second].rows / 2);
+ int d1 = (c1 - c2).dot(c1 - c2);
+
+ c1 = corners_[r.first] + Point(src_[r.first].cols / 2, src_[r.first].rows / 2);
+ c2 = corners_[r.second] + Point(src_[r.second].cols / 2, src_[r.second].rows / 2);
+ int d2 = (c1 - c2).dot(c1 - c2);
+
+ return d1 < d2;
+ }
+
+ private:
+ const Mat *src_;
+ const Point *corners_;
+ };
+
+ class ClosePoints
+ {
+ public:
+ ClosePoints(int minDist) : minDist_(minDist) {}
+
+ bool operator() (const Point &p1, const Point &p2) const
+ {
+ int dist2 = (p1.x-p2.x) * (p1.x-p2.x) + (p1.y-p2.y) * (p1.y-p2.y);
+ return dist2 < minDist_ * minDist_;
+ }
+
+ private:
+ int minDist_;
+ };
+
+ void process(
+ const Mat &image1, const Mat &image2, Point tl1, Point tl2, Mat &mask1, Mat &mask2);
+
+ void findComponents();
+
+ void findEdges();
+
+ void resolveConflicts(
+ const Mat &image1, const Mat &image2, Point tl1, Point tl2, Mat &mask1, Mat &mask2);
+
+ void computeGradients(const Mat &image1, const Mat &image2);
+
+ bool hasOnlyOneNeighbor(int comp);
+
+ bool closeToContour(int y, int x, const Mat_<uchar> &contourMask);
+
+ bool getSeamTips(int comp1, int comp2, Point &p1, Point &p2);
+
+ void computeCosts(
+ const Mat &image1, const Mat &image2, Point tl1, Point tl2,
+ int comp, Mat_<float> &costV, Mat_<float> &costH);
+
+ bool estimateSeam(
+ const Mat &image1, const Mat &image2, Point tl1, Point tl2, int comp,
+ Point p1, Point p2, std::vector<Point> &seam, bool &isHorizontal);
+
+ void updateLabelsUsingSeam(
+ int comp1, int comp2, const std::vector<Point> &seam, bool isHorizontalSeam);
+
+ CostFunction costFunc_;
+
+ // processing images pair data
+ Point unionTl_, unionBr_;
+ Size unionSize_;
+ Mat_<uchar> mask1_, mask2_;
+ Mat_<uchar> contour1mask_, contour2mask_;
+ Mat_<float> gradx1_, grady1_;
+ Mat_<float> gradx2_, grady2_;
+
+ // components data
+ int ncomps_;
+ Mat_<int> labels_;
+ std::vector<ComponentState> states_;
+ std::vector<Point> tls_, brs_;
+ std::vector<std::vector<Point> > contours_;
+ std::set<std::pair<int, int> > edges_;
+};
+
+/** @brief Base class for all minimum graph-cut-based seam estimators.
+ */
+class CV_EXPORTS GraphCutSeamFinderBase
+{
+public:
+ enum CostType { COST_COLOR, COST_COLOR_GRAD };
+};
+
+/** @brief Minimum graph cut-based seam estimator. See details in @cite V03 .
+ */
+class CV_EXPORTS GraphCutSeamFinder : public GraphCutSeamFinderBase, public SeamFinder
+{
+public:
+ GraphCutSeamFinder(int cost_type = COST_COLOR_GRAD, float terminal_cost = 10000.f,
+ float bad_region_penalty = 1000.f);
+
+ ~GraphCutSeamFinder();
+
+ void find(const std::vector<UMat> &src, const std::vector<Point> &corners,
+ std::vector<UMat> &masks);
+
+private:
+ // To avoid GCGraph dependency
+ class Impl;
+ Ptr<PairwiseSeamFinder> impl_;
+};
+
+
+#ifdef HAVE_OPENCV_CUDALEGACY
+class CV_EXPORTS GraphCutSeamFinderGpu : public GraphCutSeamFinderBase, public PairwiseSeamFinder
+{
+public:
+ GraphCutSeamFinderGpu(int cost_type = COST_COLOR_GRAD, float terminal_cost = 10000.f,
+ float bad_region_penalty = 1000.f)
+ : cost_type_(cost_type), terminal_cost_(terminal_cost),
+ bad_region_penalty_(bad_region_penalty) {}
+
+ void find(const std::vector<cv::UMat> &src, const std::vector<cv::Point> &corners,
+ std::vector<cv::UMat> &masks);
+ void findInPair(size_t first, size_t second, Rect roi);
+
+private:
+ void setGraphWeightsColor(const cv::Mat &img1, const cv::Mat &img2, const cv::Mat &mask1, const cv::Mat &mask2,
+ cv::Mat &terminals, cv::Mat &leftT, cv::Mat &rightT, cv::Mat &top, cv::Mat &bottom);
+ void setGraphWeightsColorGrad(const cv::Mat &img1, const cv::Mat &img2, const cv::Mat &dx1, const cv::Mat &dx2,
+ const cv::Mat &dy1, const cv::Mat &dy2, const cv::Mat &mask1, const cv::Mat &mask2,
+ cv::Mat &terminals, cv::Mat &leftT, cv::Mat &rightT, cv::Mat &top, cv::Mat &bottom);
+ std::vector<Mat> dx_, dy_;
+ int cost_type_;
+ float terminal_cost_;
+ float bad_region_penalty_;
+};
+#endif
+
+//! @}
+
+} // namespace detail
+} // namespace cv
+
+#endif // OPENCV_STITCHING_SEAM_FINDERS_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/stitching/detail/timelapsers.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,91 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+
+#ifndef OPENCV_STITCHING_TIMELAPSERS_HPP
+#define OPENCV_STITCHING_TIMELAPSERS_HPP
+
+#include "opencv2/core.hpp"
+
+namespace cv {
+namespace detail {
+
+//! @addtogroup stitching
+//! @{
+
+// Base Timelapser class, takes a sequence of images, applies appropriate shift, stores result in dst_.
+
+class CV_EXPORTS Timelapser
+{
+public:
+
+ enum {AS_IS, CROP};
+
+ virtual ~Timelapser() {}
+
+ static Ptr<Timelapser> createDefault(int type);
+
+ virtual void initialize(const std::vector<Point> &corners, const std::vector<Size> &sizes);
+ virtual void process(InputArray img, InputArray mask, Point tl);
+ virtual const UMat& getDst() {return dst_;}
+
+protected:
+
+ virtual bool test_point(Point pt);
+
+ UMat dst_;
+ Rect dst_roi_;
+};
+
+
+class CV_EXPORTS TimelapserCrop : public Timelapser
+{
+public:
+ virtual void initialize(const std::vector<Point> &corners, const std::vector<Size> &sizes);
+};
+
+//! @}
+
+} // namespace detail
+} // namespace cv
+
+#endif // OPENCV_STITCHING_TIMELAPSERS_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/stitching/detail/util.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,121 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_STITCHING_UTIL_HPP
+#define OPENCV_STITCHING_UTIL_HPP
+
+#include <list>
+#include "opencv2/core.hpp"
+
+namespace cv {
+namespace detail {
+
+//! @addtogroup stitching
+//! @{
+
+class CV_EXPORTS DisjointSets
+{
+public:
+ DisjointSets(int elem_count = 0) { createOneElemSets(elem_count); }
+
+ void createOneElemSets(int elem_count);
+ int findSetByElem(int elem);
+ int mergeSets(int set1, int set2);
+
+ std::vector<int> parent;
+ std::vector<int> size;
+
+private:
+ std::vector<int> rank_;
+};
+
+
+struct CV_EXPORTS GraphEdge
+{
+ GraphEdge(int from, int to, float weight);
+ bool operator <(const GraphEdge& other) const { return weight < other.weight; }
+ bool operator >(const GraphEdge& other) const { return weight > other.weight; }
+
+ int from, to;
+ float weight;
+};
+
+inline GraphEdge::GraphEdge(int _from, int _to, float _weight) : from(_from), to(_to), weight(_weight) {}
+
+
+class CV_EXPORTS Graph
+{
+public:
+ Graph(int num_vertices = 0) { create(num_vertices); }
+ void create(int num_vertices) { edges_.assign(num_vertices, std::list<GraphEdge>()); }
+ int numVertices() const { return static_cast<int>(edges_.size()); }
+ void addEdge(int from, int to, float weight);
+ template <typename B> B forEach(B body) const;
+ template <typename B> B walkBreadthFirst(int from, B body) const;
+
+private:
+ std::vector< std::list<GraphEdge> > edges_;
+};
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Auxiliary functions
+
+CV_EXPORTS bool overlapRoi(Point tl1, Point tl2, Size sz1, Size sz2, Rect &roi);
+CV_EXPORTS Rect resultRoi(const std::vector<Point> &corners, const std::vector<UMat> &images);
+CV_EXPORTS Rect resultRoi(const std::vector<Point> &corners, const std::vector<Size> &sizes);
+CV_EXPORTS Rect resultRoiIntersection(const std::vector<Point> &corners, const std::vector<Size> &sizes);
+CV_EXPORTS Point resultTl(const std::vector<Point> &corners);
+
+// Returns random 'count' element subset of the {0,1,...,size-1} set
+CV_EXPORTS void selectRandomSubset(int count, int size, std::vector<int> &subset);
+
+CV_EXPORTS int& stitchingLogLevel();
+
+//! @}
+
+} // namespace detail
+} // namespace cv
+
+#include "util_inl.hpp"
+
+#endif // OPENCV_STITCHING_UTIL_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/stitching/detail/util_inl.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,131 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_STITCHING_UTIL_INL_HPP
+#define OPENCV_STITCHING_UTIL_INL_HPP
+
+#include <queue>
+#include "opencv2/core.hpp"
+#include "util.hpp" // Make your IDE see declarations
+
+//! @cond IGNORED
+
+namespace cv {
+namespace detail {
+
+template <typename B>
+B Graph::forEach(B body) const
+{
+ for (int i = 0; i < numVertices(); ++i)
+ {
+ std::list<GraphEdge>::const_iterator edge = edges_[i].begin();
+ for (; edge != edges_[i].end(); ++edge)
+ body(*edge);
+ }
+ return body;
+}
+
+
+template <typename B>
+B Graph::walkBreadthFirst(int from, B body) const
+{
+ std::vector<bool> was(numVertices(), false);
+ std::queue<int> vertices;
+
+ was[from] = true;
+ vertices.push(from);
+
+ while (!vertices.empty())
+ {
+ int vertex = vertices.front();
+ vertices.pop();
+
+ std::list<GraphEdge>::const_iterator edge = edges_[vertex].begin();
+ for (; edge != edges_[vertex].end(); ++edge)
+ {
+ if (!was[edge->to])
+ {
+ body(*edge);
+ was[edge->to] = true;
+ vertices.push(edge->to);
+ }
+ }
+ }
+
+ return body;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Some auxiliary math functions
+
+static inline
+float normL2(const Point3f& a)
+{
+ return a.x * a.x + a.y * a.y + a.z * a.z;
+}
+
+
+static inline
+float normL2(const Point3f& a, const Point3f& b)
+{
+ return normL2(a - b);
+}
+
+
+static inline
+double normL2sq(const Mat &r)
+{
+ return r.dot(r);
+}
+
+
+static inline int sqr(int x) { return x * x; }
+static inline float sqr(float x) { return x * x; }
+static inline double sqr(double x) { return x * x; }
+
+} // namespace detail
+} // namespace cv
+
+//! @endcond
+
+#endif // OPENCV_STITCHING_UTIL_INL_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/stitching/detail/warpers.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,616 @@
+ /*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_STITCHING_WARPERS_HPP
+#define OPENCV_STITCHING_WARPERS_HPP
+
+#include "opencv2/core.hpp"
+#include "opencv2/core/cuda.hpp"
+#include "opencv2/imgproc.hpp"
+#include "opencv2/opencv_modules.hpp"
+
+namespace cv {
+namespace detail {
+
+//! @addtogroup stitching_warp
+//! @{
+
+/** @brief Rotation-only model image warper interface.
+ */
+class CV_EXPORTS RotationWarper
+{
+public:
+ virtual ~RotationWarper() {}
+
+ /** @brief Projects the image point.
+
+ @param pt Source point
+ @param K Camera intrinsic parameters
+ @param R Camera rotation matrix
+ @return Projected point
+ */
+ virtual Point2f warpPoint(const Point2f &pt, InputArray K, InputArray R) = 0;
+
+ /** @brief Builds the projection maps according to the given camera data.
+
+ @param src_size Source image size
+ @param K Camera intrinsic parameters
+ @param R Camera rotation matrix
+ @param xmap Projection map for the x axis
+ @param ymap Projection map for the y axis
+ @return Projected image minimum bounding box
+ */
+ virtual Rect buildMaps(Size src_size, InputArray K, InputArray R, OutputArray xmap, OutputArray ymap) = 0;
+
+ /** @brief Projects the image.
+
+ @param src Source image
+ @param K Camera intrinsic parameters
+ @param R Camera rotation matrix
+ @param interp_mode Interpolation mode
+ @param border_mode Border extrapolation mode
+ @param dst Projected image
+ @return Project image top-left corner
+ */
+ virtual Point warp(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode,
+ OutputArray dst) = 0;
+
+ /** @brief Projects the image backward.
+
+ @param src Projected image
+ @param K Camera intrinsic parameters
+ @param R Camera rotation matrix
+ @param interp_mode Interpolation mode
+ @param border_mode Border extrapolation mode
+ @param dst_size Backward-projected image size
+ @param dst Backward-projected image
+ */
+ virtual void warpBackward(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode,
+ Size dst_size, OutputArray dst) = 0;
+
+ /**
+ @param src_size Source image bounding box
+ @param K Camera intrinsic parameters
+ @param R Camera rotation matrix
+ @return Projected image minimum bounding box
+ */
+ virtual Rect warpRoi(Size src_size, InputArray K, InputArray R) = 0;
+
+ virtual float getScale() const { return 1.f; }
+ virtual void setScale(float) {}
+};
+
+/** @brief Base class for warping logic implementation.
+ */
+struct CV_EXPORTS ProjectorBase
+{
+ void setCameraParams(InputArray K = Mat::eye(3, 3, CV_32F),
+ InputArray R = Mat::eye(3, 3, CV_32F),
+ InputArray T = Mat::zeros(3, 1, CV_32F));
+
+ float scale;
+ float k[9];
+ float rinv[9];
+ float r_kinv[9];
+ float k_rinv[9];
+ float t[3];
+};
+
+/** @brief Base class for rotation-based warper using a detail::ProjectorBase_ derived class.
+ */
+template <class P>
+class CV_EXPORTS RotationWarperBase : public RotationWarper
+{
+public:
+ Point2f warpPoint(const Point2f &pt, InputArray K, InputArray R);
+
+ Rect buildMaps(Size src_size, InputArray K, InputArray R, OutputArray xmap, OutputArray ymap);
+
+ Point warp(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode,
+ OutputArray dst);
+
+ void warpBackward(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode,
+ Size dst_size, OutputArray dst);
+
+ Rect warpRoi(Size src_size, InputArray K, InputArray R);
+
+ float getScale() const { return projector_.scale; }
+ void setScale(float val) { projector_.scale = val; }
+
+protected:
+
+ // Detects ROI of the destination image. It's correct for any projection.
+ virtual void detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br);
+
+ // Detects ROI of the destination image by walking over image border.
+ // Correctness for any projection isn't guaranteed.
+ void detectResultRoiByBorder(Size src_size, Point &dst_tl, Point &dst_br);
+
+ P projector_;
+};
+
+
+struct CV_EXPORTS PlaneProjector : ProjectorBase
+{
+ void mapForward(float x, float y, float &u, float &v);
+ void mapBackward(float u, float v, float &x, float &y);
+};
+
+/** @brief Warper that maps an image onto the z = 1 plane.
+ */
+class CV_EXPORTS PlaneWarper : public RotationWarperBase<PlaneProjector>
+{
+public:
+ /** @brief Construct an instance of the plane warper class.
+
+ @param scale Projected image scale multiplier
+ */
+ PlaneWarper(float scale = 1.f) { projector_.scale = scale; }
+
+ Point2f warpPoint(const Point2f &pt, InputArray K, InputArray R);
+ Point2f warpPoint(const Point2f &pt, InputArray K, InputArray R, InputArray T);
+
+ virtual Rect buildMaps(Size src_size, InputArray K, InputArray R, InputArray T, OutputArray xmap, OutputArray ymap);
+ Rect buildMaps(Size src_size, InputArray K, InputArray R, OutputArray xmap, OutputArray ymap);
+
+ Point warp(InputArray src, InputArray K, InputArray R,
+ int interp_mode, int border_mode, OutputArray dst);
+ virtual Point warp(InputArray src, InputArray K, InputArray R, InputArray T, int interp_mode, int border_mode,
+ OutputArray dst);
+
+ Rect warpRoi(Size src_size, InputArray K, InputArray R);
+ Rect warpRoi(Size src_size, InputArray K, InputArray R, InputArray T);
+
+protected:
+ void detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br);
+};
+
+
+/** @brief Affine warper that uses rotations and translations
+
+ Uses affine transformation in homogeneous coordinates to represent both rotation and
+ translation in camera rotation matrix.
+ */
+class CV_EXPORTS AffineWarper : public PlaneWarper
+{
+public:
+ /** @brief Construct an instance of the affine warper class.
+
+ @param scale Projected image scale multiplier
+ */
+ AffineWarper(float scale = 1.f) : PlaneWarper(scale) {}
+
+ Point2f warpPoint(const Point2f &pt, InputArray K, InputArray R);
+ Rect buildMaps(Size src_size, InputArray K, InputArray R, OutputArray xmap, OutputArray ymap);
+ Point warp(InputArray src, InputArray K, InputArray R,
+ int interp_mode, int border_mode, OutputArray dst);
+ Rect warpRoi(Size src_size, InputArray K, InputArray R);
+
+protected:
+ /** @brief Extracts rotation and translation matrices from matrix H representing
+ affine transformation in homogeneous coordinates
+ */
+ void getRTfromHomogeneous(InputArray H, Mat &R, Mat &T);
+};
+
+
+struct CV_EXPORTS SphericalProjector : ProjectorBase
+{
+ void mapForward(float x, float y, float &u, float &v);
+ void mapBackward(float u, float v, float &x, float &y);
+};
+
+
+/** @brief Warper that maps an image onto the unit sphere located at the origin.
+
+ Projects image onto unit sphere with origin at (0, 0, 0) and radius scale, measured in pixels.
+ A 360° panorama would therefore have a resulting width of 2 * scale * PI pixels.
+ Poles are located at (0, -1, 0) and (0, 1, 0) points.
+*/
+class CV_EXPORTS SphericalWarper : public RotationWarperBase<SphericalProjector>
+{
+public:
+ /** @brief Construct an instance of the spherical warper class.
+
+ @param scale Radius of the projected sphere, in pixels. An image spanning the
+ whole sphere will have a width of 2 * scale * PI pixels.
+ */
+ SphericalWarper(float scale) { projector_.scale = scale; }
+
+ Rect buildMaps(Size src_size, InputArray K, InputArray R, OutputArray xmap, OutputArray ymap);
+ Point warp(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode, OutputArray dst);
+protected:
+ void detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br);
+};
+
+
+struct CV_EXPORTS CylindricalProjector : ProjectorBase
+{
+ void mapForward(float x, float y, float &u, float &v);
+ void mapBackward(float u, float v, float &x, float &y);
+};
+
+
+/** @brief Warper that maps an image onto the x\*x + z\*z = 1 cylinder.
+ */
+class CV_EXPORTS CylindricalWarper : public RotationWarperBase<CylindricalProjector>
+{
+public:
+ /** @brief Construct an instance of the cylindrical warper class.
+
+ @param scale Projected image scale multiplier
+ */
+ CylindricalWarper(float scale) { projector_.scale = scale; }
+
+ Rect buildMaps(Size src_size, InputArray K, InputArray R, OutputArray xmap, OutputArray ymap);
+ Point warp(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode, OutputArray dst);
+protected:
+ void detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br)
+ {
+ RotationWarperBase<CylindricalProjector>::detectResultRoiByBorder(src_size, dst_tl, dst_br);
+ }
+};
+
+
+struct CV_EXPORTS FisheyeProjector : ProjectorBase
+{
+ void mapForward(float x, float y, float &u, float &v);
+ void mapBackward(float u, float v, float &x, float &y);
+};
+
+
+class CV_EXPORTS FisheyeWarper : public RotationWarperBase<FisheyeProjector>
+{
+public:
+ FisheyeWarper(float scale) { projector_.scale = scale; }
+};
+
+
+struct CV_EXPORTS StereographicProjector : ProjectorBase
+{
+ void mapForward(float x, float y, float &u, float &v);
+ void mapBackward(float u, float v, float &x, float &y);
+};
+
+
+class CV_EXPORTS StereographicWarper : public RotationWarperBase<StereographicProjector>
+{
+public:
+ StereographicWarper(float scale) { projector_.scale = scale; }
+};
+
+
+struct CV_EXPORTS CompressedRectilinearProjector : ProjectorBase
+{
+ float a, b;
+
+ void mapForward(float x, float y, float &u, float &v);
+ void mapBackward(float u, float v, float &x, float &y);
+};
+
+
+class CV_EXPORTS CompressedRectilinearWarper : public RotationWarperBase<CompressedRectilinearProjector>
+{
+public:
+ CompressedRectilinearWarper(float scale, float A = 1, float B = 1)
+ {
+ projector_.a = A;
+ projector_.b = B;
+ projector_.scale = scale;
+ }
+};
+
+
+struct CV_EXPORTS CompressedRectilinearPortraitProjector : ProjectorBase
+{
+ float a, b;
+
+ void mapForward(float x, float y, float &u, float &v);
+ void mapBackward(float u, float v, float &x, float &y);
+};
+
+
+class CV_EXPORTS CompressedRectilinearPortraitWarper : public RotationWarperBase<CompressedRectilinearPortraitProjector>
+{
+public:
+ CompressedRectilinearPortraitWarper(float scale, float A = 1, float B = 1)
+ {
+ projector_.a = A;
+ projector_.b = B;
+ projector_.scale = scale;
+ }
+};
+
+
+struct CV_EXPORTS PaniniProjector : ProjectorBase
+{
+ float a, b;
+
+ void mapForward(float x, float y, float &u, float &v);
+ void mapBackward(float u, float v, float &x, float &y);
+};
+
+
+class CV_EXPORTS PaniniWarper : public RotationWarperBase<PaniniProjector>
+{
+public:
+ PaniniWarper(float scale, float A = 1, float B = 1)
+ {
+ projector_.a = A;
+ projector_.b = B;
+ projector_.scale = scale;
+ }
+};
+
+
+struct CV_EXPORTS PaniniPortraitProjector : ProjectorBase
+{
+ float a, b;
+
+ void mapForward(float x, float y, float &u, float &v);
+ void mapBackward(float u, float v, float &x, float &y);
+};
+
+
+class CV_EXPORTS PaniniPortraitWarper : public RotationWarperBase<PaniniPortraitProjector>
+{
+public:
+ PaniniPortraitWarper(float scale, float A = 1, float B = 1)
+ {
+ projector_.a = A;
+ projector_.b = B;
+ projector_.scale = scale;
+ }
+
+};
+
+
+struct CV_EXPORTS MercatorProjector : ProjectorBase
+{
+ void mapForward(float x, float y, float &u, float &v);
+ void mapBackward(float u, float v, float &x, float &y);
+};
+
+
+class CV_EXPORTS MercatorWarper : public RotationWarperBase<MercatorProjector>
+{
+public:
+ MercatorWarper(float scale) { projector_.scale = scale; }
+};
+
+
+struct CV_EXPORTS TransverseMercatorProjector : ProjectorBase
+{
+ void mapForward(float x, float y, float &u, float &v);
+ void mapBackward(float u, float v, float &x, float &y);
+};
+
+
+class CV_EXPORTS TransverseMercatorWarper : public RotationWarperBase<TransverseMercatorProjector>
+{
+public:
+ TransverseMercatorWarper(float scale) { projector_.scale = scale; }
+};
+
+
+class CV_EXPORTS PlaneWarperGpu : public PlaneWarper
+{
+public:
+ PlaneWarperGpu(float scale = 1.f) : PlaneWarper(scale) {}
+
+ Rect buildMaps(Size src_size, InputArray K, InputArray R, OutputArray xmap, OutputArray ymap)
+ {
+ Rect result = buildMaps(src_size, K, R, d_xmap_, d_ymap_);
+ d_xmap_.download(xmap);
+ d_ymap_.download(ymap);
+ return result;
+ }
+
+ Rect buildMaps(Size src_size, InputArray K, InputArray R, InputArray T, OutputArray xmap, OutputArray ymap)
+ {
+ Rect result = buildMaps(src_size, K, R, T, d_xmap_, d_ymap_);
+ d_xmap_.download(xmap);
+ d_ymap_.download(ymap);
+ return result;
+ }
+
+ Point warp(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode,
+ OutputArray dst)
+ {
+ d_src_.upload(src);
+ Point result = warp(d_src_, K, R, interp_mode, border_mode, d_dst_);
+ d_dst_.download(dst);
+ return result;
+ }
+
+ Point warp(InputArray src, InputArray K, InputArray R, InputArray T, int interp_mode, int border_mode,
+ OutputArray dst)
+ {
+ d_src_.upload(src);
+ Point result = warp(d_src_, K, R, T, interp_mode, border_mode, d_dst_);
+ d_dst_.download(dst);
+ return result;
+ }
+
+ Rect buildMaps(Size src_size, InputArray K, InputArray R, cuda::GpuMat & xmap, cuda::GpuMat & ymap);
+
+ Rect buildMaps(Size src_size, InputArray K, InputArray R, InputArray T, cuda::GpuMat & xmap, cuda::GpuMat & ymap);
+
+ Point warp(const cuda::GpuMat & src, InputArray K, InputArray R, int interp_mode, int border_mode,
+ cuda::GpuMat & dst);
+
+ Point warp(const cuda::GpuMat & src, InputArray K, InputArray R, InputArray T, int interp_mode, int border_mode,
+ cuda::GpuMat & dst);
+
+private:
+ cuda::GpuMat d_xmap_, d_ymap_, d_src_, d_dst_;
+};
+
+
+class CV_EXPORTS SphericalWarperGpu : public SphericalWarper
+{
+public:
+ SphericalWarperGpu(float scale) : SphericalWarper(scale) {}
+
+ Rect buildMaps(Size src_size, InputArray K, InputArray R, OutputArray xmap, OutputArray ymap)
+ {
+ Rect result = buildMaps(src_size, K, R, d_xmap_, d_ymap_);
+ d_xmap_.download(xmap);
+ d_ymap_.download(ymap);
+ return result;
+ }
+
+ Point warp(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode,
+ OutputArray dst)
+ {
+ d_src_.upload(src);
+ Point result = warp(d_src_, K, R, interp_mode, border_mode, d_dst_);
+ d_dst_.download(dst);
+ return result;
+ }
+
+ Rect buildMaps(Size src_size, InputArray K, InputArray R, cuda::GpuMat & xmap, cuda::GpuMat & ymap);
+
+ Point warp(const cuda::GpuMat & src, InputArray K, InputArray R, int interp_mode, int border_mode,
+ cuda::GpuMat & dst);
+
+private:
+ cuda::GpuMat d_xmap_, d_ymap_, d_src_, d_dst_;
+};
+
+
+class CV_EXPORTS CylindricalWarperGpu : public CylindricalWarper
+{
+public:
+ CylindricalWarperGpu(float scale) : CylindricalWarper(scale) {}
+
+ Rect buildMaps(Size src_size, InputArray K, InputArray R, OutputArray xmap, OutputArray ymap)
+ {
+ Rect result = buildMaps(src_size, K, R, d_xmap_, d_ymap_);
+ d_xmap_.download(xmap);
+ d_ymap_.download(ymap);
+ return result;
+ }
+
+ Point warp(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode,
+ OutputArray dst)
+ {
+ d_src_.upload(src);
+ Point result = warp(d_src_, K, R, interp_mode, border_mode, d_dst_);
+ d_dst_.download(dst);
+ return result;
+ }
+
+ Rect buildMaps(Size src_size, InputArray K, InputArray R, cuda::GpuMat & xmap, cuda::GpuMat & ymap);
+
+ Point warp(const cuda::GpuMat & src, InputArray K, InputArray R, int interp_mode, int border_mode,
+ cuda::GpuMat & dst);
+
+private:
+ cuda::GpuMat d_xmap_, d_ymap_, d_src_, d_dst_;
+};
+
+
+struct SphericalPortraitProjector : ProjectorBase
+{
+ void mapForward(float x, float y, float &u, float &v);
+ void mapBackward(float u, float v, float &x, float &y);
+};
+
+
+// Projects image onto unit sphere with origin at (0, 0, 0).
+// Poles are located NOT at (0, -1, 0) and (0, 1, 0) points, BUT at (1, 0, 0) and (-1, 0, 0) points.
+class CV_EXPORTS SphericalPortraitWarper : public RotationWarperBase<SphericalPortraitProjector>
+{
+public:
+ SphericalPortraitWarper(float scale) { projector_.scale = scale; }
+
+protected:
+ void detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br);
+};
+
+struct CylindricalPortraitProjector : ProjectorBase
+{
+ void mapForward(float x, float y, float &u, float &v);
+ void mapBackward(float u, float v, float &x, float &y);
+};
+
+
+class CV_EXPORTS CylindricalPortraitWarper : public RotationWarperBase<CylindricalPortraitProjector>
+{
+public:
+ CylindricalPortraitWarper(float scale) { projector_.scale = scale; }
+
+protected:
+ void detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br)
+ {
+ RotationWarperBase<CylindricalPortraitProjector>::detectResultRoiByBorder(src_size, dst_tl, dst_br);
+ }
+};
+
+struct PlanePortraitProjector : ProjectorBase
+{
+ void mapForward(float x, float y, float &u, float &v);
+ void mapBackward(float u, float v, float &x, float &y);
+};
+
+
+class CV_EXPORTS PlanePortraitWarper : public RotationWarperBase<PlanePortraitProjector>
+{
+public:
+ PlanePortraitWarper(float scale) { projector_.scale = scale; }
+
+protected:
+ void detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br)
+ {
+ RotationWarperBase<PlanePortraitProjector>::detectResultRoiByBorder(src_size, dst_tl, dst_br);
+ }
+};
+
+//! @} stitching_warp
+
+} // namespace detail
+} // namespace cv
+
+#include "warpers_inl.hpp"
+
+#endif // OPENCV_STITCHING_WARPERS_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/stitching/detail/warpers_inl.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,774 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_STITCHING_WARPERS_INL_HPP
+#define OPENCV_STITCHING_WARPERS_INL_HPP
+
+#include "opencv2/core.hpp"
+#include "warpers.hpp" // Make your IDE see declarations
+#include <limits>
+
+//! @cond IGNORED
+
+namespace cv {
+namespace detail {
+
+template <class P>
+Point2f RotationWarperBase<P>::warpPoint(const Point2f &pt, InputArray K, InputArray R)
+{
+ projector_.setCameraParams(K, R);
+ Point2f uv;
+ projector_.mapForward(pt.x, pt.y, uv.x, uv.y);
+ return uv;
+}
+
+
+template <class P>
+Rect RotationWarperBase<P>::buildMaps(Size src_size, InputArray K, InputArray R, OutputArray _xmap, OutputArray _ymap)
+{
+ projector_.setCameraParams(K, R);
+
+ Point dst_tl, dst_br;
+ detectResultRoi(src_size, dst_tl, dst_br);
+
+ _xmap.create(dst_br.y - dst_tl.y + 1, dst_br.x - dst_tl.x + 1, CV_32F);
+ _ymap.create(dst_br.y - dst_tl.y + 1, dst_br.x - dst_tl.x + 1, CV_32F);
+
+ Mat xmap = _xmap.getMat(), ymap = _ymap.getMat();
+
+ float x, y;
+ for (int v = dst_tl.y; v <= dst_br.y; ++v)
+ {
+ for (int u = dst_tl.x; u <= dst_br.x; ++u)
+ {
+ projector_.mapBackward(static_cast<float>(u), static_cast<float>(v), x, y);
+ xmap.at<float>(v - dst_tl.y, u - dst_tl.x) = x;
+ ymap.at<float>(v - dst_tl.y, u - dst_tl.x) = y;
+ }
+ }
+
+ return Rect(dst_tl, dst_br);
+}
+
+
+template <class P>
+Point RotationWarperBase<P>::warp(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode,
+ OutputArray dst)
+{
+ UMat xmap, ymap;
+ Rect dst_roi = buildMaps(src.size(), K, R, xmap, ymap);
+
+ dst.create(dst_roi.height + 1, dst_roi.width + 1, src.type());
+ remap(src, dst, xmap, ymap, interp_mode, border_mode);
+
+ return dst_roi.tl();
+}
+
+
+template <class P>
+void RotationWarperBase<P>::warpBackward(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode,
+ Size dst_size, OutputArray dst)
+{
+ projector_.setCameraParams(K, R);
+
+ Point src_tl, src_br;
+ detectResultRoi(dst_size, src_tl, src_br);
+
+ Size size = src.size();
+ CV_Assert(src_br.x - src_tl.x + 1 == size.width && src_br.y - src_tl.y + 1 == size.height);
+
+ Mat xmap(dst_size, CV_32F);
+ Mat ymap(dst_size, CV_32F);
+
+ float u, v;
+ for (int y = 0; y < dst_size.height; ++y)
+ {
+ for (int x = 0; x < dst_size.width; ++x)
+ {
+ projector_.mapForward(static_cast<float>(x), static_cast<float>(y), u, v);
+ xmap.at<float>(y, x) = u - src_tl.x;
+ ymap.at<float>(y, x) = v - src_tl.y;
+ }
+ }
+
+ dst.create(dst_size, src.type());
+ remap(src, dst, xmap, ymap, interp_mode, border_mode);
+}
+
+
+template <class P>
+Rect RotationWarperBase<P>::warpRoi(Size src_size, InputArray K, InputArray R)
+{
+ projector_.setCameraParams(K, R);
+
+ Point dst_tl, dst_br;
+ detectResultRoi(src_size, dst_tl, dst_br);
+
+ return Rect(dst_tl, Point(dst_br.x + 1, dst_br.y + 1));
+}
+
+
+template <class P>
+void RotationWarperBase<P>::detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br)
+{
+ float tl_uf = (std::numeric_limits<float>::max)();
+ float tl_vf = (std::numeric_limits<float>::max)();
+ float br_uf = -(std::numeric_limits<float>::max)();
+ float br_vf = -(std::numeric_limits<float>::max)();
+
+ float u, v;
+ for (int y = 0; y < src_size.height; ++y)
+ {
+ for (int x = 0; x < src_size.width; ++x)
+ {
+ projector_.mapForward(static_cast<float>(x), static_cast<float>(y), u, v);
+ tl_uf = (std::min)(tl_uf, u); tl_vf = (std::min)(tl_vf, v);
+ br_uf = (std::max)(br_uf, u); br_vf = (std::max)(br_vf, v);
+ }
+ }
+
+ dst_tl.x = static_cast<int>(tl_uf);
+ dst_tl.y = static_cast<int>(tl_vf);
+ dst_br.x = static_cast<int>(br_uf);
+ dst_br.y = static_cast<int>(br_vf);
+}
+
+
+template <class P>
+void RotationWarperBase<P>::detectResultRoiByBorder(Size src_size, Point &dst_tl, Point &dst_br)
+{
+ float tl_uf = (std::numeric_limits<float>::max)();
+ float tl_vf = (std::numeric_limits<float>::max)();
+ float br_uf = -(std::numeric_limits<float>::max)();
+ float br_vf = -(std::numeric_limits<float>::max)();
+
+ float u, v;
+ for (float x = 0; x < src_size.width; ++x)
+ {
+ projector_.mapForward(static_cast<float>(x), 0, u, v);
+ tl_uf = (std::min)(tl_uf, u); tl_vf = (std::min)(tl_vf, v);
+ br_uf = (std::max)(br_uf, u); br_vf = (std::max)(br_vf, v);
+
+ projector_.mapForward(static_cast<float>(x), static_cast<float>(src_size.height - 1), u, v);
+ tl_uf = (std::min)(tl_uf, u); tl_vf = (std::min)(tl_vf, v);
+ br_uf = (std::max)(br_uf, u); br_vf = (std::max)(br_vf, v);
+ }
+ for (int y = 0; y < src_size.height; ++y)
+ {
+ projector_.mapForward(0, static_cast<float>(y), u, v);
+ tl_uf = (std::min)(tl_uf, u); tl_vf = (std::min)(tl_vf, v);
+ br_uf = (std::max)(br_uf, u); br_vf = (std::max)(br_vf, v);
+
+ projector_.mapForward(static_cast<float>(src_size.width - 1), static_cast<float>(y), u, v);
+ tl_uf = (std::min)(tl_uf, u); tl_vf = (std::min)(tl_vf, v);
+ br_uf = (std::max)(br_uf, u); br_vf = (std::max)(br_vf, v);
+ }
+
+ dst_tl.x = static_cast<int>(tl_uf);
+ dst_tl.y = static_cast<int>(tl_vf);
+ dst_br.x = static_cast<int>(br_uf);
+ dst_br.y = static_cast<int>(br_vf);
+}
+
+
+inline
+void PlaneProjector::mapForward(float x, float y, float &u, float &v)
+{
+ float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
+ float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
+ float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
+
+ x_ = t[0] + x_ / z_ * (1 - t[2]);
+ y_ = t[1] + y_ / z_ * (1 - t[2]);
+
+ u = scale * x_;
+ v = scale * y_;
+}
+
+
+inline
+void PlaneProjector::mapBackward(float u, float v, float &x, float &y)
+{
+ u = u / scale - t[0];
+ v = v / scale - t[1];
+
+ float z;
+ x = k_rinv[0] * u + k_rinv[1] * v + k_rinv[2] * (1 - t[2]);
+ y = k_rinv[3] * u + k_rinv[4] * v + k_rinv[5] * (1 - t[2]);
+ z = k_rinv[6] * u + k_rinv[7] * v + k_rinv[8] * (1 - t[2]);
+
+ x /= z;
+ y /= z;
+}
+
+
+inline
+void SphericalProjector::mapForward(float x, float y, float &u, float &v)
+{
+ float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
+ float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
+ float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
+
+ u = scale * atan2f(x_, z_);
+ float w = y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_);
+ v = scale * (static_cast<float>(CV_PI) - acosf(w == w ? w : 0));
+}
+
+
+inline
+void SphericalProjector::mapBackward(float u, float v, float &x, float &y)
+{
+ u /= scale;
+ v /= scale;
+
+ float sinv = sinf(static_cast<float>(CV_PI) - v);
+ float x_ = sinv * sinf(u);
+ float y_ = cosf(static_cast<float>(CV_PI) - v);
+ float z_ = sinv * cosf(u);
+
+ float z;
+ x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
+ y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
+ z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
+
+ if (z > 0) { x /= z; y /= z; }
+ else x = y = -1;
+}
+
+
+inline
+void CylindricalProjector::mapForward(float x, float y, float &u, float &v)
+{
+ float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
+ float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
+ float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
+
+ u = scale * atan2f(x_, z_);
+ v = scale * y_ / sqrtf(x_ * x_ + z_ * z_);
+}
+
+
+inline
+void CylindricalProjector::mapBackward(float u, float v, float &x, float &y)
+{
+ u /= scale;
+ v /= scale;
+
+ float x_ = sinf(u);
+ float y_ = v;
+ float z_ = cosf(u);
+
+ float z;
+ x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
+ y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
+ z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
+
+ if (z > 0) { x /= z; y /= z; }
+ else x = y = -1;
+}
+
+inline
+void FisheyeProjector::mapForward(float x, float y, float &u, float &v)
+{
+ float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
+ float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
+ float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
+
+ float u_ = atan2f(x_, z_);
+ float v_ = (float)CV_PI - acosf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_));
+
+ u = scale * v_ * cosf(u_);
+ v = scale * v_ * sinf(u_);
+}
+
+inline
+void FisheyeProjector::mapBackward(float u, float v, float &x, float &y)
+{
+ u /= scale;
+ v /= scale;
+
+ float u_ = atan2f(v, u);
+ float v_ = sqrtf(u*u + v*v);
+
+ float sinv = sinf((float)CV_PI - v_);
+ float x_ = sinv * sinf(u_);
+ float y_ = cosf((float)CV_PI - v_);
+ float z_ = sinv * cosf(u_);
+
+ float z;
+ x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
+ y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
+ z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
+
+ if (z > 0) { x /= z; y /= z; }
+ else x = y = -1;
+}
+
+inline
+void StereographicProjector::mapForward(float x, float y, float &u, float &v)
+{
+ float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
+ float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
+ float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
+
+ float u_ = atan2f(x_, z_);
+ float v_ = (float)CV_PI - acosf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_));
+
+ float r = sinf(v_) / (1 - cosf(v_));
+
+ u = scale * r * cos(u_);
+ v = scale * r * sin(u_);
+}
+
+inline
+void StereographicProjector::mapBackward(float u, float v, float &x, float &y)
+{
+ u /= scale;
+ v /= scale;
+
+ float u_ = atan2f(v, u);
+ float r = sqrtf(u*u + v*v);
+ float v_ = 2 * atanf(1.f / r);
+
+ float sinv = sinf((float)CV_PI - v_);
+ float x_ = sinv * sinf(u_);
+ float y_ = cosf((float)CV_PI - v_);
+ float z_ = sinv * cosf(u_);
+
+ float z;
+ x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
+ y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
+ z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
+
+ if (z > 0) { x /= z; y /= z; }
+ else x = y = -1;
+}
+
+inline
+void CompressedRectilinearProjector::mapForward(float x, float y, float &u, float &v)
+{
+ float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
+ float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
+ float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
+
+ float u_ = atan2f(x_, z_);
+ float v_ = asinf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_));
+
+ u = scale * a * tanf(u_ / a);
+ v = scale * b * tanf(v_) / cosf(u_);
+}
+
+inline
+void CompressedRectilinearProjector::mapBackward(float u, float v, float &x, float &y)
+{
+ u /= scale;
+ v /= scale;
+
+ float aatg = a * atanf(u / a);
+ float u_ = aatg;
+ float v_ = atanf(v * cosf(aatg) / b);
+
+ float cosv = cosf(v_);
+ float x_ = cosv * sinf(u_);
+ float y_ = sinf(v_);
+ float z_ = cosv * cosf(u_);
+
+ float z;
+ x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
+ y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
+ z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
+
+ if (z > 0) { x /= z; y /= z; }
+ else x = y = -1;
+}
+
+inline
+void CompressedRectilinearPortraitProjector::mapForward(float x, float y, float &u, float &v)
+{
+ float y_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
+ float x_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
+ float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
+
+ float u_ = atan2f(x_, z_);
+ float v_ = asinf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_));
+
+ u = - scale * a * tanf(u_ / a);
+ v = scale * b * tanf(v_) / cosf(u_);
+}
+
+inline
+void CompressedRectilinearPortraitProjector::mapBackward(float u, float v, float &x, float &y)
+{
+ u /= - scale;
+ v /= scale;
+
+ float aatg = a * atanf(u / a);
+ float u_ = aatg;
+ float v_ = atanf(v * cosf( aatg ) / b);
+
+ float cosv = cosf(v_);
+ float y_ = cosv * sinf(u_);
+ float x_ = sinf(v_);
+ float z_ = cosv * cosf(u_);
+
+ float z;
+ x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
+ y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
+ z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
+
+ if (z > 0) { x /= z; y /= z; }
+ else x = y = -1;
+}
+
+inline
+void PaniniProjector::mapForward(float x, float y, float &u, float &v)
+{
+ float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
+ float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
+ float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
+
+ float u_ = atan2f(x_, z_);
+ float v_ = asinf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_));
+
+ float tg = a * tanf(u_ / a);
+ u = scale * tg;
+
+ float sinu = sinf(u_);
+ if ( fabs(sinu) < 1E-7 )
+ v = scale * b * tanf(v_);
+ else
+ v = scale * b * tg * tanf(v_) / sinu;
+}
+
+inline
+void PaniniProjector::mapBackward(float u, float v, float &x, float &y)
+{
+ u /= scale;
+ v /= scale;
+
+ float lamda = a * atanf(u / a);
+ float u_ = lamda;
+
+ float v_;
+ if ( fabs(lamda) > 1E-7)
+ v_ = atanf(v * sinf(lamda) / (b * a * tanf(lamda / a)));
+ else
+ v_ = atanf(v / b);
+
+ float cosv = cosf(v_);
+ float x_ = cosv * sinf(u_);
+ float y_ = sinf(v_);
+ float z_ = cosv * cosf(u_);
+
+ float z;
+ x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
+ y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
+ z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
+
+ if (z > 0) { x /= z; y /= z; }
+ else x = y = -1;
+}
+
+inline
+void PaniniPortraitProjector::mapForward(float x, float y, float &u, float &v)
+{
+ float y_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
+ float x_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
+ float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
+
+ float u_ = atan2f(x_, z_);
+ float v_ = asinf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_));
+
+ float tg = a * tanf(u_ / a);
+ u = - scale * tg;
+
+ float sinu = sinf( u_ );
+ if ( fabs(sinu) < 1E-7 )
+ v = scale * b * tanf(v_);
+ else
+ v = scale * b * tg * tanf(v_) / sinu;
+}
+
+inline
+void PaniniPortraitProjector::mapBackward(float u, float v, float &x, float &y)
+{
+ u /= - scale;
+ v /= scale;
+
+ float lamda = a * atanf(u / a);
+ float u_ = lamda;
+
+ float v_;
+ if ( fabs(lamda) > 1E-7)
+ v_ = atanf(v * sinf(lamda) / (b * a * tanf(lamda/a)));
+ else
+ v_ = atanf(v / b);
+
+ float cosv = cosf(v_);
+ float y_ = cosv * sinf(u_);
+ float x_ = sinf(v_);
+ float z_ = cosv * cosf(u_);
+
+ float z;
+ x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
+ y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
+ z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
+
+ if (z > 0) { x /= z; y /= z; }
+ else x = y = -1;
+}
+
+inline
+void MercatorProjector::mapForward(float x, float y, float &u, float &v)
+{
+ float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
+ float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
+ float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
+
+ float u_ = atan2f(x_, z_);
+ float v_ = asinf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_));
+
+ u = scale * u_;
+ v = scale * logf( tanf( (float)(CV_PI/4) + v_/2 ) );
+}
+
+inline
+void MercatorProjector::mapBackward(float u, float v, float &x, float &y)
+{
+ u /= scale;
+ v /= scale;
+
+ float v_ = atanf( sinhf(v) );
+ float u_ = u;
+
+ float cosv = cosf(v_);
+ float x_ = cosv * sinf(u_);
+ float y_ = sinf(v_);
+ float z_ = cosv * cosf(u_);
+
+ float z;
+ x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
+ y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
+ z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
+
+ if (z > 0) { x /= z; y /= z; }
+ else x = y = -1;
+}
+
+inline
+void TransverseMercatorProjector::mapForward(float x, float y, float &u, float &v)
+{
+ float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
+ float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
+ float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
+
+ float u_ = atan2f(x_, z_);
+ float v_ = asinf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_));
+
+ float B = cosf(v_) * sinf(u_);
+
+ u = scale / 2 * logf( (1+B) / (1-B) );
+ v = scale * atan2f(tanf(v_), cosf(u_));
+}
+
+inline
+void TransverseMercatorProjector::mapBackward(float u, float v, float &x, float &y)
+{
+ u /= scale;
+ v /= scale;
+
+ float v_ = asinf( sinf(v) / coshf(u) );
+ float u_ = atan2f( sinhf(u), cos(v) );
+
+ float cosv = cosf(v_);
+ float x_ = cosv * sinf(u_);
+ float y_ = sinf(v_);
+ float z_ = cosv * cosf(u_);
+
+ float z;
+ x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
+ y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
+ z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
+
+ if (z > 0) { x /= z; y /= z; }
+ else x = y = -1;
+}
+
+inline
+void SphericalPortraitProjector::mapForward(float x, float y, float &u0, float &v0)
+{
+ float x0_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
+ float y0_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
+ float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
+
+ float x_ = y0_;
+ float y_ = x0_;
+ float u, v;
+
+ u = scale * atan2f(x_, z_);
+ v = scale * (static_cast<float>(CV_PI) - acosf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_)));
+
+ u0 = -u;//v;
+ v0 = v;//u;
+}
+
+
+inline
+void SphericalPortraitProjector::mapBackward(float u0, float v0, float &x, float &y)
+{
+ float u, v;
+ u = -u0;//v0;
+ v = v0;//u0;
+
+ u /= scale;
+ v /= scale;
+
+ float sinv = sinf(static_cast<float>(CV_PI) - v);
+ float x0_ = sinv * sinf(u);
+ float y0_ = cosf(static_cast<float>(CV_PI) - v);
+ float z_ = sinv * cosf(u);
+
+ float x_ = y0_;
+ float y_ = x0_;
+
+ float z;
+ x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
+ y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
+ z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
+
+ if (z > 0) { x /= z; y /= z; }
+ else x = y = -1;
+}
+
+inline
+void CylindricalPortraitProjector::mapForward(float x, float y, float &u0, float &v0)
+{
+ float x0_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
+ float y0_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
+ float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
+
+ float x_ = y0_;
+ float y_ = x0_;
+ float u, v;
+
+ u = scale * atan2f(x_, z_);
+ v = scale * y_ / sqrtf(x_ * x_ + z_ * z_);
+
+ u0 = -u;//v;
+ v0 = v;//u;
+}
+
+
+inline
+void CylindricalPortraitProjector::mapBackward(float u0, float v0, float &x, float &y)
+{
+ float u, v;
+ u = -u0;//v0;
+ v = v0;//u0;
+
+ u /= scale;
+ v /= scale;
+
+ float x0_ = sinf(u);
+ float y0_ = v;
+ float z_ = cosf(u);
+
+ float x_ = y0_;
+ float y_ = x0_;
+
+ float z;
+ x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
+ y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
+ z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
+
+ if (z > 0) { x /= z; y /= z; }
+ else x = y = -1;
+}
+
+inline
+void PlanePortraitProjector::mapForward(float x, float y, float &u0, float &v0)
+{
+ float x0_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
+ float y0_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
+ float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
+
+ float x_ = y0_;
+ float y_ = x0_;
+
+ x_ = t[0] + x_ / z_ * (1 - t[2]);
+ y_ = t[1] + y_ / z_ * (1 - t[2]);
+
+ float u,v;
+ u = scale * x_;
+ v = scale * y_;
+
+ u0 = -u;
+ v0 = v;
+}
+
+
+inline
+void PlanePortraitProjector::mapBackward(float u0, float v0, float &x, float &y)
+{
+ float u, v;
+ u = -u0;
+ v = v0;
+
+ u = u / scale - t[0];
+ v = v / scale - t[1];
+
+ float z;
+ x = k_rinv[0] * v + k_rinv[1] * u + k_rinv[2] * (1 - t[2]);
+ y = k_rinv[3] * v + k_rinv[4] * u + k_rinv[5] * (1 - t[2]);
+ z = k_rinv[6] * v + k_rinv[7] * u + k_rinv[8] * (1 - t[2]);
+
+ x /= z;
+ y /= z;
+}
+
+
+} // namespace detail
+} // namespace cv
+
+//! @endcond
+
+#endif // OPENCV_STITCHING_WARPERS_INL_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/stitching/warpers.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,192 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_STITCHING_WARPER_CREATORS_HPP
+#define OPENCV_STITCHING_WARPER_CREATORS_HPP
+
+#include "opencv2/stitching/detail/warpers.hpp"
+
+namespace cv {
+
+//! @addtogroup stitching_warp
+//! @{
+
+/** @brief Image warper factories base class.
+ */
+class WarperCreator
+{
+public:
+ virtual ~WarperCreator() {}
+ virtual Ptr<detail::RotationWarper> create(float scale) const = 0;
+};
+
+/** @brief Plane warper factory class.
+ @sa detail::PlaneWarper
+ */
+class PlaneWarper : public WarperCreator
+{
+public:
+ Ptr<detail::RotationWarper> create(float scale) const { return makePtr<detail::PlaneWarper>(scale); }
+};
+
+/** @brief Affine warper factory class.
+ @sa detail::AffineWarper
+ */
+class AffineWarper : public WarperCreator
+{
+public:
+ Ptr<detail::RotationWarper> create(float scale) const { return makePtr<detail::AffineWarper>(scale); }
+};
+
+/** @brief Cylindrical warper factory class.
+@sa detail::CylindricalWarper
+*/
+class CylindricalWarper: public WarperCreator
+{
+public:
+ Ptr<detail::RotationWarper> create(float scale) const { return makePtr<detail::CylindricalWarper>(scale); }
+};
+
+/** @brief Spherical warper factory class */
+class SphericalWarper: public WarperCreator
+{
+public:
+ Ptr<detail::RotationWarper> create(float scale) const { return makePtr<detail::SphericalWarper>(scale); }
+};
+
+class FisheyeWarper : public WarperCreator
+{
+public:
+ Ptr<detail::RotationWarper> create(float scale) const { return makePtr<detail::FisheyeWarper>(scale); }
+};
+
+class StereographicWarper: public WarperCreator
+{
+public:
+ Ptr<detail::RotationWarper> create(float scale) const { return makePtr<detail::StereographicWarper>(scale); }
+};
+
+class CompressedRectilinearWarper: public WarperCreator
+{
+ float a, b;
+public:
+ CompressedRectilinearWarper(float A = 1, float B = 1)
+ {
+ a = A; b = B;
+ }
+ Ptr<detail::RotationWarper> create(float scale) const { return makePtr<detail::CompressedRectilinearWarper>(scale, a, b); }
+};
+
+class CompressedRectilinearPortraitWarper: public WarperCreator
+{
+ float a, b;
+public:
+ CompressedRectilinearPortraitWarper(float A = 1, float B = 1)
+ {
+ a = A; b = B;
+ }
+ Ptr<detail::RotationWarper> create(float scale) const { return makePtr<detail::CompressedRectilinearPortraitWarper>(scale, a, b); }
+};
+
+class PaniniWarper: public WarperCreator
+{
+ float a, b;
+public:
+ PaniniWarper(float A = 1, float B = 1)
+ {
+ a = A; b = B;
+ }
+ Ptr<detail::RotationWarper> create(float scale) const { return makePtr<detail::PaniniWarper>(scale, a, b); }
+};
+
+class PaniniPortraitWarper: public WarperCreator
+{
+ float a, b;
+public:
+ PaniniPortraitWarper(float A = 1, float B = 1)
+ {
+ a = A; b = B;
+ }
+ Ptr<detail::RotationWarper> create(float scale) const { return makePtr<detail::PaniniPortraitWarper>(scale, a, b); }
+};
+
+class MercatorWarper: public WarperCreator
+{
+public:
+ Ptr<detail::RotationWarper> create(float scale) const { return makePtr<detail::MercatorWarper>(scale); }
+};
+
+class TransverseMercatorWarper: public WarperCreator
+{
+public:
+ Ptr<detail::RotationWarper> create(float scale) const { return makePtr<detail::TransverseMercatorWarper>(scale); }
+};
+
+
+
+#ifdef HAVE_OPENCV_CUDAWARPING
+class PlaneWarperGpu: public WarperCreator
+{
+public:
+ Ptr<detail::RotationWarper> create(float scale) const { return makePtr<detail::PlaneWarperGpu>(scale); }
+};
+
+
+class CylindricalWarperGpu: public WarperCreator
+{
+public:
+ Ptr<detail::RotationWarper> create(float scale) const { return makePtr<detail::CylindricalWarperGpu>(scale); }
+};
+
+
+class SphericalWarperGpu: public WarperCreator
+{
+public:
+ Ptr<detail::RotationWarper> create(float scale) const { return makePtr<detail::SphericalWarperGpu>(scale); }
+};
+#endif
+
+//! @} stitching_warp
+
+} // namespace cv
+
+#endif // OPENCV_STITCHING_WARPER_CREATORS_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/superres.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,207 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_SUPERRES_HPP
+#define OPENCV_SUPERRES_HPP
+
+#include "opencv2/core.hpp"
+#include "opencv2/superres/optical_flow.hpp"
+
+/**
+ @defgroup superres Super Resolution
+
+The Super Resolution module contains a set of functions and classes that can be used to solve the
+problem of resolution enhancement. There are a few methods implemented, most of them are descibed in
+the papers @cite Farsiu03 and @cite Mitzel09 .
+
+ */
+
+namespace cv
+{
+ namespace superres
+ {
+
+//! @addtogroup superres
+//! @{
+
+ class CV_EXPORTS FrameSource
+ {
+ public:
+ virtual ~FrameSource();
+
+ virtual void nextFrame(OutputArray frame) = 0;
+ virtual void reset() = 0;
+ };
+
+ CV_EXPORTS Ptr<FrameSource> createFrameSource_Empty();
+
+ CV_EXPORTS Ptr<FrameSource> createFrameSource_Video(const String& fileName);
+ CV_EXPORTS Ptr<FrameSource> createFrameSource_Video_CUDA(const String& fileName);
+
+ CV_EXPORTS Ptr<FrameSource> createFrameSource_Camera(int deviceId = 0);
+
+ /** @brief Base class for Super Resolution algorithms.
+
+ The class is only used to define the common interface for the whole family of Super Resolution
+ algorithms.
+ */
+ class CV_EXPORTS SuperResolution : public cv::Algorithm, public FrameSource
+ {
+ public:
+ /** @brief Set input frame source for Super Resolution algorithm.
+
+ @param frameSource Input frame source
+ */
+ void setInput(const Ptr<FrameSource>& frameSource);
+
+ /** @brief Process next frame from input and return output result.
+
+ @param frame Output result
+ */
+ void nextFrame(OutputArray frame);
+ void reset();
+
+ /** @brief Clear all inner buffers.
+ */
+ virtual void collectGarbage();
+
+ //! @brief Scale factor
+ /** @see setScale */
+ virtual int getScale() const = 0;
+ /** @copybrief getScale @see getScale */
+ virtual void setScale(int val) = 0;
+
+ //! @brief Iterations count
+ /** @see setIterations */
+ virtual int getIterations() const = 0;
+ /** @copybrief getIterations @see getIterations */
+ virtual void setIterations(int val) = 0;
+
+ //! @brief Asymptotic value of steepest descent method
+ /** @see setTau */
+ virtual double getTau() const = 0;
+ /** @copybrief getTau @see getTau */
+ virtual void setTau(double val) = 0;
+
+ //! @brief Weight parameter to balance data term and smoothness term
+ /** @see setLabmda */
+ virtual double getLabmda() const = 0;
+ /** @copybrief getLabmda @see getLabmda */
+ virtual void setLabmda(double val) = 0;
+
+ //! @brief Parameter of spacial distribution in Bilateral-TV
+ /** @see setAlpha */
+ virtual double getAlpha() const = 0;
+ /** @copybrief getAlpha @see getAlpha */
+ virtual void setAlpha(double val) = 0;
+
+ //! @brief Kernel size of Bilateral-TV filter
+ /** @see setKernelSize */
+ virtual int getKernelSize() const = 0;
+ /** @copybrief getKernelSize @see getKernelSize */
+ virtual void setKernelSize(int val) = 0;
+
+ //! @brief Gaussian blur kernel size
+ /** @see setBlurKernelSize */
+ virtual int getBlurKernelSize() const = 0;
+ /** @copybrief getBlurKernelSize @see getBlurKernelSize */
+ virtual void setBlurKernelSize(int val) = 0;
+
+ //! @brief Gaussian blur sigma
+ /** @see setBlurSigma */
+ virtual double getBlurSigma() const = 0;
+ /** @copybrief getBlurSigma @see getBlurSigma */
+ virtual void setBlurSigma(double val) = 0;
+
+ //! @brief Radius of the temporal search area
+ /** @see setTemporalAreaRadius */
+ virtual int getTemporalAreaRadius() const = 0;
+ /** @copybrief getTemporalAreaRadius @see getTemporalAreaRadius */
+ virtual void setTemporalAreaRadius(int val) = 0;
+
+ //! @brief Dense optical flow algorithm
+ /** @see setOpticalFlow */
+ virtual Ptr<cv::superres::DenseOpticalFlowExt> getOpticalFlow() const = 0;
+ /** @copybrief getOpticalFlow @see getOpticalFlow */
+ virtual void setOpticalFlow(const Ptr<cv::superres::DenseOpticalFlowExt> &val) = 0;
+
+ protected:
+ SuperResolution();
+
+ virtual void initImpl(Ptr<FrameSource>& frameSource) = 0;
+ virtual void processImpl(Ptr<FrameSource>& frameSource, OutputArray output) = 0;
+
+ bool isUmat_;
+
+ private:
+ Ptr<FrameSource> frameSource_;
+ bool firstCall_;
+ };
+
+ /** @brief Create Bilateral TV-L1 Super Resolution.
+
+ This class implements Super Resolution algorithm described in the papers @cite Farsiu03 and
+ @cite Mitzel09 .
+
+ Here are important members of the class that control the algorithm, which you can set after
+ constructing the class instance:
+
+ - **int scale** Scale factor.
+ - **int iterations** Iteration count.
+ - **double tau** Asymptotic value of steepest descent method.
+ - **double lambda** Weight parameter to balance data term and smoothness term.
+ - **double alpha** Parameter of spacial distribution in Bilateral-TV.
+ - **int btvKernelSize** Kernel size of Bilateral-TV filter.
+ - **int blurKernelSize** Gaussian blur kernel size.
+ - **double blurSigma** Gaussian blur sigma.
+ - **int temporalAreaRadius** Radius of the temporal search area.
+ - **Ptr\<DenseOpticalFlowExt\> opticalFlow** Dense optical flow algorithm.
+ */
+ CV_EXPORTS Ptr<SuperResolution> createSuperResolution_BTVL1();
+ CV_EXPORTS Ptr<SuperResolution> createSuperResolution_BTVL1_CUDA();
+
+//! @} superres
+
+ }
+}
+
+#endif // OPENCV_SUPERRES_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/superres/optical_flow.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,203 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_SUPERRES_OPTICAL_FLOW_HPP
+#define OPENCV_SUPERRES_OPTICAL_FLOW_HPP
+
+#include "opencv2/core.hpp"
+
+namespace cv
+{
+ namespace superres
+ {
+
+//! @addtogroup superres
+//! @{
+
+ class CV_EXPORTS DenseOpticalFlowExt : public cv::Algorithm
+ {
+ public:
+ virtual void calc(InputArray frame0, InputArray frame1, OutputArray flow1, OutputArray flow2 = noArray()) = 0;
+ virtual void collectGarbage() = 0;
+ };
+
+
+ class CV_EXPORTS FarnebackOpticalFlow : public virtual DenseOpticalFlowExt
+ {
+ public:
+ /** @see setPyrScale */
+ virtual double getPyrScale() const = 0;
+ /** @copybrief getPyrScale @see getPyrScale */
+ virtual void setPyrScale(double val) = 0;
+ /** @see setLevelsNumber */
+ virtual int getLevelsNumber() const = 0;
+ /** @copybrief getLevelsNumber @see getLevelsNumber */
+ virtual void setLevelsNumber(int val) = 0;
+ /** @see setWindowSize */
+ virtual int getWindowSize() const = 0;
+ /** @copybrief getWindowSize @see getWindowSize */
+ virtual void setWindowSize(int val) = 0;
+ /** @see setIterations */
+ virtual int getIterations() const = 0;
+ /** @copybrief getIterations @see getIterations */
+ virtual void setIterations(int val) = 0;
+ /** @see setPolyN */
+ virtual int getPolyN() const = 0;
+ /** @copybrief getPolyN @see getPolyN */
+ virtual void setPolyN(int val) = 0;
+ /** @see setPolySigma */
+ virtual double getPolySigma() const = 0;
+ /** @copybrief getPolySigma @see getPolySigma */
+ virtual void setPolySigma(double val) = 0;
+ /** @see setFlags */
+ virtual int getFlags() const = 0;
+ /** @copybrief getFlags @see getFlags */
+ virtual void setFlags(int val) = 0;
+ };
+ CV_EXPORTS Ptr<FarnebackOpticalFlow> createOptFlow_Farneback();
+ CV_EXPORTS Ptr<FarnebackOpticalFlow> createOptFlow_Farneback_CUDA();
+
+
+// CV_EXPORTS Ptr<DenseOpticalFlowExt> createOptFlow_Simple();
+
+
+ class CV_EXPORTS DualTVL1OpticalFlow : public virtual DenseOpticalFlowExt
+ {
+ public:
+ /** @see setTau */
+ virtual double getTau() const = 0;
+ /** @copybrief getTau @see getTau */
+ virtual void setTau(double val) = 0;
+ /** @see setLambda */
+ virtual double getLambda() const = 0;
+ /** @copybrief getLambda @see getLambda */
+ virtual void setLambda(double val) = 0;
+ /** @see setTheta */
+ virtual double getTheta() const = 0;
+ /** @copybrief getTheta @see getTheta */
+ virtual void setTheta(double val) = 0;
+ /** @see setScalesNumber */
+ virtual int getScalesNumber() const = 0;
+ /** @copybrief getScalesNumber @see getScalesNumber */
+ virtual void setScalesNumber(int val) = 0;
+ /** @see setWarpingsNumber */
+ virtual int getWarpingsNumber() const = 0;
+ /** @copybrief getWarpingsNumber @see getWarpingsNumber */
+ virtual void setWarpingsNumber(int val) = 0;
+ /** @see setEpsilon */
+ virtual double getEpsilon() const = 0;
+ /** @copybrief getEpsilon @see getEpsilon */
+ virtual void setEpsilon(double val) = 0;
+ /** @see setIterations */
+ virtual int getIterations() const = 0;
+ /** @copybrief getIterations @see getIterations */
+ virtual void setIterations(int val) = 0;
+ /** @see setUseInitialFlow */
+ virtual bool getUseInitialFlow() const = 0;
+ /** @copybrief getUseInitialFlow @see getUseInitialFlow */
+ virtual void setUseInitialFlow(bool val) = 0;
+ };
+ CV_EXPORTS Ptr<DualTVL1OpticalFlow> createOptFlow_DualTVL1();
+ CV_EXPORTS Ptr<DualTVL1OpticalFlow> createOptFlow_DualTVL1_CUDA();
+
+
+ class CV_EXPORTS BroxOpticalFlow : public virtual DenseOpticalFlowExt
+ {
+ public:
+ //! @brief Flow smoothness
+ /** @see setAlpha */
+ virtual double getAlpha() const = 0;
+ /** @copybrief getAlpha @see getAlpha */
+ virtual void setAlpha(double val) = 0;
+ //! @brief Gradient constancy importance
+ /** @see setGamma */
+ virtual double getGamma() const = 0;
+ /** @copybrief getGamma @see getGamma */
+ virtual void setGamma(double val) = 0;
+ //! @brief Pyramid scale factor
+ /** @see setScaleFactor */
+ virtual double getScaleFactor() const = 0;
+ /** @copybrief getScaleFactor @see getScaleFactor */
+ virtual void setScaleFactor(double val) = 0;
+ //! @brief Number of lagged non-linearity iterations (inner loop)
+ /** @see setInnerIterations */
+ virtual int getInnerIterations() const = 0;
+ /** @copybrief getInnerIterations @see getInnerIterations */
+ virtual void setInnerIterations(int val) = 0;
+ //! @brief Number of warping iterations (number of pyramid levels)
+ /** @see setOuterIterations */
+ virtual int getOuterIterations() const = 0;
+ /** @copybrief getOuterIterations @see getOuterIterations */
+ virtual void setOuterIterations(int val) = 0;
+ //! @brief Number of linear system solver iterations
+ /** @see setSolverIterations */
+ virtual int getSolverIterations() const = 0;
+ /** @copybrief getSolverIterations @see getSolverIterations */
+ virtual void setSolverIterations(int val) = 0;
+ };
+ CV_EXPORTS Ptr<BroxOpticalFlow> createOptFlow_Brox_CUDA();
+
+
+ class PyrLKOpticalFlow : public virtual DenseOpticalFlowExt
+ {
+ public:
+ /** @see setWindowSize */
+ virtual int getWindowSize() const = 0;
+ /** @copybrief getWindowSize @see getWindowSize */
+ virtual void setWindowSize(int val) = 0;
+ /** @see setMaxLevel */
+ virtual int getMaxLevel() const = 0;
+ /** @copybrief getMaxLevel @see getMaxLevel */
+ virtual void setMaxLevel(int val) = 0;
+ /** @see setIterations */
+ virtual int getIterations() const = 0;
+ /** @copybrief getIterations @see getIterations */
+ virtual void setIterations(int val) = 0;
+ };
+ CV_EXPORTS Ptr<PyrLKOpticalFlow> createOptFlow_PyrLK_CUDA();
+
+//! @}
+
+ }
+}
+
+#endif // OPENCV_SUPERRES_OPTICAL_FLOW_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/video.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,63 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_VIDEO_HPP
+#define OPENCV_VIDEO_HPP
+
+/**
+ @defgroup video Video Analysis
+ @{
+ @defgroup video_motion Motion Analysis
+ @defgroup video_track Object Tracking
+ @defgroup video_c C API
+ @}
+*/
+
+#include "opencv2/video/tracking.hpp"
+#include "opencv2/video/background_segm.hpp"
+
+#ifndef DISABLE_OPENCV_24_COMPATIBILITY
+#include "opencv2/video/tracking_c.h"
+#endif
+
+#endif //OPENCV_VIDEO_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/video/background_segm.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,306 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_BACKGROUND_SEGM_HPP
+#define OPENCV_BACKGROUND_SEGM_HPP
+
+#include "opencv2/core.hpp"
+
+namespace cv
+{
+
+//! @addtogroup video_motion
+//! @{
+
+/** @brief Base class for background/foreground segmentation. :
+
+The class is only used to define the common interface for the whole family of background/foreground
+segmentation algorithms.
+ */
+class CV_EXPORTS_W BackgroundSubtractor : public Algorithm
+{
+public:
+ /** @brief Computes a foreground mask.
+
+ @param image Next video frame.
+ @param fgmask The output foreground mask as an 8-bit binary image.
+ @param learningRate The value between 0 and 1 that indicates how fast the background model is
+ learnt. Negative parameter value makes the algorithm to use some automatically chosen learning
+ rate. 0 means that the background model is not updated at all, 1 means that the background model
+ is completely reinitialized from the last frame.
+ */
+ CV_WRAP virtual void apply(InputArray image, OutputArray fgmask, double learningRate=-1) = 0;
+
+ /** @brief Computes a background image.
+
+ @param backgroundImage The output background image.
+
+ @note Sometimes the background image can be very blurry, as it contain the average background
+ statistics.
+ */
+ CV_WRAP virtual void getBackgroundImage(OutputArray backgroundImage) const = 0;
+};
+
+
+/** @brief Gaussian Mixture-based Background/Foreground Segmentation Algorithm.
+
+The class implements the Gaussian mixture model background subtraction described in @cite Zivkovic2004
+and @cite Zivkovic2006 .
+ */
+class CV_EXPORTS_W BackgroundSubtractorMOG2 : public BackgroundSubtractor
+{
+public:
+ /** @brief Returns the number of last frames that affect the background model
+ */
+ CV_WRAP virtual int getHistory() const = 0;
+ /** @brief Sets the number of last frames that affect the background model
+ */
+ CV_WRAP virtual void setHistory(int history) = 0;
+
+ /** @brief Returns the number of gaussian components in the background model
+ */
+ CV_WRAP virtual int getNMixtures() const = 0;
+ /** @brief Sets the number of gaussian components in the background model.
+
+ The model needs to be reinitalized to reserve memory.
+ */
+ CV_WRAP virtual void setNMixtures(int nmixtures) = 0;//needs reinitialization!
+
+ /** @brief Returns the "background ratio" parameter of the algorithm
+
+ If a foreground pixel keeps semi-constant value for about backgroundRatio\*history frames, it's
+ considered background and added to the model as a center of a new component. It corresponds to TB
+ parameter in the paper.
+ */
+ CV_WRAP virtual double getBackgroundRatio() const = 0;
+ /** @brief Sets the "background ratio" parameter of the algorithm
+ */
+ CV_WRAP virtual void setBackgroundRatio(double ratio) = 0;
+
+ /** @brief Returns the variance threshold for the pixel-model match
+
+ The main threshold on the squared Mahalanobis distance to decide if the sample is well described by
+ the background model or not. Related to Cthr from the paper.
+ */
+ CV_WRAP virtual double getVarThreshold() const = 0;
+ /** @brief Sets the variance threshold for the pixel-model match
+ */
+ CV_WRAP virtual void setVarThreshold(double varThreshold) = 0;
+
+ /** @brief Returns the variance threshold for the pixel-model match used for new mixture component generation
+
+ Threshold for the squared Mahalanobis distance that helps decide when a sample is close to the
+ existing components (corresponds to Tg in the paper). If a pixel is not close to any component, it
+ is considered foreground or added as a new component. 3 sigma =\> Tg=3\*3=9 is default. A smaller Tg
+ value generates more components. A higher Tg value may result in a small number of components but
+ they can grow too large.
+ */
+ CV_WRAP virtual double getVarThresholdGen() const = 0;
+ /** @brief Sets the variance threshold for the pixel-model match used for new mixture component generation
+ */
+ CV_WRAP virtual void setVarThresholdGen(double varThresholdGen) = 0;
+
+ /** @brief Returns the initial variance of each gaussian component
+ */
+ CV_WRAP virtual double getVarInit() const = 0;
+ /** @brief Sets the initial variance of each gaussian component
+ */
+ CV_WRAP virtual void setVarInit(double varInit) = 0;
+
+ CV_WRAP virtual double getVarMin() const = 0;
+ CV_WRAP virtual void setVarMin(double varMin) = 0;
+
+ CV_WRAP virtual double getVarMax() const = 0;
+ CV_WRAP virtual void setVarMax(double varMax) = 0;
+
+ /** @brief Returns the complexity reduction threshold
+
+ This parameter defines the number of samples needed to accept to prove the component exists. CT=0.05
+ is a default value for all the samples. By setting CT=0 you get an algorithm very similar to the
+ standard Stauffer&Grimson algorithm.
+ */
+ CV_WRAP virtual double getComplexityReductionThreshold() const = 0;
+ /** @brief Sets the complexity reduction threshold
+ */
+ CV_WRAP virtual void setComplexityReductionThreshold(double ct) = 0;
+
+ /** @brief Returns the shadow detection flag
+
+ If true, the algorithm detects shadows and marks them. See createBackgroundSubtractorMOG2 for
+ details.
+ */
+ CV_WRAP virtual bool getDetectShadows() const = 0;
+ /** @brief Enables or disables shadow detection
+ */
+ CV_WRAP virtual void setDetectShadows(bool detectShadows) = 0;
+
+ /** @brief Returns the shadow value
+
+ Shadow value is the value used to mark shadows in the foreground mask. Default value is 127. Value 0
+ in the mask always means background, 255 means foreground.
+ */
+ CV_WRAP virtual int getShadowValue() const = 0;
+ /** @brief Sets the shadow value
+ */
+ CV_WRAP virtual void setShadowValue(int value) = 0;
+
+ /** @brief Returns the shadow threshold
+
+ A shadow is detected if pixel is a darker version of the background. The shadow threshold (Tau in
+ the paper) is a threshold defining how much darker the shadow can be. Tau= 0.5 means that if a pixel
+ is more than twice darker then it is not shadow. See Prati, Mikic, Trivedi and Cucchiarra,
+ *Detecting Moving Shadows...*, IEEE PAMI,2003.
+ */
+ CV_WRAP virtual double getShadowThreshold() const = 0;
+ /** @brief Sets the shadow threshold
+ */
+ CV_WRAP virtual void setShadowThreshold(double threshold) = 0;
+};
+
+/** @brief Creates MOG2 Background Subtractor
+
+@param history Length of the history.
+@param varThreshold Threshold on the squared Mahalanobis distance between the pixel and the model
+to decide whether a pixel is well described by the background model. This parameter does not
+affect the background update.
+@param detectShadows If true, the algorithm will detect shadows and mark them. It decreases the
+speed a bit, so if you do not need this feature, set the parameter to false.
+ */
+CV_EXPORTS_W Ptr<BackgroundSubtractorMOG2>
+ createBackgroundSubtractorMOG2(int history=500, double varThreshold=16,
+ bool detectShadows=true);
+
+/** @brief K-nearest neigbours - based Background/Foreground Segmentation Algorithm.
+
+The class implements the K-nearest neigbours background subtraction described in @cite Zivkovic2006 .
+Very efficient if number of foreground pixels is low.
+ */
+class CV_EXPORTS_W BackgroundSubtractorKNN : public BackgroundSubtractor
+{
+public:
+ /** @brief Returns the number of last frames that affect the background model
+ */
+ CV_WRAP virtual int getHistory() const = 0;
+ /** @brief Sets the number of last frames that affect the background model
+ */
+ CV_WRAP virtual void setHistory(int history) = 0;
+
+ /** @brief Returns the number of data samples in the background model
+ */
+ CV_WRAP virtual int getNSamples() const = 0;
+ /** @brief Sets the number of data samples in the background model.
+
+ The model needs to be reinitalized to reserve memory.
+ */
+ CV_WRAP virtual void setNSamples(int _nN) = 0;//needs reinitialization!
+
+ /** @brief Returns the threshold on the squared distance between the pixel and the sample
+
+ The threshold on the squared distance between the pixel and the sample to decide whether a pixel is
+ close to a data sample.
+ */
+ CV_WRAP virtual double getDist2Threshold() const = 0;
+ /** @brief Sets the threshold on the squared distance
+ */
+ CV_WRAP virtual void setDist2Threshold(double _dist2Threshold) = 0;
+
+ /** @brief Returns the number of neighbours, the k in the kNN.
+
+ K is the number of samples that need to be within dist2Threshold in order to decide that that
+ pixel is matching the kNN background model.
+ */
+ CV_WRAP virtual int getkNNSamples() const = 0;
+ /** @brief Sets the k in the kNN. How many nearest neigbours need to match.
+ */
+ CV_WRAP virtual void setkNNSamples(int _nkNN) = 0;
+
+ /** @brief Returns the shadow detection flag
+
+ If true, the algorithm detects shadows and marks them. See createBackgroundSubtractorKNN for
+ details.
+ */
+ CV_WRAP virtual bool getDetectShadows() const = 0;
+ /** @brief Enables or disables shadow detection
+ */
+ CV_WRAP virtual void setDetectShadows(bool detectShadows) = 0;
+
+ /** @brief Returns the shadow value
+
+ Shadow value is the value used to mark shadows in the foreground mask. Default value is 127. Value 0
+ in the mask always means background, 255 means foreground.
+ */
+ CV_WRAP virtual int getShadowValue() const = 0;
+ /** @brief Sets the shadow value
+ */
+ CV_WRAP virtual void setShadowValue(int value) = 0;
+
+ /** @brief Returns the shadow threshold
+
+ A shadow is detected if pixel is a darker version of the background. The shadow threshold (Tau in
+ the paper) is a threshold defining how much darker the shadow can be. Tau= 0.5 means that if a pixel
+ is more than twice darker then it is not shadow. See Prati, Mikic, Trivedi and Cucchiarra,
+ *Detecting Moving Shadows...*, IEEE PAMI,2003.
+ */
+ CV_WRAP virtual double getShadowThreshold() const = 0;
+ /** @brief Sets the shadow threshold
+ */
+ CV_WRAP virtual void setShadowThreshold(double threshold) = 0;
+};
+
+/** @brief Creates KNN Background Subtractor
+
+@param history Length of the history.
+@param dist2Threshold Threshold on the squared distance between the pixel and the sample to decide
+whether a pixel is close to that sample. This parameter does not affect the background update.
+@param detectShadows If true, the algorithm will detect shadows and mark them. It decreases the
+speed a bit, so if you do not need this feature, set the parameter to false.
+ */
+CV_EXPORTS_W Ptr<BackgroundSubtractorKNN>
+ createBackgroundSubtractorKNN(int history=500, double dist2Threshold=400.0,
+ bool detectShadows=true);
+
+//! @} video_motion
+
+} // cv
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/video/tracking.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,626 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_TRACKING_HPP
+#define OPENCV_TRACKING_HPP
+
+#include "opencv2/core.hpp"
+#include "opencv2/imgproc.hpp"
+
+namespace cv
+{
+
+//! @addtogroup video_track
+//! @{
+
+enum { OPTFLOW_USE_INITIAL_FLOW = 4,
+ OPTFLOW_LK_GET_MIN_EIGENVALS = 8,
+ OPTFLOW_FARNEBACK_GAUSSIAN = 256
+ };
+
+/** @brief Finds an object center, size, and orientation.
+
+@param probImage Back projection of the object histogram. See calcBackProject.
+@param window Initial search window.
+@param criteria Stop criteria for the underlying meanShift.
+returns
+(in old interfaces) Number of iterations CAMSHIFT took to converge
+The function implements the CAMSHIFT object tracking algorithm @cite Bradski98 . First, it finds an
+object center using meanShift and then adjusts the window size and finds the optimal rotation. The
+function returns the rotated rectangle structure that includes the object position, size, and
+orientation. The next position of the search window can be obtained with RotatedRect::boundingRect()
+
+See the OpenCV sample camshiftdemo.c that tracks colored objects.
+
+@note
+- (Python) A sample explaining the camshift tracking algorithm can be found at
+ opencv_source_code/samples/python/camshift.py
+ */
+CV_EXPORTS_W RotatedRect CamShift( InputArray probImage, CV_IN_OUT Rect& window,
+ TermCriteria criteria );
+
+/** @brief Finds an object on a back projection image.
+
+@param probImage Back projection of the object histogram. See calcBackProject for details.
+@param window Initial search window.
+@param criteria Stop criteria for the iterative search algorithm.
+returns
+: Number of iterations CAMSHIFT took to converge.
+The function implements the iterative object search algorithm. It takes the input back projection of
+an object and the initial position. The mass center in window of the back projection image is
+computed and the search window center shifts to the mass center. The procedure is repeated until the
+specified number of iterations criteria.maxCount is done or until the window center shifts by less
+than criteria.epsilon. The algorithm is used inside CamShift and, unlike CamShift , the search
+window size or orientation do not change during the search. You can simply pass the output of
+calcBackProject to this function. But better results can be obtained if you pre-filter the back
+projection and remove the noise. For example, you can do this by retrieving connected components
+with findContours , throwing away contours with small area ( contourArea ), and rendering the
+remaining contours with drawContours.
+
+@note
+- A mean-shift tracking sample can be found at opencv_source_code/samples/cpp/camshiftdemo.cpp
+ */
+CV_EXPORTS_W int meanShift( InputArray probImage, CV_IN_OUT Rect& window, TermCriteria criteria );
+
+/** @brief Constructs the image pyramid which can be passed to calcOpticalFlowPyrLK.
+
+@param img 8-bit input image.
+@param pyramid output pyramid.
+@param winSize window size of optical flow algorithm. Must be not less than winSize argument of
+calcOpticalFlowPyrLK. It is needed to calculate required padding for pyramid levels.
+@param maxLevel 0-based maximal pyramid level number.
+@param withDerivatives set to precompute gradients for the every pyramid level. If pyramid is
+constructed without the gradients then calcOpticalFlowPyrLK will calculate them internally.
+@param pyrBorder the border mode for pyramid layers.
+@param derivBorder the border mode for gradients.
+@param tryReuseInputImage put ROI of input image into the pyramid if possible. You can pass false
+to force data copying.
+@return number of levels in constructed pyramid. Can be less than maxLevel.
+ */
+CV_EXPORTS_W int buildOpticalFlowPyramid( InputArray img, OutputArrayOfArrays pyramid,
+ Size winSize, int maxLevel, bool withDerivatives = true,
+ int pyrBorder = BORDER_REFLECT_101,
+ int derivBorder = BORDER_CONSTANT,
+ bool tryReuseInputImage = true );
+
+/** @brief Calculates an optical flow for a sparse feature set using the iterative Lucas-Kanade method with
+pyramids.
+
+@param prevImg first 8-bit input image or pyramid constructed by buildOpticalFlowPyramid.
+@param nextImg second input image or pyramid of the same size and the same type as prevImg.
+@param prevPts vector of 2D points for which the flow needs to be found; point coordinates must be
+single-precision floating-point numbers.
+@param nextPts output vector of 2D points (with single-precision floating-point coordinates)
+containing the calculated new positions of input features in the second image; when
+OPTFLOW_USE_INITIAL_FLOW flag is passed, the vector must have the same size as in the input.
+@param status output status vector (of unsigned chars); each element of the vector is set to 1 if
+the flow for the corresponding features has been found, otherwise, it is set to 0.
+@param err output vector of errors; each element of the vector is set to an error for the
+corresponding feature, type of the error measure can be set in flags parameter; if the flow wasn't
+found then the error is not defined (use the status parameter to find such cases).
+@param winSize size of the search window at each pyramid level.
+@param maxLevel 0-based maximal pyramid level number; if set to 0, pyramids are not used (single
+level), if set to 1, two levels are used, and so on; if pyramids are passed to input then
+algorithm will use as many levels as pyramids have but no more than maxLevel.
+@param criteria parameter, specifying the termination criteria of the iterative search algorithm
+(after the specified maximum number of iterations criteria.maxCount or when the search window
+moves by less than criteria.epsilon.
+@param flags operation flags:
+ - **OPTFLOW_USE_INITIAL_FLOW** uses initial estimations, stored in nextPts; if the flag is
+ not set, then prevPts is copied to nextPts and is considered the initial estimate.
+ - **OPTFLOW_LK_GET_MIN_EIGENVALS** use minimum eigen values as an error measure (see
+ minEigThreshold description); if the flag is not set, then L1 distance between patches
+ around the original and a moved point, divided by number of pixels in a window, is used as a
+ error measure.
+@param minEigThreshold the algorithm calculates the minimum eigen value of a 2x2 normal matrix of
+optical flow equations (this matrix is called a spatial gradient matrix in @cite Bouguet00), divided
+by number of pixels in a window; if this value is less than minEigThreshold, then a corresponding
+feature is filtered out and its flow is not processed, so it allows to remove bad points and get a
+performance boost.
+
+The function implements a sparse iterative version of the Lucas-Kanade optical flow in pyramids. See
+@cite Bouguet00 . The function is parallelized with the TBB library.
+
+@note
+
+- An example using the Lucas-Kanade optical flow algorithm can be found at
+ opencv_source_code/samples/cpp/lkdemo.cpp
+- (Python) An example using the Lucas-Kanade optical flow algorithm can be found at
+ opencv_source_code/samples/python/lk_track.py
+- (Python) An example using the Lucas-Kanade tracker for homography matching can be found at
+ opencv_source_code/samples/python/lk_homography.py
+ */
+CV_EXPORTS_W void calcOpticalFlowPyrLK( InputArray prevImg, InputArray nextImg,
+ InputArray prevPts, InputOutputArray nextPts,
+ OutputArray status, OutputArray err,
+ Size winSize = Size(21,21), int maxLevel = 3,
+ TermCriteria criteria = TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 30, 0.01),
+ int flags = 0, double minEigThreshold = 1e-4 );
+
+/** @brief Computes a dense optical flow using the Gunnar Farneback's algorithm.
+
+@param prev first 8-bit single-channel input image.
+@param next second input image of the same size and the same type as prev.
+@param flow computed flow image that has the same size as prev and type CV_32FC2.
+@param pyr_scale parameter, specifying the image scale (\<1) to build pyramids for each image;
+pyr_scale=0.5 means a classical pyramid, where each next layer is twice smaller than the previous
+one.
+@param levels number of pyramid layers including the initial image; levels=1 means that no extra
+layers are created and only the original images are used.
+@param winsize averaging window size; larger values increase the algorithm robustness to image
+noise and give more chances for fast motion detection, but yield more blurred motion field.
+@param iterations number of iterations the algorithm does at each pyramid level.
+@param poly_n size of the pixel neighborhood used to find polynomial expansion in each pixel;
+larger values mean that the image will be approximated with smoother surfaces, yielding more
+robust algorithm and more blurred motion field, typically poly_n =5 or 7.
+@param poly_sigma standard deviation of the Gaussian that is used to smooth derivatives used as a
+basis for the polynomial expansion; for poly_n=5, you can set poly_sigma=1.1, for poly_n=7, a
+good value would be poly_sigma=1.5.
+@param flags operation flags that can be a combination of the following:
+ - **OPTFLOW_USE_INITIAL_FLOW** uses the input flow as an initial flow approximation.
+ - **OPTFLOW_FARNEBACK_GAUSSIAN** uses the Gaussian \f$\texttt{winsize}\times\texttt{winsize}\f$
+ filter instead of a box filter of the same size for optical flow estimation; usually, this
+ option gives z more accurate flow than with a box filter, at the cost of lower speed;
+ normally, winsize for a Gaussian window should be set to a larger value to achieve the same
+ level of robustness.
+
+The function finds an optical flow for each prev pixel using the @cite Farneback2003 algorithm so that
+
+\f[\texttt{prev} (y,x) \sim \texttt{next} ( y + \texttt{flow} (y,x)[1], x + \texttt{flow} (y,x)[0])\f]
+
+@note
+
+- An example using the optical flow algorithm described by Gunnar Farneback can be found at
+ opencv_source_code/samples/cpp/fback.cpp
+- (Python) An example using the optical flow algorithm described by Gunnar Farneback can be
+ found at opencv_source_code/samples/python/opt_flow.py
+ */
+CV_EXPORTS_W void calcOpticalFlowFarneback( InputArray prev, InputArray next, InputOutputArray flow,
+ double pyr_scale, int levels, int winsize,
+ int iterations, int poly_n, double poly_sigma,
+ int flags );
+
+/** @brief Computes an optimal affine transformation between two 2D point sets.
+
+@param src First input 2D point set stored in std::vector or Mat, or an image stored in Mat.
+@param dst Second input 2D point set of the same size and the same type as A, or another image.
+@param fullAffine If true, the function finds an optimal affine transformation with no additional
+restrictions (6 degrees of freedom). Otherwise, the class of transformations to choose from is
+limited to combinations of translation, rotation, and uniform scaling (4 degrees of freedom).
+
+The function finds an optimal affine transform *[A|b]* (a 2 x 3 floating-point matrix) that
+approximates best the affine transformation between:
+
+* Two point sets
+* Two raster images. In this case, the function first finds some features in the src image and
+ finds the corresponding features in dst image. After that, the problem is reduced to the first
+ case.
+In case of point sets, the problem is formulated as follows: you need to find a 2x2 matrix *A* and
+2x1 vector *b* so that:
+
+\f[[A^*|b^*] = arg \min _{[A|b]} \sum _i \| \texttt{dst}[i] - A { \texttt{src}[i]}^T - b \| ^2\f]
+where src[i] and dst[i] are the i-th points in src and dst, respectively
+\f$[A|b]\f$ can be either arbitrary (when fullAffine=true ) or have a form of
+\f[\begin{bmatrix} a_{11} & a_{12} & b_1 \\ -a_{12} & a_{11} & b_2 \end{bmatrix}\f]
+when fullAffine=false.
+
+@sa
+estimateAffine2D, estimateAffinePartial2D, getAffineTransform, getPerspectiveTransform, findHomography
+ */
+CV_EXPORTS_W Mat estimateRigidTransform( InputArray src, InputArray dst, bool fullAffine );
+
+
+enum
+{
+ MOTION_TRANSLATION = 0,
+ MOTION_EUCLIDEAN = 1,
+ MOTION_AFFINE = 2,
+ MOTION_HOMOGRAPHY = 3
+};
+
+/** @brief Finds the geometric transform (warp) between two images in terms of the ECC criterion @cite EP08 .
+
+@param templateImage single-channel template image; CV_8U or CV_32F array.
+@param inputImage single-channel input image which should be warped with the final warpMatrix in
+order to provide an image similar to templateImage, same type as temlateImage.
+@param warpMatrix floating-point \f$2\times 3\f$ or \f$3\times 3\f$ mapping matrix (warp).
+@param motionType parameter, specifying the type of motion:
+ - **MOTION_TRANSLATION** sets a translational motion model; warpMatrix is \f$2\times 3\f$ with
+ the first \f$2\times 2\f$ part being the unity matrix and the rest two parameters being
+ estimated.
+ - **MOTION_EUCLIDEAN** sets a Euclidean (rigid) transformation as motion model; three
+ parameters are estimated; warpMatrix is \f$2\times 3\f$.
+ - **MOTION_AFFINE** sets an affine motion model (DEFAULT); six parameters are estimated;
+ warpMatrix is \f$2\times 3\f$.
+ - **MOTION_HOMOGRAPHY** sets a homography as a motion model; eight parameters are
+ estimated;\`warpMatrix\` is \f$3\times 3\f$.
+@param criteria parameter, specifying the termination criteria of the ECC algorithm;
+criteria.epsilon defines the threshold of the increment in the correlation coefficient between two
+iterations (a negative criteria.epsilon makes criteria.maxcount the only termination criterion).
+Default values are shown in the declaration above.
+@param inputMask An optional mask to indicate valid values of inputImage.
+
+The function estimates the optimum transformation (warpMatrix) with respect to ECC criterion
+(@cite EP08), that is
+
+\f[\texttt{warpMatrix} = \texttt{warpMatrix} = \arg\max_{W} \texttt{ECC}(\texttt{templateImage}(x,y),\texttt{inputImage}(x',y'))\f]
+
+where
+
+\f[\begin{bmatrix} x' \\ y' \end{bmatrix} = W \cdot \begin{bmatrix} x \\ y \\ 1 \end{bmatrix}\f]
+
+(the equation holds with homogeneous coordinates for homography). It returns the final enhanced
+correlation coefficient, that is the correlation coefficient between the template image and the
+final warped input image. When a \f$3\times 3\f$ matrix is given with motionType =0, 1 or 2, the third
+row is ignored.
+
+Unlike findHomography and estimateRigidTransform, the function findTransformECC implements an
+area-based alignment that builds on intensity similarities. In essence, the function updates the
+initial transformation that roughly aligns the images. If this information is missing, the identity
+warp (unity matrix) should be given as input. Note that if images undergo strong
+displacements/rotations, an initial transformation that roughly aligns the images is necessary
+(e.g., a simple euclidean/similarity transform that allows for the images showing the same image
+content approximately). Use inverse warping in the second image to take an image close to the first
+one, i.e. use the flag WARP_INVERSE_MAP with warpAffine or warpPerspective. See also the OpenCV
+sample image_alignment.cpp that demonstrates the use of the function. Note that the function throws
+an exception if algorithm does not converges.
+
+@sa
+estimateAffine2D, estimateAffinePartial2D, findHomography
+ */
+CV_EXPORTS_W double findTransformECC( InputArray templateImage, InputArray inputImage,
+ InputOutputArray warpMatrix, int motionType = MOTION_AFFINE,
+ TermCriteria criteria = TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 50, 0.001),
+ InputArray inputMask = noArray());
+
+/** @brief Kalman filter class.
+
+The class implements a standard Kalman filter <http://en.wikipedia.org/wiki/Kalman_filter>,
+@cite Welch95 . However, you can modify transitionMatrix, controlMatrix, and measurementMatrix to get
+an extended Kalman filter functionality. See the OpenCV sample kalman.cpp.
+
+@note
+
+- An example using the standard Kalman filter can be found at
+ opencv_source_code/samples/cpp/kalman.cpp
+ */
+class CV_EXPORTS_W KalmanFilter
+{
+public:
+ /** @brief The constructors.
+
+ @note In C API when CvKalman\* kalmanFilter structure is not needed anymore, it should be released
+ with cvReleaseKalman(&kalmanFilter)
+ */
+ CV_WRAP KalmanFilter();
+ /** @overload
+ @param dynamParams Dimensionality of the state.
+ @param measureParams Dimensionality of the measurement.
+ @param controlParams Dimensionality of the control vector.
+ @param type Type of the created matrices that should be CV_32F or CV_64F.
+ */
+ CV_WRAP KalmanFilter( int dynamParams, int measureParams, int controlParams = 0, int type = CV_32F );
+
+ /** @brief Re-initializes Kalman filter. The previous content is destroyed.
+
+ @param dynamParams Dimensionality of the state.
+ @param measureParams Dimensionality of the measurement.
+ @param controlParams Dimensionality of the control vector.
+ @param type Type of the created matrices that should be CV_32F or CV_64F.
+ */
+ void init( int dynamParams, int measureParams, int controlParams = 0, int type = CV_32F );
+
+ /** @brief Computes a predicted state.
+
+ @param control The optional input control
+ */
+ CV_WRAP const Mat& predict( const Mat& control = Mat() );
+
+ /** @brief Updates the predicted state from the measurement.
+
+ @param measurement The measured system parameters
+ */
+ CV_WRAP const Mat& correct( const Mat& measurement );
+
+ CV_PROP_RW Mat statePre; //!< predicted state (x'(k)): x(k)=A*x(k-1)+B*u(k)
+ CV_PROP_RW Mat statePost; //!< corrected state (x(k)): x(k)=x'(k)+K(k)*(z(k)-H*x'(k))
+ CV_PROP_RW Mat transitionMatrix; //!< state transition matrix (A)
+ CV_PROP_RW Mat controlMatrix; //!< control matrix (B) (not used if there is no control)
+ CV_PROP_RW Mat measurementMatrix; //!< measurement matrix (H)
+ CV_PROP_RW Mat processNoiseCov; //!< process noise covariance matrix (Q)
+ CV_PROP_RW Mat measurementNoiseCov;//!< measurement noise covariance matrix (R)
+ CV_PROP_RW Mat errorCovPre; //!< priori error estimate covariance matrix (P'(k)): P'(k)=A*P(k-1)*At + Q)*/
+ CV_PROP_RW Mat gain; //!< Kalman gain matrix (K(k)): K(k)=P'(k)*Ht*inv(H*P'(k)*Ht+R)
+ CV_PROP_RW Mat errorCovPost; //!< posteriori error estimate covariance matrix (P(k)): P(k)=(I-K(k)*H)*P'(k)
+
+ // temporary matrices
+ Mat temp1;
+ Mat temp2;
+ Mat temp3;
+ Mat temp4;
+ Mat temp5;
+};
+
+
+class CV_EXPORTS_W DenseOpticalFlow : public Algorithm
+{
+public:
+ /** @brief Calculates an optical flow.
+
+ @param I0 first 8-bit single-channel input image.
+ @param I1 second input image of the same size and the same type as prev.
+ @param flow computed flow image that has the same size as prev and type CV_32FC2.
+ */
+ CV_WRAP virtual void calc( InputArray I0, InputArray I1, InputOutputArray flow ) = 0;
+ /** @brief Releases all inner buffers.
+ */
+ CV_WRAP virtual void collectGarbage() = 0;
+};
+
+/** @brief Base interface for sparse optical flow algorithms.
+ */
+class CV_EXPORTS_W SparseOpticalFlow : public Algorithm
+{
+public:
+ /** @brief Calculates a sparse optical flow.
+
+ @param prevImg First input image.
+ @param nextImg Second input image of the same size and the same type as prevImg.
+ @param prevPts Vector of 2D points for which the flow needs to be found.
+ @param nextPts Output vector of 2D points containing the calculated new positions of input features in the second image.
+ @param status Output status vector. Each element of the vector is set to 1 if the
+ flow for the corresponding features has been found. Otherwise, it is set to 0.
+ @param err Optional output vector that contains error response for each point (inverse confidence).
+ */
+ CV_WRAP virtual void calc(InputArray prevImg, InputArray nextImg,
+ InputArray prevPts, InputOutputArray nextPts,
+ OutputArray status,
+ OutputArray err = cv::noArray()) = 0;
+};
+
+/** @brief "Dual TV L1" Optical Flow Algorithm.
+
+The class implements the "Dual TV L1" optical flow algorithm described in @cite Zach2007 and
+@cite Javier2012 .
+Here are important members of the class that control the algorithm, which you can set after
+constructing the class instance:
+
+- member double tau
+ Time step of the numerical scheme.
+
+- member double lambda
+ Weight parameter for the data term, attachment parameter. This is the most relevant
+ parameter, which determines the smoothness of the output. The smaller this parameter is,
+ the smoother the solutions we obtain. It depends on the range of motions of the images, so
+ its value should be adapted to each image sequence.
+
+- member double theta
+ Weight parameter for (u - v)\^2, tightness parameter. It serves as a link between the
+ attachment and the regularization terms. In theory, it should have a small value in order
+ to maintain both parts in correspondence. The method is stable for a large range of values
+ of this parameter.
+
+- member int nscales
+ Number of scales used to create the pyramid of images.
+
+- member int warps
+ Number of warpings per scale. Represents the number of times that I1(x+u0) and grad(
+ I1(x+u0) ) are computed per scale. This is a parameter that assures the stability of the
+ method. It also affects the running time, so it is a compromise between speed and
+ accuracy.
+
+- member double epsilon
+ Stopping criterion threshold used in the numerical scheme, which is a trade-off between
+ precision and running time. A small value will yield more accurate solutions at the
+ expense of a slower convergence.
+
+- member int iterations
+ Stopping criterion iterations number used in the numerical scheme.
+
+C. Zach, T. Pock and H. Bischof, "A Duality Based Approach for Realtime TV-L1 Optical Flow".
+Javier Sanchez, Enric Meinhardt-Llopis and Gabriele Facciolo. "TV-L1 Optical Flow Estimation".
+*/
+class CV_EXPORTS_W DualTVL1OpticalFlow : public DenseOpticalFlow
+{
+public:
+ //! @brief Time step of the numerical scheme
+ /** @see setTau */
+ CV_WRAP virtual double getTau() const = 0;
+ /** @copybrief getTau @see getTau */
+ CV_WRAP virtual void setTau(double val) = 0;
+ //! @brief Weight parameter for the data term, attachment parameter
+ /** @see setLambda */
+ CV_WRAP virtual double getLambda() const = 0;
+ /** @copybrief getLambda @see getLambda */
+ CV_WRAP virtual void setLambda(double val) = 0;
+ //! @brief Weight parameter for (u - v)^2, tightness parameter
+ /** @see setTheta */
+ CV_WRAP virtual double getTheta() const = 0;
+ /** @copybrief getTheta @see getTheta */
+ CV_WRAP virtual void setTheta(double val) = 0;
+ //! @brief coefficient for additional illumination variation term
+ /** @see setGamma */
+ CV_WRAP virtual double getGamma() const = 0;
+ /** @copybrief getGamma @see getGamma */
+ CV_WRAP virtual void setGamma(double val) = 0;
+ //! @brief Number of scales used to create the pyramid of images
+ /** @see setScalesNumber */
+ CV_WRAP virtual int getScalesNumber() const = 0;
+ /** @copybrief getScalesNumber @see getScalesNumber */
+ CV_WRAP virtual void setScalesNumber(int val) = 0;
+ //! @brief Number of warpings per scale
+ /** @see setWarpingsNumber */
+ CV_WRAP virtual int getWarpingsNumber() const = 0;
+ /** @copybrief getWarpingsNumber @see getWarpingsNumber */
+ CV_WRAP virtual void setWarpingsNumber(int val) = 0;
+ //! @brief Stopping criterion threshold used in the numerical scheme, which is a trade-off between precision and running time
+ /** @see setEpsilon */
+ CV_WRAP virtual double getEpsilon() const = 0;
+ /** @copybrief getEpsilon @see getEpsilon */
+ CV_WRAP virtual void setEpsilon(double val) = 0;
+ //! @brief Inner iterations (between outlier filtering) used in the numerical scheme
+ /** @see setInnerIterations */
+ CV_WRAP virtual int getInnerIterations() const = 0;
+ /** @copybrief getInnerIterations @see getInnerIterations */
+ CV_WRAP virtual void setInnerIterations(int val) = 0;
+ //! @brief Outer iterations (number of inner loops) used in the numerical scheme
+ /** @see setOuterIterations */
+ CV_WRAP virtual int getOuterIterations() const = 0;
+ /** @copybrief getOuterIterations @see getOuterIterations */
+ CV_WRAP virtual void setOuterIterations(int val) = 0;
+ //! @brief Use initial flow
+ /** @see setUseInitialFlow */
+ CV_WRAP virtual bool getUseInitialFlow() const = 0;
+ /** @copybrief getUseInitialFlow @see getUseInitialFlow */
+ CV_WRAP virtual void setUseInitialFlow(bool val) = 0;
+ //! @brief Step between scales (<1)
+ /** @see setScaleStep */
+ CV_WRAP virtual double getScaleStep() const = 0;
+ /** @copybrief getScaleStep @see getScaleStep */
+ CV_WRAP virtual void setScaleStep(double val) = 0;
+ //! @brief Median filter kernel size (1 = no filter) (3 or 5)
+ /** @see setMedianFiltering */
+ CV_WRAP virtual int getMedianFiltering() const = 0;
+ /** @copybrief getMedianFiltering @see getMedianFiltering */
+ CV_WRAP virtual void setMedianFiltering(int val) = 0;
+
+ /** @brief Creates instance of cv::DualTVL1OpticalFlow*/
+ CV_WRAP static Ptr<DualTVL1OpticalFlow> create(
+ double tau = 0.25,
+ double lambda = 0.15,
+ double theta = 0.3,
+ int nscales = 5,
+ int warps = 5,
+ double epsilon = 0.01,
+ int innnerIterations = 30,
+ int outerIterations = 10,
+ double scaleStep = 0.8,
+ double gamma = 0.0,
+ int medianFiltering = 5,
+ bool useInitialFlow = false);
+};
+
+/** @brief Creates instance of cv::DenseOpticalFlow
+*/
+CV_EXPORTS_W Ptr<DualTVL1OpticalFlow> createOptFlow_DualTVL1();
+
+/** @brief Class computing a dense optical flow using the Gunnar Farneback’s algorithm.
+ */
+class CV_EXPORTS_W FarnebackOpticalFlow : public DenseOpticalFlow
+{
+public:
+ CV_WRAP virtual int getNumLevels() const = 0;
+ CV_WRAP virtual void setNumLevels(int numLevels) = 0;
+
+ CV_WRAP virtual double getPyrScale() const = 0;
+ CV_WRAP virtual void setPyrScale(double pyrScale) = 0;
+
+ CV_WRAP virtual bool getFastPyramids() const = 0;
+ CV_WRAP virtual void setFastPyramids(bool fastPyramids) = 0;
+
+ CV_WRAP virtual int getWinSize() const = 0;
+ CV_WRAP virtual void setWinSize(int winSize) = 0;
+
+ CV_WRAP virtual int getNumIters() const = 0;
+ CV_WRAP virtual void setNumIters(int numIters) = 0;
+
+ CV_WRAP virtual int getPolyN() const = 0;
+ CV_WRAP virtual void setPolyN(int polyN) = 0;
+
+ CV_WRAP virtual double getPolySigma() const = 0;
+ CV_WRAP virtual void setPolySigma(double polySigma) = 0;
+
+ CV_WRAP virtual int getFlags() const = 0;
+ CV_WRAP virtual void setFlags(int flags) = 0;
+
+ CV_WRAP static Ptr<FarnebackOpticalFlow> create(
+ int numLevels = 5,
+ double pyrScale = 0.5,
+ bool fastPyramids = false,
+ int winSize = 13,
+ int numIters = 10,
+ int polyN = 5,
+ double polySigma = 1.1,
+ int flags = 0);
+};
+
+
+/** @brief Class used for calculating a sparse optical flow.
+
+The class can calculate an optical flow for a sparse feature set using the
+iterative Lucas-Kanade method with pyramids.
+
+@sa calcOpticalFlowPyrLK
+
+*/
+class CV_EXPORTS_W SparsePyrLKOpticalFlow : public SparseOpticalFlow
+{
+public:
+ CV_WRAP virtual Size getWinSize() const = 0;
+ CV_WRAP virtual void setWinSize(Size winSize) = 0;
+
+ CV_WRAP virtual int getMaxLevel() const = 0;
+ CV_WRAP virtual void setMaxLevel(int maxLevel) = 0;
+
+ CV_WRAP virtual TermCriteria getTermCriteria() const = 0;
+ CV_WRAP virtual void setTermCriteria(TermCriteria& crit) = 0;
+
+ CV_WRAP virtual int getFlags() const = 0;
+ CV_WRAP virtual void setFlags(int flags) = 0;
+
+ CV_WRAP virtual double getMinEigThreshold() const = 0;
+ CV_WRAP virtual void setMinEigThreshold(double minEigThreshold) = 0;
+
+ CV_WRAP static Ptr<SparsePyrLKOpticalFlow> create(
+ Size winSize = Size(21, 21),
+ int maxLevel = 3, TermCriteria crit =
+ TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 30, 0.01),
+ int flags = 0,
+ double minEigThreshold = 1e-4);
+};
+
+//! @} video_track
+
+} // cv
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/video/tracking_c.h Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,232 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_TRACKING_C_H
+#define OPENCV_TRACKING_C_H
+
+#include "opencv2/imgproc/types_c.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @addtogroup video_c
+ @{
+*/
+
+/****************************************************************************************\
+* Motion Analysis *
+\****************************************************************************************/
+
+/************************************ optical flow ***************************************/
+
+#define CV_LKFLOW_PYR_A_READY 1
+#define CV_LKFLOW_PYR_B_READY 2
+#define CV_LKFLOW_INITIAL_GUESSES 4
+#define CV_LKFLOW_GET_MIN_EIGENVALS 8
+
+/* It is Lucas & Kanade method, modified to use pyramids.
+ Also it does several iterations to get optical flow for
+ every point at every pyramid level.
+ Calculates optical flow between two images for certain set of points (i.e.
+ it is a "sparse" optical flow, which is opposite to the previous 3 methods) */
+CVAPI(void) cvCalcOpticalFlowPyrLK( const CvArr* prev, const CvArr* curr,
+ CvArr* prev_pyr, CvArr* curr_pyr,
+ const CvPoint2D32f* prev_features,
+ CvPoint2D32f* curr_features,
+ int count,
+ CvSize win_size,
+ int level,
+ char* status,
+ float* track_error,
+ CvTermCriteria criteria,
+ int flags );
+
+
+/* Modification of a previous sparse optical flow algorithm to calculate
+ affine flow */
+CVAPI(void) cvCalcAffineFlowPyrLK( const CvArr* prev, const CvArr* curr,
+ CvArr* prev_pyr, CvArr* curr_pyr,
+ const CvPoint2D32f* prev_features,
+ CvPoint2D32f* curr_features,
+ float* matrices, int count,
+ CvSize win_size, int level,
+ char* status, float* track_error,
+ CvTermCriteria criteria, int flags );
+
+/* Estimate rigid transformation between 2 images or 2 point sets */
+CVAPI(int) cvEstimateRigidTransform( const CvArr* A, const CvArr* B,
+ CvMat* M, int full_affine );
+
+/* Estimate optical flow for each pixel using the two-frame G. Farneback algorithm */
+CVAPI(void) cvCalcOpticalFlowFarneback( const CvArr* prev, const CvArr* next,
+ CvArr* flow, double pyr_scale, int levels,
+ int winsize, int iterations, int poly_n,
+ double poly_sigma, int flags );
+
+/********************************* motion templates *************************************/
+
+/****************************************************************************************\
+* All the motion template functions work only with single channel images. *
+* Silhouette image must have depth IPL_DEPTH_8U or IPL_DEPTH_8S *
+* Motion history image must have depth IPL_DEPTH_32F, *
+* Gradient mask - IPL_DEPTH_8U or IPL_DEPTH_8S, *
+* Motion orientation image - IPL_DEPTH_32F *
+* Segmentation mask - IPL_DEPTH_32F *
+* All the angles are in degrees, all the times are in milliseconds *
+\****************************************************************************************/
+
+/* Updates motion history image given motion silhouette */
+CVAPI(void) cvUpdateMotionHistory( const CvArr* silhouette, CvArr* mhi,
+ double timestamp, double duration );
+
+/* Calculates gradient of the motion history image and fills
+ a mask indicating where the gradient is valid */
+CVAPI(void) cvCalcMotionGradient( const CvArr* mhi, CvArr* mask, CvArr* orientation,
+ double delta1, double delta2,
+ int aperture_size CV_DEFAULT(3));
+
+/* Calculates average motion direction within a selected motion region
+ (region can be selected by setting ROIs and/or by composing a valid gradient mask
+ with the region mask) */
+CVAPI(double) cvCalcGlobalOrientation( const CvArr* orientation, const CvArr* mask,
+ const CvArr* mhi, double timestamp,
+ double duration );
+
+/* Splits a motion history image into a few parts corresponding to separate independent motions
+ (e.g. left hand, right hand) */
+CVAPI(CvSeq*) cvSegmentMotion( const CvArr* mhi, CvArr* seg_mask,
+ CvMemStorage* storage,
+ double timestamp, double seg_thresh );
+
+/****************************************************************************************\
+* Tracking *
+\****************************************************************************************/
+
+/* Implements CAMSHIFT algorithm - determines object position, size and orientation
+ from the object histogram back project (extension of meanshift) */
+CVAPI(int) cvCamShift( const CvArr* prob_image, CvRect window,
+ CvTermCriteria criteria, CvConnectedComp* comp,
+ CvBox2D* box CV_DEFAULT(NULL) );
+
+/* Implements MeanShift algorithm - determines object position
+ from the object histogram back project */
+CVAPI(int) cvMeanShift( const CvArr* prob_image, CvRect window,
+ CvTermCriteria criteria, CvConnectedComp* comp );
+
+/*
+standard Kalman filter (in G. Welch' and G. Bishop's notation):
+
+ x(k)=A*x(k-1)+B*u(k)+w(k) p(w)~N(0,Q)
+ z(k)=H*x(k)+v(k), p(v)~N(0,R)
+*/
+typedef struct CvKalman
+{
+ int MP; /* number of measurement vector dimensions */
+ int DP; /* number of state vector dimensions */
+ int CP; /* number of control vector dimensions */
+
+ /* backward compatibility fields */
+#if 1
+ float* PosterState; /* =state_pre->data.fl */
+ float* PriorState; /* =state_post->data.fl */
+ float* DynamMatr; /* =transition_matrix->data.fl */
+ float* MeasurementMatr; /* =measurement_matrix->data.fl */
+ float* MNCovariance; /* =measurement_noise_cov->data.fl */
+ float* PNCovariance; /* =process_noise_cov->data.fl */
+ float* KalmGainMatr; /* =gain->data.fl */
+ float* PriorErrorCovariance;/* =error_cov_pre->data.fl */
+ float* PosterErrorCovariance;/* =error_cov_post->data.fl */
+ float* Temp1; /* temp1->data.fl */
+ float* Temp2; /* temp2->data.fl */
+#endif
+
+ CvMat* state_pre; /* predicted state (x'(k)):
+ x(k)=A*x(k-1)+B*u(k) */
+ CvMat* state_post; /* corrected state (x(k)):
+ x(k)=x'(k)+K(k)*(z(k)-H*x'(k)) */
+ CvMat* transition_matrix; /* state transition matrix (A) */
+ CvMat* control_matrix; /* control matrix (B)
+ (it is not used if there is no control)*/
+ CvMat* measurement_matrix; /* measurement matrix (H) */
+ CvMat* process_noise_cov; /* process noise covariance matrix (Q) */
+ CvMat* measurement_noise_cov; /* measurement noise covariance matrix (R) */
+ CvMat* error_cov_pre; /* priori error estimate covariance matrix (P'(k)):
+ P'(k)=A*P(k-1)*At + Q)*/
+ CvMat* gain; /* Kalman gain matrix (K(k)):
+ K(k)=P'(k)*Ht*inv(H*P'(k)*Ht+R)*/
+ CvMat* error_cov_post; /* posteriori error estimate covariance matrix (P(k)):
+ P(k)=(I-K(k)*H)*P'(k) */
+ CvMat* temp1; /* temporary matrices */
+ CvMat* temp2;
+ CvMat* temp3;
+ CvMat* temp4;
+ CvMat* temp5;
+} CvKalman;
+
+/* Creates Kalman filter and sets A, B, Q, R and state to some initial values */
+CVAPI(CvKalman*) cvCreateKalman( int dynam_params, int measure_params,
+ int control_params CV_DEFAULT(0));
+
+/* Releases Kalman filter state */
+CVAPI(void) cvReleaseKalman( CvKalman** kalman);
+
+/* Updates Kalman filter by time (predicts future state of the system) */
+CVAPI(const CvMat*) cvKalmanPredict( CvKalman* kalman,
+ const CvMat* control CV_DEFAULT(NULL));
+
+/* Updates Kalman filter by measurement
+ (corrects state of the system and internal matrices) */
+CVAPI(const CvMat*) cvKalmanCorrect( CvKalman* kalman, const CvMat* measurement );
+
+#define cvKalmanUpdateByTime cvKalmanPredict
+#define cvKalmanUpdateByMeasurement cvKalmanCorrect
+
+/** @} video_c */
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+
+#endif // OPENCV_TRACKING_C_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/opencv2/video/video.hpp Fri Jan 29 04:53:38 2021 +0000 @@ -0,0 +1,48 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifdef __OPENCV_BUILD +#error this is a compatibility header which should not be used inside the OpenCV library +#endif + +#include "opencv2/video.hpp"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/videostab.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,81 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_VIDEOSTAB_HPP
+#define OPENCV_VIDEOSTAB_HPP
+
+/**
+ @defgroup videostab Video Stabilization
+
+The video stabilization module contains a set of functions and classes that can be used to solve the
+problem of video stabilization. There are a few methods implemented, most of them are described in
+the papers @cite OF06 and @cite G11 . However, there are some extensions and deviations from the original
+paper methods.
+
+### References
+
+ 1. "Full-Frame Video Stabilization with Motion Inpainting"
+ Yasuyuki Matsushita, Eyal Ofek, Weina Ge, Xiaoou Tang, Senior Member, and Heung-Yeung Shum
+ 2. "Auto-Directed Video Stabilization with Robust L1 Optimal Camera Paths"
+ Matthias Grundmann, Vivek Kwatra, Irfan Essa
+
+ @{
+ @defgroup videostab_motion Global Motion Estimation
+
+The video stabilization module contains a set of functions and classes for global motion estimation
+between point clouds or between images. In the last case features are extracted and matched
+internally. For the sake of convenience the motion estimation functions are wrapped into classes.
+Both the functions and the classes are available.
+
+ @defgroup videostab_marching Fast Marching Method
+
+The Fast Marching Method @cite Telea04 is used in of the video stabilization routines to do motion and
+color inpainting. The method is implemented is a flexible way and it's made public for other users.
+
+ @}
+
+*/
+
+#include "opencv2/videostab/stabilizer.hpp"
+#include "opencv2/videostab/ring_buffer.hpp"
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/videostab/deblurring.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,116 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_VIDEOSTAB_DEBLURRING_HPP
+#define OPENCV_VIDEOSTAB_DEBLURRING_HPP
+
+#include <vector>
+#include "opencv2/core.hpp"
+
+namespace cv
+{
+namespace videostab
+{
+
+//! @addtogroup videostab
+//! @{
+
+CV_EXPORTS float calcBlurriness(const Mat &frame);
+
+class CV_EXPORTS DeblurerBase
+{
+public:
+ DeblurerBase() : radius_(0), frames_(0), motions_(0), blurrinessRates_(0) {}
+
+ virtual ~DeblurerBase() {}
+
+ virtual void setRadius(int val) { radius_ = val; }
+ virtual int radius() const { return radius_; }
+
+ virtual void deblur(int idx, Mat &frame) = 0;
+
+
+ // data from stabilizer
+
+ virtual void setFrames(const std::vector<Mat> &val) { frames_ = &val; }
+ virtual const std::vector<Mat>& frames() const { return *frames_; }
+
+ virtual void setMotions(const std::vector<Mat> &val) { motions_ = &val; }
+ virtual const std::vector<Mat>& motions() const { return *motions_; }
+
+ virtual void setBlurrinessRates(const std::vector<float> &val) { blurrinessRates_ = &val; }
+ virtual const std::vector<float>& blurrinessRates() const { return *blurrinessRates_; }
+
+protected:
+ int radius_;
+ const std::vector<Mat> *frames_;
+ const std::vector<Mat> *motions_;
+ const std::vector<float> *blurrinessRates_;
+};
+
+class CV_EXPORTS NullDeblurer : public DeblurerBase
+{
+public:
+ virtual void deblur(int /*idx*/, Mat &/*frame*/) {}
+};
+
+class CV_EXPORTS WeightingDeblurer : public DeblurerBase
+{
+public:
+ WeightingDeblurer();
+
+ void setSensitivity(float val) { sensitivity_ = val; }
+ float sensitivity() const { return sensitivity_; }
+
+ virtual void deblur(int idx, Mat &frame);
+
+private:
+ float sensitivity_;
+ Mat_<float> bSum_, gSum_, rSum_, wSum_;
+};
+
+//! @}
+
+} // namespace videostab
+} // namespace cv
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/videostab/fast_marching.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,121 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_VIDEOSTAB_FAST_MARCHING_HPP
+#define OPENCV_VIDEOSTAB_FAST_MARCHING_HPP
+
+#include <cmath>
+#include <queue>
+#include <algorithm>
+#include "opencv2/core.hpp"
+
+namespace cv
+{
+namespace videostab
+{
+
+//! @addtogroup videostab_marching
+//! @{
+
+/** @brief Describes the Fast Marching Method implementation.
+
+ See http://iwi.eldoc.ub.rug.nl/FILES/root/2004/JGraphToolsTelea/2004JGraphToolsTelea.pdf
+ */
+class CV_EXPORTS FastMarchingMethod
+{
+public:
+ FastMarchingMethod() : inf_(1e6f) {}
+
+ /** @brief Template method that runs the Fast Marching Method.
+
+ @param mask Image mask. 0 value indicates that the pixel value must be inpainted, 255 indicates
+ that the pixel value is known, other values aren't acceptable.
+ @param inpaint Inpainting functor that overloads void operator ()(int x, int y).
+ @return Inpainting functor.
+ */
+ template <typename Inpaint>
+ Inpaint run(const Mat &mask, Inpaint inpaint);
+
+ /**
+ @return Distance map that's created during working of the method.
+ */
+ Mat distanceMap() const { return dist_; }
+
+private:
+ enum { INSIDE = 0, BAND = 1, KNOWN = 255 };
+
+ struct DXY
+ {
+ float dist;
+ int x, y;
+
+ DXY() : dist(0), x(0), y(0) {}
+ DXY(float _dist, int _x, int _y) : dist(_dist), x(_x), y(_y) {}
+ bool operator <(const DXY &dxy) const { return dist < dxy.dist; }
+ };
+
+ float solve(int x1, int y1, int x2, int y2) const;
+ int& indexOf(const DXY &dxy) { return index_(dxy.y, dxy.x); }
+
+ void heapUp(int idx);
+ void heapDown(int idx);
+ void heapAdd(const DXY &dxy);
+ void heapRemoveMin();
+
+ float inf_;
+
+ cv::Mat_<uchar> flag_; // flag map
+ cv::Mat_<float> dist_; // distance map
+
+ cv::Mat_<int> index_; // index of point in the narrow band
+ std::vector<DXY> narrowBand_; // narrow band heap
+ int size_; // narrow band size
+};
+
+//! @}
+
+} // namespace videostab
+} // namespace cv
+
+#include "fast_marching_inl.hpp"
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/videostab/fast_marching_inl.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,165 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_VIDEOSTAB_FAST_MARCHING_INL_HPP
+#define OPENCV_VIDEOSTAB_FAST_MARCHING_INL_HPP
+
+#include "opencv2/videostab/fast_marching.hpp"
+
+namespace cv
+{
+namespace videostab
+{
+
+template <typename Inpaint>
+Inpaint FastMarchingMethod::run(const cv::Mat &mask, Inpaint inpaint)
+{
+ using namespace cv;
+
+ CV_Assert(mask.type() == CV_8U);
+
+ static const int lut[4][2] = {{-1,0}, {0,-1}, {1,0}, {0,1}};
+
+ mask.copyTo(flag_);
+ flag_.create(mask.size());
+ dist_.create(mask.size());
+ index_.create(mask.size());
+ narrowBand_.clear();
+ size_ = 0;
+
+ // init
+ for (int y = 0; y < flag_.rows; ++y)
+ {
+ for (int x = 0; x < flag_.cols; ++x)
+ {
+ if (flag_(y,x) == KNOWN)
+ dist_(y,x) = 0.f;
+ else
+ {
+ int n = 0;
+ int nunknown = 0;
+
+ for (int i = 0; i < 4; ++i)
+ {
+ int xn = x + lut[i][0];
+ int yn = y + lut[i][1];
+
+ if (xn >= 0 && xn < flag_.cols && yn >= 0 && yn < flag_.rows)
+ {
+ n++;
+ if (flag_(yn,xn) != KNOWN)
+ nunknown++;
+ }
+ }
+
+ if (n>0 && nunknown == n)
+ {
+ dist_(y,x) = inf_;
+ flag_(y,x) = INSIDE;
+ }
+ else
+ {
+ dist_(y,x) = 0.f;
+ flag_(y,x) = BAND;
+ inpaint(x, y);
+
+ narrowBand_.push_back(DXY(0.f,x,y));
+ index_(y,x) = size_++;
+ }
+ }
+ }
+ }
+
+ // make heap
+ for (int i = size_/2-1; i >= 0; --i)
+ heapDown(i);
+
+ // main cycle
+ while (size_ > 0)
+ {
+ int x = narrowBand_[0].x;
+ int y = narrowBand_[0].y;
+ heapRemoveMin();
+
+ flag_(y,x) = KNOWN;
+ for (int n = 0; n < 4; ++n)
+ {
+ int xn = x + lut[n][0];
+ int yn = y + lut[n][1];
+
+ if (xn >= 0 && xn < flag_.cols && yn >= 0 && yn < flag_.rows && flag_(yn,xn) != KNOWN)
+ {
+ dist_(yn,xn) = std::min(std::min(solve(xn-1, yn, xn, yn-1), solve(xn+1, yn, xn, yn-1)),
+ std::min(solve(xn-1, yn, xn, yn+1), solve(xn+1, yn, xn, yn+1)));
+
+ if (flag_(yn,xn) == INSIDE)
+ {
+ flag_(yn,xn) = BAND;
+ inpaint(xn, yn);
+ heapAdd(DXY(dist_(yn,xn),xn,yn));
+ }
+ else
+ {
+ int i = index_(yn,xn);
+ if (dist_(yn,xn) < narrowBand_[i].dist)
+ {
+ narrowBand_[i].dist = dist_(yn,xn);
+ heapUp(i);
+ }
+ // works better if it's commented out
+ /*else if (dist(yn,xn) > narrowBand[i].dist)
+ {
+ narrowBand[i].dist = dist(yn,xn);
+ heapDown(i);
+ }*/
+ }
+ }
+ }
+ }
+
+ return inpaint;
+}
+
+} // namespace videostab
+} // namespace cv
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/videostab/frame_source.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,94 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_VIDEOSTAB_FRAME_SOURCE_HPP
+#define OPENCV_VIDEOSTAB_FRAME_SOURCE_HPP
+
+#include <vector>
+#include "opencv2/core.hpp"
+
+namespace cv
+{
+namespace videostab
+{
+
+//! @addtogroup videostab
+//! @{
+
+class CV_EXPORTS IFrameSource
+{
+public:
+ virtual ~IFrameSource() {}
+ virtual void reset() = 0;
+ virtual Mat nextFrame() = 0;
+};
+
+class CV_EXPORTS NullFrameSource : public IFrameSource
+{
+public:
+ virtual void reset() {}
+ virtual Mat nextFrame() { return Mat(); }
+};
+
+class CV_EXPORTS VideoFileSource : public IFrameSource
+{
+public:
+ VideoFileSource(const String &path, bool volatileFrame = false);
+
+ virtual void reset();
+ virtual Mat nextFrame();
+
+ int width();
+ int height();
+ int count();
+ double fps();
+
+private:
+ Ptr<IFrameSource> impl;
+};
+
+//! @}
+
+} // namespace videostab
+} // namespace cv
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/videostab/global_motion.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,299 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_VIDEOSTAB_GLOBAL_MOTION_HPP
+#define OPENCV_VIDEOSTAB_GLOBAL_MOTION_HPP
+
+#include <vector>
+#include <fstream>
+#include "opencv2/core.hpp"
+#include "opencv2/features2d.hpp"
+#include "opencv2/opencv_modules.hpp"
+#include "opencv2/videostab/optical_flow.hpp"
+#include "opencv2/videostab/motion_core.hpp"
+#include "opencv2/videostab/outlier_rejection.hpp"
+
+#ifdef HAVE_OPENCV_CUDAIMGPROC
+# include "opencv2/cudaimgproc.hpp"
+#endif
+
+namespace cv
+{
+namespace videostab
+{
+
+//! @addtogroup videostab_motion
+//! @{
+
+/** @brief Estimates best global motion between two 2D point clouds in the least-squares sense.
+
+@note Works in-place and changes input point arrays.
+
+@param points0 Source set of 2D points (32F).
+@param points1 Destination set of 2D points (32F).
+@param model Motion model (up to MM_AFFINE).
+@param rmse Final root-mean-square error.
+@return 3x3 2D transformation matrix (32F).
+ */
+CV_EXPORTS Mat estimateGlobalMotionLeastSquares(
+ InputOutputArray points0, InputOutputArray points1, int model = MM_AFFINE,
+ float *rmse = 0);
+
+/** @brief Estimates best global motion between two 2D point clouds robustly (using RANSAC method).
+
+@param points0 Source set of 2D points (32F).
+@param points1 Destination set of 2D points (32F).
+@param model Motion model. See cv::videostab::MotionModel.
+@param params RANSAC method parameters. See videostab::RansacParams.
+@param rmse Final root-mean-square error.
+@param ninliers Final number of inliers.
+ */
+CV_EXPORTS Mat estimateGlobalMotionRansac(
+ InputArray points0, InputArray points1, int model = MM_AFFINE,
+ const RansacParams ¶ms = RansacParams::default2dMotion(MM_AFFINE),
+ float *rmse = 0, int *ninliers = 0);
+
+/** @brief Base class for all global motion estimation methods.
+ */
+class CV_EXPORTS MotionEstimatorBase
+{
+public:
+ virtual ~MotionEstimatorBase() {}
+
+ /** @brief Sets motion model.
+
+ @param val Motion model. See cv::videostab::MotionModel.
+ */
+ virtual void setMotionModel(MotionModel val) { motionModel_ = val; }
+
+ /**
+ @return Motion model. See cv::videostab::MotionModel.
+ */
+ virtual MotionModel motionModel() const { return motionModel_; }
+
+ /** @brief Estimates global motion between two 2D point clouds.
+
+ @param points0 Source set of 2D points (32F).
+ @param points1 Destination set of 2D points (32F).
+ @param ok Indicates whether motion was estimated successfully.
+ @return 3x3 2D transformation matrix (32F).
+ */
+ virtual Mat estimate(InputArray points0, InputArray points1, bool *ok = 0) = 0;
+
+protected:
+ MotionEstimatorBase(MotionModel model) { setMotionModel(model); }
+
+private:
+ MotionModel motionModel_;
+};
+
+/** @brief Describes a robust RANSAC-based global 2D motion estimation method which minimizes L2 error.
+ */
+class CV_EXPORTS MotionEstimatorRansacL2 : public MotionEstimatorBase
+{
+public:
+ MotionEstimatorRansacL2(MotionModel model = MM_AFFINE);
+
+ void setRansacParams(const RansacParams &val) { ransacParams_ = val; }
+ RansacParams ransacParams() const { return ransacParams_; }
+
+ void setMinInlierRatio(float val) { minInlierRatio_ = val; }
+ float minInlierRatio() const { return minInlierRatio_; }
+
+ virtual Mat estimate(InputArray points0, InputArray points1, bool *ok = 0);
+
+private:
+ RansacParams ransacParams_;
+ float minInlierRatio_;
+};
+
+/** @brief Describes a global 2D motion estimation method which minimizes L1 error.
+
+@note To be able to use this method you must build OpenCV with CLP library support. :
+ */
+class CV_EXPORTS MotionEstimatorL1 : public MotionEstimatorBase
+{
+public:
+ MotionEstimatorL1(MotionModel model = MM_AFFINE);
+
+ virtual Mat estimate(InputArray points0, InputArray points1, bool *ok = 0);
+
+private:
+ std::vector<double> obj_, collb_, colub_;
+ std::vector<double> elems_, rowlb_, rowub_;
+ std::vector<int> rows_, cols_;
+
+ void set(int row, int col, double coef)
+ {
+ rows_.push_back(row);
+ cols_.push_back(col);
+ elems_.push_back(coef);
+ }
+};
+
+/** @brief Base class for global 2D motion estimation methods which take frames as input.
+ */
+class CV_EXPORTS ImageMotionEstimatorBase
+{
+public:
+ virtual ~ImageMotionEstimatorBase() {}
+
+ virtual void setMotionModel(MotionModel val) { motionModel_ = val; }
+ virtual MotionModel motionModel() const { return motionModel_; }
+
+ virtual Mat estimate(const Mat &frame0, const Mat &frame1, bool *ok = 0) = 0;
+
+protected:
+ ImageMotionEstimatorBase(MotionModel model) { setMotionModel(model); }
+
+private:
+ MotionModel motionModel_;
+};
+
+class CV_EXPORTS FromFileMotionReader : public ImageMotionEstimatorBase
+{
+public:
+ FromFileMotionReader(const String &path);
+
+ virtual Mat estimate(const Mat &frame0, const Mat &frame1, bool *ok = 0);
+
+private:
+ std::ifstream file_;
+};
+
+class CV_EXPORTS ToFileMotionWriter : public ImageMotionEstimatorBase
+{
+public:
+ ToFileMotionWriter(const String &path, Ptr<ImageMotionEstimatorBase> estimator);
+
+ virtual void setMotionModel(MotionModel val) { motionEstimator_->setMotionModel(val); }
+ virtual MotionModel motionModel() const { return motionEstimator_->motionModel(); }
+
+ virtual Mat estimate(const Mat &frame0, const Mat &frame1, bool *ok = 0);
+
+private:
+ std::ofstream file_;
+ Ptr<ImageMotionEstimatorBase> motionEstimator_;
+};
+
+/** @brief Describes a global 2D motion estimation method which uses keypoints detection and optical flow for
+matching.
+ */
+class CV_EXPORTS KeypointBasedMotionEstimator : public ImageMotionEstimatorBase
+{
+public:
+ KeypointBasedMotionEstimator(Ptr<MotionEstimatorBase> estimator);
+
+ virtual void setMotionModel(MotionModel val) { motionEstimator_->setMotionModel(val); }
+ virtual MotionModel motionModel() const { return motionEstimator_->motionModel(); }
+
+ void setDetector(Ptr<FeatureDetector> val) { detector_ = val; }
+ Ptr<FeatureDetector> detector() const { return detector_; }
+
+ void setOpticalFlowEstimator(Ptr<ISparseOptFlowEstimator> val) { optFlowEstimator_ = val; }
+ Ptr<ISparseOptFlowEstimator> opticalFlowEstimator() const { return optFlowEstimator_; }
+
+ void setOutlierRejector(Ptr<IOutlierRejector> val) { outlierRejector_ = val; }
+ Ptr<IOutlierRejector> outlierRejector() const { return outlierRejector_; }
+
+ virtual Mat estimate(const Mat &frame0, const Mat &frame1, bool *ok = 0);
+
+private:
+ Ptr<MotionEstimatorBase> motionEstimator_;
+ Ptr<FeatureDetector> detector_;
+ Ptr<ISparseOptFlowEstimator> optFlowEstimator_;
+ Ptr<IOutlierRejector> outlierRejector_;
+
+ std::vector<uchar> status_;
+ std::vector<KeyPoint> keypointsPrev_;
+ std::vector<Point2f> pointsPrev_, points_;
+ std::vector<Point2f> pointsPrevGood_, pointsGood_;
+};
+
+#if defined(HAVE_OPENCV_CUDAIMGPROC) && defined(HAVE_OPENCV_CUDAOPTFLOW)
+
+class CV_EXPORTS KeypointBasedMotionEstimatorGpu : public ImageMotionEstimatorBase
+{
+public:
+ KeypointBasedMotionEstimatorGpu(Ptr<MotionEstimatorBase> estimator);
+
+ virtual void setMotionModel(MotionModel val) { motionEstimator_->setMotionModel(val); }
+ virtual MotionModel motionModel() const { return motionEstimator_->motionModel(); }
+
+ void setOutlierRejector(Ptr<IOutlierRejector> val) { outlierRejector_ = val; }
+ Ptr<IOutlierRejector> outlierRejector() const { return outlierRejector_; }
+
+ virtual Mat estimate(const Mat &frame0, const Mat &frame1, bool *ok = 0);
+ Mat estimate(const cuda::GpuMat &frame0, const cuda::GpuMat &frame1, bool *ok = 0);
+
+private:
+ Ptr<MotionEstimatorBase> motionEstimator_;
+ Ptr<cuda::CornersDetector> detector_;
+ SparsePyrLkOptFlowEstimatorGpu optFlowEstimator_;
+ Ptr<IOutlierRejector> outlierRejector_;
+
+ cuda::GpuMat frame0_, grayFrame0_, frame1_;
+ cuda::GpuMat pointsPrev_, points_;
+ cuda::GpuMat status_;
+
+ Mat hostPointsPrev_, hostPoints_;
+ std::vector<Point2f> hostPointsPrevTmp_, hostPointsTmp_;
+ std::vector<uchar> rejectionStatus_;
+};
+
+#endif // defined(HAVE_OPENCV_CUDAIMGPROC) && defined(HAVE_OPENCV_CUDAOPTFLOW)
+
+/** @brief Computes motion between two frames assuming that all the intermediate motions are known.
+
+@param from Source frame index.
+@param to Destination frame index.
+@param motions Pair-wise motions. motions[i] denotes motion from the frame i to the frame i+1
+@return Motion from the frame from to the frame to.
+ */
+CV_EXPORTS Mat getMotion(int from, int to, const std::vector<Mat> &motions);
+
+//! @}
+
+} // namespace videostab
+} // namespace cv
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/videostab/inpainting.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,212 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_VIDEOSTAB_INPAINTINT_HPP
+#define OPENCV_VIDEOSTAB_INPAINTINT_HPP
+
+#include <vector>
+#include "opencv2/core.hpp"
+#include "opencv2/videostab/optical_flow.hpp"
+#include "opencv2/videostab/fast_marching.hpp"
+#include "opencv2/videostab/global_motion.hpp"
+#include "opencv2/photo.hpp"
+
+namespace cv
+{
+namespace videostab
+{
+
+//! @addtogroup videostab
+//! @{
+
+class CV_EXPORTS InpainterBase
+{
+public:
+ InpainterBase()
+ : radius_(0), motionModel_(MM_UNKNOWN), frames_(0), motions_(0),
+ stabilizedFrames_(0), stabilizationMotions_(0) {}
+
+ virtual ~InpainterBase() {}
+
+ virtual void setRadius(int val) { radius_ = val; }
+ virtual int radius() const { return radius_; }
+
+ virtual void setMotionModel(MotionModel val) { motionModel_ = val; }
+ virtual MotionModel motionModel() const { return motionModel_; }
+
+ virtual void inpaint(int idx, Mat &frame, Mat &mask) = 0;
+
+
+ // data from stabilizer
+
+ virtual void setFrames(const std::vector<Mat> &val) { frames_ = &val; }
+ virtual const std::vector<Mat>& frames() const { return *frames_; }
+
+ virtual void setMotions(const std::vector<Mat> &val) { motions_ = &val; }
+ virtual const std::vector<Mat>& motions() const { return *motions_; }
+
+ virtual void setStabilizedFrames(const std::vector<Mat> &val) { stabilizedFrames_ = &val; }
+ virtual const std::vector<Mat>& stabilizedFrames() const { return *stabilizedFrames_; }
+
+ virtual void setStabilizationMotions(const std::vector<Mat> &val) { stabilizationMotions_ = &val; }
+ virtual const std::vector<Mat>& stabilizationMotions() const { return *stabilizationMotions_; }
+
+protected:
+ int radius_;
+ MotionModel motionModel_;
+ const std::vector<Mat> *frames_;
+ const std::vector<Mat> *motions_;
+ const std::vector<Mat> *stabilizedFrames_;
+ const std::vector<Mat> *stabilizationMotions_;
+};
+
+class CV_EXPORTS NullInpainter : public InpainterBase
+{
+public:
+ virtual void inpaint(int /*idx*/, Mat &/*frame*/, Mat &/*mask*/) {}
+};
+
+class CV_EXPORTS InpaintingPipeline : public InpainterBase
+{
+public:
+ void pushBack(Ptr<InpainterBase> inpainter) { inpainters_.push_back(inpainter); }
+ bool empty() const { return inpainters_.empty(); }
+
+ virtual void setRadius(int val);
+ virtual void setMotionModel(MotionModel val);
+ virtual void setFrames(const std::vector<Mat> &val);
+ virtual void setMotions(const std::vector<Mat> &val);
+ virtual void setStabilizedFrames(const std::vector<Mat> &val);
+ virtual void setStabilizationMotions(const std::vector<Mat> &val);
+
+ virtual void inpaint(int idx, Mat &frame, Mat &mask);
+
+private:
+ std::vector<Ptr<InpainterBase> > inpainters_;
+};
+
+class CV_EXPORTS ConsistentMosaicInpainter : public InpainterBase
+{
+public:
+ ConsistentMosaicInpainter();
+
+ void setStdevThresh(float val) { stdevThresh_ = val; }
+ float stdevThresh() const { return stdevThresh_; }
+
+ virtual void inpaint(int idx, Mat &frame, Mat &mask);
+
+private:
+ float stdevThresh_;
+};
+
+class CV_EXPORTS MotionInpainter : public InpainterBase
+{
+public:
+ MotionInpainter();
+
+ void setOptFlowEstimator(Ptr<IDenseOptFlowEstimator> val) { optFlowEstimator_ = val; }
+ Ptr<IDenseOptFlowEstimator> optFlowEstimator() const { return optFlowEstimator_; }
+
+ void setFlowErrorThreshold(float val) { flowErrorThreshold_ = val; }
+ float flowErrorThreshold() const { return flowErrorThreshold_; }
+
+ void setDistThreshold(float val) { distThresh_ = val; }
+ float distThresh() const { return distThresh_; }
+
+ void setBorderMode(int val) { borderMode_ = val; }
+ int borderMode() const { return borderMode_; }
+
+ virtual void inpaint(int idx, Mat &frame, Mat &mask);
+
+private:
+ FastMarchingMethod fmm_;
+ Ptr<IDenseOptFlowEstimator> optFlowEstimator_;
+ float flowErrorThreshold_;
+ float distThresh_;
+ int borderMode_;
+
+ Mat frame1_, transformedFrame1_;
+ Mat_<uchar> grayFrame_, transformedGrayFrame1_;
+ Mat_<uchar> mask1_, transformedMask1_;
+ Mat_<float> flowX_, flowY_, flowErrors_;
+ Mat_<uchar> flowMask_;
+};
+
+class CV_EXPORTS ColorAverageInpainter : public InpainterBase
+{
+public:
+ virtual void inpaint(int idx, Mat &frame, Mat &mask);
+
+private:
+ FastMarchingMethod fmm_;
+};
+
+class CV_EXPORTS ColorInpainter : public InpainterBase
+{
+public:
+ ColorInpainter(int method = INPAINT_TELEA, double radius = 2.);
+
+ virtual void inpaint(int idx, Mat &frame, Mat &mask);
+
+private:
+ int method_;
+ double radius_;
+ Mat invMask_;
+};
+
+inline ColorInpainter::ColorInpainter(int _method, double _radius)
+ : method_(_method), radius_(_radius) {}
+
+CV_EXPORTS void calcFlowMask(
+ const Mat &flowX, const Mat &flowY, const Mat &errors, float maxError,
+ const Mat &mask0, const Mat &mask1, Mat &flowMask);
+
+CV_EXPORTS void completeFrameAccordingToFlow(
+ const Mat &flowMask, const Mat &flowX, const Mat &flowY, const Mat &frame1, const Mat &mask1,
+ float distThresh, Mat& frame0, Mat &mask0);
+
+//! @}
+
+} // namespace videostab
+} // namespace cv
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/videostab/log.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,80 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_VIDEOSTAB_LOG_HPP
+#define OPENCV_VIDEOSTAB_LOG_HPP
+
+#include "opencv2/core.hpp"
+
+namespace cv
+{
+namespace videostab
+{
+
+//! @addtogroup videostab
+//! @{
+
+class CV_EXPORTS ILog
+{
+public:
+ virtual ~ILog() {}
+ virtual void print(const char *format, ...) = 0;
+};
+
+class CV_EXPORTS NullLog : public ILog
+{
+public:
+ virtual void print(const char * /*format*/, ...) {}
+};
+
+class CV_EXPORTS LogToStdout : public ILog
+{
+public:
+ virtual void print(const char *format, ...);
+};
+
+//! @}
+
+} // namespace videostab
+} // namespace cv
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/videostab/motion_core.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,129 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_VIDEOSTAB_MOTION_CORE_HPP
+#define OPENCV_VIDEOSTAB_MOTION_CORE_HPP
+
+#include <cmath>
+#include "opencv2/core.hpp"
+
+namespace cv
+{
+namespace videostab
+{
+
+//! @addtogroup videostab_motion
+//! @{
+
+/** @brief Describes motion model between two point clouds.
+ */
+enum MotionModel
+{
+ MM_TRANSLATION = 0,
+ MM_TRANSLATION_AND_SCALE = 1,
+ MM_ROTATION = 2,
+ MM_RIGID = 3,
+ MM_SIMILARITY = 4,
+ MM_AFFINE = 5,
+ MM_HOMOGRAPHY = 6,
+ MM_UNKNOWN = 7
+};
+
+/** @brief Describes RANSAC method parameters.
+ */
+struct CV_EXPORTS RansacParams
+{
+ int size; //!< subset size
+ float thresh; //!< max error to classify as inlier
+ float eps; //!< max outliers ratio
+ float prob; //!< probability of success
+
+ RansacParams() : size(0), thresh(0), eps(0), prob(0) {}
+ /** @brief Constructor
+ @param size Subset size.
+ @param thresh Maximum re-projection error value to classify as inlier.
+ @param eps Maximum ratio of incorrect correspondences.
+ @param prob Required success probability.
+ */
+ RansacParams(int size, float thresh, float eps, float prob);
+
+ /**
+ @return Number of iterations that'll be performed by RANSAC method.
+ */
+ int niters() const
+ {
+ return static_cast<int>(
+ std::ceil(std::log(1 - prob) / std::log(1 - std::pow(1 - eps, size))));
+ }
+
+ /**
+ @param model Motion model. See cv::videostab::MotionModel.
+ @return Default RANSAC method parameters for the given motion model.
+ */
+ static RansacParams default2dMotion(MotionModel model)
+ {
+ CV_Assert(model < MM_UNKNOWN);
+ if (model == MM_TRANSLATION)
+ return RansacParams(1, 0.5f, 0.5f, 0.99f);
+ if (model == MM_TRANSLATION_AND_SCALE)
+ return RansacParams(2, 0.5f, 0.5f, 0.99f);
+ if (model == MM_ROTATION)
+ return RansacParams(1, 0.5f, 0.5f, 0.99f);
+ if (model == MM_RIGID)
+ return RansacParams(2, 0.5f, 0.5f, 0.99f);
+ if (model == MM_SIMILARITY)
+ return RansacParams(2, 0.5f, 0.5f, 0.99f);
+ if (model == MM_AFFINE)
+ return RansacParams(3, 0.5f, 0.5f, 0.99f);
+ return RansacParams(4, 0.5f, 0.5f, 0.99f);
+ }
+};
+
+inline RansacParams::RansacParams(int _size, float _thresh, float _eps, float _prob)
+ : size(_size), thresh(_thresh), eps(_eps), prob(_prob) {}
+
+//! @}
+
+} // namespace videostab
+} // namespace cv
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/videostab/motion_stabilizing.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,174 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_VIDEOSTAB_MOTION_STABILIZING_HPP
+#define OPENCV_VIDEOSTAB_MOTION_STABILIZING_HPP
+
+#include <vector>
+#include <utility>
+#include "opencv2/core.hpp"
+#include "opencv2/videostab/global_motion.hpp"
+
+namespace cv
+{
+namespace videostab
+{
+
+//! @addtogroup videostab_motion
+//! @{
+
+class CV_EXPORTS IMotionStabilizer
+{
+public:
+ virtual ~IMotionStabilizer() {}
+
+ //! assumes that [0, size-1) is in or equals to [range.first, range.second)
+ virtual void stabilize(
+ int size, const std::vector<Mat> &motions, std::pair<int,int> range,
+ Mat *stabilizationMotions) = 0;
+};
+
+class CV_EXPORTS MotionStabilizationPipeline : public IMotionStabilizer
+{
+public:
+ void pushBack(Ptr<IMotionStabilizer> stabilizer) { stabilizers_.push_back(stabilizer); }
+ bool empty() const { return stabilizers_.empty(); }
+
+ virtual void stabilize(
+ int size, const std::vector<Mat> &motions, std::pair<int,int> range,
+ Mat *stabilizationMotions);
+
+private:
+ std::vector<Ptr<IMotionStabilizer> > stabilizers_;
+};
+
+class CV_EXPORTS MotionFilterBase : public IMotionStabilizer
+{
+public:
+ virtual ~MotionFilterBase() {}
+
+ virtual Mat stabilize(
+ int idx, const std::vector<Mat> &motions, std::pair<int,int> range) = 0;
+
+ virtual void stabilize(
+ int size, const std::vector<Mat> &motions, std::pair<int,int> range,
+ Mat *stabilizationMotions);
+};
+
+class CV_EXPORTS GaussianMotionFilter : public MotionFilterBase
+{
+public:
+ GaussianMotionFilter(int radius = 15, float stdev = -1.f);
+
+ void setParams(int radius, float stdev = -1.f);
+ int radius() const { return radius_; }
+ float stdev() const { return stdev_; }
+
+ virtual Mat stabilize(
+ int idx, const std::vector<Mat> &motions, std::pair<int,int> range);
+
+private:
+ int radius_;
+ float stdev_;
+ std::vector<float> weight_;
+};
+
+inline GaussianMotionFilter::GaussianMotionFilter(int _radius, float _stdev) { setParams(_radius, _stdev); }
+
+class CV_EXPORTS LpMotionStabilizer : public IMotionStabilizer
+{
+public:
+ LpMotionStabilizer(MotionModel model = MM_SIMILARITY);
+
+ void setMotionModel(MotionModel val) { model_ = val; }
+ MotionModel motionModel() const { return model_; }
+
+ void setFrameSize(Size val) { frameSize_ = val; }
+ Size frameSize() const { return frameSize_; }
+
+ void setTrimRatio(float val) { trimRatio_ = val; }
+ float trimRatio() const { return trimRatio_; }
+
+ void setWeight1(float val) { w1_ = val; }
+ float weight1() const { return w1_; }
+
+ void setWeight2(float val) { w2_ = val; }
+ float weight2() const { return w2_; }
+
+ void setWeight3(float val) { w3_ = val; }
+ float weight3() const { return w3_; }
+
+ void setWeight4(float val) { w4_ = val; }
+ float weight4() const { return w4_; }
+
+ virtual void stabilize(
+ int size, const std::vector<Mat> &motions, std::pair<int,int> range,
+ Mat *stabilizationMotions);
+
+private:
+ MotionModel model_;
+ Size frameSize_;
+ float trimRatio_;
+ float w1_, w2_, w3_, w4_;
+
+ std::vector<double> obj_, collb_, colub_;
+ std::vector<int> rows_, cols_;
+ std::vector<double> elems_, rowlb_, rowub_;
+
+ void set(int row, int col, double coef)
+ {
+ rows_.push_back(row);
+ cols_.push_back(col);
+ elems_.push_back(coef);
+ }
+};
+
+CV_EXPORTS Mat ensureInclusionConstraint(const Mat &M, Size size, float trimRatio);
+
+CV_EXPORTS float estimateOptimalTrimRatio(const Mat &M, Size size);
+
+//! @}
+
+} // namespace videostab
+} // namespace
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/videostab/optical_flow.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,150 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_VIDEOSTAB_OPTICAL_FLOW_HPP
+#define OPENCV_VIDEOSTAB_OPTICAL_FLOW_HPP
+
+#include "opencv2/core.hpp"
+#include "opencv2/opencv_modules.hpp"
+
+#ifdef HAVE_OPENCV_CUDAOPTFLOW
+ #include "opencv2/cudaoptflow.hpp"
+#endif
+
+namespace cv
+{
+namespace videostab
+{
+
+//! @addtogroup videostab
+//! @{
+
+class CV_EXPORTS ISparseOptFlowEstimator
+{
+public:
+ virtual ~ISparseOptFlowEstimator() {}
+ virtual void run(
+ InputArray frame0, InputArray frame1, InputArray points0, InputOutputArray points1,
+ OutputArray status, OutputArray errors) = 0;
+};
+
+class CV_EXPORTS IDenseOptFlowEstimator
+{
+public:
+ virtual ~IDenseOptFlowEstimator() {}
+ virtual void run(
+ InputArray frame0, InputArray frame1, InputOutputArray flowX, InputOutputArray flowY,
+ OutputArray errors) = 0;
+};
+
+class CV_EXPORTS PyrLkOptFlowEstimatorBase
+{
+public:
+ PyrLkOptFlowEstimatorBase() { setWinSize(Size(21, 21)); setMaxLevel(3); }
+
+ virtual void setWinSize(Size val) { winSize_ = val; }
+ virtual Size winSize() const { return winSize_; }
+
+ virtual void setMaxLevel(int val) { maxLevel_ = val; }
+ virtual int maxLevel() const { return maxLevel_; }
+ virtual ~PyrLkOptFlowEstimatorBase() {}
+
+protected:
+ Size winSize_;
+ int maxLevel_;
+};
+
+class CV_EXPORTS SparsePyrLkOptFlowEstimator
+ : public PyrLkOptFlowEstimatorBase, public ISparseOptFlowEstimator
+{
+public:
+ virtual void run(
+ InputArray frame0, InputArray frame1, InputArray points0, InputOutputArray points1,
+ OutputArray status, OutputArray errors);
+};
+
+#ifdef HAVE_OPENCV_CUDAOPTFLOW
+
+class CV_EXPORTS SparsePyrLkOptFlowEstimatorGpu
+ : public PyrLkOptFlowEstimatorBase, public ISparseOptFlowEstimator
+{
+public:
+ SparsePyrLkOptFlowEstimatorGpu();
+
+ virtual void run(
+ InputArray frame0, InputArray frame1, InputArray points0, InputOutputArray points1,
+ OutputArray status, OutputArray errors);
+
+ void run(const cuda::GpuMat &frame0, const cuda::GpuMat &frame1, const cuda::GpuMat &points0, cuda::GpuMat &points1,
+ cuda::GpuMat &status, cuda::GpuMat &errors);
+
+ void run(const cuda::GpuMat &frame0, const cuda::GpuMat &frame1, const cuda::GpuMat &points0, cuda::GpuMat &points1,
+ cuda::GpuMat &status);
+
+private:
+ Ptr<cuda::SparsePyrLKOpticalFlow> optFlowEstimator_;
+ cuda::GpuMat frame0_, frame1_, points0_, points1_, status_, errors_;
+};
+
+class CV_EXPORTS DensePyrLkOptFlowEstimatorGpu
+ : public PyrLkOptFlowEstimatorBase, public IDenseOptFlowEstimator
+{
+public:
+ DensePyrLkOptFlowEstimatorGpu();
+
+ virtual void run(
+ InputArray frame0, InputArray frame1, InputOutputArray flowX, InputOutputArray flowY,
+ OutputArray errors);
+
+private:
+ Ptr<cuda::DensePyrLKOpticalFlow> optFlowEstimator_;
+ cuda::GpuMat frame0_, frame1_, flowX_, flowY_, errors_;
+};
+
+#endif
+
+//! @}
+
+} // namespace videostab
+} // namespace cv
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/videostab/outlier_rejection.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,101 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_VIDEOSTAB_OUTLIER_REJECTION_HPP
+#define OPENCV_VIDEOSTAB_OUTLIER_REJECTION_HPP
+
+#include <vector>
+#include "opencv2/core.hpp"
+#include "opencv2/videostab/motion_core.hpp"
+
+namespace cv
+{
+namespace videostab
+{
+
+//! @addtogroup videostab
+//! @{
+
+class CV_EXPORTS IOutlierRejector
+{
+public:
+ virtual ~IOutlierRejector() {}
+
+ virtual void process(
+ Size frameSize, InputArray points0, InputArray points1, OutputArray mask) = 0;
+};
+
+class CV_EXPORTS NullOutlierRejector : public IOutlierRejector
+{
+public:
+ virtual void process(
+ Size frameSize, InputArray points0, InputArray points1, OutputArray mask);
+};
+
+class CV_EXPORTS TranslationBasedLocalOutlierRejector : public IOutlierRejector
+{
+public:
+ TranslationBasedLocalOutlierRejector();
+
+ void setCellSize(Size val) { cellSize_ = val; }
+ Size cellSize() const { return cellSize_; }
+
+ void setRansacParams(RansacParams val) { ransacParams_ = val; }
+ RansacParams ransacParams() const { return ransacParams_; }
+
+ virtual void process(
+ Size frameSize, InputArray points0, InputArray points1, OutputArray mask);
+
+private:
+ Size cellSize_;
+ RansacParams ransacParams_;
+
+ typedef std::vector<int> Cell;
+ std::vector<Cell> grid_;
+};
+
+//! @}
+
+} // namespace videostab
+} // namespace cv
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/videostab/ring_buffer.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,72 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_VIDEOSTAB_RING_BUFFER_HPP
+#define OPENCV_VIDEOSTAB_RING_BUFFER_HPP
+
+#include <vector>
+#include "opencv2/imgproc.hpp"
+
+namespace cv
+{
+namespace videostab
+{
+
+//! @addtogroup videostab
+//! @{
+
+template <typename T> inline T& at(int idx, std::vector<T> &items)
+{
+ return items[cv::borderInterpolate(idx, static_cast<int>(items.size()), cv::BORDER_WRAP)];
+}
+
+template <typename T> inline const T& at(int idx, const std::vector<T> &items)
+{
+ return items[cv::borderInterpolate(idx, static_cast<int>(items.size()), cv::BORDER_WRAP)];
+}
+
+//! @}
+
+} // namespace videostab
+} // namespace cv
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/videostab/stabilizer.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,200 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_VIDEOSTAB_STABILIZER_HPP
+#define OPENCV_VIDEOSTAB_STABILIZER_HPP
+
+#include <vector>
+#include <ctime>
+#include "opencv2/core.hpp"
+#include "opencv2/imgproc.hpp"
+#include "opencv2/videostab/global_motion.hpp"
+#include "opencv2/videostab/motion_stabilizing.hpp"
+#include "opencv2/videostab/frame_source.hpp"
+#include "opencv2/videostab/log.hpp"
+#include "opencv2/videostab/inpainting.hpp"
+#include "opencv2/videostab/deblurring.hpp"
+#include "opencv2/videostab/wobble_suppression.hpp"
+
+namespace cv
+{
+namespace videostab
+{
+
+//! @addtogroup videostab
+//! @{
+
+class CV_EXPORTS StabilizerBase
+{
+public:
+ virtual ~StabilizerBase() {}
+
+ void setLog(Ptr<ILog> ilog) { log_ = ilog; }
+ Ptr<ILog> log() const { return log_; }
+
+ void setRadius(int val) { radius_ = val; }
+ int radius() const { return radius_; }
+
+ void setFrameSource(Ptr<IFrameSource> val) { frameSource_ = val; }
+ Ptr<IFrameSource> frameSource() const { return frameSource_; }
+
+ void setMotionEstimator(Ptr<ImageMotionEstimatorBase> val) { motionEstimator_ = val; }
+ Ptr<ImageMotionEstimatorBase> motionEstimator() const { return motionEstimator_; }
+
+ void setDeblurer(Ptr<DeblurerBase> val) { deblurer_ = val; }
+ Ptr<DeblurerBase> deblurrer() const { return deblurer_; }
+
+ void setTrimRatio(float val) { trimRatio_ = val; }
+ float trimRatio() const { return trimRatio_; }
+
+ void setCorrectionForInclusion(bool val) { doCorrectionForInclusion_ = val; }
+ bool doCorrectionForInclusion() const { return doCorrectionForInclusion_; }
+
+ void setBorderMode(int val) { borderMode_ = val; }
+ int borderMode() const { return borderMode_; }
+
+ void setInpainter(Ptr<InpainterBase> val) { inpainter_ = val; }
+ Ptr<InpainterBase> inpainter() const { return inpainter_; }
+
+protected:
+ StabilizerBase();
+
+ void reset();
+ Mat nextStabilizedFrame();
+ bool doOneIteration();
+ virtual void setUp(const Mat &firstFrame);
+ virtual Mat estimateMotion() = 0;
+ virtual Mat estimateStabilizationMotion() = 0;
+ void stabilizeFrame();
+ virtual Mat postProcessFrame(const Mat &frame);
+ void logProcessingTime();
+
+ Ptr<ILog> log_;
+ Ptr<IFrameSource> frameSource_;
+ Ptr<ImageMotionEstimatorBase> motionEstimator_;
+ Ptr<DeblurerBase> deblurer_;
+ Ptr<InpainterBase> inpainter_;
+ int radius_;
+ float trimRatio_;
+ bool doCorrectionForInclusion_;
+ int borderMode_;
+
+ Size frameSize_;
+ Mat frameMask_;
+ int curPos_;
+ int curStabilizedPos_;
+ bool doDeblurring_;
+ Mat preProcessedFrame_;
+ bool doInpainting_;
+ Mat inpaintingMask_;
+ Mat finalFrame_;
+ std::vector<Mat> frames_;
+ std::vector<Mat> motions_; // motions_[i] is the motion from i-th to i+1-th frame
+ std::vector<float> blurrinessRates_;
+ std::vector<Mat> stabilizedFrames_;
+ std::vector<Mat> stabilizedMasks_;
+ std::vector<Mat> stabilizationMotions_;
+ clock_t processingStartTime_;
+};
+
+class CV_EXPORTS OnePassStabilizer : public StabilizerBase, public IFrameSource
+{
+public:
+ OnePassStabilizer();
+
+ void setMotionFilter(Ptr<MotionFilterBase> val) { motionFilter_ = val; }
+ Ptr<MotionFilterBase> motionFilter() const { return motionFilter_; }
+
+ virtual void reset();
+ virtual Mat nextFrame() { return nextStabilizedFrame(); }
+
+protected:
+ virtual void setUp(const Mat &firstFrame);
+ virtual Mat estimateMotion();
+ virtual Mat estimateStabilizationMotion();
+ virtual Mat postProcessFrame(const Mat &frame);
+
+ Ptr<MotionFilterBase> motionFilter_;
+};
+
+class CV_EXPORTS TwoPassStabilizer : public StabilizerBase, public IFrameSource
+{
+public:
+ TwoPassStabilizer();
+
+ void setMotionStabilizer(Ptr<IMotionStabilizer> val) { motionStabilizer_ = val; }
+ Ptr<IMotionStabilizer> motionStabilizer() const { return motionStabilizer_; }
+
+ void setWobbleSuppressor(Ptr<WobbleSuppressorBase> val) { wobbleSuppressor_ = val; }
+ Ptr<WobbleSuppressorBase> wobbleSuppressor() const { return wobbleSuppressor_; }
+
+ void setEstimateTrimRatio(bool val) { mustEstTrimRatio_ = val; }
+ bool mustEstimateTrimaRatio() const { return mustEstTrimRatio_; }
+
+ virtual void reset();
+ virtual Mat nextFrame();
+
+protected:
+ void runPrePassIfNecessary();
+
+ virtual void setUp(const Mat &firstFrame);
+ virtual Mat estimateMotion();
+ virtual Mat estimateStabilizationMotion();
+ virtual Mat postProcessFrame(const Mat &frame);
+
+ Ptr<IMotionStabilizer> motionStabilizer_;
+ Ptr<WobbleSuppressorBase> wobbleSuppressor_;
+ bool mustEstTrimRatio_;
+
+ int frameCount_;
+ bool isPrePassDone_;
+ bool doWobbleSuppression_;
+ std::vector<Mat> motions2_;
+ Mat suppressedFrame_;
+};
+
+//! @}
+
+} // namespace videostab
+} // namespace cv
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opencv2/videostab/wobble_suppression.hpp Fri Jan 29 04:53:38 2021 +0000
@@ -0,0 +1,140 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef OPENCV_VIDEOSTAB_WOBBLE_SUPPRESSION_HPP
+#define OPENCV_VIDEOSTAB_WOBBLE_SUPPRESSION_HPP
+
+#include <vector>
+#include "opencv2/core.hpp"
+#include "opencv2/core/cuda.hpp"
+#include "opencv2/videostab/global_motion.hpp"
+#include "opencv2/videostab/log.hpp"
+
+namespace cv
+{
+namespace videostab
+{
+
+//! @addtogroup videostab
+//! @{
+
+class CV_EXPORTS WobbleSuppressorBase
+{
+public:
+ WobbleSuppressorBase();
+
+ virtual ~WobbleSuppressorBase() {}
+
+ void setMotionEstimator(Ptr<ImageMotionEstimatorBase> val) { motionEstimator_ = val; }
+ Ptr<ImageMotionEstimatorBase> motionEstimator() const { return motionEstimator_; }
+
+ virtual void suppress(int idx, const Mat &frame, Mat &result) = 0;
+
+
+ // data from stabilizer
+
+ virtual void setFrameCount(int val) { frameCount_ = val; }
+ virtual int frameCount() const { return frameCount_; }
+
+ virtual void setMotions(const std::vector<Mat> &val) { motions_ = &val; }
+ virtual const std::vector<Mat>& motions() const { return *motions_; }
+
+ virtual void setMotions2(const std::vector<Mat> &val) { motions2_ = &val; }
+ virtual const std::vector<Mat>& motions2() const { return *motions2_; }
+
+ virtual void setStabilizationMotions(const std::vector<Mat> &val) { stabilizationMotions_ = &val; }
+ virtual const std::vector<Mat>& stabilizationMotions() const { return *stabilizationMotions_; }
+
+protected:
+ Ptr<ImageMotionEstimatorBase> motionEstimator_;
+ int frameCount_;
+ const std::vector<Mat> *motions_;
+ const std::vector<Mat> *motions2_;
+ const std::vector<Mat> *stabilizationMotions_;
+};
+
+class CV_EXPORTS NullWobbleSuppressor : public WobbleSuppressorBase
+{
+public:
+ virtual void suppress(int idx, const Mat &frame, Mat &result);
+};
+
+class CV_EXPORTS MoreAccurateMotionWobbleSuppressorBase : public WobbleSuppressorBase
+{
+public:
+ virtual void setPeriod(int val) { period_ = val; }
+ virtual int period() const { return period_; }
+
+protected:
+ MoreAccurateMotionWobbleSuppressorBase() { setPeriod(30); }
+
+ int period_;
+};
+
+class CV_EXPORTS MoreAccurateMotionWobbleSuppressor : public MoreAccurateMotionWobbleSuppressorBase
+{
+public:
+ virtual void suppress(int idx, const Mat &frame, Mat &result);
+
+private:
+ Mat_<float> mapx_, mapy_;
+};
+
+#if defined(HAVE_OPENCV_CUDAWARPING)
+class CV_EXPORTS MoreAccurateMotionWobbleSuppressorGpu : public MoreAccurateMotionWobbleSuppressorBase
+{
+public:
+ void suppress(int idx, const cuda::GpuMat &frame, cuda::GpuMat &result);
+ virtual void suppress(int idx, const Mat &frame, Mat &result);
+
+private:
+ cuda::GpuMat frameDevice_, resultDevice_;
+ cuda::GpuMat mapx_, mapy_;
+};
+#endif
+
+//! @}
+
+} // namespace videostab
+} // namespace cv
+
+#endif
Binary file lib/TOOLCHAIN_GCC_ARM/libopencv_calib3d320.a has changed
Binary file lib/TOOLCHAIN_GCC_ARM/libopencv_core320.a has changed
Binary file lib/TOOLCHAIN_GCC_ARM/libopencv_features2d320.a has changed
Binary file lib/TOOLCHAIN_GCC_ARM/libopencv_flann320.a has changed
Binary file lib/TOOLCHAIN_GCC_ARM/libopencv_imgcodecs320.a has changed
Binary file lib/TOOLCHAIN_GCC_ARM/libopencv_imgproc320.a has changed
Binary file lib/TOOLCHAIN_GCC_ARM/libopencv_ml320.a has changed
Binary file lib/TOOLCHAIN_GCC_ARM/libopencv_objdetect320.a has changed
Binary file lib/TOOLCHAIN_GCC_ARM/libopencv_photo320.a has changed
Binary file lib/TOOLCHAIN_GCC_ARM/libopencv_shape320.a has changed
Binary file lib/TOOLCHAIN_GCC_ARM/libopencv_stitching320.a has changed
Binary file lib/TOOLCHAIN_GCC_ARM/libopencv_superres320.a has changed
Binary file lib/TOOLCHAIN_GCC_ARM/libopencv_video320.a has changed
Binary file lib/TOOLCHAIN_GCC_ARM/libopencv_videostab320.a has changed