# Understanding the behavior of volume node's SetAndObserveImageData method

**URL:** <https://discourse.slicer.org/t/understanding-the-behavior-of-volume-nodes-setandobserveimagedata-method/16015>\
**Category:** Development\
**Tags:** python\
**Created:** [February 16, 2021, 5:55pm UTC](https://discourse.slicer.org/t/understanding-the-behavior-of-volume-nodes-setandobserveimagedata-method/16015 "2021-02-16T17:55:34Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![marianaslicer](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/marianaslicer/32/8555_2.png) [@marianaslicer](https://discourse.slicer.org/u/marianaslicer)\
**Post date:** [February 16, 2021, 5:55pm UTC](https://discourse.slicer.org/t/understanding-the-behavior-of-volume-nodes-setandobserveimagedata-method/16015/1 "2021-02-16T17:55:34Z")

</div>

Hi everyone,

Slicer: 4.13

My question might be stupid…  
I am not understanding the behavior of these lines of code:

```
mathMultiply = vtk.vtkImageMathematics()
mathMultiply.RemoveAllInputs()
CT_before.SetAndObserveImageData(ctNode.GetImageData())
mathMultiply.SetInputData(ctNode.GetImageData())
mathMultiply.Modified()
mathMultiply.Update()
CT_after.SetAndObserveImageData(mathMultiply.GetOutput())

```

I was expecting that CT\_before and CT\_after to be exactly the same, but I’m having a shift in the voxel values. Any idea why?

![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/c/5/c5e4368c46dfdbca55b92be1cd8dbbcf806b9e26.png)

Thank you in advance.

---

<div class="post-metadata">

**Author:** ![pieper](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/pieper/32/8_2.png) [@pieper](https://discourse.slicer.org/u/pieper)\
**Post date:** [February 16, 2021, 6:38pm UTC](https://discourse.slicer.org/t/understanding-the-behavior-of-volume-nodes-setandobserveimagedata-method/16015/2 "2021-02-16T18:38:10Z")

</div>

Did you get any error messages? The default operation of `vtkImageMathematics` is Add, which requires two inputs. Also you would typically use the `SetInput1Data` and optionally `SetInput2Data` depending on the selected operation.

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [February 16, 2021, 8:15pm UTC](https://discourse.slicer.org/t/understanding-the-behavior-of-volume-nodes-setandobserveimagedata-method/16015/3 "2021-02-16T20:15:49Z")

</div>

Note that it is not enough to copy the image data, you also need to copy image origin, spacing, and axis directions (for example, by copying the IJKToRAS matrix). Although in this case the difference is not cause by this, because you seem to have origin=(0,0,0), spacing=(1,1,1), directions=`np.diag([1,1,1])`. By the way, it is rare to have isotropic spacing of 1.0mm/pixel along all axes and directions is most commonly is `np.diag([-1,-1,1])`), so maybe you have lost your image geometry during some previous preprocessing step.

Where did you get your inputs from? What are you trying to achieve?

---

<div class="post-metadata">

**Author:** ![marianaslicer](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/marianaslicer/32/8555_2.png) [@marianaslicer](https://discourse.slicer.org/u/marianaslicer)\
**Post date:** [February 16, 2021, 9:40pm UTC](https://discourse.slicer.org/t/understanding-the-behavior-of-volume-nodes-setandobserveimagedata-method/16015/4 "2021-02-16T21:40:29Z")

</div>

Hi Pieper,

Thanks for your response.  
Yes, I am getting several VTK errors:

```
Bad component index 1
Bad component index 2
Bad component index 2

Execute: input2 ScalarType, 4, must match output ScalarType 6
Execute: input2 ScalarType, 6, must match output ScalarType 4

```

I changed the code as you can see in the following answer but I am getting the same errors.

---

<div class="post-metadata">

**Author:** ![marianaslicer](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/marianaslicer/32/8555_2.png) [@marianaslicer](https://discourse.slicer.org/u/marianaslicer)\
**Post date:** [February 16, 2021, 9:41pm UTC](https://discourse.slicer.org/t/understanding-the-behavior-of-volume-nodes-setandobserveimagedata-method/16015/5 "2021-02-16T21:41:34Z")

</div>

Hi Andras Lasso,

Thank you for your response.  
I am trying to calculate the average CT of 10 CT and I have the following code:

```
ctImageData = vtk.vtkImageData()
mathMultiply = vtk.vtkImageMathematics()
mathAddCT = vtk.vtkImageMathematics()
mathAddCT.RemoveAllInputs()

if firstRun:
  ctImageData.SetSpacing(ctNode.GetSpacing())
  ctImageData.SetOrigin(ctNode.GetOrigin())
  ctImageData.DeepCopy(ctNode.GetImageData())
  firstRun = False

else:
  mathAddCT.SetOperationToAdd()
  mathAddCT.SetInput1Data(ctNode.GetImageData())
  mathAddCT.SetInput2Data(ctImageData)
  mathAddCT.Modified()
  mathAddCT.Update()
  ctImageData.DeepCopy(mathAddCT.GetOutput())

after adding 10 CT, calculate the mean:

mathMultiply.RemoveAllInputs()
mathMultiply.SetOperationToMultiplyByK()
mathMultiply.SetConstantK(0.1)
mathMultiply.SetInput1Data(ctImageData)
mathMultiply.Modified()
mathMultiply.Update()
ctImageData.DeepCopy(mathMultiply.GetOutput())

```

I am not understanding why I have this shift in voxel values after applying mathematical operations.The input medical images have origin = (300, 157, 24)mm , spacing = (1.171875, 1.171875, 2)mm and size of 512x512x89 mm.

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [February 16, 2021, 10:52pm UTC](https://discourse.slicer.org/t/understanding-the-behavior-of-volume-nodes-setandobserveimagedata-method/16015/6 "2021-02-16T22:52:19Z")

</div>

Instead of using VTK filters, it is much easier to add values using numpy operations. You can get the voxels as a numpy array by calling [`arrayFromVolume`](https://slicer.readthedocs.io/en/latest/developer_guide/slicer.html#slicer.util.arrayFromVolume).

Before you can compute average, you need to ensure that all arrays have the same geometry (origin, spacing, axis directions, and extents). You can achieve that by registering them to a common template and resampling them using the same reference geometry.

---

<div class="post-metadata">

**Author:** ![marianaslicer](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/marianaslicer/32/8555_2.png) [@marianaslicer](https://discourse.slicer.org/u/marianaslicer)\
**Post date:** [February 16, 2021, 11:56pm UTC](https://discourse.slicer.org/t/understanding-the-behavior-of-volume-nodes-setandobserveimagedata-method/16015/7 "2021-02-16T23:56:24Z")

</div>

Thank you for your useful suggestion. It solved my problem!
