7

I am using openCV and I have a 95,1 mat object of type CV_32F, which I would like to write to a binary file. I am using the code below however I cannot cast a 32F to an char type. Are there any suggestions? I also want to perform the reverse procedure of reading a binary file and storing the values into a mat object of the same type.

try{
    ofstream posBinary;
    posBinary.open("C:/Users/Dr.Mollica/Documents/TSR Datasets/signDatabasePublicFramesOnly/posSamps.bin", ios::out | ios::binary);
    posBinary.write((char *)featureVector, sizeof(featureVector);
}
catch (exception X){ cout << "Error! Could not write Binary file" << endl; }

Also to note, the reason I want to do it in a binary file is I will be writing a large number of these vectors to the file which will be read in to a machine learning algorithm. And from my understanding reading and writing to a binary file is the fastest way possible.

herohuyongtao
  • 49,413
  • 29
  • 133
  • 174
pdm
  • 145
  • 1
  • 2
  • 9

1 Answers1

10

I recommend you to use OpenCV APIs to write cv::Mat to xml or yml files, which you can later read the cv::Mat back from them easily.

For example:

cv::Mat yourMatData;

// write Mat to file
cv::FileStorage fs("file.yml", cv::FileStorage::WRITE);
fs << "yourMat" << yourMatData;

// read Mat from file
cv::FileStorage fs2("file.yml", FileStorage::READ);
fs2["yourMat"] >> yourMatData;

Updated: If you prefer to write/read them to/from binary files, you can first convert cv::Mat to array/vector. And then write the array/vector to files.

To read on, check out Convert Mat to Array/Vector in OpenCV.

Community
  • 1
  • 1
herohuyongtao
  • 49,413
  • 29
  • 133
  • 174
  • 1
    From my understanding reading an writing using binary files is faster. I am going to have a large number of these vectors to be fed to a learning algorithm so I would like to write and read them as fast as possible. – pdm Apr 19 '15 at 02:23
  • 1
    @pdm I also suggest you use xml or yml. It's true that using binary files is faster, but xml or yml is fast enough for most cases. Remember not to test the speed in Visual Studio debugger, using xml or yml for large files in the debugger is VERY VERY slow. If you think xml or yml is too large, you can use xml.gz or yml.gz and OpenCV will automatically compress the file. – delphifirst Apr 19 '15 at 02:43
  • 1
    Thank you I think I will stick with using a xml or yml file but for future reference would it be possible to give an example of how this could be done with a binary file. Thank you again for the speedy responses. – pdm Apr 19 '15 at 02:54
  • @pdm After converting `cv::Mat` to array/vector, you can just write them into files as you normally did, e.g. `posBinary.write((float *)yourArray, sizeof(float)*num);` – herohuyongtao Apr 19 '15 at 03:01
  • @herohuyongtao just as a correction for reading it was just cv::FileStorage fs2("file.yml", FileStorage::READ); fs2["yourMat"] >> yourMatData; – pdm Apr 19 '15 at 03:40
  • @pdm You're right. Corrected now. – herohuyongtao Apr 19 '15 at 04:29
  • @herohuyongtao I think in the link "Convert Mat to Array/Vector in OpenCV", the data in the array is not continuous, which is why we could not directly write data using a simple starting pointer. – user1914692 Aug 20 '15 at 14:55
  • Can we directly read the written .yml file and create a new Mat object (which is similar to the initially written object) with that data? – Samitha Chathuranga Nov 11 '15 at 07:41
  • @SamithaChathuranga It will be simply like: `fs2["yourMat"] >> newMat`. :) – herohuyongtao Nov 11 '15 at 08:35