【发布时间】:2015-01-04 15:25:19
【问题描述】:
我一直在尝试实现 MATLAB 和 GNU Octave 中的 im2col 函数。我发现很难理解 Octave 源代码中的实现,所以我在几个矩阵上运行该函数以了解其背后的逻辑。使用它,我使用 OpenCV 在 C++ 中实现了相同的功能,虽然结果似乎相同,但速度非常慢。
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int main(int argc, char** argv)
{
Mat input = Mat::eye(100,100,CV_32FC1);
input.at<float>(1,2) = 2; //Makes it easier to verify the correct solution
int rowBlock = 7;
int colBlock = 5;
int m = input.rows;
int n = input.cols;
int x = m - rowBlock + 1;
int y = n - colBlock + 1;
Mat result = Mat::zeros(1,rowBlock*colBlock,CV_32FC1);
for(int i = 0; i< y; i++)
{
for (int j = 0; j< x; j++)
{
Mat temp2 = input.rowRange(j,j+rowBlock).colRange(i,i+colBlock).t();
temp2 = temp2.reshape(1,1);
vconcat(result,temp2,result);
}
}
result = result.rowRange(1,result.rows);
cout << result << endl;
return 0;
}
有什么方法可以改进吗?我敢肯定我在这里做很多事情效率很低。
【问题讨论】:
-
不知道 im2col 应该做什么,但我猜它的结果将是您示例中的 9024 x 35 矩阵?每个块中的元素是否只是写入结果中的一行?如果是,顺序是什么?结果中行的第一个元素中的块的第一行?紧随其后的第二行?
-
你有一个问题,行和列不直观地与 x 和 y 混合。也许您的问题是,您的外循环在列上,而您的内循环在行上,这违反了数据排序,导致缓存问题。
-
@Micka -
im2col是一个 MATLAB 函数,它采用已知大小的每个可能的像素邻域,将它们转换为堆叠的一维列,并创建一个矩阵,将所有这些列连接在一起。当我想实现一个在 MATLAB 中没有内置等效项的过滤器时,我一直使用它。 -
堆叠邻域的顺序重要吗?我会假设 col-first ordering,但是您的代码给出了 row-first ordering。如果您想要最高效率,这些事情很重要。但是,我发布的答案应该与您发布的结果相同,但应该更快。
-
@Micka - 这不是我的代码或我的帖子,但是是的,它以 col-first 排序。它按列抓取像素邻域,并对像素邻域进行排序,以使列首先展开。因此,如果我们有一个像素邻域为
{{1,2,3}, {4,5,6}, {7,8,9}};,它将变为:{1,4,7,2,5,8,3,6,9};。
标签: c++ matlab opencv image-processing computer-vision