OpenCV Matrix of user-defined type
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 t开发者_StackOverflow中文版here 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.
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));
}
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!)
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.
You can create a CV mat that users your own allocated memory by specifying the address to the constructor. If you also want the width and height to be correct you will need to find an openCV pixel type that is the same number of bytes.
精彩评论