mirror of
https://github.com/opencv/opencv.git
synced 2026-07-30 15:53:03 +04:00
Merge branch '4.x' into '5.x'
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
#define OPENCV_3D_HPP
|
||||
|
||||
#include "opencv2/core.hpp"
|
||||
#include "opencv2/core/types_c.h"
|
||||
#include "opencv2/core/utils/logger.hpp"
|
||||
|
||||
#include "opencv2/3d/depth.hpp"
|
||||
#include "opencv2/3d/odometry.hpp"
|
||||
@@ -792,8 +792,8 @@ correctly only when there are more than 50% of inliers. Finally, if there are no
|
||||
noise is rather small, use the default method (method=0).
|
||||
|
||||
The function is used to find initial intrinsic and extrinsic matrices. Homography matrix is
|
||||
determined up to a scale. Thus, it is normalized so that \f$h_{33}=1\f$. Note that whenever an \f$H\f$ matrix
|
||||
cannot be estimated, an empty one will be returned.
|
||||
determined up to a scale. If \f$h_{33}\f$ is non-zero, the matrix is normalized so that \f$h_{33}=1\f$.
|
||||
@note Whenever an \f$H\f$ matrix cannot be estimated, an empty one will be returned.
|
||||
|
||||
@sa
|
||||
getAffineTransform, estimateAffine2D, estimateAffinePartial2D, getPerspectiveTransform, warpPerspective,
|
||||
@@ -1407,13 +1407,13 @@ CV_EXPORTS_W Mat findFundamentalMat( InputArray points1, InputArray points2,
|
||||
|
||||
@param points1 Array of N (N \>= 5) 2D points from the first image. The point coordinates should
|
||||
be floating-point (single or double precision).
|
||||
@param points2 Array of the second image points of the same size and format as points1 .
|
||||
@param points2 Array of the second image points of the same size and format as points1.
|
||||
@param cameraMatrix Camera intrinsic matrix \f$\cameramatrix{A}\f$ .
|
||||
Note that this function assumes that points1 and points2 are feature points from cameras with the
|
||||
same camera intrinsic matrix. If this assumption does not hold for your use case, use
|
||||
#undistortPoints with `P = cv::NoArray()` for both cameras to transform image points
|
||||
to normalized image coordinates, which are valid for the identity camera intrinsic matrix. When
|
||||
passing these coordinates, pass the identity matrix for this parameter.
|
||||
same camera intrinsic matrix. If this assumption does not hold for your use case, use another
|
||||
function overload or #undistortPoints with `P = cv::NoArray()` for both cameras to transform image
|
||||
points to normalized image coordinates, which are valid for the identity camera intrinsic matrix.
|
||||
When passing these coordinates, pass the identity matrix for this parameter.
|
||||
@param method Method for computing an essential matrix.
|
||||
- @ref RANSAC for the RANSAC algorithm.
|
||||
- @ref LMEDS for the LMedS algorithm.
|
||||
@@ -1487,23 +1487,13 @@ Mat findEssentialMat(
|
||||
|
||||
@param points1 Array of N (N \>= 5) 2D points from the first image. The point coordinates should
|
||||
be floating-point (single or double precision).
|
||||
@param points2 Array of the second image points of the same size and format as points1 .
|
||||
@param cameraMatrix1 Camera matrix \f$K = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}\f$ .
|
||||
Note that this function assumes that points1 and points2 are feature points from cameras with the
|
||||
same camera matrix. If this assumption does not hold for your use case, use
|
||||
#undistortPoints with `P = cv::NoArray()` for both cameras to transform image points
|
||||
to normalized image coordinates, which are valid for the identity camera matrix. When
|
||||
passing these coordinates, pass the identity matrix for this parameter.
|
||||
@param cameraMatrix2 Camera matrix \f$K = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}\f$ .
|
||||
Note that this function assumes that points1 and points2 are feature points from cameras with the
|
||||
same camera matrix. If this assumption does not hold for your use case, use
|
||||
#undistortPoints with `P = cv::NoArray()` for both cameras to transform image points
|
||||
to normalized image coordinates, which are valid for the identity camera matrix. When
|
||||
passing these coordinates, pass the identity matrix for this parameter.
|
||||
@param distCoeffs1 Input vector of distortion coefficients
|
||||
@param points2 Array of the second image points of the same size and format as points1.
|
||||
@param cameraMatrix1 Camera matrix for the first camera \f$K = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}\f$ .
|
||||
@param cameraMatrix2 Camera matrix for the second camera \f$K = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}\f$ .
|
||||
@param distCoeffs1 Input vector of distortion coefficients for the first camera
|
||||
\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 distCoeffs2 Input vector of distortion coefficients
|
||||
@param distCoeffs2 Input vector of distortion coefficients for the second camera
|
||||
\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 method Method for computing an essential matrix.
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
//M*/
|
||||
|
||||
#include "precomp.hpp"
|
||||
#include "hal_replacement.hpp"
|
||||
#include "distortion_model.hpp"
|
||||
#include <stdio.h>
|
||||
#include <iterator>
|
||||
@@ -539,20 +540,15 @@ void cv::projectPoints( InputArray _objectPoints,
|
||||
(objectPoints.rows == count && objpt_cn*objectPoints.cols == 3) ||
|
||||
(objectPoints.rows == 3 && objpt_cn == 1 && objectPoints.cols == count));
|
||||
|
||||
Mat matM(objectPoints.size(), CV_64FC(objpt_cn));
|
||||
objectPoints.convertTo(matM, CV_64F);
|
||||
if (objectPoints.rows == 3 && objectPoints.cols == count) {
|
||||
Mat temp;
|
||||
transpose(matM, temp);
|
||||
matM = temp;
|
||||
transpose(objectPoints, temp);
|
||||
objectPoints = temp;
|
||||
}
|
||||
|
||||
CV_Assert( _imagePoints.needed() );
|
||||
_imagePoints.create(count, 1, CV_MAKETYPE(objpt_depth, 2), -1, true);
|
||||
Mat ipoints = _imagePoints.getMat();
|
||||
ipoints.convertTo(_m, CV_64F);
|
||||
const Point3d* M = matM.ptr<Point3d>();
|
||||
Point2d* m = _m.ptr<Point2d>();
|
||||
|
||||
Mat rvec = _rvec.getMat(), tvec = _tvec.getMat();
|
||||
if(!((rvec.depth() == CV_32F || rvec.depth() == CV_64F) &&
|
||||
@@ -656,6 +652,127 @@ void cv::projectPoints( InputArray _objectPoints,
|
||||
bool calc_derivatives = dpdr.data || dpdt.data || dpdf.data ||
|
||||
dpdc.data || dpdk.data || dpdo.data;
|
||||
|
||||
if (!calc_derivatives)
|
||||
{
|
||||
if (objpt_depth == CV_32F && ipoints.type() == CV_32F)
|
||||
{
|
||||
float rtMatrix[12] = { (float)R[0], (float)R[1], (float)R[2], (float)t[0],
|
||||
(float)R[3], (float)R[4], (float)R[5], (float)t[1],
|
||||
(float)R[6], (float)R[7], (float)R[8], (float)t[2] };
|
||||
|
||||
cv_camera_intrinsics_pinhole_32f intr;
|
||||
intr.fx = (float)fx; intr.fy = (float)fy;
|
||||
intr.cx = (float)cx; intr.cy = (float)cy;
|
||||
intr.amt_k = 0; intr.amt_p = 0; intr.amt_s = 0; intr.use_tau = false;
|
||||
|
||||
switch (ktotal)
|
||||
{
|
||||
case 0: break;
|
||||
case 4: // [k_1, k_2, p_1, p_2]
|
||||
intr.amt_k = 2; intr.amt_p = 2;
|
||||
break;
|
||||
case 5: // [k_1, k_2, p_1, p_2, k_3]
|
||||
intr.amt_k = 3; intr.amt_p = 2;
|
||||
break;
|
||||
case 8: // [k_1, k_2, p_1, p_2, k_3, k_4, k_5, k_6]
|
||||
intr.amt_k = 6; intr.amt_p = 2;
|
||||
break;
|
||||
case 12: // [k_1, k_2, p_1, p_2, k_3, k_4, k_5, k_6, s_1, s_2, s_3, s_4]
|
||||
intr.amt_k = 6; intr.amt_p = 2; intr.amt_s = 4;
|
||||
break;
|
||||
case 14: // [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]
|
||||
intr.amt_k = 6; intr.amt_p = 2; intr.amt_s = 4; intr.use_tau = true;
|
||||
break;
|
||||
default:
|
||||
CV_Error(cv::Error::StsInternal, "Wrong number of distortion coefficients");
|
||||
}
|
||||
|
||||
intr.k[0] = (float)k[0];
|
||||
intr.k[1] = (float)k[1];
|
||||
intr.k[2] = (float)k[4];
|
||||
intr.k[3] = (float)k[5];
|
||||
intr.k[4] = (float)k[6];
|
||||
intr.k[5] = (float)k[7];
|
||||
|
||||
intr.p[0] = (float)k[2];
|
||||
intr.p[1] = (float)k[3];
|
||||
|
||||
for (int ctr = 0; ctr < 4; ctr++)
|
||||
{
|
||||
intr.s[ctr] = (float)k[8+ctr];
|
||||
}
|
||||
|
||||
intr.tau_x = (float)k[12];
|
||||
intr.tau_y = (float)k[13];
|
||||
|
||||
CALL_HAL(projectPoints, cv_hal_project_points_pinhole32f,
|
||||
(float*)objectPoints.data, objectPoints.step, count,
|
||||
(float*)ipoints.data, ipoints.step, rtMatrix, &intr);
|
||||
}
|
||||
|
||||
if (objpt_depth == CV_64F && ipoints.type() == CV_64F)
|
||||
{
|
||||
double rtMatrix[12] = { R[0], R[1], R[2], t[0],
|
||||
R[3], R[4], R[5], t[1],
|
||||
R[6], R[7], R[8], t[2] };
|
||||
|
||||
cv_camera_intrinsics_pinhole_64f intr;
|
||||
intr.fx = fx; intr.fy = fy;
|
||||
intr.cx = cx; intr.cy = cy;
|
||||
intr.amt_k = 0; intr.amt_p = 0; intr.amt_s = 0; intr.use_tau = false;
|
||||
|
||||
switch (ktotal)
|
||||
{
|
||||
case 0: break;
|
||||
case 4: // [k_1, k_2, p_1, p_2]
|
||||
intr.amt_k = 2; intr.amt_p = 2;
|
||||
break;
|
||||
case 5: // [k_1, k_2, p_1, p_2, k_3]
|
||||
intr.amt_k = 3; intr.amt_p = 2;
|
||||
break;
|
||||
case 8: // [k_1, k_2, p_1, p_2, k_3, k_4, k_5, k_6]
|
||||
intr.amt_k = 6; intr.amt_p = 2;
|
||||
break;
|
||||
case 12: // [k_1, k_2, p_1, p_2, k_3, k_4, k_5, k_6, s_1, s_2, s_3, s_4]
|
||||
intr.amt_k = 6; intr.amt_p = 2; intr.amt_s = 4;
|
||||
break;
|
||||
case 14: // [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]
|
||||
intr.amt_k = 6; intr.amt_p = 2; intr.amt_s = 4; intr.use_tau = true;
|
||||
break;
|
||||
default:
|
||||
CV_Error(cv::Error::StsInternal, "Wrong number of distortion coefficients");
|
||||
}
|
||||
|
||||
intr.k[0] = k[0];
|
||||
intr.k[1] = k[1];
|
||||
intr.k[2] = k[4];
|
||||
intr.k[3] = k[5];
|
||||
intr.k[4] = k[6];
|
||||
intr.k[5] = k[7];
|
||||
|
||||
intr.p[0] = k[2];
|
||||
intr.p[1] = k[3];
|
||||
|
||||
for (int ctr = 0; ctr < 4; ctr++)
|
||||
{
|
||||
intr.s[ctr] = k[8+ctr];
|
||||
}
|
||||
|
||||
intr.tau_x = k[12];
|
||||
intr.tau_y = k[13];
|
||||
|
||||
CALL_HAL(projectPoints, cv_hal_project_points_pinhole64f,
|
||||
(double*)objectPoints.data, objectPoints.step, count,
|
||||
(double*)ipoints.data, ipoints.step, rtMatrix, &intr);
|
||||
}
|
||||
}
|
||||
|
||||
Mat matM(objectPoints.size(), CV_64FC(objpt_cn));
|
||||
objectPoints.convertTo(matM, CV_64F);
|
||||
ipoints.convertTo(_m, CV_64F);
|
||||
const Point3d* M = matM.ptr<Point3d>();
|
||||
Point2d* m = _m.ptr<Point2d>();
|
||||
|
||||
for( i = 0; i < count; i++ )
|
||||
{
|
||||
double X = M[i].x, Y = M[i].y, Z = M[i].z;
|
||||
|
||||
+19
-21
@@ -48,6 +48,13 @@
|
||||
|
||||
namespace cv {
|
||||
|
||||
static inline double scaleFor(double x){
|
||||
return (std::fabs(x) > std::numeric_limits<float>::epsilon()) ? 1./x : 1.;
|
||||
}
|
||||
static inline float scaleFor(float x){
|
||||
return (std::fabs(x) > std::numeric_limits<float>::epsilon()) ? 1.f/x : 1.f;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class estimates a homography \f$H\in \mathbb{R}^{3\times 3}\f$
|
||||
* between \f$\mathbf{x} \in \mathbb{R}^3\f$ and
|
||||
@@ -176,8 +183,7 @@ public:
|
||||
eigen( _LtL, matW, matV );
|
||||
_Htemp = _invHnorm*_H0;
|
||||
_H0 = _Htemp*_Hnorm2;
|
||||
_H0.convertTo(_model, _H0.type(), 1./_H0.at<double>(2,2) );
|
||||
|
||||
_H0.convertTo(_model, _H0.type(), scaleFor(_H0.at<double>(2,2)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -196,14 +202,14 @@ public:
|
||||
const Point2f* M = m1.ptr<Point2f>();
|
||||
const Point2f* m = m2.ptr<Point2f>();
|
||||
const double* H = model.ptr<double>();
|
||||
float Hf[] = { (float)H[0], (float)H[1], (float)H[2], (float)H[3], (float)H[4], (float)H[5], (float)H[6], (float)H[7] };
|
||||
float Hf[] = { (float)H[0], (float)H[1], (float)H[2], (float)H[3], (float)H[4], (float)H[5], (float)H[6], (float)H[7], (float)H[8] };
|
||||
|
||||
_err.create(count, 1, CV_32F);
|
||||
float* err = _err.getMat().ptr<float>();
|
||||
|
||||
for( i = 0; i < count; i++ )
|
||||
{
|
||||
float ww = 1.f/(Hf[6]*M[i].x + Hf[7]*M[i].y + 1.f);
|
||||
float ww = 1.f/(Hf[6]*M[i].x + Hf[7]*M[i].y + Hf[8]);
|
||||
float dx = (Hf[0]*M[i].x + Hf[1]*M[i].y + Hf[2])*ww - m[i].x;
|
||||
float dy = (Hf[3]*M[i].x + Hf[4]*M[i].y + Hf[5])*ww - m[i].y;
|
||||
err[i] = dx*dx + dy*dy;
|
||||
@@ -357,7 +363,7 @@ Mat findHomography( InputArray _points1, InputArray _points2,
|
||||
dst = dst1;
|
||||
if( method == RANSAC || method == LMEDS )
|
||||
cb->runKernel( src, dst, H );
|
||||
Mat H8(8, 1, CV_64F, H.ptr<double>());
|
||||
Mat H8(9, 1, CV_64F, H.ptr<double>());
|
||||
|
||||
auto homographyRefineCallback = [src, dst](InputOutputArray _param, OutputArray _err, OutputArray _Jac) -> bool
|
||||
{
|
||||
@@ -368,8 +374,9 @@ Mat findHomography( InputArray _points1, InputArray _points2,
|
||||
if (_Jac.needed())
|
||||
{
|
||||
_Jac.create(count * 2, param.rows, CV_64F);
|
||||
_Jac.setTo(0.);
|
||||
J = _Jac.getMat();
|
||||
CV_Assert(J.isContinuous() && J.cols == 8);
|
||||
CV_Assert(J.isContinuous() && J.cols == 9);
|
||||
}
|
||||
|
||||
const Point2f* M = src.ptr<Point2f>();
|
||||
@@ -381,7 +388,7 @@ Mat findHomography( InputArray _points1, InputArray _points2,
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
double Mx = M[i].x, My = M[i].y;
|
||||
double ww = h[6] * Mx + h[7] * My + 1.;
|
||||
double ww = h[6] * Mx + h[7] * My + h[8];
|
||||
ww = fabs(ww) > DBL_EPSILON ? 1. / ww : 0;
|
||||
double xi = (h[0] * Mx + h[1] * My + h[2]) * ww;
|
||||
double yi = (h[3] * Mx + h[4] * My + h[5]) * ww;
|
||||
@@ -391,13 +398,11 @@ Mat findHomography( InputArray _points1, InputArray _points2,
|
||||
if (Jptr)
|
||||
{
|
||||
Jptr[0] = Mx * ww; Jptr[1] = My * ww; Jptr[2] = ww;
|
||||
Jptr[3] = Jptr[4] = Jptr[5] = 0.;
|
||||
Jptr[6] = -Mx * ww * xi; Jptr[7] = -My * ww * xi;
|
||||
Jptr[8] = Jptr[9] = Jptr[10] = 0.;
|
||||
Jptr[11] = Mx * ww; Jptr[12] = My * ww; Jptr[13] = ww;
|
||||
Jptr[14] = -Mx * ww * yi; Jptr[15] = -My * ww * yi;
|
||||
Jptr[6] = -Mx * ww * xi; Jptr[7] = -My * ww * xi; Jptr[8] = -ww * xi;
|
||||
Jptr[12] = Mx * ww; Jptr[13] = My * ww; Jptr[14] = ww;
|
||||
Jptr[15] = -Mx * ww * yi; Jptr[16] = -My * ww * yi; Jptr[17] = -ww * yi;
|
||||
|
||||
Jptr += 16;
|
||||
Jptr += 18;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -408,6 +413,7 @@ Mat findHomography( InputArray _points1, InputArray _points2,
|
||||
.setMaxIterations(10)
|
||||
.setGeodesic(true));
|
||||
solver.optimize();
|
||||
H.convertTo(H, H.type(), scaleFor(H.at<double>(2, 2)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -984,14 +990,6 @@ void computeCorrespondEpilines( InputArray _points, int whichImage,
|
||||
}
|
||||
}
|
||||
|
||||
static inline double scaleFor(double x){
|
||||
return (std::fabs(x) > std::numeric_limits<float>::epsilon()) ? 1./x : 1.;
|
||||
}
|
||||
static inline float scaleFor(float x){
|
||||
return (std::fabs(x) > std::numeric_limits<float>::epsilon()) ? 1.f/x : 1.f;
|
||||
}
|
||||
|
||||
|
||||
void convertPointsFromHomogeneous( InputArray _src, OutputArray _dst, int dtype )
|
||||
{
|
||||
CV_INSTRUMENT_REGION();
|
||||
|
||||
@@ -0,0 +1,188 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
|
||||
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
|
||||
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
|
||||
// Copyright (C) 2015, Itseez Inc., all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
#ifndef OPENCV_CALIB3D_HAL_REPLACEMENT_HPP
|
||||
#define OPENCV_CALIB3D_HAL_REPLACEMENT_HPP
|
||||
|
||||
#include "opencv2/core/hal/interface.h"
|
||||
|
||||
#if defined(__clang__) // clang or MSVC clang
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunused-parameter"
|
||||
#elif defined(_MSC_VER)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4100)
|
||||
#elif defined(__GNUC__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||
#endif
|
||||
|
||||
//! @addtogroup calib3d_hal_interface
|
||||
//! @note Define your functions to override default implementations:
|
||||
//! @code
|
||||
//! #undef hal_add8u
|
||||
//! #define hal_add8u my_add8u
|
||||
//! @endcode
|
||||
//! @{
|
||||
|
||||
/**
|
||||
* @brief Camera intrinsics structure, see projectPoints() documentation for details
|
||||
*/
|
||||
struct cv_camera_intrinsics_pinhole_32f
|
||||
{
|
||||
// focal length, principal point
|
||||
float fx, fy, cx, cy;
|
||||
// radial distortion coefficients
|
||||
float k[6];
|
||||
// amount of radial distortion coefficients passed
|
||||
int amt_k;
|
||||
// tangential distortion coefficients
|
||||
float p[2];
|
||||
// amount of tangential distortion coefficients passed
|
||||
int amt_p;
|
||||
// prism distortion coefficients
|
||||
float s[4];
|
||||
// amount of prism distortion coefficients passed
|
||||
int amt_s;
|
||||
// tilt distortion coefficients
|
||||
float tau_x, tau_y;
|
||||
// to use tilt distortion coefficients or not
|
||||
bool use_tau;
|
||||
};
|
||||
|
||||
/**
|
||||
@brief Project points from 3D world space to 2D screen space using rotation and translation matrix and camera intrinsic parameters
|
||||
@param src_data Pointer to 3D points array with coordinates interleaved as X, Y, Z, X, Y, Z,..
|
||||
@param src_step Step between consecutive 3D points
|
||||
@param src_size Amount of points
|
||||
@param dst_data Pointer to resulting projected 2D points with coordinates interleaved as u, v, u, v,..
|
||||
@param dst_step Step between consecutive projected 2D points
|
||||
@param rt_data Pointer to 3x4 array containing rotation-then-translation matrix
|
||||
@param intr_data Pointer to camera intrinsics structure
|
||||
*/
|
||||
inline int hal_ni_project_points_pinhole32f(const float* src_data, size_t src_step, size_t src_size,
|
||||
float* dst_data, size_t dst_step, const float* rt_data,
|
||||
const cv_camera_intrinsics_pinhole_32f* intr_data)
|
||||
{ return CV_HAL_ERROR_NOT_IMPLEMENTED; }
|
||||
|
||||
//! @cond IGNORED
|
||||
#define cv_hal_project_points_pinhole32f hal_ni_project_points_pinhole32f
|
||||
//! @endcond
|
||||
|
||||
/**
|
||||
* @brief Camera intrinsics structure, see projectPoints() documentation for details
|
||||
*/
|
||||
struct cv_camera_intrinsics_pinhole_64f
|
||||
{
|
||||
// focal length, principal point
|
||||
double fx, fy, cx, cy;
|
||||
// radial distortion coefficients
|
||||
double k[6];
|
||||
// amount of radial distortion coefficients passed
|
||||
int amt_k;
|
||||
// tangential distortion coefficients
|
||||
double p[2];
|
||||
// amount of tangential distortion coefficients passed
|
||||
int amt_p;
|
||||
// prism distortion coefficients
|
||||
double s[4];
|
||||
// amount of prism distortion coefficients passed
|
||||
int amt_s;
|
||||
// tilt distortion coefficients
|
||||
double tau_x, tau_y;
|
||||
// to use tilt distortion coefficients or not
|
||||
bool use_tau;
|
||||
};
|
||||
|
||||
/**
|
||||
@brief Project points from 3D world space to 2D screen space using rotation and translation matrix and camera intrinsic parameters
|
||||
@param src_data Pointer to 3D points array with coordinates interleaved as X, Y, Z, X, Y, Z,..
|
||||
@param src_step Step between consecutive 3D points
|
||||
@param src_size Amount of points
|
||||
@param dst_data Pointer to resulting projected 2D points with coordinates interleaved as u, v, u, v,..
|
||||
@param dst_step Step between consecutive projected 2D points
|
||||
@param rt_data Pointer to 3x4 array containing rotation-then-translation matrix
|
||||
@param intr_data Pointer to camera intrinsics structure
|
||||
*/
|
||||
inline int hal_ni_project_points_pinhole64f(const double* src_data, size_t src_step, size_t src_size,
|
||||
double* dst_data, size_t dst_step, const double* rt_data,
|
||||
const cv_camera_intrinsics_pinhole_64f* intr_data)
|
||||
{ return CV_HAL_ERROR_NOT_IMPLEMENTED; }
|
||||
|
||||
//! @cond IGNORED
|
||||
#define cv_hal_project_points_pinhole64f hal_ni_project_points_pinhole64f
|
||||
//! @endcond
|
||||
|
||||
//! @}
|
||||
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#elif defined(_MSC_VER)
|
||||
#pragma warning(pop)
|
||||
#elif defined(__GNUC__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#include "custom_hal.hpp"
|
||||
|
||||
//! @cond IGNORED
|
||||
#define CALL_HAL_RET(name, fun, retval, ...) \
|
||||
int res = __CV_EXPAND(fun(__VA_ARGS__, &retval)); \
|
||||
if (res == CV_HAL_ERROR_OK) \
|
||||
return retval; \
|
||||
else if (res != CV_HAL_ERROR_NOT_IMPLEMENTED) \
|
||||
CV_Error_(cv::Error::StsInternal, \
|
||||
("HAL implementation " CVAUX_STR(name) " ==> " CVAUX_STR(fun) " returned %d (0x%08x)", res, res));
|
||||
|
||||
|
||||
#define CALL_HAL(name, fun, ...) \
|
||||
int res = __CV_EXPAND(fun(__VA_ARGS__)); \
|
||||
if (res == CV_HAL_ERROR_OK) \
|
||||
return; \
|
||||
else if (res != CV_HAL_ERROR_NOT_IMPLEMENTED) \
|
||||
CV_Error_(cv::Error::StsInternal, \
|
||||
("HAL implementation " CVAUX_STR(name) " ==> " CVAUX_STR(fun) " returned %d (0x%08x)", res, res));
|
||||
//! @endcond
|
||||
|
||||
#endif
|
||||
@@ -155,7 +155,12 @@ public:
|
||||
const auto &eigen_vectors = eigen_solver.eigenvectors();
|
||||
const auto &eigen_values = eigen_solver.eigenvalues();
|
||||
#else
|
||||
|
||||
#if defined (ACCELERATE_NEW_LAPACK) && defined (ACCELERATE_LAPACK_ILP64)
|
||||
long mat_order = 27, info, lda = 27, ldvl = 1, ldvr = 27, lwork = 500;
|
||||
#else
|
||||
int mat_order = 27, info, lda = 27, ldvl = 1, ldvr = 27, lwork = 500;
|
||||
#endif
|
||||
double wr[27], wi[27] = {0}; // 27 = mat_order
|
||||
std::vector<double> work(lwork), eig_vecs(729);
|
||||
char jobvl = 'N', jobvr = 'V'; // only left eigen vectors are computed
|
||||
|
||||
@@ -259,7 +259,11 @@ public:
|
||||
action_mat_data[83] = -1.0; // 8 row, 3 col
|
||||
action_mat_data[96] = -1.0; // 9 row, 6 col
|
||||
|
||||
#if defined (ACCELERATE_NEW_LAPACK) && defined (ACCELERATE_LAPACK_ILP64)
|
||||
long mat_order = 10, info, lda = 10, ldvl = 10, ldvr = 1, lwork = 100;
|
||||
#else
|
||||
int mat_order = 10, info, lda = 10, ldvl = 10, ldvr = 1, lwork = 100;
|
||||
#endif
|
||||
double wr[10], wi[10] = {0}, eig_vecs[100], work[100]; // 10 = mat_order, 100 = lwork
|
||||
char jobvl = 'V', jobvr = 'N'; // only left eigen vectors are computed
|
||||
OCV_LAPACK_FUNC(dgeev)(&jobvl, &jobvr, &mat_order, action_mat_data, &lda, wr, wi, eig_vecs, &ldvl,
|
||||
|
||||
@@ -705,4 +705,63 @@ TEST(Calib3d_Homography, minPoints)
|
||||
EXPECT_THROW(findHomography(p1, p2, RANSAC, 0.01, mask), cv::Exception);
|
||||
}
|
||||
|
||||
TEST(Calib3d_Homography, not_normalized)
|
||||
{
|
||||
Mat_<double> p1({5, 2}, {-1, -1, -2, -2, -1, 1, -2, 2, -1, 0});
|
||||
Mat_<double> p2({5, 2}, {0, -1, -1, -1, 0, 0, -1, 0, 0, -0.5});
|
||||
Mat_<double> ref({3, 3}, {
|
||||
0.74276086, 0., 0.74276086,
|
||||
0.18569022, 0.18569022, 0.,
|
||||
-0.37138043, 0., 0.
|
||||
});
|
||||
|
||||
for (int method : std::vector<int>({0, RANSAC, LMEDS}))
|
||||
{
|
||||
Mat h = findHomography(p1, p2, method);
|
||||
for (auto it = h.begin<double>(); it != h.end<double>(); ++it) {
|
||||
ASSERT_FALSE(cvIsNaN(*it)) << cv::format("method %d\nResult:\n", method) << h;
|
||||
}
|
||||
if (h.at<double>(0, 0) * ref.at<double>(0, 0) < 0) {
|
||||
h *= -1;
|
||||
}
|
||||
ASSERT_LE(cv::norm(h, ref, NORM_INF), 1e-8) << cv::format("method %d\nResult:\n", method) << h;
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Calib3d_Homography, Refine)
|
||||
{
|
||||
Mat_<double> p1({10, 2}, {41, -86, -87, 99, 66, -96, -86, -8, -67, 24,
|
||||
-87, -76, -19, 89, 37, -4, -86, -86, -66, -53});
|
||||
Mat_<double> p2({10, 2}, {
|
||||
0.007723226608700208, -1.177541410622515,
|
||||
-0.1909072353027552, -0.4247610181930323,
|
||||
-0.134992319993638, -0.6469949816560389,
|
||||
-0.3570627451405215, 0.1811469436293486,
|
||||
-0.3005671881038939, -0.02325733734262935,
|
||||
-0.4404509481789249, 0.4851526464158342,
|
||||
0.6343346428859541, -3.396187657072353,
|
||||
-0.3539383967092603, 0.1469447227353143,
|
||||
-0.4526924606856586, 0.5296757109061794,
|
||||
-0.4309974583614644, 0.4522732662733471
|
||||
});
|
||||
hconcat(p1, Mat::ones(p1.rows, 1, CV_64F), p1);
|
||||
hconcat(p2, Mat::ones(p2.rows, 1, CV_64F), p2);
|
||||
|
||||
for(int method : std::vector<int>({0, RANSAC, LMEDS}))
|
||||
{
|
||||
Mat h = findHomography(p1, p2, method);
|
||||
EXPECT_NEAR(h.at<double>(2, 2), 1.0, 1e-7);
|
||||
|
||||
Mat proj = p1 * h.t();
|
||||
proj.col(0) /= proj.col(2);
|
||||
proj.col(1) /= proj.col(2);
|
||||
|
||||
Mat error;
|
||||
cv::pow(p2.colRange(0, 2) - proj.colRange(0, 2), 2, error);
|
||||
cv::reduce(error, error, 1, REDUCE_SUM);
|
||||
cv::reduce(error, error, 0, REDUCE_AVG);
|
||||
EXPECT_LE(sqrt(error.at<double>(0, 0)), method == LMEDS ? 7e-2 : 7e-5);
|
||||
}
|
||||
}
|
||||
|
||||
}} // namespace
|
||||
|
||||
Reference in New Issue
Block a user