在我的应用程序中,我想创建一个具有一些值的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中解决这个问题?
答案 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)
虽然您的答案对您的情况是正确的,但最好知道step
和AUTO_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
,*data
,data[0]
,&data[0]
和{{1}指向数组的基数。可以选择以上任何一种表示来正确构造&data[0][0]
来代替Mat
X
由于OpenCV的数据为accepted为A = 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进行错误步骤参数,你得到的。