I’m exporting multiple models for my skull anatomy models. I cannot get Slicer to export my models with their colors. Anyone know how to get the models exported with their colors? I have tried exporting them in several different file formats with no success.
here are the models in 3D slicer with their original colors:
Are you certain those aren’t the correct colors? It looks to me like they are just different lighting parameters. Can you try adjusting the lights? Can you give some examples of that numbers changed?
I have tried adjusting the lights. It’s definitely a change in color. For example, in Slicer I set the color of the frontal (the light blue bone) to #7de8e1, and then when I import the file into Blender the hex code has changed to #709694
The Openanatomy extension in glTF gets me closer to the true colors, but they are still distorted. Now my frontal has a hex code of #90F5F0, still not the original code I assigned in slicer. Here’s a screenshot:
I should add for these models, the hex codes are important. These models are part of a collection where the colors of the bones need to be comparable between models. These are models I have made over the years in different software - first Avizo, then VGStudio, and now Slicer.
If you want to try a workaround you could force boostGouraudColor to be False in this line:
The module file would be someplace like ~/Downloads/Slicer-5.4.0-linux-amd64/slicer.org/Extensions-31938/SlicerOpenAnatomy/lib/Slicer-5.4/qt-scripted-modules/OpenAnatomyExport.py and you could just restart the application after editing that line to be something like self.addModelsToRenderer(inputShFolderItemId, boostGouraudColor=False)
@jaimigray Your use case sounds valid, so probably it would be good to expose an advanced option in the GUI to disable this feature. @mhalle@lassoan
@jaimigray you can also enable developer mode (under application settings->Developer), and then when you restart the application, you will see these buttons for Python scripted modules like Open Anatomy. You can then click Edit and make the change @pieper suggested, save and hit restart.
Matching model appearance between applications is very hard, because they use different lighting models with potentially very different parametrization. I implemented color “boosting” by experimentation as described here:
This may be inaccurate, if someone has time to dig into how to better convert colors between different lighting models then it would be awesome. For example, here someone seems to have an idea of a better approximation (but maybe that only addresses RGB/sRGB color space and not Gouraud/PBR lighting model difference): glTF - setting colors - baseColorFactor - Stack Overflow
For better consistency of colors between Slicer and Blender you can set shading to PBR in models module in Slicer. We then don’t modify the RGB color codes in OpenAnatomy export. Overall appearance will be still very different in Slicer and Blender because default lights in the scene are very different in the two applications.
You can choose to encode some information in various color fields, but colors may not remain exactly the same when you import/export into a software or convert to a different mesh file format. Most mesh file formats allow you to define parts of a mesh in more robust ways, I would recommend relying on those mechanisms instead of color similarity.
@mhalle has been working a lot on storing anatomical atlases, maybe he can give you further advice.
What about writing per vertex color instead of a material file? That seems to give me the most consistency between applications for models that just need solid color.
Is there a way to do this in Slicer? This is how I color my models in VGStudio (as PLY files), and the colors are always consistent when exported into other software
I don’t think standard OBJ can store per-vertex color, but for for example PLY can, so a PLY option could be added to OpenAnatomy exporter if that solved some problem.
However, if the main need is to identify parts of a mesh then it is more robust to rely on materials in OBJ files (one material for each segment, as we do it now) or use mesh hierarchy in glTF files. Color component values may change because the color space of the application may not be the same as the color space of the file (and there is often not even an accurate correspondence of colors between different color spaces).
How do you use the per-vertex colors? In what software, for what purpose? Only rendering or also for processing? Do you need to show/hide individual structures?
It would take maybe 20-30 lines of Python code in the OpenAnatomy exporter to add a vertex color array and set a different value for each segment. It could be a good task for someone who wants to learn a bit of VTK and Python scripting (probably chatgpt/bingchat can generate the code and it would just need to be copied into the Slicer module).
I use the per-vertex colors mostly for my Sketchfab models, see here: Colors of Skull Anatomy - A 3D model collection by Blackburn Lab (@ufherps) - Sketchfab
These models are made up of multiple mesh files. I import the models into Blender to do any clean-up and to animate them, and then Blender has a handy Sketchfab plugin to upload directly to Sketchfab. Without the vertex colors (or material colors), extra steps are required to color the meshes in Blender. It would be a big time-saver if I could just keep the original colors on the mesh from the segmentation software, like VGStudio allows.
VGstudio also lets me write per-vertex colors onto meshes using volume renders, allowing me to create meshes as per-vertex colored PLY files. This feature is really useful for creating meshes with density heat-maps, or for creating some nice shading effects that can make the meshes look more bone-like
It sounds like the feature you are looking for is provided by “Probe volume with model” module. It can write the values of the input volume directly into the mesh.
I tried this, but I don’t think the chosen transfer function for volume rendering has any impact on the outcome of the model generated. There is a texture, but that texture is independent of the transfer function specified.