topostats.grainstats#

Contains class for calculating the statistics of grains - 2d raster images

Attributes#

Classes#

GrainStats

Class for calculating grain stats.

Module Contents#

topostats.grainstats.LOGGER#
topostats.grainstats.GRAIN_STATS_COLUMNS = ['Molecule Number', 'centre_x', 'centre_y', 'radius_min', 'radius_max', 'radius_mean',...#
class topostats.grainstats.GrainStats(data: numpy.ndarray, labelled_data: numpy.ndarray, pixel_to_nanometre_scaling: float, direction: str, base_output_dir: str | pathlib.Path, image_name: str = None, save_cropped_grains: bool = False, cropped_size: float = -1, plot_opts: dict = None)[source]#

Class for calculating grain stats.

data#
labelled_data#
pixel_to_nanometre_scaling#
direction#
base_output_dir#
start_point = None#
image_name#
save_cropped_grains#
cropped_size#
plot_opts#
static get_angle(point_1: tuple, point_2: tuple) float[source]#

Function that calculates the angle in radians between two points.

Parameters:
  • point1 (tuple) – Coordinate vectors for the first point to find the angle between.

  • point2 (tuple) – Coordinate vectors for the second point to find the angle between.

Returns:

angle – The angle in radians between the two input vectors.

Return type:

float

static is_clockwise(p_1: tuple, p_2: tuple, p_3: tuple) bool[source]#

Function to determine if three points make a clockwise or counter-clockwise turn.

Parameters:
  • p_1 (tuple) – First point to be used to calculate turn.

  • p_2 (tuple) – Second point to be used to calculate turn.

  • p_3 (tuple) – Third point to be used to calculate turn.

Returns:

Indicator of whether turn is clockwise.

Return type:

boolean

calculate_stats() Dict[source]#

Calculate the stats of grains in the labelled image

static calculate_points(grain_mask: numpy.ndarray)[source]#

Class method that takes a 2D boolean numpy array image of a grain and returns a list containing the co-ordinates of the points in the grain.

Parameters:

grain_mask (np.ndarray) – A 2D numpy array image of a grain. Data in the array must be boolean.

Returns:

points – A python list containing the coordinates of the pixels in the grain.

Return type:

list

static calculate_edges(grain_mask: numpy.ndarray)[source]#

Class method that takes a 2D boolean numpy array image of a grain and returns a python list of the coordinates of the edges of the grain.

Parameters:

grain_mask (np.ndarray) – A 2D numpy array image of a grain. Data in the array must be boolean.

Returns:

edges – List containing the coordinates of the edges of the grain.

Return type:

list

calculate_radius_stats(edges: list, points: list) Tuple[source]#

Class method that calculates the statistics relating to the radius. The radius in this context is the distance from the centroid to points on the edge of the grain.

Parameters:
  • edges (list) – A 2D python list containing the coordinates of the edges of a grain.

  • points (list) – A 2D python list containing the coordinates of the points in a grain.

Returns:

A tuple of the minimum, maximum, mean and median radius of the grain

Return type:

Tuple[float]

static _calculate_centroid(points: numpy.array) tuple[source]#

Calculate the centroid of a bounding box.

Parameters:

points (list) – A 2D python list containing the co-ordinates of the points in a grain.

Returns:

The co-ordinates of the centroid.

Return type:

tuple

static _calculate_displacement(edges: numpy.array, centroid: tuple) numpy.array[source]#

Calculate the displacement between the centroid and edges

static _calculate_radius(displacements) numpy.array[source]#

Calculate the radius of each point from the centroid

Parameters:
  • displacements (List[list])

  • Retrurns

  • --------

  • np.array

convex_hull(edges: list, base_output_dir: pathlib.Path, debug: bool = False)[source]#

Class method that takes a grain mask and the edges of the grain and returns the grain’s convex hull. Based off of the Graham Scan algorithm and should ideally scale in time with O(nlog(n)).

Parameters:
  • edges (list) – A python list contianing the coordinates of the edges of the grain.

  • base_output_dir (Union[str, Path]) – Directory to save output to.

  • debug (bool) – Default false. If true, debug information will be displayed to the terminal and plots for the convex hulls and edges will be saved.

Returns:

  • hull (list) – Coordinates of the points in the hull.

  • hull_indices (list) – The hull points indices inside the edges list. In other words, this provides a way to find the points from the hull inside the edges list that was passed.

  • simplices (list) – List of tuples, each tuple representing a simplex of the convex hull. These simplices are sorted such that they follow each other in counterclockwise order.

calculate_squared_distance(point_2: tuple, point_1: tuple = None) float[source]#

Function that calculates the distance squared between two points. Used for distance sorting purposes and therefore does not perform a square root in the interests of efficiency.

Parameters:
  • point_2 (tuple) – The point to find the squared distance to.

  • point_1 (tuple) – Optional - defaults to the starting point defined in the graham_scan() function. The point to find the

  • from. (squared distance)

Returns:

distance_squared – The squared distance between the two points.

Return type:

float

sort_points(points: List) List[source]#

Function to sort points in counter-clockwise order of angle made with the starting point.

Parameters:

points (list) – A python list of the coordinates to sort.

Returns:

sorted_points – A python list of sorted points.

Return type:

list

get_start_point(edges) int[source]#

Determine the index of the bottom most point of the hull when sorted by x-position.

Parameters:

edges (np.array)

graham_scan(edges: list)[source]#

A function based on the Graham Scan algorithm that constructs a convex hull from points in 2D cartesian space. Ideally this algorithm will take O( n * log(n) ) time.

Parameters:

edges (list) – A python list of coordinates that make up the edges of the grain.

Returns:

  • hull (list) – A list containing coordinates of the points in the hull.

  • hull_indices (list) – A list containing the hull points indices inside the edges list. In other words, this provides a way to find the points from the hull inside the edges list that was passed.

  • simplices (list) – A list of tuples, each tuple representing a simplex of the convex hull. These simplices are sorted such that they follow each other in counterclockwise order.

static plot(edges: list, convex_hull: list = None, file_path: pathlib.Path = None)[source]#

A function that plots and saves the coordinates of the edges in the grain and optionally the hull. The plot is saved as the file name that is provided.

Parameters:
  • coordinates (list) – A list of points to be plotted.

  • convex_hull (list) – Optional argument. A list of points that form the convex hull. Will be plotted with the coordinates if provided.

  • file_path (Path) – Path of the file to save the plot as.

calculate_aspect_ratio(edges: list, hull_simplices: numpy.ndarray, path: pathlib.Path, debug: bool = False) tuple[source]#
Class method that takes a list of edge points for a grain, and convex hull simplices and returns the width,

length and aspect ratio of the smallest bounding rectangle for the grain.

Parameters:
  • edges (list) – A python list of coordinates of the edge of the grain.

  • hull_simplices (np.ndarray) – A 2D numpy array of simplices that the hull is comprised of.

  • path (Path) – Path to the save folder for the grain.

  • debug (bool) – If true, various plots will be saved for diagnostic purposes.

Returns:

  • smallest_bounding_width (float) – The width in pixels (not nanometres), of the smallest bounding rectangle for the grain.

  • smallest_bounding_length (float) – The length in pixels (not nanometres), of the smallest bounding rectangle for the grain.

  • aspect_ratio (float) – The width divided by the length of the smallest bounding rectangle for the grain. It will always be greater or equal to 1.

static find_cartesian_extremes(rotated_points: numpy.ndarray) Dict[source]#

Find the limits of x and y of rotated points.

Parameters:

rotated_points (np.ndarray) – 2-D array of rotated points.

Returns:

Dictionary of the x and y min and max.__annotations__

Return type:

Dict

static get_shift(coords: numpy.ndarray, shape: numpy.ndarray) int[source]#

Obtains the coordinate shift to reflect the cropped image box for molecules near the edges of the image.

Parameters:
  • coords (np.ndarray) – Value representing integer coordinates which may be outside of the image.

  • shape (np.ndarray) – Array of the shape of an image.

Returns:

Max value of the shift to reflect the croped region so it stays within the image.

Return type:

np.int64

get_cropped_region(image: numpy.ndarray, length: int, centre: numpy.ndarray) numpy.ndarray[source]#

Crops the image with respect to a given pixel length around the centre coordinates.

Parameters:
  • image (np.ndarray) – The image array.

  • length (int) – The length (in pixels) of the resultant cropped image.

  • centre (np.ndarray) – The centre of the object to crop.

Returns:

Cropped array of the image.

Return type:

np.ndarray

static get_triangle_height(base_point_1: numpy.array, base_point_2: numpy.array, top_point: numpy.array) float#

Returns the height of a triangle defined by the input point vectors. :param base_point_1: a base point of the triangle, eg: [5, 3]. :type base_point_1: np.ndarray :param base_point_2: a base point of the triangle, eg: [8, 3]. :type base_point_2: np.ndarray :param top_point: the top point of the triangle, defining the height from the line between the two base points, eg: [6,10]. :type top_point: np.ndarray

Returns:

The height of the triangle - ie the shortest distance between the top point and the line between the two base points.

Return type:

Float

static get_max_min_ferets(edge_points: list)#

Returns the minimum and maximum feret diameters for a grain. These are defined as the smallest and greatest distances between a pair of callipers that are rotating around a 2d object, maintaining contact at all times.

Parameters:

edge_points (list) – a list of the vector positions of the pixels comprising the edge of the grain. Eg: [[0, 0], [1, 0], [2, 1]]

Returns:

  • min_feret (float) – the minimum feret diameter of the grain

  • max_feret (float) – the maximum feret diameter of the grain

Notes

The method starts out by calculating the upper and lower convex hulls using an algorithm based on the Graham Scan Algorithm [1]. Using these upper and lower hulls, the callipers are simulated as rotating clockwise around the grain. We determine the order in which vertices are encountered by comparing the gradients of the slopes between vertices. An array of pairs of points that are in contact with either calliper at a given time is created in order to be able to calculate the maximum feret diameter. The minimum diameter is a little tricky, since it won’t simply be the shortest distance between two contact points, but it will occur somewhere during the rotation around a pair of contact points. It turns out that the point will always be such that two points are in contact with one calliper while the other calliper is in contact with another point. We can use this fact to be sure of finding the smallest feret diameter, simply by testing each triangle of 3 contact points as we iterate, finding the height of the triangle that is formed between the three aforementioned points, as this will be the perpendicular distance between the callipers.

References

[1] Graham, R.L. (1972).

“An Efficient Algorithm for Determining the Convex Hull of a Finite Planar Set”. Information Processing Letters. 1 (4): 132-133. doi:10.1016/0020-0190(72)90045-2.