From e62a7038d533225dd6dd1ec8d36b6fcc6f7ba3fb Mon Sep 17 00:00:00 2001 From: Prasad Ayush Kumar <129419372+Prasadayus@users.noreply.github.com> Date: Tue, 1 Sep 2026 14:02:39 +0530 Subject: [PATCH] Merge pull request #29767 from Prasadayus:fix/int32_output MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit python: fix int32 output arrays on Windows by mapping 32-bit NPY_LONG - #29767 On Windows numpy spells `int32` as C `long`, so such arrays arrive as `NPY_LONG` (typenum 7) instead of `NPY_INT` (5). `numpyTypeToCvDepth()` has no case for it, so `pyopencv_to()` takes the cast-and-copy path — which is rejected for **output** arguments, even though the data is already bit-identical to `CV_32S`: ```python cv.watershed(img, np.int32(markers)) ``` ``` cv2.error: (-5:Bad argument) in function 'watershed' > Overload resolution failed: > - Layout of the output array markers is incompatible with cv::Mat ``` Three tests fail on Windows for this reason, all on an int32 output argument (`markers`, `detectedIds`): - `test_watershed` - `test_aruco_detector_refine` - `test_charuco_refine` ### 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/python/src2/cv2_util.cpp | 2 ++ modules/python/test/test_misc.py | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/modules/python/src2/cv2_util.cpp b/modules/python/src2/cv2_util.cpp index e5751045df..5858c6372b 100644 --- a/modules/python/src2/cv2_util.cpp +++ b/modules/python/src2/cv2_util.cpp @@ -47,6 +47,8 @@ int numpyTypeToCvDepth(int typenum) // 'long' is 64-bit on LP64 but 32-bit on LLP64, so decide by size, not by name. case NPY_LONG: return NPY_SIZEOF_LONG == 8 ? CV_64S : CV_32S; case NPY_ULONG: return NPY_SIZEOF_LONG == 8 ? CV_64U : CV_32U; + // Map the 32-bit case: it is numpy's int32 on LLP64, and output arrays cannot be cast. + case NPY_LONG: return NPY_SIZEOF_LONG == 4 ? CV_32S : -1; case NPY_HALF: return CV_16F; case NPY_FLOAT: return CV_32F; case NPY_DOUBLE: return CV_64F; diff --git a/modules/python/test/test_misc.py b/modules/python/test/test_misc.py index c6469f7226..73cb6039ab 100644 --- a/modules/python/test/test_misc.py +++ b/modules/python/test/test_misc.py @@ -318,6 +318,11 @@ class Arguments(NewOpenCVTests): #res6 = cv.utils.dumpInputArray([a, b]) #self.assertEqual(res6, "InputArrayOfArrays: empty()=false kind=0x00050000 flags=0x01050000 total(-1)=2 dims(-1)=1 size(-1)=2x1 type(0)=CV_32FC1 dims(0)=4 size(0)=[2 3 4 5]") + def test_InputOutputArray(self): + a = np.zeros((2, 3), dtype=np.int32) + res, _ = cv.utils.dumpInputOutputArray(a) + self.assertIn('type(-1)=CV_32SC1', res) + def test_unsupported_numpy_data_types_string_description(self): for dtype in (object, str, np.complex128): test_array = np.zeros((4, 4, 3), dtype=dtype)