1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-29 15:23:05 +04:00

Merge pull request #29230 from asmorkalov:as/move_undistort

Inverted imgproc-geometry dependency and moved more functions to geometry #29230

Fixes: https://github.com/opencv/opencv/issues/20267
Continues: https://github.com/opencv/opencv/pull/29175

OpenCV Contrib: https://github.com/opencv/opencv_contrib/pull/4137
OpenCV Extra: https://github.com/opencv/opencv_extra/pull/1377

Summary:
- LSD returned back to imgproc
- drawing functions moved to imgproc
- undistort image and related perf-pixel functions moved to imgproc
- moments moved to geometry
- estimateXXXtransform moved to geometry

After the patch the geometry module depends on code and Flann and may be used everywhere without potential circular dependencies

### Pull Request Readiness Checklist

See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request

- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [ ] The PR is proposed to the proper branch
- [ ] There is a reference to the original bug report and related work
- [ ] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
      Patch to opencv_extra has the same branch name.
- [ ] The feature is well documented and sample code can be built with the project CMake
This commit is contained in:
Alexander Smorkalov
2026-06-05 10:13:45 +03:00
committed by GitHub
parent ada32973b4
commit 40ddc700aa
58 changed files with 2021 additions and 1612 deletions
+1 -3
View File
@@ -1,12 +1,10 @@
set(the_description "Computational geometry primitives")
ocv_add_dispatched_file(undistort SSE2 AVX2)
set(debug_modules "")
if(DEBUG_opencv_geometry)
list(APPEND debug_modules opencv_highgui)
endif()
ocv_define_module(geometry opencv_imgproc opencv_flann ${debug_modules}
ocv_define_module(geometry opencv_flann ${debug_modules}
WRAP java objc python js
)
ocv_target_link_libraries(${the_module} ${LAPACK_LIBRARIES})
+148 -90
View File
@@ -20,12 +20,17 @@ enum RectanglesIntersectTypes {
INTERSECT_FULL = 2 //!< One of the rectangle is fully enclosed in the other
};
//! Variants of Line Segment %Detector
enum LineSegmentDetectorModes {
LSD_REFINE_NONE = 0, //!< No refinement applied
LSD_REFINE_STD = 1, //!< Standard refinement is applied. E.g. breaking arches into smaller straighter line approximations.
LSD_REFINE_ADV = 2 //!< Advanced refinement. Number of false alarms is calculated, lines are
//!< refined through increase of precision, decrement in size, etc.
//! Distance types for Distance Transform and M-estimators
//! @see distanceTransform, fitLine
enum DistanceTypes {
DIST_USER = -1, //!< User defined distance
DIST_L1 = 1, //!< distance = |x1-x2| + |y1-y2|
DIST_L2 = 2, //!< the simple euclidean distance
DIST_C = 3, //!< distance = max(|x1-x2|,|y1-y2|)
DIST_L12 = 4, //!< L1-L2 metric: distance = 2(sqrt(1+x*x/2) - 1))
DIST_FAIR = 5, //!< distance = c^2(|x|/c-log(1+|x|/c)), c = 1.3998
DIST_WELSCH = 6, //!< distance = c^2/2(1-exp(-(x/c)^2)), c = 2.9846
DIST_HUBER = 7 //!< distance = |x|<c ? x^2/2 : c(|x|-c/2), c=1.345
};
//! @addtogroup geometry_subdiv2d
@@ -306,90 +311,6 @@ protected:
//! @} geometry_subdiv2d
//! @addtogroup geometry_feature
//! @{
/** @example samples/cpp/snippets/lsd_lines.cpp
An example using the LineSegmentDetector
\image html building_lsd.png "Sample output image" width=434 height=300
*/
/** @brief Line segment detector class
following the algorithm described at @cite Rafael12 .
@note Implementation has been removed from OpenCV version 3.4.6 to 3.4.15 and version 4.1.0 to 4.5.3 due original code license conflict.
restored again after [Computation of a NFA](https://github.com/rafael-grompone-von-gioi/binomial_nfa) code published under the MIT license.
*/
class CV_EXPORTS_W LineSegmentDetector : public Algorithm
{
public:
/** @brief Finds lines in the input image.
This is the output of the default parameters of the algorithm on the above shown image.
![image](pics/building_lsd.png)
@param image A grayscale (CV_8UC1) input image. If only a roi needs to be selected, use:
`lsd_ptr-\>detect(image(roi), lines, ...); lines += Scalar(roi.x, roi.y, roi.x, roi.y);`
@param lines A vector of Vec4f elements specifying the beginning and ending point of a line. Where
Vec4f is (x1, y1, x2, y2), point 1 is the start, point 2 - end. Returned lines are strictly
oriented depending on the gradient.
@param width Vector of widths of the regions, where the lines are found. E.g. Width of line.
@param prec Vector of precisions with which the lines are found.
@param nfa Vector containing number of false alarms in the line region, with precision of 10%. The
bigger the value, logarithmically better the detection.
- -1 corresponds to 10 mean false alarms
- 0 corresponds to 1 mean false alarm
- 1 corresponds to 0.1 mean false alarms
This vector will be calculated only when the objects type is #LSD_REFINE_ADV.
*/
CV_WRAP virtual void detect(InputArray image, OutputArray lines,
OutputArray width = noArray(), OutputArray prec = noArray(),
OutputArray nfa = noArray()) = 0;
/** @brief Draws the line segments on a given image.
@param image The image, where the lines will be drawn. Should be bigger or equal to the image,
where the lines were found.
@param lines A vector of the lines that needed to be drawn.
*/
CV_WRAP virtual void drawSegments(InputOutputArray image, InputArray lines) = 0;
/** @brief Draws two groups of lines in blue and red, counting the non overlapping (mismatching) pixels.
@param size The size of the image, where lines1 and lines2 were found.
@param lines1 The first group of lines that needs to be drawn. It is visualized in blue color.
@param lines2 The second group of lines. They visualized in red color.
@param image Optional image, where the lines will be drawn. The image should be color(3-channel)
in order for lines1 and lines2 to be drawn in the above mentioned colors.
*/
CV_WRAP virtual int compareSegments(const Size& size, InputArray lines1, InputArray lines2, InputOutputArray image = noArray()) = 0;
virtual ~LineSegmentDetector() { }
};
/** @brief Creates a smart pointer to a LineSegmentDetector object and initializes it.
The LineSegmentDetector algorithm is defined using the standard values. Only advanced users may want
to edit those, as to tailor it for their own application.
@param refine The way found lines will be refined, see #LineSegmentDetectorModes
@param scale The scale of the image that will be used to find the lines. Range (0..1].
@param sigma_scale Sigma for Gaussian filter. It is computed as sigma = sigma_scale/scale.
@param quant Bound to the quantization error on the gradient norm.
@param ang_th Gradient angle tolerance in degrees.
@param log_eps Detection threshold: -log10(NFA) \> log_eps. Used only when advance refinement is chosen.
@param density_th Minimal density of aligned region points in the enclosing rectangle.
@param n_bins Number of bins in pseudo-ordering of gradient modulus.
*/
CV_EXPORTS_W Ptr<LineSegmentDetector> createLineSegmentDetector(
LineSegmentDetectorModes refine = LSD_REFINE_STD, double scale = 0.8,
double sigma_scale = 0.6, double quant = 2.0, double ang_th = 22.5,
double log_eps = 0, double density_th = 0.7, int n_bins = 1024);
//! @} geometry_feature
/** @example samples/python/snippets/squares.py
A n example using approxPolyDP function in python. *
*/
@@ -517,6 +438,59 @@ CV_EXPORTS_W double minEnclosingTriangle( InputArray points, CV_OUT OutputArray
CV_EXPORTS_W double minEnclosingConvexPolygon ( InputArray points, OutputArray polygon, int k );
/** @brief Calculates all of the moments up to the third order of a polygon or rasterized shape.
*
* The function computes moments, up to the 3rd order, of a vector shape or a rasterized shape. The
* results are returned in the structure cv::Moments.
*
* @param array Single channel raster image (CV_8U, CV_16U, CV_16S, CV_32F, CV_64F) or an array (
* \f$1 \times N\f$ or \f$N \times 1\f$ ) of 2D points (Point or Point2f).
* @param binaryImage If it is true, all non-zero image pixels are treated as 1's. The parameter is
* used for images only.
* @returns moments.
*
* @note Only applicable to contour moments calculations from Python bindings: Note that the numpy
* type for the input array should be either np.int32 or np.float32.
*
* @note For contour-based moments, the zeroth-order moment \c m00 represents
* the contour area.
*
* If the input contour is degenerate (for example, a single point or all points
* are collinear), the area is zero and therefore \c m00 == 0.
*
* In this case, the centroid coordinates (\c m10/m00, \c m01/m00) are undefined
* and must be handled explicitly by the caller.
*
* A common workaround is to compute the center using cv::boundingRect() or by
* averaging the input points.
*
* @sa contourArea, arcLength
*/
CV_EXPORTS_W Moments moments( InputArray array, bool binaryImage = false );
/** @brief Calculates seven Hu invariants.
*
* The function calculates seven Hu invariants (introduced in @cite Hu62; see also
* <https://en.wikipedia.org/wiki/Image_moment>) defined as:
*
* \f[\begin{array}{l} hu[0]= \eta _{20}+ \eta _{02} \\ hu[1]=( \eta _{20}- \eta _{02})^{2}+4 \eta _{11}^{2} \\ hu[2]=( \eta _{30}-3 \eta _{12})^{2}+ (3 \eta _{21}- \eta _{03})^{2} \\ hu[3]=( \eta _{30}+ \eta _{12})^{2}+ ( \eta _{21}+ \eta _{03})^{2} \\ hu[4]=( \eta _{30}-3 \eta _{12})( \eta _{30}+ \eta _{12})[( \eta _{30}+ \eta _{12})^{2}-3( \eta _{21}+ \eta _{03})^{2}]+(3 \eta _{21}- \eta _{03})( \eta _{21}+ \eta _{03})[3( \eta _{30}+ \eta _{12})^{2}-( \eta _{21}+ \eta _{03})^{2}] \\ hu[5]=( \eta _{20}- \eta _{02})[( \eta _{30}+ \eta _{12})^{2}- ( \eta _{21}+ \eta _{03})^{2}]+4 \eta _{11}( \eta _{30}+ \eta _{12})( \eta _{21}+ \eta _{03}) \\ hu[6]=(3 \eta _{21}- \eta _{03})( \eta _{21}+ \eta _{03})[3( \eta _{30}+ \eta _{12})^{2}-( \eta _{21}+ \eta _{03})^{2}]-( \eta _{30}-3 \eta _{12})( \eta _{21}+ \eta _{03})[3( \eta _{30}+ \eta _{12})^{2}-( \eta _{21}+ \eta _{03})^{2}] \\ \end{array}\f]
*
* where \f$\eta_{ji}\f$ stands for \f$\texttt{Moments::nu}_{ji}\f$ .
*
* These values are proved to be invariants to the image scale, rotation, and reflection except the
* seventh one, whose sign is changed by reflection. This invariance is proved with the assumption of
* infinite image resolution. In case of raster images, the computed Hu invariants for the original and
* transformed images are a bit different.
*
* @param moments Input moments computed with moments .
* @param hu Output Hu invariants.
*
* @sa matchShapes
*/
CV_EXPORTS void HuMoments( const Moments& moments, double hu[7] );
/** @overload */
CV_EXPORTS_W void HuMoments( const Moments& m, OutputArray hu );
/** @brief Compares two shapes.
*
@@ -856,6 +830,90 @@ CV_EXPORTS_W double contourArea( InputArray contour, bool oriented = false );
*/
CV_EXPORTS_W Rect boundingRect( InputArray array );
/** @brief Calculates an affine matrix of 2D rotation.
The function calculates the following matrix:
\f[\begin{bmatrix} \alpha & \beta & (1- \alpha ) \cdot \texttt{center.x} - \beta \cdot \texttt{center.y} \\ - \beta & \alpha & \beta \cdot \texttt{center.x} + (1- \alpha ) \cdot \texttt{center.y} \end{bmatrix}\f]
where
\f[\begin{array}{l} \alpha = \texttt{scale} \cdot \cos \texttt{angle} , \\ \beta = \texttt{scale} \cdot \sin \texttt{angle} \end{array}\f]
The transformation maps the rotation center to itself. If this is not the target, adjust the shift.
@param center Center of the rotation in the source image.
@param angle Rotation angle in degrees. Positive values mean counter-clockwise rotation (the
coordinate origin is assumed to be the top-left corner).
@param scale Isotropic scale factor.
@sa getAffineTransform, warpAffine, transform
*/
CV_EXPORTS_W Mat getRotationMatrix2D(Point2f center, double angle, double scale);
/** @sa getRotationMatrix2D */
CV_EXPORTS Matx23d getRotationMatrix2D_(Point2f center, double angle, double scale);
inline
Mat getRotationMatrix2D(Point2f center, double angle, double scale)
{
return Mat(getRotationMatrix2D_(center, angle, scale), true);
}
/** @brief Calculates an affine transform from three pairs of the corresponding points.
*
* The function calculates the \f$2 \times 3\f$ matrix of an affine transform so that:
*
* \f[\begin{bmatrix} x'_i \\ y'_i \end{bmatrix} = \texttt{map_matrix} \cdot \begin{bmatrix} x_i \\ y_i \\ 1 \end{bmatrix}\f]
*
* where
*
* \f[dst(i)=(x'_i,y'_i), src(i)=(x_i, y_i), i=0,1,2\f]
*
* @param src Coordinates of triangle vertices in the source image.
* @param dst Coordinates of the corresponding triangle vertices in the destination image.
*
* @sa warpAffine, transform
*/
CV_EXPORTS Mat getAffineTransform( const Point2f src[], const Point2f dst[] );
/** @brief Inverts an affine transformation.
*
* The function computes an inverse affine transformation represented by \f$2 \times 3\f$ matrix M:
*
* \f[\begin{bmatrix} a_{11} & a_{12} & b_1 \\ a_{21} & a_{22} & b_2 \end{bmatrix}\f]
*
* The result is also a \f$2 \times 3\f$ matrix of the same type as M.
*
* @param M Original affine transformation.
* @param iM Output reverse affine transformation.
*/
CV_EXPORTS_W void invertAffineTransform( InputArray M, OutputArray iM );
/** @brief Calculates a perspective transform from four pairs of the corresponding points.
*
* The function calculates the \f$3 \times 3\f$ matrix of a perspective transform so that:
*
* \f[\begin{bmatrix} t_i x'_i \\ t_i y'_i \\ t_i \end{bmatrix} = \texttt{map_matrix} \cdot \begin{bmatrix} x_i \\ y_i \\ 1 \end{bmatrix}\f]
*
* where
*
* \f[dst(i)=(x'_i,y'_i), src(i)=(x_i, y_i), i=0,1,2,3\f]
*
* @param src Coordinates of quadrangle vertices in the source image.
* @param dst Coordinates of the corresponding quadrangle vertices in the destination image.
* @param solveMethod method passed to cv::solve (#DecompTypes)
*
* @sa findHomography, warpPerspective, perspectiveTransform
*/
CV_EXPORTS_W Mat getPerspectiveTransform(InputArray src, InputArray dst, int solveMethod = DECOMP_LU);
/** @overload */
CV_EXPORTS Mat getPerspectiveTransform(const Point2f src[], const Point2f dst[], int solveMethod = DECOMP_LU);
CV_EXPORTS_W Mat getAffineTransform( InputArray src, InputArray dst );
} // namespace cv
#endif // OPENCV_2D_HPP
@@ -1280,25 +1280,6 @@ CV_EXPORTS_W int solvePnPGeneric( InputArray objectPoints, InputArray imagePoint
InputArray rvec = noArray(), InputArray tvec = noArray(),
OutputArray reprojectionError = noArray() );
/** @brief Draw axes of the world/object coordinate system from pose estimation. @sa solvePnP
@param image Input/output image. It must have 1 or 3 channels. The number of channels is not altered.
@param cameraMatrix Input 3x3 floating-point matrix of camera intrinsic parameters.
\f$\cameramatrix{A}\f$
@param distCoeffs Input vector of distortion coefficients
\f$\distcoeffs\f$. If the vector is empty, the zero distortion coefficients are assumed.
@param rvec Rotation vector (see @ref Rodrigues ) that, together with tvec, brings points from
the model coordinate system to the camera coordinate system.
@param tvec Translation vector.
@param length Length of the painted axes in the same unit than tvec (usually in meters).
@param thickness Line thickness of the painted axes.
This function draws the axes of the world/object coordinate system w.r.t. to the camera frame.
OX is drawn in red, OY in green and OZ in blue.
*/
CV_EXPORTS_W void drawFrameAxes(InputOutputArray image, InputArray cameraMatrix, InputArray distCoeffs,
InputArray rvec, InputArray tvec, float length, int thickness=3);
/** @brief Converts points from Euclidean to homogeneous space.
@param src Input vector of N-dimensional points.
@@ -2216,201 +2197,6 @@ CV_EXPORTS_W void filterHomographyDecompByVisibleRefpoints(InputArrayOfArrays ro
OutputArray possibleSolutions,
InputArray pointsMask = noArray());
//! cv::undistort mode
enum UndistortTypes
{
PROJ_SPHERICAL_ORTHO = 0,
PROJ_SPHERICAL_EQRECT = 1
};
/** @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 #initUndistortRectifyMap (with unity R ) and #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 #getOptimalNewCameraMatrix to compute the appropriate
newCameraMatrix depending on your requirements.
The camera matrix and the distortion parameters can be determined using #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
#getOptimalNewCameraMatrix for a better control over scaling. In case of a stereo camera,
newCameraMatrix is normally set to P1 or P2 computed by #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 #stereoCalibrate. But if the stereo camera
was not calibrated, it is still possible to compute the rectification transformations directly from
the fundamental matrix using #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 #initUndistortRectifyMap 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, CV_32FC2 or CV_16SC2, see #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);
/** @brief Computes the projection and inverse-rectification transformation map. In essense, this is the inverse of
#initUndistortRectifyMap to accomodate stereo-rectification of projectors ('inverse-cameras') in projector-camera pairs.
The function computes the joint projection and inverse rectification transformation and represents the
result in the form of maps for #remap. The projected image looks like a distorted version of the original which,
once projected by a projector, should visually match the original. In case of a monocular camera, newCameraMatrix
is usually equal to cameraMatrix, or it can be computed by
#getOptimalNewCameraMatrix for a better control over scaling. In case of a projector-camera pair,
newCameraMatrix is normally set to P1 or P2 computed by #stereoRectify .
The projector is oriented differently in the coordinate space, according to R. In case of projector-camera pairs,
this helps align the projector (in the same manner as #initUndistortRectifyMap for the camera) to create a stereo-rectified pair. This
allows epipolar lines on both images to become horizontal and have the same y-coordinate (in case of a horizontally aligned projector-camera pair).
The function 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 (projected and inverse-rectified) image, the function
computes the corresponding coordinates in the source image (that is, in the original digital image). The following process is applied:
\f[
\begin{array}{l}
\text{newCameraMatrix}\\
x \leftarrow (u - {c'}_x)/{f'}_x \\
y \leftarrow (v - {c'}_y)/{f'}_y \\
\\\text{Undistortion}
\\\scriptsize{\textit{though equation shown is for radial undistortion, function implements cv::undistortPoints()}}\\
r^2 \leftarrow x^2 + y^2 \\
\theta \leftarrow \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}\\
x' \leftarrow \frac{x}{\theta} \\
y' \leftarrow \frac{y}{\theta} \\
\\\text{Rectification}\\
{[X\,Y\,W]} ^T \leftarrow R*[x' \, y' \, 1]^T \\
x'' \leftarrow X/W \\
y'' \leftarrow Y/W \\
\\\text{cameraMatrix}\\
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 vector distCoeffs.
In case of a stereo-rectified projector-camera pair, this function is called for the projector while #initUndistortRectifyMap is called for the camera head.
This is done after #stereoRectify, which in turn is called after #stereoCalibrate. If the projector-camera pair
is not calibrated, it is still possible to compute the rectification transformations directly from
the fundamental matrix using #stereoRectifyUncalibrated. For the projector and 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.
@param newCameraMatrix New camera matrix \f$A'=\vecthreethree{f_x'}{0}{c_x'}{0}{f_y'}{c_y'}{0}{0}{1}\f$.
@param size Distorted image size.
@param m1type Type of the first output map. Can be CV_32FC1, CV_32FC2 or CV_16SC2, see #convertMaps
@param map1 The first output map for #remap.
@param map2 The second output map for #remap.
*/
CV_EXPORTS_W
void initInverseRectificationMap( InputArray cameraMatrix, InputArray distCoeffs,
InputArray R, InputArray newCameraMatrix,
const Size& size, int m1type, OutputArray map1, OutputArray map2 );
//! initializes maps for #remap for wide-angle
CV_EXPORTS
float initWideAngleProjMap(InputArray cameraMatrix, InputArray distCoeffs,
Size imageSize, int destImageWidth,
int m1type, OutputArray map1, OutputArray map2,
enum UndistortTypes projType = PROJ_SPHERICAL_EQRECT, double alpha = 0);
static inline
float initWideAngleProjMap(InputArray cameraMatrix, InputArray distCoeffs,
Size imageSize, int destImageWidth,
int m1type, OutputArray map1, OutputArray map2,
int projType, double alpha = 0)
{
return initWideAngleProjMap(cameraMatrix, distCoeffs, imageSize, destImageWidth,
m1type, map1, map2, (UndistortTypes)projType, alpha);
}
/** @brief Computes useful camera characteristics from the camera intrinsic matrix.
*
* @param cameraMatrix Input camera intrinsic matrix that can be estimated by #calibrateCamera or
@@ -2701,55 +2487,6 @@ length. Balance is in range of [0, 1].
*/
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 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 intrinsic matrix \f$cameramatrix{K}\f$.
@param D Input vector of distortion coefficients \f$\distcoeffsfisheye\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 intrinsic 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 intrinsic matrix \f$cameramatrix{K}\f$.
@param D Input vector of distortion coefficients \f$\distcoeffsfisheye\f$.
@param Knew Camera intrinsic 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 new size
The function transforms an image to compensate radial and tangential lens distortion.
The function is simply a combination of #cv::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 #cv::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.
![image](pics/fisheye_undistorted.jpg)
*/
CV_EXPORTS_W void undistortImage(InputArray distorted, OutputArray undistorted,
InputArray K, InputArray D, InputArray Knew = cv::noArray(), const Size& new_size = Size());
/**
@brief Finds an object pose from 3D-2D point correspondences for fisheye camera model.
+20 -1
View File
@@ -17,6 +17,25 @@
"dst" : {"ctype" : "vector_Point2f"} },
"projectPoints" : { "objectPoints" : {"ctype" : "vector_Point3f"},
"imagePoints" : {"ctype" : "vector_Point2f"},
"distCoeffs" : {"ctype" : "vector_double" } }
"distCoeffs" : {"ctype" : "vector_double" } },
"minEnclosingCircle" : { "points" : {"ctype" : "vector_Point2f"} },
"fitEllipse" : { "points" : {"ctype" : "vector_Point2f"} },
"fillPoly" : { "pts" : {"ctype" : "vector_vector_Point"} },
"polylines" : { "pts" : {"ctype" : "vector_vector_Point"} },
"fillConvexPoly" : { "points" : {"ctype" : "vector_Point"} },
"approxPolyDP" : { "curve" : {"ctype" : "vector_Point2f"},
"approxCurve" : {"ctype" : "vector_Point2f"} },
"arcLength" : { "curve" : {"ctype" : "vector_Point2f"} },
"pointPolygonTest" : { "contour" : {"ctype" : "vector_Point2f"} },
"minAreaRect" : { "points" : {"ctype" : "vector_Point2f"} },
"getAffineTransform" : { "src" : {"ctype" : "vector_Point2f"},
"dst" : {"ctype" : "vector_Point2f"} },
"convexityDefects" : { "contour" : {"ctype" : "vector_Point"},
"convexhull" : {"ctype" : "vector_int"},
"convexityDefects" : {"ctype" : "vector_Vec4i"} },
"isContourConvex" : { "contour" : {"ctype" : "vector_Point"} },
"convexHull" : { "points" : {"ctype" : "vector_Point"},
"hull" : {"ctype" : "vector_int"},
"returnPoints" : {"ctype" : ""} }
}
}
@@ -0,0 +1,242 @@
package org.opencv.geometry;
//javadoc:Moments
public class Moments {
public double m00;
public double m10;
public double m01;
public double m20;
public double m11;
public double m02;
public double m30;
public double m21;
public double m12;
public double m03;
public double mu20;
public double mu11;
public double mu02;
public double mu30;
public double mu21;
public double mu12;
public double mu03;
public double nu20;
public double nu11;
public double nu02;
public double nu30;
public double nu21;
public double nu12;
public double nu03;
public Moments(
double m00,
double m10,
double m01,
double m20,
double m11,
double m02,
double m30,
double m21,
double m12,
double m03)
{
this.m00 = m00;
this.m10 = m10;
this.m01 = m01;
this.m20 = m20;
this.m11 = m11;
this.m02 = m02;
this.m30 = m30;
this.m21 = m21;
this.m12 = m12;
this.m03 = m03;
this.completeState();
}
public Moments() {
this(0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
}
public Moments(double[] vals) {
set(vals);
}
public void set(double[] vals) {
if (vals != null) {
m00 = vals.length > 0 ? vals[0] : 0;
m10 = vals.length > 1 ? vals[1] : 0;
m01 = vals.length > 2 ? vals[2] : 0;
m20 = vals.length > 3 ? vals[3] : 0;
m11 = vals.length > 4 ? vals[4] : 0;
m02 = vals.length > 5 ? vals[5] : 0;
m30 = vals.length > 6 ? vals[6] : 0;
m21 = vals.length > 7 ? vals[7] : 0;
m12 = vals.length > 8 ? vals[8] : 0;
m03 = vals.length > 9 ? vals[9] : 0;
this.completeState();
} else {
m00 = 0;
m10 = 0;
m01 = 0;
m20 = 0;
m11 = 0;
m02 = 0;
m30 = 0;
m21 = 0;
m12 = 0;
m03 = 0;
mu20 = 0;
mu11 = 0;
mu02 = 0;
mu30 = 0;
mu21 = 0;
mu12 = 0;
mu03 = 0;
nu20 = 0;
nu11 = 0;
nu02 = 0;
nu30 = 0;
nu21 = 0;
nu12 = 0;
nu03 = 0;
}
}
@Override
public String toString() {
return "Moments [ " +
"\n" +
"m00=" + m00 + ", " +
"\n" +
"m10=" + m10 + ", " +
"m01=" + m01 + ", " +
"\n" +
"m20=" + m20 + ", " +
"m11=" + m11 + ", " +
"m02=" + m02 + ", " +
"\n" +
"m30=" + m30 + ", " +
"m21=" + m21 + ", " +
"m12=" + m12 + ", " +
"m03=" + m03 + ", " +
"\n" +
"mu20=" + mu20 + ", " +
"mu11=" + mu11 + ", " +
"mu02=" + mu02 + ", " +
"\n" +
"mu30=" + mu30 + ", " +
"mu21=" + mu21 + ", " +
"mu12=" + mu12 + ", " +
"mu03=" + mu03 + ", " +
"\n" +
"nu20=" + nu20 + ", " +
"nu11=" + nu11 + ", " +
"nu02=" + nu02 + ", " +
"\n" +
"nu30=" + nu30 + ", " +
"nu21=" + nu21 + ", " +
"nu12=" + nu12 + ", " +
"nu03=" + nu03 + ", " +
"\n]";
}
protected void completeState()
{
double cx = 0, cy = 0;
double mu20, mu11, mu02;
double inv_m00 = 0.0;
if( Math.abs(this.m00) > 0.00000001 )
{
inv_m00 = 1. / this.m00;
cx = this.m10 * inv_m00;
cy = this.m01 * inv_m00;
}
// mu20 = m20 - m10*cx
mu20 = this.m20 - this.m10 * cx;
// mu11 = m11 - m10*cy
mu11 = this.m11 - this.m10 * cy;
// mu02 = m02 - m01*cy
mu02 = this.m02 - this.m01 * cy;
this.mu20 = mu20;
this.mu11 = mu11;
this.mu02 = mu02;
// mu30 = m30 - cx*(3*mu20 + cx*m10)
this.mu30 = this.m30 - cx * (3 * mu20 + cx * this.m10);
mu11 += mu11;
// mu21 = m21 - cx*(2*mu11 + cx*m01) - cy*mu20
this.mu21 = this.m21 - cx * (mu11 + cx * this.m01) - cy * mu20;
// mu12 = m12 - cy*(2*mu11 + cy*m10) - cx*mu02
this.mu12 = this.m12 - cy * (mu11 + cy * this.m10) - cx * mu02;
// mu03 = m03 - cy*(3*mu02 + cy*m01)
this.mu03 = this.m03 - cy * (3 * mu02 + cy * this.m01);
double inv_sqrt_m00 = Math.sqrt(Math.abs(inv_m00));
double s2 = inv_m00*inv_m00, s3 = s2*inv_sqrt_m00;
this.nu20 = this.mu20*s2;
this.nu11 = this.mu11*s2;
this.nu02 = this.mu02*s2;
this.nu30 = this.mu30*s3;
this.nu21 = this.mu21*s3;
this.nu12 = this.mu12*s3;
this.nu03 = this.mu03*s3;
}
public double get_m00() { return this.m00; }
public double get_m10() { return this.m10; }
public double get_m01() { return this.m01; }
public double get_m20() { return this.m20; }
public double get_m11() { return this.m11; }
public double get_m02() { return this.m02; }
public double get_m30() { return this.m30; }
public double get_m21() { return this.m21; }
public double get_m12() { return this.m12; }
public double get_m03() { return this.m03; }
public double get_mu20() { return this.mu20; }
public double get_mu11() { return this.mu11; }
public double get_mu02() { return this.mu02; }
public double get_mu30() { return this.mu30; }
public double get_mu21() { return this.mu21; }
public double get_mu12() { return this.mu12; }
public double get_mu03() { return this.mu03; }
public double get_nu20() { return this.nu20; }
public double get_nu11() { return this.nu11; }
public double get_nu02() { return this.nu02; }
public double get_nu30() { return this.nu30; }
public double get_nu21() { return this.nu21; }
public double get_nu12() { return this.nu12; }
public double get_nu03() { return this.nu03; }
public void set_m00(double m00) { this.m00 = m00; }
public void set_m10(double m10) { this.m10 = m10; }
public void set_m01(double m01) { this.m01 = m01; }
public void set_m20(double m20) { this.m20 = m20; }
public void set_m11(double m11) { this.m11 = m11; }
public void set_m02(double m02) { this.m02 = m02; }
public void set_m30(double m30) { this.m30 = m30; }
public void set_m21(double m21) { this.m21 = m21; }
public void set_m12(double m12) { this.m12 = m12; }
public void set_m03(double m03) { this.m03 = m03; }
public void set_mu20(double mu20) { this.mu20 = mu20; }
public void set_mu11(double mu11) { this.mu11 = mu11; }
public void set_mu02(double mu02) { this.mu02 = mu02; }
public void set_mu30(double mu30) { this.mu30 = mu30; }
public void set_mu21(double mu21) { this.mu21 = mu21; }
public void set_mu12(double mu12) { this.mu12 = mu12; }
public void set_mu03(double mu03) { this.mu03 = mu03; }
public void set_nu20(double nu20) { this.nu20 = nu20; }
public void set_nu11(double nu11) { this.nu11 = nu11; }
public void set_nu02(double nu02) { this.nu02 = nu02; }
public void set_nu30(double nu30) { this.nu30 = nu30; }
public void set_nu21(double nu21) { this.nu21 = nu21; }
public void set_nu12(double nu12) { this.nu12 = nu12; }
public void set_nu03(double nu03) { this.nu03 = nu03; }
}
@@ -452,101 +452,6 @@ public class GeometryTest extends OpenCVTestCase {
// TODO_: write better test
}
public void testInitUndistortRectifyMap() {
fail("Not yet implemented");
Mat cameraMatrix = new Mat(3, 3, CvType.CV_32F);
cameraMatrix.put(0, 0, 1, 0, 1);
cameraMatrix.put(1, 0, 0, 1, 1);
cameraMatrix.put(2, 0, 0, 0, 1);
Mat R = new Mat(3, 3, CvType.CV_32F, new Scalar(2));
Mat newCameraMatrix = new Mat(3, 3, CvType.CV_32F, new Scalar(3));
Mat distCoeffs = new Mat();
Mat map1 = new Mat();
Mat map2 = new Mat();
// TODO: complete this test
Geometry.initUndistortRectifyMap(cameraMatrix, distCoeffs, R, newCameraMatrix, size, CvType.CV_32F, map1, map2);
}
public void testInitWideAngleProjMapMatMatSizeIntIntMatMat() {
fail("Not yet implemented");
Mat cameraMatrix = new Mat(3, 3, CvType.CV_32F);
Mat distCoeffs = new Mat(1, 4, CvType.CV_32F);
// Size imageSize = new Size(2, 2);
cameraMatrix.put(0, 0, 1, 0, 1);
cameraMatrix.put(1, 0, 0, 1, 2);
cameraMatrix.put(2, 0, 0, 0, 1);
distCoeffs.put(0, 0, 1, 3, 2, 4);
truth = new Mat(3, 3, CvType.CV_32F);
truth.put(0, 0, 0, 0, 0);
truth.put(1, 0, 0, 0, 0);
truth.put(2, 0, 0, 3, 0);
// TODO: No documentation for this function
// Geometry.initWideAngleProjMap(cameraMatrix, distCoeffs, imageSize,
// 5, m1type, truthput1, truthput2);
}
public void testInitWideAngleProjMapMatMatSizeIntIntMatMatInt() {
fail("Not yet implemented");
}
public void testInitWideAngleProjMapMatMatSizeIntIntMatMatIntDouble() {
fail("Not yet implemented");
}
public void testUndistortMatMatMatMat() {
Mat src = new Mat(3, 3, CvType.CV_32F, new Scalar(3));
Mat cameraMatrix = new Mat(3, 3, CvType.CV_32F) {
{
put(0, 0, 1, 0, 1);
put(1, 0, 0, 1, 2);
put(2, 0, 0, 0, 1);
}
};
Mat distCoeffs = new Mat(1, 4, CvType.CV_32F) {
{
put(0, 0, 1, 3, 2, 4);
}
};
Geometry.undistort(src, dst, cameraMatrix, distCoeffs);
truth = new Mat(3, 3, CvType.CV_32F) {
{
put(0, 0, 0, 0, 0);
put(1, 0, 0, 0, 0);
put(2, 0, 0, 3, 0);
}
};
assertMatEqual(truth, dst, EPS);
}
public void testUndistortMatMatMatMatMat() {
Mat src = new Mat(3, 3, CvType.CV_32F, new Scalar(3));
Mat cameraMatrix = new Mat(3, 3, CvType.CV_32F) {
{
put(0, 0, 1, 0, 1);
put(1, 0, 0, 1, 2);
put(2, 0, 0, 0, 1);
}
};
Mat distCoeffs = new Mat(1, 4, CvType.CV_32F) {
{
put(0, 0, 2, 1, 4, 5);
}
};
Mat newCameraMatrix = new Mat(3, 3, CvType.CV_32F, new Scalar(1));
Geometry.undistort(src, dst, cameraMatrix, distCoeffs, newCameraMatrix);
truth = new Mat(3, 3, CvType.CV_32F, new Scalar(3));
assertMatEqual(truth, dst, EPS);
}
//undistortPoints(List<Point> src, List<Point> dst, Mat cameraMatrix, Mat distCoeffs)
public void testUndistortPointsListOfPointListOfPointMatMat() {
MatOfPoint2f src = new MatOfPoint2f(new Point(1, 2), new Point(3, 4), new Point(-1, -1));
@@ -687,7 +592,7 @@ public class GeometryTest extends OpenCVTestCase {
Mat linePoints = new Mat(4, 1, CvType.CV_32FC1);
linePoints.put(0, 0, 0.53198653, 0.84675282, 2.5, 3.75);
Geometry.fitLine(points, dst, Imgproc.DIST_L12, 0, 0.01, 0.01);
Geometry.fitLine(points, dst, Geometry.DIST_L12, 0, 0.01, 0.01);
assertMatEqual(linePoints, dst, EPS);
}
@@ -780,4 +685,44 @@ public class GeometryTest extends OpenCVTestCase {
assertTrue(bbox.contains(p1));
assertFalse(bbox.contains(p2));
}
public void testGetAffineTransform() {
MatOfPoint2f src = new MatOfPoint2f(new Point(2, 3), new Point(3, 1), new Point(1, 4));
MatOfPoint2f dst = new MatOfPoint2f(new Point(3, 3), new Point(7, 4), new Point(5, 6));
Mat transform = Geometry.getAffineTransform(src, dst);
Mat truth = new Mat(2, 3, CvType.CV_64FC1) {
{
put(0, 0, -8, -6, 37);
put(1, 0, -7, -4, 29);
}
};
assertMatEqual(truth, transform, EPS);
}
public void testGetRotationMatrix2D() {
Point center = new Point(0, 0);
dst = Geometry.getRotationMatrix2D(center, 0, 1);
truth = new Mat(2, 3, CvType.CV_64F) {
{
put(0, 0, 1, 0, 0);
put(1, 0, 0, 1, 0);
}
};
assertMatEqual(truth, dst, EPS);
}
public void testInvertAffineTransform() {
Mat src = new Mat(2, 3, CvType.CV_64F, new Scalar(1));
Geometry.invertAffineTransform(src, dst);
truth = new Mat(2, 3, CvType.CV_64F, new Scalar(0));
assertMatEqual(truth, dst, EPS);
}
}
@@ -1,12 +1,12 @@
package org.opencv.test.imgproc;
package org.opencv.test.geometry;
import org.opencv.test.OpenCVTestCase;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.CvType;
import org.opencv.core.Scalar;
import org.opencv.imgproc.Imgproc;
import org.opencv.imgproc.Moments;
import org.opencv.geometry.Geometry;
import org.opencv.geometry.Moments;
public class MomentsTest extends OpenCVTestCase {
@@ -21,7 +21,7 @@ public class MomentsTest extends OpenCVTestCase {
}
public void testAll() {
Moments res = Imgproc.moments(data);
Moments res = Geometry.moments(data);
assertEquals(res.m00, 21.0, EPS);
assertEquals(res.m10, 21.0, EPS);
assertEquals(res.m01, 21.0, EPS);
+8 -3
View File
@@ -3,7 +3,6 @@
{
"": [
"findHomography",
"drawFrameAxes",
"estimateAffine2D",
"getDefaultNewCameraMatrix",
"initUndistortRectifyMap",
@@ -13,7 +12,6 @@
"solvePnPRefineLM",
"projectPoints",
"undistort",
"fisheye_initUndistortRectifyMap",
"fisheye_projectPoints",
"approxPolyDP",
"approxPolyN",
@@ -30,7 +28,14 @@
"fitEllipseAMS",
"fitEllipseDirect",
"fitLine",
"pointPolygonTest"
"pointPolygonTest",
"getAffineTransform",
"getPerspectiveTransform",
"getRotationMatrix2D",
"HuMoments",
"invertAffineTransform",
"moments",
"rotatedRectangleIntersection"
],
"UsacParams": ["UsacParams"]
}
+25
View File
@@ -1,5 +1,30 @@
{
"namespaces_dict": {
"cv.fisheye": "fisheye"
},
"func_arg_fix" : {
"Geometry" : {
"minEnclosingCircle" : { "points" : {"ctype" : "vector_Point2f"} },
"fitEllipse" : { "points" : {"ctype" : "vector_Point2f"} },
"approxPolyDP" : { "curve" : {"ctype" : "vector_Point2f"},
"approxCurve" : {"ctype" : "vector_Point2f"} },
"arcLength" : { "curve" : {"ctype" : "vector_Point2f"} },
"pointPolygonTest" : { "contour" : {"ctype" : "vector_Point2f"} },
"minAreaRect" : { "points" : {"ctype" : "vector_Point2f"} },
"getAffineTransform" : { "src" : {"ctype" : "vector_Point2f"},
"dst" : {"ctype" : "vector_Point2f"} },
"convexityDefects" : { "contour" : {"ctype" : "vector_Point"},
"convexhull" : {"ctype" : "vector_int"},
"convexityDefects" : {"ctype" : "vector_Vec4i"} },
"isContourConvex" : { "contour" : {"ctype" : "vector_Point"} },
"convexHull" : { "points" : {"ctype" : "vector_Point"},
"hull" : {"ctype" : "vector_int"},
"returnPoints" : {"ctype" : ""} },
"matchShapes" : { "method" : {"ctype" : "ShapeMatchModes"}},
"fitLine" : { "distType" : {"ctype" : "DistanceTypes"}}
},
"Subdiv2D" : {
"(void)insert:(NSArray<Point2f*>*)ptvec" : { "insert" : {"name" : "insertVector"} }
}
}
}
+159 -13
View File
@@ -7,7 +7,7 @@
import XCTest
import OpenCV
class Cv3dTest: OpenCVTestCase {
class GeometryTest: OpenCVTestCase {
var size = Size()
@@ -38,7 +38,7 @@ class Cv3dTest: OpenCVTestCase {
let outTvec = Mat(rows: 3, cols: 1, type: CvType.CV_32F)
try outTvec.put(row: 0, col: 0, data: [1.4560841, 1.0680628, 0.81598103])
Cv3d.composeRT(rvec1: rvec1, tvec1: tvec1, rvec2: rvec2, tvec2: tvec2, rvec3: rvec3, tvec3: tvec3)
Geometry.composeRT(rvec1: rvec1, tvec1: tvec1, rvec2: rvec2, tvec2: tvec2, rvec3: rvec3, tvec3: tvec3)
try assertMatEqual(outRvec, rvec3, OpenCVTestCase.EPS)
try assertMatEqual(outTvec, tvec3, OpenCVTestCase.EPS)
@@ -59,7 +59,7 @@ class Cv3dTest: OpenCVTestCase {
try transformedPoints.put(row:i, col:0, data:[y, x])
}
let hmg = Cv3d.findHomography(srcPoints: originalPoints, dstPoints: transformedPoints)
let hmg = Geometry.findHomography(srcPoints: originalPoints, dstPoints: transformedPoints)
truth = Mat(rows: 3, cols: 3, type: CvType.CV_64F)
try truth!.put(row:0, col:0, data:[0, 1, 0, 1, 0, 0, 0, 0, 1] as [Double])
@@ -72,14 +72,14 @@ class Cv3dTest: OpenCVTestCase {
try r.put(row:0, col:0, data:[.pi, 0, 0] as [Float])
Cv3d.Rodrigues(src: r, dst: R)
Geometry.Rodrigues(src: r, dst: R)
truth = Mat(rows: 3, cols: 3, type: CvType.CV_32F)
try truth!.put(row:0, col:0, data:[1, 0, 0, 0, -1, 0, 0, 0, -1] as [Float])
try assertMatEqual(truth!, R, OpenCVTestCase.EPS)
let r2 = Mat()
Cv3d.Rodrigues(src: R, dst: r2)
Geometry.Rodrigues(src: R, dst: r2)
try assertMatEqual(r, r2, OpenCVTestCase.EPS)
}
@@ -107,7 +107,7 @@ class Cv3dTest: OpenCVTestCase {
let rvec = Mat()
let tvec = Mat()
Cv3d.solvePnP(objectPoints: points3d, imagePoints: points2d, cameraMatrix: intrinsics, distCoeffs: MatOfDouble(), rvec: rvec, tvec: tvec)
Geometry.solvePnP(objectPoints: points3d, imagePoints: points2d, cameraMatrix: intrinsics, distCoeffs: MatOfDouble(), rvec: rvec, tvec: tvec)
let truth_rvec = Mat(rows: 3, cols: 1, type: CvType.CV_64F)
try truth_rvec.put(row: 0, col: 0, data: [0, .pi / 2, 0] as [Double])
@@ -128,7 +128,7 @@ class Cv3dTest: OpenCVTestCase {
let lines = Mat()
let truth = Mat(rows: 1, cols: 1, type: CvType.CV_32FC3)
try truth.put(row: 0, col: 0, data: [-0.70735186, 0.70686162, -0.70588124])
Cv3d.computeCorrespondEpilines(points: left, whichImage: 1, F: fundamental, lines: lines)
Geometry.computeCorrespondEpilines(points: left, whichImage: 1, F: fundamental, lines: lines)
try assertMatEqual(truth, lines, OpenCVTestCase.EPS)
}
@@ -161,7 +161,7 @@ class Cv3dTest: OpenCVTestCase {
let reprojectionError = Mat(rows: 2, cols: 1, type: CvType.CV_64FC1)
Cv3d.solvePnPGeneric(objectPoints: points3d, imagePoints: points2d, cameraMatrix: intrinsics, distCoeffs: MatOfDouble(), rvecs: &rvecs, tvecs: &tvecs, useExtrinsicGuess: false, flags: .SOLVEPNP_IPPE, rvec: rvec, tvec: tvec, reprojectionError: reprojectionError)
Geometry.solvePnPGeneric(objectPoints: points3d, imagePoints: points2d, cameraMatrix: intrinsics, distCoeffs: MatOfDouble(), rvecs: &rvecs, tvecs: &tvecs, useExtrinsicGuess: false, flags: .SOLVEPNP_IPPE, rvec: rvec, tvec: tvec, reprojectionError: reprojectionError)
let truth_rvec = Mat(rows: 3, cols: 1, type: CvType.CV_64F)
try truth_rvec.put(row: 0, col: 0, data: [0, .pi / 2, 0] as [Double])
@@ -174,14 +174,14 @@ class Cv3dTest: OpenCVTestCase {
}
func testGetDefaultNewCameraMatrixMat() {
let mtx = Cv3d.getDefaultNewCameraMatrix(cameraMatrix: gray0)
let mtx = Geometry.getDefaultNewCameraMatrix(cameraMatrix: gray0)
XCTAssertFalse(mtx.empty())
XCTAssertEqual(0, Core.countNonZero(src: mtx))
}
func testGetDefaultNewCameraMatrixMatSizeBoolean() {
let mtx = Cv3d.getDefaultNewCameraMatrix(cameraMatrix: gray0, imgsize: size, centerPrincipalPoint: true)
let mtx = Geometry.getDefaultNewCameraMatrix(cameraMatrix: gray0, imgsize: size, centerPrincipalPoint: true)
XCTAssertFalse(mtx.empty())
XCTAssertFalse(0 == Core.countNonZero(src: mtx))
@@ -198,7 +198,7 @@ class Cv3dTest: OpenCVTestCase {
let distCoeffs = Mat(rows: 1, cols: 4, type: CvType.CV_32F)
try distCoeffs.put(row: 0, col: 0, data: [1, 3, 2, 4] as [Float])
Cv3d.undistort(src: src, dst: dst, cameraMatrix: cameraMatrix, distCoeffs: distCoeffs)
Geometry.undistort(src: src, dst: dst, cameraMatrix: cameraMatrix, distCoeffs: distCoeffs)
truth = Mat(rows: 3, cols: 3, type: CvType.CV_32F)
try truth!.put(row: 0, col: 0, data: [0, 0, 0] as [Float])
@@ -220,7 +220,7 @@ class Cv3dTest: OpenCVTestCase {
let newCameraMatrix = Mat(rows: 3, cols: 3, type: CvType.CV_32F, scalar: Scalar(1))
Cv3d.undistort(src: src, dst: dst, cameraMatrix: cameraMatrix, distCoeffs: distCoeffs, newCameraMatrix: newCameraMatrix)
Geometry.undistort(src: src, dst: dst, cameraMatrix: cameraMatrix, distCoeffs: distCoeffs, newCameraMatrix: newCameraMatrix)
truth = Mat(rows: 3, cols: 3, type: CvType.CV_32F, scalar: Scalar(3))
try assertMatEqual(truth!, dst, OpenCVTestCase.EPS)
@@ -233,8 +233,154 @@ class Cv3dTest: OpenCVTestCase {
let cameraMatrix = Mat.eye(rows: 3, cols: 3, type: CvType.CV_64FC1)
let distCoeffs = Mat(rows: 8, cols: 1, type: CvType.CV_64FC1, scalar: Scalar(0))
Cv3d.undistortPoints(src: src, dst: dst, cameraMatrix: cameraMatrix, distCoeffs: distCoeffs)
Geometry.undistortPoints(src: src, dst: dst, cameraMatrix: cameraMatrix, distCoeffs: distCoeffs)
XCTAssertEqual(src.toArray(), dst.toArray())
}
func testApproxPolyDP() {
let curve = [Point2f(x: 1, y: 3), Point2f(x: 2, y: 4), Point2f(x: 3, y: 5), Point2f(x: 4, y: 4), Point2f(x: 5, y: 3)]
var approxCurve = [Point2f]()
Geometry.approxPolyDP(curve: curve, approxCurve: &approxCurve, epsilon: OpenCVTestCase.EPS, closed: true)
let approxCurveGold = [Point2f(x: 1, y: 3), Point2f(x: 3, y: 5), Point2f(x: 5, y: 3)]
XCTAssert(approxCurve == approxCurveGold)
}
func testArcLength() {
let curve = [Point2f(x: 1, y: 3), Point2f(x: 2, y: 4), Point2f(x: 3, y: 5), Point2f(x: 4, y: 4), Point2f(x: 5, y: 3)]
let arcLength = Geometry.arcLength(curve: curve, closed: false)
XCTAssertEqual(5.656854249, arcLength, accuracy:0.000001)
}
func testContourAreaMat() throws {
let contour = Mat(rows: 1, cols: 4, type: CvType.CV_32FC2)
try contour.put(row: 0, col: 0, data: [0, 0, 10, 0, 10, 10, 5, 4] as [Float])
let area = Geometry.contourArea(contour: contour)
XCTAssertEqual(45.0, area, accuracy: OpenCVTestCase.EPS)
}
func testContourAreaMatBoolean() throws {
let contour = Mat(rows: 1, cols: 4, type: CvType.CV_32FC2)
try contour.put(row: 0, col: 0, data: [0, 0, 10, 0, 10, 10, 5, 4] as [Float])
let area = Geometry.contourArea(contour: contour, oriented: true)
XCTAssertEqual(45.0, area, accuracy: OpenCVTestCase.EPS)
}
func testConvexHullMatMatBooleanBoolean() {
let points = [Point(x: 2, y: 0),
Point(x: 4, y: 0),
Point(x: 3, y: 2),
Point(x: 0, y: 2),
Point(x: 2, y: 1),
Point(x: 3, y: 1)]
var hull = [Int32]()
Geometry.convexHull(points: points, hull: &hull, clockwise: true)
XCTAssert([3, 2, 1, 0] == hull)
}
func testConvexityDefects() throws {
let points = [Point(x: 20, y: 0),
Point(x: 40, y: 0),
Point(x: 30, y: 20),
Point(x: 0, y: 20),
Point(x: 20, y: 10),
Point(x: 30, y: 10)]
var hull = [Int32]()
Geometry.convexHull(points: points, hull: &hull)
var convexityDefects = [Int4]()
Geometry.convexityDefects(contour: points, convexhull: hull, convexityDefects: &convexityDefects)
XCTAssertTrue(Int4(v0: 3, v1: 0, v2: 5, v3: 3620) == convexityDefects[0])
}
func testGetAffineTransform() throws {
let src = [Point2f(x: 2, y: 3), Point2f(x: 3, y: 1), Point2f(x: 1, y: 4)]
let dst = [Point2f(x: 3, y: 3), Point2f(x: 7, y: 4), Point2f(x: 5, y: 6)]
let transform = Geometry.getAffineTransform(src: src, dst: dst)
let truth = Mat(rows: 2, cols: 3, type: CvType.CV_64FC1)
try truth.put(row: 0, col: 0, data: [-8.0, -6.0, 37.0])
try truth.put(row: 1, col: 0, data: [-7.0, -4.0, 29.0])
try assertMatEqual(truth, transform, OpenCVTestCase.EPS)
}
func testGetRotationMatrix2D() throws {
let center = Point2f(x: 0, y: 0)
dst = Geometry.getRotationMatrix2D(center: center, angle: 0, scale: 1)
truth = Mat(rows: 2, cols: 3, type: CvType.CV_64F)
try truth!.put(row: 0, col: 0, data: [1.0, 0.0, 0.0])
try truth!.put(row: 1, col: 0, data: [0.0, 1.0, 0.0])
try assertMatEqual(truth!, dst, OpenCVTestCase.EPS)
}
func testInvertAffineTransform() throws {
let src = Mat(rows: 2, cols: 3, type: CvType.CV_64F, scalar: Scalar(1))
Geometry.invertAffineTransform(M: src, iM: dst)
truth = Mat(rows: 2, cols: 3, type: CvType.CV_64F, scalar: Scalar(0))
try assertMatEqual(truth!, dst, OpenCVTestCase.EPS)
}
func testIsContourConvex() {
let contour1 = [Point(x: 0, y: 0), Point(x: 10, y: 0), Point(x: 10, y: 10), Point(x: 5, y: 4)]
XCTAssertFalse(Geometry.isContourConvex(contour: contour1))
let contour2 = [Point(x: 0, y: 0), Point(x: 10, y: 0), Point(x: 10, y: 10), Point(x: 5, y: 6)]
XCTAssert(Geometry.isContourConvex(contour: contour2))
}
func testMinAreaRect() {
let points = [Point2f(x: 1, y: 1), Point2f(x: 5, y: 1), Point2f(x: 4, y: 3), Point2f(x: 6, y: 2)]
let rrect = Geometry.minAreaRect(points: points)
XCTAssertEqual(Size2f(width: 5, height: 2), rrect.size)
XCTAssertEqual(0.0, rrect.angle)
XCTAssertEqual(Point2f(x: 3.5, y: 2), rrect.center)
}
func testMinEnclosingCircle() {
let points = [Point2f(x: 0, y: 0), Point2f(x: -100, y: 0), Point2f(x: 0, y: -100), Point2f(x: 100, y: 0), Point2f(x: 0, y: 100)]
let actualCenter = Point2f()
var radius:Float = 0
Geometry.minEnclosingCircle(points: points, center: actualCenter, radius: &radius)
XCTAssertEqual(Point2f(x: 0, y: 0), actualCenter)
XCTAssertEqual(100.0, radius, accuracy: 1.0)
}
func testPointPolygonTest() {
let contour = [Point2f(x: 0, y: 0), Point2f(x: 1, y: 3), Point2f(x: 3, y: 4), Point2f(x: 4, y: 3), Point2f(x: 2, y: 1)]
let sign1 = Geometry.pointPolygonTest(contour: contour, pt: Point2f(x: 2, y: 2), measureDist: false)
XCTAssertEqual(1.0, sign1)
let sign2 = Geometry.pointPolygonTest(contour: contour, pt: Point2f(x: 4, y: 4), measureDist: true)
XCTAssertEqual(-sqrt(0.5), sign2)
}
}
+4
View File
@@ -11,4 +11,8 @@
#include <opencv2/core/ocl.hpp>
#endif
namespace opencv_test {
using namespace perf;
} // namespace
#endif
-116
View File
@@ -474,110 +474,6 @@ void cv::fisheye::undistortPoints( InputArray distorted, OutputArray undistorted
}
}
void cv::fisheye::initUndistortRectifyMap( InputArray K, InputArray D, InputArray R, InputArray P,
const cv::Size& size, int m1type, OutputArray map1, OutputArray map2 )
{
CV_INSTRUMENT_REGION();
CV_Assert( m1type == CV_16SC2 || m1type == CV_32F || m1type <=0 );
map1.create( size, m1type <= 0 ? CV_16SC2 : m1type );
map2.create( size, map1.type() == CV_16SC2 ? CV_16UC1 : CV_32F );
CV_Assert((K.depth() == CV_32F || K.depth() == CV_64F) && (D.depth() == CV_32F || D.depth() == CV_64F));
CV_Assert((P.empty() || P.depth() == CV_32F || P.depth() == CV_64F) && (R.empty() || R.depth() == CV_32F || R.depth() == CV_64F));
CV_Assert(K.size() == Size(3, 3) && (D.empty() || D.total() == 4));
CV_Assert(R.empty() || R.size() == Size(3, 3) || R.total() * R.channels() == 3);
CV_Assert(P.empty() || P.size() == Size(3, 3) || P.size() == Size(4, 3));
Vec2d f, c;
if (K.depth() == CV_32F)
{
Matx33f camMat = K.getMat();
f = Vec2f(camMat(0, 0), camMat(1, 1));
c = Vec2f(camMat(0, 2), camMat(1, 2));
}
else
{
Matx33d camMat = K.getMat();
f = Vec2d(camMat(0, 0), camMat(1, 1));
c = Vec2d(camMat(0, 2), camMat(1, 2));
}
Vec4d k = Vec4d::all(0);
if (!D.empty())
k = D.depth() == CV_32F ? (Vec4d)*D.getMat().ptr<Vec4f>(): *D.getMat().ptr<Vec4d>();
Matx33d RR = Matx33d::eye();
if (!R.empty() && R.total() * R.channels() == 3)
{
Vec3d rvec;
R.getMat().convertTo(rvec, CV_64F);
RR = Affine3d(rvec).rotation();
}
else if (!R.empty() && R.size() == Size(3, 3))
R.getMat().convertTo(RR, CV_64F);
Matx33d PP = Matx33d::eye();
if (!P.empty())
P.getMat().colRange(0, 3).convertTo(PP, CV_64F);
Matx33d iR = (PP * RR).inv(cv::DECOMP_SVD);
for( int i = 0; i < size.height; ++i)
{
float* m1f = map1.getMat().ptr<float>(i);
float* m2f = map2.getMat().ptr<float>(i);
short* m1 = (short*)m1f;
ushort* m2 = (ushort*)m2f;
double _x = i*iR(0, 1) + iR(0, 2),
_y = i*iR(1, 1) + iR(1, 2),
_w = i*iR(2, 1) + iR(2, 2);
for( int j = 0; j < size.width; ++j)
{
double u, v;
if( _w <= 0)
{
u = (_x > 0) ? -std::numeric_limits<double>::infinity() : std::numeric_limits<double>::infinity();
v = (_y > 0) ? -std::numeric_limits<double>::infinity() : std::numeric_limits<double>::infinity();
}
else
{
double x = _x/_w, y = _y/_w;
double r = sqrt(x*x + y*y);
double theta = std::atan(r);
double theta2 = theta*theta, theta4 = theta2*theta2, theta6 = theta4*theta2, theta8 = theta4*theta4;
double theta_d = theta * (1 + k[0]*theta2 + k[1]*theta4 + k[2]*theta6 + k[3]*theta8);
double scale = (r == 0) ? 1.0 : theta_d / r;
u = f[0]*x*scale + c[0];
v = f[1]*y*scale + c[1];
}
if( m1type == CV_16SC2 )
{
int iu = cv::saturate_cast<int>(u*static_cast<double>(cv::INTER_TAB_SIZE));
int iv = cv::saturate_cast<int>(v*static_cast<double>(cv::INTER_TAB_SIZE));
m1[j*2+0] = (short)(iu >> cv::INTER_BITS);
m1[j*2+1] = (short)(iv >> cv::INTER_BITS);
m2[j] = (ushort)((iv & (cv::INTER_TAB_SIZE-1))*cv::INTER_TAB_SIZE + (iu & (cv::INTER_TAB_SIZE-1)));
}
else if( m1type == CV_32FC1 )
{
m1f[j] = (float)u;
m2f[j] = (float)v;
}
_x += iR(0, 0);
_y += iR(1, 0);
_w += iR(2, 0);
}
}
}
void cv::fisheye::estimateNewCameraMatrixForUndistortRectify(InputArray K, InputArray D, const Size &image_size, InputArray R,
OutputArray P, double balance, const Size& new_size, double fov_scale)
{
@@ -648,18 +544,6 @@ void cv::fisheye::estimateNewCameraMatrixForUndistortRectify(InputArray K, Input
0, 0, 1)).convertTo(P, P.empty() ? K.type() : P.type());
}
void cv::fisheye::undistortImage(InputArray distorted, OutputArray undistorted,
InputArray K, InputArray D, InputArray Knew, const Size& new_size)
{
CV_INSTRUMENT_REGION();
Size size = !new_size.empty() ? new_size : distorted.size();
Mat map1, map2;
fisheye::initUndistortRectifyMap(K, D, Matx33d::eye(), Knew, size, CV_16SC2, map1, map2 );
cv::remap(distorted, undistorted, map1, map2, INTER_LINEAR, BORDER_CONSTANT);
}
bool cv::fisheye::solvePnP( InputArray opoints, InputArray ipoints,
InputArray cameraMatrix, InputArray distCoeffs,
OutputArray rvec, OutputArray tvec, bool useExtrinsicGuess,
+199 -1
View File
@@ -40,6 +40,7 @@
//M*/
#include "precomp.hpp"
#include "opencv2/core/hal/intrin.hpp"
#include "opencv2/core/softfloat.hpp"
using namespace cv;
@@ -711,9 +712,204 @@ cv::Rect boundingRect(InputArray array)
return m.depth() <= CV_8U ? maskBoundingRect(m) : pointSetBoundingRect(m);
}
cv::Matx23d getRotationMatrix2D_(Point2f center, double angle, double scale)
{
CV_INSTRUMENT_REGION();
angle *= CV_PI/180;
double alpha = std::cos(angle)*scale;
double beta = std::sin(angle)*scale;
Matx23d M(
alpha, beta, (1-alpha)*center.x - beta*center.y,
-beta, alpha, beta*center.x + (1-alpha)*center.y
);
return M;
}
float cv::intersectConvexConvex( InputArray _p1, InputArray _p2, OutputArray _p12, bool handleNested )
/* Calculates coefficients of perspective transformation
* which maps (xi,yi) to (ui,vi), (i=1,2,3,4):
*
* c00*xi + c01*yi + c02
* ui = ---------------------
* c20*xi + c21*yi + c22
*
* c10*xi + c11*yi + c12
* vi = ---------------------
* c20*xi + c21*yi + c22
*
* Coefficients are calculated by solving one of 2 linear systems:
* / x0 y0 1 0 0 0 -x0*u0 -y0*u0 \ /c00\ /u0\
* | x1 y1 1 0 0 0 -x1*u1 -y1*u1 | |c01| |u1|
* | x2 y2 1 0 0 0 -x2*u2 -y2*u2 | |c02| |u2|
* | x3 y3 1 0 0 0 -x3*u3 -y3*u3 |.|c10|=|u3|,
* | 0 0 0 x0 y0 1 -x0*v0 -y0*v0 | |c11| |v0|
* | 0 0 0 x1 y1 1 -x1*v1 -y1*v1 | |c12| |v1|
* | 0 0 0 x2 y2 1 -x2*v2 -y2*v2 | |c20| |v2|
* \ 0 0 0 x3 y3 1 -x3*v3 -y3*v3 / \c21/ \v3/
*
* where:
* cij - matrix coefficients, c22 = 1
*
* or
*
* / x0 y0 1 0 0 0 -x0*u0 -y0*u0 -u0 \ /c00\ /0\
* | x1 y1 1 0 0 0 -x1*u1 -y1*u1 -u1 | |c01| |0|
* | x2 y2 1 0 0 0 -x2*u2 -y2*u2 -u2 | |c02| |0|
* | x3 y3 1 0 0 0 -x3*u3 -y3*u3 -u3 |.|c10|=|0|,
* | 0 0 0 x0 y0 1 -x0*v0 -y0*v0 -v0 | |c11| |0|
* | 0 0 0 x1 y1 1 -x1*v1 -y1*v1 -v1 | |c12| |0|
* | 0 0 0 x2 y2 1 -x2*v2 -y2*v2 -v2 | |c20| |0|
* \ 0 0 0 x3 y3 1 -x3*v3 -y3*v3 -v3 / |c21| \0/
* \c22/
*
* where:
* cij - matrix coefficients, c00^2 + c01^2 + c02^2 + c10^2 + c11^2 + c12^2 + c20^2 + c21^2 + c22^2 = 1
*/
cv::Mat getPerspectiveTransform(const Point2f src[], const Point2f dst[], int solveMethod)
{
CV_INSTRUMENT_REGION();
// try c22 = 1
Mat M(3, 3, CV_64F), X8(8, 1, CV_64F, M.ptr());
double a[8][8], b[8];
Mat A(8, 8, CV_64F, a), B(8, 1, CV_64F, b);
for( int i = 0; i < 4; ++i )
{
a[i][0] = a[i+4][3] = src[i].x;
a[i][1] = a[i+4][4] = src[i].y;
a[i][2] = a[i+4][5] = 1;
a[i][3] = a[i][4] = a[i][5] =
a[i+4][0] = a[i+4][1] = a[i+4][2] = 0;
a[i][6] = -src[i].x*dst[i].x;
a[i][7] = -src[i].y*dst[i].x;
a[i+4][6] = -src[i].x*dst[i].y;
a[i+4][7] = -src[i].y*dst[i].y;
b[i] = dst[i].x;
b[i+4] = dst[i].y;
}
if (solve(A, B, X8, solveMethod) && norm(A * X8, B) < 1e-8)
{
M.ptr<double>()[8] = 1.;
return M;
}
// c00^2 + c01^2 + c02^2 + c10^2 + c11^2 + c12^2 + c20^2 + c21^2 + c22^2 = 1
hconcat(A, -B, A);
Mat AtA;
mulTransposed(A, AtA, true);
Mat D, U;
SVDecomp(AtA, D, U, noArray());
Mat X9(9, 1, CV_64F, M.ptr());
U.col(8).copyTo(X9);
return M;
}
/* Calculates coefficients of affine transformation
* which maps (xi,yi) to (ui,vi), (i=1,2,3):
*
* ui = c00*xi + c01*yi + c02
*
* vi = c10*xi + c11*yi + c12
*
* Coefficients are calculated by solving linear system:
* / x0 y0 1 0 0 0 \ /c00\ /u0\
* | x1 y1 1 0 0 0 | |c01| |u1|
* | x2 y2 1 0 0 0 | |c02| |u2|
* | 0 0 0 x0 y0 1 | |c10| |v0|
* | 0 0 0 x1 y1 1 | |c11| |v1|
* \ 0 0 0 x2 y2 1 / |c12| |v2|
*
* where:
* cij - matrix coefficients
*/
cv::Mat getAffineTransform( const Point2f src[], const Point2f dst[] )
{
Mat M(2, 3, CV_64F), X(6, 1, CV_64F, M.ptr());
double a[6*6], b[6];
Mat A(6, 6, CV_64F, a), B(6, 1, CV_64F, b);
for( int i = 0; i < 3; i++ )
{
int j = i*12;
int k = i*12+6;
a[j] = a[k+3] = src[i].x;
a[j+1] = a[k+4] = src[i].y;
a[j+2] = a[k+5] = 1;
a[j+3] = a[j+4] = a[j+5] = 0;
a[k] = a[k+1] = a[k+2] = 0;
b[i*2] = dst[i].x;
b[i*2+1] = dst[i].y;
}
solve( A, B, X );
return M;
}
void invertAffineTransform(InputArray _matM, OutputArray __iM)
{
Mat matM = _matM.getMat();
CV_Assert(matM.rows == 2 && matM.cols == 3);
__iM.create(2, 3, matM.type());
Mat _iM = __iM.getMat();
if( matM.type() == CV_32F )
{
const softfloat* M = matM.ptr<softfloat>();
softfloat* iM = _iM.ptr<softfloat>();
int step = (int)(matM.step/sizeof(M[0])), istep = (int)(_iM.step/sizeof(iM[0]));
softdouble D = M[0]*M[step+1] - M[1]*M[step];
D = D != 0. ? softdouble(1.)/D : softdouble(0.);
softdouble A11 = M[step+1]*D, A22 = M[0]*D, A12 = -M[1]*D, A21 = -M[step]*D;
softdouble b1 = -A11*M[2] - A12*M[step+2];
softdouble b2 = -A21*M[2] - A22*M[step+2];
iM[0] = A11; iM[1] = A12; iM[2] = b1;
iM[istep] = A21; iM[istep+1] = A22; iM[istep+2] = b2;
}
else if( matM.type() == CV_64F )
{
const softdouble* M = matM.ptr<softdouble>();
softdouble* iM = _iM.ptr<softdouble>();
int step = (int)(matM.step/sizeof(M[0])), istep = (int)(_iM.step/sizeof(iM[0]));
softdouble D = M[0]*M[step+1] - M[1]*M[step];
D = D != 0. ? softdouble(1.)/D : softdouble(0.);
softdouble A11 = M[step+1]*D, A22 = M[0]*D, A12 = -M[1]*D, A21 = -M[step]*D;
softdouble b1 = -A11*M[2] - A12*M[step+2];
softdouble b2 = -A21*M[2] - A22*M[step+2];
iM[0] = A11; iM[1] = A12; iM[2] = b1;
iM[istep] = A21; iM[istep+1] = A22; iM[istep+2] = b2;
}
else
CV_Error( cv::Error::StsUnsupportedFormat, "" );
}
cv::Mat getPerspectiveTransform(InputArray _src, InputArray _dst, int solveMethod)
{
Mat src = _src.getMat(), dst = _dst.getMat();
CV_Assert(src.checkVector(2, CV_32F) == 4 && dst.checkVector(2, CV_32F) == 4);
return getPerspectiveTransform((const Point2f*)src.data, (const Point2f*)dst.data, solveMethod);
}
cv::Mat getAffineTransform(InputArray _src, InputArray _dst)
{
Mat src = _src.getMat(), dst = _dst.getMat();
CV_Assert(src.checkVector(2, CV_32F) == 3 && dst.checkVector(2, CV_32F) == 3);
return getAffineTransform((const Point2f*)src.data, (const Point2f*)dst.data);
}
float intersectConvexConvex( InputArray _p1, InputArray _p2, OutputArray _p12, bool handleNested )
{
CV_INSTRUMENT_REGION();
@@ -832,3 +1028,5 @@ float cv::intersectConvexConvex( InputArray _p1, InputArray _p2, OutputArray _p1
}
return (float)fabs(area);
}
} // namespace cv
+32
View File
@@ -154,6 +154,38 @@ inline int hal_ni_project_points_pinhole64f(const double* src_data, size_t src_s
#define cv_hal_project_points_pinhole64f hal_ni_project_points_pinhole64f
//! @endcond
/**
@brief Calculates all of the moments up to the third order of a polygon or rasterized shape for image
@param src_data Source image data
@param src_step Source image step
@param src_type source pints type
@param width Source image width
@param height Source image height
@param binary If it is true, all non-zero image pixels are treated as 1's
@param m Output array of moments (10 values) in the following order:
m00, m10, m01, m20, m11, m02, m30, m21, m12, m03.
@sa moments
*/
inline int hal_ni_imageMoments(const uchar* src_data, size_t src_step, int src_type, int width, int height, bool binary, double m[10])
{ return CV_HAL_ERROR_NOT_IMPLEMENTED; }
/**
@brief Calculates all of the moments up to the third order of a polygon of 2d points
@param src_data Source points (Point 2x32f or 2x32s)
@param src_size Source points count
@param src_type source pints type
@param m Output array of moments (10 values) in the following order:
m00, m10, m01, m20, m11, m02, m30, m21, m12, m03.
@sa moments
*/
inline int hal_ni_polygonMoments(const uchar* src_data, size_t src_size, int src_type, double m[10])
{ return CV_HAL_ERROR_NOT_IMPLEMENTED; }
//! @cond IGNORED
#define cv_hal_imageMoments hal_ni_imageMoments
#define cv_hal_polygonMoments hal_ni_polygonMoments
//! @endcond
//! @}
#if defined(__clang__)
@@ -40,7 +40,8 @@
//M*/
#include "precomp.hpp"
#include "opencl_kernels_imgproc.hpp"
#include "hal_replacement.hpp"
#include "opencl_kernels_geometry.hpp"
#include "opencv2/core/hal/intrin.hpp"
namespace cv
@@ -408,7 +409,7 @@ static bool ocl_moments( InputArray _src, Moments& m, bool binary)
if (ntiles == 0)
return false;
ocl::Kernel k = ocl::Kernel("moments", ocl::imgproc::moments_oclsrc,
ocl::Kernel k = ocl::Kernel("moments", ocl::geometry::moments_oclsrc,
format("-D TILE_SIZE=%d%s",
TILE_SIZE,
binary ? " -D OP_MOMENTS_BINARY" : ""));
+352
View File
@@ -0,0 +1,352 @@
/*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*/
#include "opencv2/core/types.hpp"
#include "precomp.hpp"
#include "distortion_model.hpp"
namespace cv {
Mat getDefaultNewCameraMatrix( InputArray _cameraMatrix, Size imgsize,
bool centerPrincipalPoint )
{
Mat cameraMatrix = _cameraMatrix.getMat();
if( !centerPrincipalPoint && cameraMatrix.type() == CV_64F )
return cameraMatrix;
Mat newCameraMatrix;
cameraMatrix.convertTo(newCameraMatrix, CV_64F);
if( centerPrincipalPoint )
{
newCameraMatrix.ptr<double>()[2] = (imgsize.width-1)*0.5;
newCameraMatrix.ptr<double>()[5] = (imgsize.height-1)*0.5;
}
return newCameraMatrix;
}
void calibrationMatrixValues( InputArray _cameraMatrix, Size imageSize,
double apertureWidth, double apertureHeight,
double& fovx, double& fovy, double& focalLength,
Point2d& principalPoint, double& aspectRatio )
{
CV_INSTRUMENT_REGION();
if(_cameraMatrix.size() != Size(3, 3))
CV_Error(cv::Error::StsUnmatchedSizes, "Size of cameraMatrix must be 3x3!");
Matx33d A;
_cameraMatrix.getMat().convertTo(A, CV_64F);
CV_DbgAssert(imageSize.width != 0 && imageSize.height != 0 && A(0, 0) != 0.0 && A(1, 1) != 0.0);
/* Calculate pixel aspect ratio. */
aspectRatio = A(1, 1) / A(0, 0);
/* Calculate number of pixel per realworld unit. */
double mx, my;
if(apertureWidth != 0.0 && apertureHeight != 0.0) {
mx = imageSize.width / apertureWidth;
my = imageSize.height / apertureHeight;
} else {
mx = 1.0;
my = aspectRatio;
}
/* Calculate fovx and fovy. */
fovx = atan2(A(0, 2), A(0, 0)) + atan2(imageSize.width - A(0, 2), A(0, 0));
fovy = atan2(A(1, 2), A(1, 1)) + atan2(imageSize.height - A(1, 2), A(1, 1));
fovx *= 180.0 / CV_PI;
fovy *= 180.0 / CV_PI;
/* Calculate focal length. */
focalLength = A(0, 0) / mx;
/* Calculate principle point. */
principalPoint = Point2d(A(0, 2) / mx, A(1, 2) / my);
}
static void undistortPointsInternal( const Mat& _src, Mat& _dst, const Mat& _cameraMatrix,
const Mat& _distCoeffs, const Mat& matR, const Mat& matP, TermCriteria criteria)
{
CV_Assert(criteria.isValid());
double A[3][3], RR[3][3], k[14]={0,0,0,0,0,0,0,0,0,0,0,0,0,0};
Mat matA(3, 3, CV_64F, A), _Dk;
Mat _RR(3, 3, CV_64F, RR);
cv::Matx33d invMatTilt = cv::Matx33d::eye();
cv::Matx33d matTilt = cv::Matx33d::eye();
bool haveDistCoeffs = !_distCoeffs.empty();
CV_Assert( (_src.rows == 1 || _src.cols == 1) &&
(_dst.rows == 1 || _dst.cols == 1) &&
_src.cols + _src.rows - 1 == _dst.rows + _dst.cols - 1 &&
(_src.type() == CV_32FC2 || _src.type() == CV_64FC2) &&
(_dst.type() == CV_32FC2 || _dst.type() == CV_64FC2));
CV_Assert( _cameraMatrix.rows == 3 && _cameraMatrix.cols == 3 && _cameraMatrix.channels() == 1 );
_cameraMatrix.convertTo(matA, CV_64F);
if( haveDistCoeffs )
{
CV_Assert(
(_distCoeffs.rows == 1 || _distCoeffs.cols == 1) &&
(_distCoeffs.rows*_distCoeffs.cols == 4 ||
_distCoeffs.rows*_distCoeffs.cols == 5 ||
_distCoeffs.rows*_distCoeffs.cols == 8 ||
_distCoeffs.rows*_distCoeffs.cols == 12 ||
_distCoeffs.rows*_distCoeffs.cols == 14));
_Dk = Mat( _distCoeffs.rows, _distCoeffs.cols,
CV_MAKETYPE(CV_64F,_distCoeffs.channels()), k);
_distCoeffs.convertTo(_Dk, CV_64F);
CV_Assert(_Dk.ptr<double>() == k);
if (k[12] != 0 || k[13] != 0)
{
computeTiltProjectionMatrix<double>(k[12], k[13], NULL, NULL, NULL, &invMatTilt);
computeTiltProjectionMatrix<double>(k[12], k[13], &matTilt, NULL, NULL);
}
}
if( !matR.empty() )
{
CV_Assert( matR.rows == 3 && matR.cols == 3 && matR.channels() == 1 );
matR.convertTo(_RR, CV_64F);
CV_Assert(_RR.ptr<double>() == &RR[0][0]);
}
else
setIdentity(_RR);
if( !matP.empty() )
{
double PP[3][3];
Mat _PP(3, 3, CV_64F, PP);
CV_Assert( matP.rows == 3 && (matP.cols == 3 || matP.cols == 4));
matP.colRange(0, 3).convertTo(_PP, CV_64F);
CV_Assert(_PP.ptr<double>() == &PP[0][0]);
_RR = _PP*_RR;
}
const Point2f* srcf = (const Point2f*)_src.data;
const Point2d* srcd = (const Point2d*)_src.data;
Point2f* dstf = (Point2f*)_dst.data;
Point2d* dstd = (Point2d*)_dst.data;
int stype = _src.type();
int dtype = _dst.type();
int sstep = _src.rows == 1 ? 1 : (int)(_src.step/_src.elemSize());
int dstep = _dst.rows == 1 ? 1 : (int)(_dst.step/_dst.elemSize());
double fx = A[0][0];
double fy = A[1][1];
double ifx = 1./fx;
double ify = 1./fy;
double cx = A[0][2];
double cy = A[1][2];
int n = _src.rows + _src.cols - 1;
for( int i = 0; i < n; i++ )
{
double x, y, x0 = 0, y0 = 0, u, v;
if( stype == CV_32FC2 )
{
x = srcf[i*sstep].x;
y = srcf[i*sstep].y;
}
else
{
x = srcd[i*sstep].x;
y = srcd[i*sstep].y;
}
// [u, v]^T = [fx * x''' + cx, fy * y''' + cy]^T =>
// [x''', y''']^T = [(u - cx) / fx, (v - cy) / fy]^T
u = x; v = y;
x = (x - cx)*ifx;
y = (y - cy)*ify;
if( haveDistCoeffs ) {
// compensate tilt distortion
// s * [x''', y''', 1]^T = matTilt * [x'', y'', 1]^T =>
// s * matTilt^{-1} * [x''', y''', 1]^T = [x'', y'', 1]^T =>
// (invMatTilt := matTilt^{-1}, vecUntilt := invMatTilt * [x''', y''', 1]^T)
// s * vecUntilt = [x'', y'', 1]^T =>
// s * vecUntilt_1 = x'', s * vecUntilt_2 = y'', s * vecUntilt_3 = 1 =>
// invProj := s = 1 / vecUntilt_3, x'' = invProj * vecUntilt_1, y'' = invProj * vecUntilt_2
cv::Vec3d vecUntilt = invMatTilt * cv::Vec3d(x, y, 1);
double invProj = vecUntilt(2) ? 1./vecUntilt(2) : 1;
x0 = x = invProj * vecUntilt(0);
y0 = y = invProj * vecUntilt(1);
double error = std::numeric_limits<double>::max();
double prevError = std::numeric_limits<double>::max();
// compensate distortion iteratively using fixed-point iteration
// parameter for damped fixed-point iteration
double alpha = 1.;
for( int j = 0; ; j++ )
{
if ((criteria.type & TermCriteria::COUNT) && j >= criteria.maxCount)
break;
if ((criteria.type & TermCriteria::EPS) && error < criteria.epsilon)
break;
// r^2 = x'^2 + y'^2
double r2 = x*x + y*y;
// icdist := (1 + k4 * r^2 + k5 * r^4 + k6 * r^6) / (1 + k1 * r^2 + k2 * r^4 + k3 * r^6)
double icdist = (1 + ((k[7]*r2 + k[6])*r2 + k[5])*r2)/(1 + ((k[4]*r2 + k[1])*r2 + k[0])*r2);
if (icdist < 0) // test: undistortPoints.regression_14583
{
x = (u - cx)*ifx;
y = (v - cy)*ify;
break;
}
// deltaX := 2 * p1 * x' * y' + p2 * (r^2 + 2 * x'^2) + s1 * r^2 + s2 * r^4
// deltaY := p1 * (r^2 + 2 * y'^2) + 2 * p2 * x' * y' + s3 * r^2 + s4 * r^4
double deltaX = 2*k[2]*x*y + k[3]*(r2 + 2*x*x)+ k[8]*r2+k[9]*r2*r2;
double deltaY = k[2]*(r2 + 2*y*y) + 2*k[3]*x*y+ k[10]*r2+k[11]*r2*r2;
// [x'', y'']^T = [x' / icdist + deltaX, y' / icdist + deltaY]^T =>
// [x', y']^T = [(x'' - deltaX) * icdist, (y'' - deltaY) * icdist]^T =>
// x' = f1(x') := (x'' - deltaX) * icdist, y' = f2(y') := (y'' - deltaY) * icdist
// Damped fixed-point iteration:
// f1(x') = (x'' - deltaX) * icdist, f2(y') = (y'' - deltaY) * icdist
// new_x' = (1 - alpha) * x' + alpha * f1(x'), new_y' = (1 - alpha) * y' + alpha * f2(y')
double new_x = (1. - alpha)*x + alpha*(x0 - deltaX)*icdist;
double new_y = (1. - alpha)*y + alpha*(y0 - deltaY)*icdist;
if(criteria.type & TermCriteria::EPS)
{
double r4, r6, a1, a2, a3, cdist, icdist2;
double xd, yd, xd0, yd0;
Vec3d vecTilt;
// r^2 = x'^2 + y'^2
r2 = new_x*new_x + new_y*new_y;
r4 = r2*r2;
r6 = r4*r2;
a1 = 2*new_x*new_y;
a2 = r2 + 2*new_x*new_x;
a3 = r2 + 2*new_y*new_y;
// cdist := 1 + k1 * r^2 + k2 * r^4 + k3 * r^6
cdist = 1 + k[0]*r2 + k[1]*r4 + k[4]*r6;
// icdist2 := 1 / (1 + k4 * r^2 + k5 * r^4 + k6 * r^6)
icdist2 = 1./(1 + k[5]*r2 + k[6]*r4 + k[7]*r6);
// x'' = x' * cdist * icdist2 + 2 * p1 * x' * y' + p2 * (r^2 + 2 * x'^2) + s1 * r^2 + s2 * r^4
// y'' = y' * cdist * icdist2 + p1 * (r^2 + 2 * y'^2) + 2 * p2 * x' * y' + s3 * r^2 + s4 * r^4
xd0 = new_x*cdist*icdist2 + k[2]*a1 + k[3]*a2 + k[8]*r2+k[9]*r4;
yd0 = new_y*cdist*icdist2 + k[2]*a3 + k[3]*a1 + k[10]*r2+k[11]*r4;
// s * [x''', y''', 1]^T = matTilt * [x'', y'', 1]^T =>
// (vecTilt := matTilt * [x'', y'', 1]^T)
// s * [x''', y''', 1]^T = vecTilt =>
// s * x''' = vecTilt_1, s * y''' = vecTilt_2, s = vecTilt_3 =>
// invProj := 1 / s = 1 / vecTilt_3, x''' = invProj * vecTilt_1, y''' = invProj * vecTilt_2
vecTilt = matTilt*cv::Vec3d(xd0, yd0, 1);
invProj = vecTilt(2) ? 1./vecTilt(2) : 1;
xd = invProj * vecTilt(0);
yd = invProj * vecTilt(1);
// [u, v]^T = [fx * x''' + cx, fy * y''' + cy]^T
double x_proj = xd*fx + cx;
double y_proj = yd*fy + cy;
error = sqrt( std::pow(x_proj - u, 2) + std::pow(y_proj - v, 2) );
}
if (error > prevError) {
alpha *= .5;
} else {
x = new_x;
y = new_y;
}
prevError = error;
}
}
if( !matR.empty() || !matP.empty() )
{
double xx = RR[0][0]*x + RR[0][1]*y + RR[0][2];
double yy = RR[1][0]*x + RR[1][1]*y + RR[1][2];
double ww = 1./(RR[2][0]*x + RR[2][1]*y + RR[2][2]);
x = xx*ww;
y = yy*ww;
}
if( dtype == CV_32FC2 )
{
dstf[i*dstep].x = (float)x;
dstf[i*dstep].y = (float)y;
}
else
{
dstd[i*dstep].x = x;
dstd[i*dstep].y = y;
}
}
}
void undistortPoints(InputArray _src, OutputArray _dst,
InputArray _cameraMatrix,
InputArray _distCoeffs,
InputArray _Rmat,
InputArray _Pmat,
TermCriteria criteria)
{
Mat src = _src.getMat(), cameraMatrix = _cameraMatrix.getMat();
Mat distCoeffs = _distCoeffs.getMat(), R = _Rmat.getMat(), P = _Pmat.getMat();
int npoints = src.checkVector(2), depth = src.depth();
if (npoints < 0)
src = src.t();
npoints = src.checkVector(2);
CV_Assert(npoints >= 0 && src.isContinuous() && (depth == CV_32F || depth == CV_64F));
if (src.cols == 2)
src = src.reshape(2);
_dst.create(npoints, 1, CV_MAKETYPE(depth, 2), -1, true);
Mat dst = _dst.getMat();
undistortPointsInternal(src, dst, cameraMatrix, distCoeffs, R, P, criteria);
}
void undistortImagePoints(InputArray src, OutputArray dst, InputArray cameraMatrix, InputArray distCoeffs, TermCriteria termCriteria)
{
undistortPoints(src, dst, cameraMatrix, distCoeffs, noArray(), cameraMatrix, termCriteria);
}
}
/* End of file */
-1
View File
@@ -63,7 +63,6 @@
#include "opencv2/core/utils/trace.hpp"
#include "opencv2/geometry.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/core/ocl.hpp"
#include "opencv2/core/hal/intrin.hpp"
-41
View File
@@ -87,47 +87,6 @@ static bool approxEqual(double a, double b, double eps)
}
#endif
void drawFrameAxes(InputOutputArray image, InputArray cameraMatrix, InputArray distCoeffs,
InputArray rvec, InputArray tvec, float length, int thickness)
{
CV_INSTRUMENT_REGION();
int type = image.type();
int cn = CV_MAT_CN(type);
CV_CheckType(type, cn == 1 || cn == 3 || cn == 4,
"Number of channels must be 1, 3 or 4" );
cv::Mat img = image.getMat();
CV_Assert(img.total() > 0);
CV_Assert(length > 0);
// project axes points
std::vector<Point3f> axesPoints;
axesPoints.push_back(Point3f(0, 0, 0));
axesPoints.push_back(Point3f(length, 0, 0));
axesPoints.push_back(Point3f(0, length, 0));
axesPoints.push_back(Point3f(0, 0, length));
std::vector<Point2f> imagePoints;
projectPoints(axesPoints, rvec, tvec, cameraMatrix, distCoeffs, imagePoints);
cv::Rect imageRect(0, 0, img.cols, img.rows);
bool allIn = true;
for (size_t i = 0; i < imagePoints.size(); i++)
{
allIn &= imageRect.contains(imagePoints[i]);
}
if (!allIn)
{
CV_LOG_WARNING(NULL, "Some of projected axes endpoints are out of frame. The drawn axes may be not reliable.");
}
// draw axes lines
line(image, imagePoints[0], imagePoints[1], Scalar(0, 0, 255), thickness);
line(image, imagePoints[0], imagePoints[2], Scalar(0, 255, 0), thickness);
line(image, imagePoints[0], imagePoints[3], Scalar(255, 0, 0), thickness);
}
bool solvePnP( InputArray opoints, InputArray ipoints,
InputArray cameraMatrix, InputArray distCoeffs,
OutputArray rvec, OutputArray tvec, bool useExtrinsicGuess, int flags )
@@ -4,7 +4,7 @@
#include "../precomp.hpp"
#include "../usac.hpp"
#include "opencv2/imgproc/detail/gcgraph.hpp"
#include "opencv2/geometry/detail/gcgraph.hpp"
namespace cv { namespace usac {
class GraphCutImpl : public GraphCut {
@@ -60,9 +60,9 @@ protected:
points.push_back(Point(49, 51));
Moments m = moments(points, false);
// double area = contourArea(points);
double area = contourArea(points);
CV_Assert( m.m00 == 0 && m.m01 == 0 && m.m10 == 0 /*&& area == 0*/ );
CV_Assert( m.m00 == 0 && m.m01 == 0 && m.m10 == 0 && area == 0 );
}
catch(...)
{
@@ -73,4 +73,19 @@ protected:
TEST(Imgproc_ContourMoment, small) { CV_SmallContourMomentTest test; test.safe_run(); }
TEST(Imgproc_Moments, degenerateContours)
{
std::vector<cv::Point> c1;
c1.push_back(cv::Point(10,10));
cv::Moments m1 = cv::moments(c1, false);
EXPECT_EQ(m1.m00, 0);
std::vector<cv::Point> c2;
c2.push_back(cv::Point(0,0));
c2.push_back(cv::Point(5,5));
c2.push_back(cv::Point(10,10));
cv::Moments m2 = cv::moments(c2, false);
EXPECT_EQ(m2.m00, 0);
}
}} // namespace
+4 -1
View File
@@ -1,4 +1,5 @@
set(the_description "Image Processing")
ocv_add_dispatched_file(accum SSE4_1 AVX AVX2)
ocv_add_dispatched_file(bilateral_filter SSE2 AVX2 AVX512_SKX AVX512_ICL)
ocv_add_dispatched_file(box_filter SSE2 SSE4_1 AVX2 AVX512_SKX)
@@ -11,7 +12,9 @@ ocv_add_dispatched_file(morph SSE2 SSE4_1 AVX2)
ocv_add_dispatched_file(smooth SSE2 SSE4_1 AVX2 AVX512_ICL)
ocv_add_dispatched_file(sumpixels SSE2 AVX2 AVX512_SKX)
ocv_add_dispatched_file(warp_kernels SSE2 SSE4_1 AVX2 NEON NEON_FP16 RVV LASX)
ocv_define_module(imgproc opencv_core WRAP java objc python js)
ocv_add_dispatched_file(undistort SSE2 AVX2)
ocv_define_module(imgproc opencv_core opencv_geometry WRAP java objc python js)
ocv_module_include_directories(opencv_imgproc ${ZLIB_INCLUDE_DIRS})
+351 -148
View File
@@ -295,19 +295,6 @@ enum InterpolationMasks {
//! @addtogroup imgproc_misc
//! @{
//! Distance types for Distance Transform and M-estimators
//! @see distanceTransform, fitLine
enum DistanceTypes {
DIST_USER = -1, //!< User defined distance
DIST_L1 = 1, //!< distance = |x1-x2| + |y1-y2|
DIST_L2 = 2, //!< the simple euclidean distance
DIST_C = 3, //!< distance = max(|x1-x2|,|y1-y2|)
DIST_L12 = 4, //!< L1-L2 metric: distance = 2(sqrt(1+x*x/2) - 1))
DIST_FAIR = 5, //!< distance = c^2(|x|/c-log(1+|x|/c)), c = 1.3998
DIST_WELSCH = 6, //!< distance = c^2/2(1-exp(-(x/c)^2)), c = 2.9846
DIST_HUBER = 7 //!< distance = |x|<c ? x^2/2 : c(|x|-c/2), c=1.345
};
//! Mask size for distance transform
enum DistanceTransformMasks {
DIST_MASK_3 = 3, //!< mask=3
@@ -522,6 +509,14 @@ enum HistCompMethods {
HISTCMP_KL_DIV = 5
};
//! Variants of Line Segment %Detector
enum LineSegmentDetectorModes {
LSD_REFINE_NONE = 0, //!< No refinement applied
LSD_REFINE_STD = 1, //!< Standard refinement is applied. E.g. breaking arches into smaller straighter line approximations.
LSD_REFINE_ADV = 2 //!< Advanced refinement. Number of false alarms is calculated, lines are
//!< refined through increase of precision, decrement in size, etc.
};
/** the color conversion codes
@see @ref imgproc_color_conversions
@note The source image (src) must be of an appropriate type for the desired color conversion.
@@ -1072,6 +1067,90 @@ public:
//! @} imgproc_hist
//! @addtogroup imgproc_feature
//! @{
/** @example samples/cpp/snippets/lsd_lines.cpp
An example using the LineSegmentDetector
\image html building_lsd.png "Sample output image" width=434 height=300
*/
/** @brief Line segment detector class
following the algorithm described at @cite Rafael12 .
@note Implementation has been removed from OpenCV version 3.4.6 to 3.4.15 and version 4.1.0 to 4.5.3 due original code license conflict.
restored again after [Computation of a NFA](https://github.com/rafael-grompone-von-gioi/binomial_nfa) code published under the MIT license.
*/
class CV_EXPORTS_W LineSegmentDetector : public Algorithm
{
public:
/** @brief Finds lines in the input image.
This is the output of the default parameters of the algorithm on the above shown image.
![image](pics/building_lsd.png)
@param image A grayscale (CV_8UC1) input image. If only a roi needs to be selected, use:
`lsd_ptr-\>detect(image(roi), lines, ...); lines += Scalar(roi.x, roi.y, roi.x, roi.y);`
@param lines A vector of Vec4f elements specifying the beginning and ending point of a line. Where
Vec4f is (x1, y1, x2, y2), point 1 is the start, point 2 - end. Returned lines are strictly
oriented depending on the gradient.
@param width Vector of widths of the regions, where the lines are found. E.g. Width of line.
@param prec Vector of precisions with which the lines are found.
@param nfa Vector containing number of false alarms in the line region, with precision of 10%. The
bigger the value, logarithmically better the detection.
- -1 corresponds to 10 mean false alarms
- 0 corresponds to 1 mean false alarm
- 1 corresponds to 0.1 mean false alarms
This vector will be calculated only when the objects type is #LSD_REFINE_ADV.
*/
CV_WRAP virtual void detect(InputArray image, OutputArray lines,
OutputArray width = noArray(), OutputArray prec = noArray(),
OutputArray nfa = noArray()) = 0;
/** @brief Draws the line segments on a given image.
@param image The image, where the lines will be drawn. Should be bigger or equal to the image,
where the lines were found.
@param lines A vector of the lines that needed to be drawn.
*/
CV_WRAP virtual void drawSegments(InputOutputArray image, InputArray lines) = 0;
/** @brief Draws two groups of lines in blue and red, counting the non overlapping (mismatching) pixels.
@param size The size of the image, where lines1 and lines2 were found.
@param lines1 The first group of lines that needs to be drawn. It is visualized in blue color.
@param lines2 The second group of lines. They visualized in red color.
@param image Optional image, where the lines will be drawn. The image should be color(3-channel)
in order for lines1 and lines2 to be drawn in the above mentioned colors.
*/
CV_WRAP virtual int compareSegments(const Size& size, InputArray lines1, InputArray lines2, InputOutputArray image = noArray()) = 0;
virtual ~LineSegmentDetector() { }
};
/** @brief Creates a smart pointer to a LineSegmentDetector object and initializes it.
The LineSegmentDetector algorithm is defined using the standard values. Only advanced users may want
to edit those, as to tailor it for their own application.
@param refine The way found lines will be refined, see #LineSegmentDetectorModes
@param scale The scale of the image that will be used to find the lines. Range (0..1].
@param sigma_scale Sigma for Gaussian filter. It is computed as sigma = sigma_scale/scale.
@param quant Bound to the quantization error on the gradient norm.
@param ang_th Gradient angle tolerance in degrees.
@param log_eps Detection threshold: -log10(NFA) \> log_eps. Used only when advance refinement is chosen.
@param density_th Minimal density of aligned region points in the enclosing rectangle.
@param n_bins Number of bins in pseudo-ordering of gradient modulus.
*/
CV_EXPORTS_W Ptr<LineSegmentDetector> createLineSegmentDetector(
LineSegmentDetectorModes refine = LSD_REFINE_STD, double scale = 0.8,
double sigma_scale = 0.6, double quant = 2.0, double ang_th = 22.5,
double log_eps = 0, double density_th = 0.7, int n_bins = 1024);
//! @} imgproc_feature
//! @addtogroup imgproc_filter
//! @{
@@ -2166,89 +2245,252 @@ 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);
/** @sa getRotationMatrix2D */
CV_EXPORTS Matx23d getRotationMatrix2D_(Point2f center, double angle, double scale);
inline
Mat getRotationMatrix2D(Point2f center, double angle, double scale)
//! cv::undistort mode
enum UndistortTypes
{
return Mat(getRotationMatrix2D_(center, angle, scale), true);
PROJ_SPHERICAL_ORTHO = 0,
PROJ_SPHERICAL_EQRECT = 1
};
/** @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 #initUndistortRectifyMap (with unity R ) and #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 #getOptimalNewCameraMatrix to compute the appropriate
newCameraMatrix depending on your requirements.
The camera matrix and the distortion parameters can be determined using #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
#getOptimalNewCameraMatrix for a better control over scaling. In case of a stereo camera,
newCameraMatrix is normally set to P1 or P2 computed by #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 #stereoCalibrate. But if the stereo camera
was not calibrated, it is still possible to compute the rectification transformations directly from
the fundamental matrix using #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 #initUndistortRectifyMap 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, CV_32FC2 or CV_16SC2, see #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);
/** @brief Computes the projection and inverse-rectification transformation map. In essense, this is the inverse of
#initUndistortRectifyMap to accomodate stereo-rectification of projectors ('inverse-cameras') in projector-camera pairs.
The function computes the joint projection and inverse rectification transformation and represents the
result in the form of maps for #remap. The projected image looks like a distorted version of the original which,
once projected by a projector, should visually match the original. In case of a monocular camera, newCameraMatrix
is usually equal to cameraMatrix, or it can be computed by
#getOptimalNewCameraMatrix for a better control over scaling. In case of a projector-camera pair,
newCameraMatrix is normally set to P1 or P2 computed by #stereoRectify .
The projector is oriented differently in the coordinate space, according to R. In case of projector-camera pairs,
this helps align the projector (in the same manner as #initUndistortRectifyMap for the camera) to create a stereo-rectified pair. This
allows epipolar lines on both images to become horizontal and have the same y-coordinate (in case of a horizontally aligned projector-camera pair).
The function 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 (projected and inverse-rectified) image, the function
computes the corresponding coordinates in the source image (that is, in the original digital image). The following process is applied:
\f[
\begin{array}{l}
\text{newCameraMatrix}\\
x \leftarrow (u - {c'}_x)/{f'}_x \\
y \leftarrow (v - {c'}_y)/{f'}_y \\
\\\text{Undistortion}
\\\scriptsize{\textit{though equation shown is for radial undistortion, function implements cv::undistortPoints()}}\\
r^2 \leftarrow x^2 + y^2 \\
\theta \leftarrow \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}\\
x' \leftarrow \frac{x}{\theta} \\
y' \leftarrow \frac{y}{\theta} \\
\\\text{Rectification}\\
{[X\,Y\,W]} ^T \leftarrow R*[x' \, y' \, 1]^T \\
x'' \leftarrow X/W \\
y'' \leftarrow Y/W \\
\\\text{cameraMatrix}\\
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 vector distCoeffs.
In case of a stereo-rectified projector-camera pair, this function is called for the projector while #initUndistortRectifyMap is called for the camera head.
This is done after #stereoRectify, which in turn is called after #stereoCalibrate. If the projector-camera pair
is not calibrated, it is still possible to compute the rectification transformations directly from
the fundamental matrix using #stereoRectifyUncalibrated. For the projector and 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.
@param newCameraMatrix New camera matrix \f$A'=\vecthreethree{f_x'}{0}{c_x'}{0}{f_y'}{c_y'}{0}{0}{1}\f$.
@param size Distorted image size.
@param m1type Type of the first output map. Can be CV_32FC1, CV_32FC2 or CV_16SC2, see #convertMaps
@param map1 The first output map for #remap.
@param map2 The second output map for #remap.
*/
CV_EXPORTS_W
void initInverseRectificationMap( InputArray cameraMatrix, InputArray distCoeffs,
InputArray R, InputArray newCameraMatrix,
const Size& size, int m1type, OutputArray map1, OutputArray map2 );
//! initializes maps for #remap for wide-angle
CV_EXPORTS
float initWideAngleProjMap(InputArray cameraMatrix, InputArray distCoeffs,
Size imageSize, int destImageWidth,
int m1type, OutputArray map1, OutputArray map2,
enum UndistortTypes projType = PROJ_SPHERICAL_EQRECT, double alpha = 0);
static inline
float initWideAngleProjMap(InputArray cameraMatrix, InputArray distCoeffs,
Size imageSize, int destImageWidth,
int m1type, OutputArray map1, OutputArray map2,
int projType, double alpha = 0)
{
return initWideAngleProjMap(cameraMatrix, distCoeffs, imageSize, destImageWidth,
m1type, map1, map2, (UndistortTypes)projType, alpha);
}
/** @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
namespace fisheye {
/** @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 intrinsic matrix \f$cameramatrix{K}\f$.
@param D Input vector of distortion coefficients \f$\distcoeffsfisheye\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 intrinsic 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 Mat getAffineTransform( const Point2f src[], const Point2f dst[] );
CV_EXPORTS_W void initUndistortRectifyMap(InputArray K, InputArray D, InputArray R, InputArray P,
const cv::Size& size, int m1type, OutputArray map1, OutputArray map2);
/** @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.
/** @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 intrinsic matrix \f$cameramatrix{K}\f$.
@param D Input vector of distortion coefficients \f$\distcoeffsfisheye\f$.
@param Knew Camera intrinsic 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 new size
The function transforms an image to compensate radial and tangential lens distortion.
The function is simply a combination of #cv::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 #cv::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.
![image](pics/fisheye_undistorted.jpg)
*/
CV_EXPORTS_W void invertAffineTransform( InputArray M, OutputArray iM );
CV_EXPORTS_W void undistortImage(InputArray distorted, OutputArray undistorted,
InputArray K, InputArray D, InputArray Knew = cv::noArray(), const Size& new_size = Size());
/** @brief Calculates a perspective transform from four pairs of the corresponding points.
*
* The function calculates the \f$3 \times 3\f$ matrix of a perspective transform so that:
*
* \f[\begin{bmatrix} t_i x'_i \\ t_i y'_i \\ t_i \end{bmatrix} = \texttt{map_matrix} \cdot \begin{bmatrix} x_i \\ y_i \\ 1 \end{bmatrix}\f]
*
* where
*
* \f[dst(i)=(x'_i,y'_i), src(i)=(x_i, y_i), i=0,1,2,3\f]
*
* @param src Coordinates of quadrangle vertices in the source image.
* @param dst Coordinates of the corresponding quadrangle vertices in the destination image.
* @param solveMethod method passed to cv::solve (#DecompTypes)
*
* @sa findHomography, warpPerspective, perspectiveTransform
*/
CV_EXPORTS_W Mat getPerspectiveTransform(InputArray src, InputArray dst, int solveMethod = DECOMP_LU);
/** @overload */
CV_EXPORTS Mat getPerspectiveTransform(const Point2f src[], const Point2f dst[], int solveMethod = DECOMP_LU);
CV_EXPORTS_W Mat getAffineTransform( InputArray src, InputArray dst );
}
/** @brief Retrieves a pixel rectangle from an image with sub-pixel accuracy.
@@ -3337,65 +3579,6 @@ CV_EXPORTS_W void demosaicing(InputArray src, OutputArray dst, int code, int dst
//! @} imgproc_color_conversions
//! @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 Single channel raster image (CV_8U, CV_16U, CV_16S, CV_32F, CV_64F) or an array (
\f$1 \times N\f$ or \f$N \times 1\f$ ) of 2D points (Point or Point2f).
@param binaryImage If it is true, all non-zero image pixels are treated as 1's. The parameter is
used for images only.
@returns moments.
@note Only applicable to contour moments calculations from Python bindings: Note that the numpy
type for the input array should be either np.int32 or np.float32.
@note For contour-based moments, the zeroth-order moment \c m00 represents
the contour area.
If the input contour is degenerate (for example, a single point or all points
are collinear), the area is zero and therefore \c m00 == 0.
In this case, the centroid coordinates (\c m10/m00, \c m01/m00) are undefined
and must be handled explicitly by the caller.
A common workaround is to compute the center using cv::boundingRect() or by
averaging the input points.
@sa contourArea, arcLength
*/
CV_EXPORTS_W Moments moments( InputArray array, bool binaryImage = false );
/** @brief Calculates seven Hu invariants.
The function calculates seven Hu invariants (introduced in @cite Hu62; see also
<https://en.wikipedia.org/wiki/Image_moment>) defined as:
\f[\begin{array}{l} hu[0]= \eta _{20}+ \eta _{02} \\ hu[1]=( \eta _{20}- \eta _{02})^{2}+4 \eta _{11}^{2} \\ hu[2]=( \eta _{30}-3 \eta _{12})^{2}+ (3 \eta _{21}- \eta _{03})^{2} \\ hu[3]=( \eta _{30}+ \eta _{12})^{2}+ ( \eta _{21}+ \eta _{03})^{2} \\ hu[4]=( \eta _{30}-3 \eta _{12})( \eta _{30}+ \eta _{12})[( \eta _{30}+ \eta _{12})^{2}-3( \eta _{21}+ \eta _{03})^{2}]+(3 \eta _{21}- \eta _{03})( \eta _{21}+ \eta _{03})[3( \eta _{30}+ \eta _{12})^{2}-( \eta _{21}+ \eta _{03})^{2}] \\ hu[5]=( \eta _{20}- \eta _{02})[( \eta _{30}+ \eta _{12})^{2}- ( \eta _{21}+ \eta _{03})^{2}]+4 \eta _{11}( \eta _{30}+ \eta _{12})( \eta _{21}+ \eta _{03}) \\ hu[6]=(3 \eta _{21}- \eta _{03})( \eta _{21}+ \eta _{03})[3( \eta _{30}+ \eta _{12})^{2}-( \eta _{21}+ \eta _{03})^{2}]-( \eta _{30}-3 \eta _{12})( \eta _{21}+ \eta _{03})[3( \eta _{30}+ \eta _{12})^{2}-( \eta _{21}+ \eta _{03})^{2}] \\ \end{array}\f]
where \f$\eta_{ji}\f$ stands for \f$\texttt{Moments::nu}_{ji}\f$ .
These values are proved to be invariants to the image scale, rotation, and reflection except the
seventh one, whose sign is changed by reflection. This invariance is proved with the assumption of
infinite image resolution. In case of raster images, the computed Hu invariants for the original and
transformed images are a bit different.
@param moments Input moments computed with moments .
@param hu Output Hu invariants.
@sa matchShapes
*/
CV_EXPORTS void HuMoments( const Moments& moments, double hu[7] );
/** @overload */
CV_EXPORTS_W void HuMoments( const Moments& m, OutputArray hu );
//! @} imgproc_shape
//! @addtogroup imgproc_object
//! @{
@@ -3719,6 +3902,26 @@ The function cv::arrowedLine draws an arrow between pt1 and pt2 points in the im
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 Draw axes of the world/object coordinate system from pose estimation. @sa solvePnP
*
* @param image Input/output image. It must have 1 or 3 channels. The number of channels is not altered.
* @param cameraMatrix Input 3x3 floating-point matrix of camera intrinsic parameters.
* \f$\cameramatrix{A}\f$
* @param distCoeffs Input vector of distortion coefficients
* \f$\distcoeffs\f$. If the vector is empty, the zero distortion coefficients are assumed.
* @param rvec Rotation vector (see @ref Rodrigues ) that, together with tvec, brings points from
* the model coordinate system to the camera coordinate system.
* @param tvec Translation vector.
* @param length Length of the painted axes in the same unit than tvec (usually in meters).
* @param thickness Line thickness of the painted axes.
*
* This function draws the axes of the world/object coordinate system w.r.t. to the camera frame.
* OX is drawn in red, OY in green and OZ in blue.
*/
CV_EXPORTS_W void drawFrameAxes(InputOutputArray image, InputArray cameraMatrix, InputArray distCoeffs,
InputArray rvec, InputArray tvec, float length, int thickness=3);
/** @brief Draws a simple, thick, or filled up-right rectangle.
The function cv::rectangle draws a rectangle outline or a filled rectangle whose two opposite corners
+1 -20
View File
@@ -105,26 +105,7 @@
}
},
"func_arg_fix" : {
"minEnclosingCircle" : { "points" : {"ctype" : "vector_Point2f"} },
"fitEllipse" : { "points" : {"ctype" : "vector_Point2f"} },
"fillPoly" : { "pts" : {"ctype" : "vector_vector_Point"} },
"polylines" : { "pts" : {"ctype" : "vector_vector_Point"} },
"fillConvexPoly" : { "points" : {"ctype" : "vector_Point"} },
"approxPolyDP" : { "curve" : {"ctype" : "vector_Point2f"},
"approxCurve" : {"ctype" : "vector_Point2f"} },
"arcLength" : { "curve" : {"ctype" : "vector_Point2f"} },
"pointPolygonTest" : { "contour" : {"ctype" : "vector_Point2f"} },
"minAreaRect" : { "points" : {"ctype" : "vector_Point2f"} },
"getAffineTransform" : { "src" : {"ctype" : "vector_Point2f"},
"dst" : {"ctype" : "vector_Point2f"} },
"drawContours" : {"contours" : {"ctype" : "vector_vector_Point"} },
"findContours" : {"contours" : {"ctype" : "vector_vector_Point"} },
"convexityDefects" : { "contour" : {"ctype" : "vector_Point"},
"convexhull" : {"ctype" : "vector_int"},
"convexityDefects" : {"ctype" : "vector_Vec4i"} },
"isContourConvex" : { "contour" : {"ctype" : "vector_Point"} },
"convexHull" : { "points" : {"ctype" : "vector_Point"},
"hull" : {"ctype" : "vector_int"},
"returnPoints" : {"ctype" : ""} }
"findContours" : {"contours" : {"ctype" : "vector_vector_Point"} }
}
}
+96 -40
View File
@@ -19,6 +19,7 @@ import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.core.TermCriteria;
import org.opencv.imgproc.Imgproc;
import org.opencv.geometry.Geometry;
import org.opencv.test.OpenCVTestCase;
public class ImgprocTest extends OpenCVTestCase {
@@ -524,7 +525,7 @@ public class ImgprocTest extends OpenCVTestCase {
Mat dstLables = getMat(CvType.CV_32SC1, 0);
Mat labels = new Mat();
Imgproc.distanceTransformWithLabels(gray128, dst, labels, Imgproc.DIST_L2, 3);
Imgproc.distanceTransformWithLabels(gray128, dst, labels, Geometry.DIST_L2, 3);
assertMatEqual(dstLables, labels);
assertMatEqual(getMat(CvType.CV_32FC1, 65533.805), dst, EPS);
@@ -741,21 +742,6 @@ public class ImgprocTest extends OpenCVTestCase {
// TODO_: write better test
}
public void testGetAffineTransform() {
MatOfPoint2f src = new MatOfPoint2f(new Point(2, 3), new Point(3, 1), new Point(1, 4));
MatOfPoint2f dst = new MatOfPoint2f(new Point(3, 3), new Point(7, 4), new Point(5, 6));
Mat transform = Imgproc.getAffineTransform(src, dst);
Mat truth = new Mat(2, 3, CvType.CV_64FC1) {
{
put(0, 0, -8, -6, 37);
put(1, 0, -7, -4, 29);
}
};
assertMatEqual(truth, transform, EPS);
}
public void testGetDerivKernelsMatMatIntIntInt() {
Mat kx = new Mat(imgprocSz, imgprocSz, CvType.CV_32F);
Mat ky = new Mat(imgprocSz, imgprocSz, CvType.CV_32F);
@@ -833,21 +819,6 @@ public class ImgprocTest extends OpenCVTestCase {
assertMatEqual(truth, dst, EPS);
}
public void testGetRotationMatrix2D() {
Point center = new Point(0, 0);
dst = Imgproc.getRotationMatrix2D(center, 0, 1);
truth = new Mat(2, 3, CvType.CV_64F) {
{
put(0, 0, 1, 0, 0);
put(1, 0, 0, 1, 0);
}
};
assertMatEqual(truth, dst, EPS);
}
public void testGetStructuringElementIntSize() {
dst = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, size);
@@ -1095,15 +1066,6 @@ public class ImgprocTest extends OpenCVTestCase {
assertMatEqual(truth, dst, EPS);
}
public void testInvertAffineTransform() {
Mat src = new Mat(2, 3, CvType.CV_64F, new Scalar(1));
Imgproc.invertAffineTransform(src, dst);
truth = new Mat(2, 3, CvType.CV_64F, new Scalar(0));
assertMatEqual(truth, dst, EPS);
}
public void testLaplacianMatMatInt() {
Imgproc.Laplacian(gray0, dst, CvType.CV_8U);
@@ -1863,4 +1825,98 @@ public class ImgprocTest extends OpenCVTestCase {
Imgproc.rectangle(img, new Point(10, 10), new Point(labelSize.width + 10, labelSize.height + 10), colorBlack, Imgproc.FILLED);
assertEquals(0, Core.countNonZero(img));
}
public void testInitUndistortRectifyMap() {
fail("Not yet implemented");
Mat cameraMatrix = new Mat(3, 3, CvType.CV_32F);
cameraMatrix.put(0, 0, 1, 0, 1);
cameraMatrix.put(1, 0, 0, 1, 1);
cameraMatrix.put(2, 0, 0, 0, 1);
Mat R = new Mat(3, 3, CvType.CV_32F, new Scalar(2));
Mat newCameraMatrix = new Mat(3, 3, CvType.CV_32F, new Scalar(3));
Mat distCoeffs = new Mat();
Mat map1 = new Mat();
Mat map2 = new Mat();
// TODO: complete this test
Imgproc.initUndistortRectifyMap(cameraMatrix, distCoeffs, R, newCameraMatrix, size, CvType.CV_32F, map1, map2);
}
public void testInitWideAngleProjMapMatMatSizeIntIntMatMat() {
fail("Not yet implemented");
Mat cameraMatrix = new Mat(3, 3, CvType.CV_32F);
Mat distCoeffs = new Mat(1, 4, CvType.CV_32F);
// Size imageSize = new Size(2, 2);
cameraMatrix.put(0, 0, 1, 0, 1);
cameraMatrix.put(1, 0, 0, 1, 2);
cameraMatrix.put(2, 0, 0, 0, 1);
distCoeffs.put(0, 0, 1, 3, 2, 4);
truth = new Mat(3, 3, CvType.CV_32F);
truth.put(0, 0, 0, 0, 0);
truth.put(1, 0, 0, 0, 0);
truth.put(2, 0, 0, 3, 0);
// TODO: No documentation for this function
// Imgproc.initWideAngleProjMap(cameraMatrix, distCoeffs, imageSize,
// 5, m1type, truthput1, truthput2);
}
public void testInitWideAngleProjMapMatMatSizeIntIntMatMatInt() {
fail("Not yet implemented");
}
public void testInitWideAngleProjMapMatMatSizeIntIntMatMatIntDouble() {
fail("Not yet implemented");
}
public void testUndistortMatMatMatMat() {
Mat src = new Mat(3, 3, CvType.CV_32F, new Scalar(3));
Mat cameraMatrix = new Mat(3, 3, CvType.CV_32F) {
{
put(0, 0, 1, 0, 1);
put(1, 0, 0, 1, 2);
put(2, 0, 0, 0, 1);
}
};
Mat distCoeffs = new Mat(1, 4, CvType.CV_32F) {
{
put(0, 0, 1, 3, 2, 4);
}
};
Imgproc.undistort(src, dst, cameraMatrix, distCoeffs);
truth = new Mat(3, 3, CvType.CV_32F) {
{
put(0, 0, 0, 0, 0);
put(1, 0, 0, 0, 0);
put(2, 0, 0, 3, 0);
}
};
assertMatEqual(truth, dst, EPS);
}
public void testUndistortMatMatMatMatMat() {
Mat src = new Mat(3, 3, CvType.CV_32F, new Scalar(3));
Mat cameraMatrix = new Mat(3, 3, CvType.CV_32F) {
{
put(0, 0, 1, 0, 1);
put(1, 0, 0, 1, 2);
put(2, 0, 0, 0, 1);
}
};
Mat distCoeffs = new Mat(1, 4, CvType.CV_32F) {
{
put(0, 0, 2, 1, 4, 5);
}
};
Mat newCameraMatrix = new Mat(3, 3, CvType.CV_32F, new Scalar(1));
Imgproc.undistort(src, dst, cameraMatrix, distCoeffs, newCameraMatrix);
truth = new Mat(3, 3, CvType.CV_32F, new Scalar(3));
assertMatEqual(truth, dst, EPS);
}
}
+2 -7
View File
@@ -32,6 +32,7 @@
"distanceTransformWithLabels",
"drawContours",
"drawMarker",
"drawFrameAxes",
"ellipse",
"ellipse2Poly",
"equalizeHist",
@@ -42,26 +43,21 @@
"findContours",
"findContoursLinkRuns",
"floodFill",
"fisheye_initUndistortRectifyMap",
"GaussianBlur",
"getAffineTransform",
"getFontScaleFromHeight",
"getPerspectiveTransform",
"getRectSubPix",
"getRotationMatrix2D",
"getStructuringElement",
"grabCut",
"HoughCircles",
"HoughLines",
"HoughLinesP",
"HuMoments",
"integral",
"integral2",
"invertAffineTransform",
"Laplacian",
"line",
"matchTemplate",
"medianBlur",
"moments",
"morphologyEx",
"polylines",
"preCornerDetect",
@@ -71,7 +67,6 @@
"rectangle",
"remap",
"resize",
"rotatedRectangleIntersection",
"Scharr",
"sepFilter2D",
"Sobel",
-21
View File
@@ -45,39 +45,22 @@
},
"func_arg_fix" : {
"Imgproc" : {
"minEnclosingCircle" : { "points" : {"ctype" : "vector_Point2f"} },
"fitEllipse" : { "points" : {"ctype" : "vector_Point2f"} },
"fillPoly" : { "pts" : {"ctype" : "vector_vector_Point"},
"lineType" : {"ctype" : "LineTypes"}},
"polylines" : { "pts" : {"ctype" : "vector_vector_Point"},
"lineType" : {"ctype" : "LineTypes"} },
"fillConvexPoly" : { "points" : {"ctype" : "vector_Point"},
"lineType" : {"ctype" : "LineTypes"} },
"approxPolyDP" : { "curve" : {"ctype" : "vector_Point2f"},
"approxCurve" : {"ctype" : "vector_Point2f"} },
"arcLength" : { "curve" : {"ctype" : "vector_Point2f"} },
"pointPolygonTest" : { "contour" : {"ctype" : "vector_Point2f"} },
"minAreaRect" : { "points" : {"ctype" : "vector_Point2f"} },
"getAffineTransform" : { "src" : {"ctype" : "vector_Point2f"},
"dst" : {"ctype" : "vector_Point2f"} },
"drawContours" : { "contours" : {"ctype" : "vector_vector_Point"},
"lineType" : {"ctype" : "LineTypes"} },
"findContours" : { "contours" : {"ctype" : "vector_vector_Point"},
"mode" : {"ctype" : "RetrievalModes"},
"method" : {"ctype" : "ContourApproximationModes"} },
"convexityDefects" : { "contour" : {"ctype" : "vector_Point"},
"convexhull" : {"ctype" : "vector_int"},
"convexityDefects" : {"ctype" : "vector_Vec4i"} },
"isContourConvex" : { "contour" : {"ctype" : "vector_Point"} },
"convexHull" : { "points" : {"ctype" : "vector_Point"},
"hull" : {"ctype" : "vector_int"},
"returnPoints" : {"ctype" : ""} },
"getStructuringElement" : { "shape" : {"ctype" : "MorphShapes"} },
"EMD" : {"lowerBound" : {"defval" : "cv::Ptr<float>()"},
"distType" : {"ctype" : "DistanceTypes"}},
"createLineSegmentDetector" : { "_refine" : {"ctype" : "LineSegmentDetectorModes"}},
"compareHist" : { "method" : {"ctype" : "HistCompMethods"}},
"matchShapes" : { "method" : {"ctype" : "ShapeMatchModes"}},
"threshold" : { "type" : {"ctype" : "ThresholdTypes"}},
"connectedComponentsWithStatsWithAlgorithm" : { "ccltype" : {"ctype" : "ConnectedComponentsAlgorithmsTypes"}},
"GaussianBlur" : { "borderType" : {"ctype" : "BorderTypes"}},
@@ -108,7 +91,6 @@
"ellipse" : { "lineType" : {"ctype" : "LineTypes"}},
"erode" : { "borderType" : {"ctype" : "BorderTypes"}},
"filter2D" : { "borderType" : {"ctype" : "BorderTypes"}},
"fitLine" : { "distType" : {"ctype" : "DistanceTypes"}},
"line" : { "lineType" : {"ctype" : "LineTypes"}},
"matchTemplate" : { "method" : {"ctype" : "TemplateMatchModes"}},
"morphologyEx" : { "op" : {"ctype" : "MorphTypes"},
@@ -126,9 +108,6 @@
"warpAffine" : { "borderMode": {"ctype" : "BorderTypes"}},
"warpPerspective" : { "borderMode": {"ctype" : "BorderTypes"}},
"getTextSize" : { "fontFace": {"ctype" : "HersheyFonts"}}
},
"Subdiv2D" : {
"(void)insert:(NSArray<Point2f*>*)ptvec" : { "insert" : {"name" : "insertVector"} }
}
},
"type_dict": {
@@ -122,26 +122,6 @@ class ImgprocTest: OpenCVTestCase {
XCTAssertEqual(src.rows(), Core.countNonZero(src: dst))
}
func testApproxPolyDP() {
let curve = [Point2f(x: 1, y: 3), Point2f(x: 2, y: 4), Point2f(x: 3, y: 5), Point2f(x: 4, y: 4), Point2f(x: 5, y: 3)]
var approxCurve = [Point2f]()
Imgproc.approxPolyDP(curve: curve, approxCurve: &approxCurve, epsilon: OpenCVTestCase.EPS, closed: true)
let approxCurveGold = [Point2f(x: 1, y: 3), Point2f(x: 3, y: 5), Point2f(x: 5, y: 3)]
XCTAssert(approxCurve == approxCurveGold)
}
func testArcLength() {
let curve = [Point2f(x: 1, y: 3), Point2f(x: 2, y: 4), Point2f(x: 3, y: 5), Point2f(x: 4, y: 4), Point2f(x: 5, y: 3)]
let arcLength = Imgproc.arcLength(curve: curve, closed: false)
XCTAssertEqual(5.656854249, arcLength, accuracy:0.000001)
}
func testBilateralFilterMatMatIntDoubleDouble() throws {
Imgproc.bilateralFilter(src: gray255, dst: dst, d: 5, sigmaColor: 10, sigmaSpace: 5)
@@ -315,24 +295,6 @@ class ImgprocTest: OpenCVTestCase {
XCTAssertEqual(1.0, distance, accuracy: OpenCVTestCase.EPS)
}
func testContourAreaMat() throws {
let contour = Mat(rows: 1, cols: 4, type: CvType.CV_32FC2)
try contour.put(row: 0, col: 0, data: [0, 0, 10, 0, 10, 10, 5, 4] as [Float])
let area = Imgproc.contourArea(contour: contour)
XCTAssertEqual(45.0, area, accuracy: OpenCVTestCase.EPS)
}
func testContourAreaMatBoolean() throws {
let contour = Mat(rows: 1, cols: 4, type: CvType.CV_32FC2)
try contour.put(row: 0, col: 0, data: [0, 0, 10, 0, 10, 10, 5, 4] as [Float])
let area = Imgproc.contourArea(contour: contour, oriented: true)
XCTAssertEqual(45.0, area, accuracy: OpenCVTestCase.EPS)
}
func testConvertMapsMatMatMatMatInt() throws {
let map1 = Mat(rows: 1, cols: 4, type: CvType.CV_32FC1, scalar: Scalar(1))
let map2 = Mat(rows: 1, cols: 4, type: CvType.CV_32FC1, scalar: Scalar(2))
@@ -379,38 +341,6 @@ class ImgprocTest: OpenCVTestCase {
XCTAssert([0, 1, 2, 3] == hull)
}
func testConvexHullMatMatBooleanBoolean() {
let points = [Point(x: 2, y: 0),
Point(x: 4, y: 0),
Point(x: 3, y: 2),
Point(x: 0, y: 2),
Point(x: 2, y: 1),
Point(x: 3, y: 1)]
var hull = [Int32]()
Imgproc.convexHull(points: points, hull: &hull, clockwise: true)
XCTAssert([3, 2, 1, 0] == hull)
}
func testConvexityDefects() throws {
let points = [Point(x: 20, y: 0),
Point(x: 40, y: 0),
Point(x: 30, y: 20),
Point(x: 0, y: 20),
Point(x: 20, y: 10),
Point(x: 30, y: 10)]
var hull = [Int32]()
Imgproc.convexHull(points: points, hull: &hull)
var convexityDefects = [Int4]()
Imgproc.convexityDefects(contour: points, convexhull: hull, convexityDefects: &convexityDefects)
XCTAssertTrue(Int4(v0: 3, v1: 0, v2: 5, v3: 3620) == convexityDefects[0])
}
func testCornerEigenValsAndVecsMatMatIntInt() throws {
let src = Mat(rows: imgprocSz, cols: imgprocSz, type: CvType.CV_32FC1)
try src.put(row: 0, col: 0, data: [1, 2] as [Float])
@@ -733,19 +663,6 @@ class ImgprocTest: OpenCVTestCase {
try assertMatEqual(gray2, dst)
}
func testGetAffineTransform() throws {
let src = [Point2f(x: 2, y: 3), Point2f(x: 3, y: 1), Point2f(x: 1, y: 4)]
let dst = [Point2f(x: 3, y: 3), Point2f(x: 7, y: 4), Point2f(x: 5, y: 6)]
let transform = Imgproc.getAffineTransform(src: src, dst: dst)
let truth = Mat(rows: 2, cols: 3, type: CvType.CV_64FC1)
try truth.put(row: 0, col: 0, data: [-8.0, -6.0, 37.0])
try truth.put(row: 1, col: 0, data: [-7.0, -4.0, 29.0])
try assertMatEqual(truth, transform, OpenCVTestCase.EPS)
}
func testGetDerivKernelsMatMatIntIntInt() throws {
let kx = Mat(rows: imgprocSz, cols: imgprocSz, type: CvType.CV_32F)
let ky = Mat(rows: imgprocSz, cols: imgprocSz, type: CvType.CV_32F)
@@ -819,18 +736,6 @@ class ImgprocTest: OpenCVTestCase {
try assertMatEqual(truth!, dst, OpenCVTestCase.EPS)
}
func testGetRotationMatrix2D() throws {
let center = Point2f(x: 0, y: 0)
dst = Imgproc.getRotationMatrix2D(center: center, angle: 0, scale: 1)
truth = Mat(rows: 2, cols: 3, type: CvType.CV_64F)
try truth!.put(row: 0, col: 0, data: [1.0, 0.0, 0.0])
try truth!.put(row: 1, col: 0, data: [0.0, 1.0, 0.0])
try assertMatEqual(truth!, dst, OpenCVTestCase.EPS)
}
func testGetStructuringElementIntSize() throws {
dst = Imgproc.getStructuringElement(shape: .MORPH_RECT, ksize: size)
@@ -1021,25 +926,6 @@ class ImgprocTest: OpenCVTestCase {
try assertMatEqual(truth!, dst, OpenCVTestCase.EPS)
}
func testInvertAffineTransform() throws {
let src = Mat(rows: 2, cols: 3, type: CvType.CV_64F, scalar: Scalar(1))
Imgproc.invertAffineTransform(M: src, iM: dst)
truth = Mat(rows: 2, cols: 3, type: CvType.CV_64F, scalar: Scalar(0))
try assertMatEqual(truth!, dst, OpenCVTestCase.EPS)
}
func testIsContourConvex() {
let contour1 = [Point(x: 0, y: 0), Point(x: 10, y: 0), Point(x: 10, y: 10), Point(x: 5, y: 4)]
XCTAssertFalse(Imgproc.isContourConvex(contour: contour1))
let contour2 = [Point(x: 0, y: 0), Point(x: 10, y: 0), Point(x: 10, y: 10), Point(x: 5, y: 6)]
XCTAssert(Imgproc.isContourConvex(contour: contour2))
}
func testLaplacianMatMatInt() throws {
Imgproc.Laplacian(src: gray0, dst: dst, ddepth: CvType.CV_8U)
@@ -1103,27 +989,6 @@ class ImgprocTest: OpenCVTestCase {
// TODO_: write better test
}
func testMinAreaRect() {
let points = [Point2f(x: 1, y: 1), Point2f(x: 5, y: 1), Point2f(x: 4, y: 3), Point2f(x: 6, y: 2)]
let rrect = Imgproc.minAreaRect(points: points)
XCTAssertEqual(Size2f(width: 5, height: 2), rrect.size)
XCTAssertEqual(0.0, rrect.angle)
XCTAssertEqual(Point2f(x: 3.5, y: 2), rrect.center)
}
func testMinEnclosingCircle() {
let points = [Point2f(x: 0, y: 0), Point2f(x: -100, y: 0), Point2f(x: 0, y: -100), Point2f(x: 100, y: 0), Point2f(x: 0, y: 100)]
let actualCenter = Point2f()
var radius:Float = 0
Imgproc.minEnclosingCircle(points: points, center: actualCenter, radius: &radius)
XCTAssertEqual(Point2f(x: 0, y: 0), actualCenter)
XCTAssertEqual(100.0, radius, accuracy: 1.0)
}
func testMorphologyExMatMatIntMat() throws {
Imgproc.morphologyEx(src: gray255, dst: dst, op: MorphTypes.MORPH_GRADIENT, kernel: gray0)
@@ -1159,15 +1024,6 @@ class ImgprocTest: OpenCVTestCase {
try assertMatEqual(truth!, dst)
}
func testPointPolygonTest() {
let contour = [Point2f(x: 0, y: 0), Point2f(x: 1, y: 3), Point2f(x: 3, y: 4), Point2f(x: 4, y: 3), Point2f(x: 2, y: 1)]
let sign1 = Imgproc.pointPolygonTest(contour: contour, pt: Point2f(x: 2, y: 2), measureDist: false)
XCTAssertEqual(1.0, sign1)
let sign2 = Imgproc.pointPolygonTest(contour: contour, pt: Point2f(x: 4, y: 4), measureDist: true)
XCTAssertEqual(-sqrt(0.5), sign2)
}
func testPreCornerDetectMatMatInt() throws {
let src = Mat(rows: 4, cols: 4, type: CvType.CV_32F, scalar: Scalar(1))
let ksize:Int32 = 3
@@ -1,42 +0,0 @@
//
// MomentsTest.swift
//
// Created by Giles Payne on 2020/02/10.
//
import XCTest
import OpenCV
class MomentsTest: XCTestCase {
func testAll() {
let data = Mat(rows: 3,cols: 3, type: CvType.CV_8UC1, scalar: Scalar(1))
data.row(1).setTo(scalar: Scalar(5))
let res = Imgproc.moments(array: data)
XCTAssertEqual(res.m00, 21.0, accuracy: OpenCVTestCase.EPS);
XCTAssertEqual(res.m10, 21.0, accuracy: OpenCVTestCase.EPS);
XCTAssertEqual(res.m01, 21.0, accuracy: OpenCVTestCase.EPS);
XCTAssertEqual(res.m20, 35.0, accuracy: OpenCVTestCase.EPS);
XCTAssertEqual(res.m11, 21.0, accuracy: OpenCVTestCase.EPS);
XCTAssertEqual(res.m02, 27.0, accuracy: OpenCVTestCase.EPS);
XCTAssertEqual(res.m30, 63.0, accuracy: OpenCVTestCase.EPS);
XCTAssertEqual(res.m21, 35.0, accuracy: OpenCVTestCase.EPS);
XCTAssertEqual(res.m12, 27.0, accuracy: OpenCVTestCase.EPS);
XCTAssertEqual(res.m03, 39.0, accuracy: OpenCVTestCase.EPS);
XCTAssertEqual(res.mu20, 14.0, accuracy: OpenCVTestCase.EPS);
XCTAssertEqual(res.mu11, 0.0, accuracy: OpenCVTestCase.EPS);
XCTAssertEqual(res.mu02, 6.0, accuracy: OpenCVTestCase.EPS);
XCTAssertEqual(res.mu30, 0.0, accuracy: OpenCVTestCase.EPS);
XCTAssertEqual(res.mu21, 0.0, accuracy: OpenCVTestCase.EPS);
XCTAssertEqual(res.mu12, 0.0, accuracy: OpenCVTestCase.EPS);
XCTAssertEqual(res.mu03, 0.0, accuracy: OpenCVTestCase.EPS);
XCTAssertEqual(res.nu20, 0.031746031746031744, accuracy: OpenCVTestCase.EPS);
XCTAssertEqual(res.nu11, 0.0, accuracy: OpenCVTestCase.EPS);
XCTAssertEqual(res.nu02, 0.013605442176870746, accuracy: OpenCVTestCase.EPS);
XCTAssertEqual(res.nu30, 0.0, accuracy: OpenCVTestCase.EPS);
XCTAssertEqual(res.nu21, 0.0, accuracy: OpenCVTestCase.EPS);
XCTAssertEqual(res.nu12, 0.0, accuracy: OpenCVTestCase.EPS);
XCTAssertEqual(res.nu03, 0.0, accuracy: OpenCVTestCase.EPS);
}
}
+1
View File
@@ -6,6 +6,7 @@
#include "opencv2/ts.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/geometry.hpp"
namespace opencv_test {
using namespace perf;
+123
View File
@@ -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 {
/**
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 = std::cos(tauX);
FLOAT sTauX = std::sin(tauX);
FLOAT cTauY = std::cos(tauY);
FLOAT sTauY = std::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, _3d, cv
//! @endcond
#endif // OPENCV_IMGPROC_DETAIL_DISTORTION_MODEL_HPP
+41
View File
@@ -2250,3 +2250,44 @@ void cv::drawContours( InputOutputArray _image, InputArrayOfArrays _contours,
}
}
}
void cv::drawFrameAxes(InputOutputArray image, InputArray cameraMatrix, InputArray distCoeffs,
InputArray rvec, InputArray tvec, float length, int thickness)
{
CV_INSTRUMENT_REGION();
int type = image.type();
int cn = CV_MAT_CN(type);
CV_CheckType(type, cn == 1 || cn == 3 || cn == 4,
"Number of channels must be 1, 3 or 4" );
cv::Mat img = image.getMat();
CV_Assert(img.total() > 0);
CV_Assert(length > 0);
// project axes points
std::vector<Point3f> axesPoints;
axesPoints.push_back(Point3f(0, 0, 0));
axesPoints.push_back(Point3f(length, 0, 0));
axesPoints.push_back(Point3f(0, length, 0));
axesPoints.push_back(Point3f(0, 0, length));
std::vector<Point2f> imagePoints;
projectPoints(axesPoints, rvec, tvec, cameraMatrix, distCoeffs, imagePoints);
cv::Rect imageRect(0, 0, img.cols, img.rows);
bool allIn = true;
for (size_t i = 0; i < imagePoints.size(); i++)
{
allIn &= imageRect.contains(imagePoints[i]);
}
if (!allIn)
{
CV_LOG_WARNING(NULL, "Some of projected axes endpoints are out of frame. The drawn axes may be not reliable.");
}
// draw axes lines
line(image, imagePoints[0], imagePoints[1], Scalar(0, 0, 255), thickness);
line(image, imagePoints[0], imagePoints[2], Scalar(0, 255, 0), thickness);
line(image, imagePoints[0], imagePoints[3], Scalar(255, 0, 0), thickness);
}
+128
View File
@@ -0,0 +1,128 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html
#include "precomp.hpp"
#include "opencv2/core/affine.hpp"
namespace cv {
namespace fisheye {
void initUndistortRectifyMap( InputArray K, InputArray D, InputArray R, InputArray P,
const cv::Size& size, int m1type, OutputArray map1, OutputArray map2 )
{
CV_INSTRUMENT_REGION();
CV_Assert( m1type == CV_16SC2 || m1type == CV_32F || m1type <=0 );
map1.create( size, m1type <= 0 ? CV_16SC2 : m1type );
map2.create( size, map1.type() == CV_16SC2 ? CV_16UC1 : CV_32F );
CV_Assert((K.depth() == CV_32F || K.depth() == CV_64F) && (D.depth() == CV_32F || D.depth() == CV_64F));
CV_Assert((P.empty() || P.depth() == CV_32F || P.depth() == CV_64F) && (R.empty() || R.depth() == CV_32F || R.depth() == CV_64F));
CV_Assert(K.size() == Size(3, 3) && (D.empty() || D.total() == 4));
CV_Assert(R.empty() || R.size() == Size(3, 3) || R.total() * R.channels() == 3);
CV_Assert(P.empty() || P.size() == Size(3, 3) || P.size() == Size(4, 3));
Vec2d f, c;
if (K.depth() == CV_32F)
{
Matx33f camMat = K.getMat();
f = Vec2f(camMat(0, 0), camMat(1, 1));
c = Vec2f(camMat(0, 2), camMat(1, 2));
}
else
{
Matx33d camMat = K.getMat();
f = Vec2d(camMat(0, 0), camMat(1, 1));
c = Vec2d(camMat(0, 2), camMat(1, 2));
}
Vec4d k = Vec4d::all(0);
if (!D.empty())
k = D.depth() == CV_32F ? (Vec4d)*D.getMat().ptr<Vec4f>(): *D.getMat().ptr<Vec4d>();
Matx33d RR = Matx33d::eye();
if (!R.empty() && R.total() * R.channels() == 3)
{
Vec3d rvec;
R.getMat().convertTo(rvec, CV_64F);
RR = Affine3d(rvec).rotation();
}
else if (!R.empty() && R.size() == Size(3, 3))
R.getMat().convertTo(RR, CV_64F);
Matx33d PP = Matx33d::eye();
if (!P.empty())
P.getMat().colRange(0, 3).convertTo(PP, CV_64F);
Matx33d iR = (PP * RR).inv(cv::DECOMP_SVD);
for( int i = 0; i < size.height; ++i)
{
float* m1f = map1.getMat().ptr<float>(i);
float* m2f = map2.getMat().ptr<float>(i);
short* m1 = (short*)m1f;
ushort* m2 = (ushort*)m2f;
double _x = i*iR(0, 1) + iR(0, 2),
_y = i*iR(1, 1) + iR(1, 2),
_w = i*iR(2, 1) + iR(2, 2);
for( int j = 0; j < size.width; ++j)
{
double u, v;
if( _w <= 0)
{
u = (_x > 0) ? -std::numeric_limits<double>::infinity() : std::numeric_limits<double>::infinity();
v = (_y > 0) ? -std::numeric_limits<double>::infinity() : std::numeric_limits<double>::infinity();
}
else
{
double x = _x/_w, y = _y/_w;
double r = sqrt(x*x + y*y);
double theta = std::atan(r);
double theta2 = theta*theta, theta4 = theta2*theta2, theta6 = theta4*theta2, theta8 = theta4*theta4;
double theta_d = theta * (1 + k[0]*theta2 + k[1]*theta4 + k[2]*theta6 + k[3]*theta8);
double scale = (r == 0) ? 1.0 : theta_d / r;
u = f[0]*x*scale + c[0];
v = f[1]*y*scale + c[1];
}
if( m1type == CV_16SC2 )
{
int iu = cv::saturate_cast<int>(u*static_cast<double>(cv::INTER_TAB_SIZE));
int iv = cv::saturate_cast<int>(v*static_cast<double>(cv::INTER_TAB_SIZE));
m1[j*2+0] = (short)(iu >> cv::INTER_BITS);
m1[j*2+1] = (short)(iv >> cv::INTER_BITS);
m2[j] = (ushort)((iv & (cv::INTER_TAB_SIZE-1))*cv::INTER_TAB_SIZE + (iu & (cv::INTER_TAB_SIZE-1)));
}
else if( m1type == CV_32FC1 )
{
m1f[j] = (float)u;
m2f[j] = (float)v;
}
_x += iR(0, 0);
_y += iR(1, 0);
_w += iR(2, 0);
}
}
}
void undistortImage(InputArray distorted, OutputArray undistorted,
InputArray K, InputArray D, InputArray Knew, const Size& new_size)
{
CV_INSTRUMENT_REGION();
Size size = !new_size.empty() ? new_size : distorted.size();
Mat map1, map2;
fisheye::initUndistortRectifyMap(K, D, Matx33d::eye(), Knew, size, CV_16SC2, map1, map2 );
cv::remap(distorted, undistorted, map1, map2, INTER_LINEAR, BORDER_CONSTANT);
}
} // namespace fisheye
} // namespace cv
+1 -1
View File
@@ -40,7 +40,7 @@
//M*/
#include "precomp.hpp"
#include "opencv2/imgproc/detail/gcgraph.hpp"
#include "opencv2/geometry/detail/gcgraph.hpp"
#include <limits>
using namespace cv;
-32
View File
@@ -1520,38 +1520,6 @@ inline int hal_ni_canny(const uchar* src_data, size_t src_step, uchar* dst_data,
#define cv_hal_canny hal_ni_canny
//! @endcond
/**
@brief Calculates all of the moments up to the third order of a polygon or rasterized shape for image
@param src_data Source image data
@param src_step Source image step
@param src_type source pints type
@param width Source image width
@param height Source image height
@param binary If it is true, all non-zero image pixels are treated as 1's
@param m Output array of moments (10 values) in the following order:
m00, m10, m01, m20, m11, m02, m30, m21, m12, m03.
@sa moments
*/
inline int hal_ni_imageMoments(const uchar* src_data, size_t src_step, int src_type, int width, int height, bool binary, double m[10])
{ return CV_HAL_ERROR_NOT_IMPLEMENTED; }
/**
@brief Calculates all of the moments up to the third order of a polygon of 2d points
@param src_data Source points (Point 2x32f or 2x32s)
@param src_size Source points count
@param src_type source pints type
@param m Output array of moments (10 values) in the following order:
m00, m10, m01, m20, m11, m02, m30, m21, m12, m03.
@sa moments
*/
inline int hal_ni_polygonMoments(const uchar* src_data, size_t src_size, int src_type, double m[10])
{ return CV_HAL_ERROR_NOT_IMPLEMENTED; }
//! @cond IGNORED
#define cv_hal_imageMoments hal_ni_imageMoments
#define cv_hal_polygonMoments hal_ni_polygonMoments
//! @endcond
/**
@brief Calculates a histogram of a set of arrays
@param src_data Source imgage data
-198
View File
@@ -3059,204 +3059,6 @@ void cv::warpPerspective( InputArray _src, OutputArray _dst, InputArray _M0,
matM.ptr<double>(), interpolation, borderType, borderValue.val, hint);
}
cv::Matx23d cv::getRotationMatrix2D_(Point2f center, double angle, double scale)
{
CV_INSTRUMENT_REGION();
angle *= CV_PI/180;
double alpha = std::cos(angle)*scale;
double beta = std::sin(angle)*scale;
Matx23d M(
alpha, beta, (1-alpha)*center.x - beta*center.y,
-beta, alpha, beta*center.x + (1-alpha)*center.y
);
return M;
}
/* Calculates coefficients of perspective transformation
* which maps (xi,yi) to (ui,vi), (i=1,2,3,4):
*
* c00*xi + c01*yi + c02
* ui = ---------------------
* c20*xi + c21*yi + c22
*
* c10*xi + c11*yi + c12
* vi = ---------------------
* c20*xi + c21*yi + c22
*
* Coefficients are calculated by solving one of 2 linear systems:
* / x0 y0 1 0 0 0 -x0*u0 -y0*u0 \ /c00\ /u0\
* | x1 y1 1 0 0 0 -x1*u1 -y1*u1 | |c01| |u1|
* | x2 y2 1 0 0 0 -x2*u2 -y2*u2 | |c02| |u2|
* | x3 y3 1 0 0 0 -x3*u3 -y3*u3 |.|c10|=|u3|,
* | 0 0 0 x0 y0 1 -x0*v0 -y0*v0 | |c11| |v0|
* | 0 0 0 x1 y1 1 -x1*v1 -y1*v1 | |c12| |v1|
* | 0 0 0 x2 y2 1 -x2*v2 -y2*v2 | |c20| |v2|
* \ 0 0 0 x3 y3 1 -x3*v3 -y3*v3 / \c21/ \v3/
*
* where:
* cij - matrix coefficients, c22 = 1
*
* or
*
* / x0 y0 1 0 0 0 -x0*u0 -y0*u0 -u0 \ /c00\ /0\
* | x1 y1 1 0 0 0 -x1*u1 -y1*u1 -u1 | |c01| |0|
* | x2 y2 1 0 0 0 -x2*u2 -y2*u2 -u2 | |c02| |0|
* | x3 y3 1 0 0 0 -x3*u3 -y3*u3 -u3 |.|c10|=|0|,
* | 0 0 0 x0 y0 1 -x0*v0 -y0*v0 -v0 | |c11| |0|
* | 0 0 0 x1 y1 1 -x1*v1 -y1*v1 -v1 | |c12| |0|
* | 0 0 0 x2 y2 1 -x2*v2 -y2*v2 -v2 | |c20| |0|
* \ 0 0 0 x3 y3 1 -x3*v3 -y3*v3 -v3 / |c21| \0/
* \c22/
*
* where:
* cij - matrix coefficients, c00^2 + c01^2 + c02^2 + c10^2 + c11^2 + c12^2 + c20^2 + c21^2 + c22^2 = 1
*/
cv::Mat cv::getPerspectiveTransform(const Point2f src[], const Point2f dst[], int solveMethod)
{
CV_INSTRUMENT_REGION();
// try c22 = 1
Mat M(3, 3, CV_64F), X8(8, 1, CV_64F, M.ptr());
double a[8][8], b[8];
Mat A(8, 8, CV_64F, a), B(8, 1, CV_64F, b);
for( int i = 0; i < 4; ++i )
{
a[i][0] = a[i+4][3] = src[i].x;
a[i][1] = a[i+4][4] = src[i].y;
a[i][2] = a[i+4][5] = 1;
a[i][3] = a[i][4] = a[i][5] =
a[i+4][0] = a[i+4][1] = a[i+4][2] = 0;
a[i][6] = -src[i].x*dst[i].x;
a[i][7] = -src[i].y*dst[i].x;
a[i+4][6] = -src[i].x*dst[i].y;
a[i+4][7] = -src[i].y*dst[i].y;
b[i] = dst[i].x;
b[i+4] = dst[i].y;
}
if (solve(A, B, X8, solveMethod) && norm(A * X8, B) < 1e-8)
{
M.ptr<double>()[8] = 1.;
return M;
}
// c00^2 + c01^2 + c02^2 + c10^2 + c11^2 + c12^2 + c20^2 + c21^2 + c22^2 = 1
hconcat(A, -B, A);
Mat AtA;
mulTransposed(A, AtA, true);
Mat D, U;
SVDecomp(AtA, D, U, noArray());
Mat X9(9, 1, CV_64F, M.ptr());
U.col(8).copyTo(X9);
return M;
}
/* Calculates coefficients of affine transformation
* which maps (xi,yi) to (ui,vi), (i=1,2,3):
*
* ui = c00*xi + c01*yi + c02
*
* vi = c10*xi + c11*yi + c12
*
* Coefficients are calculated by solving linear system:
* / x0 y0 1 0 0 0 \ /c00\ /u0\
* | x1 y1 1 0 0 0 | |c01| |u1|
* | x2 y2 1 0 0 0 | |c02| |u2|
* | 0 0 0 x0 y0 1 | |c10| |v0|
* | 0 0 0 x1 y1 1 | |c11| |v1|
* \ 0 0 0 x2 y2 1 / |c12| |v2|
*
* where:
* cij - matrix coefficients
*/
cv::Mat cv::getAffineTransform( const Point2f src[], const Point2f dst[] )
{
Mat M(2, 3, CV_64F), X(6, 1, CV_64F, M.ptr());
double a[6*6], b[6];
Mat A(6, 6, CV_64F, a), B(6, 1, CV_64F, b);
for( int i = 0; i < 3; i++ )
{
int j = i*12;
int k = i*12+6;
a[j] = a[k+3] = src[i].x;
a[j+1] = a[k+4] = src[i].y;
a[j+2] = a[k+5] = 1;
a[j+3] = a[j+4] = a[j+5] = 0;
a[k] = a[k+1] = a[k+2] = 0;
b[i*2] = dst[i].x;
b[i*2+1] = dst[i].y;
}
solve( A, B, X );
return M;
}
void cv::invertAffineTransform(InputArray _matM, OutputArray __iM)
{
Mat matM = _matM.getMat();
CV_Assert(matM.rows == 2 && matM.cols == 3);
__iM.create(2, 3, matM.type());
Mat _iM = __iM.getMat();
if( matM.type() == CV_32F )
{
const softfloat* M = matM.ptr<softfloat>();
softfloat* iM = _iM.ptr<softfloat>();
int step = (int)(matM.step/sizeof(M[0])), istep = (int)(_iM.step/sizeof(iM[0]));
softdouble D = M[0]*M[step+1] - M[1]*M[step];
D = D != 0. ? softdouble(1.)/D : softdouble(0.);
softdouble A11 = M[step+1]*D, A22 = M[0]*D, A12 = -M[1]*D, A21 = -M[step]*D;
softdouble b1 = -A11*M[2] - A12*M[step+2];
softdouble b2 = -A21*M[2] - A22*M[step+2];
iM[0] = A11; iM[1] = A12; iM[2] = b1;
iM[istep] = A21; iM[istep+1] = A22; iM[istep+2] = b2;
}
else if( matM.type() == CV_64F )
{
const softdouble* M = matM.ptr<softdouble>();
softdouble* iM = _iM.ptr<softdouble>();
int step = (int)(matM.step/sizeof(M[0])), istep = (int)(_iM.step/sizeof(iM[0]));
softdouble D = M[0]*M[step+1] - M[1]*M[step];
D = D != 0. ? softdouble(1.)/D : softdouble(0.);
softdouble A11 = M[step+1]*D, A22 = M[0]*D, A12 = -M[1]*D, A21 = -M[step]*D;
softdouble b1 = -A11*M[2] - A12*M[step+2];
softdouble b2 = -A21*M[2] - A22*M[step+2];
iM[0] = A11; iM[1] = A12; iM[2] = b1;
iM[istep] = A21; iM[istep+1] = A22; iM[istep+2] = b2;
}
else
CV_Error( cv::Error::StsUnsupportedFormat, "" );
}
cv::Mat cv::getPerspectiveTransform(InputArray _src, InputArray _dst, int solveMethod)
{
Mat src = _src.getMat(), dst = _dst.getMat();
CV_Assert(src.checkVector(2, CV_32F) == 4 && dst.checkVector(2, CV_32F) == 4);
return getPerspectiveTransform((const Point2f*)src.data, (const Point2f*)dst.data, solveMethod);
}
cv::Mat cv::getAffineTransform(InputArray _src, InputArray _dst)
{
Mat src = _src.getMat(), dst = _dst.getMat();
CV_Assert(src.checkVector(2, CV_32F) == 3 && dst.checkVector(2, CV_32F) == 3);
return getAffineTransform((const Point2f*)src.data, (const Point2f*)dst.data);
}
/****************************************************************************************
PkLab.net 2018 based on cv::linearPolar from OpenCV by J.L. Blanco, Apr 2009
****************************************************************************************/
+1
View File
@@ -44,6 +44,7 @@
#define __OPENCV_PRECOMP_H__
#include "opencv2/imgproc.hpp"
#include "opencv2/geometry.hpp"
#include "opencv2/core/utility.hpp"
#include "opencv2/core/private.hpp"
@@ -49,63 +49,6 @@
namespace cv {
Mat getDefaultNewCameraMatrix( InputArray _cameraMatrix, Size imgsize,
bool centerPrincipalPoint )
{
Mat cameraMatrix = _cameraMatrix.getMat();
if( !centerPrincipalPoint && cameraMatrix.type() == CV_64F )
return cameraMatrix;
Mat newCameraMatrix;
cameraMatrix.convertTo(newCameraMatrix, CV_64F);
if( centerPrincipalPoint )
{
newCameraMatrix.ptr<double>()[2] = (imgsize.width-1)*0.5;
newCameraMatrix.ptr<double>()[5] = (imgsize.height-1)*0.5;
}
return newCameraMatrix;
}
void calibrationMatrixValues( InputArray _cameraMatrix, Size imageSize,
double apertureWidth, double apertureHeight,
double& fovx, double& fovy, double& focalLength,
Point2d& principalPoint, double& aspectRatio )
{
CV_INSTRUMENT_REGION();
if(_cameraMatrix.size() != Size(3, 3))
CV_Error(cv::Error::StsUnmatchedSizes, "Size of cameraMatrix must be 3x3!");
Matx33d A;
_cameraMatrix.getMat().convertTo(A, CV_64F);
CV_DbgAssert(imageSize.width != 0 && imageSize.height != 0 && A(0, 0) != 0.0 && A(1, 1) != 0.0);
/* Calculate pixel aspect ratio. */
aspectRatio = A(1, 1) / A(0, 0);
/* Calculate number of pixel per realworld unit. */
double mx, my;
if(apertureWidth != 0.0 && apertureHeight != 0.0) {
mx = imageSize.width / apertureWidth;
my = imageSize.height / apertureHeight;
} else {
mx = 1.0;
my = aspectRatio;
}
/* Calculate fovx and fovy. */
fovx = atan2(A(0, 2), A(0, 0)) + atan2(imageSize.width - A(0, 2), A(0, 0));
fovy = atan2(A(1, 2), A(1, 1)) + atan2(imageSize.height - A(1, 2), A(1, 1));
fovx *= 180.0 / CV_PI;
fovy *= 180.0 / CV_PI;
/* Calculate focal length. */
focalLength = A(0, 0) / mx;
/* Calculate principle point. */
principalPoint = Point2d(A(0, 2) / mx, A(1, 2) / my);
}
static Ptr<ParallelLoopBody> getInitUndistortRectifyMapComputer(Size _size, Mat &_map1, Mat &_map2, int _m1type,
const double* _ir, Matx33d &_matTilt,
double _u0, double _v0, double _fx, double _fy,
@@ -358,8 +301,8 @@ void undistort( InputArray _src, OutputArray _dst, InputArray _cameraMatrix,
int stripe_size = std::min( stripe_size0, src.rows - y );
Ar(1, 2) = v0 - y;
Mat map1_part = map1.rowRange(0, stripe_size),
map2_part = map2.rowRange(0, stripe_size),
dst_part = dst.rowRange(y, y + stripe_size);
map2_part = map2.rowRange(0, stripe_size),
dst_part = dst.rowRange(y, y + stripe_size);
initUndistortRectifyMap( A, distCoeffs, I, Ar, Size(src.cols, stripe_size),
map1_part.type(), map1_part, map2_part );
@@ -367,251 +310,6 @@ void undistort( InputArray _src, OutputArray _dst, InputArray _cameraMatrix,
}
}
static void undistortPointsInternal( const Mat& _src, Mat& _dst, const Mat& _cameraMatrix,
const Mat& _distCoeffs, const Mat& matR, const Mat& matP, TermCriteria criteria)
{
CV_Assert(criteria.isValid());
double A[3][3], RR[3][3], k[14]={0,0,0,0,0,0,0,0,0,0,0,0,0,0};
Mat matA(3, 3, CV_64F, A), _Dk;
Mat _RR(3, 3, CV_64F, RR);
cv::Matx33d invMatTilt = cv::Matx33d::eye();
cv::Matx33d matTilt = cv::Matx33d::eye();
bool haveDistCoeffs = !_distCoeffs.empty();
CV_Assert( (_src.rows == 1 || _src.cols == 1) &&
(_dst.rows == 1 || _dst.cols == 1) &&
_src.cols + _src.rows - 1 == _dst.rows + _dst.cols - 1 &&
(_src.type() == CV_32FC2 || _src.type() == CV_64FC2) &&
(_dst.type() == CV_32FC2 || _dst.type() == CV_64FC2));
CV_Assert( _cameraMatrix.rows == 3 && _cameraMatrix.cols == 3 && _cameraMatrix.channels() == 1 );
_cameraMatrix.convertTo(matA, CV_64F);
if( haveDistCoeffs )
{
CV_Assert(
(_distCoeffs.rows == 1 || _distCoeffs.cols == 1) &&
(_distCoeffs.rows*_distCoeffs.cols == 4 ||
_distCoeffs.rows*_distCoeffs.cols == 5 ||
_distCoeffs.rows*_distCoeffs.cols == 8 ||
_distCoeffs.rows*_distCoeffs.cols == 12 ||
_distCoeffs.rows*_distCoeffs.cols == 14));
_Dk = Mat( _distCoeffs.rows, _distCoeffs.cols,
CV_MAKETYPE(CV_64F,_distCoeffs.channels()), k);
_distCoeffs.convertTo(_Dk, CV_64F);
CV_Assert(_Dk.ptr<double>() == k);
if (k[12] != 0 || k[13] != 0)
{
computeTiltProjectionMatrix<double>(k[12], k[13], NULL, NULL, NULL, &invMatTilt);
computeTiltProjectionMatrix<double>(k[12], k[13], &matTilt, NULL, NULL);
}
}
if( !matR.empty() )
{
CV_Assert( matR.rows == 3 && matR.cols == 3 && matR.channels() == 1 );
matR.convertTo(_RR, CV_64F);
CV_Assert(_RR.ptr<double>() == &RR[0][0]);
}
else
setIdentity(_RR);
if( !matP.empty() )
{
double PP[3][3];
Mat _PP(3, 3, CV_64F, PP);
CV_Assert( matP.rows == 3 && (matP.cols == 3 || matP.cols == 4));
matP.colRange(0, 3).convertTo(_PP, CV_64F);
CV_Assert(_PP.ptr<double>() == &PP[0][0]);
_RR = _PP*_RR;
}
const Point2f* srcf = (const Point2f*)_src.data;
const Point2d* srcd = (const Point2d*)_src.data;
Point2f* dstf = (Point2f*)_dst.data;
Point2d* dstd = (Point2d*)_dst.data;
int stype = _src.type();
int dtype = _dst.type();
int sstep = _src.rows == 1 ? 1 : (int)(_src.step/_src.elemSize());
int dstep = _dst.rows == 1 ? 1 : (int)(_dst.step/_dst.elemSize());
double fx = A[0][0];
double fy = A[1][1];
double ifx = 1./fx;
double ify = 1./fy;
double cx = A[0][2];
double cy = A[1][2];
int n = _src.rows + _src.cols - 1;
for( int i = 0; i < n; i++ )
{
double x, y, x0 = 0, y0 = 0, u, v;
if( stype == CV_32FC2 )
{
x = srcf[i*sstep].x;
y = srcf[i*sstep].y;
}
else
{
x = srcd[i*sstep].x;
y = srcd[i*sstep].y;
}
// [u, v]^T = [fx * x''' + cx, fy * y''' + cy]^T =>
// [x''', y''']^T = [(u - cx) / fx, (v - cy) / fy]^T
u = x; v = y;
x = (x - cx)*ifx;
y = (y - cy)*ify;
if( haveDistCoeffs ) {
// compensate tilt distortion
// s * [x''', y''', 1]^T = matTilt * [x'', y'', 1]^T =>
// s * matTilt^{-1} * [x''', y''', 1]^T = [x'', y'', 1]^T =>
// (invMatTilt := matTilt^{-1}, vecUntilt := invMatTilt * [x''', y''', 1]^T)
// s * vecUntilt = [x'', y'', 1]^T =>
// s * vecUntilt_1 = x'', s * vecUntilt_2 = y'', s * vecUntilt_3 = 1 =>
// invProj := s = 1 / vecUntilt_3, x'' = invProj * vecUntilt_1, y'' = invProj * vecUntilt_2
cv::Vec3d vecUntilt = invMatTilt * cv::Vec3d(x, y, 1);
double invProj = vecUntilt(2) ? 1./vecUntilt(2) : 1;
x0 = x = invProj * vecUntilt(0);
y0 = y = invProj * vecUntilt(1);
double error = std::numeric_limits<double>::max();
double prevError = std::numeric_limits<double>::max();
// compensate distortion iteratively using fixed-point iteration
// parameter for damped fixed-point iteration
double alpha = 1.;
for( int j = 0; ; j++ )
{
if ((criteria.type & TermCriteria::COUNT) && j >= criteria.maxCount)
break;
if ((criteria.type & TermCriteria::EPS) && error < criteria.epsilon)
break;
// r^2 = x'^2 + y'^2
double r2 = x*x + y*y;
// icdist := (1 + k4 * r^2 + k5 * r^4 + k6 * r^6) / (1 + k1 * r^2 + k2 * r^4 + k3 * r^6)
double icdist = (1 + ((k[7]*r2 + k[6])*r2 + k[5])*r2)/(1 + ((k[4]*r2 + k[1])*r2 + k[0])*r2);
if (icdist < 0) // test: undistortPoints.regression_14583
{
x = (u - cx)*ifx;
y = (v - cy)*ify;
break;
}
// deltaX := 2 * p1 * x' * y' + p2 * (r^2 + 2 * x'^2) + s1 * r^2 + s2 * r^4
// deltaY := p1 * (r^2 + 2 * y'^2) + 2 * p2 * x' * y' + s3 * r^2 + s4 * r^4
double deltaX = 2*k[2]*x*y + k[3]*(r2 + 2*x*x)+ k[8]*r2+k[9]*r2*r2;
double deltaY = k[2]*(r2 + 2*y*y) + 2*k[3]*x*y+ k[10]*r2+k[11]*r2*r2;
// [x'', y'']^T = [x' / icdist + deltaX, y' / icdist + deltaY]^T =>
// [x', y']^T = [(x'' - deltaX) * icdist, (y'' - deltaY) * icdist]^T =>
// x' = f1(x') := (x'' - deltaX) * icdist, y' = f2(y') := (y'' - deltaY) * icdist
// Damped fixed-point iteration:
// f1(x') = (x'' - deltaX) * icdist, f2(y') = (y'' - deltaY) * icdist
// new_x' = (1 - alpha) * x' + alpha * f1(x'), new_y' = (1 - alpha) * y' + alpha * f2(y')
double new_x = (1. - alpha)*x + alpha*(x0 - deltaX)*icdist;
double new_y = (1. - alpha)*y + alpha*(y0 - deltaY)*icdist;
if(criteria.type & TermCriteria::EPS)
{
double r4, r6, a1, a2, a3, cdist, icdist2;
double xd, yd, xd0, yd0;
Vec3d vecTilt;
// r^2 = x'^2 + y'^2
r2 = new_x*new_x + new_y*new_y;
r4 = r2*r2;
r6 = r4*r2;
a1 = 2*new_x*new_y;
a2 = r2 + 2*new_x*new_x;
a3 = r2 + 2*new_y*new_y;
// cdist := 1 + k1 * r^2 + k2 * r^4 + k3 * r^6
cdist = 1 + k[0]*r2 + k[1]*r4 + k[4]*r6;
// icdist2 := 1 / (1 + k4 * r^2 + k5 * r^4 + k6 * r^6)
icdist2 = 1./(1 + k[5]*r2 + k[6]*r4 + k[7]*r6);
// x'' = x' * cdist * icdist2 + 2 * p1 * x' * y' + p2 * (r^2 + 2 * x'^2) + s1 * r^2 + s2 * r^4
// y'' = y' * cdist * icdist2 + p1 * (r^2 + 2 * y'^2) + 2 * p2 * x' * y' + s3 * r^2 + s4 * r^4
xd0 = new_x*cdist*icdist2 + k[2]*a1 + k[3]*a2 + k[8]*r2+k[9]*r4;
yd0 = new_y*cdist*icdist2 + k[2]*a3 + k[3]*a1 + k[10]*r2+k[11]*r4;
// s * [x''', y''', 1]^T = matTilt * [x'', y'', 1]^T =>
// (vecTilt := matTilt * [x'', y'', 1]^T)
// s * [x''', y''', 1]^T = vecTilt =>
// s * x''' = vecTilt_1, s * y''' = vecTilt_2, s = vecTilt_3 =>
// invProj := 1 / s = 1 / vecTilt_3, x''' = invProj * vecTilt_1, y''' = invProj * vecTilt_2
vecTilt = matTilt*cv::Vec3d(xd0, yd0, 1);
invProj = vecTilt(2) ? 1./vecTilt(2) : 1;
xd = invProj * vecTilt(0);
yd = invProj * vecTilt(1);
// [u, v]^T = [fx * x''' + cx, fy * y''' + cy]^T
double x_proj = xd*fx + cx;
double y_proj = yd*fy + cy;
error = sqrt( std::pow(x_proj - u, 2) + std::pow(y_proj - v, 2) );
}
if (error > prevError) {
alpha *= .5;
} else {
x = new_x;
y = new_y;
}
prevError = error;
}
}
if( !matR.empty() || !matP.empty() )
{
double xx = RR[0][0]*x + RR[0][1]*y + RR[0][2];
double yy = RR[1][0]*x + RR[1][1]*y + RR[1][2];
double ww = 1./(RR[2][0]*x + RR[2][1]*y + RR[2][2]);
x = xx*ww;
y = yy*ww;
}
if( dtype == CV_32FC2 )
{
dstf[i*dstep].x = (float)x;
dstf[i*dstep].y = (float)y;
}
else
{
dstd[i*dstep].x = x;
dstd[i*dstep].y = y;
}
}
}
void undistortPoints(InputArray _src, OutputArray _dst,
InputArray _cameraMatrix,
InputArray _distCoeffs,
InputArray _Rmat,
InputArray _Pmat,
TermCriteria criteria)
{
Mat src = _src.getMat(), cameraMatrix = _cameraMatrix.getMat();
Mat distCoeffs = _distCoeffs.getMat(), R = _Rmat.getMat(), P = _Pmat.getMat();
int npoints = src.checkVector(2), depth = src.depth();
if (npoints < 0)
src = src.t();
npoints = src.checkVector(2);
CV_Assert(npoints >= 0 && src.isContinuous() && (depth == CV_32F || depth == CV_64F));
if (src.cols == 2)
src = src.reshape(2);
_dst.create(npoints, 1, CV_MAKETYPE(depth, 2), -1, true);
Mat dst = _dst.getMat();
undistortPointsInternal(src, dst, cameraMatrix, distCoeffs, R, P, criteria);
}
void undistortImagePoints(InputArray src, OutputArray dst, InputArray cameraMatrix, InputArray distCoeffs, TermCriteria termCriteria)
{
undistortPoints(src, dst, cameraMatrix, distCoeffs, noArray(), cameraMatrix, termCriteria);
}
static Point2f mapPointSpherical(const Point2f& p, float alpha, Vec4d* J, enum UndistortTypes projType)
{
double x = p.x, y = p.y;
-15
View File
@@ -219,20 +219,5 @@ TEST(Imgproc_DrawContours, MatListOfMatIntScalarInt)
EXPECT_EQ(nz, 0);
}
TEST(Imgproc_Moments, degenerateContours)
{
std::vector<cv::Point> c1;
c1.push_back(cv::Point(10,10));
cv::Moments m1 = cv::moments(c1, false);
EXPECT_EQ(m1.m00, 0);
std::vector<cv::Point> c2;
c2.push_back(cv::Point(0,0));
c2.push_back(cv::Point(5,5));
c2.push_back(cv::Point(10,10));
cv::Moments m2 = cv::moments(c2, false);
EXPECT_EQ(m2.m00, 0);
}
}} // namespace
/* End of file. */
View File
+2 -1
View File
@@ -7,8 +7,9 @@
#include "opencv2/ts.hpp"
#include "opencv2/ts/ts_gtest.h"
#include "opencv2/ts/ocl_test.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/core.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/geometry.hpp"
#include "opencv2/core/private.hpp"
+1 -1
View File
@@ -41,7 +41,7 @@
//M*/
#include "precomp.hpp"
#include "opencv2/imgproc/detail/gcgraph.hpp"
#include "opencv2/geometry/detail/gcgraph.hpp"
#include <map>
namespace cv {
+1
View File
@@ -48,5 +48,6 @@
#include "opencv2/core/private.hpp"
#include "opencv2/core/ocl.hpp"
#include "opencv2/core.hpp"
#include "opencv2/geometry.hpp"
#endif
+1
View File
@@ -6,6 +6,7 @@
#include "opencv2/ts.hpp"
#include "opencv2/video.hpp"
#include "opencv2/geometry.hpp"
#include <opencv2/ts/ts_perf.hpp>
#include "opencv2/core/utils/configuration.private.hpp"
+1
View File
@@ -1,4 +1,5 @@
#include <opencv2/core/utility.hpp>
#include "opencv2/geometry.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
@@ -5,6 +5,7 @@
@modified by Suleyman TURKMEN
*/
#include "opencv2/geometry.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
@@ -6,6 +6,7 @@
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/geometry.hpp"
#include "opencv2/imgproc.hpp"
#include <iostream>
@@ -4,6 +4,7 @@
*/
#include <opencv2/core.hpp>
#include <opencv2/geometry.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
@@ -1,5 +1,6 @@
#include <iostream>
#include <vector>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/objdetect/aruco_detector.hpp>
#include "aruco_samples_utility.hpp"
@@ -1,4 +1,5 @@
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
//! [charucohdr]
#include <opencv2/objdetect/charuco_detector.hpp>
//! [charucohdr]
@@ -1,4 +1,5 @@
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <vector>
#include <iostream>
#include <opencv2/objdetect/charuco_detector.hpp>
@@ -1,3 +1,4 @@
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/objdetect/aruco_detector.hpp>
#include <iostream>
+1
View File
@@ -27,6 +27,7 @@
#include <iostream>
#include <fstream>
#include <opencv2/geometry.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/dnn.hpp>