2
$\begingroup$

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.

$\endgroup$
  • 1
    $\begingroup$ "Real32" as the second argument reduces the image size by a factor of two. $\endgroup$ – bbgodfrey Feb 7 '16 at 5:57
  • $\begingroup$ @bbgodfrey Thank you bbgodfrey. That works. But the size reduction is not enough. $\endgroup$ – matheorem Feb 7 '16 at 8:25
  • $\begingroup$ See How to place an image inside a notebook, with the minimum memory footprint? $\endgroup$ – user9660 Feb 7 '16 at 8:52
  • 1
    $\begingroup$ Base on the comment by @Louis and my own comment above, small = ImportString[ExportString[test, "JPEG"], "JPEG"] returns the plot in the figure but at a ByteCount of 422720. $\endgroup$ – bbgodfrey Feb 7 '16 at 15:07
  • 1
    $\begingroup$ However, although the image returned by the code in my last comment looks the same as the image in the question, it no longer is 3D and so cannot be processed by such functions as Image3DSlices. So, whether this is a good solution depends on the use to which the compressed image is to be put. $\endgroup$ – bbgodfrey Feb 7 '16 at 15:15
4
$\begingroup$

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.

$\endgroup$
  • $\begingroup$ 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. $\endgroup$ – matheorem Feb 7 '16 at 16:35
  • $\begingroup$ 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 : ) $\endgroup$ – matheorem Feb 7 '16 at 16:46
  • $\begingroup$ 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? $\endgroup$ – matheorem Feb 7 '16 at 16:54
  • $\begingroup$ 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. $\endgroup$ – bill s Feb 7 '16 at 16:55
  • $\begingroup$ Oh, Byte ! This is useful. Thank you bill s $\endgroup$ – matheorem Feb 8 '16 at 0:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.