My question lacked of precision: I have several T1-weighted images, and I would like, always on the same scalp, calculate distance along the surface.
“Model to model distance” seems works for two different models, I would rather work just about one model (T1–>mesh of the scalp–>compute the distance between two points on the mesh).
Is-it possible?
Dear Andras and Slicer users,
I have begun my script to calculate distance along the surface.
However, I butt into an obstacle. Indeed, How could I make correspond vertex (in bold below) of my vtkPolyDataMapper with coordinate obtain by the fiducal properties (in italic)?
Perhaps by a KD-Tree (tk.vtkKdTree)?
Thanks in advance.
Frederic
In python:
##Access to Fiducial Properties
fidList = slicer.util.getNode('F')
numFids = fidList.GetNumberOfFiducials()
for i in range(numFids):
ras = [0,0,0]
fidList.GetNthFiducialPosition(i,ras)
print i,": RAS =",ras_
#vtkDijkstraGraphGeodesicPath
dijkstra = vtk.vtkDijkstraGraphGeodesicPath()
dijkstra.SetInputConnection(reader.GetOutputPort())
dijkstra.SetStartVertex(**20**)
dijkstra.SetEndVertex(**500000**)
dijkstra.Update()
Not that these are all standard VTK operations, there is nothing specific to Slicer. So, you may find answers by searching in VTK source code, reading the VTK textbook (it is worth reading the book cover to cover, a few times), and browsing VTK examples.
Hello,I have the same question with you? On the surface of the scalp,how to measure the distance between two pionts without Curve maker module?Dose the problem has been solved?
Thanks for your attention!
@Frederic it would be great if you could upload current version of your module to Github, even if it is not functional yet. It would allow me, @doc-xie, and others to see the progress and help out. The core of this feature can be implemented by adding 30-40 lines of python code to the module template generated by Extension wizard module, so it should be possible to complete it in a couple of days. If you get stuck anywhere then let us know.
Hi,
First of all, thanks @lassoan for your locator code.
Second, my in progress draft for the module was here, with two python scripts: One is a standalone version for python (without 3dslicer) and the second for 3dslicer.
I am moving slowly because I found this RvtkStatismo that made all that I want (HTH @doc-xie) .
Thanks for the update. Slicer is a frontend, from where you can use various libraries. So, if you find Statismo useful then you can add wrappers to make it avaiable directly from Slicer.
@doc-xie if you are interested to pick it up from where @Frederic left off then, I would recommend to create a skeleton extension and a Python scripted module inside (as explained in the Slicer programming tutorial) and add Frederic’s processing code to that.
Yes, thanks for your believing, I am very intresting about 3D Slicer, but I am a new learner and have not any knowledge about Python. So I decide to study it with your help because the importance of Python. By the way, I am looking forward to the progress of this topic!
Hi doc-xie.
Yes, I have update the Github. @lassoan could you help me to create an extension (I have begun on my Github)? @doc-xie For the moment, you could use it from your python interactor (for 3 points):
1/ Load your model in 3dslicer
2/ Draw your 3 points with the “Create-and-Place-Fiducial” button
3/ Insert this code in your python interactor:
import sys, slicer, numpy, os, math, vtk
model = getNode('name_of_your_data') #Go to Data module and see the name of your model, "Name"
#Access to Fiducial Properties (to determinate the start and the end point of the geodesic path)
fidList = slicer.util.getNode('F')
numFids = fidList.GetNumberOfFiducials()
list=[]
for i in range(numFids):
ras = [0,0,0]
fidList.GetNthFiducialPosition(i,ras)
print i,": RAS =",ras
list.append(ras)
#create locator
pd = model.GetModelDisplayNode()
pd1=pd.GetOutputPolyData()
pd1.GetNumberOfPoints()
loc = vtk.vtkPointLocator()
loc.SetDataSet(pd1)
loc.BuildLocator()
closestPointId = loc.FindClosestPoint(list[0]) #point1
closestPointId1 = loc.FindClosestPoint(list[1]) #point2
closestPointId2 = loc.FindClosestPoint(list[2]) #point3
#get the distance of the geodesic path
appendFilter = vtk.vtkAppendFilter()
appendFilter.MergePointsOn()
points = vtk.vtkPoints()
vIds = [closestPointId,closestPointId1,closestPointId2]
p0 = [0,0,0]
p1 = [0,0,0]
dist = 0.0
for n in range(len(vIds)-1):
v0 = vIds[n]
v1 = vIds[n+1]
#create geodesic path: vtkDijkstraGraphGeodesicPath
dijkstra = vtk.vtkDijkstraGraphGeodesicPath()
dijkstra.SetInputConnection(pd.GetOutputPolyDataConnection())
dijkstra.SetStartVertex(v0)
dijkstra.SetEndVertex(v1)
dijkstra.Update()
pts = dijkstra.GetOutput().GetPoints()
end = n<len(vIds)-2 and 0 or -1
for ptId in range(pts.GetNumberOfPoints()-1, end, -1):
pts.GetPoint(ptId, p0)
points.InsertNextPoint(p0)
for ptId in range(pts.GetNumberOfPoints()-1):
pts.GetPoint(ptId, p0)
pts.GetPoint(ptId+1, p1)
dist += math.sqrt(vtk.vtkMath.Distance2BetweenPoints(p0, p1))
appendFilter.AddInputConnection(dijkstra.GetOutputPort())
print 'length= ', dist/10 ,'cm'