vkit.mechanism.distortion.photometric.opt

 1# Copyright 2022 vkit-x Administrator. All Rights Reserved.
 2#
 3# This project (vkit-x/vkit) is dual-licensed under commercial and SSPL licenses.
 4#
 5# The commercial license gives you the full rights to create and distribute software
 6# on your own terms without any SSPL license obligations. For more information,
 7# please see the "LICENSE_COMMERCIAL.txt" file.
 8#
 9# This project is also available under Server Side Public License (SSPL).
10# The SSPL licensing is ideal for use cases such as open source projects with
11# SSPL distribution, student/academic purposes, hobby projects, internal research
12# projects without external distribution, or other projects where all SSPL
13# obligations can be met. For more information, please see the "LICENSE_SSPL.txt" file.
14from typing import Optional, Sequence
15from enum import unique, Enum
16
17import numpy as np
18import numpy.typing as npt
19import attrs
20
21from vkit.element import Image, ImageMode
22
23
24def extract_mat_from_image(
25    image: Image,
26    dtype: npt.DTypeLike,
27    channels: Optional[Sequence[int]] = None,
28) -> np.ndarray:
29    mat = image.mat
30    if channels:
31        mat: np.ndarray = mat[:, :, channels]
32    return mat.astype(dtype)
33
34
35@unique
36class OutOfBoundBehavior(Enum):
37    CLIP = 'clip'
38    CYCLE = 'cycle'
39
40
41def clip_mat_back_to_uint8(mat: np.ndarray) -> np.ndarray:
42    return np.clip(mat, 0, 255).astype(np.uint8)
43
44
45def cycle_mat_back_to_uint8(mat: np.ndarray) -> np.ndarray:
46    return (mat % 256).astype(np.uint8)
47
48
49def handle_out_of_bound_and_dtype(mat: np.ndarray, oob_behavior: OutOfBoundBehavior):
50    mat = np.round(mat)
51    if oob_behavior == OutOfBoundBehavior.CLIP:
52        mat = clip_mat_back_to_uint8(mat)
53    elif oob_behavior == OutOfBoundBehavior.CYCLE:
54        mat = cycle_mat_back_to_uint8(mat)
55    else:
56        raise NotImplementedError()
57    return mat
58
59
60def generate_new_image(
61    image: Image,
62    new_mat: np.ndarray,
63    channels: Optional[Sequence[int]] = None,
64):
65    if channels:
66        new_image = image.copy()
67        with new_image.writable_context:
68            new_image.mat[:, :, channels] = new_mat
69    else:
70        assert image.mat.shape == new_mat.shape
71        new_image = attrs.evolve(image, mat=new_mat)
72
73    return new_image
74
75
76def to_rgb_image(image: Image, mode: ImageMode):
77    if mode not in (ImageMode.GRAYSCALE, ImageMode.RGB):
78        image = image.to_rgb_image()
79    return image
80
81
82def to_original_image(image: Image, mode: ImageMode):
83    if mode not in (ImageMode.GRAYSCALE, ImageMode.RGB):
84        image = image.to_target_mode_image(mode)
85    return image
def extract_mat_from_image( image: vkit.element.image.Image, dtype: Union[numpy.dtype[Any], NoneType, Type[Any], numpy.__dtype_like._SupportsDType[numpy.dtype[Any]], str, Tuple[Any, int], Tuple[Any, Union[SupportsIndex, Sequence[SupportsIndex]]], List[Any], numpy.__dtype_like._DTypeDict, Tuple[Any, Any]], channels: Union[Sequence[int], NoneType] = None) -> numpy.ndarray:
25def extract_mat_from_image(
26    image: Image,
27    dtype: npt.DTypeLike,
28    channels: Optional[Sequence[int]] = None,
29) -> np.ndarray:
30    mat = image.mat
31    if channels:
32        mat: np.ndarray = mat[:, :, channels]
33    return mat.astype(dtype)
class OutOfBoundBehavior(enum.Enum):
37class OutOfBoundBehavior(Enum):
38    CLIP = 'clip'
39    CYCLE = 'cycle'

An enumeration.

CLIP = <OutOfBoundBehavior.CLIP: 'clip'>
CYCLE = <OutOfBoundBehavior.CYCLE: 'cycle'>
Inherited Members
enum.Enum
name
value
def clip_mat_back_to_uint8(mat: numpy.ndarray) -> numpy.ndarray:
42def clip_mat_back_to_uint8(mat: np.ndarray) -> np.ndarray:
43    return np.clip(mat, 0, 255).astype(np.uint8)
def cycle_mat_back_to_uint8(mat: numpy.ndarray) -> numpy.ndarray:
46def cycle_mat_back_to_uint8(mat: np.ndarray) -> np.ndarray:
47    return (mat % 256).astype(np.uint8)
def handle_out_of_bound_and_dtype( mat: numpy.ndarray, oob_behavior: vkit.mechanism.distortion.photometric.opt.OutOfBoundBehavior):
50def handle_out_of_bound_and_dtype(mat: np.ndarray, oob_behavior: OutOfBoundBehavior):
51    mat = np.round(mat)
52    if oob_behavior == OutOfBoundBehavior.CLIP:
53        mat = clip_mat_back_to_uint8(mat)
54    elif oob_behavior == OutOfBoundBehavior.CYCLE:
55        mat = cycle_mat_back_to_uint8(mat)
56    else:
57        raise NotImplementedError()
58    return mat
def generate_new_image( image: vkit.element.image.Image, new_mat: numpy.ndarray, channels: Union[Sequence[int], NoneType] = None):
61def generate_new_image(
62    image: Image,
63    new_mat: np.ndarray,
64    channels: Optional[Sequence[int]] = None,
65):
66    if channels:
67        new_image = image.copy()
68        with new_image.writable_context:
69            new_image.mat[:, :, channels] = new_mat
70    else:
71        assert image.mat.shape == new_mat.shape
72        new_image = attrs.evolve(image, mat=new_mat)
73
74    return new_image
def to_rgb_image(image: vkit.element.image.Image, mode: vkit.element.image.ImageMode):
77def to_rgb_image(image: Image, mode: ImageMode):
78    if mode not in (ImageMode.GRAYSCALE, ImageMode.RGB):
79        image = image.to_rgb_image()
80    return image
def to_original_image(image: vkit.element.image.Image, mode: vkit.element.image.ImageMode):
83def to_original_image(image: Image, mode: ImageMode):
84    if mode not in (ImageMode.GRAYSCALE, ImageMode.RGB):
85        image = image.to_target_mode_image(mode)
86    return image