OpenCV用户定义类型的矩阵

时间:2011-08-25 18:51:38

标签: c++ opencv

有没有办法在OpenCV 2.x中有一个用户定义类型的矩阵?类似的东西:

cv::Mat_<KalmanRGBPixel> backgroundModel;

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

我知道有一个DataType&lt; _Tp&gt; core.hpp中的类需要为我的类型定义,但我不知道该怎么做。

编辑: KalmanRGBPixel只是cv :: KalmanFilter类的包装器。至于现在,它是唯一的成员。

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

感谢您的帮助。

4 个答案:

答案 0 :(得分:3)

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

您需要专门化DataType模板,但不要使用1个通道,而是使通道与自定义对象的大小相同。您可能还需要覆盖一些函数以获得预期的功能,但稍后再回过头来。

首先,这是我的自定义类型模板专业化的一个示例:

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

超级的typedef不需要,但有助于cpp中的可读性。 注意我用width / hight参数覆盖了构造函数。这是因为如果我们想要一个2D矩阵,我们必须以这种方式实例化。

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&lt; _T&gt;()覆盖只是为了更清晰的代码:

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

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

答案 1 :(得分:1)

如果您不想使用OpenCV功能,那么Mat不适合您。 请改用std::vector<std::vector<Type> >。您可以在初始化期间给出大小:

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

然后您可以使用[] - 运营商进行访问。不需要在这里使用晦涩的cv::Mat

如果您真的需要使用OpenCV-Matrix,那么您必须定义DataType。它基本上是一堆特征。您可以在网上阅读有关C ++ Traits的信息。

答案 2 :(得分:1)

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

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

  

DataType类主要用于提供对这种原始数据类型的描述,而不向相应的类添加任何字段或方法(实际上不可能向原始C / C ++数据类型添加任何内容)。这种技术在C ++中称为类特征。它不是使用的DataType本身,而是它的专用版本[...]这个类的主要目的是将编译时类型信息转换为OpenCV兼容的数据类型标识符[...]

(是的,最后我在这个帖子中回答了问题!)

答案 3 :(得分:0)

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