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.);
}