Merge remote-tracking branch 'upstream/3.4' into merge-3.4

This commit is contained in:
Alexander Alekhin 2021-04-08 10:48:51 +00:00
commit 68d15fc62e
11 changed files with 111 additions and 23 deletions

View File

@ -151,7 +151,7 @@ macro(ipp_detect_version)
if("${name}" STREQUAL "core") # https://github.com/opencv/opencv/pull/19681 if("${name}" STREQUAL "core") # https://github.com/opencv/opencv/pull/19681
if(OPENCV_FORCE_IPP_EXCLUDE_LIBS OR OPENCV_FORCE_IPP_EXCLUDE_LIBS_CORE if(OPENCV_FORCE_IPP_EXCLUDE_LIBS OR OPENCV_FORCE_IPP_EXCLUDE_LIBS_CORE
OR (UNIX AND NOT ANDROID AND NOT APPLE OR (UNIX AND NOT ANDROID AND NOT APPLE
AND (CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") AND CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|Intel"
) )
AND NOT OPENCV_SKIP_IPP_EXCLUDE_LIBS_CORE AND NOT OPENCV_SKIP_IPP_EXCLUDE_LIBS_CORE
) )

View File

@ -29,7 +29,7 @@ if(WITH_IPP)
if(OPENCV_FORCE_IPP_EXCLUDE_LIBS if(OPENCV_FORCE_IPP_EXCLUDE_LIBS
OR (HAVE_IPP_ICV OR (HAVE_IPP_ICV
AND UNIX AND NOT ANDROID AND NOT APPLE AND UNIX AND NOT ANDROID AND NOT APPLE
AND (CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") AND CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|Intel"
) )
AND NOT OPENCV_SKIP_IPP_EXCLUDE_LIBS AND NOT OPENCV_SKIP_IPP_EXCLUDE_LIBS
) )

View File

@ -2690,6 +2690,7 @@ final fundamental matrix. It can be set to something like 1-3, depending on the
point localization, image resolution, and the image noise. point localization, image resolution, and the image noise.
@param mask Output array of N elements, every element of which is set to 0 for outliers and to 1 @param mask Output array of N elements, every element of which is set to 0 for outliers and to 1
for the other points. The array is computed only in the RANSAC and LMedS methods. for the other points. The array is computed only in the RANSAC and LMedS methods.
@param maxIters The maximum number of robust method iterations.
This function estimates essential matrix based on the five-point algorithm solver in @cite Nister03 . This function estimates essential matrix based on the five-point algorithm solver in @cite Nister03 .
@cite SteweniusCFS is also a related. The epipolar geometry is described by the following equation: @cite SteweniusCFS is also a related. The epipolar geometry is described by the following equation:
@ -2700,10 +2701,22 @@ where \f$E\f$ is an essential matrix, \f$p_1\f$ and \f$p_2\f$ are corresponding
second images, respectively. The result of this function may be passed further to second images, respectively. The result of this function may be passed further to
decomposeEssentialMat or recoverPose to recover the relative pose between cameras. decomposeEssentialMat or recoverPose to recover the relative pose between cameras.
*/ */
CV_EXPORTS_W Mat findEssentialMat( InputArray points1, InputArray points2, CV_EXPORTS_W
InputArray cameraMatrix, int method = RANSAC, Mat findEssentialMat(
double prob = 0.999, double threshold = 1.0, InputArray points1, InputArray points2,
OutputArray mask = noArray() ); InputArray cameraMatrix, int method = RANSAC,
double prob = 0.999, double threshold = 1.0,
int maxIters = 1000, OutputArray mask = noArray()
);
/** @overload */
CV_EXPORTS
Mat findEssentialMat(
InputArray points1, InputArray points2,
InputArray cameraMatrix, int method,
double prob, double threshold,
OutputArray mask
); // TODO remove from OpenCV 5.0
/** @overload /** @overload
@param points1 Array of N (N \>= 5) 2D points from the first image. The point coordinates should @param points1 Array of N (N \>= 5) 2D points from the first image. The point coordinates should
@ -2723,6 +2736,7 @@ point localization, image resolution, and the image noise.
confidence (probability) that the estimated matrix is correct. confidence (probability) that the estimated matrix is correct.
@param mask Output array of N elements, every element of which is set to 0 for outliers and to 1 @param mask Output array of N elements, every element of which is set to 0 for outliers and to 1
for the other points. The array is computed only in the RANSAC and LMedS methods. for the other points. The array is computed only in the RANSAC and LMedS methods.
@param maxIters The maximum number of robust method iterations.
This function differs from the one above that it computes camera intrinsic matrix from focal length and This function differs from the one above that it computes camera intrinsic matrix from focal length and
principal point: principal point:
@ -2734,10 +2748,23 @@ f & 0 & x_{pp} \\
0 & 0 & 1 0 & 0 & 1
\end{bmatrix}\f] \end{bmatrix}\f]
*/ */
CV_EXPORTS_W Mat findEssentialMat( InputArray points1, InputArray points2, CV_EXPORTS_W
double focal = 1.0, Point2d pp = Point2d(0, 0), Mat findEssentialMat(
int method = RANSAC, double prob = 0.999, InputArray points1, InputArray points2,
double threshold = 1.0, OutputArray mask = noArray() ); double focal = 1.0, Point2d pp = Point2d(0, 0),
int method = RANSAC, double prob = 0.999,
double threshold = 1.0, int maxIters = 1000,
OutputArray mask = noArray()
);
/** @overload */
CV_EXPORTS
Mat findEssentialMat(
InputArray points1, InputArray points2,
double focal, Point2d pp,
int method, double prob,
double threshold, OutputArray mask
); // TODO remove from OpenCV 5.0
/** @brief Calculates an essential matrix from the corresponding points in two images from potentially two different cameras. /** @brief Calculates an essential matrix from the corresponding points in two images from potentially two different cameras.

View File

@ -405,7 +405,8 @@ protected:
// Input should be a vector of n 2D points or a Nx2 matrix // Input should be a vector of n 2D points or a Nx2 matrix
cv::Mat cv::findEssentialMat( InputArray _points1, InputArray _points2, InputArray _cameraMatrix, cv::Mat cv::findEssentialMat( InputArray _points1, InputArray _points2, InputArray _cameraMatrix,
int method, double prob, double threshold, OutputArray _mask) int method, double prob, double threshold,
int maxIters, OutputArray _mask)
{ {
CV_INSTRUMENT_REGION(); CV_INSTRUMENT_REGION();
@ -448,20 +449,36 @@ cv::Mat cv::findEssentialMat( InputArray _points1, InputArray _points2, InputArr
Mat E; Mat E;
if( method == RANSAC ) if( method == RANSAC )
createRANSACPointSetRegistrator(makePtr<EMEstimatorCallback>(), 5, threshold, prob)->run(points1, points2, E, _mask); createRANSACPointSetRegistrator(makePtr<EMEstimatorCallback>(), 5, threshold, prob, maxIters)->run(points1, points2, E, _mask);
else else
createLMeDSPointSetRegistrator(makePtr<EMEstimatorCallback>(), 5, prob)->run(points1, points2, E, _mask); createLMeDSPointSetRegistrator(makePtr<EMEstimatorCallback>(), 5, prob, maxIters)->run(points1, points2, E, _mask);
return E; return E;
} }
cv::Mat cv::findEssentialMat( InputArray _points1, InputArray _points2, InputArray _cameraMatrix,
int method, double prob, double threshold,
OutputArray _mask)
{
return cv::findEssentialMat(_points1, _points2, _cameraMatrix, method, prob, threshold, 1000, _mask);
}
cv::Mat cv::findEssentialMat( InputArray _points1, InputArray _points2, double focal, Point2d pp,
int method, double prob, double threshold, int maxIters, OutputArray _mask)
{
CV_INSTRUMENT_REGION();
Mat cameraMatrix = (Mat_<double>(3,3) << focal, 0, pp.x, 0, focal, pp.y, 0, 0, 1);
return cv::findEssentialMat(_points1, _points2, cameraMatrix, method, prob, threshold, maxIters, _mask);
}
cv::Mat cv::findEssentialMat( InputArray _points1, InputArray _points2, double focal, Point2d pp, cv::Mat cv::findEssentialMat( InputArray _points1, InputArray _points2, double focal, Point2d pp,
int method, double prob, double threshold, OutputArray _mask) int method, double prob, double threshold, OutputArray _mask)
{ {
CV_INSTRUMENT_REGION(); CV_INSTRUMENT_REGION();
Mat cameraMatrix = (Mat_<double>(3,3) << focal, 0, pp.x, 0, focal, pp.y, 0, 0, 1); Mat cameraMatrix = (Mat_<double>(3,3) << focal, 0, pp.x, 0, focal, pp.y, 0, 0, 1);
return cv::findEssentialMat(_points1, _points2, cameraMatrix, method, prob, threshold, _mask); return cv::findEssentialMat(_points1, _points2, cameraMatrix, method, prob, threshold, 1000, _mask);
} }
cv::Mat cv::findEssentialMat( InputArray _points1, InputArray _points2, cv::Mat cv::findEssentialMat( InputArray _points1, InputArray _points2,

View File

@ -888,7 +888,7 @@ cv::Mat cv::findFundamentalMat( InputArray _points1, InputArray _points2,
if( (method & ~3) == FM_RANSAC && npoints >= 15 ) if( (method & ~3) == FM_RANSAC && npoints >= 15 )
result = createRANSACPointSetRegistrator(cb, 7, ransacReprojThreshold, confidence, maxIters)->run(m1, m2, F, _mask); result = createRANSACPointSetRegistrator(cb, 7, ransacReprojThreshold, confidence, maxIters)->run(m1, m2, F, _mask);
else else
result = createLMeDSPointSetRegistrator(cb, 7, confidence)->run(m1, m2, F, _mask); result = createLMeDSPointSetRegistrator(cb, 7, confidence, maxIters)->run(m1, m2, F, _mask);
} }
if( result <= 0 ) if( result <= 0 )

View File

@ -678,7 +678,12 @@ OCL_PERF_TEST_P(SqrtFixture, Sqrt, ::testing::Combine(
OCL_TEST_CYCLE() cv::sqrt(src, dst); OCL_TEST_CYCLE() cv::sqrt(src, dst);
if (CV_MAT_DEPTH(type) >= CV_32F) // To square root 32 bit floats we use native_sqrt, which has implementation
// defined accuracy. We know intel devices have accurate native_sqrt, but
// otherwise stick to a relaxed sanity check. For types larger than 32 bits
// we can do the accuracy check for all devices as normal.
if (CV_MAT_DEPTH(type) > CV_32F || !ocl::useOpenCL() ||
ocl::Device::getDefault().isIntel())
SANITY_CHECK(dst, 1e-5, ERROR_RELATIVE); SANITY_CHECK(dst, 1e-5, ERROR_RELATIVE);
else else
SANITY_CHECK(dst, 1); SANITY_CHECK(dst, 1);

View File

@ -325,13 +325,19 @@ void SimpleBlobDetectorImpl::detect(InputArray image, std::vector<cv::KeyPoint>&
std::vector < Center > curCenters; std::vector < Center > curCenters;
findBlobs(grayscaleImage, binarizedImage, curCenters); findBlobs(grayscaleImage, binarizedImage, curCenters);
if(params.maxThreshold - params.minThreshold <= params.thresholdStep) {
// if the difference between min and max threshold is less than the threshold step
// we're only going to enter the loop once, so we need to add curCenters
// to ensure we still use minDistBetweenBlobs
centers.push_back(curCenters);
}
std::vector < std::vector<Center> > newCenters; std::vector < std::vector<Center> > newCenters;
for (size_t i = 0; i < curCenters.size(); i++) for (size_t i = 0; i < curCenters.size(); i++)
{ {
bool isNew = true; bool isNew = true;
for (size_t j = 0; j < centers.size(); j++) for (size_t j = 0; j < centers.size(); j++)
{ {
double dist = norm(centers[j][ centers[j].size() / 2 ].location - curCenters[i].location); double dist = norm(centers[j][centers[j].size() / 2 ].location - curCenters[i].location);
isNew = dist >= params.minDistBetweenBlobs && dist >= centers[j][ centers[j].size() / 2 ].radius && dist >= curCenters[i].radius; isNew = dist >= params.minDistBetweenBlobs && dist >= centers[j][ centers[j].size() / 2 ].radius && dist >= curCenters[i].radius;
if (!isNew) if (!isNew)
{ {

View File

@ -0,0 +1,21 @@
// 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 "test_precomp.hpp"
namespace opencv_test { namespace {
TEST(Features2d_BlobDetector, bug_6667)
{
cv::Mat image = cv::Mat(cv::Size(100, 100), CV_8UC1, cv::Scalar(255, 255, 255));
cv::circle(image, Point(50, 50), 20, cv::Scalar(0), -1);
SimpleBlobDetector::Params params;
params.minThreshold = 250;
params.maxThreshold = 260;
std::vector<KeyPoint> keypoints;
Ptr<SimpleBlobDetector> detector = SimpleBlobDetector::create(params);
detector->detect(image, keypoints);
ASSERT_NE((int) keypoints.size(), 0);
}
}} // namespace

View File

@ -166,7 +166,17 @@ OCL_PERF_TEST_P(CornerMinEigenValFixture, CornerMinEigenVal,
OCL_TEST_CYCLE() cv::cornerMinEigenVal(src, dst, blockSize, apertureSize, borderType); OCL_TEST_CYCLE() cv::cornerMinEigenVal(src, dst, blockSize, apertureSize, borderType);
SANITY_CHECK(dst, 1e-6, ERROR_RELATIVE); #ifdef HAVE_OPENCL
bool strictCheck = !ocl::useOpenCL() || ocl::Device::getDefault().isIntel();
#else
bool strictCheck = true;
#endif
// using native_* OpenCL functions on non-intel devices may lose accuracy
if (strictCheck)
SANITY_CHECK(dst, 1e-6, ERROR_RELATIVE);
else
SANITY_CHECK(dst, 0.1, ERROR_RELATIVE);
} }
///////////// CornerHarris //////////////////////// ///////////// CornerHarris ////////////////////////

View File

@ -2190,7 +2190,7 @@ public:
int bw = std::min( bw0, dst.cols - x); int bw = std::min( bw0, dst.cols - x);
int bh = std::min( bh0, range.end - y); int bh = std::min( bh0, range.end - y);
Mat _XY(bh, bw, CV_16SC2, XY), matA; Mat _XY(bh, bw, CV_16SC2, XY);
Mat dpart(dst, Rect(x, y, bw, bh)); Mat dpart(dst, Rect(x, y, bw, bh));
for( y1 = 0; y1 < bh; y1++ ) for( y1 = 0; y1 < bh; y1++ )
@ -2979,7 +2979,7 @@ public:
int bw = std::min( bw0, width - x); int bw = std::min( bw0, width - x);
int bh = std::min( bh0, range.end - y); // height int bh = std::min( bh0, range.end - y); // height
Mat _XY(bh, bw, CV_16SC2, XY), matA; Mat _XY(bh, bw, CV_16SC2, XY);
Mat dpart(dst, Rect(x, y, bw, bh)); Mat dpart(dst, Rect(x, y, bw, bh));
for( y1 = 0; y1 < bh; y1++ ) for( y1 = 0; y1 < bh; y1++ )

View File

@ -234,10 +234,12 @@ OCL_TEST_P(CornerMinEigenVal, Mat)
OCL_OFF(cv::cornerMinEigenVal(src_roi, dst_roi, blockSize, apertureSize, borderType)); OCL_OFF(cv::cornerMinEigenVal(src_roi, dst_roi, blockSize, apertureSize, borderType));
OCL_ON(cv::cornerMinEigenVal(usrc_roi, udst_roi, blockSize, apertureSize, borderType)); OCL_ON(cv::cornerMinEigenVal(usrc_roi, udst_roi, blockSize, apertureSize, borderType));
if (ocl::Device::getDefault().isIntel()) // The corner kernel uses native_sqrt() which has implementation defined accuracy.
Near(1e-5, true); // If we're using a CL implementation that isn't intel, test with relaxed accuracy.
if (!ocl::useOpenCL() || ocl::Device::getDefault().isIntel())
Near(1e-5, true);
else else
Near(0.1, true); // using native_* OpenCL functions may lose accuracy Near(0.1, true);
} }
} }