1

If I have a 3D plot, I can get its image data by using ImageData as below:-

Plot1 = Import["ExampleData/CTengine.tiff", "Image3D"];
PlotData1 = ImageData@Plot1;
PlotReconstructed1=Image3D@PlotData1

enter image description here

As you can see, the 3D image of the cheese Plot_Reconstructed1 is reconstructed at the last line. However, if I do same for Anatomy image:-

Plot2 = AnatomyPlot3D[Entity["AnatomicalStructure", "LeftFemur"]];
PlotData2 = ImageData@Plot2;
PlotReconstructed2=Image3D@PlotData2

enter image description here

Plot_Reconstructed2 is a flattened bone, which is not what I want. I want it to be same as plot2. The problem is, when I am trying to extract the image data by using ImageData@Plot2, the data PlotData2 extracted was wrong (i.e. 3 pixe in width only).

How can I fix the error? Many thanks!

H42
  • 3,469
  • 7
  • 17

1 Answers1

3

Take a look at the dimensions of PlotData2:

PlotData2 // Dimensions
{432, 110, 4}

It represents a 4 channel 2D image. What's happening here is the syntax of ImageData is a bit forgiving. Normally it expects an Image or Image3D object, but when given a Graphics or Graphics3D object it will rasterize them to a 2D Image first.

Now when you pass PlotData2 to Image3D, it see a nice 3-tensor of dimensions 432 x 110 x 4 and so it creates a 3D image of those dimensions. Effectively stacking the output of ColorSeparate on top of each other.

Your working example started out as a 3D image and so things just worked.


The only built in way to rasterize an object in 3D is RegionImage, which needs a valid region as input. Luckily we can find such a region for anatomical data:

mr = Entity["AnatomicalStructure", "LeftFemur"]["MeshRegion"];

im = RegionImage[mr]

enter image description here


One caveat here is reg just represents the boundary surface of the femur and so your raster will be hollow:

{Area[mr], Volume[mr]}
{61317.9, 0}
Image3DSlices[im, 100]

enter image description here

If you'd like your raster to be solid, you could first convert your surface mesh into a solid through BoundaryMeshRegion:

imsolid = RegionImage[BoundaryMeshRegion[MeshCoordinates[mr], MeshCells[mr, 2]]];

Image3DSlices[imsolid, 100]

enter image description here

Conversion to BoundaryMeshRegion might not work for every anatomical entity though -- not all have 'watertight' surface mesh representations.

Greg Hurst
  • 35,921
  • 1
  • 90
  • 136