使用 OpenCV 在 Mat 中分配

Posted

技术标签:

【中文标题】使用 OpenCV 在 Mat 中分配【英文标题】:Assign in Mat with OpenCV 【发布时间】:2014-02-11 21:10:40 【问题描述】:

我需要用值 CV_32FC1 (float) 在 M(变量类型 Mat)中分配值,但在大小为 10000x10000 时需要很长时间。即:

 for (i=0 ; i<rows; i++)   
   for (j=0 ; j<cols; j++)
      ...build variable NEW_VALUE for indexes i, j
      M.at<float>(i,j) = NEW_VALUE   
   

上面的代码大约需要 1 秒。我看到的其他形式是定义一个联合(复制字节):

typedef unionfloat _float;  uchar _uchar[4]; Bits;
...
Bits bits;
float new_value;
for (i=0 ; i<rows; i++)
  for (j=0 ; j<cols; j+=4)
     ...//build variable new_value for indexes i, j
     bits._float = new_value;
     M.data[i*cols + j] = bits._uchar[0];
     M.data[i*cols + j+1] = bits._uchar[1];
     M.data[i*cols + j+2] = bits._uchar[3];
     M.data[i*cols + j+3] = bits._uchar[3];
  

这比第一个要快得多。但不工作。我试着做:

 memcpy(&M.data[i*cols + j], bits._uchar[0], 1);
 memcpy(&M.data[i*cols + j+1], bits._uchar[1], 1);
 ...

但不工作。

还有:

 memcpy(&M.at<float>(i,j), bits._uchar, 4);

也很慢。

我需要知道如何在 M 中正确复制 new_value 的字节

【问题讨论】:

【参考方案1】:

您的代码很慢,因为您要为每个像素执行大量计算。乘法运算不是一个便宜的运算,您可以多次显式 (i*cols + j) 或隐式 (at(i,j)) 使用它。阅读this tutorial 以更好地了解如何有效地访问像素。

【讨论】:

【参考方案2】:

你可以这样做:

float *prtM=(float*)M.data;
for (i=0 ; i<rows; i++)   
   for (j=0 ; j<cols; j++)
       //...build variable NEW_VALUE for indexes i, j
       *prtM = NEW_VALUE;
       prtM++;
   

【讨论】:

您将 NEW_VALUE 设置为指针,而不是它指向的数据。 ups,我错过了那里的 *,谢谢@MichaelBurdinov 不客气。但是请注意,这种方法仅适用于内存中连续的图像,即您的图像不是某个更大图像的 ROI。要解决此问题,您可以使用 'float *prtM = M.ptr(i);'每一行。【参考方案3】:
float* p;
for (i=0 ; i<rows; i++)  

    p = M.ptr<float>(i);
    for (j=0 ; j<cols; j++)
    
        *p++ = NEW_VALUE;
    

paghdv 的代码是最优化的代码,但如果矩阵中的值不连续,则无法工作。

【讨论】:

以上是关于使用 OpenCV 在 Mat 中分配的主要内容,如果未能解决你的问题,请参考以下文章

行优先与列优先遍历opencv中Mat数据类型的效率差异

如何在 OpenCV 中删除 cvseq?

将图像加载到现有 Mat 中

opencv怎么给mat赋值

No implementation found for long org.opencv.core.Mat.n_Mat() 错误使用 OpenCV

opencv中MatND和Mat的区别