From a87b9fb4b66bfda73e8b797c4ad0278ac17066a6 Mon Sep 17 00:00:00 2001 From: Lilit Grigoryan Date: Mon, 13 Feb 2023 20:12:37 +0300 Subject: [PATCH 01/22] Fix focal length estimation from homography matrix --- modules/stitching/src/autocalib.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/modules/stitching/src/autocalib.cpp b/modules/stitching/src/autocalib.cpp index 18b6e048d0..772eb7e7e9 100644 --- a/modules/stitching/src/autocalib.cpp +++ b/modules/stitching/src/autocalib.cpp @@ -74,7 +74,11 @@ void focalsFromHomography(const Mat& H, double &f0, double &f1, bool &f0_ok, boo d2 = (h[7] - h[6]) * (h[7] + h[6]); v1 = -(h[0] * h[1] + h[3] * h[4]) / d1; v2 = (h[0] * h[0] + h[3] * h[3] - h[1] * h[1] - h[4] * h[4]) / d2; - if (v1 < v2) std::swap(v1, v2); + if (v1 < v2) + { + std::swap(v1, v2); + std::swap(d1, d2); + } if (v1 > 0 && v2 > 0) f1 = std::sqrt(std::abs(d1) > std::abs(d2) ? v1 : v2); else if (v1 > 0) f1 = std::sqrt(v1); else f1_ok = false; @@ -84,7 +88,11 @@ void focalsFromHomography(const Mat& H, double &f0, double &f1, bool &f0_ok, boo d2 = h[0] * h[0] + h[1] * h[1] - h[3] * h[3] - h[4] * h[4]; v1 = -h[2] * h[5] / d1; v2 = (h[5] * h[5] - h[2] * h[2]) / d2; - if (v1 < v2) std::swap(v1, v2); + if (v1 < v2) + { + std::swap(v1, v2); + std::swap(d1, d2); + } if (v1 > 0 && v2 > 0) f0 = std::sqrt(std::abs(d1) > std::abs(d2) ? v1 : v2); else if (v1 > 0) f0 = std::sqrt(v1); else f0_ok = false; From 2ab7b7c09eff6cb69fadaf9238869f01f350fc8f Mon Sep 17 00:00:00 2001 From: Vladimir Ponomarev Date: Thu, 16 Feb 2023 15:18:30 +0300 Subject: [PATCH 02/22] Remove separator between trackbars. Remove separator between 2 or more trackbars. This separator has zero thickness and creates bags in toolbar. --- modules/highgui/src/window_w32.cpp | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/modules/highgui/src/window_w32.cpp b/modules/highgui/src/window_w32.cpp index eb17d5fc01..a4eb322faf 100644 --- a/modules/highgui/src/window_w32.cpp +++ b/modules/highgui/src/window_w32.cpp @@ -2205,21 +2205,6 @@ icvCreateTrackbar( const char* trackbar_name, const char* window_name, /* Retrieve current buttons count */ bcount = (int)SendMessage(window->toolbar.toolbar, TB_BUTTONCOUNT, 0, 0); - if (bcount > 0) - { - /* If this is not the first button then we need to - separate it from the previous one */ - tbs.iBitmap = 0; - tbs.idCommand = bcount; // Set button id to it's number - tbs.iString = 0; - tbs.fsStyle = TBSTYLE_SEP; - tbs.fsState = TBSTATE_ENABLED; - SendMessage(window->toolbar.toolbar, TB_ADDBUTTONS, 1, (LPARAM)&tbs); - - // Retrieve current buttons count - bcount = (int)SendMessage(window->toolbar.toolbar, TB_BUTTONCOUNT, 0, 0); - } - /* Add a button which we're going to cover with the slider */ tbs.iBitmap = 0; tbs.idCommand = bcount; // Set button id to it's number From fe59a5695f9afd9cbf02fd20a1551ed0d4dfeac8 Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Mon, 27 Feb 2023 03:17:46 +0000 Subject: [PATCH 03/22] core(simd): 64-bit integer EQ/NE without misused 64F guard --- .../include/opencv2/core/hal/intrin_cpp.hpp | 8 +- .../include/opencv2/core/hal/intrin_neon.hpp | 54 +++++++++---- modules/core/test/test_intrin_utils.hpp | 78 +++++++++++-------- 3 files changed, 86 insertions(+), 54 deletions(-) diff --git a/modules/core/include/opencv2/core/hal/intrin_cpp.hpp b/modules/core/include/opencv2/core/hal/intrin_cpp.hpp index 46222140e6..9a97376898 100644 --- a/modules/core/include/opencv2/core/hal/intrin_cpp.hpp +++ b/modules/core/include/opencv2/core/hal/intrin_cpp.hpp @@ -879,14 +879,10 @@ OPENCV_HAL_IMPL_CMP_OP(<=) For all types except 64-bit integer values. */ OPENCV_HAL_IMPL_CMP_OP(>=) -/** @brief Equal comparison - -For all types except 64-bit integer values. */ +/** @brief Equal comparison */ OPENCV_HAL_IMPL_CMP_OP(==) -/** @brief Not equal comparison - -For all types except 64-bit integer values. */ +/** @brief Not equal comparison */ OPENCV_HAL_IMPL_CMP_OP(!=) template diff --git a/modules/core/include/opencv2/core/hal/intrin_neon.hpp b/modules/core/include/opencv2/core/hal/intrin_neon.hpp index 5792694a40..3897cee12b 100644 --- a/modules/core/include/opencv2/core/hal/intrin_neon.hpp +++ b/modules/core/include/opencv2/core/hal/intrin_neon.hpp @@ -1038,18 +1038,6 @@ OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_float64x2, v_min, vminq_f64) OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_float64x2, v_max, vmaxq_f64) #endif -#if CV_SIMD128_64F -inline int64x2_t vmvnq_s64(int64x2_t a) -{ - int64x2_t vx = vreinterpretq_s64_u32(vdupq_n_u32(0xFFFFFFFF)); - return veorq_s64(a, vx); -} -inline uint64x2_t vmvnq_u64(uint64x2_t a) -{ - uint64x2_t vx = vreinterpretq_u64_u32(vdupq_n_u32(0xFFFFFFFF)); - return veorq_u64(a, vx); -} -#endif #define OPENCV_HAL_IMPL_NEON_INT_CMP_OP(_Tpvec, cast, suffix, not_suffix) \ inline _Tpvec operator == (const _Tpvec& a, const _Tpvec& b) \ { return _Tpvec(cast(vceqq_##suffix(a.val, b.val))); } \ @@ -1071,9 +1059,47 @@ OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_int16x8, vreinterpretq_s16_u16, s16, u16) OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_uint32x4, OPENCV_HAL_NOP, u32, u32) OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_int32x4, vreinterpretq_s32_u32, s32, u32) OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_float32x4, vreinterpretq_f32_u32, f32, u32) +#if defined(__aarch64__) || defined(_M_ARM64) +static inline uint64x2_t vmvnq_u64(uint64x2_t a) +{ + uint64x2_t vx = vreinterpretq_u64_u32(vdupq_n_u32(0xFFFFFFFF)); + return veorq_u64(a, vx); +} +//OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_uint64x2, OPENCV_HAL_NOP, u64, u64) +//OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_int64x2, vreinterpretq_s64_u64, s64, u64) +static inline v_uint64x2 operator == (const v_uint64x2& a, const v_uint64x2& b) +{ return v_uint64x2(vceqq_u64(a.val, b.val)); } +static inline v_uint64x2 operator != (const v_uint64x2& a, const v_uint64x2& b) +{ return v_uint64x2(vmvnq_u64(vceqq_u64(a.val, b.val))); } +static inline v_int64x2 operator == (const v_int64x2& a, const v_int64x2& b) +{ return v_int64x2(vreinterpretq_s64_u64(vceqq_s64(a.val, b.val))); } +static inline v_int64x2 operator != (const v_int64x2& a, const v_int64x2& b) +{ return v_int64x2(vreinterpretq_s64_u64(vmvnq_u64(vceqq_s64(a.val, b.val)))); } +#else +static inline v_uint64x2 operator == (const v_uint64x2& a, const v_uint64x2& b) +{ + uint32x4_t cmp = vceqq_u32(vreinterpretq_u32_u64(a.val), vreinterpretq_u32_u64(b.val)); + uint32x4_t swapped = vrev64q_u32(cmp); + return v_uint64x2(vreinterpretq_u64_u32(vandq_u32(cmp, swapped))); +} +static inline v_uint64x2 operator != (const v_uint64x2& a, const v_uint64x2& b) +{ + uint32x4_t cmp = vceqq_u32(vreinterpretq_u32_u64(a.val), vreinterpretq_u32_u64(b.val)); + uint32x4_t swapped = vrev64q_u32(cmp); + uint64x2_t v_eq = vreinterpretq_u64_u32(vandq_u32(cmp, swapped)); + uint64x2_t vx = vreinterpretq_u64_u32(vdupq_n_u32(0xFFFFFFFF)); + return v_uint64x2(veorq_u64(v_eq, vx)); +} +static inline v_int64x2 operator == (const v_int64x2& a, const v_int64x2& b) +{ + return v_reinterpret_as_s64(v_reinterpret_as_u64(a) == v_reinterpret_as_u64(b)); +} +static inline v_int64x2 operator != (const v_int64x2& a, const v_int64x2& b) +{ + return v_reinterpret_as_s64(v_reinterpret_as_u64(a) != v_reinterpret_as_u64(b)); +} +#endif #if CV_SIMD128_64F -OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_uint64x2, OPENCV_HAL_NOP, u64, u64) -OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_int64x2, vreinterpretq_s64_u64, s64, u64) OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_float64x2, vreinterpretq_f64_u64, f64, u64) #endif diff --git a/modules/core/test/test_intrin_utils.hpp b/modules/core/test/test_intrin_utils.hpp index 3f196f1342..da1f26790c 100644 --- a/modules/core/test/test_intrin_utils.hpp +++ b/modules/core/test/test_intrin_utils.hpp @@ -97,7 +97,7 @@ template struct Data { *this = r; } - operator R () + operator R () const { return initializer().init(*this); } @@ -1559,11 +1559,34 @@ template struct TheTest } #endif -#if CV_SIMD_64F + void do_check_cmp64(const Data& dataA, const Data& dataB) + { + R a = dataA; + R b = dataB; + + Data dataEQ = (a == b); + Data dataNE = (a != b); + + for (int i = 0; i < R::nlanes; ++i) + { + SCOPED_TRACE(cv::format("i=%d", i)); + if (cvtest::debugLevel > 0) cout << "i=" << i << " ( " << dataA[i] << " vs " << dataB[i] << " ): eq=" << dataEQ[i] << " ne=" << dataNE[i] << endl; + EXPECT_NE((LaneType)dataEQ[i], (LaneType)dataNE[i]); + if (dataA[i] == dataB[i]) + EXPECT_EQ((LaneType)-1, (LaneType)dataEQ[i]); + else + EXPECT_EQ((LaneType)0, (LaneType)dataEQ[i]); + if (dataA[i] != dataB[i]) + EXPECT_EQ((LaneType)-1, (LaneType)dataNE[i]); + else + EXPECT_EQ((LaneType)0, (LaneType)dataNE[i]); + } + } + TheTest & test_cmp64() { - Data dataA, dataB; - R a = dataA, b = dataB; + Data dataA; + Data dataB; for (int i = 0; i < R::nlanes; ++i) { @@ -1571,37 +1594,25 @@ template struct TheTest } dataA[0]++; - a = dataA, b = dataB; + do_check_cmp64(dataA, dataB); + do_check_cmp64(dataB, dataA); - Data resC = (a == b); - Data resD = (a != b); + dataA[0] = dataB[0]; + dataA[1] += (((LaneType)1) << 32); + do_check_cmp64(dataA, dataB); + do_check_cmp64(dataB, dataA); - for (int i = 0; i < R::nlanes; ++i) - { - SCOPED_TRACE(cv::format("i=%d", i)); - EXPECT_EQ(dataA[i] == dataB[i], resC[i] != 0); - EXPECT_EQ(dataA[i] != dataB[i], resD[i] != 0); - } + dataA[0] = (LaneType)-1; + dataB[0] = (LaneType)-1; + dataA[1] = (LaneType)-1; + dataB[1] = (LaneType)2; - for (int i = 0; i < R::nlanes; ++i) - { - dataA[i] = dataB[i] = (LaneType)-1; - } + do_check_cmp64(dataA, dataB); + do_check_cmp64(dataB, dataA); - a = dataA, b = dataB; - - resC = (a == b); - resD = (a != b); - - for (int i = 0; i < R::nlanes; ++i) - { - SCOPED_TRACE(cv::format("i=%d", i)); - EXPECT_EQ(dataA[i] == dataB[i], resC[i] != 0); - EXPECT_EQ(dataA[i] != dataB[i], resD[i] != 0); - } return *this; } -#endif + }; @@ -1837,9 +1848,8 @@ void test_hal_intrin_uint64() TheTest() .test_loadstore() .test_addsub() -#if CV_SIMD_64F .test_cmp64() -#endif + //.test_cmp() - not declared as supported .test_shift<1>().test_shift<8>() .test_logic() .test_reverse() @@ -1857,9 +1867,8 @@ void test_hal_intrin_int64() TheTest() .test_loadstore() .test_addsub() -#if CV_SIMD_64F .test_cmp64() -#endif + //.test_cmp() - not declared as supported .test_shift<1>().test_shift<8>() .test_logic() .test_reverse() @@ -1936,7 +1945,8 @@ void test_hal_intrin_float64() .test_rotate<2>().test_rotate<3>() #endif ; - +#else + std::cout << "SKIP: CV_SIMD_64F is not available" << std::endl; #endif } From 8ad8ec679fe8ff970c075fb327d5b97f61a48220 Mon Sep 17 00:00:00 2001 From: Vincent Rabaud Date: Tue, 7 Mar 2023 13:05:38 +0100 Subject: [PATCH 04/22] Merge pull request #22441 from vrabaud:hls_while In case of huge (and probably invalid) input, make sure we do not rely only on the while loops for truncation. ### 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 --- modules/imgproc/src/color_hsv.simd.hpp | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/modules/imgproc/src/color_hsv.simd.hpp b/modules/imgproc/src/color_hsv.simd.hpp index 424a6d1494..0c30564a12 100644 --- a/modules/imgproc/src/color_hsv.simd.hpp +++ b/modules/imgproc/src/color_hsv.simd.hpp @@ -419,6 +419,14 @@ inline void HSV2RGB_simd(const v_float32& h, const v_float32& s, const v_float32 } #endif +// Compute the sector and the new H for HSV and HLS 2 RGB conversions. +inline void ComputeSectorAndClampedH(float& h, int §or) { + sector = cvFloor(h); + h -= sector; + sector %= 6; + sector += sector < 0 ? 6 : 0; +} + inline void HSV2RGB_native(float h, float s, float v, float& b, float& g, float& r, @@ -433,14 +441,7 @@ inline void HSV2RGB_native(float h, float s, float v, float tab[4]; int sector; h *= hscale; - h = fmod(h, 6.f); - sector = cvFloor(h); - h -= sector; - if( (unsigned)sector >= 6u ) - { - sector = 0; - h = 0.f; - } + ComputeSectorAndClampedH(h, sector); tab[0] = v; tab[1] = v*(1.f - s); @@ -987,13 +988,7 @@ struct HLS2RGB_f float p1 = 2*l - p2; h *= hscale; - // We need both loops to clamp (e.g. for h == -1e-40). - while( h < 0 ) h += 6; - while( h >= 6 ) h -= 6; - - CV_DbgAssert( 0 <= h && h < 6 ); - sector = cvFloor(h); - h -= sector; + ComputeSectorAndClampedH(h, sector); tab[0] = p2; tab[1] = p1; From 7ea6b356c782ae8ae76e6bb5c49f6a77ef5bbf7e Mon Sep 17 00:00:00 2001 From: Bhavit Patel Date: Fri, 10 Mar 2023 01:50:36 -0500 Subject: [PATCH 05/22] Merge pull request #23305 from bhavitp:fix/calib3d/undistortion_grid Resolves https://github.com/opencv/opencv/issues/23304 Fixes the incorrect pixel grid Switches type to double to avoid precision loss as all callers use doubles ### 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 --- modules/calib3d/src/calibration.cpp | 32 ++++---- modules/calib3d/test/test_undistort.cpp | 99 +++++++++++++++++++++++++ 2 files changed, 115 insertions(+), 16 deletions(-) diff --git a/modules/calib3d/src/calibration.cpp b/modules/calib3d/src/calibration.cpp index 7081ee8b4d..2cf10afba6 100644 --- a/modules/calib3d/src/calibration.cpp +++ b/modules/calib3d/src/calibration.cpp @@ -2258,28 +2258,28 @@ double cvStereoCalibrate( const CvMat* _objectPoints, const CvMat* _imagePoints1 static void icvGetRectangles( const CvMat* cameraMatrix, const CvMat* distCoeffs, const CvMat* R, const CvMat* newCameraMatrix, CvSize imgSize, - cv::Rect_& inner, cv::Rect_& outer ) + cv::Rect_& inner, cv::Rect_& outer ) { const int N = 9; int x, y, k; - cv::Ptr _pts(cvCreateMat(1, N*N, CV_32FC2)); - CvPoint2D32f* pts = (CvPoint2D32f*)(_pts->data.ptr); + cv::Ptr _pts(cvCreateMat(1, N*N, CV_64FC2)); + CvPoint2D64f* pts = (CvPoint2D64f*)(_pts->data.ptr); for( y = k = 0; y < N; y++ ) for( x = 0; x < N; x++ ) - pts[k++] = cvPoint2D32f((float)x*imgSize.width/(N-1), - (float)y*imgSize.height/(N-1)); + pts[k++] = cvPoint2D64f((double)x*(imgSize.width-1)/(N-1), + (double)y*(imgSize.height-1)/(N-1)); cvUndistortPoints(_pts, _pts, cameraMatrix, distCoeffs, R, newCameraMatrix); - float iX0=-FLT_MAX, iX1=FLT_MAX, iY0=-FLT_MAX, iY1=FLT_MAX; - float oX0=FLT_MAX, oX1=-FLT_MAX, oY0=FLT_MAX, oY1=-FLT_MAX; + double iX0=-FLT_MAX, iX1=FLT_MAX, iY0=-FLT_MAX, iY1=FLT_MAX; + double oX0=FLT_MAX, oX1=-FLT_MAX, oY0=FLT_MAX, oY1=-FLT_MAX; // find the inscribed rectangle. // the code will likely not work with extreme rotation matrices (R) (>45%) for( y = k = 0; y < N; y++ ) for( x = 0; x < N; x++ ) { - CvPoint2D32f p = pts[k++]; + CvPoint2D64f p = pts[k++]; oX0 = MIN(oX0, p.x); oX1 = MAX(oX1, p.x); oY0 = MIN(oY0, p.y); @@ -2294,8 +2294,8 @@ icvGetRectangles( const CvMat* cameraMatrix, const CvMat* distCoeffs, if( y == N-1 ) iY1 = MIN(iY1, p.y); } - inner = cv::Rect_(iX0, iY0, iX1-iX0, iY1-iY0); - outer = cv::Rect_(oX0, oY0, oX1-oX0, oY1-oY0); + inner = cv::Rect_(iX0, iY0, iX1-iX0, iY1-iY0); + outer = cv::Rect_(oX0, oY0, oX1-oX0, oY1-oY0); } @@ -2308,7 +2308,7 @@ void cvStereoRectify( const CvMat* _cameraMatrix1, const CvMat* _cameraMatrix2, { double _om[3], _t[3] = {0}, _uu[3]={0,0,0}, _r_r[3][3], _pp[3][4]; double _ww[3], _wr[3][3], _z[3] = {0,0,0}, _ri[3][3]; - cv::Rect_ inner1, inner2, outer1, outer2; + cv::Rect_ inner1, inner2, outer1, outer2; CvMat om = cvMat(3, 1, CV_64F, _om); CvMat t = cvMat(3, 1, CV_64F, _t); @@ -2515,7 +2515,7 @@ void cvGetOptimalNewCameraMatrix( const CvMat* cameraMatrix, const CvMat* distCo CvMat* newCameraMatrix, CvSize newImgSize, CvRect* validPixROI, int centerPrincipalPoint ) { - cv::Rect_ inner, outer; + cv::Rect_ inner, outer; newImgSize = newImgSize.width*newImgSize.height != 0 ? newImgSize : imgSize; double M[3][3]; @@ -2545,10 +2545,10 @@ void cvGetOptimalNewCameraMatrix( const CvMat* cameraMatrix, const CvMat* distCo if( validPixROI ) { - inner = cv::Rect_((float)((inner.x - cx0)*s + cx), - (float)((inner.y - cy0)*s + cy), - (float)(inner.width*s), - (float)(inner.height*s)); + inner = cv::Rect_((double)((inner.x - cx0)*s + cx), + (double)((inner.y - cy0)*s + cy), + (double)(inner.width*s), + (double)(inner.height*s)); cv::Rect r(cvCeil(inner.x), cvCeil(inner.y), cvFloor(inner.width), cvFloor(inner.height)); r &= cv::Rect(0, 0, newImgSize.width, newImgSize.height); *validPixROI = cvRect(r); diff --git a/modules/calib3d/test/test_undistort.cpp b/modules/calib3d/test/test_undistort.cpp index 4d90ecab4d..db6c2f764e 100644 --- a/modules/calib3d/test/test_undistort.cpp +++ b/modules/calib3d/test/test_undistort.cpp @@ -157,6 +157,104 @@ void CV_DefaultNewCameraMatrixTest::prepare_to_validation( int /*test_case_idx*/ //--------- +class CV_GetOptimalNewCameraMatrixNoDistortionTest : public cvtest::ArrayTest +{ +public: + CV_GetOptimalNewCameraMatrixNoDistortionTest(); +protected: + int prepare_test_case (int test_case_idx); + void prepare_to_validation(int test_case_idx); + void get_test_array_types_and_sizes(int test_case_idx, vector >& sizes, vector >& types); + void run_func(); + +private: + cv::Mat camera_mat; + cv::Mat distortion_coeffs; + cv::Mat new_camera_mat; + + cv::Size img_size; + double alpha; + bool center_principal_point; + + int matrix_type; + + static const int MAX_X = 2048; + static const int MAX_Y = 2048; +}; + +CV_GetOptimalNewCameraMatrixNoDistortionTest::CV_GetOptimalNewCameraMatrixNoDistortionTest() +{ + test_array[INPUT].push_back(NULL); // camera_mat + test_array[INPUT].push_back(NULL); // distortion_coeffs + test_array[OUTPUT].push_back(NULL); // new_camera_mat + test_array[REF_OUTPUT].push_back(NULL); + + alpha = 0.0; + center_principal_point = false; + matrix_type = 0; +} + +void CV_GetOptimalNewCameraMatrixNoDistortionTest::get_test_array_types_and_sizes(int test_case_idx, vector >& sizes, vector >& types) +{ + cvtest::ArrayTest::get_test_array_types_and_sizes(test_case_idx, sizes, types); + RNG& rng = ts->get_rng(); + matrix_type = types[INPUT][0] = types[INPUT][1] = types[OUTPUT][0] = types[REF_OUTPUT][0] = cvtest::randInt(rng)%2 ? CV_64F : CV_32F; + sizes[INPUT][0] = sizes[OUTPUT][0] = sizes[REF_OUTPUT][0] = cvSize(3,3); + sizes[INPUT][1] = cvSize(1,4); +} + +int CV_GetOptimalNewCameraMatrixNoDistortionTest::prepare_test_case(int test_case_idx) +{ + int code = cvtest::ArrayTest::prepare_test_case( test_case_idx ); + + if (code <= 0) + return code; + + RNG& rng = ts->get_rng(); + + alpha = cvtest::randReal(rng); + center_principal_point = ((cvtest::randInt(rng) % 2)!=0); + + // Generate random camera matrix. Use floating point precision for source to avoid precision loss + img_size.width = cvtest::randInt(rng) % MAX_X + 1; + img_size.height = cvtest::randInt(rng) % MAX_Y + 1; + const float aspect_ratio = static_cast(img_size.width) / img_size.height; + float cam_array[9] = {0,0,0,0,0,0,0,0,1}; + cam_array[2] = static_cast((img_size.width - 1)*0.5); // center + cam_array[5] = static_cast((img_size.height - 1)*0.5); // center + cam_array[0] = static_cast(MAX(img_size.width, img_size.height)/(0.9 - cvtest::randReal(rng)*0.6)); + cam_array[4] = aspect_ratio*cam_array[0]; + + Mat& input_camera_mat = test_mat[INPUT][0]; + cvtest::convert(Mat(3, 3, CV_32F, cam_array), input_camera_mat, input_camera_mat.type()); + camera_mat = input_camera_mat; + + // Generate zero distortion matrix + const Mat zero_dist_coeffs = Mat::zeros(1, 4, CV_32F); + Mat& input_dist_coeffs = test_mat[INPUT][1]; + cvtest::convert(zero_dist_coeffs, input_dist_coeffs, input_dist_coeffs.type()); + distortion_coeffs = input_dist_coeffs; + + return code; +} + +void CV_GetOptimalNewCameraMatrixNoDistortionTest::run_func() +{ + new_camera_mat = cv::getOptimalNewCameraMatrix(camera_mat, distortion_coeffs, img_size, alpha, img_size, NULL, center_principal_point); +} + +void CV_GetOptimalNewCameraMatrixNoDistortionTest::prepare_to_validation(int /*test_case_idx*/) +{ + const Mat& src = test_mat[INPUT][0]; + Mat& dst = test_mat[REF_OUTPUT][0]; + cvtest::copy(src, dst); + + Mat& output = test_mat[OUTPUT][0]; + cvtest::convert(new_camera_mat, output, output.type()); +} + +//--------- + class CV_UndistortPointsTest : public cvtest::ArrayTest { public: @@ -935,6 +1033,7 @@ double CV_InitUndistortRectifyMapTest::get_success_error_level( int /*test_case_ ////////////////////////////////////////////////////////////////////////////////////////////////////// TEST(Calib3d_DefaultNewCameraMatrix, accuracy) { CV_DefaultNewCameraMatrixTest test; test.safe_run(); } +TEST(Calib3d_GetOptimalNewCameraMatrixNoDistortion, accuracy) { CV_GetOptimalNewCameraMatrixNoDistortionTest test; test.safe_run(); } TEST(Calib3d_UndistortPoints, accuracy) { CV_UndistortPointsTest test; test.safe_run(); } TEST(Calib3d_InitUndistortRectifyMap, accuracy) { CV_InitUndistortRectifyMapTest test; test.safe_run(); } From b204c3981588351aab39ec30c2e1aabc7b30c733 Mon Sep 17 00:00:00 2001 From: Vladimir Ponomarev Date: Tue, 14 Mar 2023 15:00:44 +0300 Subject: [PATCH 06/22] Merge pull request #23276 from vovka643:flann_corrections Fixed potential memory leak in flann Issue #22426 ### 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 --- .../include/opencv2/flann/flann_base.hpp | 23 +++++++++++++++---- modules/flann/src/miniflann.cpp | 10 ++++---- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/modules/flann/include/opencv2/flann/flann_base.hpp b/modules/flann/include/opencv2/flann/flann_base.hpp index 258ec38d20..af0b380bbf 100644 --- a/modules/flann/include/opencv2/flann/flann_base.hpp +++ b/modules/flann/include/opencv2/flann/flann_base.hpp @@ -45,6 +45,21 @@ namespace cvflann { +class FILEScopeGuard { + +public: + explicit FILEScopeGuard(FILE* file) { + file_ = file; + }; + + ~FILEScopeGuard() { + fclose(file_); + }; + +private: + FILE* file_; +}; + /** * Sets the log level used for all flann functions @@ -69,7 +84,6 @@ struct SavedIndexParams : public IndexParams } }; - template NNIndex* load_saved_index(const Matrix& dataset, const cv::String& filename, Distance distance) { @@ -79,13 +93,13 @@ NNIndex* load_saved_index(const Matrix if (fin == NULL) { return NULL; } + FILEScopeGuard fscgd(fin); + IndexHeader header = load_header(fin); if (header.data_type != Datatype::type()) { - fclose(fin); FLANN_THROW(cv::Error::StsError, "Datatype of saved index is different than of the one to be created."); } if ((size_t(header.rows) != dataset.rows)||(size_t(header.cols) != dataset.cols)) { - fclose(fin); FLANN_THROW(cv::Error::StsError, "The index saved belongs to a different dataset"); } @@ -93,7 +107,6 @@ NNIndex* load_saved_index(const Matrix params["algorithm"] = header.index_type; NNIndex* nnIndex = create_index_by_type(dataset, params, distance); nnIndex->loadIndex(fin); - fclose(fin); return nnIndex; } @@ -107,7 +120,7 @@ public: typedef typename Distance::ResultType DistanceType; Index(const Matrix& features, const IndexParams& params, Distance distance = Distance() ) - : index_params_(params) + :index_params_(params) { flann_algorithm_t index_type = get_param(params,"algorithm"); loaded_ = false; diff --git a/modules/flann/src/miniflann.cpp b/modules/flann/src/miniflann.cpp index a1146ec2e7..ea0494ddec 100644 --- a/modules/flann/src/miniflann.cpp +++ b/modules/flann/src/miniflann.cpp @@ -767,11 +767,15 @@ bool Index::load(InputArray _data, const String& filename) Mat data = _data.getMat(); bool ok = true; release(); + FILE* fin = fopen(filename.c_str(), "rb"); - if (fin == NULL) + if (fin == NULL) { return false; + } + FILEScopeGuard fscgd(fin); ::cvflann::IndexHeader header = ::cvflann::load_header(fin); + algo = header.index_type; featureType = header.data_type == FLANN_UINT8 ? CV_8U : header.data_type == FLANN_INT8 ? CV_8S : @@ -786,7 +790,6 @@ bool Index::load(InputArray _data, const String& filename) { fprintf(stderr, "Reading FLANN index error: the saved data size (%d, %d) or type (%d) is different from the passed one (%d, %d), %d\n", (int)header.rows, (int)header.cols, featureType, data.rows, data.cols, data.type()); - fclose(fin); return false; } @@ -799,7 +802,6 @@ bool Index::load(InputArray _data, const String& filename) (distType != FLANN_DIST_HAMMING && featureType == CV_32F)) ) { fprintf(stderr, "Reading FLANN index error: unsupported feature type %d for the index type %d\n", featureType, algo); - fclose(fin); return false; } @@ -839,8 +841,6 @@ bool Index::load(InputArray _data, const String& filename) ok = false; } - if( fin ) - fclose(fin); return ok; } From 56a4877e3072b0a2b7c981795276af334e327cc2 Mon Sep 17 00:00:00 2001 From: TuNanTang Date: Tue, 14 Mar 2023 21:09:53 +0800 Subject: [PATCH 07/22] Merge pull request #23341 from TuNanTang:3.4 ### 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. - [ ] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [ ] The PR is proposed to the proper branch - [ ] There is a reference to the original bug report and related work - [ ] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [ ] The feature is well documented and sample code can be built with the project CMake --- .../core/mat_mask_operations/mat_mask_operations.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/cpp/tutorial_code/core/mat_mask_operations/mat_mask_operations.cpp b/samples/cpp/tutorial_code/core/mat_mask_operations/mat_mask_operations.cpp index 0fece804b2..c1c67b90ce 100644 --- a/samples/cpp/tutorial_code/core/mat_mask_operations/mat_mask_operations.cpp +++ b/samples/cpp/tutorial_code/core/mat_mask_operations/mat_mask_operations.cpp @@ -92,7 +92,7 @@ void Sharpen(const Mat& myImage,Mat& Result) for(int i= nChannels;i < nChannels*(myImage.cols-1); ++i) { - *output++ = saturate_cast(5*current[i] + output[i] = saturate_cast(5*current[i] -current[i-nChannels] - current[i+nChannels] - previous[i] - next[i]); } } From 68e2df56e7f6487239341867ab95df9d545087ec Mon Sep 17 00:00:00 2001 From: TuNanTang Date: Tue, 14 Mar 2023 21:17:39 +0800 Subject: [PATCH 08/22] Optimize&Fix fitEllipse sample Optimize&Fix fitEllipse sample --- samples/cpp/fitellipse.cpp | 38 +++++++++++++++++--------------------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/samples/cpp/fitellipse.cpp b/samples/cpp/fitellipse.cpp index f136b9c408..7d217014d5 100644 --- a/samples/cpp/fitellipse.cpp +++ b/samples/cpp/fitellipse.cpp @@ -218,6 +218,11 @@ int main( int argc, char** argv ) return 0; } +inline static bool isGoodBox(const RotatedRect& box) { + //size.height >= size.width awalys,only if the pts are on a line or at the same point,size.width=0 + return (box.size.height <= box.size.width * 30) && (box.size.width > 0); +} + // Define trackbar callback function. This function finds contours, // draws them, and approximates by ellipses. void processImage(int /*h*/, void*) @@ -276,39 +281,30 @@ void processImage(int /*h*/, void*) { vector pts = points[i]; - if (pts.size()<=5) { + //At least 5 points can fit an ellipse + if (pts.size()<5) { continue; } if (fitEllipseQ) { box = fitEllipse(pts); - if( MAX(box.size.width, box.size.height) > MIN(box.size.width, box.size.height)*30 || - MAX(box.size.width, box.size.height) <= 0 || - MIN(box.size.width, box.size.height) <= 0){continue;}; + if (isGoodBox(box)) { + paper.drawEllipseWithBox(box, fitEllipseColor, 3); + } } if (fitEllipseAMSQ) { boxAMS = fitEllipseAMS(pts); - if( MAX(boxAMS.size.width, boxAMS.size.height) > MIN(boxAMS.size.width, boxAMS.size.height)*30 || - MAX(box.size.width, box.size.height) <= 0 || - MIN(box.size.width, box.size.height) <= 0){continue;}; + if (isGoodBox(boxAMS)) { + paper.drawEllipseWithBox(boxAMS, fitEllipseAMSColor, 2); + } } if (fitEllipseDirectQ) { boxDirect = fitEllipseDirect(pts); - if( MAX(boxDirect.size.width, boxDirect.size.height) > MIN(boxDirect.size.width, boxDirect.size.height)*30 || - MAX(box.size.width, box.size.height) <= 0 || - MIN(box.size.width, box.size.height) <= 0 ){continue;}; + if (isGoodBox(boxDirect)){ + paper.drawEllipseWithBox(boxDirect, fitEllipseDirectColor, 1); + } } - if (fitEllipseQ) { - paper.drawEllipseWithBox(box, fitEllipseColor, 3); - } - if (fitEllipseAMSQ) { - paper.drawEllipseWithBox(boxAMS, fitEllipseAMSColor, 2); - } - if (fitEllipseDirectQ) { - paper.drawEllipseWithBox(boxDirect, fitEllipseDirectColor, 1); - } - - paper.drawPoints(pts, cv::Scalar(255,255,255)); + paper.drawPoints(pts, fitEllipseTrueColor); } imshow("result", paper.img); From 69fd82fc465c5ce72c2d2b3a1b0bf33f1a87ca75 Mon Sep 17 00:00:00 2001 From: Abduragim Date: Wed, 15 Mar 2023 16:30:00 +0300 Subject: [PATCH 09/22] minor grammatical fixes to dnn_custom_layers.md --- .../dnn_custom_layers/dnn_custom_layers.md | 49 ++++++++++--------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/doc/tutorials/dnn/dnn_custom_layers/dnn_custom_layers.md b/doc/tutorials/dnn/dnn_custom_layers/dnn_custom_layers.md index a3f521d5df..6f4a70f642 100644 --- a/doc/tutorials/dnn/dnn_custom_layers/dnn_custom_layers.md +++ b/doc/tutorials/dnn/dnn_custom_layers/dnn_custom_layers.md @@ -3,29 +3,30 @@ @prev_tutorial{tutorial_dnn_javascript} ## Introduction -Deep learning is a fast growing area. The new approaches to build neural networks -usually introduce new types of layers. They could be modifications of existing -ones or implement outstanding researching ideas. +Deep learning is a fast-growing area. New approaches to building neural networks +usually introduce new types of layers. These could be modifications of existing +ones or implementation of outstanding research ideas. -OpenCV gives an opportunity to import and run networks from different deep learning -frameworks. There are a number of the most popular layers. However you can face -a problem that your network cannot be imported using OpenCV because of unimplemented layers. +OpenCV allows importing and running networks from different deep learning frameworks. +There is a number of the most popular layers. However, you can face a problem that +your network cannot be imported using OpenCV because some layers of your network +can be not implemented in the deep learning engine of OpenCV. The first solution is to create a feature request at https://github.com/opencv/opencv/issues -mentioning details such a source of model and type of new layer. A new layer could -be implemented if OpenCV community shares this need. +mentioning details such as a source of a model and a type of new layer. +The new layer could be implemented if the OpenCV community shares this need. -The second way is to define a **custom layer** so OpenCV's deep learning engine +The second way is to define a **custom layer** so that OpenCV's deep learning engine will know how to use it. This tutorial is dedicated to show you a process of deep -learning models import customization. +learning model's import customization. ## Define a custom layer in C++ Deep learning layer is a building block of network's pipeline. It has connections to **input blobs** and produces results to **output blobs**. There are trained **weights** and **hyper-parameters**. -Layers' names, types, weights and hyper-parameters are stored in files are generated by -native frameworks during training. If OpenCV mets unknown layer type it throws an -exception trying to read a model: +Layers' names, types, weights and hyper-parameters are stored in files are +generated by native frameworks during training. If OpenCV encounters unknown +layer type it throws an exception while trying to read a model: ``` Unspecified error: Can't create layer "layer_name" of type "MyType" in function getLayerInstance @@ -61,7 +62,7 @@ This method should create an instance of you layer and return cv::Ptr with it. @snippet dnn/custom_layers.hpp MyLayer::getMemoryShapes -Returns layer's output shapes depends on input shapes. You may request an extra +Returns layer's output shapes depending on input shapes. You may request an extra memory using `internals`. - Run a layer @@ -71,20 +72,20 @@ memory using `internals`. Implement a layer's logic here. Compute outputs for given inputs. @note OpenCV manages memory allocated for layers. In the most cases the same memory -can be reused between layers. So your `forward` implementation should not rely that -the second invocation of `forward` will has the same data at `outputs` and `internals`. +can be reused between layers. So your `forward` implementation should not rely on that +the second invocation of `forward` will have the same data at `outputs` and `internals`. - Optional `finalize` method @snippet dnn/custom_layers.hpp MyLayer::finalize -The chain of methods are the following: OpenCV deep learning engine calls `create` -method once then it calls `getMemoryShapes` for an every created layer then you -can make some preparations depends on known input dimensions at cv::dnn::Layer::finalize. -After network was initialized only `forward` method is called for an every network's input. +The chain of methods is the following: OpenCV deep learning engine calls `create` +method once, then it calls `getMemoryShapes` for every created layer, then you +can make some preparations depend on known input dimensions at cv::dnn::Layer::finalize. +After network was initialized only `forward` method is called for every network's input. -@note Varying input blobs' sizes such height or width or batch size you make OpenCV -reallocate all the internal memory. That leads efficiency gaps. Try to initialize +@note Varying input blobs' sizes such height, width or batch size make OpenCV +reallocate all the internal memory. That leads to efficiency gaps. Try to initialize and deploy models using a fixed batch size and image's dimensions. ## Example: custom layer from Caffe @@ -201,7 +202,7 @@ deep learning model. That was trained with one and only difference comparing to a current version of [Caffe framework](http://caffe.berkeleyvision.org/). `Crop` layers that receive two input blobs and crop the first one to match spatial dimensions of the second one used to crop from the center. Nowadays Caffe's layer does it -from the top-left corner. So using the latest version of Caffe or OpenCV you'll +from the top-left corner. So using the latest version of Caffe or OpenCV you will get shifted results with filled borders. Next we're going to replace OpenCV's `Crop` layer that makes top-left cropping by @@ -217,7 +218,7 @@ a centric one. @snippet dnn/edge_detection.py Register -That's it! We've replaced an implemented OpenCV's layer to a custom one. +That's it! We have replaced an implemented OpenCV's layer to a custom one. You may find a full script in the [source code](https://github.com/opencv/opencv/tree/3.4/samples/dnn/edge_detection.py). From 8483f2ef2f948d68f18c430816abafab917fc636 Mon Sep 17 00:00:00 2001 From: Zero-nnkn Date: Mon, 20 Mar 2023 23:08:53 +0700 Subject: [PATCH 10/22] Fix error of `POSE_PAIRS` in pose estimation doc --- doc/js_tutorials/js_assets/js_pose_estimation.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/js_tutorials/js_assets/js_pose_estimation.html b/doc/js_tutorials/js_assets/js_pose_estimation.html index 19c64663d1..dbdb26fdbc 100644 --- a/doc/js_tutorials/js_assets/js_pose_estimation.html +++ b/doc/js_tutorials/js_assets/js_pose_estimation.html @@ -147,7 +147,7 @@ if (dataset === 'COCO') { ["Neck", "LShoulder"], ["RShoulder", "RElbow"], ["RElbow", "RWrist"], ["LShoulder", "LElbow"], ["LElbow", "LWrist"], ["Nose", "REye"], - ["REye", "REar"], ["Neck", "LEye"], + ["REye", "REar"], ["Nose", "LEye"], ["LEye", "LEar"], ["Neck", "MidHip"], ["MidHip", "RHip"], ["RHip", "RKnee"], ["RKnee", "RAnkle"], ["RAnkle", "RBigToe"], From 42793e16ddded7315fd00c23b17071361748f963 Mon Sep 17 00:00:00 2001 From: Raj Kachhadiya <110079774+kachhadiyaraj15@users.noreply.github.com> Date: Fri, 20 Jan 2023 18:47:46 +0530 Subject: [PATCH 11/22] Update py_intro.markdown --- doc/py_tutorials/py_setup/py_intro/py_intro.markdown | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/py_tutorials/py_setup/py_intro/py_intro.markdown b/doc/py_tutorials/py_setup/py_intro/py_intro.markdown index b013ef014e..b7a600afc1 100644 --- a/doc/py_tutorials/py_setup/py_intro/py_intro.markdown +++ b/doc/py_tutorials/py_setup/py_intro/py_intro.markdown @@ -79,8 +79,8 @@ Below is the list of contributors who submitted tutorials to OpenCV-Python. Additional Resources -------------------- --# A Quick guide to Python - [A Byte of Python](http://swaroopch.com/notes/python/) -2. [NumPy Quickstart tutorial](https://numpy.org/devdocs/user/quickstart.html) -3. [NumPy Reference](https://numpy.org/devdocs/reference/index.html#reference) -4. [OpenCV Documentation](http://docs.opencv.org/) +1. [A Quick guide to Python](https://www.freecodecamp.org/news/the-python-guide-for-beginners/) +2. [NumPy Quickstart tutorial](https://numpy.org/doc/stable/user/quickstart.html) +3. [NumPy Reference](https://numpy.org/doc/stable/reference/index.html) +4. [OpenCV Documentation](https://docs.opencv.org/4.x/index.html) 5. [OpenCV Forum](https://forum.opencv.org/) From 5c5ef9746c9c9ce3fa3306f1d8d4eb038c2c1130 Mon Sep 17 00:00:00 2001 From: Alexander Smorkalov Date: Tue, 21 Mar 2023 15:32:21 +0300 Subject: [PATCH 12/22] Presume original book, update references. --- doc/py_tutorials/py_setup/py_intro/py_intro.markdown | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/py_tutorials/py_setup/py_intro/py_intro.markdown b/doc/py_tutorials/py_setup/py_intro/py_intro.markdown index b7a600afc1..0108462f95 100644 --- a/doc/py_tutorials/py_setup/py_intro/py_intro.markdown +++ b/doc/py_tutorials/py_setup/py_intro/py_intro.markdown @@ -79,8 +79,9 @@ Below is the list of contributors who submitted tutorials to OpenCV-Python. Additional Resources -------------------- +-# A Quick guide to Python - [A Byte of Python](https://python.swaroopch.com/) 1. [A Quick guide to Python](https://www.freecodecamp.org/news/the-python-guide-for-beginners/) 2. [NumPy Quickstart tutorial](https://numpy.org/doc/stable/user/quickstart.html) 3. [NumPy Reference](https://numpy.org/doc/stable/reference/index.html) -4. [OpenCV Documentation](https://docs.opencv.org/4.x/index.html) +4. [OpenCV Documentation](https://docs.opencv.org/) 5. [OpenCV Forum](https://forum.opencv.org/) From 6033599c88f7e100338002a15a080cd54ab0d92e Mon Sep 17 00:00:00 2001 From: Simon Lynen Date: Wed, 22 Mar 2023 04:12:51 +0100 Subject: [PATCH 13/22] Make LineSegmentDetector deterministic by using stable_sort for ordering keypoints prior to region growing This makes LineSegmentDetector deterministic by using stable_sort for ordering points by norm. Without this change the region growing in LSD is non-determinstic and thus the returned lines are changing between invocations. This is a replacement for https://github.com/opencv/opencv/pull/23370 --- modules/imgproc/src/lsd.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/imgproc/src/lsd.cpp b/modules/imgproc/src/lsd.cpp index 2f13c5a8a0..8d26a016ab 100644 --- a/modules/imgproc/src/lsd.cpp +++ b/modules/imgproc/src/lsd.cpp @@ -592,8 +592,8 @@ void LineSegmentDetectorImpl::ll_angle(const double& threshold, } } - // Sort - std::sort(ordered_points.begin(), ordered_points.end(), compare_norm); + // Use stable sort to ensure deterministic region growing and thus overall LSD result determinism. + std::stable_sort(ordered_points.begin(), ordered_points.end(), compare_norm); } void LineSegmentDetectorImpl::region_grow(const Point2i& s, std::vector& reg, From c9e42c50504bcf11debe132041834f9f449ea5b2 Mon Sep 17 00:00:00 2001 From: Christian Henkel <6976069+ct2034@users.noreply.github.com> Date: Mon, 20 Mar 2023 22:26:05 +0100 Subject: [PATCH 14/22] two typos --- modules/core/src/hal_replacement.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/core/src/hal_replacement.hpp b/modules/core/src/hal_replacement.hpp index 6ed795b5e1..25acff662c 100644 --- a/modules/core/src/hal_replacement.hpp +++ b/modules/core/src/hal_replacement.hpp @@ -531,7 +531,7 @@ inline int hal_ni_dftFree1D(cvhalDFT *context) { return CV_HAL_ERROR_NOT_IMPLEME /** @param context double pointer to context storing all necessary data @param width,height image dimensions -@param depth image type (CV_32F or CV64F) +@param depth image type (CV_32F or CV_64F) @param src_channels number of channels in input image @param dst_channels number of channels in output image @param flags algorithm options (combination of CV_HAL_DFT_INVERSE, ...) @@ -558,7 +558,7 @@ inline int hal_ni_dftFree2D(cvhalDFT *context) { return CV_HAL_ERROR_NOT_IMPLEME /** @param context double pointer to context storing all necessary data @param width,height image dimensions -@param depth image type (CV_32F or CV64F) +@param depth image type (CV_32F or CV_64F) @param flags algorithm options (combination of CV_HAL_DFT_INVERSE, ...) */ inline int hal_ni_dctInit2D(cvhalDFT **context, int width, int height, int depth, int flags) { return CV_HAL_ERROR_NOT_IMPLEMENTED; } From ea7efd57d890f73e00ff2130baf303d81964adb9 Mon Sep 17 00:00:00 2001 From: tkram01 Date: Wed, 22 Mar 2023 09:50:58 +0300 Subject: [PATCH 15/22] Fix for using sampleIdx to limit training data --- modules/ml/src/data.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ml/src/data.cpp b/modules/ml/src/data.cpp index a5dd101f1d..d8b41ed91c 100644 --- a/modules/ml/src/data.cpp +++ b/modules/ml/src/data.cpp @@ -904,7 +904,7 @@ public: if( s ) { j = s[i]; - CV_Assert( 0 <= j && j < nsamples ); + CV_Assert( 0 <= j && j < ((layout == ROW_SAMPLE) ? samples.rows : samples.cols) ); } values[i] = src[j*sstep]; if( values[i] == MISSED_VAL ) From 6ffe686ba884b0ed4e9ed7ef14b0790050c82f82 Mon Sep 17 00:00:00 2001 From: Sergey Petrenko Date: Wed, 22 Mar 2023 10:24:22 +0300 Subject: [PATCH 16/22] check keydown event characters length before returning the pressed character code --- modules/highgui/src/window_cocoa.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/highgui/src/window_cocoa.mm b/modules/highgui/src/window_cocoa.mm index 1cf55f9397..2c05b10be5 100644 --- a/modules/highgui/src/window_cocoa.mm +++ b/modules/highgui/src/window_cocoa.mm @@ -618,7 +618,7 @@ CV_IMPL int cvWaitKey (int maxWait) inMode:NSDefaultRunLoopMode dequeue:YES]; - if([event type] == NSKeyDown) { + if([event type] == NSKeyDown && [[event characters] length]) { returnCode = [[event characters] characterAtIndex:0]; break; } From 83a49b4f6a74276d43d54e8b0d7cb1799a823adf Mon Sep 17 00:00:00 2001 From: Kumataro Date: Sun, 26 Mar 2023 09:03:16 +0900 Subject: [PATCH 17/22] imgcodecs: update documentation for imwrite() to support images formats. --- .../imgcodecs/include/opencv2/imgcodecs.hpp | 25 +++++++++++++------ 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/modules/imgcodecs/include/opencv2/imgcodecs.hpp b/modules/imgcodecs/include/opencv2/imgcodecs.hpp index c4b570e68c..2eb5e596fc 100644 --- a/modules/imgcodecs/include/opencv2/imgcodecs.hpp +++ b/modules/imgcodecs/include/opencv2/imgcodecs.hpp @@ -218,17 +218,26 @@ CV_EXPORTS_W bool imreadmulti(const String& filename, CV_OUT std::vector& m /** @brief Saves an image to a specified file. The function imwrite saves the image to the specified file. The image format is chosen based on the -filename extension (see cv::imread for the list of extensions). In general, only 8-bit +filename extension (see cv::imread for the list of extensions). In general, only 8-bit unsigned (CV_8U) single-channel or 3-channel (with 'BGR' channel order) images can be saved using this function, with these exceptions: -- 16-bit unsigned (CV_16U) images can be saved in the case of PNG, JPEG 2000, and TIFF formats -- 32-bit float (CV_32F) images can be saved in TIFF, OpenEXR, and Radiance HDR formats; 3-channel -(CV_32FC3) TIFF images will be saved using the LogLuv high dynamic range encoding (4 bytes per pixel) -- PNG images with an alpha channel can be saved using this function. To do this, create -8-bit (or 16-bit) 4-channel image BGRA, where the alpha channel goes last. Fully transparent pixels -should have alpha set to 0, fully opaque pixels should have alpha set to 255/65535 (see the code sample below). -- Multiple images (vector of Mat) can be saved in TIFF format (see the code sample below). +- With OpenEXR encoder, only 32-bit float (CV_32F) images can be saved. + - 8-bit unsigned (CV_8U) images are not supported. +- With Radiance HDR encoder, non 64-bit float (CV_64F) images can be saved. + - All images will be converted to 32-bit float (CV_32F). +- With JPEG 2000 encoder, 8-bit unsigned (CV_8U) and 16-bit unsigned (CV_16U) images can be saved. +- With PAM encoder, 8-bit unsigned (CV_8U) and 16-bit unsigned (CV_16U) images can be saved. +- With PNG encoder, 8-bit unsigned (CV_8U) and 16-bit unsigned (CV_16U) images can be saved. + - PNG images with an alpha channel can be saved using this function. To do this, create + 8-bit (or 16-bit) 4-channel image BGRA, where the alpha channel goes last. Fully transparent pixels + should have alpha set to 0, fully opaque pixels should have alpha set to 255/65535 (see the code sample below). +- With PGM/PPM encoder, 8-bit unsigned (CV_8U) and 16-bit unsigned (CV_16U) images can be saved. +- With TIFF encoder, 8-bit unsigned (CV_8U), 16-bit unsigned (CV_16U), + 32-bit float (CV_32F) and 64-bit float (CV_64F) images can be saved. + - Multiple images (vector of Mat) can be saved in TIFF format (see the code sample below). + - 32-bit float 3-channel (CV_32FC3) TIFF images will be saved + using the LogLuv high dynamic range encoding (4 bytes per pixel) If the image format is not supported, the image will be converted to 8-bit unsigned (CV_8U) and saved that way. From 1c6c3dfa8d63bdb4758763cbc2ec91872ddd8612 Mon Sep 17 00:00:00 2001 From: Kumataro Date: Sun, 26 Mar 2023 18:33:54 +0900 Subject: [PATCH 18/22] remove tail whitespace --- modules/imgcodecs/include/opencv2/imgcodecs.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/imgcodecs/include/opencv2/imgcodecs.hpp b/modules/imgcodecs/include/opencv2/imgcodecs.hpp index 2eb5e596fc..9ae0c3a807 100644 --- a/modules/imgcodecs/include/opencv2/imgcodecs.hpp +++ b/modules/imgcodecs/include/opencv2/imgcodecs.hpp @@ -233,7 +233,7 @@ can be saved using this function, with these exceptions: 8-bit (or 16-bit) 4-channel image BGRA, where the alpha channel goes last. Fully transparent pixels should have alpha set to 0, fully opaque pixels should have alpha set to 255/65535 (see the code sample below). - With PGM/PPM encoder, 8-bit unsigned (CV_8U) and 16-bit unsigned (CV_16U) images can be saved. -- With TIFF encoder, 8-bit unsigned (CV_8U), 16-bit unsigned (CV_16U), +- With TIFF encoder, 8-bit unsigned (CV_8U), 16-bit unsigned (CV_16U), 32-bit float (CV_32F) and 64-bit float (CV_64F) images can be saved. - Multiple images (vector of Mat) can be saved in TIFF format (see the code sample below). - 32-bit float 3-channel (CV_32FC3) TIFF images will be saved From 26ca124150b7f87392d380fc9333d409ebab6e38 Mon Sep 17 00:00:00 2001 From: Sajjad Ali Date: Thu, 2 Mar 2023 18:26:08 +0500 Subject: [PATCH 19/22] fix "ImportError: DLL load failed while importing cv2" while installing using pre-built binaries --- .../py_setup/py_setup_in_windows/py_setup_in_windows.markdown | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/py_tutorials/py_setup/py_setup_in_windows/py_setup_in_windows.markdown b/doc/py_tutorials/py_setup/py_setup_in_windows/py_setup_in_windows.markdown index 0ba1643ee1..1cefb01d5c 100644 --- a/doc/py_tutorials/py_setup/py_setup_in_windows/py_setup_in_windows.markdown +++ b/doc/py_tutorials/py_setup/py_setup_in_windows/py_setup_in_windows.markdown @@ -33,6 +33,8 @@ Installing OpenCV from prebuilt binaries -# Copy **cv2.pyd** to **C:/Python27/lib/site-packages**. +-# Copy the **opencv_world.dll** file to **C:/Python27/lib/site-packages** + -# Open Python IDLE and type following codes in Python terminal. @code >>> import cv2 as cv From b34fc422a2f7924b60e77daf224f9bbcfd999ce8 Mon Sep 17 00:00:00 2001 From: Zwyx <29386932+Zwyx@users.noreply.github.com> Date: Sun, 2 Apr 2023 23:00:21 +0800 Subject: [PATCH 20/22] Switch `rows` and `cols` in call to Mat.zeros The correct order is rows then cols: https://docs.opencv.org/4.x/d3/d63/classcv_1_1Mat.html#a56daa006391a670e9cb0cd08e3168c99 --- doc/js_tutorials/js_assets/js_contours_begin_contours.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/js_tutorials/js_assets/js_contours_begin_contours.html b/doc/js_tutorials/js_assets/js_contours_begin_contours.html index 8efd3298a5..09e6ec44e1 100644 --- a/doc/js_tutorials/js_assets/js_contours_begin_contours.html +++ b/doc/js_tutorials/js_assets/js_contours_begin_contours.html @@ -41,7 +41,7 @@