使用 C++ 在 OpenCV 中的矩阵中的多维数据

Posted

技术标签:

【中文标题】使用 C++ 在 OpenCV 中的矩阵中的多维数据【英文标题】:Multi-Dimensional data in a Matrix in OpenCV with C++ 【发布时间】:2012-01-10 19:43:12 【问题描述】:

我想在 OpenCV (C++) 中声明、填充、访问与 namespace cv 兼容的多维矩阵。我发现没有关于它们的快速和容易学习的例子。你能帮帮我吗?

【问题讨论】:

【参考方案1】:

这是来自NAryMatIterator 文档的简短示例;它展示了如何在 OpenCV 中创建、填充和处理多维矩阵:

void computeNormalizedColorHist(const Mat& image, Mat& hist, int N, double minProb)

    const int histSize[] = N, N, N;

    // make sure that the histogram has a proper size and type
    hist.create(3, histSize, CV_32F);

    // and clear it
    hist = Scalar(0);

    // the loop below assumes that the image
    // is a 8-bit 3-channel. check it.
    CV_Assert(image.type() == CV_8UC3);
    MatConstIterator_<Vec3b> it = image.begin<Vec3b>(),
                             it_end = image.end<Vec3b>();
    for( ; it != it_end; ++it )
    
        const Vec3b& pix = *it;
        hist.at<float>(pix[0]*N/256, pix[1]*N/256, pix[2]*N/256) += 1.f;
    

    minProb *= image.rows*image.cols;
    Mat plane;
    NAryMatIterator it(&hist, &plane, 1);
    double s = 0;
    // iterate through the matrix. on each iteration
    // it.planes[*] (of type Mat) will be set to the current plane.
    for(int p = 0; p < it.nplanes; p++, ++it)
    
        threshold(it.planes[0], it.planes[0], minProb, 0, THRESH_TOZERO);
        s += sum(it.planes[0])[0];
    

    s = 1./s;
    it = NAryMatIterator(&hist, &plane, 1);
    for(int p = 0; p < it.nplanes; p++, ++it)
        it.planes[0] *= s;

另外,请查看cv::compareHist 函数,了解NAryMatIterator here 的另一个用法示例。

【讨论】:

所以 3 维数组应该是这样的吧? int sz[] = 3, 3, 3; Mat accumarray(3, sz, CV_8U, Scalar::all(0)); accumarray.at(0, 1, 2) = 20; 好吧,上面的方法似乎不适用于 4 维矩阵。你知道原因吗? 参数 minProb 是什么? 不确定这是基于哪个版本,但是在opencv 4中,`NAryMatIterator`采用指向mat的指针,而不是指向mat的指针,所以这段代码无法编译。 API 好像有点变化,更新的例子在这里:docs.opencv.org/master/d5/dd2/…【参考方案2】:

要创建一个大小为 100x100x3 的多维矩阵,使用浮点数,一个通道,并将所有元素初始化为 10,您可以这样编写:

int size[3] =  100, 100, 3 ;
cv::Mat M(3, size, CV_32FC1, cv::Scalar(10));

要遍历并输出矩阵中的元素,您可以这样做:

for (int i = 0; i < 100; i++)
  for (int j = 0; j < 100; j++)
    for (int k = 0; k < 3; k++) 
      std::cout << M.at<cv::Vec3f>(i,j)[k] << ", ";

但是,请注意使用此处记录的多维矩阵的麻烦:How do i get the size of a multi-dimensional cv::Mat? (Mat, or MatND)

【讨论】:

正是我想要的,简单方便!谢谢。

以上是关于使用 C++ 在 OpenCV 中的矩阵中的多维数据的主要内容,如果未能解决你的问题,请参考以下文章

一个管理多维数组的类!如何管理单元格中的不同数据类型?

OpenCV C++中的矩阵复共轭

opencv矩阵运算

如何在openCV中修改部分多维矩阵?

R中的多维稀疏数组(3路张量)

从 OpenCV 中的矩阵访问值