Skip to content

Feature request: customizable InputArray #20869

@vrabaud

Description

@vrabaud
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; } 
};

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions