2

I want to make the output of Image3D much smaller. For example

test = Image3D[
  Table[Sin[x + y + z], {x, 1, 100}, {y, 1, 100}, {z, 1, 100}]]

It outputs

enter image description here

We can look at how much memory this image takes

ByteCount[test]/1024/1024.

it takes 7.62976 MB

If I want to generate many such kind of image3D in a notebook for studying. The notebook will become very large.

I notice in the "interactive example" section of "ref/Image3DSlices", there is a delicate image of a human head (NMR??). Which only takes up 0.9 MB.

So I was wondering how to make the output of Image3D smaller?


Update

I also want to know what is the usage of ImageResolution in Image3D? I tried it, but I didn't see any difference after using it.

matheorem
  • 17,132
  • 8
  • 45
  • 115

1 Answers1

4

There are several ways to reduce the size of the image. Perhaps the simplest is to reduce the number of pixels when it is generated. For example, if you do:

test = Image3D[Table[Sin[x + y + z], 
               {x, 1, 100, 3}, {y, 1, 100, 3}, {z, 1, 100, 3}]]

Then you get an image that looks much the same and the memory is 0.3 MB

ByteCount[test]/1024/1024 // N

If you want to make it smaller after the initial image generation (or to make an imported image smaller) then you can downsample:

test = Image3D[Table[Sin[x + y + z], {x, 1, 100}, {y, 1, 100}, {z, 1, 100}]];
test2 = Image3D[Downsample[ImageData[test], 3]]

Again, this is about 0.3 MB.

Both of these decrease the resolution of the image. If your data is real-valued, then you can also reduce the size by storing the image data as integers. For example, the CT scan of the head is a 100x100x100 image that takes up only 1 MB (instead of 7). This is accomplished by storing the image as integers instead of reals. This can be done by changing the second argument of the Image3D:

q = Image3D[test, "Byte"]

This is now about 1 MB.

bill s
  • 68,936
  • 4
  • 101
  • 191
  • Hi, Bill S. Thank you very much for your answer. But I think your approach maybe not what I want. Take the CT human head as an example, I think your method probably can not achieve that effect. I think the head should be generated in high detail first, and then efficiently rasterized and adjust resolution instead of directly deleting data point. I tried your method on my data, it seems not producing good looking quality. – matheorem Feb 07 '16 at 16:35
  • I reconsidered and realized that I actually don't know the basic of rasterization, I am not familiar with image compression, wish you could correct me if I am wrong : ) – matheorem Feb 07 '16 at 16:46
  • I notice in the human head example, the size is 100, that means if it were simply array of pixels, it should be 7MB, am I right? – matheorem Feb 07 '16 at 16:54
  • It would be pretty common to apply some kind of low pass filter (maybe Gaussian) to the image before downsampling. This might help a little, but you can't expect miracles. Reducing the resolution of the image will make it look worse. – bill s Feb 07 '16 at 16:55
  • Oh, Byte ! This is useful. Thank you bill s – matheorem Feb 08 '16 at 00:54