在opencv c ++中保存多维矩阵
Posted
技术标签:
【中文标题】在opencv c ++中保存多维矩阵【英文标题】:Saving multi-dimensional matrix in opencv c++ 【发布时间】:2014-09-08 13:25:00 【问题描述】:在 brunocodutra in his answer 的帮助下,我在 opencv、c++ 中创建了一个 3D 浮点矩阵。我的矩阵是1024*1024*N(N不是常数,可能会改变)
当我说const int N = some_number;
我可以说
typedef Vec<float,N> VecNf;
在这个类型定义之后,我可以玩矩阵了。但是,我不希望 N 保持不变,因此我被困在那里。我相信,应该有一些简单的解决方案,但我还找不到。
编辑:我添加了保存矩阵的代码。假设我正确地创建了具有 100 个通道的 3D Mat noise
。
typedef Vec<float,100> Vec100f;
void writeNoise_ND(string filename,Mat noise) throw()
int chans = noise.channels();
int sz = noise.rows;
FILE* fp = fopen(filename.c_str(),"wb");
if (!fp)
perror("out directory is not found\n");
float *buffer = new float[sz];
for(int c = 0; c < chans; c++)
for(int i=0;i<sz;++i)
for(int j=0;j<sz;++j)
buffer[j]=noise.at<Vec100f>(i,j)[c];
fwrite(buffer,sizeof(Vec100f),sz,fp);
fclose(fp);
free(buffer);
有人可以指导我吗?如果它已经被问到问题,对不起。
提前致谢,
【问题讨论】:
您能否详细说明“保存”部分?我想你的意思是声明。 我删除了我的答案,因为这显然不是你想要的。您的问题源于Vec
的大小 N 是编译时常量。在我看来,您可以更改您的类型,以便 Mat::at 返回std::vector
而不是Vec
。 std::vector
的大小在编译时可能未知。另一种方法是编写一个包装器来序列化和反序列化您的 Mat。这样的函数可以在写入数据和每个维度的大小 + 通道数之前重塑 Mat。你需要一个互惠函数来读回它。
我没有得到包装部分。你能详细说明一下吗?是不是有vector<Mat>
而不是N dimensional Mat
?
【参考方案1】:
您的 Mat 似乎是我认为的具有 N 个通道的 2D Mat。就像典型的图像是 2D Mat 3 通道 (RGB)。以下代码将存储所有通道 0,然后是所有通道 1 等,直到通道 N-1:
#include <fstream>
#include <vector>
void writeNoise(string filename, Mat noise)
int chans = noise.channels();
int sz = noise.rows; // should check that noise.cols is == noise.rows
std::ofstream f(filename, ios::out | ios::binary);
if (!f.is_open())
throw std::ofstream::failure("out directory is not found\n");
std::vector<float> buffer(sz);
for(int c = 0; c < chans; c++)
for(int i = 0; i < sz; ++i)
float* p = noise.ptr<float>(i) + c;
for(int j = 0; j < sz; ++j)
buffer[j] = *p;
p += chans;
f.write((const char *) &buffer[0], sizeof(float) * buffer.size());
f.close();
如果你想在 (row = 15, col = 15) 访问通道 15,假设你不知道编译时的通道数(所以你不能使用at()
),你可以这样做这个;
float get(cv::Mat m, int row, int col, int chan)
float* p = m.ptr<float>(row);
return p[col * m.channels() + chan];
/* ... */
cout << get(noise, 15, 15, 15) << endl;
请注意,将get()
用于顺序访问像素是不合适的(因为与我在writeNoise()
中那样访问像素相比,它会非常慢)
【讨论】:
这看起来不错,但为什么f.write((char *) &buffer[0], sizeof(float) * buffer.size());
中有(char *)
?此外,访问元素仍然是一个问题吗?例如,我想打印出noise[15,15,15]th element
,我将如何访问该元素?
write()
接受const char *
参数,而&buffer[0]
是float*
,因此需要显式转换 - 我通过添加const
更正了我的答案。至于访问元素,这不是您的问题的一部分,但我在答案中添加了一种可能的方式。以上是关于在opencv c ++中保存多维矩阵的主要内容,如果未能解决你的问题,请参考以下文章