...
 
Commits (2)
......@@ -9,6 +9,7 @@ from sksurgerycore.transforms.transform_manager import TransformManager
from sksurgeryvtk.models.vtk_cylinder_model import VTKCylinderModel
from sksurgerytrackervisualisation.shapes.cone import VTKConeModel
from sksurgerytrackervisualisation.shapes.sphere import VTKSphereModel
from sksurgerytrackervisualisation.shapes.vtk_point_model import VTKPointCloud
def np2vtk(mat):
......@@ -113,9 +114,16 @@ def populate_models(model_config):
name = model.get("name")
model_temp = VTKConeModel(height, radius, colour, 'name',
True, 1.0)
dictionary = {"model" : model_temp,
"port handle" : port_handle,
"transform manager" : transform_manager}
dictionary = {
"model" : model_temp,
"port handle" : port_handle,
"transform manager" : transform_manager
}
if model.get("grab points"):
dictionary["point cloud"] = VTKPointCloud(colour)
else:
dictionary["point cloud"] = None
model_dictionaries.append(dictionary)
else:
print("load it in")
......
......@@ -11,8 +11,12 @@ from sksurgerytrackervisualisation.algorithms.background_image import \
class OverlayApp(OverlayBaseApp):
"""Inherits from OverlayBaseApp, adding code to move vtk models
based on input from a scikitsurgery tracker"""
"""
Inherits from OverlayBaseApp, adding code to move vtk models
based on input from a scikitsurgery tracker.
Adds a function to detect a key press event, ("g")
and add points to a point cloud.
"""
def __init__(self, config):
"""Overides overlay base app's init, to initialise the
......@@ -42,6 +46,11 @@ class OverlayApp(OverlayBaseApp):
self.vtk_overlay_window.add_vtk_models(models_t)
for model in self._models:
if model.get("point cloud") is not None:
self.vtk_overlay_window.add_vtk_actor(
model.get("point cloud").actor)
if "camera" in config:
camera_config = config.get("camera")
if "bounding box" in camera_config:
......@@ -84,20 +93,20 @@ class OverlayApp(OverlayBaseApp):
for actor_index, actor in enumerate(
self.vtk_overlay_window.get_foreground_renderer().
GetActors()):
if self._models[actor_index].get("port handle") == port_handle:
if not isnan(quality[ph_index]):
self._models[actor_index].get("transform manager").add(
"tracker2world", tracking[ph_index])
actor.SetUserMatrix(np2vtk(
self._models[actor_index].get(
"transform manager").get("model2world")))
if record:
print(actor_index,
self._models[actor_index].get(
"transform manager").get("model2world"))
break
model = self._models[actor_index]
if model.get("port handle") == port_handle \
and not isnan(quality[ph_index]):
model.get("transform manager").add(
"tracker2world", tracking[ph_index])
model2world = model.get(
"transform manager").get("model2world")
actor.SetUserMatrix(np2vtk(model2world))
if record:
print(ph_index, "is not tracked")
if model.get("point cloud") is not None:
model.get("point cloud").add_point(
(model2world[0:3, 3]))
break
def key_press_event(self, _obj_not_used, _ev_not_used):
"""
......@@ -105,7 +114,5 @@ class OverlayApp(OverlayBaseApp):
"""
if self.vtk_overlay_window.GetKeySym() == 'p':
if self.vtk_overlay_window.GetKeySym() == 'g':
self._update_tracking(record=True)
else:
print("Unhandled key press event. Valid options are, p.")
# -*- coding: utf-8 -*-
"""
Class to represent a point cloud via a vtkPolyData, with the
ability to dynamically add points
"""
from numpy import hstack, ones, int64, arange, ascontiguousarray
from vtk import (vtkPoints, vtkCellArray, vtkPolyData, vtkPolyDataMapper,
VTK_ID_TYPE)
from vtk.util import numpy_support
import sksurgeryvtk.models.vtk_base_model as vbm
class VTKPointCloud(vbm.VTKBaseModel):
"""
Class to represent a point cloud via a vtkPolyData, with the
ability to dynamically add points
"""
def __init__(self, colour,
visibility=True, opacity=1.0):
"""
Creates a new point model.
:param colour: numpy 1 x 3 array containing RGB as [0-255] uchar
:param visibility: boolean, True|False
:param opacity: float [0,1]
"""
super(VTKPointCloud, self).__init__((1.0, 1.0, 1.0),
visibility,
opacity)
self._vtk_points = vtkPoints()
self._vtk_points.SetDataTypeToFloat()
self.actor.GetProperty().SetPointSize(5)
self.actor.GetProperty().SetColor(colour)
def _update_actor(self):
number_of_points = self._vtk_points.GetNumberOfPoints()
if number_of_points == 0:
return
cells = hstack((ones((number_of_points, 1), dtype=int64),
arange(number_of_points).reshape(-1, 1)))
cells = ascontiguousarray(cells, dtype=int64)
cell_array = numpy_support.numpy_to_vtk(
num_array=cells, deep=True, array_type=VTK_ID_TYPE)
vtk_cells = vtkCellArray()
vtk_cells.SetCells(number_of_points, cell_array)
vtk_poly = vtkPolyData()
vtk_poly.SetPoints(self._vtk_points)
vtk_poly.SetVerts(vtk_cells)
vtk_mapper = vtkPolyDataMapper()
vtk_mapper.SetInputData(vtk_poly)
self.actor.SetMapper(vtk_mapper)
def add_point(self, point):
"""
Adds a point to the point cloud and updates the
vtk actor to show the complete point cloud
:param: A 3 tuple representing the point coordinate
"""
self._vtk_points.InsertNextPoint(point)
self._update_actor()
......@@ -180,3 +180,36 @@ def test_invalid_video_config(setup_qt):
}
with pytest.raises(KeyError):
_ = OverlayApp(configuration)
def test_key_press_event(setup_qt):
"""
Test key press events
"""
_ = setup_qt
configuration = {
"tracker config" :
{
"tracker type" : "aruco",
"debug" : False,
"video source" : "data/aruco_tag.avi"
},
"models" : [
{
"name" : "tip",
"port handle" : 0,
"load" : False,
"source" : "cylinder",
"colour" : [1.0, 0.0, 0.0],
"height" : 50.0,
"radius" : 10.0,
"grab points" : True
},
]
}
overlay = OverlayApp(configuration)
overlay.vtk_overlay_window.SetKeySym("p")
overlay.vtk_overlay_window.KeyPressEvent()
overlay.vtk_overlay_window.SetKeySym("x")
overlay.vtk_overlay_window.KeyPressEvent()