I have been successful in using the gradio.Model3D
in my apps, which have enabled my to render volumetric 3D segmentations of various structures from medical images.
An obstacle is that there did not appear to be any simple way to change the color of the objects rendered in the Model3D
scene. After debugging this further, I realised that changing the color may be more tricky than I thought, which is likely why there is no API-method to do this.
I am converting a binary numpy array to .obj
by first performing marching cubes to get the surface, which I then use to write to .obj
. I believe when writing here, I need to specify Materials
and define colours which I then will use when I write the faces and vertices, however it seems like when trying to do so it did not work.
Below is a snippet of the script that I have been using for converting a binary numpy array to .obj
:
from skimage.measure import marching_cubes
# data : some 3D binary 0-1 numpy array with uint8 type
# Create a material with a red diffuse color (RGB value)
red_material = "newmtl RedMaterial\nKd 1 0 0" # Red diffuse color (RGB)
# extract surface
verts, faces, normals, values = marching_cubes(data, 0)
faces += 1
with open(output, "w") as thefile:
# Write the material definition to the OBJ file
thefile.write(red_material + "\n")
for item in verts:
# thefile.write('usemtl RedMaterial\n') # <- uncommenting this I would expect would change the color, but it does not.
thefile.write("v {0} {1} {2}\n".format(item[0], item[1], item[2]))
for item in normals:
thefile.write("vn {0} {1} {2}\n".format(item[0], item[1], item[2]))
for item in faces:
thefile.write(
"f {0}//{0} {1}//{1} {2}//{2}\n".format(
item[0], item[1], item[2]
)
)
# then I can connect the `.obj` file to the `Model3D` scene:
self.volume_renderer = gr.Model3D(
clear_color=[0.0, 0.0, 0.0, 0.0],
label="3D Model",
show_label=True,
visible=True,
elem_id="model-3d",
).style(height=512)