优化了从openCV mat到2D float数组的复制



我想在2D float数组中复制一个opencv Mat变量。我使用下面的代码来达到这个目的。但因为我开发的代码,速度是一个非常重要的指标,这种方法的复制是不够优化。有没有其他更优化的使用方式?

float *ImgSrc_f;
ImgSrc_f = (float *)malloc(512 * 512 * sizeof(float));
for(int i=0;i<512;i++)
    for(int j=0;j<512;j++)
    {
        ImgSrc_f[i * 512 + j]=ImgSrc.at<float>(i,j);
    }

真的,

//first method
Mat img_cropped = ImgSrc(512, 512).clone();
float *ImgSrc_f = img_cropped.data;

的效率不应该比最佳方法低几个百分点。我建议采用这种方法,只要它对第二种方法的损失不超过1%。

也可以试试这个,它非常接近于绝对最好的方法,除非您可以使用某种扩展的cpu指令集(如果可用,则使用)。您可能会发现方法2和方法1之间的差异很小。

//method 2    
//preallocated memory
//largest possible with minimum number of direct copy calls
//caching pointer arithmetic can speed up things extremely minimally
//removing the Mat header with a malloc can speed up things minimally
>>startx, >>starty, >>ROI;
Mat img_roi = ImgSrc(ROI);
Mat img_copied(ROI.height, ROI.width, CV_32FC1);
for (int y = starty; y < starty+ROI.height; ++y)
{
    unsigned char* rowptr = img_roi.data + y*img_roi.step1() + startx * sizeof(float);
    unsigned char* rowptr2 = img_coped.data + y*img_copied.step1();
    memcpy(rowptr2, rowptr, ROI.width * sizeof(float));
}

基本上,如果你真的,真的关心这些性能细节,你应该远离重载操作符。代码中的抽象层次越多,代价就越高。当然,这会让你的代码更危险,更难读,更容易出错。

也可以使用std::vector结构吗?如果尝试

std::vector<float> container;
container.assign((float*)matrix.startpos, (float*)matrix.endpos);

最新更新