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 の出力は で-0あり、double は例外、つまり を返しassertion failedます。しかし、RELEASE modefloat の出力を使用する-0、 double の場合は 0.832 になり、これは 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()withnewまたはdeletewith を使用しないでmalloc()ください。その結果、デバッグが困難な問題になる可能性があります。

delete[]緩衝材としてご利用ください。

于 2013-10-24T12:30:37.540 に答える