[Insight-developers] Centered Transforms

Lorensen, William E (Research) lorensen at crd.ge.com
Wed Mar 9 18:02:10 EST 2005


Maybe we need a better name then. Or...

I think, since gcc3.4, we do allow subclasses to explicitly set the ivars using this.

this->m_Offset = foo;

is now OK. I think this is better than a non-standard method name.

Bill 



-----Original Message-----
From: Stephen R. Aylward [mailto:aylward at unc.edu]
Sent: Wednesday, March 09, 2005 5:52 PM
To: Lorensen, William E (Research)
Cc: Miller, James V (Research); Insight-developers (E-mail)
Subject: Re: [Insight-developers] Centered Transforms


I struggled a bit with this...I welcome any suggestions....

Here's the story...

Transforms have public member functions SetOffset, SetCenter, etc. 
These functions do more than set the corresponding private member variable.

However, derived classes need to be able to change the private member 
variable without doing the other stuff that is being done in SetOffset 
and SetCenter.

So, I made the protected functions Set_M_Offset, Set_M_Center - to 
change the m_Variable without doing the other stuff.   I know the naming 
convention isn't 100% standard, but since it is a protected member 
function, I felt that calling it Set_M_Center provided clarity when a 
SetCenter was already present, and as a protected function, the users 
wouldn't see this inconsistency (it is kind of a variable-name 
consistency even if it is a function name inconsistency).   Yup...I bet 
there is a better option....

Also, I thought that we had decided to use protected member functions in 
ITK to get/set private variables, and to not use "this->m_Variable".  Of 
course, it now seems like there are some speed issues in gcc3.3 when 
using such a function call.   Again,  I am open to suggestions....

Also, I tried very hard to keep the API consistent - all of our 
external-to-itk code that heavily uses ITK still compiled and ran 
without modification using the changes I just made to ITK.   Also, all 
of the tests ran without modification (except where some had bugs in 
them).   Please let me know if I have missed something.

Thanks for your patience with these changes.  If you look at the 
transform classes, I hope you will find that they are greatly 
simplified, have consistent concepts, and actually work :)  We should 
also have better testing coverage...

Thanks,
Stephen


Lorensen, William E (Research) wrote:
> Stephen,
> I noticed in the new code in MatrixOffsetTransformBase, there there are nethod like:
> Set_M_Offset, Set_M_Translate, ...
> 
> This naming is not consistent with itk style. Did you mean
> SetOffset, SetTranslate, ... ?
> 
> Bill
> 
> 
> -----Original Message-----
> From: insight-developers-bounces at itk.org
> [mailto:insight-developers-bounces at itk.org]On Behalf Of Stephen R.
> Aylward
> Sent: Monday, March 07, 2005 4:59 PM
> To: Miller, James V (Research)
> Cc: Insight-developers (E-mail)
> Subject: Re: [Insight-developers] Centered Transforms
> 
> 
> Hi,
> 
> Yup - the terms center, offset, and translation aren't my favorite 
> either (I didn't pick them, I am following the ITK standard)...it was 
> decided quite some time ago to call "translation" the component of the 
> transform that defines the shift to be applied after rotation about a 
> center of rotation.   The offset vector defines the amount of shift to 
> apply after a rotation when a center of rotation has not used.
> 
> Center (of rotation) must be maintained since it is not specifically 
> being optimized during registration.  That is, it must be stored since 
> it isn't being passed.
> 
> Furthermore, since center isn't being optimized, rotation can only 
> decoupled from shifting during registration if the optimizers update 
> translation instead of offset during registration.   So, translation is 
> a parameter of the optimizer instead of offset.
> 
> So, the optimizers drove the addition of the concepts of center of 
> rotation and translation in the transforms.
> 
> Having a center of rotation greatly simplifies certain registration 
> optimizations compared to image alignment when rotation were limited to 
> being about the origin.  ITK began years ago by having registration 
> optimization temporarily move the origin of an image to the center of 
> the image during registration, and then move the origin back after 
> registration, but that really is a hack - the origin really shouldn't 
> move during registration...so, we added the concept of a center of 
> rotation...
> 
> I hope this clarifies things a bit.   I don't like classes that have 
> redundant/linked variables that must be kept in sync, but there is no 
> way that Bill would let us remove the Get/SetOffset functions :)   And, 
> actually, I don't think we should either... :)
> 
> So this is the rock and the hard place that we are between...   With 
> that in mind...any ideas/suggestions?   I've been working with the 
> transforms quite a bit - switching between them within a single 
> application and composing them in chains while using center of rotation. 
>    This has revealed some inconsistencies in how offset and translation 
> are handled (not surprisingly) as well as inconsistencies in their APIs. 
>    This lead to the development of the MatrixOffsetTransform base class 
> that we are adding to make sure all of the affine, similarity, rigid, 
> translation, and rotation transforms handle these concepts consistently. 
>    I just want to make sure we all agree on which is the lessor of the 
> evils :)
> 
> Sorry for the long email...just looking for someone I can share the 
> blame with when we ultimately pick a standard... :)   Anyone.... 
> Anyone... :)
> 
> Thanks,
> Stephen
> 
> 
> Miller, James V (Research) wrote:
> 
>>I don't think I am going to be of much help since I do not 
>>understand the difference between an "offset" and a "translation".
>>
>>Skimming through the headers, it looks like transforms like the 
>>affine transform are defined by equations
>>
>>y = Ax + b
>>
>>where A is the "matrix" stored in the transform and "b" is the offset.
>>
>>To me, it looks like the only things that need to be STORED are the
>>matrix and offset.  With the "center" and "translation" being computations
>>based on A and b.  Conversely, you could argue that one would want to
>>set the center and translation. In doing so, the matrix A and offset b
>>would have to be updated. However, I would favor not storing the center and
>>translation if there are truly secondary parameters completely defined by
>>A and b.
>>
>>
>>
>>
>>
>>-----Original Message-----
>>From: insight-developers-bounces at itk.org
>>[mailto:insight-developers-bounces at itk.org]On Behalf Of Stephen R.
>>Aylward
>>Sent: Monday, March 07, 2005 1:15 PM
>>To: Insight-developers (E-mail)
>>Subject: [Insight-developers] Centered Transforms
>>
>>
>>
>>When someone updates the center of rotation or matrix for a transform, 
>>either the translation or the offset must be implicitly updated for 
>>consistency.   This implicit update is necessary since translation and 
>>offset are related to one another via the transform matrix and the 
>>center of rotation.
>>
>>My vote is that the offset should be implicitly updated when the center, 
>>matrix, or translation is set by the user; and that translation should 
>>only be implicitly updated when the offset is set by the user.
>>
>>That is, we assume that most people will set the translation component 
>>and not the offset component - this assumption is consistent with the 
>>behaviour of our optimizers which use translation as a parameter during 
>>optimization, not offset.
>>
>>As a result, the following code will be valid:
>>
>>Using an Euler3DTransform called transform...
>>
>>CenterType center;
>>center.Fill(10);
>>
>>TranslationType translation;
>>translation.Fill(0);
>>
>>transform.SetRotation( 1, 2, 3 );
>>transform.SetTranslation( translation );
>>transform.SetCenter( center );
>>
>>OutputPointType transformedPoint = transform.TransformPoint( center );
>>if( transformedPoint[0] != center[0] )
>>   {
>>   itkWarningMacro(<< "Oops.  Transform of center is not the center");
>>   }
>>
>>This is consistent with most of the current transforms.  Can we accept 
>>this as the general "rule" for itk?
>>
>>The other options are to (2) update the offset implicitly when center or 
>>matrix are updated, or (3) require the user to explicitly call 
>>ComputeTranslation, ComputeMatrix, ComputeOffset, and 
>>ComputeMatrixParameters (which, for example, updates the versor in a 
>>versorTransform when the user sets the matrix directly).  Option 3 
>>requires significant changes throughout ITK.   Option 2 is okay, but 
>>will require a few changes - probably about the same number as 
>>implicitly updating transform - however, I see it as less consistent 
>>because of how optimizers update transforms....
>>
>>Any opinions / comments?
>>
>>Thanks,
>>Stephen
>>
> 
> 

-- 
===========================================================
Dr. Stephen R. Aylward
Associate Professor of Radiology
Adjunct Associate Professor of Computer Science and Surgery
http://caddlab.rad.unc.edu
aylward at unc.edu
(919) 966-9695


More information about the Insight-developers mailing list