• Welcome to Overclockers Forums! Join us to reply in threads, receive reduced ads, and to customize your site experience!

Same problem, but this time with 3D arrays

Overclockers is supported by our readers. When you click a link to make a purchase, we may earn a commission. Learn More.

CAPiTA

Member
Joined
Mar 7, 2004
Location
Canada
Hey guys, I'm back :p

I'm basically expanding my program to make a different view of the images that I created by creating a "3D cube" where it will take 31 front-view images and make a side-view image e.g.

31 original images that look like this: (front view)

http://www.nlm.nih.gov/research/visible/image/head_mri.jpg

To produce 256 images that look like something like this: (side view)

http://www.qedata.se/bilder/grafik/mri-scan.jpg


Well, that's not really important. I know how I would go by doing that once I get the data into a 3D array, but I'm stuck on the importing part.

Say for instance, I have a set of data that looks like this:

255 0 0 0 0 0 0 255
255 50 50 50 50 50 50 255
255 50 70 70 70 70 50 255
255 50 50 50 50 50 50 255

255 0 0 0 0 0 0 255
255 50 50 50 50 50 50 255
255 50 70 70 70 70 50 255
255 50 50 50 50 50 50 255

255 0 0 0 0 0 0 255
255 50 50 50 50 50 50 255
255 50 70 70 70 70 50 255
255 50 50 50 50 50 50 255

and I want to place each set of data in it's own specific location i.e. the first one would be imagearray[4][8][0], the second [4][8][1] and the third [4][8][2] (kind of in the form [x][y][z])

The problem is that I don't know how I would go about addressing the z value. I have no idea how I would make it so the data from the first table goes into [4][8][0], and the second [4][8][1] etc. Is it simply a modification of my original code (which I owe you guys a million for helping me with)

Code:
for (row = 0; row < ROWS; row++)
	{																	 
		for (col = 0; col < COLS; col++)	// Enters data into array column-by-column and row-by-row
		{														
			fscanf(inf, "%d", &imagearray[row][col]); //Stores image data into the array
		}
	}

So, I was thinking of something like this:

Code:
for (set = 0; set < SETS; set++)
{

for (row = 0; row < ROWS; row++)
	{																	 
		for (col = 0; col < COLS; col++)	// Enters data into array column-by-column and row-by-row
		{														
			fscanf(inf, "%d", &imagearray[row][col][set]); //Stores image data into the array
		}
	}
}

But the part that gets me is how I would tell the program to skip to the next table once the data has been entered into the previous one. Am I missing something really simple here?
 
CAPiTA said:
Hey guys, I'm back :p

I'm basically expanding my program to make a different view of the images that I created by creating a "3D cube" where it will take 31 front-view images and make a side-view image e.g.

31 original images that look like this: (front view)

http://www.nlm.nih.gov/research/visible/image/head_mri.jpg

To produce 256 images that look like something like this: (side view)

http://www.qedata.se/bilder/grafik/mri-scan.jpg


Well, that's not really important. I know how I would go by doing that once I get the data into a 3D array, but I'm stuck on the importing part.

Say for instance, I have a set of data that looks like this:

255 0 0 0 0 0 0 255
255 50 50 50 50 50 50 255
255 50 70 70 70 70 50 255
255 50 50 50 50 50 50 255

255 0 0 0 0 0 0 255
255 50 50 50 50 50 50 255
255 50 70 70 70 70 50 255
255 50 50 50 50 50 50 255

255 0 0 0 0 0 0 255
255 50 50 50 50 50 50 255
255 50 70 70 70 70 50 255
255 50 50 50 50 50 50 255

and I want to place each set of data in it's own specific location i.e. the first one would be imagearray[4][8][0], the second [4][8][1] and the third [4][8][2] (kind of in the form [x][y][z])

The problem is that I don't know how I would go about addressing the z value. I have no idea how I would make it so the data from the first table goes into [4][8][0], and the second [4][8][1] etc. Is it simply a modification of my original code (which I owe you guys a million for helping me with)

Code:
for (row = 0; row < ROWS; row++)
	{																	 
		for (col = 0; col < COLS; col++)	// Enters data into array column-by-column and row-by-row
		{														
			fscanf(inf, "%d", &imagearray[row][col]); //Stores image data into the array
		}
	}

So, I was thinking of something like this:

Code:
for (set = 0; set < SETS; set++)
{

for (row = 0; row < ROWS; row++)
	{																	 
		for (col = 0; col < COLS; col++)	// Enters data into array column-by-column and row-by-row
		{														
			fscanf(inf, "%d", &imagearray[row][col][set]); //Stores image data into the array
		}
	}
}

But the part that gets me is how I would tell the program to skip to the next table once the data has been entered into the previous one. Am I missing something really simple here?

I don't think you're missing anything SIMPLE. You'll need, I believe, to keep explicit "flag" variables to guide your program how to load your next data set.

If you can load the right data by hand, it should be quite possible to have the program load it, as well. You may need to go so far as to have a small three digit struct to represent x, y, z values. Then make an array of those structs, and preload it with where the next data needs to go into your main image array.

Such an array of structs would guide the loading with it's three values.
xyz[0] == (w.x == 4, w.y == 10, w.z == 0 (or whatever), so that's the first value loading location. (w is short for where)

xyz[1] == (w.x == 4, w.y == 10, w.z == 1) whatever.

I'm a tad muddy on this, not having worked with pic's before (except your last post), but this is what comes quickly to mind.

Any help?

Adak
 
Yeah, it helps clarify things. I'm think I might try to import all the data into a 2D array, and then create a 3D array from the 2D array. It's probably slower, but a lot more simple.
Thanks again, Adak.
 
It looks like the set loop should be inside the column loop.
Code:
for (row = 0; row < ROWS; row++)
{																	 
    for (col = 0; col < COLS; col++)	// Enters data into array column-by-column and row-by-row
    {														
        for (set = 0; set < SETS; set++)
        {
            fscanf(inf, "%d", &imagearray[row][col][set]); //Stores image data into the array
        }
    }
}

I'm a little confused about your data format though.
 
Me too :/ I basically have a 5 meg text file (with 31 images crushed together, with the exact same format in my last topic) that needs to be imported into a 3D array. The first 256 rows and 256 columns would be table 0, the 256 rows and 256 columns after the previous table would be table 1, and so on.

I'm pretty damn lost on this one. I tried making a 2D array, but I guess it was too big; it just crashed. It was declared as imagearray[7935][7935]. I was then going to take that 2D array and make the 3D array e.g. [255][255][1] and then [255][255][2] and so on until [255][255][30] So I've decided to scrap that idea.

I'll just keep fiddling around with the code until I can get it to work. The funny thing is that I would have expected some documentation for a task like this. I was thinking that it would be quite common in the programming world to import data into multi-dimensional arrays. I guess I was wrong.
 
mccoyn said:
It looks like the set loop should be inside the column loop.
Code:
for (row = 0; row < ROWS; row++)
{																	 
    for (col = 0; col < COLS; col++)	// Enters data into array column-by-column and row-by-row
    {														
        for (set = 0; set < SETS; set++)
        {
            fscanf(inf, "%d", &imagearray[row][col][set]); //Stores image data into the array
        }
    }
}

I'm a little confused about your data format though.

I believe the "set" is the z parameter. What he's trying to produce is a "slice" of the image, very shallow, but with multiple 2d images. Like an overlay, almost.

Given that, (as I understand it and no guarantee's on that!), the "set" would need to go outside the row and col parameters in a set of nested loops.

If the 2d array's could be numbered by the program, I'm not sure I'd even use a 3d array. Maybe just a series of 2d array's and a very small auxilliary array with just two entries: the current 2d array number being displayed, and the highest 2d array number.

If CAPiTA could post up a larger sample of the data and give us a more detailed example of how it needs to be moved, I'm sure we could assist him more.

In general, I understand the problem, but the specifics are just not clear.
(Which is, I think, that he has "slice" pics from the top or front of a head, now he wants to take those top or front slice pics, and create a side view of that same head.

So if it was a top view, the depth needs to be translated into rows for the side view, and the columns changed into depth, while the rows need to become columns.

For a front view, the depth becomes columns, the columns become depth, and the rows become rows, but now they're moved to the right hand side of the pic array. The more left they were, the more right they will now be.

I think! But I know this is the kind of thing that makes aspirin or excedrin, a big seller! :p

CAPiTA, have you worked out the above relationships for the transformation of data? I think this is the more important part, really.

Coding something first, at least for me, is the tail wagging the dog. YMMV, especially since you have more experience with pics arrays.

Adak
 
Wow! Adak, you seem to understand it a lot better than I do, and you don't even have half the information. You're correct regarding the various slices and the set as the z parameter. It would do exactly as you said. I'm pretty sure that I can code the rest of the program if I manage to import the damn data. I was also hoping to be able to able to use multiple 2D arrays like you said, but the parameters call for a 3D array.

Heh, I'm impressed that you managed to understand the algorithm in such little time and with such little information. It took me 2 days of thinking on how to do the image transposing.. . but you managed to do it in a single post :p

The biggest The biggest thing for me right now is just being able to see that imported data in my program. Once I get that data in, I know for a fact that I can manipulate it at will.
 
Ugh. I'm a complete moron guys. I could have just stuck with my original idea and used 3 for loops

e.g.
Code:
for(z=0;z<31;z++) {
  for(y=0;y<256;y++) {
    for(x=0;x<256;x++) {
	   fscanf(inf, "%d", &myImage[z][y][x]);

    }
  }
}

My friend punched me in the back of the head after telling me how stupid I was :p

But sorry for the waste of your time. I had no idea the for loops would automatically go to the next table after it was done with the first one.
 
You skated that one right under my radar. I just "knew" the problem really was in transforming the data from one view to the other.

And all the time it was just getting a handle on the nested for loops.

Funny stuff! :p

Now I've got to get to work on my elongated ears I pulled out of shape, trying to wrap my head around the data transforming!

Is there a forum for elongated ears? :clap: :clap: :clap:

Adak
 
I've been messing around with the data now, trying to get it to do what I want. I'm having problems with my program crashing once the data is written to the new image file. Basically, I've just picked an arbitrary column from the 3D array to be the reference. I think my logic is correct, but I can't figure out why the blasted thing crashes.

Code:
for (slice = 0; slice < SLICES; slice++)
{
	for (row = 0; row < ROWS; row++)
	{
		for (col = 0; col < COLS; col++)
		{
		                newimage[row][col] = imageArray[slice][row][125];
				fprintf(outf, "%d ", newimage[row][col]);
		}
	}
}

Any ideas?
 
Are SLICES, ROWS and COLS all equal? If not, then I'll bet its the indexing of newimage thats causeing problems. Could you post the part of the code that defines the newimage and imageArray variables. Based on the code you posted, I would expect it to look something like this.

Code:
int imageArray[SLICES][ROWS][COLS];
int newimage[ROWS][COLS];
 
Yes, I defined them all as constants, ROWS and COLS were 256, and SLICES was 31. Turns out now that my function prints out the entire 3D array instead of a 256 x 31 one.

The newimage is in its own function:

Code:
void newview(FILE *outf, int imageArray[SLICES][ROWS][COLS])
{
	int row, col, slice;
	int newimage[ROWS][COLS];
	
	fprintf(outf, "P2\n256 256\n255\n\n"); //Prints file header
	                     	
	for (slice = 0; slice < SLICES; slice++)
	{
	  for (row = 0; row < ROWS; row++)
	    {
		  for (col = 0; col < COLS; col++)
		  {
			  newimage[row][col] = imageArray[slice][row][125];
			  fprintf(outf, "%d ", newimage[row][col]);
		  }
	     }
	}
return;	
	
} // end newview

The image array is declared in Main as:
Code:
int imageArray[SLICES][ROWS][COLS];

The functions are declared at the top with:
Code:
void readImage(FILE *, int [SLICES][ROWS][COLS]);
void newview(FILE *, int [SLICES][ROWS][COLS]);

and callled as:

readImage(inFile, imageArray);
newview(outFile, imageArray);

And once again I appreciate you guys taking the time to help me with my screw-ups.
 
Last edited:
I think you can get rid of the col variable in the last function. If you look at it you loop through for each column and output the same value [slice][row][125]. Instead, I think if you take out the col variable and use the slice variable and also take out the col loop you'll get a single side view slice.

Code:
	for (slice = 0; slice < SLICES; slice++)
	{
	  for (row = 0; row < ROWS; row++)
	    {
		  newimage[row][slice] = imageArray[slice][row][125];
		  fprintf(outf, "%d ", newimage[row][slice]);
		}
	}
 
Back