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

Posted

技术标签:

【中文标题】如何在openCV中修改部分多维矩阵?【英文标题】:How to modify part of the multi-dimensional matrix in openCV? 【发布时间】:2015-09-23 01:25:50 【问题描述】:

我想使用 openCV 修改多维矩阵的一部分。基本上我想达到和用Matlab写的一样:

A = zeros(5,5,25);
A(:,:,1) = some_matrix1;
A(:,:,2) = some_matrix2;

我不确定我应该使用具有 25 个通道的 5x5 矩阵还是具有单通道的 5x5x25 矩阵。这是我尝试过的:

int dim[3] =  5,5,25 ;
Mat A(3, dim, CV_32FC(1), Scalar::all(0));
A(Range::all(),Range::all(),0) = some_matrix;

但似乎我只能将 Range 用于二维。 或者

Mat A(5, 5, CV_32FC(25), Scalar::all(0));
A(Range::all(),Range::all())[0] = some_matrix;

但在这种情况下,我不知道如何访问该频道。 你能帮我解决一下吗?

【问题讨论】:

看看这里docs.opencv.org/modules/core/doc/… 【参考方案1】:

OpenCV 针对 2D 矩阵进行了优化。多维矩阵会起作用,但效率低下且难以访问。

此示例代码将向您展示如何从 3D 矩阵中写入和读取值:

#include <opencv2\opencv.hpp>
using namespace cv;

int main()

    int sizes[] =  5, 5, 25 ;
    Mat data(3, sizes, CV_32F);

    Mat1f some_matrix(sizes[0], sizes[1]);
    randu(some_matrix, 0.f, 100.f); // some random  values

    // Init data with each plane a constant increasing value 
    for (int z = 0; z < data.size[2]; ++z)
    
        // Set each z-plane to some scalar value
        Range ranges[] =  Range::all(), Range::all(), Range(z, z + 1) ;
        data(ranges) = data.size[2] - z;
    

    // Set the n-th z-plane to some_matrix
    int z = 0;
    for (int r = 0; r < sizes[0]; ++r)
    
        for (int c = 0; c < sizes[1]; ++c)
        
            data.at<float>(r, c, z) = some_matrix(r, c);
        
    

    // Access all slices along z dimension
    for (int z = 0; z < data.size[2]; ++z)
    
        Range ranges[] =  Range::all(), Range::all(), Range(z, z + 1) ;
        Mat slice3d(data(ranges).clone()); // with clone slice is continuous, but still 3d
        Mat slice(2, &data.size[0], data.type(), slice3d.data);
    

    return 0;

但是,将 5x5x25 3D 矩阵存储为 std::vector&lt;Mat&gt; 会更容易和实用,其中 vector 的长度为 25,每个矩阵都是 2D 5x5。

查看代码:

#include <opencv2\opencv.hpp>
using namespace cv;

int main()

    int sizes[] =  5, 5, 25 ;

    vector<Mat> data(sizes[2]);
    // Init data with each plane a constant increasing value
    for (int z = 0; z < sizes[2]; ++z)
    
        data[z] = Mat(sizes[0], sizes[1], CV_32F, float(sizes[2] - z));
    

    Mat1f some_matrix(sizes[0], sizes[1]);
    randu(some_matrix, 0.f, 100.f); // some random  values

    // Set the n-th z-plane to some_matrix
    int z = 0;
    data[z] = some_matrix;

    return 0;

【讨论】:

【参考方案2】:

这是从通道访问像素的一段代码,你可以试试。

int dim[3] =  5,5,25 ;
Mat A(3, dim, CV_32FC1, Scalar::all(0));

 for (int m = 0; m < 5; m++)

  for (int n = 0; n < 5; n++)
  
    for (int a = 0; a < 25; a++) // no of channels
    
      cout << A.at<cv::Vec3f>(m,n)[a] << endl;
    
  

【讨论】:

以上是关于如何在openCV中修改部分多维矩阵?的主要内容,如果未能解决你的问题,请参考以下文章

opencv编程中cvMat到Mat如何进行数据转换?

在opencv c ++中保存多维矩阵

如何在opencv中获取矩阵的一部分

如何在 OpenCV 中访问高维矩阵的元素?

MATLAB中如何定义多维矩阵

如何在openCV中获取像素矩阵和重塑矩阵