C++ 如何在 OpenCV 中将 Float Mat 写入文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16312904/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to write a Float Mat to a file in OpenCV
提问by Karthik Murugan
I have a matrix
我有一个矩阵
Mat B(480,640,CV_32FC1);
Mat B(480,640,CV_32FC1);
containing floating values..I want to write this matrix to a file which could be opened in notepad or Ms word or Excel to see the values inside and for storage....imwrite functioncan save 8-bit or 16-bit image only..
包含浮动值..我想将此矩阵写入一个文件,该文件可以在记事本或 Ms word 或 Excel 中打开以查看内部和存储的值.... imwrite 函数只能保存 8 位或 16 位图像..
Drop in your suggestions if this could be done?? if yes, how ??
如果可以做到这一点,请提出您的建议?如果是,如何?
回答by sansuiso
Using pure OpenCV API calls:
使用纯 OpenCV API 调用:
// Declare what you need
cv::FileStorage file("some_name.ext", cv::FileStorage::WRITE);
cv::Mat someMatrixOfAnyType;
// Write to file!
file << "matName" << someMatrixOfAnyType;
The file extension can be xmlor yml. In both cases you get a small header that you can easily remove/parse, then you have access to the data in a floating point format. I used this approach successfully (with yml files) to get data into Matlab and Matplotlib
文件扩展名可以是xml或yml。在这两种情况下,您都会获得一个可以轻松删除/解析的小标题,然后您可以访问浮点格式的数据。我成功地使用了这种方法(使用 yml 文件)将数据导入 Matlab 和 Matplotlib
To get the data:
要获取数据:
- open the file with any editor
- then suppress all the text and numbers except the content of the data tag (i.e., the pixel values).
- When done, save your file with a txt or csv extension and open it with matlab (drag-and-drop works).
- 使用任何编辑器打开文件
- 然后抑制除数据标签内容(即像素值)之外的所有文本和数字。
- 完成后,使用 txt 或 csv 扩展名保存文件并使用 matlab 打开它(拖放工作)。
Voilà. You may have to reshape the resulting matrix in matlab command line if it didn't guess correctly the image size.
瞧。如果它没有正确猜测图像大小,您可能必须在 matlab 命令行中重塑结果矩阵。
回答by sgarizvi
You can write cv::Mat
to text file using simple C++ file handling.
您可以cv::Mat
使用简单的 C++ 文件处理写入文本文件。
Here is how you can do it:
您可以这样做:
#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);
}
回答by John Smith
OpenCV can serialize (save) its objects in JSON
, XML
or YAML
formats. You can use any editors, which understand these formats, in order to read these files, or use OpenCV to download data (de-serialize) from these files. Detailed explanation how this is done can be found here. In short, to store the data into xml
-file, you have to call
OpenCV 可以以JSON
、XML
或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.
If you want to use JSON
or YAML
, just change the extension to .json
or .yaml/.yml
- openCV will automatically understand your intentions.
如果您想使用JSON
or YAML
,只需将扩展名更改为.json
or .yaml/.yml
- openCV 将自动理解您的意图。
The important thing is the command
重要的是命令
fs << "cameraMatrix" << cameraM;
the string "cameraMatrix"
is the tag name, under which this matrix will be stored and using which this matrix can be found later in the file.
该字符串"cameraMatrix"
是标签名称,该矩阵将存储在该标签名称下,稍后可以在文件中找到该矩阵。
Note that xml
format will not allow you to use tag names with spaces and some special characters, since only alphanumeric values, dots, dashes and underscores are allowed (see XML
specification for details), while in YAML
and JSON
you can have something like
请注意,xml
format 不允许您使用带有空格和一些特殊字符的标签名称,因为只允许使用字母数字值、点、破折号和下划线(XML
有关详细信息,请参阅规范),而在 in 中YAML
,JSON
您可以使用类似
fs << "Camera Matrix" << cameraM;
回答by Nadav B
I wrote this code:
我写了这段代码:
#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;
}
回答by michael scheinfeild
use 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);
then you can read in in matlab read size and then reshape (type=single)
然后您可以在matlab读取大小中读取然后重塑(类型=单个)
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);