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.
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;
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.
the VTK world coordinates, which are returned by picker.GetPickPosition()
the VTK data coordinates, which are returned by picker.GetMapperPosition()
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:´
@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!