pyssam package
Submodules
pyssam.datasets module
Some basic datasets for unit-testing and training examples
- class pyssam.datasets.Torus(inner_radius_mean=1, outer_radius_mean=2, inner_radius_std=0.3, outer_radius_std=0.15)[source]
Bases:
object
- class pyssam.datasets.Tree(length: list = [3.8, 4.2], length_ratio: list = [0.2, 0.8], angle: list = [5, 60], num_extra_ends: int = 0)[source]
Bases:
objectCreate tree object based on a set of pre-defined parameters.
- Parameters:
length (list) – Minimum and maximum values for tree first branch segment
length_ratio (list) – Minimum and maximum values to sample for length ratio between parent and child branches
angle (list) – Minimum and maximum values to sample for angle between child branch and parent branch vectors
num_extra_ends (int) – Number of additional bifurcation levels to generate
Examples
>>> import pyssam >>> tree_class = pyssam.datasets.Tree() >>> print(tree_class.make_tree_landmarks().shape) (8, 3) >>> tree_class = Tree(num_extra_ends=2) >>> print(tree_class.make_tree_landmarks().shape) (32, 3)
- graph_to_coords(graph: DiGraph) array[source]
Convert “position” key from all nodes in graph to a numpy array of coordinates.
- Parameters:
graph (nx.DiGraph) – Graph with “position” entry in nodal attributes
pyssam.statistical_model_base module
- class pyssam.statistical_model_base.StatisticalModelBase[source]
Bases:
ABCAbstract base class for statistical model.
- compute_dataset_mean(dataset_columnvector) array[source]
Average over all samples to produce a column-vector of the mean shape, appearance, or other quantity included in model.
- Returns:
mean_columnvector
- Return type:
array_like
- create_pca_model(dataset: ndarray, desired_variance: float = 0.9) None[source]
Perform principal component analysis to create statistical model and extract modelling quantites from the PCA class.
- Parameters:
dataset (array_like) – 2D array of data to model, where each row on the first axis is one sample and each column on the second axis is e.g. shape or appearance for a landmark
desired_variance (float) – Fraction of total variance to be described by the reduced-dimension model
- Return type:
None
- Raises:
Warning – If mean of each sample in dataset not equal to 0
Warning – If standard deviation of each sample in dataset not equal to 1
- do_pca(dataset: ndarray, desired_variance: float = 0.9) Tuple[Any, int][source]
Fit principal component analysis to given dataset.
- Parameters:
dataset (array_like) – 2D array of data to model, where each row on the first axis is one sample and each column on the second axis is e.g. shape or appearance for a landmark
desired_variance (float) – Fraction of total variance to be described by the reduced-dimension model
- Returns:
pca (sklearn.decomposition._pca.PCA) – Object containing fitted PCA information e.g. components, explained variance
required_mode_number (int) – Number of principal components needed to produce desired_variance
- Raises:
Warning – If mean of each sample in dataset not equal to 0
Warning – If standard deviation of each sample in dataset not equal to 1
- fit_model_parameters(input_sample, num_modes: int = 1000000) array[source]
See docs in static function pyssam.fit_model_parameters
- landmark_data_to_column(landmark_array)[source]
Reduce an containing spatial information on landmarks in cartesian coordinates to essentially a set of stacked column-vectors. Remove any array dimensions with only one size e.g. (1, 1000, 3) -> (3000,)
- Parameters:
landmark_array (array_like) – Landmarks spatial coordinates with 2 or 3 dimensions. The final dimension should size of e.g. 3 for coordinates in 3D space.
- Returns:
reduced_array – Landmarks where the N-dimensional array is collapsed to N-1 dimensions.
- Return type:
array_like
Examples
>>> import numpy as np >>> import pyssam >>> landmarks_in = np.random.uniform(0, 100, size=(5, 100, 3)) >>> ssm = pyssam.SSM(landmarks_in) >>> print(ssm.landmark_data_to_column(landmarks_in).shape) (5, 300)
- morph_model(model_parameters: array, num_modes: int = 1000000) array[source]
See docs in static function pyssam.morph_model
- property num_landmarks
Property for number of landmarks in a shape model entry.
Should set by default in model class, e.g. in pyssam.SSM.
- scale_dataset(dataset)[source]
Take 2D or 3D array representing landmarks for multiple samples in a population, and scale to have zero mean and unit std dev.
- Parameters:
dataset (array_like) – Landmarks for multiple samples in a population, with 2 or 3 dimensions
- Returns:
scaled_dataset – Landmarks for multiple samples, each centered on mean = 0 and std dev = 1
- Return type:
array_like
- Raises:
AssertionError – If number of dimensions on input data are not equal to 2 or 3
Examples
>>> import numpy as np >>> import pyssam >>> landmarks_in = np.random.uniform(0, 100, size=(5, 100, 3)) >>> ssm = pyssam.SSM(landmarks_in) >>> scaled_landmarks = ssm.scale_dataset(landmarks_in) >>> print(abs(round(scaled_landmarks.mean(), 5)), round(scaled_landmarks.std(), 5)) 0.0 1.0
- pyssam.statistical_model_base.fit_model_parameters(input_sample, pca_model_components: ndarray, pca_model_std: array, mean_dataset_columnvector: ndarray, num_modes: int = 1000000) array[source]
Find the model parameters which best match the given input_sample with the trained pca model. Assumes that the shape can be described by input_sample pprox dataset_mean + model_modes cdot model_std.
- Parameters:
input_sample (array_like) – Column-vector representing landmark information (e.g. shape, appearance)
pca_model_components (array_like) – eigenvectors of covariance matrix, obtain by PCA.
pca_model_std (array_like) – eigenvalues of covariance matrix, obtain by PCA.
mean_dataset_columnvector (array_like) – Array of dataset mean
num_modes (int) – Number of principal components (or `modes’) to include in model to morph. By default this is set to a high number to set all modes as included.
- Returns:
model_parameters – model parameters used to perturb each principal component by some amount 1D array, where values should all be within +/- 3.
- Return type:
array_like
- pyssam.statistical_model_base.morph_model(mean_dataset_columnvector: array, pca_model_components: ndarray, model_parameters: array, pca_model_std: array, num_modes: int = 1000000) array[source]
Morph the mean dataset based on the PCA weights and variances, with some user-defined model parameters to create a new sample.
- Parameters:
mean_dataset_columnvector (array_like) – mean shape of the training data in a 1D array.
pca_model_components (array_like) – eigenvectors of covariance matrix, obtain by PCA.
model_parameters (array_like) – model parameters used to perturb each principal component by some amount 1D array, where values should all be within +/- 3.
num_modes (int) – Number of principal components (or `modes’) to include in model to morph. By default this is set to a high number to set all modes as included.
- Returns:
morphed_output – A 1D array which has been perturbed from the mean shape based on the pca_model and model_parameters.
- Return type:
array_like
- Raises:
Warning – If model parameters are outwith +/- 3
AssertionError – If number of dimension in pca_model_components not equal to 2
pyssam.ssm module
Create statistical shape model (SSM) for a set of shapes.
- class pyssam.ssm.SSM(landmarks: ndarray)[source]
Bases:
StatisticalModelBaseCreate statistical shape model for a set of shapes.
- Parameters:
landmarks (array_like) – Coordinates for landmarks in dataset, with 3 dimensions. First dimension has size equal to the number of samples. Second dimension has size equal to the number of landmarks per sample. Third dimension has size equal to the number of spatial dimensions occupied by the shapes (e.g. 3D or 2D).
Examples
>>> import numpy as np >>> import pyssam >>> num_samples = 5 >>> num_landmarks = 10 >>> landmarks = np.random.normal(size=(num_samples, num_landmarks, 3)) >>> ssm = pyssam.SSM(landmarks) >>> print(ssm.landmarks_columns_scale.shape) (5, 30) >>> print(ssm.compute_dataset_mean().shape) (30,)
pyssam.sam module
Create statistical appearance model (SAM) for a set of samples.
- class pyssam.sam.SAM(appearance: ndarray)[source]
Bases:
StatisticalModelBaseCreate statistical appearance model for a set of samples.
- Parameters:
appearance (array_like) – Appearances for landmarks in dataset, with 2 dimensions. First dimension has size equal to the number of samples. Second dimension has size equal to the number of landmarks per sample.
Examples
>>> import numpy as np >>> import pyssam >>> num_samples = 5 >>> num_landmarks = 10 >>> appearances = np.random.normal(size=(num_samples, num_landmarks)) >>> sam = pyssam.SAM(appearances) >>> print(sam.appearance_scale.shape) (5, 10, 1) >>> print(sam.compute_dataset_mean().shape) (10,)
pyssam.ssam module
Create statistical shape and appearance model (SSAM) for a set of samples.
- class pyssam.ssam.SSAM(landmarks: ndarray, appearance: ndarray)[source]
Bases:
StatisticalModelBaseCreate statistical shape and appearance model for a set of samples.
- Parameters:
landmarks (array_like) – Coordinates for landmarks in dataset, with 3 dimensions. First dimension has size equal to the number of samples. Second dimension has size equal to the number of landmarks per sample. Third dimension has size equal to the number of spatial dimensions occupied by the shapes (e.g. 3D or 2D).
appearance (array_like) – Appearances for landmarks in dataset, with 2 dimensions. First dimension has size equal to the number of samples. Second dimension has size equal to the number of landmarks per sample.
Examples
>>> import numpy as np >>> import pyssam >>> num_samples = 5 >>> num_landmarks = 10 >>> landmarks = np.random.normal(size=(num_samples, num_landmarks, 3)) >>> appearances = np.random.normal(size=(num_samples, num_landmarks)) >>> ssam = pyssam.SSAM(landmarks, appearances) >>> print(ssam.shape_appearance_columns.shape) (5, 40) >>> print(ssam.compute_dataset_mean().shape) (40,)
pyssam.utils module
Utilities to aid modelling classes.
- class pyssam.utils.AppearanceFromXray(imgs_all: ndarray, img_origin: ndarray, img_spacing: ndarray)[source]
Bases:
objectExtract appearance information from X-ray.
- Parameters:
imgs_all (array_like) – 3D array for all images in dataset, where the first dimension is the number of samples. Second and third dimensions are the image pixels.
img_origin (array_like) – 2D array for spatial coordinates of origins for all images in dataset. The first dimension is the number of samples. If one image is used, only x and y are needed to expected size is 2.
img_spacing (array_like) – 2D array for pixel spacing of all images in dataset. The first dimension is the number of samples. If one image is used, only x and y are needed to expected size is 2.
Examples
>>> import numpy as np >>> import pyssam >>> num_samples = 5 >>> num_pixels = 250 >>> image_all = np.random.rand(num_samples, num_pixels, num_pixels) >>> origin_all = np.zeros((num_samples, 2)) >>> spacing_all = np.ones((num_samples, 2)) >>> appearance_helper = pyssam.utils.AppearanceFromXray(image_all, origin_all, spacing_all) using 2D coordinates for X-ray >>> print(appearance_helper.pixel_coordinates.shape) (5, 250, 2) >>> appearance_helper = pyssam.utils.AppearanceFromXray(np.random.rand(250,250), np.zeros(3), np.ones(3)) using 3D coordinates for XR >>> print(appearance_helper.pixel_coordinates.shape) (1, 250, 3)
- all_landmark_density(landmarks: ndarray) ndarray[source]
Returns density of all landmarks in a dataset based on comparing landmark coordinates to spatial coordinates of pixels in X-rays.
- Parameters:
landmarks (array_like) – Landmark coordinates used to find appearance. Array has 3 dimensions with shape (num_samples, num_landmarks, 2)
img (array_like) – Array of grey-values from X-rays, with 3 dimensions and shape is (num_samples, num_x_pixels, num_y_pixels). Images should be square (meaning same number of pixels in x and y axes).
pixel_coordinates (array_like) – Spatial coordinates corresponding to each voxel, with shape with shape (num_samples, num_x_pixels, 2)
- Returns:
density – Normalised grey-value for each landmark location, with shape (num_samples, num_landmarks).
- Return type:
array_like
- compute_landmark_density(landmarks: ndarray, img: ndarray, pixel_coordinates: ndarray) ndarray[source]
Find the gray value at each landmark based on nearest neighbor interpolation to pixel coordinates on image. The grayvalues are all normalised to zero mean and unit variance.
- Parameters:
landmarks (array_like) – Array of all landmarks for one sample. Expected shape is 2D, where first dimension has size equal to number of landmarks and second dimension has size of two.
img (array_like) – Image to extract appearance from. Expected 2D array with equal size in first and second dimensions to represent pixels.
pixel_coordinates – Array with spatial locations of each pixel. Note that pixel_coordinates axis=1 value assumes a square figure (same number of x and y pixels)
- Returns:
landmark_grayvalue – 1D array of grey value for each landmark.
- Return type:
array_like
- Raises:
AssertionError – If shape of input arguments do not agree.
- radiograph_to_realworld_coordinates(img: ndarray, origin: ndarray, spacing: ndarray) ndarray[source]
Get 2D or 3D set of coordinates (xy or xyz) for image pixels.
- Parameters:
imgs (array_like) – 3D array for all images in dataset, where the first dimension is the number of samples. Second and third dimensions are the image pixels.
origin (array_like) – 2D array for spatial coordinates of origins for all images in dataset. The first dimension is the number of samples. Second dimension is the number of spatial dimensions If one image is used, only x and y are needed to expected size is 2.
spacing (array_like) – 2D array for pixel spacing of all images in dataset. The first dimension is the number of samples. Second dimension is the number of spatial dimensions If one image is used, only x and y are needed to expected size is 2.
- Returns:
pixel_coordinates – Array with spatial locations of each pixel.
- Return type:
array_like
- Raises:
AssertionError – If final dimension of spacing has shape not equal to 2 or 3.
AssertionError – If size of final two dimensions of img not equal to each other (square image)
pyssam.morph_mesh module
Create a surface mesh by morphing a template mesh and landmarks to a new set of landmarks. This is done using a radial basis function with a gaussian kernel. Source: Grassi et al. (2011) Medical Engineering & Physics.
- class pyssam.morph_mesh.MorphTemplateMesh(landmark_target, landmark_template, mesh_template, kernel_width=0.3, smooth=False)[source]
Bases:
objectCreate a mesh for a new set of landmarks based on a pre-existing ‘template’ mesh, for which we already have a set of landmarks. This is done using a radial basis function with a gaussian kernel. Source: Grassi et al. (2011) Medical Engineering & Physics.
Note that this requires the meshes are already aligned. In rare cases, the error may be high. In this case, I would suggest trying a template that is closer to the target if available.
Examples
>>> import pyssam >>> torus = pyssam.datasets.Torus() >>> torus_mesh_list = torus.make_dataset(2) >>> landmark_coordinates = [sample_i.points[::10] for sample_i in torus_mesh_list] >>> mesh_target_actual = torus_mesh_list[-1] >>> mesh_target_computed = pyssam.morph_mesh.MorphTemplateMesh( landmark_target=landmark_coordinates[-1], landmark_template=landmark_coordinates[0], mesh_template=torus_mesh_list[0] ).mesh_target >>> volume_error = 100.0 * abs(mesh_target_computed.volume() - mesh_target_actual.volume()) / mesh_target_actual.volume() >>> print("volume error below 5%?", volume_error < 5.0) True
- clean_new_mesh(mesh_target)[source]
Use trimesh functionality to check mesh is watertight and do some cleaning operations and smoothing if desired.
- Parameters:
mesh_target (vedo.Mesh) – vedo object containing coordinates and face connectivity for new surface mesh
- Returns:
mesh_target – vedo object containing coordinates and face connectivity for new surface mesh
- Return type:
vedo.Mesh
- create_new_mesh(coords)[source]
Create a mesh from a set of coordinates, and faces of the template mesh.
- Parameters:
coords (array_like) – A set of coordinates corresponding to vertices on a new mesh. Ordering must be consistent with self.mesh_template.points
- Returns:
mesh – vedo object containing coordinates and face connectivity for new surface mesh
- Return type:
vedo.Mesh
- do_mesh_morphing()[source]
Compute coordinates of vertices on new mesh (corresponding to landmark_target). The new coordinates are then used to create a new mesh, where face connectivity is the same as the template mesh. The new mesh is checked for watertightness, and some cleanup is done.
- gaussian_kernel(landmark_template, template_coords_i)[source]
Function to find distance between a coordinate and all surrounding landmarks. We use a Gaussian kernel to smooth how the surrounding landmarks act on the point.
- Parameters:
landmark_template (array_like) – Landmarks of the template shape (which we already have a mesh for), shape (N,3).
template_coords_i (array_like) – coordinates on the template surface mesh, shape (3).
- Returns:
distances – Scalar value of distances between all landmarks and the template mesh coordinate.
- Return type:
array_like
- get_weights(landmark_target, landmark_template, template_coords_i, kernel_function)[source]
Find weight coefficients that control how the template mesh is morphed to the new geometry, based on the distance between the ‘template’ and ‘target’ landmarks (which are in correspondence, so the ordering is consistent).
For more information, see equations (1) and (2) in Grassi et al. (2011) (Medical Engineering & Physics).
- Parameters:
landmark_target (array_like) – Landmarks of the new shape which we want to morph the mesh to, shape (N,3).
landmark_template (array_like) – Landmarks of the template shape (which we already have a mesh for), shape (N,3).
template_coords_i (array_like) – coordinates on the template surface mesh.
- Returns:
weights – Weights are coefficients that control how strongly the kernel effects each point.
- Return type:
array_like
- scale_and_align_coordinates(landmark_target, landmark_template, coords_template)[source]
Scale the template landmarks and mesh coordinates to the same size as the target landmarks.
- Parameters:
landmark_target (array_like) – Landmarks of the new shape which we want to morph the mesh to, shape (N,3).
landmark_template (array_like) – Landmarks of the template shape (which we already have a mesh for), shape (N,3).
template_coords_i (array_like) – coordinates on the template surface mesh.
- Returns:
landmark_target (array_like) – Landmarks of the new shape which we want to morph the mesh to, scaled to 1 std-dev
landmark_template (array_like) – Landmarks of the template shape, scaled to same scale as target landmarks.
template_coords_i (array_like) – coordinates on the template surface mesh, scaled to same scale as target landmarks.
Module contents
- class pyssam.SAM(appearance: ndarray)[source]
Bases:
StatisticalModelBaseCreate statistical appearance model for a set of samples.
- Parameters:
appearance (array_like) – Appearances for landmarks in dataset, with 2 dimensions. First dimension has size equal to the number of samples. Second dimension has size equal to the number of landmarks per sample.
Examples
>>> import numpy as np >>> import pyssam >>> num_samples = 5 >>> num_landmarks = 10 >>> appearances = np.random.normal(size=(num_samples, num_landmarks)) >>> sam = pyssam.SAM(appearances) >>> print(sam.appearance_scale.shape) (5, 10, 1) >>> print(sam.compute_dataset_mean().shape) (10,)
- class pyssam.SSAM(landmarks: ndarray, appearance: ndarray)[source]
Bases:
StatisticalModelBaseCreate statistical shape and appearance model for a set of samples.
- Parameters:
landmarks (array_like) – Coordinates for landmarks in dataset, with 3 dimensions. First dimension has size equal to the number of samples. Second dimension has size equal to the number of landmarks per sample. Third dimension has size equal to the number of spatial dimensions occupied by the shapes (e.g. 3D or 2D).
appearance (array_like) – Appearances for landmarks in dataset, with 2 dimensions. First dimension has size equal to the number of samples. Second dimension has size equal to the number of landmarks per sample.
Examples
>>> import numpy as np >>> import pyssam >>> num_samples = 5 >>> num_landmarks = 10 >>> landmarks = np.random.normal(size=(num_samples, num_landmarks, 3)) >>> appearances = np.random.normal(size=(num_samples, num_landmarks)) >>> ssam = pyssam.SSAM(landmarks, appearances) >>> print(ssam.shape_appearance_columns.shape) (5, 40) >>> print(ssam.compute_dataset_mean().shape) (40,)
- class pyssam.SSM(landmarks: ndarray)[source]
Bases:
StatisticalModelBaseCreate statistical shape model for a set of shapes.
- Parameters:
landmarks (array_like) – Coordinates for landmarks in dataset, with 3 dimensions. First dimension has size equal to the number of samples. Second dimension has size equal to the number of landmarks per sample. Third dimension has size equal to the number of spatial dimensions occupied by the shapes (e.g. 3D or 2D).
Examples
>>> import numpy as np >>> import pyssam >>> num_samples = 5 >>> num_landmarks = 10 >>> landmarks = np.random.normal(size=(num_samples, num_landmarks, 3)) >>> ssm = pyssam.SSM(landmarks) >>> print(ssm.landmarks_columns_scale.shape) (5, 30) >>> print(ssm.compute_dataset_mean().shape) (30,)