1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-27 14:23:04 +04:00

Merge branch 4.x

This commit is contained in:
Alexander Smorkalov
2023-09-28 16:42:08 +03:00
202 changed files with 14784 additions and 7242 deletions
+9 -1
View File
@@ -39,12 +39,20 @@
class ArgInfo
{
private:
static const uint32_t arg_outputarg_flag = 0x1;
static const uint32_t arg_arithm_op_src_flag = 0x2;
public:
const char* name;
bool outputarg;
bool arithm_op_src;
// more fields may be added if necessary
ArgInfo(const char* name_, bool outputarg_) : name(name_), outputarg(outputarg_) {}
ArgInfo(const char* name_, uint32_t arg_) :
name(name_),
outputarg((arg_ & arg_outputarg_flag) != 0),
arithm_op_src((arg_ & arg_arithm_op_src_flag) != 0) {}
private:
ArgInfo(const ArgInfo&) = delete;
+53 -9
View File
@@ -63,20 +63,39 @@ bool pyopencv_to(PyObject* o, Mat& m, const ArgInfo& info)
if( PyInt_Check(o) )
{
double v[] = {static_cast<double>(PyInt_AsLong((PyObject*)o)), 0., 0., 0.};
if ( info.arithm_op_src )
{
// Normally cv.XXX(x) means cv.XXX( (x, 0., 0., 0.) );
// However cv.add(mat,x) means cv::add(mat, (x,x,x,x) ).
v[1] = v[0];
v[2] = v[0];
v[3] = v[0];
}
m = Mat(4, 1, CV_64F, v).clone();
return true;
}
if( PyFloat_Check(o) )
{
double v[] = {PyFloat_AsDouble((PyObject*)o), 0., 0., 0.};
if ( info.arithm_op_src )
{
// Normally cv.XXX(x) means cv.XXX( (x, 0., 0., 0.) );
// However cv.add(mat,x) means cv::add(mat, (x,x,x,x) ).
v[1] = v[0];
v[2] = v[0];
v[3] = v[0];
}
m = Mat(4, 1, CV_64F, v).clone();
return true;
}
if( PyTuple_Check(o) )
{
int i, sz = (int)PyTuple_Size((PyObject*)o);
m = Mat(sz, 1, CV_64F);
for( i = 0; i < sz; i++ )
// see https://github.com/opencv/opencv/issues/24057
const int sz = (int)PyTuple_Size((PyObject*)o);
const int sz2 = info.arithm_op_src ? std::max(4, sz) : sz; // Scalar has 4 elements.
m = Mat::zeros(sz2, 1, CV_64F);
for( int i = 0; i < sz; i++ )
{
PyObject* oi = PyTuple_GetItem(o, i);
if( PyInt_Check(oi) )
@@ -241,6 +260,31 @@ bool pyopencv_to(PyObject* o, Mat& m, const ArgInfo& info)
}
}
// see https://github.com/opencv/opencv/issues/24057
if ( ( info.arithm_op_src ) && ( ndims == 1 ) && ( size[0] <= 4 ) )
{
const int sz = size[0]; // Real Data Length(1, 2, 3 or 4)
const int sz2 = 4; // Scalar has 4 elements.
m = Mat::zeros(sz2, 1, CV_64F);
const char *base_ptr = PyArray_BYTES(oarr);
for(int i = 0; i < sz; i++ )
{
PyObject* oi = PyArray_GETITEM(oarr, base_ptr + step[0] * i);
if( PyInt_Check(oi) )
m.at<double>(i) = (double)PyInt_AsLong(oi);
else if( PyFloat_Check(oi) )
m.at<double>(i) = (double)PyFloat_AsDouble(oi);
else
{
failmsg("%s has some non-numerical elements", info.name);
m.release();
return false;
}
}
return true;
}
// handle degenerate case
// FIXIT: Don't force 1D for Scalars
if( ndims == 0) {
@@ -807,7 +851,7 @@ bool pyopencv_to(PyObject* obj, RotatedRect& dst, const ArgInfo& info)
}
{
const String centerItemName = format("'%s' center point", info.name);
const ArgInfo centerItemInfo(centerItemName.c_str(), false);
const ArgInfo centerItemInfo(centerItemName.c_str(), 0);
SafeSeqItem centerItem(obj, 0);
if (!pyopencv_to(centerItem.item, dst.center, centerItemInfo))
{
@@ -816,7 +860,7 @@ bool pyopencv_to(PyObject* obj, RotatedRect& dst, const ArgInfo& info)
}
{
const String sizeItemName = format("'%s' size", info.name);
const ArgInfo sizeItemInfo(sizeItemName.c_str(), false);
const ArgInfo sizeItemInfo(sizeItemName.c_str(), 0);
SafeSeqItem sizeItem(obj, 1);
if (!pyopencv_to(sizeItem.item, dst.size, sizeItemInfo))
{
@@ -825,7 +869,7 @@ bool pyopencv_to(PyObject* obj, RotatedRect& dst, const ArgInfo& info)
}
{
const String angleItemName = format("'%s' angle", info.name);
const ArgInfo angleItemInfo(angleItemName.c_str(), false);
const ArgInfo angleItemInfo(angleItemName.c_str(), 0);
SafeSeqItem angleItem(obj, 2);
if (!pyopencv_to(angleItem.item, dst.angle, angleItemInfo))
{
@@ -1075,7 +1119,7 @@ bool pyopencv_to(PyObject* obj, TermCriteria& dst, const ArgInfo& info)
}
{
const String typeItemName = format("'%s' criteria type", info.name);
const ArgInfo typeItemInfo(typeItemName.c_str(), false);
const ArgInfo typeItemInfo(typeItemName.c_str(), 0);
SafeSeqItem typeItem(obj, 0);
if (!pyopencv_to(typeItem.item, dst.type, typeItemInfo))
{
@@ -1084,7 +1128,7 @@ bool pyopencv_to(PyObject* obj, TermCriteria& dst, const ArgInfo& info)
}
{
const String maxCountItemName = format("'%s' max count", info.name);
const ArgInfo maxCountItemInfo(maxCountItemName.c_str(), false);
const ArgInfo maxCountItemInfo(maxCountItemName.c_str(), 0);
SafeSeqItem maxCountItem(obj, 1);
if (!pyopencv_to(maxCountItem.item, dst.maxCount, maxCountItemInfo))
{
@@ -1093,7 +1137,7 @@ bool pyopencv_to(PyObject* obj, TermCriteria& dst, const ArgInfo& info)
}
{
const String epsilonItemName = format("'%s' epsilon", info.name);
const ArgInfo epsilonItemInfo(epsilonItemName.c_str(), false);
const ArgInfo epsilonItemInfo(epsilonItemName.c_str(), 0);
SafeSeqItem epsilonItem(obj, 2);
if (!pyopencv_to(epsilonItem.item, dst.epsilon, epsilonItemInfo))
{
+2 -2
View File
@@ -286,13 +286,13 @@ bool pyopencv_to(PyObject *obj, std::map<K,V> &map, const ArgInfo& info)
while(PyDict_Next(obj, &pos, &py_key, &py_value))
{
K cpp_key;
if (!pyopencv_to(py_key, cpp_key, ArgInfo("key", false))) {
if (!pyopencv_to(py_key, cpp_key, ArgInfo("key", 0))) {
failmsg("Can't parse dict key. Key on position %lu has a wrong type", pos);
return false;
}
V cpp_value;
if (!pyopencv_to(py_value, cpp_value, ArgInfo("value", false))) {
if (!pyopencv_to(py_value, cpp_value, ArgInfo("value", 0))) {
failmsg("Can't parse dict value. Value on position %lu has a wrong type", pos);
return false;
}
+10 -4
View File
@@ -109,7 +109,7 @@ gen_template_set_prop_from_map = Template("""
if( PyMapping_HasKeyString(src, (char*)"$propname") )
{
tmp = PyMapping_GetItemString(src, (char*)"$propname");
ok = tmp && pyopencv_to_safe(tmp, dst.$propname, ArgInfo("$propname", false));
ok = tmp && pyopencv_to_safe(tmp, dst.$propname, ArgInfo("$propname", 0));
Py_DECREF(tmp);
if(!ok) return false;
}""")
@@ -163,7 +163,7 @@ static int pyopencv_${name}_set_${member}(pyopencv_${name}_t* p, PyObject *value
PyErr_SetString(PyExc_TypeError, "Cannot delete the ${member} attribute");
return -1;
}
return pyopencv_to_safe(value, p->v${access}${member}, ArgInfo("value", false)) ? 0 : -1;
return pyopencv_to_safe(value, p->v${access}${member}, ArgInfo("value", 0)) ? 0 : -1;
}
""")
@@ -181,7 +181,7 @@ static int pyopencv_${name}_set_${member}(pyopencv_${name}_t* p, PyObject *value
failmsgp("Incorrect type of object (must be '${name}' or its derivative)");
return -1;
}
return pyopencv_to_safe(value, _self_${access}${member}, ArgInfo("value", false)) ? 0 : -1;
return pyopencv_to_safe(value, _self_${access}${member}, ArgInfo("value", 0)) ? 0 : -1;
}
""")
@@ -492,6 +492,10 @@ class ArgInfo(object):
def inputarg(self):
return '/O' not in self._modifiers
@property
def arithm_op_src_arg(self):
return '/AOS' in self._modifiers
@property
def outputarg(self):
return '/O' in self._modifiers or '/IO' in self._modifiers
@@ -517,7 +521,9 @@ class ArgInfo(object):
"UMat", "vector_UMat"] # or self.tp.startswith("vector")
def crepr(self):
return "ArgInfo(\"%s\", %d)" % (self.name, self.outputarg)
arg = 0x01 if self.outputarg else 0x0
arg += 0x02 if self.arithm_op_src_arg else 0x0
return "ArgInfo(\"%s\", %d)" % (self.name, arg)
def find_argument_class_info(argument_type, function_namespace,
+9
View File
@@ -537,6 +537,13 @@ class CppHeaderParser(object):
funcname = self.get_dotted_name(funcname)
# see https://github.com/opencv/opencv/issues/24057
is_arithm_op_func = funcname in {"cv.add",
"cv.subtract",
"cv.absdiff",
"cv.multiply",
"cv.divide"}
if not self.wrap_mode:
decl = self.parse_func_decl_no_wrap(decl_str, static_method, docstring)
decl[0] = funcname
@@ -597,6 +604,8 @@ class CppHeaderParser(object):
if arg_type == "InputArray":
arg_type = mat
if is_arithm_op_func:
modlist.append("/AOS") # Arithm Ope Source
elif arg_type == "InputOutputArray":
arg_type = mat
modlist.append("/IO")