mirror of
https://github.com/opencv/opencv.git
synced 2025-06-07 17:44:04 +08:00
core: wrap custom types via _RawArray (raw() call)
- support passing of `std::vector<KeyPoint>` via InputArray
This commit is contained in:
parent
aa5c45339c
commit
a0f86479e0
@ -148,6 +148,12 @@ synonym is needed to generate Python/Java etc. wrappers properly. At the functio
|
|||||||
level their use is similar, but _InputArray::getMat(idx) should be used to get header for the
|
level their use is similar, but _InputArray::getMat(idx) should be used to get header for the
|
||||||
idx-th component of the outer vector and _InputArray::size().area() should be used to find the
|
idx-th component of the outer vector and _InputArray::size().area() should be used to find the
|
||||||
number of components (vectors/matrices) of the outer vector.
|
number of components (vectors/matrices) of the outer vector.
|
||||||
|
|
||||||
|
In general, type support is limited to cv::Mat types. Other types are forbidden.
|
||||||
|
But in some cases we need to support passing of custom non-general Mat types, like arrays of cv::KeyPoint, cv::DMatch, etc.
|
||||||
|
This data is not intented to be interpreted as an image data, or processed somehow like regular cv::Mat.
|
||||||
|
To pass such custom type use rawIn() / rawOut() / rawInOut() wrappers.
|
||||||
|
Custom type is wrapped as Mat-compatible `CV_8UC<N>` values (N = sizeof(T), N <= CV_CN_MAX).
|
||||||
*/
|
*/
|
||||||
class CV_EXPORTS _InputArray
|
class CV_EXPORTS _InputArray
|
||||||
{
|
{
|
||||||
@ -203,6 +209,11 @@ public:
|
|||||||
template<std::size_t _Nm> _InputArray(const std::array<Mat, _Nm>& arr);
|
template<std::size_t _Nm> _InputArray(const std::array<Mat, _Nm>& arr);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
template<typename _Tp> static _InputArray rawIn(const std::vector<_Tp>& vec);
|
||||||
|
#ifdef CV_CXX_STD_ARRAY
|
||||||
|
template<typename _Tp, std::size_t _Nm> static _InputArray rawIn(const std::array<_Tp, _Nm>& arr);
|
||||||
|
#endif
|
||||||
|
|
||||||
Mat getMat(int idx=-1) const;
|
Mat getMat(int idx=-1) const;
|
||||||
Mat getMat_(int idx=-1) const;
|
Mat getMat_(int idx=-1) const;
|
||||||
UMat getUMat(int idx=-1) const;
|
UMat getUMat(int idx=-1) const;
|
||||||
@ -339,6 +350,11 @@ public:
|
|||||||
template<std::size_t _Nm> _OutputArray(const std::array<Mat, _Nm>& arr);
|
template<std::size_t _Nm> _OutputArray(const std::array<Mat, _Nm>& arr);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
template<typename _Tp> static _OutputArray rawOut(std::vector<_Tp>& vec);
|
||||||
|
#ifdef CV_CXX_STD_ARRAY
|
||||||
|
template<typename _Tp, std::size_t _Nm> static _OutputArray rawOut(std::array<_Tp, _Nm>& arr);
|
||||||
|
#endif
|
||||||
|
|
||||||
bool fixedSize() const;
|
bool fixedSize() const;
|
||||||
bool fixedType() const;
|
bool fixedType() const;
|
||||||
bool needed() const;
|
bool needed() const;
|
||||||
@ -408,8 +424,20 @@ public:
|
|||||||
template<std::size_t _Nm> _InputOutputArray(const std::array<Mat, _Nm>& arr);
|
template<std::size_t _Nm> _InputOutputArray(const std::array<Mat, _Nm>& arr);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
template<typename _Tp> static _InputOutputArray rawInOut(std::vector<_Tp>& vec);
|
||||||
|
#ifdef CV_CXX_STD_ARRAY
|
||||||
|
template<typename _Tp, std::size_t _Nm> _InputOutputArray rawInOut(std::array<_Tp, _Nm>& arr);
|
||||||
|
#endif
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Helper to wrap custom types. @see InputArray */
|
||||||
|
template<typename _Tp> static inline _InputArray rawIn(_Tp& v);
|
||||||
|
/** Helper to wrap custom types. @see InputArray */
|
||||||
|
template<typename _Tp> static inline _OutputArray rawOut(_Tp& v);
|
||||||
|
/** Helper to wrap custom types. @see InputArray */
|
||||||
|
template<typename _Tp> static inline _InputOutputArray rawInOut(_Tp& v);
|
||||||
|
|
||||||
CV__DEBUG_NS_END
|
CV__DEBUG_NS_END
|
||||||
|
|
||||||
typedef const _InputArray& InputArray;
|
typedef const _InputArray& InputArray;
|
||||||
|
@ -61,6 +61,16 @@ CV__DEBUG_NS_BEGIN
|
|||||||
|
|
||||||
//! @cond IGNORED
|
//! @cond IGNORED
|
||||||
|
|
||||||
|
////////////////////////// Custom (raw) type wrapper //////////////////////////
|
||||||
|
|
||||||
|
template<typename _Tp> static inline
|
||||||
|
int rawType()
|
||||||
|
{
|
||||||
|
CV_StaticAssert(sizeof(_Tp) <= CV_CN_MAX, "sizeof(_Tp) is too large");
|
||||||
|
const int elemSize = sizeof(_Tp);
|
||||||
|
return (int)CV_MAKETYPE(CV_8U, elemSize);
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////// Input/Output Arrays ////////////////////////
|
//////////////////////// Input/Output Arrays ////////////////////////
|
||||||
|
|
||||||
inline void _InputArray::init(int _flags, const void* _obj)
|
inline void _InputArray::init(int _flags, const void* _obj)
|
||||||
@ -140,6 +150,27 @@ inline _InputArray::_InputArray(const ogl::Buffer& buf)
|
|||||||
inline _InputArray::_InputArray(const cuda::HostMem& cuda_mem)
|
inline _InputArray::_InputArray(const cuda::HostMem& cuda_mem)
|
||||||
{ init(CUDA_HOST_MEM + ACCESS_READ, &cuda_mem); }
|
{ init(CUDA_HOST_MEM + ACCESS_READ, &cuda_mem); }
|
||||||
|
|
||||||
|
template<typename _Tp> inline
|
||||||
|
_InputArray _InputArray::rawIn(const std::vector<_Tp>& vec)
|
||||||
|
{
|
||||||
|
_InputArray v;
|
||||||
|
v.flags = _InputArray::FIXED_TYPE + _InputArray::STD_VECTOR + rawType<_Tp>() + ACCESS_READ;
|
||||||
|
v.obj = (void*)&vec;
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CV_CXX_STD_ARRAY
|
||||||
|
template<typename _Tp, std::size_t _Nm> inline
|
||||||
|
_InputArray _InputArray::rawIn(const std::array<_Tp, _Nm>& arr)
|
||||||
|
{
|
||||||
|
_InputArray v;
|
||||||
|
v.flags = FIXED_TYPE + FIXED_SIZE + STD_ARRAY + traits::Type<_Tp>::value + ACCESS_READ;
|
||||||
|
v.obj = (void*)arr.data();
|
||||||
|
v.sz = Size(1, _Nm);
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
inline _InputArray::~_InputArray() {}
|
inline _InputArray::~_InputArray() {}
|
||||||
|
|
||||||
inline Mat _InputArray::getMat(int i) const
|
inline Mat _InputArray::getMat(int i) const
|
||||||
@ -279,6 +310,27 @@ inline _OutputArray::_OutputArray(const ogl::Buffer& buf)
|
|||||||
inline _OutputArray::_OutputArray(const cuda::HostMem& cuda_mem)
|
inline _OutputArray::_OutputArray(const cuda::HostMem& cuda_mem)
|
||||||
{ init(FIXED_TYPE + FIXED_SIZE + CUDA_HOST_MEM + ACCESS_WRITE, &cuda_mem); }
|
{ init(FIXED_TYPE + FIXED_SIZE + CUDA_HOST_MEM + ACCESS_WRITE, &cuda_mem); }
|
||||||
|
|
||||||
|
template<typename _Tp> inline
|
||||||
|
_OutputArray _OutputArray::rawOut(std::vector<_Tp>& vec)
|
||||||
|
{
|
||||||
|
_OutputArray v;
|
||||||
|
v.flags = _InputArray::FIXED_TYPE + _InputArray::STD_VECTOR + rawType<_Tp>() + ACCESS_WRITE;
|
||||||
|
v.obj = (void*)&vec;
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CV_CXX_STD_ARRAY
|
||||||
|
template<typename _Tp, std::size_t _Nm> inline
|
||||||
|
_OutputArray _OutputArray::rawOut(std::array<_Tp, _Nm>& arr)
|
||||||
|
{
|
||||||
|
_OutputArray v;
|
||||||
|
v.flags = FIXED_TYPE + FIXED_SIZE + STD_ARRAY + traits::Type<_Tp>::value + ACCESS_WRITE;
|
||||||
|
v.obj = (void*)arr.data();
|
||||||
|
v.sz = Size(1, _Nm);
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
inline _InputOutputArray::_InputOutputArray() { init(ACCESS_RW, 0); }
|
inline _InputOutputArray::_InputOutputArray() { init(ACCESS_RW, 0); }
|
||||||
@ -395,6 +447,32 @@ inline _InputOutputArray::_InputOutputArray(const ogl::Buffer& buf)
|
|||||||
inline _InputOutputArray::_InputOutputArray(const cuda::HostMem& cuda_mem)
|
inline _InputOutputArray::_InputOutputArray(const cuda::HostMem& cuda_mem)
|
||||||
{ init(FIXED_TYPE + FIXED_SIZE + CUDA_HOST_MEM + ACCESS_RW, &cuda_mem); }
|
{ init(FIXED_TYPE + FIXED_SIZE + CUDA_HOST_MEM + ACCESS_RW, &cuda_mem); }
|
||||||
|
|
||||||
|
template<typename _Tp> inline
|
||||||
|
_InputOutputArray _InputOutputArray::rawInOut(std::vector<_Tp>& vec)
|
||||||
|
{
|
||||||
|
_InputOutputArray v;
|
||||||
|
v.flags = _InputArray::FIXED_TYPE + _InputArray::STD_VECTOR + rawType<_Tp>() + ACCESS_RW;
|
||||||
|
v.obj = (void*)&vec;
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CV_CXX_STD_ARRAY
|
||||||
|
template<typename _Tp, std::size_t _Nm> inline
|
||||||
|
_InputOutputArray _InputOutputArray::rawInOut(std::array<_Tp, _Nm>& arr)
|
||||||
|
{
|
||||||
|
_InputOutputArray v;
|
||||||
|
v.flags = FIXED_TYPE + FIXED_SIZE + STD_ARRAY + traits::Type<_Tp>::value + ACCESS_RW;
|
||||||
|
v.obj = (void*)arr.data();
|
||||||
|
v.sz = Size(1, _Nm);
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
template<typename _Tp> static inline _InputArray rawIn(_Tp& v) { return _InputArray::rawIn(v); }
|
||||||
|
template<typename _Tp> static inline _OutputArray rawOut(_Tp& v) { return _OutputArray::rawOut(v); }
|
||||||
|
template<typename _Tp> static inline _InputOutputArray rawInOut(_Tp& v) { return _InputOutputArray::rawInOut(v); }
|
||||||
|
|
||||||
CV__DEBUG_NS_END
|
CV__DEBUG_NS_END
|
||||||
|
|
||||||
//////////////////////////////////////////// Mat //////////////////////////////////////////
|
//////////////////////////////////////////// Mat //////////////////////////////////////////
|
||||||
|
@ -1413,18 +1413,39 @@ void _OutputArray::create(int d, const int* sizes, int mtype, int i,
|
|||||||
case 16:
|
case 16:
|
||||||
((std::vector<Vec4i>*)v)->resize(len);
|
((std::vector<Vec4i>*)v)->resize(len);
|
||||||
break;
|
break;
|
||||||
|
case 20:
|
||||||
|
((std::vector<Vec<int, 5> >*)v)->resize(len);
|
||||||
|
break;
|
||||||
case 24:
|
case 24:
|
||||||
((std::vector<Vec6i>*)v)->resize(len);
|
((std::vector<Vec6i>*)v)->resize(len);
|
||||||
break;
|
break;
|
||||||
|
case 28:
|
||||||
|
((std::vector<Vec<int, 7> >*)v)->resize(len);
|
||||||
|
break;
|
||||||
case 32:
|
case 32:
|
||||||
((std::vector<Vec8i>*)v)->resize(len);
|
((std::vector<Vec8i>*)v)->resize(len);
|
||||||
break;
|
break;
|
||||||
case 36:
|
case 36:
|
||||||
((std::vector<Vec<int, 9> >*)v)->resize(len);
|
((std::vector<Vec<int, 9> >*)v)->resize(len);
|
||||||
break;
|
break;
|
||||||
|
case 40:
|
||||||
|
((std::vector<Vec<int, 10> >*)v)->resize(len);
|
||||||
|
break;
|
||||||
|
case 44:
|
||||||
|
((std::vector<Vec<int, 11> >*)v)->resize(len);
|
||||||
|
break;
|
||||||
case 48:
|
case 48:
|
||||||
((std::vector<Vec<int, 12> >*)v)->resize(len);
|
((std::vector<Vec<int, 12> >*)v)->resize(len);
|
||||||
break;
|
break;
|
||||||
|
case 52:
|
||||||
|
((std::vector<Vec<int, 13> >*)v)->resize(len);
|
||||||
|
break;
|
||||||
|
case 56:
|
||||||
|
((std::vector<Vec<int, 14> >*)v)->resize(len);
|
||||||
|
break;
|
||||||
|
case 60:
|
||||||
|
((std::vector<Vec<int, 15> >*)v)->resize(len);
|
||||||
|
break;
|
||||||
case 64:
|
case 64:
|
||||||
((std::vector<Vec<int, 16> >*)v)->resize(len);
|
((std::vector<Vec<int, 16> >*)v)->resize(len);
|
||||||
break;
|
break;
|
||||||
|
@ -1882,4 +1882,63 @@ TEST(Core_Split, crash_12171)
|
|||||||
EXPECT_EQ(2, dst2.ptr<uchar>(1)[1]);
|
EXPECT_EQ(2, dst2.ptr<uchar>(1)[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct CustomType // like cv::Keypoint
|
||||||
|
{
|
||||||
|
Point2f pt;
|
||||||
|
float size;
|
||||||
|
float angle;
|
||||||
|
float response;
|
||||||
|
int octave;
|
||||||
|
int class_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void test_CustomType(InputArray src_, OutputArray dst_)
|
||||||
|
{
|
||||||
|
Mat src = src_.getMat();
|
||||||
|
ASSERT_EQ(sizeof(CustomType), src.elemSize());
|
||||||
|
CV_CheckTypeEQ(src.type(), CV_MAKETYPE(CV_8U, sizeof(CustomType)), "");
|
||||||
|
|
||||||
|
CustomType* kpt = NULL;
|
||||||
|
{
|
||||||
|
Mat dst = dst_.getMat();
|
||||||
|
for (size_t i = 0; i < dst.total(); i++)
|
||||||
|
{
|
||||||
|
kpt = dst.ptr<CustomType>(0) + i;
|
||||||
|
kpt->octave = (int)i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const int N = (int)src.total();
|
||||||
|
dst_.create(1, N * 2, rawType<CustomType>());
|
||||||
|
Mat dst = dst_.getMat();
|
||||||
|
for (size_t i = N; i < dst.total(); i++)
|
||||||
|
{
|
||||||
|
kpt = dst.ptr<CustomType>(0) + i;
|
||||||
|
kpt->octave = -(int)i;
|
||||||
|
}
|
||||||
|
#if 0 // Compilation error
|
||||||
|
CustomType& kpt = dst.at<CustomType>(0, 5);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Core_InputArray, support_CustomType)
|
||||||
|
{
|
||||||
|
std::vector<CustomType> kp1(5);
|
||||||
|
std::vector<CustomType> kp2(3);
|
||||||
|
test_CustomType(rawIn(kp1), rawOut(kp2));
|
||||||
|
ASSERT_EQ((size_t)10, kp2.size());
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
EXPECT_EQ(i, kp2[i].octave);
|
||||||
|
}
|
||||||
|
for (int i = 3; i < 5; i++)
|
||||||
|
{
|
||||||
|
EXPECT_EQ(0, kp2[i].octave);
|
||||||
|
}
|
||||||
|
for (int i = 5; i < 10; i++)
|
||||||
|
{
|
||||||
|
EXPECT_EQ(-i, kp2[i].octave);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}} // namespace
|
}} // namespace
|
||||||
|
Loading…
Reference in New Issue
Block a user