【发布时间】:2013-09-28 21:24:53
【问题描述】:
我正在用 C++ 做一些计算机视觉方面的工作,处理 JPG 图像。在 C++ 中,我从 Piotr Dollar's Toolbox 调用计算机视觉函数,这些函数最初是为与 Matlab 兼容而设计的。 我试图弄清楚如何从 C++ 文件中快速加载图像,并将它们排列成 Matlab 风格的数据布局。
Matlab 风格的数据布局
由于Piotr's Toolbox 旨在很好地处理 Matlab MEX 文件,因此 Piotr 通常在他的 C++ 函数中使用这种图像数据布局:
image = imread('img.jpg') //in Matlab
//flattened array notation:
image[x*width+ y + channel*width*height]
//unflattened C++ array notation:
image[channel][x][y] //typically: 3-channel color images
C++ 风格的数据布局
C++ 的大多数图像文件 I/O 库(例如 OpenCV imread)在从文件加载 JPG 图像时提供此数据布局:
Mat image = cv::imread("img.jpg") //in C++ with OpenCV
//flattened array notation:
image.data[x*nChannels + y*width*d + channel]
//unflattened C++ array notation:
image.data[y][x][channel]
问题:
- 是否有 C++ 函数(可能来自库)将图像从文件加载到 Matlab 样式的
[channel][width][height]数据布局中? (不一定要用OpenCV。加载图片后,我还是用原始指针。) - 是否有可以快速将 C++ 样式布局转换为 Matlab 样式布局的 C++ 函数?我编写了一个简单的转置函数,但速度很慢:
//this implementation also converts char* to float*, but that's not too important for this question
float* transpose_opencv_to_matlab(Mat img){
assert(img.type() == CV_8UC3);
int h = img.rows; //height
int w = img.cols; //width
int d = 3; //nChannels
float multiplier = 1 / 255.0f; //rescale pixels to range [0 to 1]
uchar* img_data = &img.data[0];
float* I = (float*)malloc(h * w * d * sizeof(float)); //img transposed to Matlab data layout.
for(int y=0; y<h; y++){
for(int x=0; x<w; x++){
for(int ch=0; ch<d; ch++){
I[x*h + y + ch*w*h] = img_data[x*d + y*w*d + ch] * multiplier;
}
}
}
return I;
}
【问题讨论】:
-
cv::split() 可能是最接近的东西
-
只是谷歌搜索似乎有一个
cv::transpose()函数。你试过这个吗?从这个答案:stackoverflow.com/questions/2259678/…. -
@jucestain
cv::transpose可以做到[y][x][channel]到[x][y][channel]。但是,cv::transpose似乎并没有使channel成为最长步幅维度,例如[channel][x][y]。不过,执行cv::split,然后执行cv::transpose可能会起作用。另外,我不确定cv::transpose是否真的对数据进行了置换,或者它是否只是在使用image<>.at(y,x)像素访问接口时更改了索引。 -
澄清一下,您实际上并没有使用 MATLAB,您只是想使用 Piotr 的 C++ 来处理 MATLAB 数据?
-
@chappjc 没错,是的。 :)
标签: c++ matlab opencv image-processing computer-vision