dictk

dictk: Digital Image Correlation Toolkit.

CLI vs. API: the dictk command-line entry points (dictk rosta, dictk checkerboard, dictk astronaut, ...) write image files to disk — that's their whole job. The corresponding Python API functions (dictk.rosta, dictk.checkerboard, dictk.astronaut, ...) do not perform any file I/O; they return NumPy arrays only. This keeps the API composable in a functional style — arrays can be piped through further functions (e.g. dictk.image.combine) before anything touches disk — and callers who do want a file call dictk.image.write explicitly as a separate, deliberate step.

 1"""dictk: Digital Image Correlation Toolkit.
 2
 3CLI vs. API: the `dictk` command-line entry points (`dictk rosta`,
 4`dictk checkerboard`, `dictk astronaut`, ...) write image files to disk —
 5that's their whole job. The corresponding Python API functions
 6(`dictk.rosta`, `dictk.checkerboard`, `dictk.astronaut`, ...) do not
 7perform any file I/O; they return NumPy arrays only. This keeps the API
 8composable in a functional style — arrays
 9can be piped through further functions (e.g. `dictk.image.combine`)
10before anything touches disk — and callers who do want a file call
11`dictk.image.write` explicitly as a separate, deliberate step.
12"""
13
14from importlib.metadata import PackageNotFoundError, version
15
16from dictk.image import astronaut, checkerboard
17from dictk.rosta import rosta
18
19try:
20    __version__ = version("dictk")
21except PackageNotFoundError:
22    __version__ = "0.0.0+unknown"
23
24__all__ = [
25    "astronaut",
26    "checkerboard",
27    "rosta",
28    "__version__",
29]
def astronaut(*, width: int = 512, height: int = 512) -> numpy.ndarray:
500def astronaut(*, width: int = 512, height: int = 512) -> np.ndarray:
501    """Load a bundled real-world grayscale reference image.
502
503    Same parameters and pixel values as the `dictk astronaut` CLI
504    command, minus the file write — see the `dictk` package docstring for
505    why the API layer stops at the array.
506
507    The source is a NASA portrait of astronaut Eileen Collins, from the
508    NASA Great Images database ("No known copyright restrictions, released
509    into the public domain."). It's bundled as a color image and converted
510    with `rgba_to_gray`; unlike `rosta` and `checkerboard`, it isn't
511    procedurally generated, so `width`/`height` other than the native
512    512x512 resize the source image (via `scipy.ndimage.zoom`) rather than
513    computing a fresh pattern at that size.
514
515    Args:
516        width: Image width in pixels. Must be >= 1.
517        height: Image height in pixels. Must be >= 1.
518
519    Returns:
520        A 2D uint8 array of shape (height, width).
521
522    Raises:
523        ValueError: If width or height is less than 1.
524    """
525    if width < 1:
526        raise ValueError(f"width {width} must be >= 1")
527    if height < 1:
528        raise ValueError(f"height {height} must be >= 1")
529
530    asset_path = importlib.resources.files("dictk") / "data" / "astronaut.png"
531    with importlib.resources.as_file(asset_path) as path:
532        color = read(path=path)
533    gray = rgba_to_gray(color)
534
535    native_height, native_width = gray.shape
536    if (width, height) == (native_width, native_height):
537        return gray
538
539    zoom_factors = (height / native_height, width / native_width)
540    resized = zoom(gray.astype(np.float64), zoom_factors, order=3)
541    return np.clip(resized, 0, 255).astype(np.uint8)

Load a bundled real-world grayscale reference image.

Same parameters and pixel values as the dictk astronaut CLI command, minus the file write — see the dictk package docstring for why the API layer stops at the array.

The source is a NASA portrait of astronaut Eileen Collins, from the NASA Great Images database ("No known copyright restrictions, released into the public domain."). It's bundled as a color image and converted with rgba_to_gray; unlike rosta and checkerboard, it isn't procedurally generated, so width/height other than the native 512x512 resize the source image (via scipy.ndimage.zoom) rather than computing a fresh pattern at that size.

Args: width: Image width in pixels. Must be >= 1. height: Image height in pixels. Must be >= 1.

Returns: A 2D uint8 array of shape (height, width).

Raises: ValueError: If width or height is less than 1.

def checkerboard( *, width: int, height: int, count_x: int = 8, count_y: int = 8) -> numpy.ndarray:
465def checkerboard(
466    *, width: int, height: int, count_x: int = 8, count_y: int = 8
467) -> np.ndarray:
468    """Generate a black-and-white checkerboard test image.
469
470    Same parameters and pixel values as the `dictk checkerboard` CLI
471    command, minus the file write — see the `dictk` package docstring for
472    why the API layer stops at the array. count_x and count_y are named for
473    the rectangles they divide the image into, not "squares": unequal
474    counts (or a width/height ratio that doesn't match count_x/count_y)
475    produce rectangular cells, not square ones.
476
477    Args:
478        width: Image width in pixels.
479        height: Image height in pixels.
480        count_x: Number of rectangles along the width. Must be >= 1.
481        count_y: Number of rectangles along the height. Must be >= 1.
482
483    Returns:
484        A 2D uint8 array of shape (height, width) with values 0 or 255.
485
486    Raises:
487        ValueError: If count_x or count_y is less than 1.
488    """
489    if count_x < 1:
490        raise ValueError(f"count_x {count_x} must be >= 1")
491    if count_y < 1:
492        raise ValueError(f"count_y {count_y} must be >= 1")
493
494    rows = (np.arange(height) * count_y // height) % 2
495    cols = (np.arange(width) * count_x // width) % 2
496    pattern = np.logical_xor(rows[:, None], cols[None, :])
497    return (pattern * 255).astype(np.uint8)

Generate a black-and-white checkerboard test image.

Same parameters and pixel values as the dictk checkerboard CLI command, minus the file write — see the dictk package docstring for why the API layer stops at the array. count_x and count_y are named for the rectangles they divide the image into, not "squares": unequal counts (or a width/height ratio that doesn't match count_x/count_y) produce rectangular cells, not square ones.

Args: width: Image width in pixels. height: Image height in pixels. count_x: Number of rectangles along the width. Must be >= 1. count_y: Number of rectangles along the height. Must be >= 1.

Returns: A 2D uint8 array of shape (height, width) with values 0 or 255.

Raises: ValueError: If count_x or count_y is less than 1.

def rosta( *, width: int = 200, height: int = 200, dot_size: float = 4.0, density: float = 0.32, smoothness: float = 2.0, random_seed: int = 42) -> numpy.ndarray:
100def rosta(
101    *,
102    width: int = 200,
103    height: int = 200,
104    dot_size: float = 4.0,
105    density: float = 0.32,
106    smoothness: float = 2.0,
107    random_seed: int = 42,
108) -> np.ndarray:
109    """Generate a Rosta speckle pattern as a uint8 grayscale image array.
110
111    Same parameters and pixel values as the `dictk rosta` CLI command, minus
112    the file write — see the `dictk` package docstring for why the API
113    layer stops at the array.
114
115    Args:
116        width: Image width in pixels.
117        height: Image height in pixels.
118        dot_size: Size factor for pattern dots (0.0 to 100.0).
119        density: Density of pattern elements (0.0 to 1.0).
120        smoothness: Smoothness factor for final blur (0.0 to 100.0).
121        random_seed: Seed for reproducible random number generation.
122
123    Returns:
124        A 2D uint8 array of shape (height, width), grayscale in [0, 255].
125
126    Raises:
127        ValueError: If dot_size, density, or smoothness is out of range.
128    """
129    rp = RostaParameters(
130        image_size=ImageSize(width=width, height=height),
131        dot_size=dot_size,
132        density=density,
133        smoothness=smoothness,
134        random_seed=random_seed,
135    )
136    pattern = rosta_pattern(rp)
137    return (pattern * 255).astype(np.uint8)

Generate a Rosta speckle pattern as a uint8 grayscale image array.

Same parameters and pixel values as the dictk rosta CLI command, minus the file write — see the dictk package docstring for why the API layer stops at the array.

Args: width: Image width in pixels. height: Image height in pixels. dot_size: Size factor for pattern dots (0.0 to 100.0). density: Density of pattern elements (0.0 to 1.0). smoothness: Smoothness factor for final blur (0.0 to 100.0). random_seed: Seed for reproducible random number generation.

Returns: A 2D uint8 array of shape (height, width), grayscale in [0, 255].

Raises: ValueError: If dot_size, density, or smoothness is out of range.

__version__ = '0.1.dev1+ge4856afda'