webentwicklung-frage-antwort-db.com.de

So schreiben Sie eine Float Mat in eine Datei in OpenCV

Ich habe eine Matrix

Mat B(480,640,CV_32FC1);

ich möchte diese Matrix in eine Datei schreiben, die im Editor oder in MS Word oder Excel geöffnet werden kann, um die Werte darin zu sehen und zu speichern .... Schreibfunktion kann 8-Bit oder 16 speichern -bit Bild nur ..

Schreiben Sie uns Ihre Vorschläge, ob dies möglich ist. wenn ja wie ??

25
Karthik Murugan

Verwenden von reinen OpenCV-API-Aufrufen:

// Declare what you need
cv::FileStorage file("some_name.ext", cv::FileStorage::WRITE);
cv::Mat someMatrixOfAnyType;

// Write to file!
file << "matName" << someMatrixOfAnyType;

Die Dateierweiterung kann xml oder yml ..__ sein. In beiden Fällen erhalten Sie einen kleinen Header, den Sie leicht entfernen/analysieren können, und haben dann Zugriff auf die Daten in einem Fließkomma-Format. Ich habe diesen Ansatz (mit Yml-Dateien) erfolgreich angewendet, um Daten in Matlab und Matplotlib zu bekommen

Um die Daten zu erhalten:

  1. Öffnen Sie die Datei mit einem beliebigen Editor 
  2. unterdrücken Sie dann den gesamten Text und die Zahlen mit Ausnahme des Inhalts des Datenetiketts (d. h. der Pixelwerte). 
  3. Wenn Sie fertig sind, speichern Sie Ihre Datei mit einer TXT- oder CSV-Erweiterung und öffnen Sie sie mit Matlab (Drag & Drop funktioniert).

Voilà. Möglicherweise müssen Sie die resultierende Matrix in der Matlab-Befehlszeile umformen, wenn die Bildgröße nicht korrekt ermittelt wurde.

39
sansuiso

Sie können cv::Mat in eine Textdatei schreiben, indem Sie die einfache C++ - Dateibearbeitung verwenden.

So kannst du es machen:

#include <iostream>
#include <fstream>

using namespace std;

void writeMatToFile(cv::Mat& m, const char* filename)
{
    ofstream fout(filename);

    if(!fout)
    {
        cout<<"File Not Opened"<<endl;  return;
    }

    for(int i=0; i<m.rows; i++)
    {
        for(int j=0; j<m.cols; j++)
        {
            fout<<m.at<float>(i,j)<<"\t";
        }
        fout<<endl;
    }

    fout.close();
}

int main()
{
    cv::Mat m = cv::Mat::eye(5,5,CV_32FC1);

    const char* filename = "output.txt";

    writeMatToFile(m,filename);

}
16
sgarizvi

OpenCV kann seine Objekte in den Formaten JSON, XML oder YAML serialisieren (speichern). Sie können beliebige Editoren verwenden, die diese Formate verstehen, um diese Dateien zu lesen, oder Sie können OpenCV verwenden, um Daten aus diesen Dateien herunterzuladen (Deserialisierung). Ausführliche Erklärungen dazu finden Sie hier . Um die Daten in xml- Datei zu speichern, müssen Sie kurz anrufen

cv::FileStorage fs("/path/to/file.xml", cv::FileStorage::WRITE); // create FileStorage object
cv::Mat cameraM; // matrix, which you need to save, do not forget to fill it with some data
fs << "cameraMatrix" << cameraM; // command to save the data
fs.release(); // releasing the file.

Wenn Sie JSON oder YAML verwenden möchten, ändern Sie einfach die Erweiterung in .json oder .yaml/.yml - openCV wird Ihre Absichten automatisch verstehen.

Das Wichtigste ist der Befehl

fs << "cameraMatrix" << cameraM;

der String "cameraMatrix" ist der Tag-Name, unter dem diese Matrix gespeichert wird und mit dem diese Matrix später in der Datei gefunden werden kann.

Beachten Sie, dass das xml-Format die Verwendung von Tag-Namen mit Leerzeichen und einigen Sonderzeichen nicht zulässt, da nur alphanumerische Werte, Punkte, Bindestriche und Unterstriche zulässig sind (Einzelheiten finden Sie unter XML-Spezifikation). In YAML und JSON können Sie etwas ähnliches haben

fs << "Camera Matrix" << cameraM;
2
John Smith

schreibe binäre verwenden:

FILE* FP = fopen("D.bin","wb");
    int sizeImg[2] = { D.cols , D.rows };
    fwrite(sizeImg, 2, sizeof(int), FP);
    fwrite(D.data, D.cols * D.rows, sizeof(float), FP);
    fclose(FP);

dann kannst du in matlabread einlesen und dann umformen (type = single)

fp=fopen(fname);
data=fread(fp,2,'int');
width = data(1); height = data(2);
B = fread(fp,Inf,type);

imageOut = reshape(B,[width,height])';

fclose(fp);
2

Ich habe diesen Code geschrieben:

#include "opencv2/opencv.hpp"

using namespace cv;
using namespace std;

/*
Will save in the file:
cols\n
rows\n
elemSize\n
type\n
DATA
*/
void serializeMatbin(cv::Mat& mat, std::string filename){
    if (!mat.isContinuous()) {
        std::cout << "Not implemented yet" << std::endl;
        exit(1);
    }

    int elemSizeInBytes = (int)mat.elemSize();
    int elemType        = (int)mat.type();
    int dataSize        = (int)(mat.cols * mat.rows * mat.elemSize());

    FILE* FP = fopen(filename.c_str(), "wb");
    int sizeImg[4] = {mat.cols, mat.rows, elemSizeInBytes, elemType };
    fwrite(/* buffer */ sizeImg, /* how many elements */ 4, /* size of each element */ sizeof(int), /* file */ FP);
    fwrite(mat.data, mat.cols * mat.rows, elemSizeInBytes, FP);
    fclose(FP);
}

cv::Mat deserializeMatbin(std::string filename){
    FILE* fp = fopen(filename.c_str(), "rb");
    int header[4];
    fread(header, sizeof(int), 4, fp);
    int cols            = header[0]; 
    int rows            = header[1];
    int elemSizeInBytes = header[2];
    int elemType        = header[3];

    //std::cout << "rows="<<rows<<" cols="<<cols<<" elemSizeInBytes=" << elemSizeInBytes << std::endl;

    cv::Mat outputMat = cv::Mat::ones(rows, cols, elemType);

    size_t result = fread(outputMat.data, elemSizeInBytes, (size_t)(cols * rows), fp);

    if (result != (size_t)(cols * rows)) {
        fputs ("Reading error", stderr);
    }

    std::cout << ((float*)outputMat.data)[200] << std::endl;
    fclose(fp);
    return outputMat;
}

void testSerializeMatbin(){
    cv::Mat a = cv::Mat::ones(/*cols*/ 10, /* rows */ 5, CV_32F) * -2;
    std::string filename = "test.matbin";
    serializeMatbin(a, filename);
    cv::Mat b = deserializeMatbin(filename);
    std::cout << "Rows: " << b.rows << " Cols: " << b.cols << " type: " << b.type()<< std::endl;
}
0
Nadav B