Orthogonal and Oblique MPR Slicing and Fusion

@lassoan @jcfr @pieper,

No no, I don’t expect you to have solutions to all of my dumb mistakes. My apologies for taking up so much of your time. I’m just happy that I can contribute my issues and solutions to the forum to help others.

@lassoan @pieper @Sankhesh_Jhaveri

Hi, I’m trying to dynamically change the window level of images after I push button to change the W/L.

 vtkSmartPointer< vtkResliceImageViewer > riw;

… read in and displayed images.

riw->GetWindowLevel()->SetWindow(400);
riw->GetWindowLevel()->SetLevel(40);|
riw->Render();

This does not display the new W/L immediately but does so when I use the mouse interactively. I.e., after the code is executed there is no change; then when I press the left button down and move the mouse, the new W/L shows.

What is the correct way to accomplish this?

Where does this vtkResliceImageViewer come from? Do you place custom VTK actors in renderers in Slicer?

OK, I think I should be posting this is a general VTK forum. I’m not doing this in Slicer. Sorry. :neutral_face:

1 Like

I just asked this because we have a mechanism to manage rendering requests in Slicer, but there is no such thing in VTK. So, the answer is different in a plain VTK render window than a render window in Slicer.

For quick prototyping it might make sense try a vtkResliceImageViewer, but the current image reslice widgets are not too far from what vtkResliceImageViewer can do, so that may be a good option, too (slightly more work, but has long-term benefits). @Sunderlandkyl is currently working on adding ROI markup widget and in scope of this activity he may move draggable handles out from markups so that other components (such as slice intersection widgets) could utilize it. With some coordination of this effort, it might be not too much development work to make slice intersections and slice view boundaries draggable.

@Sunderlandkyl what do you think? How difficult would be to add markups plane widget-like features to slice and 3D views (translate, rotate, change slice thickness of slices) without redeveloping handles from scratch?

To be clear, you’re saying that currently, Slicer does not have draggable handles for translating, rotating, and changing slice thickness of slice intersection widgets, correct? I could live without having handles for changing thickness; it’s probably easier and more intuitive to set thickness with a slider and/or entering a value in a text box. But for oblique slicing, using translation and rotation handles are most intuitive.

for oblique slicing, using translation and rotation handles are most intuitive.

The existing support is available through the “Reformat” widget, it can enabled using this icon:

image
image

Once enabled, this widget is available in the 3d viewer:

image

@lassoan I don’t think it should be too much work to move the interaction handle pipeline to a more general location. I’ll start looking into it

1 Like

The widgets are draggable in 3D view as @jcfr showed above. In slice views, you can move slice intersection by holding down Shift key and rotate slice intersections by Ctrl-Alt + left-click-and-drag. These mouse&keyboard gestures are very effective and keep the image viewers clean, but not easily discoverable for newcomers, so it may be useful to allow dragging the intersections using visible handles.

This all sounds great. I look forward to seeing it all come together. Thanks.

By the way, the answer to my window/level issue earlier was to use vtkResliceImageViewer’s base class, vtkImageViewer2 methods, SetColorWindow and SetColorLevel.

        vtkSmartPointer< vtkResliceImageViewer > riw;
        riw->SetColorWindow(400);
        riw->SetColorLevel(40);

Using these set the W/Ls immediately :slight_smile:

Hello @lassoan,

Does a VTK reference manual exist that contains examples of how to use functions like vtkImageSlabReslice->SetSlabThickness(thickness); How do I set the thickness and show the change in the thickness reference lines on the image. Here my code and nothing happens …

void QtVTKRenderWindows::SetSlabThickness(double thickness)
{
if (debug_mode) std::cout << "SetSlabThickness = " << thickness << std::endl;
for (int i = 0; i < 3; i++)
{
vtkImageSlabReslice* thickSlabReslice = vtkImageSlabReslice::SafeDownCast(
vtkResliceCursorThickLineRepresentation::SafeDownCast(
riw[i]->GetResliceCursorWidget()->GetRepresentation())->GetReslice());
thickSlabReslice->SetSlabThickness(thickness);
riw[i]->GetRenderer()->ResetCamera();
riw[i]->Render();
}
}

Setting the slab thickness is tricky. I remember that I had trouble figuring out how exactly it has to be specified (I think it is not set in mm but in image space or something like that). Have look at the documentation, if that does not clarify it then fall back to the source code, and if all these fail then ask David Gobbi on the VTK forum.

Hmm… GetSlabThickness returns the thickness in mm, it just seems SetSlabThickness would allow you to change the thickness in the same units. OK. I’ll ask in the VTK forum because this is still a vtkResliceImageViewer quetion.

A post was split to a new topic: Web application based on vtk.js

Hello @jcfr @pieper @lassoan @superlib

I’m very grateful for the amazing help you’ve given us here ay Mayo. No other way would I have gotten through my issues. Your service to the 3D imaging development community is extremely valuable and in the end, helps the patient, and the patient’s wellbeing is always our top priority. We all contribute to saving lives. Thanks you!

1 Like

Thank you! Could you write this (maybe copy, maybe add one sentence for some context) as a topic in this category?

Maybe it is too early to say it is “Success story” yet, so it is up to you, you can post it later, when you managed to actually deploy it. Anyway, happy to see that you are happy.

@jcfr @pieper @lassoan @superlib

Question: Do any of you know Dan Blezek, Brad Erickson or Bill Ryan here at mayo? :slight_smile:

They definitely know @pieper from way back.

Oh yes indeed. Say hello to them all!

Oh OK, yes you’re correct. I’ll remove it for now.