How Can I Pick from an Image that is Not the Top Layer in a vtkImageStack?

Hello,

In my application, I am rendering two images overlayed on one another. The images are vtkImageSlice(s) and I use a vtkImageStack to store both images. The topmost image is cropped in such a way that it’s exent is smaller than the bottom image.

As I roll my mouse over the images, a use vtkVolumePicker to return the i, j, k coordinates of the top image. I would like to return the coordinates of the bottom image instead, but I don’t know how to accomplish this. It seems as though the picker will only return coordinates for the image that is in the top layer position in the vtkImageStack. I’ve tried various combinations of vtkImageStack.SetActiveLayer() and vtkImage.SetPickable(), to no avail. The only way that I can get the picker to return non-zero i,j,k coordinates for the bottom image is if I do not even display the top image (by not adding the top image to the stack).

Can anyone give me some guidance on this?

Thank you,
Michelle K.

picker = vtk.vtkVolumePicker()

( ... )

base_image = vtk.vtkImageSlice()
base_image .SetMapper(vtk.vtkImageSliceMapper())
base_image .GetProperty().SetOpacity(1.0)
base_image .GetMapper().SetInputConnection(base_mapper.GetOutputPort())
base_image .SetScale(1.0, 1.0, 1.0)
base_image .SetPosition(0.0, 0.0, 0.0)
base_image .SetPickable(1)
base_image .Update()

top_image = vtk.vtkImageSlice()
top_image .SetMapper(vtk.vtkImageSliceMapper())
top_image .GetProperty().SetInterpolationTypeToLinear()
top_image .GetProperty().SetOpacity(0.8)
top_image .GetMapper().SetInputConnection(top_mapper.GetOutputPort())
top_image .SetPickable(0)
top_image .Update()

stack = vtk.vtkImageStack()
stack.AddImage(base_image) 
stack.AddImage(top_image)  

renderer = vtk.vtkRenderer()
renderer .AddViewProp(stack)
renderer .AddActor2D(scale_bar_actor)  # this is a vtkScalarBarActor
renderer .AddViewProp(anno)                 # this is vtkCornerAnnotation

window.AddRenderer(renderer)

( ... )

# this is some code from my mouse move callback function
base_image.SetPickable(1)
top_image.SetPickable(0)  # tried various combinations 
stack.SetActiveLayer(0)  # tried 0, 1
picker.Pick(mouseX, mouseY, 0, renderer)
image_coords_2d = picker.GetCellIJK()    # returns (0, 0, 0)
image_coords_3d = (image_coords_2d[0] * spacing_patient[0], image_coords_2d[1] * spacing_patient[1], curr_slice_image * spacing_patient[2], 1)
patient_coords = anat_affine.MultiplyPoint(image_coords_3d)
display_annotation(image_coords_2d, patient_coords, 1)

The SetActiveLayer(n) method is the method that allows you to choose which image to pick. In order for this method to work, a unique layer number must be assigned to each image:

base_image.GetProperty().SetLayerNumber(0)
top_image.GetProperty().SetLayerNumber(1)
stack.SetActiveLayer(0)
3 Likes

Thank you, David. This is exactly the information I needed.