2013-10-24 127 views
1

我正在編寫一個代碼,在該代碼中,我讀取並進行圖像處理並獲得Mat of double/float。我將它保存到一個文件中,稍後,我正在從該文件中讀取它。Visual Studio版本和調試差異

當我使用double時,它需要的空間是8MB,對於1Kx1K圖像,當我使用float時,它是4MB。所以我想用float

這裏是我的代碼和輸出:

Mat data = readFloatFile("file_location"); 
cout << data.at<float>(0,0) << " " << data.at<double>(0,0); 

當我運行在DEBUG mode這段代碼,浮法打印出來是-0雙給人異常即assertion failed。但是當我使用RELEASE mode時,打印出的浮點數爲-00.832,這是真值

我的問題是爲什麼當我使用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); 
} 

感謝,

+0

添加'readFloatFile()'代碼。 – Alex

+0

我同時添加了讀寫代碼 – smttsp

回答

0

調試&版本之間的區別:

有一個在你的代碼中的錯誤。它只是在發佈模式下不顯示。這就是調試器的用途。調試器會告訴您代碼是否存在任何錯誤/問題,Release只是通過它運行... 此外,編譯器會優化您的代碼以使其運行速度更快,因此調試器會在HD上使用更多大小,因爲您實際上可以調試它。

版本初始化您的未初始化變量爲0.這可能會在不同的編譯器中有所不同。

+0

感謝您的解釋,我添加了讀/寫代碼,您能否檢查錯誤在哪裏? – smttsp

1

首先,您不能在一個cv::Mat中使用floatdouble,因爲存儲本身只是字節數組。對於float的矩陣和double的矩陣,此陣列的大小將不同。

所以,你必須決定你在用什麼。

從本質上講,data.at<type>(x,y)相當於(type*)data_ptr[x][y](注意這是不準確的代碼,其目的是爲了展示發生了什麼)

編輯: 在您添加您創建的CV_32F矩陣代碼的基礎這意味着您必須使用float來編寫和讀取元素。使用雙重原因重新解釋的價值,一定會給你一個不正確的結果。

關於到斷言,我敢肯定,cv::MAT::at<class T>裏邊有一種下面的代碼:

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

通常聲稱僅在DEBUG模式下進行編譯,所以這就是爲什麼你不RELEASE給這個錯誤。

EDIT2: 不是針對問題,但從來沒有與newdelete使用free()malloc()。結果可能幾乎不是一個調試問題。

所以請使用delete[]作爲緩衝區。

+0

我知道我必須選擇,並且我已經選擇了float並進行了相應的編碼,但是我忘記了代碼中的某處出現了雙重部分,並找出了這個問題。 – smttsp

+0

@smttsp assert未在發佈模式下編譯。 – Alex

+0

我明白了,因爲它沒有給出錯誤。我試過它也沒有給出任何例外。我的錯誤怎麼樣?你有什麼想法是什麼讓我得到異常? – smttsp