# Offset changes with each registration

**URL:** https://discourse.itk.org/t/offset-changes-with-each-registration/3398
**Category:** Beginner Questions
**Tags:** python, simpleitk
**Created:** [August 18, 2020, 9:26am UTC](https://discourse.itk.org/t/offset-changes-with-each-registration/3398 "2020-08-18T09:26:51Z")
**Posts on this page:** 11
**Page:** 1

<div class="post-metadata">

### Author: ![Yew\_Shu\_Ning](https://discourse.itk.org/user_avatar/discourse.itk.org/yew_shu_ning/32/1659_2.png) [@Yew\_Shu\_Ning](https://discourse.itk.org/u/Yew_Shu_Ning)
#### Post date: [August 18, 2020, 9:26am UTC](https://discourse.itk.org/t/offset-changes-with-each-registration/3398/1 "2020-08-18T09:26:51Z")

</div>

Hi! I tried to register two images, using the following code:

# Registration framework setup.

```
registration_method = sitk.ImageRegistrationMethod()

#Set Interpolator
registration_method.SetInterpolator(sitk.sitkLinear)

#Set Metric as Mutual Information
#registration_method.SetMetricAsANTSNeighborhoodCorrelation(radius=100)
registration_method.SetMetricAsMattesMutualInformation(numberOfHistogramBins=50)
registration_method.SetMetricSamplingStrategy(registration_method.RANDOM)
registration_method.SetMetricSamplingPercentage(0.01)

#Set Optimizer
registration_method.SetOptimizerAsGradientDescent(learningRate=0.1, numberOfIterations=1000, convergenceMinimumValue=1e-6, convergenceWindowSize=10)
registration_method.SetOptimizerScalesFromPhysicalShift() 

#Set initial transform 
registration_method.SetInitialTransform(initial_transform, inPlace=True)

# Setup for the multi-resolution framework
registration_method.SetShrinkFactorsPerLevel(shrinkFactors = [4,2,1])
registration_method.SetSmoothingSigmasPerLevel(smoothingSigmas = [2,1,0])
registration_method.SmoothingSigmasAreSpecifiedInPhysicalUnitsOn()

#Show the graph of Mi against iterations
#registration_method.AddCommand(sitk.sitkStartEvent, metric_start_plot)
#registration_method.AddCommand(sitk.sitkEndEvent, metric_end_plot)
#registration_method.AddCommand(sitk.sitkMultiResolutionIterationEvent, metric_update_multires_iterations) 
#registration_method.AddCommand(sitk.sitkIterationEvent, lambda: metric_plot_values(registration_method))

#Execute the registration
final_transform = registration_method.Execute(fixed_image, moving_image)

#Print results
print('Final metric value: {0}'.format(registration_method.GetMetricValue()))
print('Optimizer\'s stopping condition, {0}'.format(registration_method.GetOptimizerStopConditionDescription()))
print(final_transform)

```

However, every time I run the code with the exact same two images, the offset (from the final transform), metric value, changes. Is there a reason why it changes?

---

<div class="post-metadata">

### Author: ![blowekamp](https://discourse.itk.org/user_avatar/discourse.itk.org/blowekamp/32/79_2.png) [@blowekamp](https://discourse.itk.org/u/blowekamp)
#### Post date: [August 18, 2020, 11:47am UTC](https://discourse.itk.org/t/offset-changes-with-each-registration/3398/2 "2020-08-18T11:47:43Z")

</div>

Please look at the `seed` parameter for the [`SetMetricSamplingPercentage`](https://simpleitk.org/doxygen/latest/html/classitk_1_1simple_1_1ImageRegistrationMethod.html#a8b891c62404a8dc5010241fea619c932) it default to `sitkWallClock`. This adds some time based randomness to the samples generated. If it set to your favorite integer is should make the process more reproducible.

However, if the registration is not converging to similar place with a little random sampling then this is an indication that there is a stability problem with the registration that needs more investigation. Is it converting to a local minima? ( optimization parameter tuning ) Are there multiple local minima? ( under sampling, noise or problematic data ).

---

<div class="post-metadata">

### Author: ![Yew\_Shu\_Ning](https://discourse.itk.org/user_avatar/discourse.itk.org/yew_shu_ning/32/1659_2.png) [@Yew\_Shu\_Ning](https://discourse.itk.org/u/Yew_Shu_Ning)
#### Post date: [August 18, 2020, 5:18pm UTC](https://discourse.itk.org/t/offset-changes-with-each-registration/3398/3 "2020-08-18T17:18:04Z")

</div>

Does this mean if I set the

> registration\_method.SetMetricSamplingPercentage()

to a number, for example, 1, it should be around the same results?

Here’s what I got from doing the registration callback (found from simpleitk notebook in this link: [[SimpleITKTutorialMICCAI2015](https://github.com/InsightSoftwareConsortium/SimpleITKTutorialMICCAI2015)]([SimpleITKTutorialMICCAI2015/3\_Registration\_1.ipynb at master · InsightSoftwareConsortium/SimpleITKTutorialMICCAI2015 · GitHub](https://github.com/InsightSoftwareConsortium/SimpleITKTutorialMICCAI2015/blob/master/3_Registration_1.ipynb))), using the above code and gradient line descent as optimizer:

 ![image](https://discourse.itk.org/uploads/default/original/2X/1/135855f74fdd5801d16e09f7b60758c6e9f171ef.png)

But, when I run it again, the metric value is so better:

 ![image](https://discourse.itk.org/uploads/default/original/2X/f/fcf748f5ea24fda618a3274b6c37d59623b0a1c5.png)

Also, can I ask: shouldn’t the optimizer’s stopping condition be the point where the metric value is the lowest, but it didn’t choose the iteration where the metric value was the lowest according to the graph.

---

<div class="post-metadata">

### Author: ![zivy](https://discourse.itk.org/user_avatar/discourse.itk.org/zivy/32/1726_2.png) [@zivy](https://discourse.itk.org/u/zivy)
#### Post date: [August 18, 2020, 5:54pm UTC](https://discourse.itk.org/t/offset-changes-with-each-registration/3398/4 "2020-08-18T17:54:07Z")

</div>

Hello @Yew_Shu_Ning,

Per @blowekamp’s suggestion, if you want the registration’s random sampling to be reproducible you need to set the random seed. Looking at the `SetMetricSamplingPercentage` method we see that it has two parameters, `percentage` and `seed`. You are required to set the percentage, and if you set the optional `seed` value to a fixed integer you will get results that are more reproducible as you always use the same seed for the random number generator.

With respect to the optimizer’s stopping condition, it is stopping after 11 iterations in the lowest level of the pyramid, this is the lowest similarity value for that level. The graph is displaying the similarity metric for all levels of the pyramid. The leftmost portion of the graph is the highest pyramid level, using the smallest image. Then we restart the registration at a lower level in the pyramid, using a larger image and plot the values during that phase. Thus, the lowest similarity value in the graph does not correspond to the best transformation. The lowest value in the rightmost portion of the graph does correspond to the best transformation.

Note, that as the registration is using a TranslationTransform you don’t need to call `SetOptimizerScalesFromPhysicalShift` as your parameters are commensurate. If you mix parameters, e.g. mm and radians then you need to call this scaling function.

Finally, I suggest looking at [the newest online tutorial](https://simpleitk.org/TUTORIAL/) as you’re browsing material from 5 years ago

---

<div class="post-metadata">

### Author: ![Yew\_Shu\_Ning](https://discourse.itk.org/user_avatar/discourse.itk.org/yew_shu_ning/32/1659_2.png) [@Yew\_Shu\_Ning](https://discourse.itk.org/u/Yew_Shu_Ning)
#### Post date: [August 19, 2020, 4:47am UTC](https://discourse.itk.org/t/offset-changes-with-each-registration/3398/5 "2020-08-19T04:47:37Z")

</div>

Thank you so much for the explanation. By specifying the seed value, the offset and metric value did not change anymore. So, is it true to assume that the most optimal stopping condition is the minimal similarity value at the lowest level of the pyramid?

---

<div class="post-metadata">

### Author: ![zivy](https://discourse.itk.org/user_avatar/discourse.itk.org/zivy/32/1726_2.png) [@zivy](https://discourse.itk.org/u/zivy)
#### Post date: [August 19, 2020, 2:39pm UTC](https://discourse.itk.org/t/offset-changes-with-each-registration/3398/6 "2020-08-19T14:39:30Z")

</div>

Yes, as long as the optimizer didn’t stop due to early termination (reaching maximal number of iterations, which in your case it didn’t. set to 1000 and stopped after 11).

---

<div class="post-metadata">

### Author: ![Yew\_Shu\_Ning](https://discourse.itk.org/user_avatar/discourse.itk.org/yew_shu_ning/32/1659_2.png) [@Yew\_Shu\_Ning](https://discourse.itk.org/u/Yew_Shu_Ning)
#### Post date: [September 15, 2020, 7:32am UTC](https://discourse.itk.org/t/offset-changes-with-each-registration/3398/7 "2020-09-15T07:32:02Z")

</div>

Thank you! Can I ask whether the offset I got is the same as the translation shifts for the translation used in registration? If not, how can i print out the translation shifts?

---

<div class="post-metadata">

### Author: ![zivy](https://discourse.itk.org/user_avatar/discourse.itk.org/zivy/32/1726_2.png) [@zivy](https://discourse.itk.org/u/zivy)
#### Post date: [September 15, 2020, 1:23pm UTC](https://discourse.itk.org/t/offset-changes-with-each-registration/3398/8 "2020-09-15T13:23:22Z")

</div>

Yes, the term offset for TranslationTransform refers to the translation optimized during registration.

---

<div class="post-metadata">

### Author: ![fred\_weiss](https://discourse.itk.org/letter_avatar_proxy/v4/letter/f/4bbf92/32.png) [@fred\_weiss](https://discourse.itk.org/u/fred_weiss)
#### Post date: [October 15, 2020, 6:50pm UTC](https://discourse.itk.org/t/offset-changes-with-each-registration/3398/9 "2020-10-15T18:50:45Z")

</div>

Thank you for your explanations, setting the seed parameter works fine. Yet one question remains unclear for me:  
If I set `MetricSamplingPercentage` to `1`, why isn’t the registration deterministic then? For my understanding, in this case every point of the image should be included in calculation of the metric value, which means the points are no more chosen randomly. But what is the reason that this is not the case?

---

<div class="post-metadata">

### Author: ![zivy](https://discourse.itk.org/user_avatar/discourse.itk.org/zivy/32/1726_2.png) [@zivy](https://discourse.itk.org/u/zivy)
#### Post date: [October 15, 2020, 7:20pm UTC](https://discourse.itk.org/t/offset-changes-with-each-registration/3398/10 "2020-10-15T19:20:24Z")

</div>

Hello @fred_weiss,

Setting the `MetricSamplingPercentage` to 1 when using the random sampling strategy will not use every pixel/voxel in the image because the sampling is **with replacement**.

If you want to use all of the pixels, then set the sampling strategy to NONE.

---

<div class="post-metadata">

### Author: ![blowekamp](https://discourse.itk.org/user_avatar/discourse.itk.org/blowekamp/32/79_2.png) [@blowekamp](https://discourse.itk.org/u/blowekamp)
#### Post date: [October 15, 2020, 9:20pm UTC](https://discourse.itk.org/t/offset-changes-with-each-registration/3398/11 "2020-10-15T21:20:20Z")

</div>

> [@zivy](#):
>
> If you want to use all of the pixels, then set the sampling strategy to NONE.

If I recall correctly even with the “NONE” strategy each pixel is perturbed a random amount. So the seed should still be used for reproducibility.
