mirror of
https://github.com/opencv/opencv.git
synced 2026-09-25 04:09:57 +03:00
code cleanup
This commit is contained in:
@@ -632,8 +632,6 @@ TOLERANCE_OVERRIDES = {
|
||||
"test_roialign_aligned_true": (3e-05, 0.0001),
|
||||
}
|
||||
|
||||
# Cases the C++ suite passes but that fail only through the Python bindings.
|
||||
# Not a port of the C++ denylist; empty is the expected state.
|
||||
KNOWN_SKIPS = {
|
||||
# "test_name": "reason",
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ from tst_scene_render import TestSceneRender
|
||||
def intersectionRate(s1, s2):
|
||||
|
||||
x1, y1, x2, y2 = s1
|
||||
# dtype is explicit: the geometry functions accept only CV_32S/CV_32F points.
|
||||
# intersectConvexConvex()/contourArea() accept only CV_32S/CV_32F points
|
||||
s1 = np.array([[x1, y1], [x2,y1], [x2, y2], [x1, y2]], dtype=np.int32)
|
||||
s2 = np.array(s2, dtype=np.int32)
|
||||
|
||||
|
||||
@@ -133,10 +133,6 @@ bool pyopencv_to(PyObject* o, Mat& m, const ArgInfo& info)
|
||||
|
||||
if( type < 0 )
|
||||
{
|
||||
// 64-bit integers used to be force-cast to CV_32S here, which silently
|
||||
// truncated any value outside the int32 range. They now map to
|
||||
// CV_64S/CV_64U in numpyTypeToCvDepth(), so reaching this point means
|
||||
// the dtype genuinely has no cv::Mat equivalent.
|
||||
const std::string dtype_name = getArrayTypeName(oarr);
|
||||
failmsg("%s data type = %s is not supported", info.name,
|
||||
dtype_name.c_str());
|
||||
@@ -304,15 +300,12 @@ bool pyopencv_to(PyObject* o, Mat& m, const ArgInfo& info)
|
||||
template<>
|
||||
PyObject* pyopencv_from(const cv::Mat& m)
|
||||
{
|
||||
// NumPy has no bfloat16 dtype, so CV_16BF is widened to float32 (lossless).
|
||||
// The values must actually be converted, not just relabelled: cvDepthToNumpyType()
|
||||
// reports NPY_FLOAT for CV_16BF, and handing a 2-byte-per-element buffer to the
|
||||
// NumPy allocator under a 4-byte dtype would misinterpret the payload.
|
||||
// NumPy has no bfloat16 dtype: widen CV_16BF to float32 (lossless).
|
||||
if( m.depth() == CV_16BF )
|
||||
{
|
||||
cv::Mat m32f;
|
||||
ERRWRAP2(m.convertTo(m32f, CV_32F));
|
||||
return pyopencv_from(m32f); // m32f is CV_32F, so this recurses at most once
|
||||
return pyopencv_from(m32f);
|
||||
}
|
||||
if( m.empty() )
|
||||
{
|
||||
|
||||
@@ -34,10 +34,8 @@ UMatData* NumpyAllocator::allocate(int dims0, const int* sizes, int type, void*
|
||||
|
||||
int depth = CV_MAT_DEPTH(type);
|
||||
int cn = CV_MAT_CN(type);
|
||||
// cvDepthToNumpyType() widens CV_16BF to NPY_FLOAT for export, which is only
|
||||
// valid when the values are converted (see pyopencv_from). Backing a CV_16BF
|
||||
// Mat with a float32 buffer here would instead pair a 2-byte element step with
|
||||
// 4-byte NumPy strides and silently corrupt the data, so refuse it outright.
|
||||
// Backing a CV_16BF Mat with the float32 buffer cvDepthToNumpyType() asks for
|
||||
// would pair a 2-byte element step with 4-byte NumPy strides and corrupt the data.
|
||||
if( depth == CV_16BF )
|
||||
CV_Error(Error::StsNotImplemented,
|
||||
"CV_16BF (bfloat16) arrays cannot be allocated through the NumPy allocator: "
|
||||
|
||||
@@ -21,14 +21,10 @@ int cvDepthToNumpyType(int depth)
|
||||
case CV_32F: return NPY_FLOAT;
|
||||
case CV_64F: return NPY_DOUBLE;
|
||||
case CV_16F: return NPY_HALF;
|
||||
// NumPy has no bfloat16 dtype, so CV_16BF is exported as float32 (a lossless
|
||||
// widening). pyopencv_from() performs the value conversion; without it the
|
||||
// 2-byte payload would be reinterpreted as 4-byte elements.
|
||||
// NumPy has no bfloat16 dtype; pyopencv_from() converts the values to float32.
|
||||
case CV_16BF: return NPY_FLOAT;
|
||||
case CV_Bool: return NPY_BOOL;
|
||||
default:
|
||||
// Deliberately an error rather than a fallback: silently mapping an
|
||||
// unknown depth to some default dtype mislabels the payload.
|
||||
CV_Error(cv::Error::StsNotImplemented,
|
||||
cv::format("Mat depth %d has no corresponding NumPy dtype", depth));
|
||||
}
|
||||
@@ -36,7 +32,7 @@ int cvDepthToNumpyType(int depth)
|
||||
|
||||
int numpyTypeToCvDepth(int typenum)
|
||||
{
|
||||
// Only canonical NPY_* values may appear as case labels: the fixed-width
|
||||
// Only canonical NPY_* values may be used as case labels: the fixed-width
|
||||
// aliases (NPY_INT32, NPY_INT64, ...) expand to these and would collide.
|
||||
switch (typenum)
|
||||
{
|
||||
@@ -48,8 +44,7 @@ int numpyTypeToCvDepth(int typenum)
|
||||
case NPY_INT: return CV_32S;
|
||||
case NPY_ULONGLONG: return CV_64U;
|
||||
case NPY_LONGLONG: return CV_64S;
|
||||
// 'long' is 64-bit on LP64 (Linux/macOS) but 32-bit on LLP64 (Windows),
|
||||
// so this must be decided by size rather than by name.
|
||||
// 'long' is 64-bit on LP64 but 32-bit on LLP64, so decide by size, not by name.
|
||||
case NPY_ULONG: return NPY_SIZEOF_LONG == 8 ? CV_64U : CV_32U;
|
||||
case NPY_LONG: return NPY_SIZEOF_LONG == 8 ? CV_64S : CV_32S;
|
||||
case NPY_HALF: return CV_16F;
|
||||
|
||||
@@ -263,8 +263,7 @@ class Arguments(NewOpenCVTests):
|
||||
self.assertEqual(res2_1, "InputArray: empty()=false kind=0x00010000 flags=0x01010000 total(-1)=2 dims(-1)=2 size(-1)=1x2 type(-1)=CV_64FC1")
|
||||
res2_2 = cv.utils.dumpInputArray(1.5) # Scalar(1.5, 1.5, 1.5, 1.5)
|
||||
self.assertEqual(res2_2, "InputArray: empty()=false kind=0x00010000 flags=0x01010000 total(-1)=4 dims(-1)=2 size(-1)=1x4 type(-1)=CV_64FC1")
|
||||
# dtype is explicit: NumPy's default integer type is platform/version
|
||||
# dependent, and 64-bit integers now map to CV_64S rather than CV_32S.
|
||||
# explicit dtype: NumPy's default integer type is platform dependent
|
||||
a = np.array([[1, 2], [3, 4], [5, 6]], dtype=np.int32)
|
||||
res3 = cv.utils.dumpInputArray(a) # 32SC1
|
||||
self.assertEqual(res3, "InputArray: empty()=false kind=0x00010000 flags=0x01010000 total(-1)=6 dims(-1)=2 size(-1)=2x3 type(-1)=CV_32SC1")
|
||||
@@ -295,7 +294,6 @@ class Arguments(NewOpenCVTests):
|
||||
self.assertEqual(res2_1, "InputArrayOfArrays: empty()=false kind=0x00050000 flags=0x01050000 total(-1)=2 dims(-1)=1 size(-1)=2x1 type(0)=CV_64FC1 dims(0)=2 size(0)=1x4")
|
||||
res2_2 = cv.utils.dumpInputArrayOfArrays([1.5])
|
||||
self.assertEqual(res2_2, "InputArrayOfArrays: empty()=false kind=0x00050000 flags=0x01050000 total(-1)=1 dims(-1)=1 size(-1)=1x1 type(0)=CV_64FC1 dims(0)=2 size(0)=1x4")
|
||||
# see test_InputArray: keep the integer dtype explicit
|
||||
a = np.array([[1, 2], [3, 4], [5, 6]], dtype=np.int32)
|
||||
b = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]], dtype=np.int32)
|
||||
res3 = cv.utils.dumpInputArrayOfArrays([a, b])
|
||||
@@ -331,14 +329,12 @@ class Arguments(NewOpenCVTests):
|
||||
cv.rectangle(array, (0, 0), (5, 5), (255), 2)
|
||||
|
||||
def test_64bit_integers_map_to_64bit_depths(self):
|
||||
# 64-bit integer arrays used to fall through to a CV_32S cast.
|
||||
for dtype, expected in ((np.int64, "CV_64SC1"), (np.uint64, "CV_64UC1")):
|
||||
array = np.zeros((2, 2), dtype=dtype)
|
||||
self.assertIn(expected, cv.utils.dumpInputArray(array))
|
||||
|
||||
def test_64bit_integers_are_not_truncated(self):
|
||||
# Regression: values outside the int32 range were silently truncated
|
||||
# (2**40 came back as 0) because of that cast.
|
||||
# Values outside the int32 range used to be silently truncated.
|
||||
for dtype in (np.int64, np.uint64):
|
||||
for value in (2 ** 40, 2 ** 40 + 12345):
|
||||
array = np.array([[value]], dtype=dtype)
|
||||
@@ -349,9 +345,8 @@ class Arguments(NewOpenCVTests):
|
||||
self.assertEqual(cv.add(signed, np.zeros_like(signed))[0, 0], -2 ** 40)
|
||||
|
||||
def test_64bit_integer_dtype_number_is_preserved(self):
|
||||
# np.dtype('uint64') == np.dtype('ulonglong') compares equal even though
|
||||
# their type numbers differ, so an exported array can look correct while
|
||||
# being unusable as an input. Compare .num explicitly.
|
||||
# np.dtype('uint64') == np.dtype('ulonglong') compares equal despite having
|
||||
# different type numbers, so compare .num explicitly.
|
||||
for dtype in (np.int64, np.uint64):
|
||||
array = np.zeros((2, 2), dtype=dtype)
|
||||
self.assertEqual(cv.add(array, array).dtype.num, np.dtype(dtype).num)
|
||||
|
||||
@@ -44,8 +44,7 @@ def find_squares(img):
|
||||
return squares
|
||||
|
||||
def intersectionRate(s1, s2):
|
||||
# dtype is explicit: these helpers take plain integer lists, and the geometry
|
||||
# functions accept only CV_32S/CV_32F point coordinates.
|
||||
# intersectConvexConvex()/contourArea() accept only CV_32S/CV_32F points
|
||||
s1 = np.array(s1, dtype=np.int32)
|
||||
s2 = np.array(s2, dtype=np.int32)
|
||||
area, _intersection = cv.intersectConvexConvex(s1, s2)
|
||||
|
||||
@@ -102,7 +102,7 @@ class NewOpenCVTests(unittest.TestCase):
|
||||
|
||||
def intersectionRate(s1, s2):
|
||||
|
||||
# dtype is explicit: the geometry functions accept only CV_32S/CV_32F points.
|
||||
# intersectConvexConvex()/contourArea() accept only CV_32S/CV_32F points
|
||||
x1, y1, x2, y2 = s1
|
||||
s1 = np.array([[x1, y1], [x2,y1], [x2, y2], [x1, y2]], dtype=np.int32)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user