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:
@@ -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;
|
||||
|
||||
@@ -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))
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user