Beispiel #1
0
def test_invalid_because_not_4x4():

    with pytest.raises(ValueError):
        _ = mu.create_vtk_matrix_from_numpy(np.random.random((3, 4)))

    with pytest.raises(ValueError):
        _ = mu.create_vtk_matrix_from_numpy(np.random.random((4, 3)))
def run_demo(input_file, output_file, transform_file):
    """
    Takes a poly data input, transforms it by a 4x4 matrix, writes output.

    :param input_file: Input poly data as .vtk, .vtp, .stl or .ply file.
    :param output_file: Output poly data as .vtk file.
    :param transform_file: 4x4 matrix in plain text (e.g. numpy.savetxt) format.
    :return:
    """
    if not output_file.endswith('.vtk'):
        raise ValueError('Currently, only .vtk outputs are supported.')

    model = sm.VTKSurfaceModel(input_file,
                               colour=[1.0, 1.0, 1.0],
                               visibility=True)

    matrix = np.loadtxt(transform_file)
    transform = mu.create_vtk_matrix_from_numpy(matrix)
    model.set_model_transform(transform)

    # this line can go, when scikit-surgeryvtk updates to 0.22.0
    model.transform_filter.Update()

    writer = vtk.vtkPolyDataWriter()
    writer.SetFileName(output_file)
    writer.SetInputData(model.transform_filter.GetOutput())
    writer.Write()
Beispiel #3
0
def test_numpy_to_vtk():

    numpy_array = np.random.random((4, 4))
    vtk_matrix = mu.create_vtk_matrix_from_numpy(numpy_array)
    converted_back = mu.create_numpy_matrix_from_vtk(vtk_matrix)
    assert np.allclose(numpy_array, converted_back)
    assert id(numpy_array) != id(converted_back)
def test_create_vtk_matrix_4x4_from_numpy():

    array = np.random.rand(4, 4)

    vtk_matrix = mu.create_vtk_matrix_from_numpy(array)

    for i in range(4):
        for j in range(4):
            assert vtk_matrix.GetElement(i, j) == array[i, j]
    def set_pose_with_matrices(self, p2c, l2c, angle_of_handle):
        """
        Method to apply 4x4 transformations to actors.
        :param p2c: 4x4 matrix, either numpy or vtk matrix.
        :param l2c: 4x4 matrix, either numpy or vtk matrix.
        :param angle_of_handle: angle in deg.
        :return: N/A
        """

        # First we can compute the angle of the handle.
        # This applies directly to the data, as it comes out
        # of the vtkTransformPolyDataFilter, before the actor transformation.
        probe_offset = np.eye(4)
        probe_offset[0][3] = 0.007877540588378196
        probe_offset[1][3] = 36.24640712738037
        probe_offset[2][3] = -3.8626091003417997
        r_x = \
            cmu.construct_rx_matrix(angle_of_handle, is_in_radians=False)
        rotation_about_x = \
            cmu.construct_rigid_transformation(r_x, np.zeros((3, 1)))
        self.cyl_trans.SetMatrix(
            vmu.create_vtk_matrix_from_numpy(probe_offset @ rotation_about_x))
        self.cyl_transform_filter.Update()

        # Check p2c, l2c: if numpy, convert to vtk.
        if isinstance(p2c, np.ndarray):
            p2c = vmu.create_vtk_matrix_from_numpy(p2c)
        if isinstance(l2c, np.ndarray):
            l2c = vmu.create_vtk_matrix_from_numpy(l2c)

        # This is where we apply transforms to each actor.
        # Apply p2c to probe
        self.cyl_actor.PokeMatrix(p2c)
        probe_model = self.model_loader.get_surface_model('probe')
        probe_model.actor.PokeMatrix(p2c)
        # Apply l2c to organs in scene.
        for model in self.model_loader.get_surface_models():
            if model.get_name() != 'probe':
                model.actor.PokeMatrix(l2c)

        # Force re-render
        self.overlay.Render()
        self.repaint()
 def set_camera_pose(self, camera_to_world):
     """
     Sets the camera position and orientation, from a numpy 4x4 array.
     :param camera_to_world: camera_to_world transform.
     """
     vm.validate_rigid_matrix(camera_to_world)
     self.camera_to_world = camera_to_world
     vtk_cam = self.get_foreground_camera()
     vtk_mat = mu.create_vtk_matrix_from_numpy(camera_to_world)
     cm.set_camera_pose(vtk_cam, vtk_mat, self.opencv_style)
     self.Render()
Beispiel #7
0
    def set_all_model_to_world(self, model_to_world):
        """
        Decomposes the model_to_world string into rx,ry,rx,tx,ty,rz,
        constructs a 4x4 matrix, and applies it to all models.

        :param model_to_world: [4x4] numpy ndarray, rigid transform
        """
        if model_to_world is not None:
            m2w = mu.create_matrix_from_list(model_to_world)
            vtk_matrix = mu.create_vtk_matrix_from_numpy(m2w)
            for model in self.model_loader.get_surface_models():
                model.set_user_matrix(vtk_matrix)
Beispiel #8
0
 def set_model_to_worlds(self, dict_of_transforms):
     """
     Given a dictionary of transforms, will iterate by name,
     and apply the transform to the named object.
     :param dict_of_transforms: {name, [rx, ry, rz, tx, ty, tz]}
     """
     if dict_of_transforms is not None:
         for name in dict_of_transforms:
             if name in self.model_loader.get_surface_model_names():
                 model = self.model_loader.get_surface_model(name)
                 m2w = mu.create_matrix_from_list(dict_of_transforms[name])
                 vtk_matrix = mu.create_vtk_matrix_from_numpy(m2w)
                 model.set_user_matrix(vtk_matrix)
             else:
                 raise ValueError("'" + name + "' is not in set of models.")
def test_set_pose_identity_should_give_origin():

    np_matrix = np.eye(4)
    vtk_matrix = mu.create_vtk_matrix_from_numpy(np_matrix)

    vtk_camera = vtk.vtkCamera()
    cam.set_camera_pose(vtk_camera, vtk_matrix)

    position = vtk_camera.GetPosition()
    focal_point = vtk_camera.GetFocalPoint()
    view_up = vtk_camera.GetViewUp()

    # Identity matrix should give:
    # Position at origin
    # Facing along positive z axis
    # If x points right in the image, y axis points down.
    assert position == (0, 0, 0)
    assert focal_point[2] > 0
    assert view_up == (0, -1, 0)
def test_create_vtk_matrix_4x4_from_numpy_fail_on_invalid_shape():

    array = np.ones([2, 3])

    with pytest.raises(ValueError):
        mu.create_vtk_matrix_from_numpy(array)
def test_create_vtk_matrix_4x4_from_numpy_fail_on_invalid_type():

    with pytest.raises(TypeError):
        mu.create_vtk_matrix_from_numpy("hello")
Beispiel #12
0
def test_invalid_because_not_numpy_matrix():

    with pytest.raises(TypeError):
        _ = mu.create_vtk_matrix_from_numpy("banana")
    def set_pose(self,
                 anatomy_pose_params,
                 probe_pose_params,
                 angle_of_handle,
                 anatomy_location=None
                 ):
        """
        This is the main method to call to setup the pose of all anatomy and
        for the LUS probe, and the handle.
        You can then call get_image() to get the rendered image,
        or call get_masks() to get a set of rendered masks,
        and the relevant pose parameters for ML purposes.
        The liver2camera and probe2camera are returned as 4x4 matrices.
        This is because there are multiple different parameterisations
        that the user might be working in. e.g. Euler angles, Rodrigues etc.
        :param anatomy_pose_params: [rx, ry, rz, tx, ty, tz] in deg/mm
        :param probe_pose_params: [rx, ry, rz, tx, ty, tz] in deg/mm
        :param angle_of_handle: angle in deg
        :param anatomy_location: [1x3] location of random point on liver surface
        :return: [liver2camera4x4, probe2camera4x4, angle, anatomy_location1x3]
        """
        # The 'anatomy_location' picks a point on the surface and moves
        # the LUS probe to have it's centroid based there. This is in effect
        # updating the so-called 'reference' position of the probe.
        # Subsequent offsets in [rx, ry, rz, tx, ty, tz] are from this new posn.
        p2c = self.reference_p2c

        if anatomy_location is not None:
            picked = np.zeros((4, 1))
            picked[0][0] = anatomy_location[0]
            picked[1][0] = anatomy_location[1]
            picked[2][0] = anatomy_location[2]
            picked[3][0] = 1
            picked_point = self.reference_l2c @ picked

            # This p2c then becomes the 'reference_probe2camera'.
            p2c[0][3] = picked_point[0]
            p2c[1][3] = picked_point[1]
            p2c[2][3] = picked_point[2]

        # Compute the transformation for the anatomy.
        # We assume that the anatomy has been normalised (zero-centred).
        rotation_tx = vmu.create_matrix_from_list([anatomy_pose_params[0],
                                                   anatomy_pose_params[1],
                                                   anatomy_pose_params[2],
                                                   0, 0, 0],
                                                  is_in_radians=False)
        translation_tx = vmu.create_matrix_from_list([0, 0, 0,
                                                      anatomy_pose_params[3],
                                                      anatomy_pose_params[4],
                                                      anatomy_pose_params[5]],
                                                     is_in_radians=False)
        anatomy_tx = translation_tx @ self.reference_l2c @ rotation_tx
        full_anatomy_tx_vtk = \
            vmu.create_vtk_matrix_from_numpy(anatomy_tx)

        # Now we compute the position of the probe.
        # We assume that the probe model has been normalised (zero-centred).
        probe_tx = vmu.create_matrix_from_list(probe_pose_params,
                                               is_in_radians=False)
        p2l = np.linalg.inv(self.reference_l2c) @ p2c
        probe_actor_tx = p2l @ probe_tx

        full_probe_actor_tx = anatomy_tx @ probe_actor_tx
        full_probe_actor_tx_vtk = \
            vmu.create_vtk_matrix_from_numpy(full_probe_actor_tx)

        # Apply the transforms to each actor.
        self.set_pose_with_matrices(full_probe_actor_tx_vtk,
                                    full_anatomy_tx_vtk,
                                    angle_of_handle)

        # Return parameters for final solution.
        liver_model = self.model_loader.get_surface_model('liver')
        final_l2c = \
            vmu.create_numpy_matrix_from_vtk(liver_model.actor.GetMatrix())
        probe_model = self.model_loader.get_surface_model('probe')
        final_p2c = \
            vmu.create_numpy_matrix_from_vtk(probe_model.actor.GetMatrix())

        return [final_l2c, final_p2c, angle_of_handle, anatomy_location]