Understanding the behavior of volume node's SetAndObserveImageData method

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

Thank you in advance.

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.

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?

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.

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.

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.

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.

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

1 Like