OpenCV Matrix of user

Is there a way to have a matrix of user-defined type in OpenCV 2.x? Something like :

cv::Mat_<KalmanRGBPixel> backgroundModel;

I know cv::Mat<> is meant for image and mathematic, but I want to hold data in a matrix form. I don't plan to use inverse, transpose, multiplication, etc., it's only to store data. I want it to be in matrix form because the pixel_ij of each frame of a video will be linked to backgroundModel_ij.

I know there is a DataType<_Tp> class in core.hpp that needs to be defined for my type but I'm not sure how to do it.

EDIT : KalmanRGBPixel is only a wrapper for cv::KalmanFilter class. As for now, it's the only member.

... some functions ...
private:
    cv::KalmanFilter kalman;

Thanks for your help.


In the OpenCV documentation it is explained how to add custom types to OpenCV matrices. You need to define the corresponding cv::DataType .

https://docs.opencv.org/master/d0/d3a/classcv_1_1DataType.html

The DataType class is basically used to provide a description of such primitive data types without adding any fields or methods to the corresponding classes (and it is actually impossible to add anything to primitive C/C++ data types). This technique is known in C++ as class traits. It is not DataType itself that is used but its specialized versions […] The main purpose of this class is to convert compilation-time type information to an OpenCV-compatible data type identifier […]

(Yes, finally I answer the question itself in this thread!)


I have a more long winded answer for anybody wanting to create a matrix of custom objects, of whatever size.

You will need to specialize the DataType template but instead of having 1 channel, you make the channels the same size of your custom object. You may also need to override a few functions to get expected functionality, but back to that later.

First, here is an example of my custom type template specialization:

typedef HOGFilter::Sample Sample;
namespace cv {
    template<> class DataType<Sample>
    {
    public:
        typedef HOGFilter::Sample       value_type;
        typedef HOGFilter::Sample       channel_type;
        typedef HOGFilter::Sample       work_type;
        typedef HOGFilter::Sample       vec_type;

        enum {
            depth = CV_8U,
            channels = sizeof(HOGFilter::Sample),
            type = CV_MAKETYPE(depth, channels),
        };
    };
}

Second.. you may want to override some functions to get expected functionality:

// Special version of Mat, a matrix of Samples. Using the power of opencvs
// matrix manipulation and multi-threading capabilities 
class SampleMat : public cv::Mat_<Sample>
{
    typedef cv::Mat_<Sample> super;
public:
    SampleMat(int width = 0, int height = 0);
    SampleMat &operator=(const SampleMat &mat);

    const Sample& at(int x, int y = 0);
};

The typedef of super isnt required but helps with readability in the cpp. Notice I have overriden the constructor with width/hight parameters. This is because we have to instantiate the mat this way if we want a 2D matrix.

SampleMat::SampleMat(int width, int height)
{
    int count = width * height;

    for (int i = 0; i < count; ++i)
    {
        HOGFilter::Sample sample;
        this->push_back(sample);
    }

    *dynamic_cast<Mat_*>(this) = super::reshape(channels(), height);
}

The at<_T>() override is just for cleaner code:

const Sample & SampleMat::at(int x, int y)
{
    if (y == 0)
        return super::at<Sample>(x);

    return super::at<Sample>(cv::Point(x, y));
}

If you don't want to use the OpenCV functionality, then Mat is not the right type for you. Use std::vector<std::vector<Type> > instead. You can give the size during initialization:

std::vector<std::vector<Type> > matrix(42, std::vector<Type>(23));

Then you can access with [] -operator. No need to screw around with obscure cv::Mat s here.

If you would really need to go for an OpenCV-Matrix, you are right in that you have to define the DataType. It is basically a bunch of traits. You can read about C++ Traits on the web.

链接地址: http://www.djcxy.com/p/54620.html

上一篇: 在R中使用callNextMethod()传递参数时出现问题

下一篇: 用户的OpenCV矩阵