I am trying to show MRI volume of brains. Now I want to achieve sth that is shown here: https://www.youtube.com/watch?v=tXJS-ZnBP4k&ab_channel=mahajanimaging. It basically shows a face mesh and a variable slicer that can be adjusted to see the MRI volume in any one specific plane.
I have found and implemented one code that stacks the images from .nii file to produce 3D volume. The code is from here:Volume rendering of a nifti file using pyqtgraph library. · GitHub.
I was able to crop it along the x-axis to view the internal structure which means it is possible to make the slicer function.
However, I am not experienced enough.
I would like some guidance regarding this; mainly to learn how to accomplish this. I am a year undergrad student and I am doing this as a pet project. I would be grateful I can get guidance on how to achieve this using slicer or what algorithm to use.
I have also uploaded my output here as well.
The code I used is as follows:
"""Test GL volume tool with MRI data."""
from pyqtgraph.Qt import QtGui, QtWidgets, QtCore
import pyqtgraph.opengl as gl
import numpy as np
from nibabel import load
FILENAME = r"X:\Braillic\NIFT to Volume\MR_Gd.nii\MR_Gd.nii"
RENDER_TYPE = "translucent"
THR_MIN = 1
THR_MAX = 2000
# =============================================================================
# Get MRI data
nii = load(FILENAME)
data = np.squeeze(nii.get_fdata())
data[data == 0] = THR_MIN
data[data < THR_MIN] = THR_MIN
data[data >= THR_MAX] = THR_MAX
data -= THR_MIN
data /= THR_MAX - THR_MIN
# (optional) Reorient data
data = data[:, ::-1, :]
# Prepare data for visualization
# Cropping code implemented here. Can specify how much to crop and along what axis
# Prepare data for visualization
half_x = data.shape[0] // 2
cropped_data = data[:half_x, :, :]
d2 = np.zeros(cropped_data.shape + (4,))
d2[..., 3] = cropped_data**1 * 255 # alpha
d2[..., 0] = d2[..., 3] # red
d2[..., 1] = d2[..., 3] # green
d2[..., 2] = d2[..., 3] # blue
# (optional) RGB orientation lines
d2[:40, 0, 0] = [255, 0, 0, 255]
d2[0, :40, 0] = [0, 255, 0, 255]
d2[0, 0, :40] = [0, 0, 255, 255]
d2 = d2.astype(np.ubyte)
# =============================================================================
# Create qtgui
app = QtWidgets.QApplication([])
w = gl.GLViewWidget()
w.setGeometry(0, 0, int(1080/2), int(1920/2))
w.setCameraPosition(distance=120, elevation=0, azimuth=0)
w.pan(0, 0, 10)
w.setWindowTitle(FILENAME)
w.show()
# glOptions are 'opaque', 'translucent' and 'additive'
v = gl.GLVolumeItem(d2, sliceDensity=6, smooth=False, glOptions=RENDER_TYPE)
v.translate(dx=-d2.shape[0]/2, dy=-d2.shape[1]/2, dz=-d2.shape[2]/3)
w.addItem(v)
# =============================================================================
def update_orbit():
"""Rotate camera orbit."""
global counter
counter += 1
w.orbit(1, 0) # degree
def stop_and_exit():
"""Stop and exit program."""
app.quit()
print("Finished")
# =============================================================================
if __name__ == '__main__':
# Initiate timer
timer1 = QtCore.QTimer()
timer2 = QtCore.QTimer()
counter = 0
# Connect stuff
timer1.timeout.connect(update_orbit)
timer2.timeout.connect(stop_and_exit)
# Start timer (everytime this time is up connects are excuted)
NR_FRAMES = 360
FRAMERATE = 1000 // 2 # ms, NOTE: keep it high to guarantee all frames # ms, NOTE: keep it high to guarantee all frames
timer1.start(FRAMERATE)
timer2.start((NR_FRAMES * FRAMERATE) + 2000)
# Start program
QtWidgets.QApplication.instance().exec_()