To see the results of this code click here
To convert .nii files quickly to .obj without Freesurfer processing
import plotly.graph_objects as go
import numpy as np
brain = "/content/drive/MyDrive/Data Science/MRI/brain.obj"
# Function to read the .obj file
def read_obj(filename):
vertices = []
faces = []
with open(filename, 'r') as file:
for line in file:
if line.startswith('v '):
vertices.append(list(map(float, line.strip().split()[1:])))
elif line.startswith('f'):
face = [int(i.split('/')[0]) for i in line.strip().split()[1:]]
faces.append(face)
return np.array(vertices), np.array(faces)
vertices, faces = read_obj(brain)
vertices
array([[ 50.666779, -28.194384, -21.338442],
[ 50.121082, -27.810968, -20.198452],
[ 3.378802, -100.455139, 4.870674],
...,
[ -12.782207, 66.600349, 16.896309],
[ -13.962158, 66.610062, 17.925493],
[ -10.211386, 31.746548, -1.28224 ]])
faces
array([[34663, 28109, 28500],
[ 3049, 15445, 37208],
[ 1154, 1, 2],
...,
[50243, 51376, 44998],
[70636, 50891, 69542],
[49939, 70369, 74995]])
# Create a mesh object
pl_mygrey=[0, 'rgb(153, 153, 153)'], [1., 'rgb(255,255,255)']
mesh = go.Mesh3d(
x=vertices[:,0],
y=vertices[:,1],
z=vertices[:,2],
intensity=vertices[:,2],
i=faces[:,0]-1,
j=faces[:,1]-1,
k=faces[:,2]-1,
colorscale=pl_mygrey,
showscale=False
)
mesh.update(cmin=-7,
lighting=dict(ambient=0.18,
diffuse=1,
fresnel=0.1,
specular=1,
roughness=0.05,
facenormalsepsilon=1e-15,
vertexnormalsepsilon=1e-15),
lightposition=dict(x=100,
y=200,
z=0
)
);
# Create a figure and add the mesh object to it
fig = go.Figure(data=[mesh])
camera = dict(
eye=dict(x=5, y=1.5, z=0) # Adjust these values as needed
)
fig.update_layout(
scene=dict(
xaxis=dict(
showbackground=False,
showgrid=False,
zeroline=False,
showticklabels=False,
showline=False,
title='' # Remove the x-axis label
),
yaxis=dict(
showbackground=False,
showgrid=False,
zeroline=False,
showticklabels=False,
showline=False,
title=''
),
zaxis=dict(
showbackground=False,
showgrid=False,
zeroline=False,
showticklabels=False,
showline=False,
title=''
),
camera=camera
),
margin=dict(r=0, l=0, b=0, t=0), # Removes white margins around the plot
paper_bgcolor='rgba(0,0,0,0)', # Set the background color of the paper to transparent
plot_bgcolor='rgba(0,0,0,0)' # Set the background color of the plot to transparent
)
fig.show()
fig.write_html('/content/drive/MyDrive/Data Science/MRI/brain.html')
Subplots containing a variety of different views of the .nii to .obj conversion.
import plotly.graph_objects as go
from plotly.subplots import make_subplots
import numpy as np
face = "/content/drive/MyDrive/Data Science/MRI/nii2mesh_sub-009_T1w.obj"
T7_raw = "/content/drive/MyDrive/Data Science/MRI/nii2mesh_7T.obj"
T7_white = "/content/drive/MyDrive/Data Science/MRI/nii2mesh_c2_KP_anatomical.obj"
T7_gray = "/content/drive/MyDrive/Data Science/MRI/nii2mesh_c1_KP_anatomical.obj"
T7_csf = "/content/drive/MyDrive/Data Science/MRI/nii2mesh_c3_KP_anatomical.obj"
# Default camera settings
camera = dict(
eye=dict(x=3, y=1.5, z=0) # Adjust these values as needed
)
# Function to read the .obj file
def read_obj(filename):
vertices = []
faces = []
with open(filename, 'r') as file:
for line in file:
if line.startswith('v '):
vertices.append(list(map(float, line.strip().split()[1:])))
elif line.startswith('f'):
face = [int(i.split('/')[0]) for i in line.strip().split()[1:]]
faces.append(face)
return np.array(vertices), np.array(faces)
3T Face and 7T raw
face_vertices, face_faces = read_obj(face)
T7_raw_vertices, T7_raw_faces = read_obj(T7_raw)
# Create a mesh object
pl_mygrey=[0, 'rgb(153, 153, 153)'], [1., 'rgb(255,255,255)']
face_mesh = go.Mesh3d(
x=face_vertices[:,0],
y=face_vertices[:,1],
z=face_vertices[:,2],
intensity=face_vertices[:,2],
i=face_faces[:,0]-1,
j=face_faces[:,1]-1,
k=face_faces[:,2]-1,
colorscale=pl_mygrey,
showscale=False
)
T7_raw_mesh = go.Mesh3d(
x=T7_raw_vertices[:,0],
y=T7_raw_vertices[:,1],
z=T7_raw_vertices[:,2],
intensity=T7_raw_vertices[:,2],
i=T7_raw_faces[:,0]-1,
j=T7_raw_faces[:,1]-1,
k=T7_raw_faces[:,2]-1,
colorscale=pl_mygrey,
showscale=False
)
face_mesh.update(cmin=-3.3109,
lighting=dict(ambient=0.18,
diffuse=1,
fresnel=0.1,
specular=1,
roughness=0.05,
facenormalsepsilon=1e-15,
vertexnormalsepsilon=1e-15),
lightposition=dict(x=100,
y=200,
z=0
)
);
T7_raw_mesh.update(cmin=-3.31909,
lighting=dict(ambient=0.18,
diffuse=1,
fresnel=0.1,
specular=1,
roughness=0.05,
facenormalsepsilon=1e-15,
vertexnormalsepsilon=1e-15),
lightposition=dict(x=100,
y=200,
z=0
)
);
# Create a figure and add the mesh object to it
fig = make_subplots(
rows=1, cols=2,
specs=[[{'type': 'mesh3d'}, {'type': 'mesh3d'}]],
horizontal_spacing=0.02 # Adjust the spacing as needed
)
fig.add_trace(face_mesh, row=1, col=1)
fig.add_trace(T7_raw_mesh, row=1, col=2)
axis_settings = dict(
showbackground=False,
showgrid=False,
zeroline=False,
showticklabels=False,
showline=False,
title=""
)
# Add titles as 3D text
fig.add_trace(go.Scatter3d(
x=[np.mean(face_vertices[:,0])],
y=[np.mean(face_vertices[:,1])],
z=[np.max(face_vertices[:,2]) * 1.2], # Position above the highest point of the mesh
text=["Face (from separate 3T)"],
mode="text",
), row=1, col=1)
fig.add_trace(go.Scatter3d(
x=[np.mean(T7_raw_vertices[:,0])],
y=[np.mean(T7_raw_vertices[:,1])],
z=[np.max(T7_raw_vertices[:,2]) * 1.2], # Position above the highest point of the mesh
text=["Skulled stripped (7T)"],
mode="text",
), row=1, col=2)
fig.update_layout(
scene=dict(
xaxis=axis_settings,
yaxis=axis_settings,
zaxis=axis_settings,
camera=camera
),
scene2=dict(
xaxis=axis_settings,
yaxis=axis_settings,
zaxis=axis_settings,
camera=camera
),
margin=dict(r=0, l=0, b=0, t=0),
paper_bgcolor='rgba(0,0,0,0)',
plot_bgcolor='rgba(0,0,0,0)',
showlegend=False
)
fig.show()
fig.write_html('/content/drive/MyDrive/Data Science/MRI/face_raw.html')
7T white and gray matter, and CSF
white_vertices, white_faces = read_obj(T7_white)
gray_vertices, gray_faces = read_obj(T7_gray)
csf_vertices, csf_faces = read_obj(T7_csf)
# Create a mesh object
pl_mygrey=[0, 'rgb(153, 153, 153)'], [1., 'rgb(255,255,255)']
white_mesh = go.Mesh3d(
x=white_vertices[:,0],
y=white_vertices[:,1],
z=white_vertices[:,2],
intensity=white_vertices[:,2],
i=white_faces[:,0]-1,
j=white_faces[:,1]-1,
k=white_faces[:,2]-1,
colorscale=pl_mygrey,
showscale=False
)
gray_mesh = go.Mesh3d(
x=gray_vertices[:,0],
y=gray_vertices[:,1],
z=gray_vertices[:,2],
intensity=gray_vertices[:,2],
i=gray_faces[:,0]-1,
j=gray_faces[:,1]-1,
k=gray_faces[:,2]-1,
colorscale=pl_mygrey,
showscale=False
)
csf_mesh = go.Mesh3d(
x=csf_vertices[:,0],
y=csf_vertices[:,1],
z=csf_vertices[:,2],
intensity=csf_vertices[:,2],
i=csf_faces[:,0]-1,
j=csf_faces[:,1]-1,
k=csf_faces[:,2]-1,
colorscale=pl_mygrey,
showscale=False
)
white_mesh.update(cmin=-3.3109,
lighting=dict(ambient=0.18,
diffuse=1,
fresnel=0.1,
specular=1,
roughness=0.05,
facenormalsepsilon=1e-15,
vertexnormalsepsilon=1e-15),
lightposition=dict(x=100,
y=200,
z=0
)
);
gray_mesh.update(cmin=-3.31909,
lighting=dict(ambient=0.18,
diffuse=1,
fresnel=0.1,
specular=1,
roughness=0.05,
facenormalsepsilon=1e-15,
vertexnormalsepsilon=1e-15),
lightposition=dict(x=100,
y=200,
z=0
)
);
csf_mesh.update(cmin=-3.31909,
lighting=dict(ambient=0.18,
diffuse=1,
fresnel=0.1,
specular=1,
roughness=0.05,
facenormalsepsilon=1e-15,
vertexnormalsepsilon=1e-15),
lightposition=dict(x=100,
y=200,
z=0
)
);
# Create a figure and add the mesh object to it
fig = make_subplots(
rows=1, cols=3,
specs=[[{'type': 'mesh3d'}, {'type': 'mesh3d'}, {'type': 'mesh3d'}]],
horizontal_spacing=0.02 # Adjust the spacing as needed
)
fig.add_trace(white_mesh, row=1, col=1)
fig.add_trace(gray_mesh, row=1, col=2)
fig.add_trace(csf_mesh, row=1, col=3)
axis_settings = dict(
showbackground=False,
showgrid=False,
zeroline=False,
showticklabels=False,
showline=False,
title=""
)
# Add titles as 3D text
fig.add_trace(go.Scatter3d(
x=[np.mean(white_vertices[:,0])],
y=[np.mean(white_vertices[:,1])],
z=[np.max(white_vertices[:,2]) * 1.2], # Position above the highest point of the mesh
text=["White matter (7T)"],
mode="text",
), row=1, col=1)
fig.add_trace(go.Scatter3d(
x=[np.mean(gray_vertices[:,0])],
y=[np.mean(gray_vertices[:,1])],
z=[np.max(gray_vertices[:,2]) * 1.2], # Position above the highest point of the mesh
text=["Gray matter (7T)"],
mode="text",
), row=1, col=2)
fig.add_trace(go.Scatter3d(
x=[np.mean(csf_vertices[:,0])],
y=[np.mean(csf_vertices[:,1])],
z=[np.max(csf_vertices[:,2]) * 1.2], # Position above the highest point of the mesh
text=["CSF (7T)"],
mode="text",
), row=1, col=3)
fig.update_layout(
scene=dict(
xaxis=axis_settings,
yaxis=axis_settings,
zaxis=axis_settings,
camera=camera
),
scene2=dict(
xaxis=axis_settings,
yaxis=axis_settings,
zaxis=axis_settings,
camera=camera
),
scene3=dict(
xaxis=axis_settings,
yaxis=axis_settings,
zaxis=axis_settings,
camera=camera
),
margin=dict(r=0, l=0, b=0, t=0),
paper_bgcolor='rgba(0,0,0,0)',
plot_bgcolor='rgba(0,0,0,0)',
showlegend=False
)
fig.show()
fig.write_html('/content/drive/MyDrive/Data Science/MRI/white_gray_csf.html')