【问题标题】:Visual Studio Release and Debug differenceVisual Studio 发布和调试的区别
【发布时间】:2013-10-24 12:20:11
【问题描述】:

我正在编写一个代码,我在其中读取、成像和处理它并获得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 的打印输出为 -0,而 double 的打印输出为 0.832,这是真正的值

我的问题是为什么我在使用 data.at&lt;float&gt;(0,0) 时无法获得输出,为什么我在使用 data.at&lt;double&gt;(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);
}

提前致谢,

【问题讨论】:

  • 添加readFloatFile() 代码。
  • 我添加了读写代码

标签: c++ opencv floating-point release-mode debug-mode


【解决方案1】:

首先,你不能在一个cv::Mat 中使用floatdouble,因为存储本身只是字节数组。对于float 的矩阵和double 的矩阵,此数组的大小会有所不同。

所以,你必须决定你使用的是什么。

本质上,data.at&lt;type&gt;(x,y) 等价于(type*)data_ptr[x][y](注意这不是确切的代码,其目的是显示正在发生的事情)

编辑: 根据您添加的代码,您正在创建CV_32F 的矩阵,这意味着您必须使用float 来写入和读取元素。使用双重原因重新解释价值,肯定会给你一个不正确的结果。

关于断言,我确信cv::MAT::at&lt;class T&gt;里面有一种如下代码:

assert(sizeof<T>==this.getDepth());

通常断言只在DEBUG 模式下编译,所以这就是为什么你不在RELEASE 中给出这个错误。

EDIT2: 不考虑问题,但切勿将free()newdeletemalloc() 一起使用。结果可能是一个很难调试的问题。

所以请使用delete[]作为缓冲区。

【讨论】:

  • 我知道我必须选择,并且我选择了浮点数并进行了相应的编码,但是我忘记了代码中的双部分并找出了这个东西。
  • @smttsp 断言未在发布模式下编译。
  • 我明白了,因为它没有给出错误。我试过 它也没有给出任何例外。我的错误呢?您知道是什么导致我出现异常吗?
  • (更正) 也不例外,我用float时结果应该是错误的
  • @smttsp 我想,你应该首先检查buffer
【解决方案2】:

调试和发布的区别:

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

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

【讨论】:

  • 感谢解释,我已经添加了读/写代码,请您检查错误在哪里?
猜你喜欢
  • 2010-09-26
  • 1970-01-01
  • 1970-01-01
  • 2011-07-13
  • 2019-10-22
  • 2011-03-09
  • 2010-11-20
  • 2011-07-17
相关资源
最近更新 更多