Segmentation of Mitral valve

Dear @lassoan,

Thanks a lot for the your help. In these days i will try to follow your instructions and i will let you know.

Thank you again

Lorenzo

Dear @lassoan,

I tried Method A and by means of your instructions i was able to run the script you wrote. However when Slicer stops to run the script, my output named ‘ReconstructedVolumeSeq’ represents only a 3D volume, fixed at a precise time instant.

My question is: how can i obtain the 4D volume similar to the one rapresented in the Youtube video you loaded in the last answer?

P.S. i want to specify that the version of Slicer i am using is the 4.13: The ‘unstable version’, downloanded yesterday.

I want to thank you very much for your help

Lorenzo

You can play/pause/browse 4D volume sequences using Sequences module or using the Sequence browser toolbar (if this toolbar is not shown then click on “Sequence browser” in View / Toolbars menu).

Dear @lassoan,

Thank you very much, it works

1 Like

Hi,I have something problem like this.I have a series of images(png format) which were captured by rotating long-axis(one every 1°).And I want to recontruct the mitral valve volume by these images in the 3D slicer.But when I import these images and turn on the volume rendering ,I found something wrong like below.

My question is how can I recontruct the volume by these images like you do this.Can you give me some instruction.I have tried to use the script that you provide but I have something confused about it.

image

I have shared the images to the onedrive.
link:https://1drv.ms/u/s!AifyPV6kzq9OgkNb0qnYN4cRwjCF?e=v8yCCL

Thanks.

You can reconstruct volume from these 2D ultrasound rotational sweep very similarly to the cine MRI above.

Result:

Script that reorganizes the volume into a sequence of frames, adds position&orientation information to each frame, and reconstructs a volume:

# Input 3D volume that contains each frame as a slice
inputFrameVolumeNode = slicer.mrmlScene.GetFirstNodeByClass('vtkMRMLVolumeNode')
imageSpacingMm = 0.2  # this needs to be replaced with the actual spacing
outputSpacingMm = imageSpacingMm * 1.0  # Make the reconstructed volume spacing larger to reduce memory usage and make computations faster

# Get volume size
inputFrameVolume = inputFrameVolumeNode.GetImageData()
extent = inputFrameVolume.GetExtent()
numberOfFrames = extent[5]-extent[4]+1

# Set up frame geometry and rotation
centerOfRotationIJK = [(extent[0]+extent[1])/2.0, extent[2], 0]
rotationAxis = [0, 1, 0]
rotationDegreesPerFrame = 180.0/numberOfFrames

# Convert RGB/RGBA volume to grayscale volume
if inputFrameVolume.GetNumberOfScalarComponents() > 1:
    componentToExtract = 0
    print(f"Using scalar component {componentToExtract} of the image")
    extract = vtk.vtkImageExtractComponents()
    extract.SetInputData(inputFrameVolume)
    extract.SetComponents(componentToExtract)
    extract.Update()
    inputFrameVolume = extract.GetOutput()

# Create an image sequence that contains the frames as a time sequence
# and also contains position/orientation for each frame.
outputSequenceNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLSequenceNode", inputFrameVolumeNode.GetName()+"_frames")
outputSequenceNode.SetIndexName("frame")
outputSequenceNode.SetIndexUnit("")

# This temporary node will be used to add frames to the image sequence
tempFrameVolumeNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLScalarVolumeNode")

for frameIndex in range(numberOfFrames):
    # set current image from multiframe
    crop = vtk.vtkImageClip()
    crop.SetInputData(inputFrameVolume)
    crop.SetOutputWholeExtent(extent[0], extent[1], extent[2], extent[3], extent[4] + frameIndex, extent[4] + frameIndex)
    crop.ClipDataOn()
    crop.Update()
    croppedOutput = crop.GetOutput()
    croppedOutput.SetExtent(extent[0], extent[1], extent[2], extent[3], 0, 0)
    croppedOutput.SetOrigin(0.0, 0.0, 0.0)
    tempFrameVolumeNode.SetAndObserveImageData(croppedOutput)
    # set current transform
    ijkToRasTransform = vtk.vtkTransform()
    ijkToRasTransform.Scale(imageSpacingMm, imageSpacingMm, imageSpacingMm)
    ijkToRasTransform.RotateWXYZ(frameIndex * rotationDegreesPerFrame, *rotationAxis)
    ijkToRasTransform.Translate(-centerOfRotationIJK[0], -centerOfRotationIJK[1], -centerOfRotationIJK[2])
    tempFrameVolumeNode.SetIJKToRASMatrix(ijkToRasTransform.GetMatrix())
    # add to sequence
    added = outputSequenceNode.SetDataNodeAtValue(tempFrameVolumeNode, str(frameIndex))

slicer.mrmlScene.RemoveNode(tempFrameVolumeNode)

# Create a sequence browser node for the reconstructed volume sequence
outputSequenceBrowserNode = slicer.mrmlScene.AddNewNodeByClass(
    'vtkMRMLSequenceBrowserNode', outputSequenceNode.GetName() + '_browser')
outputSequenceBrowserNode.AddSynchronizedSequenceNode(outputSequenceNode)
slicer.modules.sequences.logic().UpdateAllProxyNodes()  # ensure that proxy node is created
outputSequenceProxyNode = outputSequenceBrowserNode.GetProxyNode(outputSequenceNode)
slicer.util.setSliceViewerLayers(background=outputSequenceProxyNode)
slicer.modules.sequences.showSequenceBrowser(outputSequenceBrowserNode)

# Make slice view move with the image (just for visualization)
driver = slicer.modules.volumereslicedriver.logic()
redSliceNode = slicer.util.getFirstNodeByClassByName("vtkMRMLSliceNode", "Red")
driver.SetModeForSlice(driver.MODE_TRANSVERSE, redSliceNode)
driver.SetDriverForSlice(outputSequenceProxyNode.GetID(), redSliceNode)


# Reconstruct
volumeReconstructionNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLVolumeReconstructionNode")
volumeReconstructionNode.SetAndObserveInputSequenceBrowserNode(outputSequenceBrowserNode)
volumeReconstructionNode.SetAndObserveInputVolumeNode(outputSequenceProxyNode)
volumeReconstructionNode.SetOutputSpacing(outputSpacingMm, outputSpacingMm, outputSpacingMm)
volumeReconstructionNode.SetFillHoles(True)
slicer.modules.volumereconstruction.logic().ReconstructVolumeFromSequence(volumeReconstructionNode)
reconstructedVolume = volumeReconstructionNode.GetOutputVolumeNode()
reconstructedVolume.SetName(outputSequenceProxyNode.GetName()+"_recon")
roiNode = volumeReconstructionNode.GetInputROINode()
# Cleanup
slicer.mrmlScene.RemoveNode(volumeReconstructionNode)
# Show reconstruction result
roiNode.SetDisplayVisibility(False)
slicer.util.setSliceViewerLayers(background=reconstructedVolume,fit=True)
2 Likes

Thank you so much ,it works well.

1 Like

Hello,

This community is wonderful and the tutorials and feedback regarding questions have been great. I have a similar question to others in the community working with Cine MRI imaging, but have not had success troubleshooting based on the community responses. I would like to create a segmentation of a specific cardiac phase (time point in the cardiac beat) using cine MRI data.

When I load the cine sequence, it results in (what has been described by other Slicer responses) as the standard way cine MRI files are viewed in Slicer. Is there a way in Slicer to have the program bring up three 2D images in the viewing window at a given time point as happens in a static (non 4D) cross sectional volume? …and then allow me to segment/seedgrow at one time point?

I attempted to follow the advice above including A, B, and C without much luck. I was able to start to Paint after I changed the DICOM settings from Multivolume to Sequence, but I cannot Paint more than one slice at a time (see image below). Some of the visualizations in that last video are impressive, but I cannot replicate them. See the picture below for what I see and please let me know if the recent iterations of Slicer have the tools built in to perform segmentation on cine 4D images.

Appreciate it, -Ray

image

Have you acquired a time sequence of a 3D volume, or a time sequence of a 2D slice?

Have you managed to reconstruct a 3D volume?

It is a 3D cine MRI of the heart with 15 slices in this instance, each with 30 phases. Thank you for your help with this.

Have you managed to reconstruct 3D volume for each phase? If not, how far did you get? What problems did you run into? Could you hate an anonymized data set?

Although segmenting all the phases (time points) within each slice would be useful for creating a moving 3D segmentation, I really only wish to segment the same phase (time point) within each slice to create a segmentated volume of (for example) cardiac diastole. My image above shows my attempt to do this… Slicer would not let me paint outside a single slice. I wish to do this with our cine MRI bc the contrast between the blood pool and tissue is excellent and it would allow segmentations of multiple cardiac cycles for comparison and other post processing.

I can try to send an anonymized data set, but would need to send it to a secure email address. Please DM me at @DrBabyHearts on Twitter. Thanks.

You can send me a direct message here (click on my name and then the message icon).

I’ve added a module to SlicerHeart extension: Reconstruct 4D cine-MRI. This module provides a convenient GUI for the 4D Cartesian volume reconstruction, so Python scripting is no longer needed. It’ll be available in the latest Slicer Preview Release that you download tomorrow or later.

1 Like

Thank you very much… above and beyond as usual. I will let you know how it goes.

1 Like

Hello again Slicer Community, I tried the Reconstruct 4D cine-MRI module shortly after the 4.13 build came out, but noted that I could not load the required extensions. I just tried it again and am having the same issues. Specifically, if I try to download SlicerHeart or IGSIO from the “Install Extensions” tab I get the error: “Failed downloading: https://slicer.packages.kitware…”. Then, if I try to “Restore Extensions” (they are both in this list) and select one or both of these extensions, nothing seems to happen when I click “Install Selected” and if I try to exit, I get the message “Install/uninstall operations are still in progress…” even after I wait about two hours. The “Reconstruct 4D cine-MRI” module is therefore not available for use in my install of 4.13.

Troubleshooting to-date: Uninstalling 4.11 and 4.13, restarting my computer, and re-installing 4.13 did not solve the problem. Being on a different network did not solve it either. When I reverted to 4.11, I can reinstall the extensions, but I obviously get an error message when I try to use the “Reconstruct 4D cine-MRI” module (Error: “This module requires Slicer core version Slicer-4.13…”). I have tried installing 4.13 on three machines, one of which never had any version of 3D Slicer installed on it previously.

Have others had this issue? Is there a fix? Thanks for the help! -Ray

Everything should work well in the latest Slicer Preview Release. Please follow the suggestions here and let us know if they helped.

Thank you. I will try the new build.

Hi,
I am trying to do a reconstruction. I have an ultrasound video (seq.mha file) and I have done a segmentation using the module Segmentation UNet. Now, I am trying to do the reconstruction of the segmentation using the module “IGT Volume Reconstruction”, as you did in this example.

My question is, can I use the same code you used for the mitral valve? Or do you know how can I approach it.