With Image3D[binaryImageStack]
, you're essentially defining your image using a 3D array of pixels (360x360x17 in your case). And you can't specify non-cubic pixels (it doesn't make much sense, just think about a 2D image).
Update 2
This is a bit of a refinement of the idea presented below. The idea is to pad the image using fixed padding before doing anything to remove border defects:
Image3D[
Binarize@*
Show@*
(ImageMesh[#, BaseStyle -> White, Background -> Black,
AspectRatio -> 1, PlotRangePadding -> -50] &)@*
(ImagePad[#, 50, "Fixed"] &) /@
Image3DSlices[Image3D@binaryImageStack, All, 2]
]
Other than that, it works similarly to the earlier version, but is a bit cleaner.
Update
As noted by @szabolcs in the comments, you can simply resize the image using ImageResize
, which produces something very similar to my original approach. The issue is still the same, i.e. you get more or less sharp steps.
The following demonstrates an idea how to fix this issue: (this is just an initial attempt, so don't expect perfect results)
Image3D[
ColorNegate@Binarize@Show[#, AspectRatio -> 1] &@*
DiscretizeRegion /@
DeleteCases[EmptyRegion[2]][
ImageMesh /@
Image3DSlices[Image3D@binaryImageStack, All, 2]
]
]
The idea is to use the ability of ImageMesh
to connect corners diagonally, providing us a nice interpolation. Since this only works on 2D images, we create slices from our 3D images (along the x or y axis, so that the z axis is in plane). After dropping empty slices (ideally you'd replace them with an empty image), we call DiscretizeRegion
(this seems to improve the results a bit) and convert the slices back to images (this time with a square aspect ratio). As noted before, the result is far from perfect, but might give you a starting point if you need nicer images and can't get more slices.
Rest of original post
What you can do: Calculate your missing images using Interpolation
(assuming calculating them takes too long, otherwise just calculate enough):
binaryImageStack = Binarize@*Slices /@ Range[-4, 4, 0.5]
interpol = Interpolation[binaryImageStack, InterpolationOrder -> 0]
Image3D@Array[interpol, 360, {1, 17}]
(The numbers in the last line are the image dimension (360) and the number of images in the interpolation (17) - alternatively, you could just specify the z-values in Interpolation
)
This yields:
Note that 0th order interpolation gives you sharp steps in the resulting image, which isn't so nice - you might have to play a bit with it. One thing I tried was to not Binarize
the images before the interpolation, but afterwards. (the result looked a bit strange though)