OpenCV用户定义类型的矩阵

OpenCV Matrix of user-defined type

本文关键字:类型 用户 定义 OpenCV      更新时间:2023-10-16

是否有办法在OpenCV 2.x中拥有用户定义类型的矩阵?例如:

cv::Mat_<KalmanRGBPixel> backgroundModel;

我知道cv::Mat<>用于图像和数学,但我想以矩阵形式保存数据。我不打算使用逆,转置,乘法等等,它只是为了存储数据。我希望它是矩阵形式,因为视频的每一帧的pixel_ij将链接到backgroundModel_ij。

我知道core.hpp中有一个DataType<_Tp>类需要为我的类型定义,但我不确定如何做到这一点。

EDIT: KalmanRGBPixel只是cv::KalmanFilter类的包装器。到目前为止,它是唯一的成员。

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

谢谢你的帮助。

对于任何想要创建任何大小的自定义对象矩阵的人,我都有一个更冗长的答案。

您将需要专门化DataType模板,但不是只有一个通道,而是使通道与自定义对象的大小相同。您可能还需要覆盖一些函数来获得预期的功能,但稍后会回到这个问题。

首先,这里有一个自定义类型模板专门化的例子:
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),
        };
    };
}

第二. .您可能需要重写一些函数以获得预期的功能:

// 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);
};

super的类型定义不是必需的,但有助于提高cpp中的可读性。注意,我已经用宽度/高度参数重写了构造函数。这是因为如果我们想要一个2D矩阵,我们必须以这种方式实例化mat。

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);
}

at<_T>()重写只是为了更简洁的代码:

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

在OpenCV文档中解释了如何向OpenCV矩阵添加自定义类型。需要定义相应的cv::DataType

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

DataType类基本上用来提供这种基本数据类型的描述,而不需要向相应的类添加任何字段或方法(实际上不可能向基本C/c++数据类型添加任何内容)。这种技术在c++中被称为类特征。这个类的主要目的是将编译时类型信息转换为与opencv兼容的数据类型标识符[…]

(是的,最后我回答这个问题本身在这个线程!)

如果您不想使用OpenCV功能,那么Mat不是适合您的类型。使用std::vector<std::vector<Type> >代替。您可以在初始化时给出大小:

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

则可以使用[] -操作符访问。没有必要在这里使用模糊的cv::Mat s。

如果你真的需要一个OpenCV-Matrix,你是正确的,你必须定义数据类型。它基本上是一堆特征。

你可以创建一个CV mat,通过指定地址给构造函数来使用你自己分配的内存。如果你还想要宽度和高度是正确的,你需要找到一个openCV像素类型是相同的字节数。