2014-04-11 22 views
5

Ich bin absolut neu in C++ und der OpenCV-Bibliothek. Ich stöberte durch stackoverflow und durchsuchte auch das Internet, konnte aber keine Antwort auf meine Frage finden.opencv: wie float array als Bild speichern

Wie kann ich ein Float-Array zu einem Bild in C++ speichern? Momentan (als Übung) konvertiere ich das Bild nur manuell in Graustufen (obwohl ich gelesen habe, dass dies mit opencv gemacht werden kann).

Später werde ich einige Filteroperationen und andere Pixeloperationen durchführen. Deshalb möchte ich ein Float-Array (der Größe 512 * 512) verwenden.

Hier ist der Code. Alles was ich weiß ist, dass das float-Array in int oder char oder uint8 oder cv :: Mat umgewandelt werden muss, damit es als .png gespeichert werden kann, aber ich wusste nicht wie.

Alle Hinweise oder Links werden sehr geschätzt.

#include <stdio.h> 
#include <opencv2/highgui/highgui.hpp> 

int main(void) 
{ 
    // load in image using opencv and convert to char 
    cv::Mat myImg = cv::imread("~/Lenna.png", CV_LOAD_IMAGE_COLOR); 
    unsigned char *img = (unsigned char*)(myImg.data); //somehow only works for unsigned char and not for float (SegFault) 

    float *r = new float[512*512]; 
    float *g = new float[512*512]; 
    float *b = new float[512*512]; 
    float *gray = new float[512*512]; 


    // 3*iCol, bc every pixel takes 3 bytes (one for R channel/B channel /G channel). 
    // see http://answers.opencv.org/question/2531/image-data-processing-in-cvmat/ 
    // faster to loop through rows first and then through colums (bc MAT stored in row-major order) 
    uint iPix = 0; 
    for(int iRow=0; iRow<512 ;iRow++){ 
    for(int iCol=0; iCol<512 ;iCol++){ 
     b[iPix] = (float) img[myImg.step * iRow + 3*iCol  ]; 
     g[iPix] = (float) img[myImg.step * iRow + 3*iCol + 1 ]; 
     r[iPix] = (float) img[myImg.step * iRow + 3*iCol + 2 ]; 
     gray[iPix] = (float) 0.0722*b[iPix] + 0.2126*r[iPix] + 0.7152*g[iPix]; 
     iPix++; 
    } 
    } 


    //write image to file (NOT WORKING!) 
    cv::imwrite("~/imgOut.png", (cv::Mat) gray); 
} 
+0

imwrite mit png kann nur mit uchar umgehen. '.exr' vielleicht (wenn Unterstützung dafür zusammengestellt wurde) – berak

Antwort

6

können Sie verwenden

cv::imwrite("~/imgOut.bmp", cv::Mat(512, 512, CV_32FC1, gray)); 

PS: Ich speicherte es stattdessen zu BMP es da funktioniert, für imwrite(), nur 8-Bit (oder 16-Bit ohne Vorzeichen (CV_16U) in Bei Verwendung von PNG, JPEG 2000 und TIFF können Bilder mit einer oder drei Kanälen (mit BGR-Kanalreihenfolge) mit dieser Funktion gespeichert werden.

2

Speichern als BMP hat in meinem Fall nicht geholfen. Ich habe das OpenEXR-Format verwendet. Sie müssen Ihre Dateien mit einer .exr Erweiterung speichern.