У меня есть матрица
Mat B(480,640,CV_32FC1);
содержащий плавающие значения. Я хочу записать эту матрицу в файл, который можно открыть в блокноте или MS Word или Excel, чтобы увидеть значения внутри и для хранения ….функция записи может сохранить только 8-битное или 16-битное изображение.
Оставьте свои предложения, если это можно сделать ?? если да, то как ??
Использование чистых вызовов 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
Чтобы получить данные:
Вуаля. Возможно, вам придется изменить результирующую матрицу в командной строке 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);
OpenCV может сериализовать (сохранить) свои объекты в JSON
, XML
или же YAML
форматы. Вы можете использовать любые редакторы, которые понимают эти форматы, для чтения этих файлов или использовать OpenCV для загрузки данных (десериализации) из этих файлов. Подробное объяснение как это сделать можно найти Вот. Короче говоря, чтобы сохранить данные в xml
-файл, ты должен позвонить
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
спецификация для деталей), в то время как в YAML
а также JSON
вы можете иметь что-то вроде
fs << "Camera Matrix" << cameraM;
Я написал этот код:
#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;
}