View Issue Details

IDProjectCategoryView StatusLast Update
0002579Slicer4Core: GUIpublic2018-05-28 09:45
Reportersbillin Assigned Tojcfr  
Status acknowledgedResolutionfixed 
Product VersionSlicer 4.1.1 
Target VersionbacklogFixed in Version 
Summary0002579: Transform Widget: easy enhancements for more user-friendly manual registrations

I am using the Transform Widget to perform a manual registration between two images and there are a few things making this module extremely difficult to use for this purpose:

1) Transform Matrix: Need ability to directly specify matrix values with adequate precision

Although the elements of the transform matrix show several decimal places when updating the transform using the sliders, the matrix elements can only be directly specified up to 2 decimal places. As a result, I am unable to directly specify the matrix value for a known transform.

Note: 2 decimal precision isn't terrible for the translation part of the matrix (column 4), but 2 decimals are by far not accurate enough for the rotation elements. At least 8 decimal places would be good.

2) Translation & Rotation Sliders: Step size is too large

The default step size (1.0) is much to large for fine-tuned manual registration. Because of this, moving the sliders causes jumps in the position rather than smooth position changes. A step size of (0.01) is much better.

It appears that no where in the code is this step size actually specified, so it defaults to 1.0. I changed my Slicer code, to call setSingleStep(0.01) in the constructor of the qMRMLTransformSliders class.

3) Rotation Sliders: enable Min/Max control

The rotation sliders would be more convenient to use if the min/max control were enabled, as is done for the Translation sliders. This allows one to control the sensitivity of the sliders when doing manual registrations.

I tried to enable this in my code by selecting "minMaxVisible" in the options for the RotationSliders in the file:

This enabled the min/max controls for the rotation sliders, however, whenever I moved a rotation slider it caused the corresponding translation slider to move with it! The vice-versa was not true, however (i.e. moving the translation slider did not cause the rotation slider to move). I couldn't figure out the reason for this, and so I'm left without min/max control for Rotation.

Additional Information

My Slicer Version: 4.1.0-2012-09-06 r20936

TagsNo tags attached.


related to 0002584 closedsankhesh Transform Widget: min/max setting changes the translation values when selecting a new transform 
related to 0002480 closedfinetjul When editing the Transform Matrix in the Transforms module, values automatically rounded to 2 decimal places 




2012-12-26 08:47

developer   ~0007584

Tried looking into how the translation sliders change when changing rotation sliders. It seems the bug arises from vtkTransform. When calculating the rotation matrix, the translation values in the transformation matrix are also changed. Need to check using a dummy project using vtkTransform. Will report back more on this later.



2012-12-26 14:35

developer   ~0007586

Last edited: 2013-01-02 10:56

Found the reason:

The reason translation values change when changing rotation values is we post-multiply the transformation matrix. This is done (instead of the usual pre-multiplication) in cases of euler angles where the axes are not fixed but moving. I am not clear why we make this assumption for Slicer. I will check with JC, the original author of this code to get more info.



2013-01-07 07:02

administrator   ~0007617

@sankhesh: Consider discussion with Alex Yarmarkovich, the original author of the code available in Slicer3. See;r2=1434&amp;pathrev=1435



2013-03-12 14:16

administrator   ~0008115

As a hacky workaround you can paste this line into the python console to set the properties of the sliders. Go into the transforms module first to create the widgets and then run this:

for s in findChildren(findChildren(text='LR')[0].parent().parent().parent(),className='qMRMLLinearTransformSlider'): s.singleStep = 0.0001; s.decimals = 5; s.pageStep = 0.001



2013-07-08 12:31

administrator   ~0008908

Fixed 1) in r22152



2013-08-27 11:53

administrator   ~0009639

Resolving this issue since two child issues have been resolved. See 0002480 and 0002584



2014-03-06 05:00

administrator   ~0010841

Closing resolved issues that have not been updated in more than 3 months



2018-05-03 15:00

reporter   ~0015697

May I suggest to re-open this issue? I don't think it's fixed and people have asked about it over the years. I forgot, too, about the incantation that'll do the trick, the one by @pieper above, or

for s in findChildren(className='qMRMLLinearTransformSlider'): s.singleStep = 0.1; s.decimals = 2; s.pageStep = 1

Still, I suggest something like adding two buttons: Stepx10 and Step/10 with an indication of current increment (1mm as default). There's plenty of room on the line with the Min and Max (that still apparently may mess up your transformation if you change them). Rotation is less important in my opinion because default is 0.1 degree and PgUp/PgDn does 1 degree.

(The other annoyance is that the "Identity" button should be "Default" , which should reset to the original loaded transform (or identity). I couldn't find the ticket for that.)



2018-05-04 09:24

administrator   ~0015701

Thanks @nick_silzer - you are right there's a lot of room for improvement here and I like the design you propose. This would be a good task for a new developer wanting to learn while doing something useful.



2018-05-28 01:05

developer   ~0015756

Probably this issue has not got enough attention because manual translation by adjusting a slider is so much worse, compared to registration using landmarks (or automatic intensity-based image registration).

Fundamental issues with slider-based manual registration process:

  • it is an iterative process (you need to adjust multiple sliders several times, while looking at multiple views to check alignment), therefore time required to complete the registration is unpredictable and can be quite significant if both rotation and translation must be aligned
  • assessment of alignment is difficult, as you need to display two images overlaid on top of each other, which makes details hard to see on both images; especially when there is non-rigid deformation between the two images
  • it only supports rigid registration

Landmark registration (Landmark registration module in Slicer core; Fiducial registration wizard module in SlicerIGT) does not have any of the issues: you specify a set of anatomical landmarks (3 or more) on each image or model and you are guaranteed to get the final, correct, rigid or non-rigid registration directly , without the need for any iterations.

You may also use fully automatic intensity-based image registration, which similarly do not have any of the above-described fundamental issues.

Do you have any specific reason to use sliders for manual registration?



2018-05-28 09:45

reporter   ~0015759

@lassoan There are three use cases in my work that depend on manual transforms:

a) Defining a ROI box aligned with an arbitrary plane -- for say MIP inspection of volume of interest or mimicking a thick slice setting.

[If possible I avoid using the reformat widget because of the UI problem that the 3D viewer becomes electrified: in practice, I can't tumble/rotate without messing up carefully placed reformat vectors because I always loose track in my mind of all the current lock and activate mode status of widgets and what -- and in any case it's cumbersome to toggle them on and off. In this sense, manual transforms are frustration-free!]

b) The initial transform for automated registration in case of volumes that are clipped (on purpose, or by clinical use such as CT sinus v. CT head). With a little practice, a rough initial transform is easy to make.

c) Fiddling with calculated transforms and masks; I stuff the calculated transform under a temporary tuner transform or play with it directly.

Issue History

Date Modified Username Field Change
2012-09-28 12:25 sbillin New Issue
2012-09-28 12:25 sbillin Status new => assigned
2012-09-28 12:25 sbillin Assigned To => kikinis
2012-12-08 06:16 kikinis Assigned To kikinis => alexy
2012-12-08 10:13 jcfr Assigned To alexy => sankhesh
2012-12-08 10:14 jcfr Target Version => Slicer 4.3.0
2012-12-10 07:02 sankhesh Relationship added related to 0002584
2012-12-10 07:02 sankhesh Relationship added related to 0002480
2012-12-26 06:58 sankhesh Status assigned => confirmed
2012-12-26 08:47 sankhesh Note Added: 0007584
2012-12-26 14:35 sankhesh Note Added: 0007586
2013-01-02 10:56 sankhesh Note Edited: 0007586
2013-01-07 07:02 jcfr Note Added: 0007617
2013-03-12 14:16 pieper Note Added: 0008115
2013-06-03 05:15 jcfr Status confirmed => assigned
2013-06-03 05:15 jcfr Assigned To sankhesh => jcfr
2013-07-08 12:31 finetjul Note Added: 0008908
2013-08-27 11:53 jcfr Note Added: 0009639
2013-08-27 11:53 jcfr Status assigned => resolved
2013-08-27 11:53 jcfr Fixed in Version => Slicer 4.3.0
2013-08-27 11:53 jcfr Resolution open => fixed
2014-03-06 05:00 jcfr Note Added: 0010841
2014-03-06 05:02 jcfr Status resolved => closed
2018-05-03 15:00 nick_slizer Note Added: 0015697
2018-05-04 09:24 pieper Note Added: 0015701
2018-05-08 20:48 jcfr Status closed => acknowledged
2018-05-08 20:49 jcfr Fixed in Version Slicer 4.3.0 =>
2018-05-08 20:49 jcfr Target Version Slicer 4.3.0 => backlog
2018-05-28 01:05 lassoan Note Added: 0015756
2018-05-28 09:45 nick_slizer Note Added: 0015759