Merge remote-tracking branch 'upstream/3.4' into merge-3.4

This commit is contained in:
Alexander Alekhin 2022-12-18 02:16:17 +00:00
commit 420db56ffd
11 changed files with 124 additions and 38 deletions

View File

@ -1296,13 +1296,13 @@ struct MorphCtx
CAROTENE_NS::BORDER_MODE border; CAROTENE_NS::BORDER_MODE border;
uchar borderValues[4]; uchar borderValues[4];
}; };
inline int TEGRA_MORPHINIT(cvhalFilter2D **context, int operation, int src_type, int dst_type, int, int, inline int TEGRA_MORPHINIT(cvhalFilter2D **context, int operation, int src_type, int dst_type, int width, int height,
int kernel_type, uchar *kernel_data, size_t kernel_step, int kernel_width, int kernel_height, int anchor_x, int anchor_y, int kernel_type, uchar *kernel_data, size_t kernel_step, int kernel_width, int kernel_height, int anchor_x, int anchor_y,
int borderType, const double borderValue[4], int iterations, bool allowSubmatrix, bool allowInplace) int borderType, const double borderValue[4], int iterations, bool allowSubmatrix, bool allowInplace)
{ {
if(!context || !kernel_data || src_type != dst_type || if(!context || !kernel_data || src_type != dst_type ||
CV_MAT_DEPTH(src_type) != CV_8U || src_type < 0 || (src_type >> CV_CN_SHIFT) > 3 || CV_MAT_DEPTH(src_type) != CV_8U || src_type < 0 || (src_type >> CV_CN_SHIFT) > 3 ||
width < kernel_width || height < kernel_height ||
allowSubmatrix || allowInplace || iterations != 1 || allowSubmatrix || allowInplace || iterations != 1 ||
!CAROTENE_NS::isSupportedConfiguration()) !CAROTENE_NS::isSupportedConfiguration())
return CV_HAL_ERROR_NOT_IMPLEMENTED; return CV_HAL_ERROR_NOT_IMPLEMENTED;

View File

@ -3142,12 +3142,16 @@ public:
/** @brief Stores algorithm parameters in a file storage /** @brief Stores algorithm parameters in a file storage
*/ */
virtual void write(FileStorage& fs) const { CV_UNUSED(fs); } CV_WRAP virtual void write(FileStorage& fs) const { CV_UNUSED(fs); }
/** @brief simplified API for language bindings /**
* @overload * @overload
*/ */
CV_WRAP void write(const Ptr<FileStorage>& fs, const String& name = String()) const; CV_WRAP void write(FileStorage& fs, const String& name) const;
#if CV_VERSION_MAJOR < 5
/** @deprecated */
void write(const Ptr<FileStorage>& fs, const String& name = String()) const;
#endif
/** @brief Reads algorithm parameters from a file storage /** @brief Reads algorithm parameters from a file storage
*/ */

View File

@ -232,6 +232,17 @@ String dumpVec2i(const cv::Vec2i value = cv::Vec2i(42, 24)) {
return format("Vec2i(%d, %d)", value[0], value[1]); return format("Vec2i(%d, %d)", value[0], value[1]);
} }
struct CV_EXPORTS_W_SIMPLE ClassWithKeywordProperties {
CV_PROP_RW int lambda;
CV_PROP int except;
CV_WRAP explicit ClassWithKeywordProperties(int lambda_arg = 24, int except_arg = 42)
{
lambda = lambda_arg;
except = except_arg;
}
};
namespace nested { namespace nested {
CV_WRAP static inline bool testEchoBooleanFunction(bool flag) { CV_WRAP static inline bool testEchoBooleanFunction(bool flag) {
return flag; return flag;

View File

@ -55,19 +55,27 @@ Algorithm::~Algorithm()
CV_TRACE_FUNCTION(); CV_TRACE_FUNCTION();
} }
void Algorithm::write(const Ptr<FileStorage>& fs, const String& name) const void Algorithm::write(FileStorage& fs, const String& name) const
{ {
CV_TRACE_FUNCTION(); CV_TRACE_FUNCTION();
if(name.empty()) if(name.empty())
{ {
write(*fs); write(fs);
return; return;
} }
*fs << name << "{"; fs << name << "{";
write(*fs); write(fs);
*fs << "}"; fs << "}";
} }
#if CV_VERSION_MAJOR < 5
void Algorithm::write(const Ptr<FileStorage>& fs, const String& name) const
{
CV_Assert(fs);
write(*fs, name);
}
#endif
void Algorithm::save(const String& filename) const void Algorithm::save(const String& filename) const
{ {
CV_TRACE_FUNCTION(); CV_TRACE_FUNCTION();

View File

@ -40,11 +40,14 @@ DECLARE_CV_PAUSE
#endif #endif
#ifndef CV_PAUSE #ifndef CV_PAUSE
# if defined __GNUC__ && (defined __i386__ || defined __x86_64__) # if defined __GNUC__ && (defined __i386__ || defined __x86_64__)
# include <x86intrin.h> /* for __rdtsc */
# if !defined(__SSE2__) # if !defined(__SSE2__)
static inline void cv_non_sse_mm_pause() { __asm__ __volatile__ ("rep; nop"); } static inline void cv_non_sse_mm_pause() { __asm__ __volatile__ ("rep; nop"); }
# define _mm_pause cv_non_sse_mm_pause # define _mm_pause cv_non_sse_mm_pause
# endif # endif
# define CV_PAUSE(v) do { for (int __delay = (v); __delay > 0; --__delay) { _mm_pause(); } } while (0) // 5 * v is meants for backward compatibility: with pre-Skylake CPUs, _mm_pause took 4 or 5 cycles.
// With post-Skylake CPUs, _mm_pause takes 140 cycles.
# define CV_PAUSE(v) do { const uint64_t __delay = 5 * v; uint64_t __init = __rdtsc(); do { _mm_pause(); } while ((__rdtsc() - __init) < __delay); } while (0)
# elif defined __GNUC__ && defined __aarch64__ # elif defined __GNUC__ && defined __aarch64__
# define CV_PAUSE(v) do { for (int __delay = (v); __delay > 0; --__delay) { asm volatile("yield" ::: "memory"); } } while (0) # define CV_PAUSE(v) do { for (int __delay = (v); __delay > 0; --__delay) { asm volatile("yield" ::: "memory"); } } while (0)
# elif defined __GNUC__ && defined __arm__ # elif defined __GNUC__ && defined __arm__

View File

@ -216,7 +216,10 @@ public:
CV_WRAP virtual String getDefaultName() const CV_OVERRIDE; CV_WRAP virtual String getDefaultName() const CV_OVERRIDE;
// see corresponding cv::Algorithm method // see corresponding cv::Algorithm method
CV_WRAP inline void write(const Ptr<FileStorage>& fs, const String& name = String()) const { Algorithm::write(fs, name); } CV_WRAP inline void write(FileStorage& fs, const String& name) const { Algorithm::write(fs, name); }
#if CV_VERSION_MAJOR < 5
inline void write(const Ptr<FileStorage>& fs, const String& name) const { CV_Assert(fs); Algorithm::write(*fs, name); }
#endif
}; };
/** Feature detectors in OpenCV have wrappers with a common interface that enables you to easily switch /** Feature detectors in OpenCV have wrappers with a common interface that enables you to easily switch
@ -1131,7 +1134,10 @@ public:
// see corresponding cv::Algorithm method // see corresponding cv::Algorithm method
CV_WRAP inline void write(const Ptr<FileStorage>& fs, const String& name = String()) const { Algorithm::write(fs, name); } CV_WRAP inline void write(FileStorage& fs, const String& name) const { Algorithm::write(fs, name); }
#if CV_VERSION_MAJOR < 5
inline void write(const Ptr<FileStorage>& fs, const String& name) const { CV_Assert(fs); Algorithm::write(*fs, name); }
#endif
protected: protected:
/** /**

View File

@ -2366,5 +2366,18 @@ TEST(Imgproc_GaussianBlur, regression_11303)
EXPECT_LE(cv::norm(src, dst, NORM_L2), 1e-3); EXPECT_LE(cv::norm(src, dst, NORM_L2), 1e-3);
} }
TEST(Imgproc, morphologyEx_small_input_22893)
{
char input_data[] = {1, 2, 3, 4};
char gold_data[] = {2, 3, 4, 4};
cv::Mat img(1, 4, CV_8UC1, input_data);
cv::Mat gold(1, 4, CV_8UC1, gold_data);
cv::Mat kernel = getStructuringElement(cv::MORPH_RECT, cv::Size(4,4));
cv::Mat result;
morphologyEx(img, result, cv::MORPH_DILATE, kernel);
ASSERT_EQ(0, cvtest::norm(result, gold, NORM_INF));
}
}} // namespace }} // namespace

View File

@ -169,10 +169,10 @@ static int pyopencv_${name}_set_${member}(pyopencv_${name}_t* p, PyObject *value
gen_template_prop_init = Template(""" gen_template_prop_init = Template("""
{(char*)"${member}", (getter)pyopencv_${name}_get_${member}, NULL, (char*)"${member}", NULL},""") {(char*)"${export_member_name}", (getter)pyopencv_${name}_get_${member}, NULL, (char*)"${export_member_name}", NULL},""")
gen_template_rw_prop_init = Template(""" gen_template_rw_prop_init = Template("""
{(char*)"${member}", (getter)pyopencv_${name}_get_${member}, (setter)pyopencv_${name}_set_${member}, (char*)"${member}", NULL},""") {(char*)"${export_member_name}", (getter)pyopencv_${name}_get_${member}, (setter)pyopencv_${name}_set_${member}, (char*)"${export_member_name}", NULL},""")
gen_template_overloaded_function_call = Template(""" gen_template_overloaded_function_call = Template("""
{ {
@ -212,6 +212,7 @@ simple_argtype_mapping = {
"c_string": ArgTypeInfo("char*", FormatStrings.string, '(char*)""'), "c_string": ArgTypeInfo("char*", FormatStrings.string, '(char*)""'),
"string": ArgTypeInfo("std::string", FormatStrings.object, None, True), "string": ArgTypeInfo("std::string", FormatStrings.object, None, True),
"Stream": ArgTypeInfo("Stream", FormatStrings.object, 'Stream::Null()', True), "Stream": ArgTypeInfo("Stream", FormatStrings.object, 'Stream::Null()', True),
"UMat": ArgTypeInfo("UMat", FormatStrings.object, 'UMat()', True), # FIXIT: switch to CV_EXPORTS_W_SIMPLE as UMat is already a some kind of smart pointer
} }
# Set of reserved keywords for Python. Can be acquired via the following call # Set of reserved keywords for Python. Can be acquired via the following call
@ -244,6 +245,13 @@ class ClassProp(object):
if "/RW" in decl[3]: if "/RW" in decl[3]:
self.readonly = False self.readonly = False
@property
def export_name(self):
if self.name in python_reserved_keywords:
return self.name + "_"
return self.name
class ClassInfo(object): class ClassInfo(object):
def __init__(self, name, decl=None, codegen=None): def __init__(self, name, decl=None, codegen=None):
# Scope name can be a module or other class e.g. cv::SimpleBlobDetector::Params # Scope name can be a module or other class e.g. cv::SimpleBlobDetector::Params
@ -355,13 +363,13 @@ class ClassInfo(object):
else: else:
getset_code.write(gen_template_get_prop.substitute(name=self.name, member=pname, membertype=p.tp, access=access_op)) getset_code.write(gen_template_get_prop.substitute(name=self.name, member=pname, membertype=p.tp, access=access_op))
if p.readonly: if p.readonly:
getset_inits.write(gen_template_prop_init.substitute(name=self.name, member=pname)) getset_inits.write(gen_template_prop_init.substitute(name=self.name, member=pname, export_member_name=p.export_name))
else: else:
if self.isalgorithm: if self.isalgorithm:
getset_code.write(gen_template_set_prop_algo.substitute(name=self.name, cname=self.cname, member=pname, membertype=p.tp, access=access_op)) getset_code.write(gen_template_set_prop_algo.substitute(name=self.name, cname=self.cname, member=pname, membertype=p.tp, access=access_op))
else: else:
getset_code.write(gen_template_set_prop.substitute(name=self.name, member=pname, membertype=p.tp, access=access_op)) getset_code.write(gen_template_set_prop.substitute(name=self.name, member=pname, membertype=p.tp, access=access_op))
getset_inits.write(gen_template_rw_prop_init.substitute(name=self.name, member=pname)) getset_inits.write(gen_template_rw_prop_init.substitute(name=self.name, member=pname, export_member_name=p.export_name))
methods_code = StringIO() methods_code = StringIO()
methods_inits = StringIO() methods_inits = StringIO()
@ -420,6 +428,7 @@ class ArgInfo(object):
self.name += "_" self.name += "_"
self.defval = arg_tuple[2] self.defval = arg_tuple[2]
self.isarray = False self.isarray = False
self.is_smart_ptr = self.tp.startswith('Ptr<') # FIXIT: handle through modifiers - need to modify parser
self.arraylen = 0 self.arraylen = 0
self.arraycvt = None self.arraycvt = None
self.inputarg = True self.inputarg = True
@ -713,7 +722,21 @@ class FuncInfo(object):
if any(tp in codegen.enums.keys() for tp in tp_candidates): if any(tp in codegen.enums.keys() for tp in tp_candidates):
defval0 = "static_cast<%s>(%d)" % (a.tp, 0) defval0 = "static_cast<%s>(%d)" % (a.tp, 0)
arg_type_info = simple_argtype_mapping.get(tp, ArgTypeInfo(tp, FormatStrings.object, defval0, True)) if tp in simple_argtype_mapping:
arg_type_info = simple_argtype_mapping[tp]
else:
if tp in all_classes:
tp_classinfo = all_classes[tp]
cname_of_value = tp_classinfo.cname if tp_classinfo.issimple else "Ptr<{}>".format(tp_classinfo.cname)
arg_type_info = ArgTypeInfo(cname_of_value, FormatStrings.object, defval0, True)
assert not (a.is_smart_ptr and tp_classinfo.issimple), "Can't pass 'simple' type as Ptr<>"
if not a.is_smart_ptr and not tp_classinfo.issimple:
assert amp == ''
amp = '*'
else:
# FIXIT: Ptr_ / vector_ / enums / nested types
arg_type_info = ArgTypeInfo(tp, FormatStrings.object, defval0, True)
parse_name = a.name parse_name = a.name
if a.py_inputarg: if a.py_inputarg:
if arg_type_info.strict_conversion: if arg_type_info.strict_conversion:

View File

@ -126,6 +126,23 @@ class Bindings(NewOpenCVTests):
test_overload_resolution('rect with float coordinates', (4.5, 4, 2, 1)) test_overload_resolution('rect with float coordinates', (4.5, 4, 2, 1))
test_overload_resolution('rect with wrong number of coordinates', (4, 4, 1)) test_overload_resolution('rect with wrong number of coordinates', (4, 4, 1))
def test_properties_with_reserved_keywords_names_are_transformed(self):
obj = cv.utils.ClassWithKeywordProperties(except_arg=23)
self.assertTrue(hasattr(obj, "lambda_"),
msg="Class doesn't have RW property with converted name")
try:
obj.lambda_ = 32
except Exception as e:
self.fail("Failed to set value to RW property. Error: {}".format(e))
self.assertTrue(hasattr(obj, "except_"),
msg="Class doesn't have readonly property with converted name")
self.assertEqual(obj.except_, 23,
msg="Can't access readonly property value")
with self.assertRaises(AttributeError):
obj.except_ = 32
class Arguments(NewOpenCVTests): class Arguments(NewOpenCVTests):
@ -665,26 +682,14 @@ class Arguments(NewOpenCVTests):
msg="Classes from submodules and global module don't refer " msg="Classes from submodules and global module don't refer "
"to the same type") "to the same type")
def test_class_from_submodule_has_global_alias(self):
self.assertTrue(hasattr(cv.ml, "Boost"),
msg="Class is not registered in the submodule")
self.assertTrue(hasattr(cv, "ml_Boost"),
msg="Class from submodule doesn't have alias in the "
"global module")
self.assertEqual(cv.ml.Boost, cv.ml_Boost,
msg="Classes from submodules and global module don't refer "
"to the same type")
def test_inner_class_has_global_alias(self): def test_inner_class_has_global_alias(self):
self.assertTrue(hasattr(cv.SimpleBlobDetector, "Params"), self.assertTrue(hasattr(cv.SimpleBlobDetector, "Params"),
msg="Class is not registered as inner class") msg="Class is not registered as inner class")
self.assertTrue(hasattr(cv, "SimpleBlobDetector_Params"), self.assertTrue(hasattr(cv, "SimpleBlobDetector_Params"),
msg="Inner class doesn't have alias in the global module") msg="Inner class doesn't have alias in the global module")
self.assertEqual(cv.SimpleBlobDetector.Params, cv.SimpleBlobDetector_Params, self.assertEqual(cv.SimpleBlobDetector.Params, cv.SimpleBlobDetector_Params,
msg="Inner class and class in global module don't refer " msg="Inner class and class in global module don't refer "
"to the same type") "to the same type")
self.assertTrue(hasattr(cv, "SimpleBlobDetector_Params"),
msg="Inner class doesn't have alias in the global module")
def test_export_class_with_different_name(self): def test_export_class_with_different_name(self):
self.assertTrue(hasattr(cv.utils.nested, "ExportClassName"), self.assertTrue(hasattr(cv.utils.nested, "ExportClassName"),
@ -705,7 +710,8 @@ class Arguments(NewOpenCVTests):
def test_export_inner_class_of_class_exported_with_different_name(self): def test_export_inner_class_of_class_exported_with_different_name(self):
if not hasattr(cv.utils.nested, "ExportClassName"): if not hasattr(cv.utils.nested, "ExportClassName"):
raise unittest.SkipTest("Outer class with export alias is not registered in the submodule") raise unittest.SkipTest(
"Outer class with export alias is not registered in the submodule")
self.assertTrue(hasattr(cv.utils.nested.ExportClassName, "Params"), self.assertTrue(hasattr(cv.utils.nested.ExportClassName, "Params"),
msg="Inner class with export alias is not registered in " msg="Inner class with export alias is not registered in "
@ -723,14 +729,15 @@ class Arguments(NewOpenCVTests):
self.assertEqual( self.assertEqual(
params.int_value, instance.getIntParam(), params.int_value, instance.getIntParam(),
msg="Class initialized with wrong integer parameter. Expected: {}. Actual: {}".format( msg="Class initialized with wrong integer parameter. Expected: {}. Actual: {}".format(
params.int_value, instance.getIntParam() params.int_value, instance.getIntParam()
)) )
)
self.assertEqual( self.assertEqual(
params.float_value, instance.getFloatParam(), params.float_value, instance.getFloatParam(),
msg="Class initialized with wrong integer parameter. Expected: {}. Actual: {}".format( msg="Class initialized with wrong integer parameter. Expected: {}. Actual: {}".format(
params.float_value, instance.getFloatParam() params.float_value, instance.getFloatParam()
)) )
)

View File

@ -389,6 +389,15 @@ int CvCaptureCAM::startCaptureDevice(int cameraNum) {
return 0; return 0;
} }
// Preserve devices ordering on the system
// see AVCaptureDevice::uniqueID property documentation for more info
devices = [devices
sortedArrayUsingComparator:^NSComparisonResult(AVCaptureDevice *d1,
AVCaptureDevice *d2) {
return [d1.uniqueID compare:d2.uniqueID];
}
];
mCaptureDevice = devices[cameraNum]; mCaptureDevice = devices[cameraNum];
if ( ! mCaptureDevice ) { if ( ! mCaptureDevice ) {

View File

@ -23,6 +23,8 @@ IF %ERRORLEVEL% EQU 0 (
GOTO :PYTHON_FOUND GOTO :PYTHON_FOUND
) )
CALL :QUERY_PYTHON 3.11
IF %ERRORLEVEL% EQU 0 GOTO :PYTHON_FOUND
CALL :QUERY_PYTHON 3.10 CALL :QUERY_PYTHON 3.10
IF %ERRORLEVEL% EQU 0 GOTO :PYTHON_FOUND IF %ERRORLEVEL% EQU 0 GOTO :PYTHON_FOUND
CALL :QUERY_PYTHON 3.9 CALL :QUERY_PYTHON 3.9