Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ Opencv Mat向量分配到矩阵的一行,最快的方式?_C++_Opencv_Matrix - Fatal编程技术网

C++ Opencv Mat向量分配到矩阵的一行,最快的方式?

C++ Opencv Mat向量分配到矩阵的一行,最快的方式?,c++,opencv,matrix,C++,Opencv,Matrix,将向量分配给循环中的矩阵行的最快方法是什么?我想用向量沿数据矩阵的行填充数据矩阵。这些向量在循环中计算。此循环持续到数据矩阵的所有条目都被这些向量填充为止 目前,我正在使用cv::Mat::at()方法访问矩阵元素并用向量填充它们,但是,这个过程似乎相当缓慢。我尝试了另一种方法,使用cv::Mat::X.row(index)=data\u vector,它工作得很快,但用一些我不理解的垃圾值填充我的矩阵X,为什么 我读到有另一种使用指针的方法(最快的方法),然而,我无法理解。有人能解释一下如何使

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

目前,我正在使用
cv::Mat::at()
方法访问矩阵元素并用向量填充它们,但是,这个过程似乎相当缓慢。我尝试了另一种方法,使用
cv::Mat::X.row(index)=data\u 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;
    }
}
#定义偏移量2
cv::Mat im=cv::imread(“001.png”,cv\u加载\u图像\u灰度);
cv::Mat X=cv::Mat((im.rows-2*偏移量)*(im.cols-2*偏移量),25,cv_64FC1);//保存训练数据。数据包含图像修补程序
cv::Mat patch=cv::Mat(5,5,im.type());//保存裁剪的图像修补程序
typedef cv::Vec Vec25f;
int ind=0;
对于(整数行=0;行<(整数行-2*偏移量);行++){
对于(int col=0;col<(im.cols-2*偏移量);col++){
cv::Mat temp_patch=im(cv::Rect(col,row,5,5));//在每个像素处裁剪一个图像补丁(5x5)
patch=temp_patch.clone();//需要执行此操作,因为temp_patch在内存中不是连续的
patch.convertTo(patch,CV_64FC1);
Vec25f data_vector=patch.reformate(0,1);//使其成为行向量(1X25)。
对于(int i=0;i<25;i++)
{
X.at(ind,i)=数据_向量[i];//目前我使用这种方式(相当慢)。
}
//X_train.row(ind)=patch.reformate(0,1);//尝试了这个方法,但它为数据矩阵分配了一些垃圾值!
ind+=1;
}
}

只需对代码进行几次编辑

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;
    }
}
double*xBuffer=X.ptr(0);
对于(整数行=0;行<(整数行-2*偏移量);行++){
对于(int col=0;col<(im.cols-2*偏移量);col++){
cv::Mat temp_patch=im(cv::Rect(col,row,5,5));//在每个像素处裁剪一个图像补丁(5x5)
patch=temp_patch.clone();//需要执行此操作,因为temp_patch在内存中不是连续的
patch.convertTo(patch,CV_64FC1);
memcpy(xBuffer,patch.data,25*sizeof(双精度));
xBuffer+=25;
}
}

此外,您似乎不需要在patch中进行任何计算,只需提取灰度值,就可以创建与im类型相同的X,并在最后将其转换为double。通过这种方式,您可以memcpy修补程序的每一行,内存中的地址为`unsigned char*buffer=im.ptr(row)+col

,以常规的opencv方式执行:-

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

尚未测试正确性或速度。

根据:

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

//计算正矩阵元素之和
//(假设M是双精度矩阵)
双和=0;
对于(int i=0;i
需要注意的是:patch.convertTo(patch,…)在每次循环运行时都会重新分配内存。创建另一个Mat:
cv::Mat convertedPatch在循环并重用它之前,内存不会被重新分配<如果
temp\u patch.convertTo(patch,…)
(或convertedPatch)是直接使用的,则不必使用code>Clone
。无法100%确定它是否仍然是连续的。如果确实要访问一行,它始终是连续的。
RowMat.copyTo(ImageMat.row(RowIndex));
// 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.);
}