visionsim.utils package

Submodules

visionsim.utils.color module

visionsim.utils.color.srgb_to_linearrgb(img: torch.Tensor | npt.NDArray[np.floating]) torch.Tensor | npt.NDArray[np.floating][source]

Performs sRGB to linear RGB color space conversion by reversing gamma correction and obtaining values that represent the scene’s intensities.

Parameters:

img (torch.Tensor | npt.NDArray) – Image to un-tonemap.

Returns:

linear rgb image.

Return type:

torch.Tensor | npt.NDArray

visionsim.utils.color.linearrgb_to_srgb(img: torch.Tensor | npt.NDArray) torch.Tensor | npt.NDArray[source]

Performs linear RGB to sRGB color space conversion to apply gamma correction for display purposes.

Parameters:

img (torch.Tensor | npt.NDArray) – Image to tonemap.

Returns:

tonemapped rgb image.

Return type:

torch.Tensor | npt.NDArray

visionsim.utils.color.rgb_to_grayscale(img: npt.NDArray[np.floating]) npt.NDArray[np.floating][source]

Performs RGB to grayscale color space conversion.

Note

If there is 4 channels, it is assumed that the last channel is alpha and it is preserved.

Parameters:

img (npt.NDArray) – Image to convert, expected to be in HWC format and normalized to [0, 1].

Returns:

grayscale image as HWC where C is 1 or 2 (if alpha channel is present).

Return type:

npt.NDArray

visionsim.utils.color.rgb_to_raw_bayer(rgb: npt.NDArray, cfa_pattern: Literal['rggb'] = 'rggb') npt.NDArray[source]

Bayer Mosaicing

Realizes a mosaiced CFA image as would be sampled by a real Bayer-patterned sensor by simply subsampling the RGB image.

Parameters:
  • rgb (npt.NDArray) – hypothetical true RGB signal

  • cfa_pattern (Literal["rggb"]) – Bayer pattern (only RGGB implemented for now)

Returns:

CFA mosaiced data

Return type:

npt.NDArray

visionsim.utils.color.raw_bayer_to_rgb(raw: npt.NDArray, cfa_pattern: Literal['rggb'] = 'rggb', method: Literal['off', 'bilinear', 'MHC04'] = 'bilinear') npt.NDArray[source]

Bayer Demosaicing

Convolution-based implementation as suggested by Malvar et al. [1].

Bilinear is simpler but visually not as nice as Malvar et al.’s method.

Alternative implementations are also available from OpenCV:

rgb = cv2.cvtColor(<uint16_array>, cv2.COLOR_BAYER_BG2BGR)[:,:,::-1],

and the colour-demosaicing library (https://pypi.org/project/colour-demosaicing):

rgb = demosaicing_CFA_Bayer_bilinear(raw, pattern=”RGGB”) rgb = demosaicing_CFA_Bayer_Malvar2004(raw, pattern=”RGGB”),

which appear to give similar results but could run faster (not benchmarked).

Parameters:
  • raw (npt.NDArray) – input array (has to be exactly 2D)

  • cfa_pattern (Literal["rggb"]) – Bayer pattern (only RGGB implemented for now)

Returns:

demosaiced RGB image

Return type:

npt.NDArray

References

visionsim.utils.imgproc module

visionsim.utils.imgproc.unsharp_mask(img: npt.ArrayLike, sigma: float = 1.0, amount: float = 1.0) npt.NDArray[source]

Unsharp-masking to sharpen an image

Borrows interface from scikit-image’s version: <https://scikit-image.org/docs/stable/api/skimage.filters.html#skimage.filters.unsharp_mask>

Parameters:
  • img (npt.ArrayLike, required) – input image, can be 2-, 3-, or 4-channel

  • sigma (float, default = 1.0) – controls extent of blurring

  • amount (float, default = 1.0) – controls how much details are amplified by

Returns:

img with unsharp mask applied,

same shape and dtype as img

Return type:

output (npt.NDArray)

References

visionsim.utils.progress module

class visionsim.utils.progress.ElapsedProgress(*columns: str | ProgressColumn, console: Console | None = None, auto_refresh: bool = True, refresh_per_second: float = 10, speed_estimate_period: float = 30.0, transient: bool = False, redirect_stdout: bool = True, redirect_stderr: bool = True, get_time: Callable[[], float] | None = None, disable: bool = False, expand: bool = False)[source]

Bases: Progress

classmethod get_default_columns() tuple[ProgressColumn, ...][source]

Overrides rich.progress.Progress’s default columns to enable showing elapsed time when finished.

class visionsim.utils.progress.PoolProgress(*args, auto_visible=True, description='[green]Total progress:', **kwargs)[source]

Bases: Progress

Convenience wrapper around rich’s Progress to enable progress bars when using multiple processes. All progressbar updates are carried out by the main process, and worker processes communicate their state via a callback obtained when a task gets added.

Example

import multiprocessing

def long_task(tick, min_len=50, max_len=200):
    import random, time

    length = random.randint(min_len, max_len)
    tick(total=length)

    for _ in range(length):
        time.sleep(0.01)
        tick(advance=1)


if __name__ == "__main__":
    with multiprocessing.Pool(4) as pool, PoolProgress() as progress:
        for i in range(25):
            tick = progress.add_task(f"Task: {i}")
            pool.apply_async(long_task, (tick, ))
        progress.wait()
        pool.close()
        pool.join()
__init__(*args, auto_visible=True, description='[green]Total progress:', **kwargs) None[source]

Initialize a PoolProgress instance.

Note

All other *args and **kwargs are passed as is to rich.progress.Progress.

Parameters:
  • auto_visible (bool, optional) – if true, automatically hides tasks that have not started or finished tasks. Defaults to True.

  • description (str, optional) – text description for the overall progress. Defaults to “[green]Total progress:”.

classmethod get_default_columns() tuple[ProgressColumn, ...][source]

Overrides rich.progress.Progress’s default columns to enable showing elapsed time when finished.

static update_task(progress: multiprocessing.Queue[dict], task_id: TaskID, **kwargs) None[source]
task_percentage(task_id: TaskID) float[source]
task_finished(task_id: TaskID) bool[source]
add_task(*args, **kwargs) UpdateFn[source]

Same as Progress.add_task except it returns a callback to update the task instead of the task-id. The returned callback is roughly equivalent to Progress.update with it’s first argument (the task-id) already filled out, except calling it will not immediately update the task’s status. The main process will perform the update asynchronously.

wait() None[source]

Block and wait for tasks to finish.

Note

This is what actually updates the progress bars, if not called before exiting the with-block no progress will be reported, and processes might be killed.

Module contents