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:
committed by
GitHub
parent
ada32973b4
commit
40ddc700aa
@@ -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})
|
||||
|
||||
@@ -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.
|
||||
|
||||

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

|
||||
*/
|
||||
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.
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+4
-4
@@ -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);
|
||||
@@ -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"]
|
||||
}
|
||||
|
||||
@@ -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"} }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -11,4 +11,8 @@
|
||||
#include <opencv2/core/ocl.hpp>
|
||||
#endif
|
||||
|
||||
namespace opencv_test {
|
||||
using namespace perf;
|
||||
} // namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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" : ""));
|
||||
@@ -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 */
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
@@ -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})
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||

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

|
||||
*/
|
||||
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
|
||||
|
||||
@@ -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"} }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include "opencv2/ts.hpp"
|
||||
#include "opencv2/imgproc.hpp"
|
||||
#include "opencv2/geometry.hpp"
|
||||
|
||||
namespace opencv_test {
|
||||
using namespace perf;
|
||||
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
****************************************************************************************/
|
||||
|
||||
@@ -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"
|
||||
|
||||
+2
-304
@@ -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;
|
||||
@@ -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. */
|
||||
|
||||
Executable → Regular
@@ -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"
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
//M*/
|
||||
|
||||
#include "precomp.hpp"
|
||||
#include "opencv2/imgproc/detail/gcgraph.hpp"
|
||||
#include "opencv2/geometry/detail/gcgraph.hpp"
|
||||
#include <map>
|
||||
|
||||
namespace cv {
|
||||
|
||||
@@ -48,5 +48,6 @@
|
||||
#include "opencv2/core/private.hpp"
|
||||
#include "opencv2/core/ocl.hpp"
|
||||
#include "opencv2/core.hpp"
|
||||
#include "opencv2/geometry.hpp"
|
||||
|
||||
#endif
|
||||
|
||||
@@ -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,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>
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
#include <opencv2/geometry.hpp>
|
||||
#include <opencv2/imgproc.hpp>
|
||||
#include <opencv2/highgui.hpp>
|
||||
#include <opencv2/dnn.hpp>
|
||||
|
||||
Reference in New Issue
Block a user