2014-09-23 101 views
0

將矢量分配給循環中的矩陣行的最快方法是什麼?我想用矢量沿着它的行填充一個數據矩陣。這些向量是循環計算的。這個循環持續到數據矩陣的所有條目填充那些向量。Opencv Mat矢量分配到一個矩陣的行,最快的方式?

目前我正在使用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; 
    } 
} 
+0

如果您確實想要訪問單個ROW,它始終是連續的afaik。 – Micka 2014-09-23 09:39:17

回答

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。通過這種方式,你可以memcpy的你的補丁的每一行,在內存beeing`無符號字符*緩衝= im.ptr(行)+山坳

+1

有些事情要提到:patch.convertTo(patch,...)將始終在循環的每次運行中重新分配內存。在循環之前創建另一個Mat:'cv :: Mat convertedPatch;'並重新使用它,內存不會被重新分配。如果'temp_patch.convertTo(patch,...)'(或convertedPatch)被直接使用,'Clone'不是必須的 - 如果它仍然連續,那麼不能100%確定。 – Micka 2014-09-23 09:37:56

1

要做到這一點的常規方式OpenCV的,你可以做地址: -

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

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

沒有測試的正確性和速度。