web-dev-qa-db-ja.com

OpenCVでファイルにフロートマットを書き込む方法

私はマトリックスを持っています

Mat B(480,640,CV_32FC1);

浮動値を含む。この行列をメモ帳またはMS WordまたはExcelで開くことができるファイルに書き込んで、内部の値とストレージを確認したい.... imwrite function can save 8-ビットまたは16ビット画像のみ。

これを行うことができたら、あなたの提案をドロップしますか?はいの場合、どのように??

28
Karthik Murugan

純粋なOpenCV API呼び出しの使用:

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

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

ファイル拡張子はxmlまたはymlです。どちらの場合も、簡単に削除/解析できる小さなヘッダーを取得すると、浮動小数点形式のデータにアクセスできます。このアプローチを(ymlファイルを使用して)正常に使用して、データをMatlabおよびMatplotlibに取得しました

データを取得するには:

  1. 任意のエディターでファイルを開きます
  2. 次に、データタグのコンテンツ(ピクセル値)を除くすべてのテキストと数字を抑制します。
  3. 完了したら、ファイルをtxtまたはcsv拡張子で保存し、matlabで開きます(ドラッグアンドドロップが機能します)。

ほらイメージサイズを正しく推測できなかった場合、matlabコマンドラインで結果のマトリックスを再形成する必要があります。

45
sansuiso

あなたは書ける cv::Mat単純なC++ファイル処理を使用してテキストファイルに。

方法は次のとおりです。

#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は、オブジェクトをJSONXML、またはYAML形式でシリアル化(保存)できます。これらのファイルを読み取るには、これらの形式を理解しているエディターを使用するか、OpenCVを使用してこれらのファイルからデータをダウンロード(デシリアライズ)します。これがどのように行われるかの詳細な説明は こちら にあります。つまり、データをxml- fileに保存するには、呼び出す必要があります

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.

JSONまたはYAMLを使用する場合は、拡張子を.jsonまたは.yaml/.ymlに変更するだけです-openCVは自動的に意図を理解します。

重要なのはコマンドです

fs << "cameraMatrix" << cameraM;

文字列"cameraMatrix"はタグ名で、このマトリックスの下にこのマトリックスが保存され、このマトリックスを使用してこのマトリックスをファイル内で後で見つけることができます。

xml形式では、スペースと一部の特殊文字を含むタグ名を使用できないことに注意してください。これは、英数字、ドット、ダッシュ、アンダースコアのみが許可されているためです(詳細はXML仕様を参照) YAMLJSONには次のようなものがあります

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

write binaryを使用します。

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);

次に、MATLAB読み取りサイズで読み取り、形状を変更できます(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

私はこのコードを書きました:

#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;
}
1
Nadav B