需要一种更快的方法将 cv::Mat 转换为一维向量形式
Posted
技术标签:
【中文标题】需要一种更快的方法将 cv::Mat 转换为一维向量形式【英文标题】:Need a faster way to convert a cv::Mat into 1 dimensional vector form 【发布时间】:2014-07-28 18:28:36 【问题描述】:我有一个 for 循环,它接受一个 n x n 维度的 OpenCV Mat 对象,并返回一个 n^2 x 1 维度的 Mat 对象。它可以工作,但是当我对该方法进行计时时,它需要 1 到 2 毫秒。由于我调用此方法 3 或 400 万次,因此我的程序运行大约需要一个小时。我引用的一篇研究论文表明,作者能够生成一个具有相同功能的程序,该程序只需几分钟即可运行,而无需并行运行任何线程。在对每一段代码进行计时后,唯一需要 >1 ms 的部分是以下方法。
static Mat mat2vec(Mat mat)
Mat toReturn = Mat(mat.rows*mat.cols, 1, mat.type());
float* matPt;
float* retPt;
for (int i = 0; i < mat.rows; i++) //rows
matPt = mat.ptr<float>(i);
for (int j = 0; j < mat.row(i).cols; j++) //col
retPt = toReturn.ptr<float>(i*mat.cols + j);
retPt[0] = matPt[j];
return toReturn;
有什么方法可以提高此方法将 n x n 矩阵转换为 n^2 x 1 矩阵(或 cv::Mat 表示向量)的速度?
这解决了@berak 的大部分问题,它现在运行得更快了。但是在某些情况下,如下所示,垫子不是连续的。知道如何在连续垫子中获得投资回报率吗?
我的方法不是这样的:
static Mat mat2vec(Mat mat)
if ( ! mat.isContinuous() )
mat = mat.clone();
return mat.reshape(1,2500);
问题发生在:
Mat patch = Mat(inputSource, Rect((inputPoint.x - (patchSize / 2)), (inputPoint.y - (patchSize / 2)), patchSize, patchSize));
Mat puVec = mat2vec(patch);
【问题讨论】:
制作一个 ROI 的 clone() 将使它连续,尽管这又是一个昂贵的操作。mat2vec(patch.clone())
未测试,但我认为Mat patch = Mat(inputSource, Rect((inputPoint.x - (patchSize / 2)), (inputPoint.y - (patchSize / 2)), patchSize, patchSize));
应该是Mat patch = inputSource(Rect((inputPoint.x - (patchSize / 2)), (inputPoint.y - (patchSize / 2)), patchSize, patchSize));
,如果需要,最后带有 .clone()
【参考方案1】:
假设你的 Mat 中的数据是连续的,Mat::reshape() 获胜。
而且几乎是免费的。只有行/列得到调整,没有内存移动。即,mat = mat.reshape(1,1)
将创建一个一维浮点数组。
【讨论】:
【参考方案2】:在 OpenCV 3.2 中看到这个,但现在函数是 mat.reshape(1)
。
【讨论】:
以上是关于需要一种更快的方法将 cv::Mat 转换为一维向量形式的主要内容,如果未能解决你的问题,请参考以下文章
如何将 cv::Mat 类型从 CV_16UC1 转换为 CV_8UC1
使用 OpenCV 在 C++ 中将 std::list 转换为 cv::Mat