Mapping between coordinate position (x,y,z) and voxel index

Dear All,

Having a (x,y,z) got with picking with a displayed mhd file, exists any VTK instruction to convert to the voxel index (other (x,y,z), preferable in float) in the image in memory?

Notice that the camera was changed with SetFocalPoint and SetPosition.

In Python.

Thanks,

Luís Gonçalves

Hello, Luis,

You can use vtkCellPicker to perform the picking. This class has a method called GetCellId() which returns the run-length cell (or voxel) index. If you need the grid address (I, J, K), you can do:

    uint nI = /* grid's number of columns */
    uint nJ = /* grid's number of rows */
	uint val = index_value;
	uint nynx = nJ * nI;
	uint k = val / nynx;
	val -= (k*nynx);
	uint j = val / nI;
	uint i = val % nI;
    std::cout << "grid address: " << i << ", " << j << ", " << k << std::endl; 

cheers,

Paulo

You can also use the static method vtkStructuredData::ComputeCellIdForExtent. You feed in the extent (which looks like [xmin, xmax, ymin, ymax, zmin, zmax]) and the cell position in the grid. A similar method exists for points : vtkStructuredData::ComputePointIdForExtent.

I think the method that the OP is looking for is the following, which can also be used from Python:

vtkImageData::TransformPhysicalPointToContinuousIndex(const double xyz[3], double ijk[3])

There are three coordinate systems in play:

  1. the VTK world coordinates, which are returned by picker.GetPickPosition()
  2. the VTK data coordinates, which are returned by picker.GetMapperPosition()
  3. the image data structured point coordinates, i.e. the voxel indices

Not all pickers have a GetMapperPosition() method. Which picker are you using?

If you can use GetMapperPosition(), then you can compute the voxel index like this:

xyz = picker.GetMapperPosition()
XYZ = [0.0, 0.0, 0.0]  # to store voxel index
image.TransformPhysicalPointToContinuousIndex(xyz, XYZ)
print(XYZ)

If you cannot use GetMapperPosition(), you must use the inverse of the actor’s matrix to convert the result of GetPickPosition() from the world coordinate system to the actor’s local data coordinate system.

The picker will automatically take all camera parameters into account, so you never have to worry about the camera when you use picker.GetPickPosition() or picker.GetMapperPosition().

Sorry for the late answer. I picked the following way.

        picker = vtk.vtkVolumePicker()
        picker.SetTolerance(1e-6)
        picker.SetVolumeOpacityIsovalue(0.1)
        coord=renderWindow.GetSize()
        x=event["x"]*coord[0]
        y=event["y"]*coord[1]
        if (picker.Pick(x, y, 0, renderer)==0):
            self.test=self.test+1
        self.p=picker.GetPickPosition()
        self.n=picker.GetPickNormal()

I already have the picked points and the display of the volume. How to:

" you must use the inverse of the actor’s matrix to convert the result of GetPickPosition() from the world coordinate system to the actor’s local data coordinate system."
Before the pick I do the following transform to the volume:´

transform = vtk.vtkTransform()
transform.RotateWXYZ(-20,0.0,-0.7,-0.7)

Thanks for any help,

Luís Gonçalves

With vtkVolumePicker, you can get the pick in the actor’s local coordinates (i.e. mapper coordinates) with these methods:

picker.GetMapperPosition()
picker.GetMapperNormal()

Or, if you have the transform that you applied to the volume, you can apply the inverse to the pick position:

point = transform.GetInverse().TransformPoint(point)
normal = transform.GetInverse().TransformNormal(normal)

If you don’t have the transform, then you can create it from the prop matrix of the vtkVolume

transform = vtk.vtkTransform()
transform.Concatenate(volumeActor.GetMatrix())
1 Like

Thanks. It worked.

@dgobbi Currently, I meet a problem about the world point, and this is the detail. Could you please have a look at this question? This question really make me crazy. Any suggestion is appreciated!