我正在编写一个代码,我在其中读取、成像和处理它并得到一个 Mat of double/float
.我将它保存到一个文件中,稍后,我从该文件中读取它。
当我使用 double 时,1Kx1K 图像需要 8MB 的空间,当我使用 float 时它需要 4MB。所以我想用 float
.
这是我的代码和输出:
Mat data = readFloatFile("file_location");
cout << data.at<float>(0,0) << " " << data.at<double>(0,0);
当我在 DEBUG mode
中运行这段代码时, float 的打印输出是 -0
和 double 给出异常(exception)即 assertion failed
强>。但是当我使用 RELEASE mode
float 的打印输出是 -0
0.832 为 double,这是真实值。
我的问题是为什么我在使用 data.at<float>(0,0)
时无法获得输出以及为什么我在使用 data.at<double>(0,0) in RELEASE mode
时没有出现异常应该是这样吗?
编辑:这是我编写和读取的代码
void writeNoiseFloat(string imageName,string fingerprintname) throw(){
Mat noise = getNoise(imageName);
FILE* fp = fopen(fingerprintname.c_str(),"wb");
if (!fp){
cout << "not found ";
perror("fopen");
}
float *buffer = new float[noise.cols];
for(int i=0;i<noise.rows;++i){
for(int j=0;j<noise.cols;++j)
buffer[j]=noise.at<float>(i,j);
fwrite(buffer,sizeof(float),noise.cols,fp);
}
fclose(fp);
free(buffer);
}
void readNoiseFloat(string fpath,Mat& data){
clock_t start = clock();
cout << fpath << endl;
FILE* fp = fopen(fpath.c_str(),"rb");
if (!fp)perror("fopen");
int size = 1024;
data.create(size,size,CV_32F);
float* buffer= new float[size];
for(int i=0;i<size;++i) {
fread(buffer,sizeof(float),size,fp);
for(int j=0;j<size;++j){
data.at<float>(i,j)=buffer[j];
cout << data.at<float>(i,j) << " " ;
cout << data.at<double>(i,j);
}
}
fclose(fp);
}
提前致谢
最佳答案
首先,你不能使用float
和 double
在一个cv::Mat
因为存储本身只是字节数组。对于 float
的矩阵,此数组的大小将不同和 double
的矩阵.
因此,您必须决定使用什么。
本质上,data.at<type>(x,y)
相当于(type*)data_ptr[x][y]
(注意这不是确切的代码,它的目的是展示正在发生的事情)
编辑:
根据您添加的代码,您正在创建 CV_32F
的矩阵这意味着您必须使用 float
写和读和元素。使用 double 会导致重新解释值,并且肯定会给您一个不正确的结果。
关于断言,我确信在cv::MAT::at<class T>
里面有一种如下代码:
assert(sizeof<T>==this.getDepth());
通常断言仅在 DEBUG
中编译模式,所以这就是为什么你不在 RELEASE
中给出这个错误.
编辑 2:
不考虑问题,但永远不要使用 free()
与 new
或 delete
与 malloc()
.结果可能是一个难以调试的问题。
所以请使用delete[]
用于缓冲。
关于c++ - Visual Studio 发布和调试区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19565788/