【问题标题】:initialize an OpenCV Mat with an 2D array使用 2D 数组初始化 OpenCV Mat
【发布时间】:2012-08-27 09:30:30
【问题描述】:

在我的应用程序中,我想创建一个具有一些值的 OpenCV Mat A(二维),然后使用 A 作为输入将其传递给另一个 OpenCV 函数。

目前,我正在尝试:

// float data[2][5] = {{1,2,3,4,5},{7,8,9,10,11}}; 
// OR
float data[10] = {1,2,3,4,5,7,8,9,10,11};

// and then
//  A = Mat(1, 5, CV_32FC1, &data, 2);   // init from float 1D - array
// OR 
    A = Mat(2, 5, CV_32FC1, &data, 2);  

如果是一维数组,传值是可以的。但这不适用于二维数组,这是更常见的情况。如何在 OpenCV 中解决这个问题?

【问题讨论】:

    标签: opencv


    【解决方案1】:

    最初,我使用了 OpenCV 在线指南中的助记符:

    Mat::Mat(Size size, int type, void* data, size_t step=AUTO_STEP)
    

    但我不明白size_t step=AUTO_STEP 的文档是什么意思。这意味着我可以省略 step 参数,OpenCV 将使用该参数自动选择 AUTO_STEP

    我试过了,这很有效:

    A = Mat(2, 5, CV_32FC1, &data);
    

    对于从数组初始化的 2D Mat

    【讨论】:

      【解决方案2】:

      虽然您的回答对您的情况是正确的,但最好了解 stepAUTO_STEP 的含义

      通常,图像存储在连续的内存块中。每一行都在前一行之后,因此您可以通过简单的指针访问数据

      data = dataPtr[currentCol + width * currentRow];
      

      其中 width 是以字节为单位的行宽(不是像素!)

      但情况并非总是如此 - 有时您访问一个子矩阵,并且数据在每一行上都是连续的,但要进入下一行,您必须跳转一个字节序列。

      这是步长(也称为步幅)的来源。它表示两个连续行之间的距离(以字节为单位)。在连续矩阵中,其值为sizeof(pixel)*rowWidth,但在特殊情况下可能有自定义值。当你将 AUTO_STEP 传递给 Mat 构造函数时,它知道数据是连续的,并用上面的公式计算步长。所以现在,读取像素值更正确的方法是

      data = dataPtr[currentCol + step * currentRow];
      

      适用于各种图像。

      最后但同样重要的是,不要忘记步长是以字节而不是像素来衡量的。所以如果你有一个 3 通道的 uchar RGB 图像,step 将是3*number of pixels,如果你有一个 3 通道的 int 图像,step = 3(channels)*(4=sizeof(int))*(number rows)

      【讨论】:

        【解决方案3】:

        除了上面的答案,还有another option

        对于较小的数据,我更喜欢以下内容:

        Mat A = (Mat_<float>(2, 5) << 1, 2, 3, 4, 5, 7, 8, 9, 10, 11);
        

        您可以轻松获得所需的结果,而无需定义额外的变量“数据”。

        【讨论】:

          【解决方案4】:

          由于data 是二维数组 - 所有data&amp;data*datadata[0]&amp;data[0]&amp;data[0][0] 都指向数组的底部。可以选择上述任何一种表示来正确构造 Mat 来代替

          中的 X
          A = Mat(2, 5, CV_32FC1, X );
          

          请放心,因为 OpenCV 的数据为 accepted,为 void*,OpenCV 的数据访问为 line。我更喜欢从单维或多维数组构造 Mat 的相同语法。

          A = Mat(1, 10, CV_32FC1, data ); //for 1D array
          A = Mat(2, 5, CV_32FC1, data ); //for 2D array
          

          返回查询 - 请注意,即使从一维数组构造 Mat 也是不正确的。 step 参数被提到为 2。它恰好起作用,因为 OpenCV overrides 提供的 step 参数,如果行数为 1。对于更高维数组,OpenCV 抛出 debug assertion 错误的 step 参数,你得到了。

          【讨论】:

            【解决方案5】:

            来自this merged pull request的C++11解决方案:

            // Mat(sizes, list)
            cv::Mat A({2, 5}, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10});
            

            【讨论】:

              猜你喜欢
              • 2019-04-28
              • 1970-01-01
              • 2023-03-30
              • 2023-04-01
              • 1970-01-01
              • 2018-09-21
              • 1970-01-01
              • 1970-01-01
              • 2015-08-05
              相关资源
              最近更新 更多