-
-
Notifications
You must be signed in to change notification settings - Fork 56.5k
Open
Description
Detailed description
It would be nice to be able to use OpenCV with any custom type. Right now, we have to do:
MyType image_in(...), image_out(...);
cv::Mat cv_image_in = MyTypeToOpenCV(image_in);
cv::Mat cv_image_out;
cv::my_function(cv_image_in, cv_image_out);
OpenCVToMyType(image_out, cv_image_out);
But it would be nice to be able to do:
MyType image_in(...), image_out(...);
cv::my_function(image_in, image_out);
Here is a transcribed discussion with @vpisarev
Regarding InputArray — I was thinking of adding yet another kind of InputArray, InputArray::CUSTOM, and adding yet another pointer to the abstract class of virtual methods.
Right now, the code is:
class InputArray
{
// various constructors
InputArray(const Mat& m);
InputArray(const std::vector<T>& vec);
...
Mat getMat(int idx=-1) const;
void create(...);
...
int kind; // MAT, UMAT, STD_VECTOR etc.
int type;
void* obj; // object;
Size size;
};
It will be something like that:
inside OpenCV
class InputArray
{
// the only constructor, but the template one and not "explicit"
template<typename ArrayT> InputArray(const ArrayT& some_array)
{
kind = ArrayDescriptor<ArrayT>::kind;
obj = &some_array;
customOps = ArrayDescriptor<ArrayT>::getArrayOps();
}
int kind;
void* obj;
int type;
Size size;
ArrayOperations* customOps; // new member
};
// for arbitrary type we don't provide any array information,
// which will make compiler issue an error in the case of completely alien array type.
template<typename T> struct ArrayDescriptor
{
};
// provide instances for popular array types
template<> struct ArrayDescriptor<Mat>
{
enum { kind = InputArray::MAT };
static ArrayOperations* getArrayOps() { return 0; }
};
template<typename T> struct ArrayDescriptor<std:vector<Mat> >
{
enum { kind = InputArray::VECTOR };
static ArrayOperations* getArrayOps() { return 0; }
};
// the base class for user arrays
class ArrayOperations
{
public:
virtual ~ArrayOperations() {}
virtual Mat getMat(void* obj, int idx) = 0;
virtual Size size(void* obj) = 0;
...
};
// somewhere inside OpenCV core
Mat InputArray:getMat(int idx) {
if (kind == MAT) return *(Mat*)obj;
if (kind == CUSTOM) { CV_Assert(customOps != 0); return customOps->getMat(obj, idx); }
...
}
outside OpenCV, in user's lib/app
// ops for your array defined
class CustomArrayOps : public ArrayOperations
{
public:
.... // implement all the interface methods
static CustomArrayOps custom_ops; // basically, you need just once instance of this class
};
// and the corresponding traits type
template<> struct ArrayDescriptor<CustomArray>
{
enum { kind = InputArray::CUSTOM };
static ArrayOperations* getArrayOps() { return &CustomlArrayOps::custom_ops; }
};
Reactions are currently unavailable