From: James Tursa on
"Jean V.G" <viv3kg(a)gmail.com> wrote in message <5024ba2e-f1a9-4cf6-bf89-8f2b37befec2(a)30g2000yqi.googlegroups.com>...
> I'm writing some software to strip image data from a camera link using
> C++ but my analysis will be done in Matlab. In my C++ code, the image
> data is stored in an array of type float and size 76800 (i.e. image
> size = 320 × 240). The array is defined as 'float pBuffer[76800];'
>
> Currently I'm saving this array into a text file, then import the txt
> file in Matlab, then use function 'reshape' to change to 320 × 240,
> then save the workspace data to a .mat file. My questions are:
>
> 1) What is the best way to save the data in C++ other than txt file as
> I find it takes a lot of space, 669 KB for text file compared to 80 KB
> for final .mat file? I'm saving the data as below:
>
> void saveArray(float* array, int length)
> {
> ofstream output("output.txt");
> for(int i=0;i<length;i++)
> {
> output<<array[i]<<endl;
> }
> }

As others have already replied, writing a binary file will be much faster and use less disk space. It can be easily read into MATLAB with the fread command.

> 2) Can I 'reshape' to get a 2-D array and save as .mat file in C++
> itself? Is there a library for that?

You could code up the physical transpose in your C++ code, but IMO it would be wasted effort since this is so easy to do on the MATLAB side. Also, the MATLAB transpose operator is very fast and will almost certainly execute faster than anything you could write by hand in C++.

Yes, you can write a MAT file directly in your C++ code. You can use the MATLAB API for this (see the External Interfaces section in the doc). You would need to become familar with the mxArray storage type that MATLAB uses. If you need help just post some questions.

Another method that writes MAT files but completely avoids the MATLAB API can be found in a submission by Malcolm McLean here on the FEX:

http://www.mathworks.com/matlabcentral/fileexchange/26731-portable-matfile-exporter-in-c

It uses doubles, so you would have to modify it for floats instead of doubles, but I would advise you only attempt this if you are very familiar with C++ programming. That being said, I would suggest you use the first approach above.

James Tursa
From: James Tursa on
Máday Péter <madapeti(a)gmail.com> wrote in message <5f3a8f97-9180-43ba-882f-ac24ab14410d(a)j21g2000yqh.googlegroups.com>...
>
> ofstream output("output.txt", std::ios::binary);

One usually doesn't name binary files with the .txt extension.

In the future please attach your reply to the original thread. It is much easier for the rest of us to follow the dialog.

James Tursa
From: Jean V.G on
On 26 Mar, 20:14, "James Tursa"
<aclassyguy_with_a_k_not_...(a)hotmail.com> wrote:
> "Jean V.G" <viv...(a)gmail.com> wrote in message <5024ba2e-f1a9-4cf6-bf89-8f2b37bef...(a)30g2000yqi.googlegroups.com>...
> > I'm writing some software to strip image data from a camera link using
> > C++ but my analysis will be done in Matlab. In my C++ code, the image
> > data is stored in an array of type float and size 76800 (i.e. image
> > size = 320 × 240). The array is defined as 'float pBuffer[76800];'
>
> > Currently I'm saving this array into a text file, then import the txt
> > file in Matlab, then use function 'reshape' to change to 320 × 240,
> > then save the workspace data to a .mat file. My questions are:
>
> > 1) What is the best way to save the data in C++ other than txt file as
> > I find it takes a lot of space, 669 KB for text file compared to 80 KB
> > for final .mat file? I'm saving the data as below:
>
> > void saveArray(float* array, int length)
> > {
> >    ofstream output("output.txt");
> >    for(int i=0;i<length;i++)
> >    {
> >            output<<array[i]<<endl;
> >    }
> > }
>
> As others have already replied, writing a binary file will be much faster and use less disk space. It can be easily read into MATLAB with the fread command.
>
> > 2) Can I 'reshape' to get a 2-D array and save as .mat file in C++
> > itself? Is there a library for that?
>
> You could code up the physical transpose in your C++ code, but IMO it would be wasted effort since this is so easy to do on the MATLAB side. Also, the MATLAB transpose operator is very fast and will almost certainly execute faster than anything you could write by hand in C++.
>
> Yes, you can write a MAT file directly in your C++ code. You can use the MATLAB API for this (see the External Interfaces section in the doc). You would need to become familar with the mxArray storage type that MATLAB uses. If you need help just post some questions.
>
> Another method that writes MAT files but completely avoids the MATLAB API can be found in a submission by Malcolm McLean here on the FEX:
>
> http://www.mathworks.com/matlabcentral/fileexchange/26731-portable-ma...
>
> It uses doubles, so you would have to modify it for floats instead of doubles, but I would advise you only attempt this if you are very familiar with C++ programming. That being said, I would suggest you use the first approach above.
>
> James Tursa

>
> As others have already replied, writing a binary file will be much faster and use less disk space. It can be easily read into MATLAB with the fread command.
>

Could you please give me an example c++ code for writing the binary
file?
The following function gives me a '2-D' array of values in a text file
but it still occupies too much disk space.

void saveArray2D(float* array, int length)
{
ofstream output("Image.txt");
for(int ind=0;ind<length;ind++)
{
if (ind%320==0)
{output << endl;}
output<<array[ind]<<'\t';
}
}

When I zip it, the file size decreases by a factor of almost 5 which
means I am saving a lot of redundant information in this. Any help on
how to decrease this disk space would be very much appreciated. I
don't mind if it's not saved in 2D as I can always use Matlab
'reshape' function later on.


> Yes, you can write a MAT file directly in your C++ code. You can use the MATLAB API for this (see the External Interfaces section in the doc). You would need to become familar with the mxArray storage type that MATLAB uses. If you need help just post some questions.

I had a go at using the mxArray but it's not giving exactly what I
want. Firstly, the mat file produced still occupies same disk space as
the .txt file obtained using ofstream etc and secondly I am doing
something wrong somewhere as the data is stored in the first 9600
locations of the mat file. The fact that 76800/9600 = 8 makes me think
I am messing up somewhere with the data types and conversions but I am
not sure where. The first 9600 locations of the array contain wrong
values. See below for code.

MATFile *pmat;
mxArray *pa1 ;
pa1 = mxCreateDoubleMatrix(76800,1,mxREAL);
memcpy((void *)(mxGetPr(pa1)), (void *)pDest, 76800);
const char *file = "mattest.mat";
int status;
pmat = matOpen(file, "w");
status = matPutVariable(pmat, "ImageValues", pa1);

mxDestroyArray(pa1);
matClose(pmat) ;