how to modify a metric in itk

Hello everyone,
I currently use itk in my project and I need to modify the metric of one of my registration between two 3d images. Is there an efficient way to implement my custom metric (in cpp)?
Thank you in advance for your help :smirk:

The most efficient would be to take an existing metric and modify it. Inventing new image metrics is not expected to be done frequently.

1 Like

Thank you for your answer. Can you show me which files to modify in order to make this as clean as possible ? I mean, I currently use Correlation metric from itkCorrelationImageToImageMetricv4 header and I do not see where the computation of the correlation metric in this .h file is…

There is a whole class hierarchy. Take a look at this discussion for modification of mutual information metric.

Ok. For now, I am totally lost in the itk architecture, I might come back if I still have questions.

Hi it is me again! I still don’t understand how to implement my own metric (even by modifying an existing one). I tried to modify the correlation metric and when I look into the files related to it (itkCorrelationImageToImageMetricv4*), I do not see where the computation is performed… Can anyone detail me the procedure to do so ? Thank you

Hello everyone,
I still get stuck in this home-made metric problem. So I looked deeply into the source code and I tried to understand where exactly mean squares metric is computed.
I read this .hxx file:

My question is: where is computed the normalization of the metric (the product of the sum with 1/N)?
Thank you!

Probably in the method which invokes ProcessPoint. ProcessPoint deals only with a single i. The for loop you are pointing out is for dealing with vector components of a pixel (e.g. RGB).

ok, thank you sir. So, can you show me in which file every i of both images are read?

Put a break-point in the debugger on line 45, then you will see in the call stack where ProcessPoint was invoked from.

Breakpoint lead me to three differents files. I still do not see where the normalization is computed.

Probably in itkImageToImageMetricv4GetValueAndDerivativeThreader.hxx line 43 (method FinalizeThread).

ok. I managed to understand the computation of the normalization. Again thank you for your help. I have another question regarding metric computation: does the computation of the metric have an influence on the computation of the optimizer or the final transform? I mean, is the metric computed at the end of the whole registration process or the metric is a stop flag which determines where the registration process have to stop?

my bad, i am reading the documentation and I saw that you made a detailed scheme of the registration pipeline.

registration = minimization of the metric by the optimizer

It is done for every iteration. Evaluating the metric is the expensive part of the registration.

registration = minimization of the metric by the optimizer

okay. Can we just pass the optimizer the fitness value? I mean, can we deactivate the computation of the metric derivative?

Some optimizers require derivatives. Which one are you using? Try Powell or Amoeba.

ok, I currently use RegularStepGradientDescent. I saw Powell but also the OnePlusOne optimizer. I will try also Amoeba too to see if one of these fits my purpose.

I was wondering if itk’s developers provided a registration example mixing Powell optimizer, mean square metric, and Euler3DTransform transform type ? I have searched this in vain after a couple of hours

Optimizers have similar interface, so adapting another example to your choice of optimizer, metric and transform type should not be hard.