Opencv Mat矢量赋值给矩阵的一行,最快的方法是什么?

时间:2014-09-23 09:14:27

标签: c++ opencv matrix

将矢量分配给循环中的矩阵行的最快方法是什么?我想用向量在其行中填充数据矩阵。这些向量在循环中计算。此循环持续到数据矩阵的所有条目都填充这些向量。

目前我正在使用cv::Mat::at<>()方法访问矩阵的元素并用向量填充它们,但是,这个过程看起来很慢。我已经尝试了另一种使用cv::Mat::X.row(index) = data_vector的方法,它工作得很快,但我的矩阵X填充了一些我无法理解的垃圾值,为什么。

我读到存在另一种使用指针的方式(最快的方式),但是,我无法理解。有人可以解释如何使用它们或其他不同的方法吗?

以下是我的代码的一部分:

#define OFFSET 2

cv::Mat im = cv::imread("001.png", CV_LOAD_IMAGE_GRAYSCALE);
cv::Mat X = cv::Mat((im.rows - 2*OFFSET)*(im.cols - 2*OFFSET), 25, CV_64FC1); // Holds the training data. Data contains image patches
cv::Mat patch = cv::Mat(5, 5, im.type()); // Holds a cropped image patch
typedef cv::Vec<float, 25> Vec25f;

int ind = 0;
for (int row = 0; row < (im.rows - 2*OFFSET); row++){
    for (int col = 0; col < (im.cols - 2*OFFSET); col++){

    cv::Mat temp_patch = im(cv::Rect(col, row, 5, 5)); // crop an image patch (5x5) at each pixel
    patch = temp_patch.clone(); // Needs to do this because temp_patch is not continuous in memory 
    patch.convertTo(patch, CV_64FC1);

    Vec25f data_vector = patch.reshape(0, 1); // make it row vector (1X25).
    for (int i = 0; i < 25; i++) 
    {
        X.at<float>(ind, i) = data_vector[i]; // Currently I am using this way (quite slow).
    }

    //X_train.row(ind) = patch.reshape(0, 1); // Tried this but it assigns some garbage values to the data matrix!
    ind += 1;
    }
}

3 个答案:

答案 0 :(得分:1)

要执行常规的opencv方法: -

ImageMat.row(RowIndex) = RowMat.clone();

RowMat.copyTo(ImageMat.row(RowIndex));

未测试正确性或速度。

答案 1 :(得分:0)

您的代码中只需进行一些编辑

double * xBuffer = X.ptr<double>(0);
for (int row = 0; row < (im.rows - 2*OFFSET); row++){
    for (int col = 0; col < (im.cols - 2*OFFSET); col++){

    cv::Mat temp_patch = im(cv::Rect(col, row, 5, 5)); // crop an image patch (5x5) at each pixel
    patch = temp_patch.clone(); // Needs to do this because temp_patch is not continuous in memory 
    patch.convertTo(patch, CV_64FC1);
    memcpy(xBuffer, patch.data, 25*sizeof(double));
    xBuffer += 25;
    }
}

另外,你似乎没有在补丁中做任何计算只提取灰度值,所以你可以创建与im相同类型的X,并在最后将其转换为double。通过这种方式,您可以记忆补丁的每一行,内存中的地址为“unsigned char * buffer = im.ptr(row)+ col

答案 2 :(得分:0)

根据docs

如果您需要处理整个矩阵行,最有效的方法是先获取指向该行的指针,然后仅使用普通的C运算符[]:

// compute sum of positive matrix elements
// (assuming that M is double-precision matrix)
double sum=0;
for(int i = 0; i < M.rows; i++)
{
    const double* Mi = M.ptr<double>(i);
    for(int j = 0; j < M.cols; j++)
        sum += std::max(Mi[j], 0.);
}