Как написать Float Mat в файл в OpenCV
У меня есть матрица
Mat B(480,640,CV_32FC1);
содержащих дробные значения..Я хочу записать эту матрицу в файл, который можно открыть в блокноте или Ms word или Excel, чтобы увидеть значения внутри и для хранения....функция imwrite смогите Сохранить Изображение 8 битов или 16 битов только..
Drop в ваших предложениях, если это можно сделать?? если да, то как ??
4 ответов
используя чистые вызовы API OpenCV:
// 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
получить данные:
- открыть файл с помощью любого редактора
 - затем подавить весь текст и числа, за исключением содержимого тега данных (т. е. значений пикселей).
 - когда закончите, сохраните файл с расширением txt или csv и откройте его с помощью matlab (drag-and-drop works).
 
вуаля. Возможно, вам придется изменить полученную матрицу в командной строке matlab, если она неправильно угадала размер изображения.
можно писать 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);
}
используйте запись двоичного файла:
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);
Я написал этот код:
#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;
}