1

我正在编写一个代码,我在其中读取、成像和处理它并获得一个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 的打印输出为-0double 即给出异常assertion failed。但是当我使用RELEASE mode打印输出 float is-00.832 for double 时,这是 true value

我的问题是为什么我在使用时无法获得输出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);
}

提前致谢,

4

2 回答 2

1

首先,您不能在其中使用floatand ,因为存储本身只是字节数组。对于 的矩阵和 的矩阵,该数组的大小会有所不同。doublecv::Matfloatdouble

所以,你必须决定你正在使用什么。

本质上,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.

EDIT2: 与问题无关,但永远不要使用free()withnewdeletewith malloc()。结果可能是一个很难调试的问题。

所以请delete[]用于缓冲。

于 2013-10-24T12:30:37.540 回答
0

调试和发布的区别:

您的代码中有一个错误。它只是没有出现在发布模式下。这就是调试器的用途。调试器会告诉您代码是否存在任何错误/问题,Release 只是通过它运行...此外,编译器会优化您的代码以更快地运行,因此更小,调试器在您的 HD 上使用更多大小,因为您实际上可以调试它。

Release 将您未初始化的变量初始化为 0。这可能因不同的编译器而异。

于 2013-10-24T12:26:42.857 回答