finitedepth#

Package for image analysis of finite depth dip coating.

To analyze with command line, specify the parameters in configuration file(s) and run:

finitedepth analyze <file1> [<file2> ...]

Submodules#

Package Contents#

Classes#

CoatingLayer

Basic implementation of coating layer without any analysis.

CoatingLayerBase

Abstract base class for coating layer object.

RectLayerShape

Coating layer over rectangular substrate.

Reference

Reference image with ROIs specified.

ReferenceBase

Abstract base class for reference object.

PolySubstrateBase

Abstract base class for substrate whose cross section is a simple polygon.

RectSubstrate

Substrate having rectangular cross section.

Substrate

Basic implementation of substrate without any geometric specification.

SubstrateBase

Abstract base class for substrate object.

Functions#

get_sample_path(*paths)

Get path to sample file.

analyze_files(*paths[, recursive, entries])

Perform analysis from configuration files.

class finitedepth.CoatingLayer(image, substrate, *, tempmatch=None)[source]#

Bases: CoatingLayerBase[finitedepth.substrate.SubstrateBase, CoatingLayerData]

Basic implementation of coating layer without any analysis.

Parameters:
  • image (numpy.typing.NDArray[numpy.uint8]) – Binary target image.

  • substrate (SubstTypeVar) – Substrate instance.

  • tempmatch (tuple[tuple[int, Ellipsis], float] | None) – Pre-computed template matching result.

Examples

Construct substrate instance first.

>>> import cv2
>>> from finitedepth import get_sample_path, Reference, Substrate
>>> img = cv2.imread(get_sample_path("ref.png"), cv2.IMREAD_GRAYSCALE)
>>> _, bin = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
>>> ref = Reference(bin, (10, 10, 1250, 200), (100, 100, 1200, 500))
>>> subst = Substrate(ref)
>>> import matplotlib.pyplot as plt 
>>> plt.imshow(subst.draw()) 
../../_images/index-12.png

Then, construct coating layer instance.

>>> from finitedepth import CoatingLayer
>>> img = cv2.imread(get_sample_path("coat.png"), cv2.IMREAD_GRAYSCALE)
>>> _, bin = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
>>> coat = CoatingLayer(bin, subst)
>>> plt.imshow(coat.draw()) 
../../_images/index-21.png
DataType#

Return CoatingLayerData.

valid()[source]#

Return true, as analysis is not performed at all.

Return type:

bool

analyze()[source]#

Return empty CoatingLayerData.

draw(subtraction_mode='none', layer_color=(255, 0, 0), layer_thickness=-1)[source]#

Subtract the template match result and paint the coating layer.

Parameters:
  • subtraction_mode ({‘none’, ‘template’, ‘substrate’, ‘full’}) – Subtraction mode. ‘template’ and ‘substrate’ removes overlapping template region and substrate region, respectively. ‘full’ removes both.

  • layer_color (tuple[int, int, int]) – Layer color for cv2.drawContours().

  • layer_thickness (int) – Layer thickness for cv2.drawContours().

Return type:

numpy.typing.NDArray[numpy.uint8]

class finitedepth.CoatingLayerBase(image, substrate, *, tempmatch=None)[source]#

Bases: abc.ABC, Generic[SubstTypeVar, DataTypeVar]

Abstract base class for coating layer object.

Coating layer object stores SubstrateBase object and target image, which is a binary image of coated substrate. The role of coating layer object is to acquire coating layer region by template matching and analyze its shape.

External API can use the following members to get analysis results of concrete subclasses.

Parameters:
  • image (numpy.typing.NDArray[numpy.uint8]) – Binary target image.

  • substrate (SubstTypeVar) – Substrate instance storing binary reference image.

  • tempmatch (tuple[tuple[int, Ellipsis], float] | None) – Pre-computed template matching result. External constructor can pass this argument to force the template matching result. If not passed, match_template() performs matching.

property image: numpy.typing.NDArray[numpy.uint8]#

Binary target image.

For immutability, this image is not writable.

Return type:

numpy.typing.NDArray[numpy.uint8]

property substrate: SubstTypeVar#

Substrate instance which contains substrate and reference information.

Return type:

SubstTypeVar

property tempmatch: tuple[tuple[int, Ellipsis], float]#

Template matching location and score.

Return type:

tuple[tuple[int, Ellipsis], float]

DataType: type[DataTypeVar]#

Return type of analyze.

Concrete subclass must assign this attribute with dataclass type.

match_template(image, template)[source]#

Perform template matching between image and template.

Template matching is performed using cv2.matchTemplate() with cv2.TM_SQDIFF_NORMED. Subclass may override this method to apply other algorithm.

Parameters:
  • image (numpy.typing.NDArray[numpy.uint8]) – Binary target image.

  • template (numpy.typing.NDArray[numpy.uint8]) – Binary template image.

Return type:

tuple[tuple[int, Ellipsis], float]

substrate_point()[source]#

Upper left point of the substrate image in target image.

Returns:

Coordinates in (x, y).

Return type:

numpy.typing.NDArray[numpy.int32]

coated_substrate()[source]#

Coated substrate region.

Returns:

Target image without artifacts, e.g., bath surface.

Return type:

numpy.typing.NDArray[numpy.bool_]

extract_layer()[source]#

Coating layer region extracted from target image.

Return type:

numpy.typing.NDArray[numpy.bool_]

abstract valid()[source]#

Return if the analysis can be performed as expected.

Sometimes, the coating layer instance should be constructed but not analyzed at all. For example, the coating video may contains frames where the capillary bridge is not ruptured yet. This method allows analyzer to skip such instances.

Return type:

bool

abstract analyze()[source]#

Return analysis result as dataclass.

Return type must be DataType.

Return type:

DataTypeVar

abstract draw(*args, **kwargs)[source]#

Return visualization result.

Return type:

numpy.typing.NDArray[numpy.uint8]

class finitedepth.RectLayerShape(image, substrate, opening_ksize, reconstruct_radius, roughness_measure, ifd_gsize=None, *, tempmatch=None)[source]#

Bases: CoatingLayerBase[finitedepth.substrate.RectSubstrate, RectLayerShapeData]

Coating layer over rectangular substrate.

Parameters:
  • image (numpy.typing.NDArray[numpy.uint8]) – Binary target image.

  • substrate (finitedepth.substrate.RectSubstrate) – Substrate instance.

  • opening_ksize (tuple[int, int]) – Kernel size for morphological operation. Elements must be zero or odd number.

  • reconstruct_radius (int) – Radius of the “safe zone” for noise removal. Imaginary circles with this radius are drawn on bottom corners of the substrate. Connected components not passing these circles are regarded as image artifacts.

  • roughness_measure (str) –

    Similarity measure to quantify roughness.

    ’DTW’

    Dynamice time warping.

    ’SDTW’

    Root mean square of dynamic time warping.

    ’IFD’

    Approximated integral Fréchet distance. Requires ifd_gsize.

  • ifd_gsize (float | None) – Grid size to approximate integral Fréchet distance. Ignored if roughness_measure is not ‘IFD’.

  • tempmatch (tuple[tuple[int, Ellipsis], float] | None) – Pre-computed template matching result.

Examples

Construct substrate instance first.

>>> import cv2
>>> from finitedepth import get_sample_path, Reference, RectSubstrate
>>> img = cv2.imread(get_sample_path("ref.png"), cv2.IMREAD_GRAYSCALE)
>>> _, bin = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
>>> ref = Reference(bin, (10, 10, 1250, 200), (100, 100, 1200, 500))
>>> subst = RectSubstrate(ref, 3.0, 1.0, 0.01)
>>> import matplotlib.pyplot as plt 
>>> plt.imshow(subst.draw()) 
../../_images/index-31.png

Then, construct coating layer instance.

>>> from finitedepth import RectLayerShape
>>> img = cv2.imread(get_sample_path("coat.png"), cv2.IMREAD_GRAYSCALE)
>>> _, bin = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
>>> coat = RectLayerShape(bin, subst, (1, 1), 50, "IFD", 3)
>>> plt.imshow(
...     coat.draw(conformality_step=10, roughness_step=5)
... ) 
../../_images/index-41.png
property opening_ksize: tuple[int, int]#

Kernel size for morphological operation.

Return type:

tuple[int, int]

property reconstruct_radius: int#

Radius of the “safe zone” for noise removal.

Return type:

int

property roughness_measure: str#

Similarity measure to quantify roughness.

Return type:

str

property ifd_gsize: float | None#

Grid size to quantify roughness if roughness_measure is IFD.

Return type:

float | None

DataType#

Return RectLayerShapeData.

valid#
layer_contours()[source]#

Find contours of coating layer region.

This method finds external contours of extract_layer(). Each contour encloses each discrete region of coating layer.

Return type:

tuple[numpy.typing.NDArray[numpy.int32], Ellipsis]

interfaces()[source]#

Find solid-liquid interfaces.

A substrate can have contact with multiple discrete coating layer regions, and a single coating layer region can have multiple contacts to the substrate. This method returns indices for contour() where solid-liquid interfaces start and stop.

Returns:

tuple of arrays. i-th array represents i-th coating layer region in layer_contours(). Shape of the array is (N, 2), where N is the number of contacts the coating layer region makes. Each column represents starting and ending indices for the interface interval in substrate contour.

Return type:

tuple[numpy.typing.NDArray[numpy.int64], Ellipsis]

Note

Each interval describes continuous patch on the substrate contour covered by the layer. To acquire the interface points, slice substrate’s contour() with the indices.

contour()[source]#

Contour of the entire coated substrate.

Return type:

numpy.typing.NDArray[numpy.int32]

capbridge_broken()[source]#

Check if capillary bridge is ruptured.

As substrate is withdrawn from fluid bath, capillary bridge forms between the coating layer and bulk fluid and then ruptures.

Return type:

bool

extract_layer()[source]#

Coating layer region extracted from target image.

Error pixels are removed by performing morphological operation and removing the disconnected components that are far from the substrate.

Return type:

numpy.typing.NDArray[numpy.bool_]

surface()[source]#

Liquid-gas interface of the coating layer.

Substrate surface exposed to air is considered to be covered by coating layer with zero thickness.

Returns:

Starting and ending indices for the surface interval in coated substrate contour.

Return type:

tuple[numpy.int64, numpy.int64]

Note

To acquire the surface points, slice contour() with the indices.

uniform_layer()[source]#

Imaginary uniform layer.

Uniform layer is a parallel curve [1] of substrate surface which has the same cross-sectional area as the actual coating layer.

Returns:

Thickness and polyline vertices of the uniform layer.

Return type:

tuple[numpy.float64, numpy.typing.NDArray[numpy.float64]]

conformality()[source]#

DTW-based conformality of the coating layer.

Returns:

Conformality between layer surface and substrate surface and its pair of points in curve space.

Return type:

tuple[float, numpy.typing.NDArray[numpy.int32]]

roughness()[source]#

Similarity-based surface roughness of the coating layer.

Returns:

Roughness between layer surface and uniform layer and its pair of points in curve space.

Return type:

tuple[float, numpy.typing.NDArray[numpy.float64]]

max_thickness()[source]#

Regional maximum thicknesses.

Coating layer is segmented using RectSubstrate.sideline_intersections(). Points on layer surface and sideline for maximum distance in each region are found.

Returns:

tuple of two arrays. The first array contains maximum thickness values on left, bottom, and right region. Value of 0 indicates no coating layer on that region. The second array contains points on layer surface and substrate lines for the maximum thickness. Shape of the array is (3, 2, 2); 1st axis indicates left, bottom and right region, 2nd axis indicates layer surface and substrate line, and 3rd axis indicates (x, y) coordinates.

Return type:

tuple[numpy.typing.NDArray[numpy.float64], numpy.typing.NDArray[numpy.float64]]

analyze()[source]#

Return RectLayerShapeData.

draw(background_mode='image', subtraction_mode='none', layer_color=(255, 0, 0), layer_thickness=-1, contactline_color=(0, 255, 0), contactline_thickness=1, maxthickness_color=(0, 255, 0), maxthickness_thickness=1, uniformlayer_color=(0, 0, 255), uniformlayer_thickness=1, conformality_color=(0, 0, 255), conformality_thickness=1, conformality_step=1, roughness_color=(0, 0, 255), roughness_thickness=1, roughness_step=1)[source]#

Visualize the analysis result.

  1. Draw the substrate with by PaintMode.

  2. Display the template matching result with SubtractionMode.

  3. Draw coating layer and contact line.

  4. If capillary bridge is broken, draw regional maximum thicknesses, uniform layer, conformality pairs and roughness pairs.

Parameters:
  • background_mode ({‘image’, ‘empty’}) – Determine how background is drawn. ‘image’ draws original background image while ‘empty’ draws on empty frame.

  • subtraction_mode ({‘none’, ‘template’, ‘substrate’, ‘full’}) – Subtraction mode. ‘template’ and ‘substrate’ removes overlapping template region and substrate region, respectively. ‘full’ removes both.

  • layer_color (tuple[int, int, int]) – Layer contour’s color for cv2.drawContours().

  • layer_thickness (int) – Layer contour’s thickness for cv2.drawContours().

  • contactline_color (tuple[int, int, int]) – Contact line’s color for cv2.line().

  • contactline_thickness (int) – Contact line’s thickness for cv2.line().

  • maxthickness_color (tuple[int, int, int]) – Regional maximum thickness line’s color for cv2.polylines().

  • maxthickness_thickness (int) – Regional maximum thickness line’s thickness for cv2.polylines().

  • uniformlayer_color (tuple[int, int, int]) – Imaginary uniform layer’s color for cv2.polylines().

  • uniformlayer_thickness (int) – Imaginary uniform layer’s thickness for cv2.polylines().

  • conformality_color (tuple[int, int, int]) – Conformality pairs’ color for cv2.polylines().

  • conformality_thickness (int) – Conformality pairs’ thickness for cv2.polylines().

  • conformality_step (int) – Step size to skip conformality pairs.

  • roughness_color (tuple[int, int, int]) – Roughness pairs’ color for cv2.polylines().

  • roughness_thickness (int) – Roughness pairs’ thickness for cv2.polylines().

  • roughness_step (int) – Step size to skip roughness pairs.

Return type:

numpy.typing.NDArray[numpy.uint8]

class finitedepth.Reference(image, templateROI=(0, 0, None, None), substrateROI=(0, 0, None, None))[source]#

Bases: ReferenceBase[ReferenceData]

Reference image with ROIs specified.

Parameters:
  • image (numpy.typing.NDArray[numpy.uint8]) – Binary reference image.

  • templateROI (DynamicROI) – ROI for template image.

  • substrateROI (DynamicROI) – ROI for substrate image.

Examples

>>> import cv2
>>> from finitedepth import get_sample_path, Reference
>>> img = cv2.imread(get_sample_path("ref.png"), cv2.IMREAD_GRAYSCALE)
>>> _, bin = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
>>> ref = Reference(bin, (10, 10, 1250, 200), (100, 100, 1200, 500))
>>> import matplotlib.pyplot as plt 
>>> plt.imshow(ref.draw()) 
../../_images/index-5.png
property templateROI: StaticROI#

ROI for template image.

Return type:

StaticROI

property substrateROI: StaticROI#

ROI for substrate image.

Return type:

StaticROI

DataType#

Return ReferenceData.

analyze()[source]#

Return empty ReferenceData.

class finitedepth.ReferenceBase(image)[source]#

Bases: abc.ABC, Generic[DataTypeVar]

Abstract base class for reference object.

Reference object stores reference image, which is a binary image of uncoated substrate. It also contains ROIs for template region and substrate region in the reference image.

External API can use the following members to get analysis results of concrete subclasses.

Parameters:

image (numpy.typing.NDArray[numpy.uint8]) – Binary reference image.

property image: numpy.typing.NDArray[numpy.uint8]#

Binary reference image.

For immutability, this image is not writable.

Return type:

numpy.typing.NDArray[numpy.uint8]

abstract property templateROI: StaticROI#

ROI for template image.

Return type:

StaticROI

abstract property substrateROI: StaticROI#

ROI for substrate image.

Return type:

StaticROI

DataType: type[DataTypeVar]#

Return type of analyze.

Concrete subclass must assign this attribute with dataclass type.

abstract analyze()[source]#

Return analysis result as dataclass.

Return type must be DataType.

Return type:

DataTypeVar

draw(templateColor=(255, 0, 0), templateThickness=1, substrateColor=(0, 255, 0), substrateThickness=1)[source]#

Return visualization result in RGB format.

Parameters:
  • templateColor (tuple[int, int, int]) – Template ROI box color for cv2.rectangle().

  • templateThickness (int) – Template ROI box line width for cv2.rectangle().

  • substrateColor (tuple[int, int, int]) – Substrate ROI box color for cv2.rectangle().

  • substrateThickness (int) – Substrate ROI box line width for cv2.rectangle().

Return type:

numpy.typing.NDArray[numpy.uint8]

class finitedepth.PolySubstrateBase(reference)[source]#

Bases: SubstrateBase[RefTypeVar, DataTypeVar]

Abstract base class for substrate whose cross section is a simple polygon.

A simple polygon does not have intersection nor hole [2]. Smooth corners are allowed.

Parameters:

reference (RefTypeVar) – Reference instance which contains the substrate image.

Note

Substrate image should not have:
  • Multiple substrates in one image

  • Multiple contours (e.g. substrate with holes)

abstract property sigma: float#

Standard deviation of gaussian filter to smooth the noise in contour.

Return type:

float

abstract property hough_parameters: tuple[float, float, int]#

Parameters for Hough line transformation.

Returns:

Tuple of numbers.

  • rho: Resolution of \(\rho\).

  • theta: Resolution of \(\theta\).

  • step: Step size to jump the points for better performance.

Return type:

tuple[float, float, int]

abstract n()[source]#

Number of polygon vertices.

Return type:

int

region_points()[source]#

Return an upper center point of the substrate image.

Substrate ROI in reference image must be selected so that this point falls into substrate region.

Return type:

numpy.typing.NDArray[numpy.int32]

contour()[source]#

Return the polygon contour.

Return type:

numpy.typing.NDArray[numpy.int32]

vertices()[source]#

Find n() vertices of the polygon.

A vertex is a point where two sides of a polygon meet [3]. When the sides are curves, the vertices are defined as local extrema of curvature [4].

The vertices are found by smoothing contour() with sigma and finding the local extrema of curvature [5].

Returns:

Indices of the vertex points in contour().

Return type:

numpy.typing.NDArray[numpy.int32]

sides()[source]#

Find n() sides of the polygon.

The sides are found by slicing contour() by vertices().

Returns:

Tuple of array containing points on each side of the polygon contour. The arrays are sorted so that the side containing the first point of the contour comes first.

Return type:

tuple[numpy.typing.NDArray[numpy.int32], Ellipsis]

Note

Sides can be noisy and curved. Use sidelines() to get linear models.

The term “side” is used instead of “edge” to avoid confusion from other image processing methods (e.g. Canny edge detection).

sidelines()[source]#

Find n() sidelines of the polygon.

Sideline is the line that contains one side of the polygon [6]. The sidelines are found by performing Hough line transformation on sides() with hough_parameters.

Returns:

Vector of line parameters in \((\rho, \theta)\). \(\rho\) is the distance from the coordinate origin. \(\theta\) is the angle of normal vector from the origin to the line.

Return type:

numpy.typing.NDArray[numpy.float32]

Note

Range of angle is \(\theta \in (-\frac{3 \pi}{2}, \frac{\pi}{2}]\). Arctangent direction can be acquired by \(\theta + \frac{\pi}{2}\).

sideline_intersections()[source]#

Find intersections of sidelines().

Return type:

numpy.typing.NDArray[numpy.float32]

class finitedepth.RectSubstrate(reference, sigma, rho_thres, theta_thres, hough_step=1)[source]#

Bases: PolySubstrateBase[finitedepth.reference.ReferenceBase, RectSubstData]

Substrate having rectangular cross section.

Parameters:
  • reference (finitedepth.reference.ReferenceBase) – Reference instance which contains the substrate image.

  • sigma (float) – Standard deviation of gaussian filter to smooth the noise in contour.

  • rho_thres (float) – Hough line transformation parameters.

  • theta_thres (float) – Hough line transformation parameters.

  • hough_step (int) – Hough line transformation parameters.

Examples

>>> import cv2
>>> from finitedepth import get_sample_path, Reference, RectSubstrate
>>> img = cv2.imread(get_sample_path("ref.png"), cv2.IMREAD_GRAYSCALE)
>>> _, bin = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
>>> ref = Reference(bin, (10, 10, 1250, 200), (100, 100, 1200, 500))
>>> subst = RectSubstrate(ref, 3.0, 1.0, 0.01)
>>> import matplotlib.pyplot as plt 
>>> plt.imshow(subst.draw()) 
../../_images/index-6.png
property sigma: float#

Sigma value passed to the constructor.

Return type:

float

property hough_parameters: tuple[float, float, int]#

Hough line transformation parameters passed to the constructor.

Return type:

tuple[float, float, int]

DataType#

Return RectSubstData.

n()[source]#

Number of vertices of rectangle, which is 4.

Return type:

int

analyze()[source]#

Return RectSubstData.

draw(mode='image', vertice_color=(0, 255, 0), vertice_thickness=1, vertice_markerSize=20, sideline_color=(0, 0, 255), sideline_thickness=1)[source]#

Draw substrate image and show vertices and sidelines.

Parameters:
  • mode ({‘image’, ‘contour’}) – Draw mode. ‘image’ draws image(), while ‘contour’ draws contour().

  • vertice_color (tuple[int, int, int]) – Vertice marker color for cv2.drawMarker().

  • vertice_thickness (int) – Vertice marker thickness for cv2.drawMarker().

  • vertice_markerSize (int) – Vertice marker size for cv2.drawMarker().

  • sideline_color (tuple[int, int, int]) – Sideline color for cv2.line().

  • sideline_thickness (int) – Sideline thickness for cv2.line().

Return type:

numpy.typing.NDArray[numpy.uint8]

class finitedepth.Substrate(reference)[source]#

Bases: SubstrateBase[finitedepth.reference.ReferenceBase, SubstrateData]

Basic implementation of substrate without any geometric specification.

Parameters:

reference (RefTypeVar) – Reference instance which contains the substrate image.

Examples

>>> import cv2
>>> from finitedepth import get_sample_path, Reference, Substrate
>>> img = cv2.imread(get_sample_path("ref.png"), cv2.IMREAD_GRAYSCALE)
>>> _, bin = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
>>> ref = Reference(bin, (10, 10, 1250, 200), (100, 100, 1200, 500))
>>> subst = Substrate(ref)
>>> import matplotlib.pyplot as plt 
>>> plt.imshow(subst.draw()) 
../../_images/index-7.png
DataType#

Return SubstrateData.

region_points()[source]#

Return an upper center point of the substrate image.

Substrate ROI in reference image must be selected so that this point falls into substrate region.

Return type:

numpy.typing.NDArray[numpy.int32]

analyze()[source]#

Return empty SubstrateData.

draw()[source]#

Return image() in RGB.

Return type:

numpy.typing.NDArray[numpy.uint8]

class finitedepth.SubstrateBase(reference)[source]#

Bases: abc.ABC, Generic[RefTypeVar, DataTypeVar]

Abstract base class for substrate object.

Substrate object stores substrate image, which is a binary image of bare substrate acquired from ReferenceBase object. The role of substrate object is to analyze the shape of the bare substrate.

External API can use the following members to get analysis results of concrete subclasses.

Parameters:

reference (RefTypeVar) – Reference instance which contains the substrate image.

property reference: RefTypeVar#

Reference instance which contains the substrate image.

Return type:

RefTypeVar

DataType: type[DataTypeVar]#

Return type of analyze.

Concrete subclass must assign this attribute with dataclass type.

image()[source]#

Substrate image from reference().

Return type:

numpy.typing.NDArray[numpy.uint8]

abstract region_points()[source]#

Coordinates of points representing each substrate region.

Substrate image can have multiple disconnected substrate regions. Concrete classes should implement this method to return coordinates of points representing each region.

Returns:

(N, 2)-shaped array, where N is the number of substrate regions. Column should be the coordinates of points in (x, y).

Return type:

numpy.typing.NDArray[numpy.int32]

Note

These points are used to distinguish substrate regions from other foreground pixels, and give indices to each region.

As higher-level methods are expected to rely on this method, it is best to keep this method simple and independent.

regions()[source]#

Labelled image of substrate regions.

Substrate regions are determined as connected component including a point in region_points().

Returns:

Labelled image. Value of i represents i-th region in region_points(). -1 represents background.

Return type:

numpy.typing.NDArray[numpy.int8]

Note

Maximum number of regions is 128.

contours(region)[source]#

Find contours of a substrate region.

Parameters:

region (int) – Label of the region from regions().

Returns:

Tuple of the result of cv2.findContours().

Return type:

tuple[tuple[numpy.typing.NDArray[numpy.int32], Ellipsis], numpy.typing.NDArray[numpy.int32]]

Note

Contours are dense, i.e., no approximation is made.

abstract analyze()[source]#

Return analysis result as dataclass.

Return type must be DataType.

Return type:

DataTypeVar

abstract draw(*args, **kwargs)[source]#

Return visualization result.

Return type:

numpy.typing.NDArray[numpy.uint8]

finitedepth.get_sample_path(*paths)[source]#

Get path to sample file.

Parameters:

paths (str) – Subpaths under finitedepth/samples/ directory.

Returns:

Absolute path to the sample file.

Return type:

str

Examples

>>> from finitedepth import get_sample_path
>>> get_sample_path() 
'path/finitedepth/samples'
>>> get_sample_path("myfile") 
'path/finitedepth/samples/myfile'
finitedepth.analyze_files(*paths, recursive=False, entries=None)[source]#

Perform analysis from configuration files.

Supported formats:
  • YAML

  • JSON

Each file can have multiple entries. Each entry must have type field which specifies the analyzer. For example, the following YAML file contains foo entry which is analyzed by Foo analyzer.

foo:
    type: Foo
    ...

Analyzers are searched and loaded from entry point group "finitedepth.analyzers", and must have the following signature:

  • entry name (str)

  • entry fields (dict)

Parameters:
  • paths (str) – Glob pattern for configuration file paths.

  • recursive (bool) – If True, search paths recursively.

  • entries (list[str] | None) – Regular expression for entries. If passed, only the matching entries are analyzed.

Returns:

Whether the analysis is finished without error.

Return type:

bool