使用2D数组初始化OpenCV Mat

时间:2012-08-27 09:30:30

标签: opencv

在我的应用程序中,我想创建一个具有一些值的OpenCV Mat A(2-Dimensions),然后使用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);  

在1D数组的情况下,传递的值是OK。但这对2D阵列不起作用,这更常见。我怎样才能在OpenCV中解决这个问题?

4 个答案:

答案 0 :(得分:26)

orginally,我使​​用了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

答案 1 :(得分:19)

虽然您的答案对您的情况是正确的,但最好知道stepAUTO_STEP的含义

通常,图像存储在连续的内存块中。每行跟在前一行之后,因此您可以通过简单的

指针访问数据
data = dataPtr[currentCol + width * currentRow];

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

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

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

data = dataPtr[currentCol + step * currentRow];

适用于各种图像。

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

答案 2 :(得分:16)

除上述答案外,还有another option

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

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

您可以轻松获得所需的结果,而无需定义其他变量'data'。

答案 3 :(得分:8)

由于data是二维数组 - 所有data&data*datadata[0]&data[0]和{{1}指向数组的基数。可以选择以上任何一种表示来正确构造&data[0][0]来代替Mat

X

由于OpenCV的数据为acceptedA = Mat(2, 5, CV_32FC1, X ); ,而OpenCV的数据访问权限与line相同,因此请您放心。我更喜欢从单维或多维数组构造Mat的相同语法。

void*

回到查询 - 请注意,即使从1D数组构建A = Mat(1, 10, CV_32FC1, data ); //for 1D array A = Mat(2, 5, CV_32FC1, data ); //for 2D array 也是错误的。步骤参数被提到为2.它恰好工作,因为OpenCV overrides提供了步骤参数,如果行数是1.对于更高维度的数组,OpenCV抛出调试assertion进行错误步骤参数,你得到的。