[Insight-users] VersorRigid3dTransform.. [More]

Karthik Krishnan Karthik.Krishnan at kitware.com
Tue Jul 5 10:44:04 EDT 2005


Hi Martin,

To add to the earlier mail, the key to getting rid of this confusion is 
to understand how centered transforms work:

p' = R (p - C)  + C  + T

where p' = transformed point, p = original point, C = Center, T= 
Translation. R= Rotation matrix.

This can be re-written as

p' = Rp + Offset         where Offset = -RC + C + T

Its clear that for any transform with any set of parameters, it is 
always possible to find an equivalent transform satisfying
p' = R(p - 0) + T '       where the Offset / translation have a value T 
'   and the center is 0.

This is how transforms operate by default in ITK.


The problem arises because you have 3 parameters Offset, Center and 
Translation and they are not independent of each other. They've got to 
satisfy the following constraint
Offset = -RC + C + T.

(These parameters were defined cause they make sense for different 
transforms, but matrix transform operations are most easily performed in 
the Rp + Offset notation.)

Now the problem arises when you let the user manipulate these 
parameters. Which of the parameters takes precedence ? Usually you set 
the center and the translation and let the transform compute the offset 
for you... Unfortunately the GetInverse method is not one of them. Here 
the inverse returns the inverse rotation matrix and the corresponding 
Offset. If you set the center later, how do you update the offset ? One 
of the parameters has got to be incorrect. So we set the center first 
and then let the GetInverse() method compute the offset for that center.

Hope this clears the confusion.

Thanks
regards
karthik




Karthik Krishnan wrote:

> Hi Martin,
>
> As you've pointed out, the documentation of MatrixOffsetTransformBase 
> says:
> "    * WARNING: When using the Center, we strongly recommend only 
> changing the
>   * matrix and translation to define a transform.   Changing a 
> transform's
>   * center, changes the mapping between spaces - specifically, 
> translation is
>   * not changed with respect to that new center, and so the offset is 
> updated
>   * to * maintain the consistency with translation.   If a center is 
> not used,
>   * or is set before the matrix and the offset, then it is safe to 
> change the
>   * offset directly. "
>
> The GetInverse method is one of those methods that changes the matrix 
> and the offset, since it has to compute the inverse matrix.
>
> The correct way to invert a transformation and retain the option of 
> defining your own center is to do it in the following order:
>
> transform2->SetCenter( transform1->GetCenter() );
> transform1->GetInverse( transform2 );
>
> transform2 will now contain the inverse of transform1 and will contain 
> transform1's center. Flipping the two statements will produce an 
> incorrect transform.
>
> I'll put this stuff in the doxygen.
>
> Thanks
> regards
> karthik
>
> Martin Urschler wrote:
>
>> Hi Karthik,
>>
>> Karthik Krishnan wrote:
>>
>>>
>>> It does bring up one minor point concerning transforms like the 
>>> VersorRigidTransform and other transforms that contain the center 
>>> (they derive from the MatrixOffSetTransformBase). If you were to 
>>> copy the transform parameters over into another transform, you will 
>>> also need to explicitly copy the center otherwise your new transform 
>>> will be incorrect.  ie....
>>>
>>>  TransformType::Pointer finalTransform = TransformType::New();
>>>  copiedTransform->SetCenter( originalTransform->GetCenter() );
>>>  copiedTransform->SetParameters( originalTransform->GetParameters() );
>>>
>>> Maybe this info should be put in the Doxygen ...... ? ?
>>
>>
>>
>>
>> Coming back to this issue we discussed a while ago. If I use the 
>> GetInverse method of a class derived from MatrixOffsetTransformBase 
>> then the inverse transform is returned but the center of rotation is 
>> set to 0 in the returned transformation.
>>
>> I.e. in
>>
>> Rigid3DTransformType::Pointer initialTransform =
>>    someTransformFromARegistration();
>>
>> Rigid3DTransformType::Pointer inverseInitialTransform =
>>    Rigid3DTransformType::New();
>> initialTransform->GetInverse( inverseInitialTransform );
>>
>>
>> the center of rotation of inverseInitialTransform is [0,0,0] no 
>> matter what the center in initialTransform is
>>
>> This is consistent with the documentation which states that the 
>> center of rotation of the inverse is centered at the origin.
>>
>>
>> My question:
>> Is it now sufficient to simply apply
>> inverseInitialTransform->SetCenter( initialTransform->GetCenter() );
>>
>> to update the center? Or do I have to call another member function 
>> that updates the internal matrix and offset accordingly?
>>
>> regards,
>> Martin
>>
> _______________________________________________
> Insight-users mailing list
> Insight-users at itk.org
> http://www.itk.org/mailman/listinfo/insight-users
>


More information about the Insight-users mailing list