[ITK-users] Inverse of Versor Rigid Transform and RIRE

Gabriel A. Giménez gabrielgimenez85 at gmail.com
Mon Apr 13 22:54:31 EDT 2015


Hi Matt,

Good to hear about your progress!


your answers help me a lot!

There may be that there is a local minima that
> is catching the optimizer


Yes Matt, but the strange thing is that while the value of a metric is
little better the result is worse...should not be better? or nearly equal ?

  As a first step, you can call SetNumberOfThreads on an
> Object


I had a compile error when trying to use this method (no exist member
funtion), I think it is no available in the ITKv4. I tried to use a
SetMaximumNumberOfThreads method, but do not notice any improvement in
performance.

 or call itk::MultiThreader::SetGlobalDefaultNumberOfThreads


It seems a bit complicated to use Matt ...

 There is a lot of interest in improving the mutual information metric
> performance


Yes, in my GA approach is critical the execution time of the
Metric...because it must be calculated for each individual in the
population. I think I have to use an alternative like a GA-Surrogate model
to improve my implementation.

Thanks Matt,

2015-04-13 12:38 GMT-04:00 Matt McCormick <matt.mccormick at kitware.com>:

> Hi Gabriel,
>
> Good to hear about your progress!
>
> To get a better idea of what is happening in the optimization, it may
> insightful to visualize the cost function and where the optimizer is
> moving over that space. There may be that there is a local minima that
> is catching the optimizer.  See, for example, the later parts of this
> video, which displays the cost function as a surface and the
> progression of the optimization [1]. See the Metrics section of the
> ITK Software Guide for another example and discussion on how to do
> this.  We can make use of the ITK Command class, the IterationEvent,
> and the ExhaustiveOptimizer.
>
> The code itself is the best place to find details on multithreading in
> the metrics.  As a first step, you can call SetNumberOfThreads on an
> Object or call itk::MultiThreader::SetGlobalDefaultNumberOfThreads.
> There is a lot of interest in improving the mutual information metric
> performance -- please keep the list informed of your experiences.
>
> Thanks,
> Matt
>
> [1]
> https://drive.google.com/file/d/0B986LSX8iqF-bl9qQWZobmRWeEk/view?usp=sharing
>
> On Thu, Apr 9, 2015 at 9:17 PM, Gabriel A. Giménez
> <gabrielgimenez85 at gmail.com> wrote:
> > Hi Matt!
> >
> >> If you are working with a current version of ITK, when you get the
> >> inverse transform, it should transfer the Center for you. The Center
> >> point locations are the FixedParameters for the parent class,
> >> MatrixOffsetTransformBase. The relationship with parent classes can be
> >> found by examining the Doxygen page for the class [1].
> >
> >
> > I took a few days to read the RIRE documentation and I came to the
> > conclusion that the direction of registration is not really
> > relevant...taking up CT as the fexed image and MR as the moving image
> can be
> > used the transformation that provides ITK...without having to calculate
> the
> > inverse.
> >
> >
> >> Do you get the same result by applying the TransformPoint() method of
> >> the inverse transform? This is the API call that should be applied to
> >> transform a point.
> >
> >
> > Yes Matt, I get the same results using the API.
> >
> > But...I made some changes in my optimizers and I got very good results,
> like
> > this ( with RegularStepGradientDescentOptimizerv4 and
> > MattesMutualInformationImageToImageMetricv4):
> >
> > iterations = 200
> > Metric value  = -0.709388
> > versor X      = 0.0155583
> >  versor Y      = 0.00642035
> >  versor Z      = -0.0487144
> >  Translation X = 7.82977
> >  Translation Y = -60.1034
> >  Translation Z = -23.6258
> >
> +-----------------------------------------------------------------------------------------------+
> > |           X GT|           Y GT|           Z GT|            X R|
> > Y R|            Z R|
> >
> -----------------------------------------------------------------------------------------------+
> > |      -7.573100|     -41.253400|     -27.309300|      -7.661395|
> > -40.915138|     -26.044441|
> > |     324.872200|     -72.815900|     -32.906300|     324.712907|
> > -73.345104|     -30.833635|
> > |      24.160700|     291.039300|     -16.272700|      24.902019|
> > 291.325008|     -15.874605|
> > |     356.606000|     259.476800|     -21.869700|     357.276322|
> > 258.895042|     -20.663798|
> > |      -6.055400|     -45.115700|      84.613700|      -6.394922|
> > -44.465633|      85.892103|
> > |     326.389900|     -76.678200|      79.016800|     325.979381|
> > -76.895599|      81.102910|
> > |      25.678400|     287.176900|      95.650300|      26.168493|
> > 287.774513|      96.061940|
> > |     358.123700|     255.614500|      90.053400|     358.542796|
> > 255.344547|      91.272747|
> >
> +-----------------------------------------------------------------------------------------------+
> > [X, Y, Z]GT are  the "ground truth" values and [X, Y, Z]R are my results
> >
> > Now, something I find strange is that when increasing the number of
> > iterations...metric value limprovement is too little but the result is
> > little worse..., example:
> >
> > Iterations    = 334
> > Metric value  = -0.710918
> >  versor X      = 0.0216566
> >  versor Y      = 0.00700629
> >  versor Z      = -0.0508766
> >  Translation X = 7.80722
> >  Translation Y = -60.5124
> >  Translation Z = -24.1047
> >
> >
> +-----------------------------------------------------------------------------------------------+
> > |           X GT|           Y GT|           Z GT|            X R|
> > Y R|            Z R|
> >
> +-----------------------------------------------------------------------------------------------+
> > |      -7.573100|     -41.253400|     -27.309300|      -8.342271|
> > -39.764911|     -28.121895|
> > |     324.872200|     -72.815900|     -32.906300|     323.882938|
> > -73.594962|     -33.530625|
> > |      24.160700|     291.039300|     -16.272700|      25.690487|
> > 292.179801|     -13.916412|
> > |     356.606000|     259.476800|     -21.869700|     357.915696|
> > 258.349750|     -19.325143|
> > |      -6.055400|     -45.115700|      84.613700|      -7.022108|
> > -44.688304|      83.762051|
> > |     326.389900|     -76.678200|      79.016800|     325.203101|
> > -78.518355|      78.353321|
> > |      25.678400|     287.176900|      95.650300|      27.010650|
> > 287.256408|      97.967534|
> > |     358.123700|     255.614500|      90.053400|     359.235859|
> > 253.426357|      92.558803|
> >
> +-----------------------------------------------------------------------------------------------+
> >
> > This pattern is repeated with other optimizers ( like OnePlusOne and  a
> GA
> > approach that I am implementing ), that you think about it?
> >
> > Other questions Matt...:
> >
> > How works the multithreaded in metrics ? is customizable? improve
> > performance? specifically in the case of Mattes Mutual Information...
> >
> > I tried using the helper CenteredVersorTransformInitializer... but the
> > transformation that generates makes, incredibly and also very strange,the
> > optimizers does not advance...using CenteredTransformInitializer this
> does
> > not happen...
> >
> > Really Thanks in advance Matt!
> > Regards,
> >
> >
> >
> > 2015-04-07 15:03 GMT-04:00 Matt McCormick <matt.mccormick at kitware.com>:
> >
> >> Hi Gabriel!
> >>
> >> > I am use RIRE project, specifically  CT (movig) and MR_PD (fixed)
> >> > images.
> >> > Basically, I hava a set of point (in millimeters) of the CT image to
> >> > which
> >> > apply the trasform result of the registration and updaload this
> results
> >> > in
> >> > the web for the evaluation. Example of set of points and his "ground
> >> > truth"
> >> > :
> >> >
> >> > Point      x          y          z        new_x       new_y
>  new_z
> >> >
> >> >   1       0.0000     0.0000     0.0000   -7.5731    -41.2534
> -27.3093
> >> >   2     333.9870     0.0000     0.0000  324.8722    -72.8159
> -32.9063
> >> >   3       0.0000   333.9870     0.0000   24.1607    291.0393
> -16.2727
> >> >   4     333.9870   333.9870     0.0000  356.6060    259.4768
> -21.8697
> >> >   5       0.0000     0.0000   112.0000   -6.0554    -45.1157
>  84.6137
> >> >   6     333.9870     0.0000   112.0000  326.3899    -76.6782
>  79.0168
> >> >   7       0.0000   333.9870   112.0000   25.6784    287.1769
>  95.6503
> >> >   8     333.9870   333.9870   112.0000  358.1237    255.6145
>  90.0534
> >>
> >> Trying to reproduce previous results is a good path forward.
> >>
> >> > So, the first I need is the transformation to apply, for that I do the
> >> > following :
> >> >
> >> >    //get the inverse transform
> >> >    TransformType::Pointer inverseTransform = TransformType::New();
> >> >    inverseTransform->SetCenter( finalTransform->GetCenter() );
> >> >    bool response = finalTransform->GetInverse(inverseTransform);
> >> >
> >> >
> >> > It makes sense to use the same center in the inverse transform?. A
> >> > "quaternion" define an "axis" (right part) of rotation and an angle to
> >> > use
> >> > for rotate the image about this axis...why use a center of
> rotation...?
> >>
> >> If you are working with a current version of ITK, when you get the
> >> inverse transform, it should transfer the Center for you. The Center
> >> point locations are the FixedParameters for the parent class,
> >> MatrixOffsetTransformBase. The relationship with parent classes can be
> >> found by examining the Doxygen page for the class [1].
> >>
> >>
> >> > Second, apply this transform...as follows:
> >> >
> >> > NewPoint = RotationMatrix * OriginalPoint + Offset
> >> >
> >> > The rotation matrix and the offset are obtained from the inverse
> >> > transforme
> >> > objetc. Found something wrong? something that is not taking into
> account
> >> > ?
> >> > The results do not appear to be correct...the calculated error is too
> >> > big
> >> > and does not correspond with the visual result.
> >>
> >> Do you get the same result by applying the TransformPoint() method of
> >> the inverse transform? This is the API call that should be applied to
> >> transform a point.
> >>
> >> Thanks,
> >> Matt
> >>
> >>
> >> [1]
> >> http://www.itk.org/Doxygen/html/classitk_1_1VersorRigid3DTransform.html
> >
> >
> >
> >
> > --
> > Gabriel Alberto Giménez.
>



-- 
*Gabriel Alberto Giménez.*
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://public.kitware.com/pipermail/insight-users/attachments/20150413/91e10c00/attachment.html>


More information about the Insight-users mailing list