trev73

Hello,
I have 3d image data ("pixelData") that I read into a dynamic array (size "countPix"). This data is then loaded into a 3d vector so that I can easily rotate the data. I have included the code below which does seem to do the job. However, it is really long winded with loads of loops. Could someone tell me how to make this code work faster
Thanks in advance.


//images upside down so sort em ...
Uint16 *pixelsort;
pixelsort = new Uint16 [countPix]; //multi dims dinnae work so use vectors to reverse

vector< vector< vector<Uint16> > > my3Ddata;

//generate a 3d space of the correct size
my3Ddata.resize(irows);
for(int i=0;i<irows;i++){
my3DdataIdea.resize(icolumns);
}

for(int i=0;i<irows;i++){
for(int j=0;j<icolumns;j++){
my3DdataIdea[j].resize(iframes);
}
}

//load the space up
for(int i=0;i<irows;i++){
for(int j=0;j<icolumns;j++){
for(int l=0;l<iframes;l++){
my3DdataIdea[j][l]=pixelData[ i + (j*icolumns) + (l*irows*icolumns) ];
}
}
}

//flip top to bottom
for(int i=0;i<irows;i++){
std::reverse(my3DdataIdea.begin(),my3DdataIdea.end());
}

//make standard array for output -- really ugly
for(int i=0;i<irows;i++){
for(int j=0;j<icolumns;j++){
for(int l=0;l<iframes;l++){
pixelsort[i + (j*icolumns) + (l*irows*icolumns)]=my3DdataIdea[j][l];
}
}
}

//write out image
ofstream myBinFile("C:\\***\\test.img", ios::out | ios::binary);

if (! myBinFile){
cout << "Error opening output file" << endl;
return -1;
}

myBinFile.write( (char *)pixelsort, countPix*2 );
myBinFile.close();
delete [] pixelsort;


Re: Visual C++ Language filling and writing multidimensional vectors

Mike Danes

Hmm... using a vector just because of std::reverse seems like overkill to me. If I understand correctly your code the following should do just the same thing without all the memory allocation and copying that using vectors involve:

UInt16 *pixelSort = new UInt16[pixelCount];

for (int i = 0; i < iRows; i++) {

for (int j = 0; j < iColumns; j++) {

for (int l = 0; l < iFrames; l++) {

pixelSort[i + (j * iColumns) + (l * iRows * iColumns)]

= pixelData[(iRows - i) + (j * iColumns) + (l * iRows * iColumns)]; // just using (iRows - i) instead of i to achieve the same effect as reverse

}}}

delete[] pixelSort;





Re: Visual C++ Language filling and writing multidimensional vectors

Marius Bancila

Hmm... using a vector just because of std::reverse seems like overkill to me.

Overkill Isn't that a little harsh to say






Re: Visual C++ Language filling and writing multidimensional vectors

Mike Danes

I was wondering how much time I have left to live until someone kills me for that comment



Re: Visual C++ Language filling and writing multidimensional vectors

rcen

try Boost.MultiArray from
http://www.boost.org/libs/multi_array/doc/index.html






Re: Visual C++ Language filling and writing multidimensional vectors

Marius Bancila

Mike Danes wrote:
I was wondering how much time I have left to live until someone kills me for that comment

Not much, it seems. Wink






Re: Visual C++ Language filling and writing multidimensional vectors

trev73

Thanks for the help.
This is'nt the first time that my programming has been desribed as overkill so I wont get defensive about it. When I get round to it I will download the boost library but I will use Mike Danes' solution in the interim.

Additionally, I tried to write out my 3d vector but ran into problems (hence going back to a 1d array). Is it possible to write 3d vectors to files




Re: Visual C++ Language filling and writing multidimensional vectors

Marius Bancila

Is it possible to write 3d vectors to files

Yes, everything is possible.

See this article about serializing STL containers, and the boost serialization library.






Re: Visual C++ Language filling and writing multidimensional vectors

einaros

Mike Danes wrote:

Hmm... using a vector just because of std::reverse seems like overkill to me. If I understand correctly your code the following should do just the same thing without all the memory allocation and copying that using vectors involve:

int myArray[] = {10, 2, 3, 6, 2, 3, 6, 7};
std::reverse(myArray, myArray + sizeof(myArray) / sizeof(int));

That's why STL is so lovely.






Re: Visual C++ Language filling and writing multidimensional vectors

Brian Kramer

If performance is an issue, perhaps using a raw C-style array can be advantageous.  For graphics intensive code, I would probably feel more comfortable using direct pointers than container classes, but that might just be a stylistic preference since the C++ compiler is pretty darn good about optimizing STL.

Note that the performance Mike's code can be improved 2x by changing the upper-limit of the outer loop to iRows/2.

Also, the original code could have been rewritten to not a new array as a middle step between the original pixel data and the file.  Can't say for sure what difference it would make performance-wise (because writing bytes one-at-a-time to a file should incur an extra cost), but if the graphics is on the order of megabytes large, doubling the application working set just to write a file might be a bad thing.

Brian

 





Re: Visual C++ Language filling and writing multidimensional vectors

trev73

Hello Brian,
thanks for the info. Can you explain how the x2 speed up works
I've had a think but cant get my head around how you can copy one array to another without accessing each point.

Thanks




Re: Visual C++ Language filling and writing multidimensional vectors

Brian Kramer

Sorry, I rescind that suggestion. If you're reversing an array in-place (i.e. not to a different copy), you swap the first and last elements, the second and second-to-last elements, etc. This is length / 2 swaps.