From 6e6c0f31f741037dcaef960187e290e1f222f59b Mon Sep 17 00:00:00 2001 From: 103yiran <1039105206@qq.com> Date: Fri, 2 Apr 2021 10:30:27 +0800 Subject: [PATCH 1/6] delete unused variable --- modules/imgproc/src/imgwarp.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/imgproc/src/imgwarp.cpp b/modules/imgproc/src/imgwarp.cpp index 298f9b3b5b..c4dfd13a93 100644 --- a/modules/imgproc/src/imgwarp.cpp +++ b/modules/imgproc/src/imgwarp.cpp @@ -2190,7 +2190,7 @@ public: int bw = std::min( bw0, dst.cols - x); 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)); for( y1 = 0; y1 < bh; y1++ ) @@ -2979,7 +2979,7 @@ public: int bw = std::min( bw0, width - x); 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)); for( y1 = 0; y1 < bh; y1++ ) From 6465e393b697cfdba1d38c155e245598ab302f33 Mon Sep 17 00:00:00 2001 From: Maksim Shabunin Date: Fri, 2 Apr 2021 10:44:32 +0300 Subject: [PATCH 2/6] IPP: use linker workaround for Intel compiler on Linux --- cmake/OpenCVFindIPP.cmake | 2 +- cmake/OpenCVFindLibsPerf.cmake | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/OpenCVFindIPP.cmake b/cmake/OpenCVFindIPP.cmake index b4f3a78f2c..6bcd81d8b4 100644 --- a/cmake/OpenCVFindIPP.cmake +++ b/cmake/OpenCVFindIPP.cmake @@ -151,7 +151,7 @@ macro(ipp_detect_version) if("${name}" STREQUAL "core") # https://github.com/opencv/opencv/pull/19681 if(OPENCV_FORCE_IPP_EXCLUDE_LIBS OR OPENCV_FORCE_IPP_EXCLUDE_LIBS_CORE 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 ) diff --git a/cmake/OpenCVFindLibsPerf.cmake b/cmake/OpenCVFindLibsPerf.cmake index 3753084d28..a191afde58 100644 --- a/cmake/OpenCVFindLibsPerf.cmake +++ b/cmake/OpenCVFindLibsPerf.cmake @@ -29,7 +29,7 @@ if(WITH_IPP) if(OPENCV_FORCE_IPP_EXCLUDE_LIBS OR (HAVE_IPP_ICV 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 ) From ac9182f20d212bd3d826030157c800f6b9cd5b7b Mon Sep 17 00:00:00 2001 From: Tiago De Gaspari Date: Sat, 3 Apr 2021 21:56:05 -0300 Subject: [PATCH 3/6] Add maxIters parameter to LMeDS method in findFundamentalMat This commit passes the parameter maxIters that represent the maximum number of iterations, that can be passed to findFundamentalMat to the method LMeDS. This parameter were added to the function findFundamentalMat and were passed just for the RANSAC method, but should be passed to both methods to be consistent. --- modules/calib3d/src/fundam.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/calib3d/src/fundam.cpp b/modules/calib3d/src/fundam.cpp index 3c1b0ce00d..7fda90641f 100644 --- a/modules/calib3d/src/fundam.cpp +++ b/modules/calib3d/src/fundam.cpp @@ -866,7 +866,7 @@ cv::Mat cv::findFundamentalMat( InputArray _points1, InputArray _points2, if( (method & ~3) == FM_RANSAC && npoints >= 15 ) result = createRANSACPointSetRegistrator(cb, 7, ransacReprojThreshold, confidence, maxIters)->run(m1, m2, F, _mask); 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 ) From f3f46096d6cdc226fe4a16279275b3dc13cebe90 Mon Sep 17 00:00:00 2001 From: Aaron Greig Date: Wed, 31 Mar 2021 10:16:19 +0100 Subject: [PATCH 4/6] Relax accuracy requirements in the OpenCL sqrt perf arithmetic test. Also bring perf_imgproc CornerMinEigenVal accuracy requirements in line with the test_imgproc accuracy requirements on that test and fix indentation on the latter. Partially addresses issue #9821 --- modules/core/perf/opencl/perf_arithm.cpp | 7 ++++++- modules/imgproc/perf/opencl/perf_imgproc.cpp | 12 +++++++++++- modules/imgproc/test/ocl/test_imgproc.cpp | 8 +++++--- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/modules/core/perf/opencl/perf_arithm.cpp b/modules/core/perf/opencl/perf_arithm.cpp index 9f5f6e9e77..0cbfc2d653 100644 --- a/modules/core/perf/opencl/perf_arithm.cpp +++ b/modules/core/perf/opencl/perf_arithm.cpp @@ -678,7 +678,12 @@ OCL_PERF_TEST_P(SqrtFixture, Sqrt, ::testing::Combine( 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); else SANITY_CHECK(dst, 1); diff --git a/modules/imgproc/perf/opencl/perf_imgproc.cpp b/modules/imgproc/perf/opencl/perf_imgproc.cpp index 4b61976553..db4c4ef451 100644 --- a/modules/imgproc/perf/opencl/perf_imgproc.cpp +++ b/modules/imgproc/perf/opencl/perf_imgproc.cpp @@ -166,7 +166,17 @@ OCL_PERF_TEST_P(CornerMinEigenValFixture, CornerMinEigenVal, 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 //////////////////////// diff --git a/modules/imgproc/test/ocl/test_imgproc.cpp b/modules/imgproc/test/ocl/test_imgproc.cpp index 35185d339f..f3e9f4bb20 100644 --- a/modules/imgproc/test/ocl/test_imgproc.cpp +++ b/modules/imgproc/test/ocl/test_imgproc.cpp @@ -234,10 +234,12 @@ OCL_TEST_P(CornerMinEigenVal, Mat) OCL_OFF(cv::cornerMinEigenVal(src_roi, dst_roi, blockSize, apertureSize, borderType)); OCL_ON(cv::cornerMinEigenVal(usrc_roi, udst_roi, blockSize, apertureSize, borderType)); - if (ocl::Device::getDefault().isIntel()) - Near(1e-5, true); + // The corner kernel uses native_sqrt() which has implementation defined accuracy. + // 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 - Near(0.1, true); // using native_* OpenCL functions may lose accuracy + Near(0.1, true); } } From 9f295b2c9125b7c6c894f49ccbf0be5ffbef70c9 Mon Sep 17 00:00:00 2001 From: Tiago De Gaspari Date: Tue, 6 Apr 2021 22:11:03 -0300 Subject: [PATCH 5/6] Expose maxIters in findEssentialMat Lets the user choose the maximum number of iterations the robust estimator runs for, similary to findFundamentalMat and findHomography functions. --- modules/calib3d/include/opencv2/calib3d.hpp | 15 +++++++++++++ modules/calib3d/src/five-point.cpp | 25 +++++++++++++++++---- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/modules/calib3d/include/opencv2/calib3d.hpp b/modules/calib3d/include/opencv2/calib3d.hpp index b48c928d82..6df79fa7b5 100644 --- a/modules/calib3d/include/opencv2/calib3d.hpp +++ b/modules/calib3d/include/opencv2/calib3d.hpp @@ -2241,6 +2241,7 @@ final fundamental matrix. It can be set to something like 1-3, depending on the point localization, image resolution, and the image noise. @param mask Output array of N elements, every element of which is set to 0 for outliers and to 1 for the other points. The array is computed only in the RANSAC and LMedS methods. +@param maxIters The maximum number of robust method iterations. 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: @@ -2251,6 +2252,12 @@ 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 decomposeEssentialMat or recoverPose to recover the relative pose between cameras. */ +CV_EXPORTS_W Mat findEssentialMat( InputArray points1, InputArray points2, + InputArray cameraMatrix, int method, + double prob, double threshold, + int maxIters, OutputArray mask = noArray() ); + +/** @overload */ CV_EXPORTS_W Mat findEssentialMat( InputArray points1, InputArray points2, InputArray cameraMatrix, int method = RANSAC, double prob = 0.999, double threshold = 1.0, @@ -2274,6 +2281,7 @@ point localization, image resolution, and the image noise. confidence (probability) that the estimated matrix is correct. @param mask Output array of N elements, every element of which is set to 0 for outliers and to 1 for the other points. The array is computed only in the RANSAC and LMedS methods. +@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 principal point: @@ -2285,6 +2293,13 @@ f & 0 & x_{pp} \\ 0 & 0 & 1 \end{bmatrix}\f] */ +CV_EXPORTS_W Mat findEssentialMat( InputArray points1, InputArray points2, + double focal, Point2d pp, + int method, double prob, + double threshold, int maxIters, + OutputArray mask = noArray() ); + +/** @overload */ CV_EXPORTS_W Mat findEssentialMat( InputArray points1, InputArray points2, double focal = 1.0, Point2d pp = Point2d(0, 0), int method = RANSAC, double prob = 0.999, diff --git a/modules/calib3d/src/five-point.cpp b/modules/calib3d/src/five-point.cpp index 5909c2e2e3..dbdd294c7e 100644 --- a/modules/calib3d/src/five-point.cpp +++ b/modules/calib3d/src/five-point.cpp @@ -403,7 +403,8 @@ protected: // Input should be a vector of n 2D points or a Nx2 matrix 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(); @@ -442,20 +443,36 @@ cv::Mat cv::findEssentialMat( InputArray _points1, InputArray _points2, InputArr Mat E; if( method == RANSAC ) - createRANSACPointSetRegistrator(makePtr(), 5, threshold, prob)->run(points1, points2, E, _mask); + createRANSACPointSetRegistrator(makePtr(), 5, threshold, prob, maxIters)->run(points1, points2, E, _mask); else - createLMeDSPointSetRegistrator(makePtr(), 5, prob)->run(points1, points2, E, _mask); + createLMeDSPointSetRegistrator(makePtr(), 5, prob, maxIters)->run(points1, points2, E, _mask); 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_(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, int method, double prob, double threshold, OutputArray _mask) { CV_INSTRUMENT_REGION(); Mat cameraMatrix = (Mat_(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); } int cv::recoverPose( InputArray E, InputArray _points1, InputArray _points2, From 76860933f0a31c0abd1b26c1f11b25972cda031e Mon Sep 17 00:00:00 2001 From: Danny <33044223+danielenricocahall@users.noreply.github.com> Date: Thu, 8 Apr 2021 06:39:26 -0400 Subject: [PATCH 6/6] Merge pull request #19859 from danielenricocahall:fix-blob-detector-single-thresh Fix Single ThresholdBug in Simple Blob Detector * address bug with using min dist between blobs in blob detector cast type in comparison and remove docs address bug with using min dist between blobs in blob detector use scalar instead of int address bug with using min dist between blobs in blob detector * fix namespace and formatting --- modules/features2d/src/blobdetector.cpp | 8 ++++++- modules/features2d/test/test_blobdetector.cpp | 21 +++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 modules/features2d/test/test_blobdetector.cpp diff --git a/modules/features2d/src/blobdetector.cpp b/modules/features2d/src/blobdetector.cpp index d07e8bae83..c2215cd57c 100644 --- a/modules/features2d/src/blobdetector.cpp +++ b/modules/features2d/src/blobdetector.cpp @@ -325,13 +325,19 @@ void SimpleBlobDetectorImpl::detect(InputArray image, std::vector& std::vector < Center > 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
> newCenters; for (size_t i = 0; i < curCenters.size(); i++) { bool isNew = true; 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; if (!isNew) { diff --git a/modules/features2d/test/test_blobdetector.cpp b/modules/features2d/test/test_blobdetector.cpp new file mode 100644 index 0000000000..56b7145862 --- /dev/null +++ b/modules/features2d/test/test_blobdetector.cpp @@ -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 keypoints; + + Ptr detector = SimpleBlobDetector::create(params); + detector->detect(image, keypoints); + ASSERT_NE((int) keypoints.size(), 0); +} +}} // namespace