Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I have a series of axisymmetric images of a jellyfish swimming in fluid. Overlaid on these images are plots of the Lagrangian coherent structures associated with swimming, which highlight the fluid transport and mixing: A plot of the jellyfish bell kinematics and the Lagrangian coherent structures

Since these images are axisymmetric, I was wondering: is there a way that I can revolve a single two-dimensional image about its x axis, so as to create a three-dimensional surface, and then visualize this as a volumetric render? If possible, I'd like to retain the same colors as in the two-dimensional image, as they are significant. As well, I'd like to create a cut-away that removes a fourth of the volume, like in the following image: A three-dimensional plot of the jellyfish bell kinematics and the Lagrangian coherent structures

I'm aware of the following posts: How to show solid bodies using volumetric rendering? and How to create blurred Graphics3D objects?. However, they don't cover a crucial step: how to do the x-axis revolution.

share|improve this question
mathematica.stackexchange.com/questions/11654/… provides the revolution, although I don't really follow what should be drawn in 3D. –  Öskå Aug 11 at 0:05
It would be useful if you could provide the grayscale and the overlaid coloured components separately. –  Szabolcs Aug 11 at 0:47
@Szabolcs: I likely won't be able to post the separated images until tomorrow. I doubt that I'll be able to get physical access to my lab workstation this late in the evening. –  isledge Aug 11 at 1:22

1 Answer 1

up vote 4 down vote accepted

This is not a full solution, but here's a start. It would be useful if you could provide the grayscale and the overlaid coloured components separately because it looks like the grayscale part should control the opacity and the colours need to be added afterwards.

Get the image:

source = Import["http://i.stack.imgur.com/W76CQ.jpg"];

Reflect because we will rotate around the top edge. Negate because white in the original needs to be transparent.

img = ColorNegate@ImageReflect[source, Top -> Bottom]

Aspect ratio:

len = Divide @@ N@ImageDimensions[img]

Interpolating functions, one per channel:

{r, g, b} = ListInterpolation[#, {{0, 1}, {0, len}}] & /@ ImageData /@ ColorSeparate[img];

In a full solution each would be converted to 3D, then combined using ColorCombine.

Rotate to generate 3D data:

step = 0.02;
data = Table[With[{rad = Sqrt[x^2 + y^2]}, If[rad > 1, 0, g[rad, z]]], {x, -1, 1, step}, {y, -1, 1, step}, {z, 0, len, step}]; // AbsoluteTiming

This took about 30 seconds on my machine. Increase step when experimenting to reduce resolution and let the computation finish faster.


Image3D[data, ClipRange -> {All, {0, 1/step}, {0, 1/step}}, ColorFunction -> "RainbowOpacity"]

This is a single channel image, so I used a colour function that makes it easier to see what's going on.

Ideally you'd compute this for the grayscale background, which will serve as the opacity channel, then for the red-blue overlay (red and blue channels), then finally ColorCombine.

share|improve this answer
I just wanted to pass along that this looks absolutely amazing! I'm still interested in seeing what the visualization looks like without a colormap applied to it. As such, I'll make sure and separate out the data tomorrow afternoon/evening and update my post. –  isledge Aug 11 at 1:45
@isledge I'm not going to be here for two days, but the information in this answer should be a good start .. –  Szabolcs Aug 11 at 2:01
Also, out of curiosity, did you use step = 0.02 when making the above image? I ask because it led to a number of jagged artifacts around certain edges (i.stack.imgur.com/l3NJq.jpg). I ultimately changed the variable value to step = 0.01 to improve the overall quality. However, I didn't know if there was some sort of post-processing technique that you were applying. –  isledge Aug 11 at 2:21
@isledge I used 0.02 first, then later changed the image to a 0.01 one. Using such a small step size really requires either a better (faster) implementation, or parallelization. Parallelization has the problem described under "Possible Issues" in the DistributeDefinitions doc page. So at this point it gets a bit non-trivial. If you have trouble, I'll be back in two days to help ... –  Szabolcs Aug 11 at 3:37

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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