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]
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.
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.
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.