|
|
|
@ -404,6 +404,63 @@ void pyPopulateArgumentConversionErrors() |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
struct SafeSeqItem |
|
|
|
|
{ |
|
|
|
|
PyObject * item; |
|
|
|
|
SafeSeqItem(PyObject *obj, size_t idx) { item = PySequence_GetItem(obj, idx); } |
|
|
|
|
~SafeSeqItem() { Py_XDECREF(item); } |
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
SafeSeqItem(const SafeSeqItem&); // = delete
|
|
|
|
|
SafeSeqItem& operator=(const SafeSeqItem&); // = delete
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
template <class T> |
|
|
|
|
class RefWrapper |
|
|
|
|
{ |
|
|
|
|
public: |
|
|
|
|
RefWrapper(T& item) : item_(item) {} |
|
|
|
|
|
|
|
|
|
T& get() CV_NOEXCEPT { return item_; } |
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
T& item_; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// In order to support this conversion on 3.x branch - use custom reference_wrapper
|
|
|
|
|
// and C-style array instead of std::array<T, N>
|
|
|
|
|
template <class T, std::size_t N> |
|
|
|
|
bool parseSequence(PyObject* obj, RefWrapper<T> (&value)[N], const ArgInfo& info) |
|
|
|
|
{ |
|
|
|
|
if (!obj || obj == Py_None) |
|
|
|
|
{ |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
if (!PySequence_Check(obj)) |
|
|
|
|
{ |
|
|
|
|
failmsg("Can't parse '%s'. Input argument doesn't provide sequence " |
|
|
|
|
"protocol", info.name); |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
const std::size_t sequenceSize = PySequence_Size(obj); |
|
|
|
|
if (sequenceSize != N) |
|
|
|
|
{ |
|
|
|
|
failmsg("Can't parse '%s'. Expected sequence length %lu, got %lu", |
|
|
|
|
info.name, N, sequenceSize); |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
for (std::size_t i = 0; i < N; ++i) |
|
|
|
|
{ |
|
|
|
|
SafeSeqItem seqItem(obj, i); |
|
|
|
|
if (!pyopencv_to(seqItem.item, value[i].get(), info)) |
|
|
|
|
{ |
|
|
|
|
failmsg("Can't parse '%s'. Sequence item with index %lu has a " |
|
|
|
|
"wrong type", info.name, i); |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
} // namespace
|
|
|
|
|
|
|
|
|
|
typedef std::vector<uchar> vector_uchar; |
|
|
|
@ -777,13 +834,6 @@ static PyObject* pyopencv_from(void*& ptr) |
|
|
|
|
return PyLong_FromVoidPtr(ptr); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
struct SafeSeqItem |
|
|
|
|
{ |
|
|
|
|
PyObject * item; |
|
|
|
|
SafeSeqItem(PyObject *obj, size_t idx) { item = PySequence_GetItem(obj, idx); } |
|
|
|
|
~SafeSeqItem() { Py_XDECREF(item); } |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
static bool pyopencv_to(PyObject *o, Scalar& s, const ArgInfo& info) |
|
|
|
|
{ |
|
|
|
|
if(!o || o == Py_None) |
|
|
|
@ -1108,10 +1158,9 @@ bool pyopencv_to(PyObject* obj, String &value, const ArgInfo& info) |
|
|
|
|
template<> |
|
|
|
|
bool pyopencv_to(PyObject* obj, Size& sz, const ArgInfo& info) |
|
|
|
|
{ |
|
|
|
|
CV_UNUSED(info); |
|
|
|
|
if(!obj || obj == Py_None) |
|
|
|
|
return true; |
|
|
|
|
return PyArg_ParseTuple(obj, "ii", &sz.width, &sz.height) > 0; |
|
|
|
|
RefWrapper<int> values[] = {RefWrapper<int>(sz.width), |
|
|
|
|
RefWrapper<int>(sz.height)}; |
|
|
|
|
return parseSequence(obj, values, info); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
template<> |
|
|
|
@ -1123,10 +1172,9 @@ PyObject* pyopencv_from(const Size& sz) |
|
|
|
|
template<> |
|
|
|
|
bool pyopencv_to(PyObject* obj, Size_<float>& sz, const ArgInfo& info) |
|
|
|
|
{ |
|
|
|
|
CV_UNUSED(info); |
|
|
|
|
if(!obj || obj == Py_None) |
|
|
|
|
return true; |
|
|
|
|
return PyArg_ParseTuple(obj, "ff", &sz.width, &sz.height) > 0; |
|
|
|
|
RefWrapper<float> values[] = {RefWrapper<float>(sz.width), |
|
|
|
|
RefWrapper<float>(sz.height)}; |
|
|
|
|
return parseSequence(obj, values, info); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
template<> |
|
|
|
@ -1138,10 +1186,10 @@ PyObject* pyopencv_from(const Size_<float>& sz) |
|
|
|
|
template<> |
|
|
|
|
bool pyopencv_to(PyObject* obj, Rect& r, const ArgInfo& info) |
|
|
|
|
{ |
|
|
|
|
CV_UNUSED(info); |
|
|
|
|
if(!obj || obj == Py_None) |
|
|
|
|
return true; |
|
|
|
|
return PyArg_ParseTuple(obj, "iiii", &r.x, &r.y, &r.width, &r.height) > 0; |
|
|
|
|
RefWrapper<int> values[] = {RefWrapper<int>(r.x), RefWrapper<int>(r.y), |
|
|
|
|
RefWrapper<int>(r.width), |
|
|
|
|
RefWrapper<int>(r.height)}; |
|
|
|
|
return parseSequence(obj, values, info); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
template<> |
|
|
|
@ -1153,10 +1201,10 @@ PyObject* pyopencv_from(const Rect& r) |
|
|
|
|
template<> |
|
|
|
|
bool pyopencv_to(PyObject* obj, Rect2d& r, const ArgInfo& info) |
|
|
|
|
{ |
|
|
|
|
CV_UNUSED(info); |
|
|
|
|
if(!obj || obj == Py_None) |
|
|
|
|
return true; |
|
|
|
|
return PyArg_ParseTuple(obj, "dddd", &r.x, &r.y, &r.width, &r.height) > 0; |
|
|
|
|
RefWrapper<double> values[] = { |
|
|
|
|
RefWrapper<double>(r.x), RefWrapper<double>(r.y), |
|
|
|
|
RefWrapper<double>(r.width), RefWrapper<double>(r.height)}; |
|
|
|
|
return parseSequence(obj, values, info); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
template<> |
|
|
|
@ -1168,44 +1216,17 @@ PyObject* pyopencv_from(const Rect2d& r) |
|
|
|
|
template<> |
|
|
|
|
bool pyopencv_to(PyObject* obj, Range& r, const ArgInfo& info) |
|
|
|
|
{ |
|
|
|
|
CV_UNUSED(info); |
|
|
|
|
if(!obj || obj == Py_None) |
|
|
|
|
return true; |
|
|
|
|
while (PySequence_Check(obj)) |
|
|
|
|
if (!obj || obj == Py_None) |
|
|
|
|
{ |
|
|
|
|
if (2 != PySequence_Size(obj)) |
|
|
|
|
{ |
|
|
|
|
failmsg("Range value for argument '%s' is longer than 2", info.name); |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
{ |
|
|
|
|
SafeSeqItem item_wrap(obj, 0); |
|
|
|
|
PyObject *item = item_wrap.item; |
|
|
|
|
if (PyInt_Check(item)) { |
|
|
|
|
r.start = (int)PyInt_AsLong(item); |
|
|
|
|
} else { |
|
|
|
|
failmsg("Range.start value for argument '%s' is not integer", info.name); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
{ |
|
|
|
|
SafeSeqItem item_wrap(obj, 1); |
|
|
|
|
PyObject *item = item_wrap.item; |
|
|
|
|
if (PyInt_Check(item)) { |
|
|
|
|
r.end = (int)PyInt_AsLong(item); |
|
|
|
|
} else { |
|
|
|
|
failmsg("Range.end value for argument '%s' is not integer", info.name); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
if(PyObject_Size(obj) == 0) |
|
|
|
|
if (PyObject_Size(obj) == 0) |
|
|
|
|
{ |
|
|
|
|
r = Range::all(); |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
return PyArg_ParseTuple(obj, "ii", &r.start, &r.end) > 0; |
|
|
|
|
RefWrapper<int> values[] = {RefWrapper<int>(r.start), RefWrapper<int>(r.end)}; |
|
|
|
|
return parseSequence(obj, values, info); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
template<> |
|
|
|
@ -1217,64 +1238,42 @@ PyObject* pyopencv_from(const Range& r) |
|
|
|
|
template<> |
|
|
|
|
bool pyopencv_to(PyObject* obj, Point& p, const ArgInfo& info) |
|
|
|
|
{ |
|
|
|
|
CV_UNUSED(info); |
|
|
|
|
if(!obj || obj == Py_None) |
|
|
|
|
return true; |
|
|
|
|
if(PyComplex_Check(obj)) |
|
|
|
|
{ |
|
|
|
|
p.x = saturate_cast<int>(PyComplex_RealAsDouble(obj)); |
|
|
|
|
p.y = saturate_cast<int>(PyComplex_ImagAsDouble(obj)); |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
return PyArg_ParseTuple(obj, "ii", &p.x, &p.y) > 0; |
|
|
|
|
RefWrapper<int> values[] = {RefWrapper<int>(p.x), RefWrapper<int>(p.y)}; |
|
|
|
|
return parseSequence(obj, values, info); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
template<> |
|
|
|
|
template <> |
|
|
|
|
bool pyopencv_to(PyObject* obj, Point2f& p, const ArgInfo& info) |
|
|
|
|
{ |
|
|
|
|
CV_UNUSED(info); |
|
|
|
|
if(!obj || obj == Py_None) |
|
|
|
|
return true; |
|
|
|
|
if (PyComplex_Check(obj)) |
|
|
|
|
{ |
|
|
|
|
p.x = saturate_cast<float>(PyComplex_RealAsDouble(obj)); |
|
|
|
|
p.y = saturate_cast<float>(PyComplex_ImagAsDouble(obj)); |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
return PyArg_ParseTuple(obj, "ff", &p.x, &p.y) > 0; |
|
|
|
|
RefWrapper<float> values[] = {RefWrapper<float>(p.x), |
|
|
|
|
RefWrapper<float>(p.y)}; |
|
|
|
|
return parseSequence(obj, values, info); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
template<> |
|
|
|
|
bool pyopencv_to(PyObject* obj, Point2d& p, const ArgInfo& info) |
|
|
|
|
{ |
|
|
|
|
CV_UNUSED(info); |
|
|
|
|
if(!obj || obj == Py_None) |
|
|
|
|
return true; |
|
|
|
|
if(PyComplex_Check(obj)) |
|
|
|
|
{ |
|
|
|
|
p.x = PyComplex_RealAsDouble(obj); |
|
|
|
|
p.y = PyComplex_ImagAsDouble(obj); |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
return PyArg_ParseTuple(obj, "dd", &p.x, &p.y) > 0; |
|
|
|
|
RefWrapper<double> values[] = {RefWrapper<double>(p.x), |
|
|
|
|
RefWrapper<double>(p.y)}; |
|
|
|
|
return parseSequence(obj, values, info); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
template<> |
|
|
|
|
bool pyopencv_to(PyObject* obj, Point3f& p, const ArgInfo& info) |
|
|
|
|
{ |
|
|
|
|
CV_UNUSED(info); |
|
|
|
|
if(!obj || obj == Py_None) |
|
|
|
|
return true; |
|
|
|
|
return PyArg_ParseTuple(obj, "fff", &p.x, &p.y, &p.z) > 0; |
|
|
|
|
RefWrapper<float> values[] = {RefWrapper<float>(p.x), |
|
|
|
|
RefWrapper<float>(p.y), |
|
|
|
|
RefWrapper<float>(p.z)}; |
|
|
|
|
return parseSequence(obj, values, info); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
template<> |
|
|
|
|
bool pyopencv_to(PyObject* obj, Point3d& p, const ArgInfo& info) |
|
|
|
|
{ |
|
|
|
|
CV_UNUSED(info); |
|
|
|
|
if(!obj || obj == Py_None) |
|
|
|
|
return true; |
|
|
|
|
return PyArg_ParseTuple(obj, "ddd", &p.x, &p.y, &p.z) > 0; |
|
|
|
|
RefWrapper<double> values[] = {RefWrapper<double>(p.x), |
|
|
|
|
RefWrapper<double>(p.y), |
|
|
|
|
RefWrapper<double>(p.z)}; |
|
|
|
|
return parseSequence(obj, values, info); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
template<> |
|
|
|
@ -1297,74 +1296,66 @@ PyObject* pyopencv_from(const Point3f& p) |
|
|
|
|
|
|
|
|
|
static bool pyopencv_to(PyObject* obj, Vec4d& v, ArgInfo& info) |
|
|
|
|
{ |
|
|
|
|
CV_UNUSED(info); |
|
|
|
|
if (!obj) |
|
|
|
|
return true; |
|
|
|
|
return PyArg_ParseTuple(obj, "dddd", &v[0], &v[1], &v[2], &v[3]) > 0; |
|
|
|
|
RefWrapper<double> values[] = {RefWrapper<double>(v[0]), RefWrapper<double>(v[1]), |
|
|
|
|
RefWrapper<double>(v[2]), RefWrapper<double>(v[3])}; |
|
|
|
|
return parseSequence(obj, values, info); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static bool pyopencv_to(PyObject* obj, Vec4f& v, ArgInfo& info) |
|
|
|
|
{ |
|
|
|
|
CV_UNUSED(info); |
|
|
|
|
if (!obj) |
|
|
|
|
return true; |
|
|
|
|
return PyArg_ParseTuple(obj, "ffff", &v[0], &v[1], &v[2], &v[3]) > 0; |
|
|
|
|
RefWrapper<float> values[] = {RefWrapper<float>(v[0]), RefWrapper<float>(v[1]), |
|
|
|
|
RefWrapper<float>(v[2]), RefWrapper<float>(v[3])}; |
|
|
|
|
return parseSequence(obj, values, info); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static bool pyopencv_to(PyObject* obj, Vec4i& v, ArgInfo& info) |
|
|
|
|
{ |
|
|
|
|
CV_UNUSED(info); |
|
|
|
|
if (!obj) |
|
|
|
|
return true; |
|
|
|
|
return PyArg_ParseTuple(obj, "iiii", &v[0], &v[1], &v[2], &v[3]) > 0; |
|
|
|
|
RefWrapper<int> values[] = {RefWrapper<int>(v[0]), RefWrapper<int>(v[1]), |
|
|
|
|
RefWrapper<int>(v[2]), RefWrapper<int>(v[3])}; |
|
|
|
|
return parseSequence(obj, values, info); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static bool pyopencv_to(PyObject* obj, Vec3d& v, ArgInfo& info) |
|
|
|
|
{ |
|
|
|
|
CV_UNUSED(info); |
|
|
|
|
if (!obj) |
|
|
|
|
return true; |
|
|
|
|
return PyArg_ParseTuple(obj, "ddd", &v[0], &v[1], &v[2]) > 0; |
|
|
|
|
RefWrapper<double> values[] = {RefWrapper<double>(v[0]), |
|
|
|
|
RefWrapper<double>(v[1]), |
|
|
|
|
RefWrapper<double>(v[2])}; |
|
|
|
|
return parseSequence(obj, values, info); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static bool pyopencv_to(PyObject* obj, Vec3f& v, ArgInfo& info) |
|
|
|
|
{ |
|
|
|
|
CV_UNUSED(info); |
|
|
|
|
if (!obj) |
|
|
|
|
return true; |
|
|
|
|
return PyArg_ParseTuple(obj, "fff", &v[0], &v[1], &v[2]) > 0; |
|
|
|
|
RefWrapper<float> values[] = {RefWrapper<float>(v[0]), |
|
|
|
|
RefWrapper<float>(v[1]), |
|
|
|
|
RefWrapper<float>(v[2])}; |
|
|
|
|
return parseSequence(obj, values, info); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static bool pyopencv_to(PyObject* obj, Vec3i& v, ArgInfo& info) |
|
|
|
|
{ |
|
|
|
|
CV_UNUSED(info); |
|
|
|
|
if (!obj) |
|
|
|
|
return true; |
|
|
|
|
return PyArg_ParseTuple(obj, "iii", &v[0], &v[1], &v[2]) > 0; |
|
|
|
|
RefWrapper<int> values[] = {RefWrapper<int>(v[0]), RefWrapper<int>(v[1]), |
|
|
|
|
RefWrapper<int>(v[2])}; |
|
|
|
|
return parseSequence(obj, values, info); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static bool pyopencv_to(PyObject* obj, Vec2d& v, ArgInfo& info) |
|
|
|
|
{ |
|
|
|
|
CV_UNUSED(info); |
|
|
|
|
if (!obj) |
|
|
|
|
return true; |
|
|
|
|
return PyArg_ParseTuple(obj, "dd", &v[0], &v[1]) > 0; |
|
|
|
|
RefWrapper<double> values[] = {RefWrapper<double>(v[0]), |
|
|
|
|
RefWrapper<double>(v[1])}; |
|
|
|
|
return parseSequence(obj, values, info); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static bool pyopencv_to(PyObject* obj, Vec2f& v, ArgInfo& info) |
|
|
|
|
{ |
|
|
|
|
CV_UNUSED(info); |
|
|
|
|
if (!obj) |
|
|
|
|
return true; |
|
|
|
|
return PyArg_ParseTuple(obj, "ff", &v[0], &v[1]) > 0; |
|
|
|
|
RefWrapper<float> values[] = {RefWrapper<float>(v[0]), |
|
|
|
|
RefWrapper<float>(v[1])}; |
|
|
|
|
return parseSequence(obj, values, info); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static bool pyopencv_to(PyObject* obj, Vec2i& v, ArgInfo& info) |
|
|
|
|
{ |
|
|
|
|
CV_UNUSED(info); |
|
|
|
|
if (!obj) |
|
|
|
|
return true; |
|
|
|
|
return PyArg_ParseTuple(obj, "ii", &v[0], &v[1]) > 0; |
|
|
|
|
RefWrapper<int> values[] = {RefWrapper<int>(v[0]), RefWrapper<int>(v[1])}; |
|
|
|
|
return parseSequence(obj, values, info); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
template<> |
|
|
|
@ -1705,12 +1696,54 @@ template<> struct pyopencvVecConverter<RotatedRect> |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
template<> |
|
|
|
|
bool pyopencv_to(PyObject *obj, TermCriteria& dst, const ArgInfo& info) |
|
|
|
|
bool pyopencv_to(PyObject* obj, TermCriteria& dst, const ArgInfo& info) |
|
|
|
|
{ |
|
|
|
|
CV_UNUSED(info); |
|
|
|
|
if(!obj) |
|
|
|
|
if (!obj || obj == Py_None) |
|
|
|
|
{ |
|
|
|
|
return true; |
|
|
|
|
return PyArg_ParseTuple(obj, "iid", &dst.type, &dst.maxCount, &dst.epsilon) > 0; |
|
|
|
|
} |
|
|
|
|
if (!PySequence_Check(obj)) |
|
|
|
|
{ |
|
|
|
|
failmsg("Can't parse '%s' as TermCriteria." |
|
|
|
|
"Input argument doesn't provide sequence protocol", |
|
|
|
|
info.name); |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
const std::size_t sequenceSize = PySequence_Size(obj); |
|
|
|
|
if (sequenceSize != 3) { |
|
|
|
|
failmsg("Can't parse '%s' as TermCriteria. Expected sequence length 3, " |
|
|
|
|
"got %lu", |
|
|
|
|
info.name, sequenceSize); |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
{ |
|
|
|
|
const String typeItemName = format("'%s' criteria type", info.name); |
|
|
|
|
const ArgInfo typeItemInfo(typeItemName.c_str(), false); |
|
|
|
|
SafeSeqItem typeItem(obj, 0); |
|
|
|
|
if (!pyopencv_to(typeItem.item, dst.type, typeItemInfo)) |
|
|
|
|
{ |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
{ |
|
|
|
|
const String maxCountItemName = format("'%s' max count", info.name); |
|
|
|
|
const ArgInfo maxCountItemInfo(maxCountItemName.c_str(), false); |
|
|
|
|
SafeSeqItem maxCountItem(obj, 1); |
|
|
|
|
if (!pyopencv_to(maxCountItem.item, dst.maxCount, maxCountItemInfo)) |
|
|
|
|
{ |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
{ |
|
|
|
|
const String epsilonItemName = format("'%s' epsilon", info.name); |
|
|
|
|
const ArgInfo epsilonItemInfo(epsilonItemName.c_str(), false); |
|
|
|
|
SafeSeqItem epsilonItem(obj, 2); |
|
|
|
|
if (!pyopencv_to(epsilonItem.item, dst.epsilon, epsilonItemInfo)) |
|
|
|
|
{ |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
template<> |
|
|
|
@ -1720,12 +1753,54 @@ PyObject* pyopencv_from(const TermCriteria& src) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
template<> |
|
|
|
|
bool pyopencv_to(PyObject *obj, RotatedRect& dst, const ArgInfo& info) |
|
|
|
|
bool pyopencv_to(PyObject* obj, RotatedRect& dst, const ArgInfo& info) |
|
|
|
|
{ |
|
|
|
|
CV_UNUSED(info); |
|
|
|
|
if(!obj) |
|
|
|
|
if (!obj || obj == Py_None) |
|
|
|
|
{ |
|
|
|
|
return true; |
|
|
|
|
return PyArg_ParseTuple(obj, "(ff)(ff)f", &dst.center.x, &dst.center.y, &dst.size.width, &dst.size.height, &dst.angle) > 0; |
|
|
|
|
} |
|
|
|
|
if (!PySequence_Check(obj)) |
|
|
|
|
{ |
|
|
|
|
failmsg("Can't parse '%s' as RotatedRect." |
|
|
|
|
"Input argument doesn't provide sequence protocol", |
|
|
|
|
info.name); |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
const std::size_t sequenceSize = PySequence_Size(obj); |
|
|
|
|
if (sequenceSize != 3) |
|
|
|
|
{ |
|
|
|
|
failmsg("Can't parse '%s' as RotatedRect. Expected sequence length 3, got %lu", |
|
|
|
|
info.name, sequenceSize); |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
{ |
|
|
|
|
const String centerItemName = format("'%s' center point", info.name); |
|
|
|
|
const ArgInfo centerItemInfo(centerItemName.c_str(), false); |
|
|
|
|
SafeSeqItem centerItem(obj, 0); |
|
|
|
|
if (!pyopencv_to(centerItem.item, dst.center, centerItemInfo)) |
|
|
|
|
{ |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
{ |
|
|
|
|
const String sizeItemName = format("'%s' size", info.name); |
|
|
|
|
const ArgInfo sizeItemInfo(sizeItemName.c_str(), false); |
|
|
|
|
SafeSeqItem sizeItem(obj, 1); |
|
|
|
|
if (!pyopencv_to(sizeItem.item, dst.size, sizeItemInfo)) |
|
|
|
|
{ |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
{ |
|
|
|
|
const String angleItemName = format("'%s' angle", info.name); |
|
|
|
|
const ArgInfo angleItemInfo(angleItemName.c_str(), false); |
|
|
|
|
SafeSeqItem angleItem(obj, 2); |
|
|
|
|
if (!pyopencv_to(angleItem.item, dst.angle, angleItemInfo)) |
|
|
|
|
{ |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
template<> |
|
|
|
|