aigarmic.plate

Class implementation for plates

Classes

Model

Helper class that provides a standard way to create an ABC using

Plate

PlateSet

Functions

split_by_grid(→ list[list[numpy.ndarray]])

Split an agar plate image into individual colony sub-images using a grid overlay.

get_image_paths() → Union[list[str], dict[str, list[str]]])

If there are no subdirectories in dir, returns a list of image paths

get_concentration_from_path(→ float)

get concentration from plate image path, e.g.

plate_set_from_dir(→ PlateSet)

Create a PlateSet from a directory of images. Images are annotated using the provided model.

Module Contents

aigarmic.plate.split_by_grid(image: numpy.ndarray, n_rows: int, n_cols: int, visualise_contours: bool = False, plate_name: str | None = None) list[list[numpy.ndarray]][source]

Split an agar plate image into individual colony sub-images using a grid overlay.

Parameters:
  • image – image file loaded using cv2.imread

  • n_rows – number of rows in the grid

  • n_cols – number of columns in the grid

  • visualise_contours – if True, display the contours found (useful for validation)

  • plate_name – name of plate to display in visualisation (useful for validation)

Returns:

matrix of sub-images

class aigarmic.plate.Model(key: list[str] | None)[source]

Bases: abc.ABC

Helper class that provides a standard way to create an ABC using inheritance.

get_key() list[str][source]

Return key to convert model output to human-readable label :return:

abstract predict(image) dict[source]
aigarmic.plate.get_image_paths(dir_path, extensions: tuple[str, Ellipsis] = ('.jpg', '.JPG')) list[str] | dict[str, list[str]][source]

If there are no subdirectories in dir, returns a list of image paths If there are subdirectories, returns a dict of ‘subdir_name’: ‘path’

Parameters:
  • dir_path – Path to directory containing images

  • extensions – Tuple of image extensions to search for

Returns:

List of image paths or dict of ‘subdir_name’: ‘path’

aigarmic.plate.get_concentration_from_path(path: str | pathlib.Path) float[source]

get concentration from plate image path, e.g. antibiotic1/0.125.jpg -> 0.125

Parameters:

path – Path to plate image

Returns:

Concentration

class aigarmic.plate.Plate(drug: str, concentration: float, image: str | cv2.typing.MatLike | None = None, n_row: int | None = None, n_col: int | None = None, growth_code_matrix: list[list[int]] | None = None, visualise_contours: bool = False, model: aigarmic.model.Model | None = None, key: list[str] | None = None)[source]
add_growth_code_matrix(growth_code_matrix: list[list[int]]) None[source]
valid_growth_code_matrix(growth_code_matrix: list[list[int]]) bool[source]
static matrix_dimensions(matrix) tuple[int, Ellipsis][source]

Get dimensions of a matrix

Parameters:

matrix – matrix to get dimensions of

Raises:

ValueError – if matrix is not 2D or is not a valid matrix

Returns:

tuple of dimensions

split_images(visualise_contours: bool = False) None[source]

Splits images into individual colony images using grid

Parameters:

visualise_contours – Visualise the contours of the plate (useful for validation of grid splitting)

import_image(image: numpy.ndarray) None[source]

Import and save image of agar plate

Parameters:

image – loaded using cv2.imread

get_colony_image(index: tuple[int, int] | None = None) tuple[numpy.ndarray, str][source]

Pulls colony image and associated code-stamp Code-stamps are strings containing, in sequence: - Antibiotic name - Antibiotic concentration - Row (i) index - Column (j) index

If no index is provided (default) a random image is given

@param index: tuple of row and column index @return: tuple of image and code-stamp (e.g., “drug_0.125_i_1_j_2”)

Link model to plate for predictions

Parameters:

model – Model to link

get_key() list[str] | None[source]

Get key from linked Model

Raises:

LookupError: No linked model to get key from

Returns:

Key (or None if one is not found)

set_key(key: list[str]) None[source]

Set plate key. Checks whether differs from linked model key (if any), and warns if different.

Parameters:

key – List of growth categories (zero-indexed)

annotate_images(model: aigarmic.model.Model | None = None) list[list[str]][source]

Annotate plate images

Parameters:

model – linked model to use for predictions

Returns:

Two-dimensional list of growth annotations

print_matrix() None[source]

Print growth matrix in human-readable format

get_inaccurate_images(threshold: float = 0.9) set[tuple[int, int]][source]

Get indexes of images with prediction accuracy below threshold :param threshold: Prediction threshold :return: Set containing indices of inaccurate images

review_poor_images(threshold: float = 0.9, save_dir: str = None) list[tuple[int, int]][source]

Review and re-classify images with prediction accuracy below threshold. Classes should be zero indexed (e.g., 0, 1, 2). Currently, only supports up to 9. If save_dir provided then colony images will also be saved to a subdirectory (named after the new classification), to allow for future use in training.

Enter new classification for each image using numbers (e.g., 0/1/2) on keyboard, press enter to skip, press esc to stop reviewing the plate.

Parameters:
  • threshold – Prediction threshold to identify inaccurate images

  • save_dir – Directory to save re-classified images

Returns:

List of indices of re-classified images

convert_growth_codes(key: list[str]) list[list[str]][source]

Convert growth codes to human-readable format using key E.g., [0, 1, 2] -> [“No growth”, “Poor growth”, “Good growth”] Sets self.growth_matrix

Parameters:

key – List of growth codes (zero-indexed)

Returns:

Growth matrix

__repr__() str[source]

Return repr(self).

__lt__(other) bool[source]

Return self<value.

__eq__(other) bool[source]

Return self==value.

__gt__(other) bool[source]

Return self>value.

__le__(other) bool[source]

Return self<=value.

__ge__(other) bool[source]

Return self>=value.

__ne__(other) bool[source]

Return self!=value.

__hash__() int[source]

Return hash(self).

class aigarmic.plate.PlateSet(plates_list: list[Plate], key: list[str] | None = None)[source]
valid_dimensions() bool[source]

Check if all plates in PlateSet have the same x and y dimensions

Returns:

True if all plates have the same dimensions, False otherwise

get_all_plates() list[Plate][source]

Returns a sorted list of all plates in the PlateSet, including the control plate

Returns:

List of Plate objects

convert_mic_matrix(mic_format: str = 'string') numpy.array[source]

Converts format of MIC matrix

Parameters:

mic_format – Format to convert to (only “string” is supported)

Returns:

matrix (array) of MIC values

calculate_mic(no_growth_key_items: tuple[int, Ellipsis]) numpy.array[source]

Calculate MIC matrix using image predictions. Sets self.mic_matrix

Parameters:

no_growth_key_items – tuple of key items that should be classified as “no growth” for MIC purposes

Returns:

MIC matrix

generate_qc() numpy.array[source]

Generate QC matrix for PlateSet, as follows:

“F” = FAIL - no growth in positive control plate, result should be disregarded “W” = WARNING - more than one change in concentration gradient. There should only be one change at the MIC breakpoint (where the images change from growth to no/poor growth). Depending on the application of the results, manual confirmation should be considered for warnings. “P” = PASS - no QC issues found

Returns:

Matrix of QC values (strings)

review_poor_images(threshold: float = 0.9, save_dir: str | None = None) list[list[tuple[int, int]]][source]

Review and re-classify images with prediction accuracy below threshold. Currently, supports up to 0–9 classes. If save_dir provided then colony images will also be saved to a subdirectory (named after the new classification), to allow for future use in training.

Enter new classification for each image using 0/1/2 on keyboard, or press enter (or esc) to skip.

Parameters:
  • threshold – Prediction threshold to identify inaccurate images

  • save_dir – Directory to save re-classified images

Returns:

List of indices of re-classified images

get_csv_data() list[dict][source]

Get MIC and QC data in a format suitable for CSV export: List of dicts containing: - Antibiotic: Antibiotic name - Position: Position of the colony (e.g., A1, B2, etc.) - MIC: MIC value - QC: QC value (P, W, F)

Returns:

List of dicts with MIC and QC data

__repr__() str[source]

Return repr(self).

aigarmic.plate.plate_set_from_dir(path: str | pathlib.Path, drug: str, model: aigarmic.model.Model, n_row: int = 8, n_col: int = 12, **kwargs) PlateSet[source]

Create a PlateSet from a directory of images. Images are annotated using the provided model.

Parameters:
  • path – directory containing plate images (.jpg) with filenames indicating antibiotic concentration

  • drug – name of drug

  • model – model file to use for predictions

  • n_row – number of rows in the plates

  • n_col – number of columns in the plates

  • kwargs – additional keyword arguments to pass to Plate constructor

Returns:

PlateSet with MIC and QC values