-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtransform.py
More file actions
67 lines (45 loc) · 2.52 KB
/
transform.py
File metadata and controls
67 lines (45 loc) · 2.52 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import cv2
import math
import numpy as np
def resized_to_shape(image: np.ndarray, shape: tuple[int, int]) -> np.ndarray:
# height = shape[0] / image.shape[0]
# width = shape[1] / image.shape[1]
# resized_shape = (width, height)
height, width, number_of_channels = shape
return cv2.resize(image[:,:,:number_of_channels], (width, height), interpolation=cv2.INTER_CUBIC)
def linear_transform(x: np.ndarray, a: int|float|np.ndarray, b: int|float|np.ndarray):
return a * x + b
def multi_linear_transform(coefficient_index: np.ndarray, x: np.ndarray, coefficients: list[tuple[int, int]]) -> np.ndarray:
assert coefficient_index.shape == x.shape, "x shape doesn't match coefficient shape"
transform = np.zeros(x.shape)
for i in range(len(coefficients)):
a, b = coefficients[i]
transform += linear_transform(x, a, b) * (coefficient_index == i)
return transform
def negative_transform(x: np.ndarray, coefficients: tuple[int, int]) -> np.ndarray:
is_negative: np.ndarray = x < 0
return multi_linear_transform(is_negative, x, [(1, 0), coefficients])
def sign_shifted_image(image: np.ndarray) -> np.ndarray:
return negative_transform(image, (1, max_luminance(image)+1)).astype(image.dtype)
def absolute_image(image: np.ndarray) -> np.ndarray:
return negative_transform(image, (-1, -1)).astype(image.dtype)
def sign_unshifted_image(is_positive: np.ndarray, image: np.ndarray) -> np.ndarray:
return multi_linear_transform(np.invert(is_positive), image, [(1, 0), (1, -max_luminance(image)-1)]).astype(image.dtype)
def signed(is_positive: np.ndarray, matrix: np.ndarray, positive_offset: int = 0, negative_offset: int = 0, positive_factor: int = 1, negative_factor: int = -1) -> np.ndarray:
assert is_positive.shape == matrix.shape, "map shape doesn't match matrix shape"
assert matrix.dtype.kind != "u"
positive = (matrix + positive_offset) * positive_factor * is_positive
negative = (matrix + negative_offset) * negative_factor * np.invert(is_positive)
return positive + negative
def remainder_modulo(value: int, modulo: int) -> int:
remainder = value % modulo
if remainder == 0:
return 0
else:
return modulo - remainder
def remainder_ceil(value: int, ceil: int) -> int:
return math.ceil(value / ceil) * ceil
def max_luminance(image):
dtype = image.dtype if hasattr(image, "dtype") else image
itemsize = dtype.itemsize if dtype.kind == "u" else dtype.itemsize // 2 # yes, signed 16 bit -> 255
return int(2 ** (8 * itemsize)) - 1