From ad6f52dc54bdc2141a7923bbe7844103158ac883 Mon Sep 17 00:00:00 2001 From: Rostislav Vasilikhin Date: Mon, 20 Nov 2023 14:54:05 +0100 Subject: [PATCH 01/19] build script fixed --- platforms/android/build_sdk.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/platforms/android/build_sdk.py b/platforms/android/build_sdk.py index f445be10f6..279b55d65e 100755 --- a/platforms/android/build_sdk.py +++ b/platforms/android/build_sdk.py @@ -250,15 +250,16 @@ class Builder: cmake_vars['BUILD_SHARED_LIBS'] = "ON" if self.config.modules_list is not None: - cmd.append("-DBUILD_LIST='%s'" % self.config.modules_list) + cmake_vars['BUILD_LIST'] = '%s' % self.config.modules_list if self.config.extra_modules_path is not None: - cmd.append("-DOPENCV_EXTRA_MODULES_PATH='%s'" % self.config.extra_modules_path) + cmake_vars['OPENCV_EXTRA_MODULES_PATH'] = '%s' % self.config.extra_modules_path if self.use_ccache == True: - cmd.append("-DNDK_CCACHE=ccache") + cmake_vars['NDK_CCACHE'] = 'ccache' if do_install: - cmd.extend(["-DBUILD_TESTS=ON", "-DINSTALL_TESTS=ON"]) + cmake_vars['BUILD_TESTS'] = "ON" + cmake_vars['INSTALL_TESTS'] = "ON" cmake_vars.update(abi.cmake_vars) cmd += [ "-D%s='%s'" % (k, v) for (k, v) in cmake_vars.items() if v is not None] From 258b06229504b2c411412067c74aa3c9edd0c9f1 Mon Sep 17 00:00:00 2001 From: ajithvallabai Date: Wed, 22 Nov 2023 15:52:51 +0530 Subject: [PATCH 02/19] cudaMemset2D fix: Correct buffer height parameter Changed the height parameter in the cudaMemset2D function call to use minSSD_buf.rows instead of disp.rows. This enures the correct buffer height is used for memory initialization. --- modules/cudastereo/src/cuda/stereobm.cu | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/cudastereo/src/cuda/stereobm.cu b/modules/cudastereo/src/cuda/stereobm.cu index 7c72f76e38..724dbfe633 100644 --- a/modules/cudastereo/src/cuda/stereobm.cu +++ b/modules/cudastereo/src/cuda/stereobm.cu @@ -391,7 +391,7 @@ namespace cv { namespace cuda { namespace device //cudaSafeCall( cudaFuncSetCacheConfig(&stereoKernel, cudaFuncCachePreferShared) ); cudaSafeCall( cudaMemset2D(disp.data, disp.step, 0, disp.cols, disp.rows) ); - cudaSafeCall( cudaMemset2D(minSSD_buf.data, minSSD_buf.step, 0xFF, minSSD_buf.cols * minSSD_buf.elemSize(), disp.rows) ); + cudaSafeCall( cudaMemset2D(minSSD_buf.data, minSSD_buf.step, 0xFF, minSSD_buf.cols * minSSD_buf.elemSize(), minSSD_buf.rows) ); cudaSafeCall( cudaMemcpyToSymbol( cwidth, &left.cols, sizeof(left.cols) ) ); cudaSafeCall( cudaMemcpyToSymbol( cheight, &left.rows, sizeof(left.rows) ) ); From 3640217772319f4beee3b5b8e3dbf875dc6f0890 Mon Sep 17 00:00:00 2001 From: MaximSmolskiy Date: Mon, 8 Jan 2024 23:13:31 +0300 Subject: [PATCH 03/19] Compensate edge length in ChessBoardDetector::generateQuads --- modules/calib3d/src/calibinit.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/modules/calib3d/src/calibinit.cpp b/modules/calib3d/src/calibinit.cpp index 39544f2bb3..f001ada867 100644 --- a/modules/calib3d/src/calibinit.cpp +++ b/modules/calib3d/src/calibinit.cpp @@ -233,7 +233,7 @@ public: all_quads_count = 0; } - void generateQuads(const cv::Mat& image_, int flags); + void generateQuads(const cv::Mat& image_, int flags, int dilations); bool processQuads(std::vector& out_corners, int &prev_sqr_size); @@ -546,7 +546,7 @@ bool findChessboardCorners(InputArray image_, Size pattern_size, rectangle( thresh_img_new, Point(0,0), Point(thresh_img_new.cols-1, thresh_img_new.rows-1), Scalar(255,255,255), 3, LINE_8); detector.reset(); - detector.generateQuads(thresh_img_new, flags); + detector.generateQuads(thresh_img_new, flags, dilations); DPRINTF("Quad count: %d/%d", detector.all_quads_count, (pattern_size.width/2+1)*(pattern_size.height/2+1)); SHOW_QUADS("New quads", thresh_img_new, &detector.all_quads[0], detector.all_quads_count); if (detector.processQuads(out_corners, prev_sqr_size)) @@ -611,7 +611,7 @@ bool findChessboardCorners(InputArray image_, Size pattern_size, rectangle( thresh_img, Point(0,0), Point(thresh_img.cols-1, thresh_img.rows-1), Scalar(255,255,255), 3, LINE_8); detector.reset(); - detector.generateQuads(thresh_img, flags); + detector.generateQuads(thresh_img, flags, dilations); DPRINTF("Quad count: %d/%d", detector.all_quads_count, (pattern_size.width/2+1)*(pattern_size.height/2+1)); SHOW_QUADS("Old quads", thresh_img, &detector.all_quads[0], detector.all_quads_count); if (detector.processQuads(out_corners, prev_sqr_size)) @@ -1754,7 +1754,7 @@ void ChessBoardDetector::findQuadNeighbors() // returns corners in clockwise order // corners don't necessarily start at same position on quad (e.g., // top left corner) -void ChessBoardDetector::generateQuads(const cv::Mat& image_, int flags) +void ChessBoardDetector::generateQuads(const cv::Mat& image_, int flags, int dilations) { binarized_image = image_; // save for debug purposes @@ -1879,6 +1879,9 @@ void ChessBoardDetector::generateQuads(const cv::Mat& image_, int flags) float d = normL2Sqr(q.corners[i]->pt - q.corners[(i+1)&3]->pt); q.edge_len = std::min(q.edge_len, d); } + + const int edge_len_compensation = 2 * dilations; + q.edge_len += 2 * sqrt(q.edge_len) * edge_len_compensation + edge_len_compensation * edge_len_compensation; } all_quads_count = quad_count; From 2b579b5a09ef277ec35601a6740c992b13bd2f85 Mon Sep 17 00:00:00 2001 From: Anastasiya Pronina Date: Fri, 15 Dec 2023 16:32:21 +0000 Subject: [PATCH 04/19] Fixed support of mean/scale preprocessing in OV backend for non-real types --- modules/gapi/src/backends/ov/govbackend.cpp | 23 ++- .../gapi/test/infer/gapi_infer_ov_tests.cpp | 181 ++++++++++++++++++ 2 files changed, 198 insertions(+), 6 deletions(-) diff --git a/modules/gapi/src/backends/ov/govbackend.cpp b/modules/gapi/src/backends/ov/govbackend.cpp index 7e99af4f77..abbe5f9f5b 100644 --- a/modules/gapi/src/backends/ov/govbackend.cpp +++ b/modules/gapi/src/backends/ov/govbackend.cpp @@ -794,13 +794,24 @@ public: } } - void cfgScaleMean(const std::string &input_name) { + void cfgScaleMean(const std::string &input_name, + const GMetaArg &input_meta) { auto &input_info = m_ppp.input(input_name); + const auto mean_vec = lookUp(m_mean_values, input_name); + const auto scale_vec = lookUp(m_scale_values, input_name); + + if (mean_vec || scale_vec) { + GAPI_Assert(cv::util::holds_alternative(input_meta)); + const auto depth = cv::util::get(input_meta).depth; + const bool depth_is_real = (depth == CV_32F) || (depth == CV_16F); + if (!depth_is_real) { + input_info.preprocess().convert_element_type(toOV(CV_32F)); + } + } if (mean_vec) { input_info.preprocess().mean(*mean_vec); } - const auto scale_vec = lookUp(m_scale_values, input_name); if (scale_vec) { input_info.preprocess().scale(*scale_vec); } @@ -974,7 +985,7 @@ struct Infer: public cv::detail::KernelTag { ppp.cfgLayouts(input_name); ppp.cfgPreProcessing(input_name, mm); - ppp.cfgScaleMean(input_name); + ppp.cfgScaleMean(input_name, mm); } ppp.cfgPostProcessing(); ppp.finalize(); @@ -1062,7 +1073,7 @@ struct InferROI: public cv::detail::KernelTag { ppp.cfgLayouts(input_name); ppp.cfgPreProcessing(input_name, mm, true /*disable_img_resize*/); - ppp.cfgScaleMean(input_name); + ppp.cfgScaleMean(input_name, mm); ppp.cfgPostProcessing(); ppp.finalize(); } @@ -1148,7 +1159,7 @@ struct InferList: public cv::detail::KernelTag { ppp.cfgLayouts(input_name); ppp.cfgPreProcessing(input_name, mm, true /*disable_img_resize*/); - ppp.cfgScaleMean(input_name); + ppp.cfgScaleMean(input_name, mm); } ppp.cfgPostProcessing(); ppp.finalize(); @@ -1267,7 +1278,7 @@ struct InferList2: public cv::detail::KernelTag { GAPI_Assert(op.k.inKinds[idx] == cv::detail::OpaqueKind::CV_MAT); } - ppp.cfgScaleMean(input_name); + ppp.cfgScaleMean(input_name, mm_0); idx++; // NB: Never forget to increment the counter } ppp.cfgPostProcessing(); diff --git a/modules/gapi/test/infer/gapi_infer_ov_tests.cpp b/modules/gapi/test/infer/gapi_infer_ov_tests.cpp index abce82b329..8a15d5e741 100644 --- a/modules/gapi/test/infer/gapi_infer_ov_tests.cpp +++ b/modules/gapi/test/infer/gapi_infer_ov_tests.cpp @@ -657,6 +657,187 @@ TEST_F(TestAgeGenderListOV, InferList2Generic_Image) { validate(); } +static ov::element::Type toOV(int depth) { + switch (depth) { + case CV_8U: return ov::element::u8; + case CV_32S: return ov::element::i32; + case CV_32F: return ov::element::f32; + case CV_16F: return ov::element::f16; + default: GAPI_Error("OV Backend: Unsupported data type"); + } + return ov::element::undefined; +} + +struct TestMeanScaleOV : public ::testing::TestWithParam{ + G_API_NET(IdentityNet, , "test-identity-net"); + + static cv::GComputation create() { + cv::GMat in; + cv::GMat out; + out = cv::gapi::infer(in); + + return cv::GComputation{cv::GIn(in), cv::GOut(out)}; + } + + using Params = cv::gapi::ov::Params; + static Params params(const std::string &xml_path, + const std::string &bin_path, + const std::string &device) { + return Params { + xml_path, bin_path, device + }.cfgInputModelLayout("NHWC") + .cfgOutputLayers({ "output" }); + } + + TestMeanScaleOV() { + initDLDTDataPath(); + + m_model_path = findDataFile("gapi/ov/identity_net_100x100.xml"); + m_weights_path = findDataFile("gapi/ov/identity_net_100x100.bin"); + m_device_id = "CPU"; + + m_ov_model = cv::gapi::ov::wrap::getCore() + .read_model(m_model_path, m_weights_path); + + auto input_depth = GetParam(); + auto input = cv::imread(findDataFile("gapi/gapi_logo.jpg")); + input.convertTo(m_in_mat, input_depth); + } + + void addPreprocToOV( + std::function f) { + + auto input_depth = GetParam(); + + ov::preprocess::PrePostProcessor ppp(m_ov_model); + ppp.input().tensor().set_layout(ov::Layout("NHWC")) + .set_element_type(toOV(input_depth)) + .set_shape({ 1, 100, 100, 3 }); + ppp.input().model().set_layout(ov::Layout("NHWC")); + f(ppp); + m_ov_model = ppp.build(); + } + + void runOV() { + auto compiled_model = cv::gapi::ov::wrap::getCore() + .compile_model(m_ov_model, m_device_id); + auto infer_request = compiled_model.create_infer_request(); + + auto input_tensor = infer_request.get_input_tensor(); + cv::gapi::ov::util::to_ov(m_in_mat, input_tensor); + + infer_request.infer(); + + auto out_tensor = infer_request.get_tensor("output"); + m_out_mat_ov.create(cv::gapi::ov::util::to_ocv(out_tensor.get_shape()), + cv::gapi::ov::util::to_ocv(out_tensor.get_element_type())); + cv::gapi::ov::util::to_ocv(out_tensor, m_out_mat_ov); + } + + std::string m_model_path; + std::string m_weights_path; + std::string m_device_id; + + std::shared_ptr m_ov_model; + + cv::Mat m_in_mat; + cv::Mat m_out_mat_gapi; + cv::Mat m_out_mat_ov; +}; + +TEST_P(TestMeanScaleOV, Mean) +{ + int input_depth = GetParam(); + + std::vector mean_values{ 220.1779, 218.9857, 217.8986 }; + + // Run OV reference pipeline: + { + addPreprocToOV([&](ov::preprocess::PrePostProcessor& ppp) { + if (input_depth == CV_8U || input_depth == CV_32S) { + ppp.input().preprocess().convert_element_type(ov::element::f32); + } + ppp.input().preprocess().mean(mean_values); + }); + runOV(); + } + + // Run G-API + GComputation comp = create(); + auto pp = params(m_model_path, m_weights_path, m_device_id); + pp.cfgMean(mean_values); + + comp.apply(cv::gin(m_in_mat), cv::gout(m_out_mat_gapi), + cv::compile_args(cv::gapi::networks(pp))); + + // Validate OV results against G-API ones: + normAssert(m_out_mat_ov, m_out_mat_gapi, "Test output"); +} + +TEST_P(TestMeanScaleOV, Scale) +{ + int input_depth = GetParam(); + + std::vector scale_values{ 2., 2., 2. }; + + // Run OV reference pipeline: + { + addPreprocToOV([&](ov::preprocess::PrePostProcessor& ppp) { + if (input_depth == CV_8U || input_depth == CV_32S) { + ppp.input().preprocess().convert_element_type(ov::element::f32); + } + ppp.input().preprocess().scale(scale_values); + }); + runOV(); + } + + // Run G-API + GComputation comp = create(); + auto pp = params(m_model_path, m_weights_path, m_device_id); + pp.cfgScale(scale_values); + + comp.apply(cv::gin(m_in_mat), cv::gout(m_out_mat_gapi), + cv::compile_args(cv::gapi::networks(pp))); + + // Validate OV results against G-API ones: + normAssert(m_out_mat_ov, m_out_mat_gapi, "Test output"); +} + +TEST_P(TestMeanScaleOV, MeanAndScale) +{ + int input_depth = GetParam(); + + std::vector mean_values{ 220.1779, 218.9857, 217.8986 }; + std::vector scale_values{ 2., 2., 2. }; + + // Run OV reference pipeline: + { + addPreprocToOV([&](ov::preprocess::PrePostProcessor& ppp) { + if (input_depth == CV_8U || input_depth == CV_32S) { + ppp.input().preprocess().convert_element_type(ov::element::f32); + } + ppp.input().preprocess().mean(mean_values); + ppp.input().preprocess().scale(scale_values); + }); + runOV(); + } + + // Run G-API + GComputation comp = create(); + auto pp = params(m_model_path, m_weights_path, m_device_id); + pp.cfgMean(mean_values); + pp.cfgScale(scale_values); + + comp.apply(cv::gin(m_in_mat), cv::gout(m_out_mat_gapi), + cv::compile_args(cv::gapi::networks(pp))); + + // Validate OV results against G-API ones: + normAssert(m_out_mat_ov, m_out_mat_gapi, "Test output"); +} + +INSTANTIATE_TEST_CASE_P(Instantiation, TestMeanScaleOV, + Values(CV_8U, CV_32S, CV_16F, CV_32F)); + } // namespace opencv_test #endif // HAVE_INF_ENGINE && INF_ENGINE_RELEASE >= 2022010000 From bcbc74d4cd57f3536d947e4815685c91a6c4fb46 Mon Sep 17 00:00:00 2001 From: MaximSmolskiy Date: Thu, 8 Feb 2024 01:31:29 +0300 Subject: [PATCH 05/19] Do not dilate binary images on first iteration in findChessboardCorners --- modules/calib3d/src/calibinit.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/modules/calib3d/src/calibinit.cpp b/modules/calib3d/src/calibinit.cpp index b61c0069e3..4b57aad1fe 100644 --- a/modules/calib3d/src/calibinit.cpp +++ b/modules/calib3d/src/calibinit.cpp @@ -531,14 +531,14 @@ bool findChessboardCorners(InputArray image_, Size pattern_size, const int min_dilations = 0; const int max_dilations = is_plain ? 0 : 7; - // Try our standard "1" dilation, but if the pattern is not found, iterate the whole procedure with higher dilations. - // This is necessary because some squares simply do not separate properly with a single dilation. However, + // Try our standard "0" and "1" dilations, but if the pattern is not found, iterate the whole procedure with higher dilations. + // This is necessary because some squares simply do not separate properly without and with a single dilations. However, // we want to use the minimum number of dilations possible since dilations cause the squares to become smaller, // making it difficult to detect smaller squares. for (int dilations = min_dilations; dilations <= max_dilations; dilations++) { //USE BINARY IMAGE COMPUTED USING icvBinarizationHistogramBased METHOD - if(!is_plain) + if(!is_plain && dilations > 0) dilate( thresh_img_new, thresh_img_new, Mat(), Point(-1, -1), 1 ); // So we can find rectangles that go to the edge, we draw a white line around the image edge. @@ -596,13 +596,13 @@ bool findChessboardCorners(InputArray image_, Size pattern_size, block_size = block_size | 1; // convert to binary adaptiveThreshold( img, thresh_img, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, block_size, (k/2)*5 ); - if (dilations > 0) - dilate( thresh_img, thresh_img, Mat(), Point(-1, -1), dilations-1 ); + dilate( thresh_img, thresh_img, Mat(), Point(-1, -1), dilations ); } else { - dilate( thresh_img, thresh_img, Mat(), Point(-1, -1), 1 ); + if (dilations > 0) + dilate( thresh_img, thresh_img, Mat(), Point(-1, -1), 1 ); } SHOW("Old binarization", thresh_img); From f5928a5be9932154e6df0c2734cad3caaaa6a0de Mon Sep 17 00:00:00 2001 From: Kumataro Date: Thu, 8 Feb 2024 12:35:29 +0900 Subject: [PATCH 06/19] imgcodecs: refix 23416 to use perf::MatType --- modules/imgcodecs/test/test_tiff.cpp | 48 +++++----------------------- 1 file changed, 8 insertions(+), 40 deletions(-) diff --git a/modules/imgcodecs/test/test_tiff.cpp b/modules/imgcodecs/test/test_tiff.cpp index db27a305e5..4b248fd5e1 100644 --- a/modules/imgcodecs/test/test_tiff.cpp +++ b/modules/imgcodecs/test/test_tiff.cpp @@ -14,38 +14,6 @@ namespace opencv_test { namespace { #define int64 int64_hack_ #include "tiff.h" -// Re-define Mat type as enum for showing on Google Test. -enum CV_ddtCn{ - _CV_8UC1 = CV_8UC1, _CV_8UC3 = CV_8UC3, _CV_8UC4 = CV_8UC4, - _CV_8SC1 = CV_8SC1, _CV_8SC3 = CV_8SC3, _CV_8SC4 = CV_8SC4, - _CV_16UC1 = CV_16UC1, _CV_16UC3 = CV_16UC3, _CV_16UC4 = CV_16UC4, - _CV_16SC1 = CV_16SC1, _CV_16SC3 = CV_16SC3, _CV_16SC4 = CV_16SC4, - _CV_32SC1 = CV_32SC1, _CV_32SC3 = CV_32SC3, _CV_32SC4 = CV_32SC4, - _CV_16FC1 = CV_16FC1, _CV_16FC3 = CV_16FC3, _CV_16FC4 = CV_16FC4, - _CV_32FC1 = CV_32FC1, _CV_32FC3 = CV_32FC3, _CV_32FC4 = CV_32FC4, - _CV_64FC1 = CV_64FC1, _CV_64FC3 = CV_64FC3, _CV_64FC4 = CV_64FC4, -}; - -static inline -void PrintTo(const CV_ddtCn& val, std::ostream* os) -{ - const int val_type = static_cast(val); - - switch ( CV_MAT_DEPTH(val_type) ) - { - case CV_8U : *os << "CV_8U" ; break; - case CV_16U : *os << "CV_16U" ; break; - case CV_8S : *os << "CV_8S" ; break; - case CV_16S : *os << "CV_16S" ; break; - case CV_32S : *os << "CV_32S" ; break; - case CV_16F : *os << "CV_16F" ; break; - case CV_32F : *os << "CV_32F" ; break; - case CV_64F : *os << "CV_64F" ; break; - default : *os << "CV_???" ; break; - } - *os << "C" << CV_MAT_CN(val_type); -} - #ifdef __ANDROID__ // Test disabled as it uses a lot of memory. // It is killed with SIGKILL by out of memory killer. @@ -874,7 +842,7 @@ TEST(Imgcodecs_Tiff, readWrite_predictor) // See https://github.com/opencv/opencv/issues/23416 -typedef std::pair Imgcodes_Tiff_TypeAndComp; +typedef std::pair Imgcodes_Tiff_TypeAndComp; typedef testing::TestWithParam< Imgcodes_Tiff_TypeAndComp > Imgcodecs_Tiff_Types; TEST_P(Imgcodecs_Tiff_Types, readWrite_alltypes) @@ -925,13 +893,13 @@ TEST_P(Imgcodecs_Tiff_Types, readWrite_alltypes) } Imgcodes_Tiff_TypeAndComp all_types[] = { - { _CV_8UC1, true }, { _CV_8UC3, true }, { _CV_8UC4, true }, - { _CV_8SC1, true }, { _CV_8SC3, true }, { _CV_8SC4, true }, - { _CV_16UC1, true }, { _CV_16UC3, true }, { _CV_16UC4, true }, - { _CV_16SC1, true }, { _CV_16SC3, true }, { _CV_16SC4, true }, - { _CV_32SC1, true }, { _CV_32SC3, true }, { _CV_32SC4, true }, - { _CV_32FC1, false }, { _CV_32FC3, false }, { _CV_32FC4, false }, // No compression - { _CV_64FC1, false }, { _CV_64FC3, false }, { _CV_64FC4, false } // No compression + { CV_8UC1, true }, { CV_8UC3, true }, { CV_8UC4, true }, + { CV_8SC1, true }, { CV_8SC3, true }, { CV_8SC4, true }, + { CV_16UC1, true }, { CV_16UC3, true }, { CV_16UC4, true }, + { CV_16SC1, true }, { CV_16SC3, true }, { CV_16SC4, true }, + { CV_32SC1, true }, { CV_32SC3, true }, { CV_32SC4, true }, + { CV_32FC1, false }, { CV_32FC3, false }, { CV_32FC4, false }, // No compression + { CV_64FC1, false }, { CV_64FC3, false }, { CV_64FC4, false } // No compression }; INSTANTIATE_TEST_CASE_P(AllTypes, Imgcodecs_Tiff_Types, testing::ValuesIn(all_types)); From 3c73557dac574a8e2f2bdd658e222f6538436f2f Mon Sep 17 00:00:00 2001 From: eplankin Date: Fri, 9 Feb 2024 04:00:06 -0800 Subject: [PATCH 07/19] Update IPPICV binaries (20231206) --- 3rdparty/ippicv/ippicv.cmake | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/3rdparty/ippicv/ippicv.cmake b/3rdparty/ippicv/ippicv.cmake index 380f65f8c6..1c711d8847 100644 --- a/3rdparty/ippicv/ippicv.cmake +++ b/3rdparty/ippicv/ippicv.cmake @@ -2,7 +2,7 @@ function(download_ippicv root_var) set(${root_var} "" PARENT_SCOPE) # Commit SHA in the opencv_3rdparty repo - set(IPPICV_COMMIT "0cc4aa06bf2bef4b05d237c69a5a96b9cd0cb85a") + set(IPPICV_COMMIT "c7c6d527dde5fee7cb914ee9e4e20f7436aab3a1") # Define actual ICV versions if(APPLE) set(OPENCV_ICV_PLATFORM "macosx") @@ -13,21 +13,21 @@ function(download_ippicv root_var) set(OPENCV_ICV_PLATFORM "linux") set(OPENCV_ICV_PACKAGE_SUBDIR "ippicv_lnx") if(X86_64) - set(OPENCV_ICV_NAME "ippicv_2021.10.0_lnx_intel64_20230919_general.tgz") - set(OPENCV_ICV_HASH "606a19b207ebedfe42d59fd916cc4850") + set(OPENCV_ICV_NAME "ippicv_2021.10.1_lnx_intel64_20231206_general.tgz") + set(OPENCV_ICV_HASH "90884d3b9508f31f6a154165591b8b0b") else() - set(OPENCV_ICV_NAME "ippicv_2021.10.0_lnx_ia32_20230919_general.tgz") - set(OPENCV_ICV_HASH "ea08487b810baad2f68aca87b74a2db9") + set(OPENCV_ICV_NAME "ippicv_2021.10.1_lnx_ia32_20231206_general.tgz") + set(OPENCV_ICV_HASH "d9510f3ce08f6074aac472a5c19a3b53") endif() elseif(WIN32 AND NOT ARM) set(OPENCV_ICV_PLATFORM "windows") set(OPENCV_ICV_PACKAGE_SUBDIR "ippicv_win") if(X86_64) - set(OPENCV_ICV_NAME "ippicv_2021.10.0_win_intel64_20230919_general.zip") - set(OPENCV_ICV_HASH "538a819ec84193a9c9f3c0f8df0be8b7") + set(OPENCV_ICV_NAME "ippicv_2021.10.1_win_intel64_20231206_general.zip") + set(OPENCV_ICV_HASH "2d5f137d4dd8a5205cc1edb5616fb3da") else() - set(OPENCV_ICV_NAME "ippicv_2021.10.0_win_ia32_20230919_general.zip") - set(OPENCV_ICV_HASH "8ff93c69415ab0835cc1e94dc5660f5d") + set(OPENCV_ICV_NAME "ippicv_2021.10.1_win_ia32_20231206_general.zip") + set(OPENCV_ICV_HASH "63c41a943e93ca87541b71ab67f207b5") endif() else() return() From f300deb569fbd2800179523adfc1a385f3789ae3 Mon Sep 17 00:00:00 2001 From: Maksym Ivashechkin Date: Mon, 12 Feb 2024 07:16:19 +0000 Subject: [PATCH 08/19] Merge pull request #24987 from ivashmak:bugfix_infinite_loop bug fix infinite loop #24987 Fixes #24967 ### 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 - [x] The PR is proposed to the proper branch - [x] There is a reference to the original bug report and related work - [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [x] The feature is well documented and sample code can be built with the project CMake Bugfix to #24967 --- modules/calib3d/src/usac/utils.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/modules/calib3d/src/usac/utils.cpp b/modules/calib3d/src/usac/utils.cpp index 204b31cf92..8d95fb9c33 100644 --- a/modules/calib3d/src/usac/utils.cpp +++ b/modules/calib3d/src/usac/utils.cpp @@ -169,6 +169,9 @@ public: int getRealRoots (const std::vector &coeffs, std::vector &real_roots) override { if (coeffs.empty()) return 0; + for (auto c : coeffs) + if (cvIsNaN(c) || cvIsInf(c)) + return 0; Poly input(coeffs); if (input.degree() < 1) return 0; From b0201ec55fbe9da0bc20c7b22478c0903c04a038 Mon Sep 17 00:00:00 2001 From: Lollyrana <106834378+Lollyrana@users.noreply.github.com> Date: Mon, 12 Feb 2024 22:55:33 +0530 Subject: [PATCH 09/19] Fix_typo_size_ predefined_types.py --- modules/python/src2/typing_stubs_generation/predefined_types.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/python/src2/typing_stubs_generation/predefined_types.py b/modules/python/src2/typing_stubs_generation/predefined_types.py index 6e08a85c9a..0514a14dda 100644 --- a/modules/python/src2/typing_stubs_generation/predefined_types.py +++ b/modules/python/src2/typing_stubs_generation/predefined_types.py @@ -79,7 +79,7 @@ _PREDEFINED_TYPES = ( PrimitiveTypeNode.float_("Moments::value")), AliasTypeNode.tuple_("RotatedRect", items=(AliasRefTypeNode("Point2f"), - AliasRefTypeNode("Size"), + AliasRefTypeNode("Size2f"), PrimitiveTypeNode.float_()), doc="Any type providing sequence protocol is supported"), AliasTypeNode.tuple_("TermCriteria", From 0424ba57d7fb7abf0649358a326fe026ad1030d4 Mon Sep 17 00:00:00 2001 From: Alexander Smorkalov Date: Mon, 12 Feb 2024 20:41:40 +0300 Subject: [PATCH 10/19] Alternative solution for QR code black/white balance computation. --- modules/objdetect/src/qrcode.cpp | 5 ++++- modules/objdetect/test/test_qrcode.cpp | 17 +++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/modules/objdetect/src/qrcode.cpp b/modules/objdetect/src/qrcode.cpp index 71dd9d8257..4a6ffcc942 100644 --- a/modules/objdetect/src/qrcode.cpp +++ b/modules/objdetect/src/qrcode.cpp @@ -3070,7 +3070,10 @@ protected: { bool operator()(const Point2f& a, const Point2f& b) const { - return a.y < b.y; + if (a.y != b.y) + return a.y < b.y; + else + return a.x < b.x; } }; struct compareSquare diff --git a/modules/objdetect/test/test_qrcode.cpp b/modules/objdetect/test/test_qrcode.cpp index 63b50a2a59..dc579e8ef3 100644 --- a/modules/objdetect/test/test_qrcode.cpp +++ b/modules/objdetect/test/test_qrcode.cpp @@ -614,4 +614,21 @@ TEST(Objdetect_QRCode_detectAndDecode, utf8_output) EXPECT_NE(decoded_info.find("M\xc3\xbcllheimstrasse"), std::string::npos); } +TEST_P(Objdetect_QRCode_detectAndDecodeMulti, detect_regression_24679) +{ + const std::string name_current_image = "issue_24679.png"; + const std::string root = "qrcode/"; + + std::string image_path = findDataFile(root + name_current_image); + Mat img = imread(image_path); + const std::string method = GetParam(); + GraphicalCodeDetector qrcode = QRCodeDetector(); + if (method == "aruco_based") { + qrcode = QRCodeDetectorAruco(); + } + std::vector decoded_info; + ASSERT_TRUE(qrcode.detectAndDecodeMulti(img, decoded_info)); + EXPECT_EQ(decoded_info.size(), 4U); +} + }} // namespace From b24e36545413d93c11cbf60ae2a680410f9ea082 Mon Sep 17 00:00:00 2001 From: Alexander Smorkalov Date: Tue, 13 Feb 2024 15:02:38 +0300 Subject: [PATCH 11/19] Suppress TBB compilation warnings visible during Android SDK build. --- 3rdparty/tbb/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/3rdparty/tbb/CMakeLists.txt b/3rdparty/tbb/CMakeLists.txt index 50f3e6ccf1..efc67046c6 100644 --- a/3rdparty/tbb/CMakeLists.txt +++ b/3rdparty/tbb/CMakeLists.txt @@ -100,6 +100,8 @@ ocv_warnings_disable(CMAKE_CXX_FLAGS -Wimplicit-fallthrough # TBB 2018 under GCC 7+ -Wmissing-prototypes # MacOSX, Android/Clang -Wundef -Wmissing-declarations # TBB 2019 + -Wnon-virtual-dtor # oneTBB-2020.2 Android + -Wunused-but-set-variable # oneTBB-2020.2 Android ) set(TBB_SOURCE_FILES ${lib_srcs} ${lib_hdrs}) From fefd2e5ce6d38eda50ddd13934f8440c33056cf5 Mon Sep 17 00:00:00 2001 From: Yannis Guyon Date: Wed, 14 Feb 2024 11:43:52 +0100 Subject: [PATCH 12/19] Remove 3 hidden leading chars in flann/dist.h /**** is EF BB BF 2F 2A 2A 2A 2A instead of 2F 2A 2A 2A 2A. --- modules/flann/include/opencv2/flann/dist.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/flann/include/opencv2/flann/dist.h b/modules/flann/include/opencv2/flann/dist.h index 2d7cbf13de..48540f7fdf 100644 --- a/modules/flann/include/opencv2/flann/dist.h +++ b/modules/flann/include/opencv2/flann/dist.h @@ -1,4 +1,4 @@ -/*********************************************************************** +/*********************************************************************** * Software License Agreement (BSD License) * * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved. From 0fa538fcc8ed637129ad04842a63d3b47becd098 Mon Sep 17 00:00:00 2001 From: lpanaf Date: Wed, 14 Feb 2024 16:12:10 +0300 Subject: [PATCH 13/19] Typo fix in Aruco documentation. --- modules/objdetect/include/opencv2/objdetect/aruco_detector.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/objdetect/include/opencv2/objdetect/aruco_detector.hpp b/modules/objdetect/include/opencv2/objdetect/aruco_detector.hpp index d537e43dc5..9d30d55d17 100644 --- a/modules/objdetect/include/opencv2/objdetect/aruco_detector.hpp +++ b/modules/objdetect/include/opencv2/objdetect/aruco_detector.hpp @@ -252,7 +252,7 @@ struct CV_EXPORTS_W_SIMPLE RefineParameters { */ CV_PROP_RW float minRepDistance; - /** @brief minRepDistance rate of allowed erroneous bits respect to the error correction capability of the used dictionary. + /** @brief errorCorrectionRate rate of allowed erroneous bits respect to the error correction capability of the used dictionary. * * -1 ignores the error correction step. */ From b87058f7acb85551ff4566a5c34bee82ae60c603 Mon Sep 17 00:00:00 2001 From: lpanaf Date: Thu, 15 Feb 2024 16:21:14 +0300 Subject: [PATCH 14/19] Changed initial estimation for F in fisheye calibration. --- modules/calib3d/src/fisheye.cpp | 2 +- modules/calib3d/test/test_fisheye.cpp | 17 +++++++++++------ 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/modules/calib3d/src/fisheye.cpp b/modules/calib3d/src/fisheye.cpp index 1be7cb44c2..911e16da9e 100644 --- a/modules/calib3d/src/fisheye.cpp +++ b/modules/calib3d/src/fisheye.cpp @@ -799,7 +799,7 @@ double cv::fisheye::calibrate(InputArrayOfArrays objectPoints, InputArrayOfArray } else { - finalParam.Init(Vec2d(max(image_size.width, image_size.height) / CV_PI, max(image_size.width, image_size.height) / CV_PI), + finalParam.Init(Vec2d(max(image_size.width, image_size.height) / 2., max(image_size.width, image_size.height) / 2.), Vec2d(image_size.width / 2.0 - 0.5, image_size.height / 2.0 - 0.5)); } diff --git a/modules/calib3d/test/test_fisheye.cpp b/modules/calib3d/test/test_fisheye.cpp index b914b72957..f48635e664 100644 --- a/modules/calib3d/test/test_fisheye.cpp +++ b/modules/calib3d/test/test_fisheye.cpp @@ -410,6 +410,11 @@ TEST_F(fisheyeTest, Calibration) { const int n_images = 34; + const cv::Matx33d goldK(558.4780870585967, 0, 620.4585053962692, + 0, 560.5067667343917, 381.9394122875291, + 0, 0, 1); + const cv::Vec4d goldD(-0.00146136, -0.00329847, 0.00605742, -0.00374201); + std::vector > imagePoints(n_images); std::vector > objectPoints(n_images); @@ -437,8 +442,8 @@ TEST_F(fisheyeTest, Calibration) cv::fisheye::calibrate(objectPoints, imagePoints, imageSize, theK, theD, cv::noArray(), cv::noArray(), flag, cv::TermCriteria(3, 20, 1e-6)); - EXPECT_MAT_NEAR(theK, this->K, 1e-10); - EXPECT_MAT_NEAR(theD, this->D, 1e-10); + EXPECT_MAT_NEAR(theK, goldK, 1e-8); + EXPECT_MAT_NEAR(theD, goldD, 1e-8); } TEST_F(fisheyeTest, CalibrationWithFixedFocalLength) @@ -597,10 +602,10 @@ TEST_F(fisheyeTest, EstimateUncertainties) cv::internal::EstimateUncertainties(objectPoints, imagePoints, param, rvec, tvec, errors, err_std, thresh_cond, check_cond, rms); - EXPECT_MAT_NEAR(errors.f, cv::Vec2d(1.34250246865020720, 1.36037536429654530), 1e-10); - EXPECT_MAT_NEAR(errors.c, cv::Vec2d(0.92070526160049848, 0.84383585812851514), 1e-10); - EXPECT_MAT_NEAR(errors.k, cv::Vec4d(0.0053379581373996041, 0.017389792901700545, 0.022036256089491224, 0.0094714594258908952), 1e-10); - EXPECT_MAT_NEAR(err_std, cv::Vec2d(0.187475975266883, 0.185678953263995), 1e-10); + EXPECT_MAT_NEAR(errors.f, cv::Vec2d(1.34250246865020720, 1.36037536429654530), 1e-6); + EXPECT_MAT_NEAR(errors.c, cv::Vec2d(0.92070526160049848, 0.84383585812851514), 1e-6); + EXPECT_MAT_NEAR(errors.k, cv::Vec4d(0.0053379581373996041, 0.017389792901700545, 0.022036256089491224, 0.0094714594258908952), 1e-7); + EXPECT_MAT_NEAR(err_std, cv::Vec2d(0.187475975266883, 0.185678953263995), 1e-7); CV_Assert(fabs(rms - 0.263782587133546) < 1e-10); CV_Assert(errors.alpha == 0); } From 78a765cb8166d719ddf5e283badbd06676eddbe4 Mon Sep 17 00:00:00 2001 From: Alexander Smorkalov Date: Fri, 16 Feb 2024 12:11:31 +0300 Subject: [PATCH 15/19] Reverted Compensate edge length in ChessBoardDetector::generateQuads #24833 --- modules/calib3d/src/calibinit.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/modules/calib3d/src/calibinit.cpp b/modules/calib3d/src/calibinit.cpp index ea5e5023b9..4b57aad1fe 100644 --- a/modules/calib3d/src/calibinit.cpp +++ b/modules/calib3d/src/calibinit.cpp @@ -234,7 +234,7 @@ public: all_quads_count = 0; } - void generateQuads(const cv::Mat& image_, int flags, int dilations); + void generateQuads(const cv::Mat& image_, int flags); bool processQuads(std::vector& out_corners, int &prev_sqr_size); @@ -547,7 +547,7 @@ bool findChessboardCorners(InputArray image_, Size pattern_size, rectangle( thresh_img_new, Point(0,0), Point(thresh_img_new.cols-1, thresh_img_new.rows-1), Scalar(255,255,255), 3, LINE_8); detector.reset(); - detector.generateQuads(thresh_img_new, flags, dilations); + detector.generateQuads(thresh_img_new, flags); DPRINTF("Quad count: %d/%d", detector.all_quads_count, (pattern_size.width/2+1)*(pattern_size.height/2+1)); SHOW_QUADS("New quads", thresh_img_new, &detector.all_quads[0], detector.all_quads_count); if (detector.processQuads(out_corners, prev_sqr_size)) @@ -612,7 +612,7 @@ bool findChessboardCorners(InputArray image_, Size pattern_size, rectangle( thresh_img, Point(0,0), Point(thresh_img.cols-1, thresh_img.rows-1), Scalar(255,255,255), 3, LINE_8); detector.reset(); - detector.generateQuads(thresh_img, flags, dilations); + detector.generateQuads(thresh_img, flags); DPRINTF("Quad count: %d/%d", detector.all_quads_count, (pattern_size.width/2+1)*(pattern_size.height/2+1)); SHOW_QUADS("Old quads", thresh_img, &detector.all_quads[0], detector.all_quads_count); if (detector.processQuads(out_corners, prev_sqr_size)) @@ -1755,7 +1755,7 @@ void ChessBoardDetector::findQuadNeighbors() // returns corners in clockwise order // corners don't necessarily start at same position on quad (e.g., // top left corner) -void ChessBoardDetector::generateQuads(const cv::Mat& image_, int flags, int dilations) +void ChessBoardDetector::generateQuads(const cv::Mat& image_, int flags) { binarized_image = image_; // save for debug purposes @@ -1880,9 +1880,6 @@ void ChessBoardDetector::generateQuads(const cv::Mat& image_, int flags, int dil float d = normL2Sqr(q.corners[i]->pt - q.corners[(i+1)&3]->pt); q.edge_len = std::min(q.edge_len, d); } - - const int edge_len_compensation = 2 * dilations; - q.edge_len += 2 * sqrt(q.edge_len) * edge_len_compensation + edge_len_compensation * edge_len_compensation; } all_quads_count = quad_count; From 68f6c81539457fc5098ca53f5cc97ba03261d98f Mon Sep 17 00:00:00 2001 From: Adrian Kretz Date: Fri, 16 Feb 2024 14:09:04 +0100 Subject: [PATCH 16/19] Merge pull request #25026 from akretz:fix_qrcode_bugs Fix qrcode bugs #25026 This PR fixes #22892, #24011 and #24450 and adds regression tests using the images provided. I've also verified with the [benchmark](https://github.com/opencv/opencv_benchmarks/tree/develop/python_benchmarks/qr_codes) that this doesn't break anything there. resolves #22892 resolves #24011 resolves #24450 Replaces #23802 Requires extra: https://github.com/opencv/opencv_extra/pull/1148 ### 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 - [x] The PR is proposed to the proper branch - [x] There is a reference to the original bug report and related work - [x] 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 --- modules/objdetect/src/qrcode.cpp | 31 +++++++++++------ modules/objdetect/test/test_qrcode.cpp | 48 ++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 11 deletions(-) diff --git a/modules/objdetect/src/qrcode.cpp b/modules/objdetect/src/qrcode.cpp index 4a6ffcc942..285535e705 100644 --- a/modules/objdetect/src/qrcode.cpp +++ b/modules/objdetect/src/qrcode.cpp @@ -466,16 +466,25 @@ bool QRDetect::localization() CV_TRACE_FUNCTION(); Point2f begin, end; vector list_lines_x = searchHorizontalLines(); - if( list_lines_x.empty() ) { return false; } - vector list_lines_y = separateVerticalLines(list_lines_x); - if( list_lines_y.empty() ) { return false; } - + vector list_lines_y; Mat labels; - kmeans(list_lines_y, 3, labels, - TermCriteria( TermCriteria::EPS + TermCriteria::COUNT, 10, 0.1), - 3, KMEANS_PP_CENTERS, localization_points); + if (!list_lines_x.empty()) + { + list_lines_y = separateVerticalLines(list_lines_x); + if (!list_lines_y.empty()) + { + kmeans(list_lines_y, 3, labels, + TermCriteria( TermCriteria::EPS + TermCriteria::COUNT, 10, 0.1), + 3, KMEANS_PP_CENTERS, localization_points); - fixationPoints(localization_points); + fixationPoints(localization_points); + } + } + + if (labels.empty()) + { + localization_points.clear(); + } bool square_flag = false, local_points_flag = false; double triangle_sides[3]; @@ -1563,9 +1572,9 @@ Point QRDecode::findClosestZeroPoint(Point2f original_point) Point zero_point; const int step = 2; - for (int i = orig_x - step; i >= 0 && i <= orig_x + step; i++) + for (int i = std::max(orig_x - step, 0); i >= 0 && i <= std::min(orig_x + step, bin_barcode.cols - 1); i++) { - for (int j = orig_y - step; j >= 0 && j <= orig_y + step; j++) + for (int j = std::max(orig_y - step, 0); j >= 0 && j <= std::min(orig_y + step, bin_barcode.rows - 1); j++) { Point p(i, j); value = bin_barcode.at(p); @@ -1943,7 +1952,7 @@ vector > QRDecode::computeSpline(const vector &x_arr, const v } for (int i = 0; i < n - 1; i++) { - h[i] = static_cast(y_arr[i + 1] - y_arr[i]); + h[i] = static_cast(y_arr[i + 1] - y_arr[i]) + std::numeric_limits::epsilon(); } for (int i = 1; i < n - 1; i++) { diff --git a/modules/objdetect/test/test_qrcode.cpp b/modules/objdetect/test/test_qrcode.cpp index dc579e8ef3..9f1ea7a800 100644 --- a/modules/objdetect/test/test_qrcode.cpp +++ b/modules/objdetect/test/test_qrcode.cpp @@ -631,4 +631,52 @@ TEST_P(Objdetect_QRCode_detectAndDecodeMulti, detect_regression_24679) EXPECT_EQ(decoded_info.size(), 4U); } +TEST_P(Objdetect_QRCode_detectAndDecodeMulti, detect_regression_24011) +{ + const std::string name_current_image = "issue_24011.jpg"; + const std::string root = "qrcode/"; + + std::string image_path = findDataFile(root + name_current_image); + Mat img = imread(image_path); + const std::string method = GetParam(); + GraphicalCodeDetector qrcode = QRCodeDetector(); + if (method == "aruco_based") { + qrcode = QRCodeDetectorAruco(); + } + std::vector decoded_info; + ASSERT_TRUE(qrcode.detectAndDecodeMulti(img, decoded_info)); + EXPECT_EQ(decoded_info.size(), 2U); +} + +TEST(Objdetect_QRCode_detect, detect_regression_24450) +{ + const std::string name_current_image = "issue_24450.png"; + const std::string root = "qrcode/"; + + std::string image_path = findDataFile(root + name_current_image); + Mat img = imread(image_path); + GraphicalCodeDetector qrcode = QRCodeDetector(); + std::vector points; + ASSERT_TRUE(qrcode.detect(img, points)); + EXPECT_EQ(points.size(), 4U); + img.at(img.rows - 1, 296) = {}; + ASSERT_TRUE(qrcode.detect(img, points)); + EXPECT_EQ(points.size(), 4U); +} + +TEST(Objdetect_QRCode_detect, detect_regression_22892) +{ + const std::string name_current_image = "issue_22892.png"; + const std::string root = "qrcode/"; + + std::string image_path = findDataFile(root + name_current_image); + Mat img = imread(image_path); + + QRCodeDetector qrcode; + std::vector corners; + Mat straight_code; + qrcode.detectAndDecodeCurved(img, corners, straight_code); + EXPECT_EQ(corners.size(), 4U); +} + }} // namespace From b2db9596193857156dbf8406fac77e5a54aa17cf Mon Sep 17 00:00:00 2001 From: Alexander Panov Date: Fri, 16 Feb 2024 16:37:49 +0300 Subject: [PATCH 17/19] Merge pull request #25035 from AleksandrPanov:fix_Barcode_detectAndDecode Fix barcode detectAndDecode #25035 The method `detectAndDecode()` in the `BarcodeDetector` class doesn't return the barcode corners. This PR fixes the and add test for `detectAndDecode`. ### 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 - [x] The PR is proposed to the proper branch - [x] There is a reference to the original bug report and related work - [x] 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 --- modules/objdetect/perf/perf_barcode.cpp | 6 ++++++ modules/objdetect/src/barcode.cpp | 4 ++-- modules/objdetect/test/test_barcode.cpp | 7 +++++++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/modules/objdetect/perf/perf_barcode.cpp b/modules/objdetect/perf/perf_barcode.cpp index b960518a1e..9c464bbd11 100644 --- a/modules/objdetect/perf/perf_barcode.cpp +++ b/modules/objdetect/perf/perf_barcode.cpp @@ -30,6 +30,7 @@ PERF_TEST_P_(Perf_Barcode_multi, detect) } SANITY_CHECK_NOTHING(); ASSERT_TRUE(res); + ASSERT_EQ(16ull, corners.size()); } PERF_TEST_P_(Perf_Barcode_multi, detect_decode) @@ -54,6 +55,8 @@ PERF_TEST_P_(Perf_Barcode_multi, detect_decode) } SANITY_CHECK_NOTHING(); ASSERT_TRUE(res); + ASSERT_EQ(16ull, corners.size()); + ASSERT_EQ(4ull, decoded_info.size()); } PERF_TEST_P_(Perf_Barcode_single, detect) @@ -76,6 +79,7 @@ PERF_TEST_P_(Perf_Barcode_single, detect) } SANITY_CHECK_NOTHING(); ASSERT_TRUE(res); + ASSERT_EQ(4ull, corners.size()); } PERF_TEST_P_(Perf_Barcode_single, detect_decode) @@ -100,6 +104,8 @@ PERF_TEST_P_(Perf_Barcode_single, detect_decode) } SANITY_CHECK_NOTHING(); ASSERT_TRUE(res); + ASSERT_EQ(4ull, corners.size()); + ASSERT_EQ(1ull, decoded_info.size()); } INSTANTIATE_TEST_CASE_P(/*nothing*/, Perf_Barcode_multi, diff --git a/modules/objdetect/src/barcode.cpp b/modules/objdetect/src/barcode.cpp index e0c7d9cb57..172fb5bd77 100644 --- a/modules/objdetect/src/barcode.cpp +++ b/modules/objdetect/src/barcode.cpp @@ -302,13 +302,13 @@ string BarcodeImpl::detectAndDecode(InputArray img, OutputArray points, OutputAr CV_UNUSED(straight_code); vector decoded_info; vector decoded_type; - vector points_; + vector points_; if (!detectAndDecodeWithType(img, decoded_info, decoded_type, points_)) return string(); if (points_.size() < 4 || decoded_info.size() < 1) return string(); points_.resize(4); - points.setTo(points_); + updatePointsResult(points, points_); return decoded_info[0]; } diff --git a/modules/objdetect/test/test_barcode.cpp b/modules/objdetect/test/test_barcode.cpp index d8e2002f23..7e295fafa3 100644 --- a/modules/objdetect/test/test_barcode.cpp +++ b/modules/objdetect/test/test_barcode.cpp @@ -95,6 +95,13 @@ TEST_P(BarcodeDetector_main, interface) EXPECT_EQ(1u, expected_lines.count(res)); } + { + string res = det.detectAndDecode(img, points); + ASSERT_FALSE(res.empty()); + EXPECT_EQ(1u, expected_lines.count(res)); + EXPECT_EQ(4u, points.size()); + } + // common interface (multi) { bool res = det.detectMulti(img, points); From bd73b7bcf51319e552a28c2b4345c0043970106d Mon Sep 17 00:00:00 2001 From: Alexander Smorkalov <2536374+asmorkalov@users.noreply.github.com> Date: Fri, 16 Feb 2024 17:54:40 +0300 Subject: [PATCH 18/19] Merge pull request #25028 from asmorkalov:as/fisheye_solvepnp solvePnP implementation for Fisheye camera model #25028 Credits to Linfei Pan Extracted from https://github.com/opencv/opencv/pull/24052 **Warning:** The patch changes Obj-C generator behaviour and adds "fisheye_" prefix for all ObjC functions from namespace. ### 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 - [x] The PR is proposed to the proper branch - [x] 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 Co-authored-by: lpanaf Co-authored-by: Vadim Levin --- modules/calib3d/include/opencv2/calib3d.hpp | 39 +++++++++++++++++++++ modules/calib3d/misc/objc/gen_dict.json | 3 ++ modules/calib3d/src/fisheye.cpp | 14 ++++++++ modules/calib3d/test/test_fisheye.cpp | 22 ++++++++++++ 4 files changed, 78 insertions(+) diff --git a/modules/calib3d/include/opencv2/calib3d.hpp b/modules/calib3d/include/opencv2/calib3d.hpp index 7b155636fe..65beca3283 100644 --- a/modules/calib3d/include/opencv2/calib3d.hpp +++ b/modules/calib3d/include/opencv2/calib3d.hpp @@ -4055,6 +4055,45 @@ optimization. It is the \f$max(width,height)/\pi\f$ or the provided \f$f_x\f$, \ OutputArray R, OutputArray T, int flags = fisheye::CALIB_FIX_INTRINSIC, TermCriteria criteria = TermCriteria(TermCriteria::COUNT + TermCriteria::EPS, 100, DBL_EPSILON)); + /** + @brief Finds an object pose from 3D-2D point correspondences for fisheye camera moodel. + + @param objectPoints Array of object points in the object coordinate space, Nx3 1-channel or + 1xN/Nx1 3-channel, where N is the number of points. vector\ can be also passed here. + @param imagePoints Array of corresponding image points, Nx2 1-channel or 1xN/Nx1 2-channel, + where N is the number of points. vector\ can be also passed here. + @param cameraMatrix Input camera intrinsic matrix \f$\cameramatrix{A}\f$ . + @param distCoeffs Input vector of distortion coefficients (4x1/1x4). + @param rvec Output rotation vector (see @ref Rodrigues ) that, together with tvec, brings points from + the model coordinate system to the camera coordinate system. + @param tvec Output translation vector. + @param useExtrinsicGuess Parameter used for #SOLVEPNP_ITERATIVE. If true (1), the function uses + the provided rvec and tvec values as initial approximations of the rotation and translation + vectors, respectively, and further optimizes them. + @param flags Method for solving a PnP problem: see @ref calib3d_solvePnP_flags + This function returns the rotation and the translation vectors that transform a 3D point expressed in the object + coordinate frame to the camera coordinate frame, using different methods: + - P3P methods (@ref SOLVEPNP_P3P, @ref SOLVEPNP_AP3P): need 4 input points to return a unique solution. + - @ref SOLVEPNP_IPPE Input points must be >= 4 and object points must be coplanar. + - @ref SOLVEPNP_IPPE_SQUARE Special case suitable for marker pose estimation. + Number of input points must be 4. Object points must be defined in the following order: + - point 0: [-squareLength / 2, squareLength / 2, 0] + - point 1: [ squareLength / 2, squareLength / 2, 0] + - point 2: [ squareLength / 2, -squareLength / 2, 0] + - point 3: [-squareLength / 2, -squareLength / 2, 0] + - for all the other flags, number of input points must be >= 4 and object points can be in any configuration. + @param criteria Termination criteria for internal undistortPoints call. + The function interally undistorts points with @ref undistortPoints and call @ref cv::solvePnP, + thus the input are very similar. Check there and Perspective-n-Points is described in @ref calib3d_solvePnP + for more information. + */ + CV_EXPORTS_W bool solvePnP( InputArray objectPoints, InputArray imagePoints, + InputArray cameraMatrix, InputArray distCoeffs, + OutputArray rvec, OutputArray tvec, + bool useExtrinsicGuess = false, int flags = SOLVEPNP_ITERATIVE, + TermCriteria criteria = TermCriteria(TermCriteria::MAX_ITER + TermCriteria::EPS, 10, 1e-8) + ); + //! @} calib3d_fisheye } // end namespace fisheye diff --git a/modules/calib3d/misc/objc/gen_dict.json b/modules/calib3d/misc/objc/gen_dict.json index bace946846..655ca2426d 100644 --- a/modules/calib3d/misc/objc/gen_dict.json +++ b/modules/calib3d/misc/objc/gen_dict.json @@ -1,4 +1,7 @@ { + "namespaces_dict": { + "cv.fisheye": "fisheye" + }, "func_arg_fix" : { "Calib3d" : { "findCirclesGrid" : { "blobDetector" : {"defval" : "cv::SimpleBlobDetector::create()"} } diff --git a/modules/calib3d/src/fisheye.cpp b/modules/calib3d/src/fisheye.cpp index 911e16da9e..751a1aa6da 100644 --- a/modules/calib3d/src/fisheye.cpp +++ b/modules/calib3d/src/fisheye.cpp @@ -1148,6 +1148,20 @@ double cv::fisheye::stereoCalibrate(InputArrayOfArrays objectPoints, InputArrayO return rms; } +////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/// cv::fisheye::solvePnP + +bool cv::fisheye::solvePnP( InputArray opoints, InputArray ipoints, + InputArray cameraMatrix, InputArray distCoeffs, + OutputArray rvec, OutputArray tvec, bool useExtrinsicGuess, + int flags, TermCriteria criteria) +{ + + Mat imagePointsNormalized; + cv::fisheye::undistortPoints(ipoints, imagePointsNormalized, cameraMatrix, distCoeffs, noArray(), cameraMatrix, criteria); + return cv::solvePnP(opoints, imagePointsNormalized, cameraMatrix, noArray(), rvec, tvec, useExtrinsicGuess, flags); +} + namespace cv{ namespace { void subMatrix(const Mat& src, Mat& dst, const std::vector& cols, const std::vector& rows) { diff --git a/modules/calib3d/test/test_fisheye.cpp b/modules/calib3d/test/test_fisheye.cpp index f48635e664..2479dac8a8 100644 --- a/modules/calib3d/test/test_fisheye.cpp +++ b/modules/calib3d/test/test_fisheye.cpp @@ -150,6 +150,28 @@ TEST_F(fisheyeTest, distortUndistortPoints) } } +TEST_F(fisheyeTest, solvePnP) +{ + const int n = 16; + + cv::Mat obj_points(1, n, CV_64FC3); + theRNG().fill(obj_points, cv::RNG::NORMAL, 2, 1); + obj_points = cv::abs(obj_points) * 10; + + cv::Mat rvec; + cv::Rodrigues(this->R, rvec); + cv::Mat img_points; + cv::fisheye::projectPoints(obj_points, img_points, rvec, this->T, this->K, this->D); + + cv::Mat rvec_pred; + cv::Mat tvec_pred; + bool converged = cv::fisheye::solvePnP(obj_points, img_points, this->K, this->D, rvec_pred, tvec_pred); + EXPECT_MAT_NEAR(rvec, rvec_pred, 1e-6); + EXPECT_MAT_NEAR(this->T, tvec_pred, 1e-6); + + ASSERT_TRUE(converged); +} + TEST_F(fisheyeTest, undistortImage) { // we use it to reduce patch size for images in testdata From 12aa0fe89819c02db53677c5749771a1007f623e Mon Sep 17 00:00:00 2001 From: Dhanwanth1803 <147172285+Dhanwanth1803@users.noreply.github.com> Date: Fri, 16 Feb 2024 20:49:29 +0530 Subject: [PATCH 19/19] Merge pull request #24985 from Dhanwanth1803:hardswish Fixes #24974 support HardSwishInt8 #24985 As given very clearly in the issue #24974 I made the required 2 changes to implement HardSwish Layer in INT8. Requesting comments. resolves https://github.com/opencv/opencv/issues/24974 - [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 - [X] The PR is proposed to the proper branch - [X] 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 Co-authored-by: Dhanwanth1803 --- modules/dnn/src/init.cpp | 1 + modules/dnn/src/int8layers/elementwise_layers.cpp | 2 ++ modules/dnn/src/tflite/tflite_importer.cpp | 2 ++ 3 files changed, 5 insertions(+) diff --git a/modules/dnn/src/init.cpp b/modules/dnn/src/init.cpp index 2170aafc4b..e8450c18f9 100644 --- a/modules/dnn/src/init.cpp +++ b/modules/dnn/src/init.cpp @@ -212,6 +212,7 @@ void initializeLayerFactory() CV_DNN_REGISTER_LAYER_CLASS(SigmoidInt8, ActivationLayerInt8); CV_DNN_REGISTER_LAYER_CLASS(TanHInt8, ActivationLayerInt8); CV_DNN_REGISTER_LAYER_CLASS(SwishInt8, ActivationLayerInt8); + CV_DNN_REGISTER_LAYER_CLASS(HardSwishInt8, ActivationLayerInt8); CV_DNN_REGISTER_LAYER_CLASS(MishInt8, ActivationLayerInt8); CV_DNN_REGISTER_LAYER_CLASS(ELUInt8, ActivationLayerInt8); CV_DNN_REGISTER_LAYER_CLASS(BNLLInt8, ActivationLayerInt8); diff --git a/modules/dnn/src/int8layers/elementwise_layers.cpp b/modules/dnn/src/int8layers/elementwise_layers.cpp index 2f40a4039f..5c533840f3 100644 --- a/modules/dnn/src/int8layers/elementwise_layers.cpp +++ b/modules/dnn/src/int8layers/elementwise_layers.cpp @@ -267,6 +267,8 @@ public: res = std::make_shared(input, 1.0f); } else if (type == "MishInt8") { res = std::make_shared(input); + } else if (type == "HardSwishInt8") { + res = std::make_shared(input); } else if (type == "AbsValInt8") { res = std::make_shared(input); } else if (type == "SigmoidInt8") { diff --git a/modules/dnn/src/tflite/tflite_importer.cpp b/modules/dnn/src/tflite/tflite_importer.cpp index ed51b4461a..f0e1546306 100644 --- a/modules/dnn/src/tflite/tflite_importer.cpp +++ b/modules/dnn/src/tflite/tflite_importer.cpp @@ -939,6 +939,8 @@ void TFLiteImporter::parseActivation(const Operator& op, const std::string& opco y = std::min(std::max(x, 0.f), 6.f); else if (opcode == "LOGISTIC") y = 1.0f / (1.0f + std::exp(-x)); + else if (opcode == "HARD_SWISH") + y = x * max(0.f, min(1.f, x / 6.f + 0.5f)); else CV_Error(Error::StsNotImplemented, "Lookup table for " + opcode);