-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmisc.py
91 lines (83 loc) · 2.99 KB
/
misc.py
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# --------------------------------------------------
# PyCV-Toolbox by Yuxuan Zhang ([email protected])
# --------------------------------------------------
from .__internal__ import *
from . import types, misc
# --------------------------------------------------
def D3(img: NDArray) -> NDArray:
"""
Add 3rd dimension to an array if it's not.
Use <NDArray>.squeeze() to revert this operation.
"""
shape = list(img.shape)
ndim = img.ndim
assert ndim == len(shape), f"len({shape}) != {ndim}"
if ndim == 2:
# Expand to 3D array, with 3rd dimension only have 1 layer
return img.reshape(shape + [-1])
else:
assert ndim == 3, f"{ndim} != 3"
return img
def text(pos=None, font=cv2.FONT_HERSHEY_PLAIN, scale=0.5, color=[255] * 3, width=1):
color = list(map(int, color))
def apply(img: NDArray, txt: str):
nonlocal pos, font, scale, color, width
if pos is None:
pos = (10, img.shape[0] - 10)
img = types.U8(img)
return cv2.putText(
img, txt, pos, font,
scale, color, width,
cv2.LINE_AA
)
return apply
def pad(*sizes: int, color: NDArray[np.floating] | float | int = 0, top=None, left=None, bottom=None, right=None):
"""
(Lambda) Pad the given image by given widths on each size.
The size parameter can be a scalar or an array of 1/2/4 elements.
0 element : no padding
1 element : all sides
2 elements: [vertical, horizontal]
4 elements: [top, right, bottom, left]
"""
args = list(map(int, sizes))
match len(args):
case 0: args = [0] * 4
case 1: args = args * 4
case 2: args = args * 2
case n:
assert n == 4, f"Unable to use {n} arugments for padding size"
if top is None:
top = args[0]
if left is None:
left = args[1]
if bottom is None:
bottom = args[2]
if right is None:
right = args[3]
def apply(img: NDArray):
nonlocal top, right, bottom, left, color
img = misc.D3(img)
h, w, d = img.shape
# Caculate color if applicable (black)
if isinstance(color, np.ndarray):
tmp = np.zeros((d,), dtype=color.dtype)
elif isinstance(color, int):
tmp = np.zeros((d,), dtype=np.uint8)
elif isinstance(color, float):
tmp = np.zeros((d,), dtype=np.float32)
else:
assert False, f"Unknown type for color: {type(color)}"
tmp[:] = color
# Match type of color with type of image
color = types.MatchType(img)(tmp).reshape((1, 1, -1))
# Create an empty canvas with padding color
canvas = np.zeros(
(top + bottom + h, left + right + w, d), dtype=img.dtype)
# Broadcast padding color into canvas
canvas[:, :] = color
# Put image into its position
canvas[bottom:bottom+h, left:left+w] = img
# Return in original dimensions
return canvas.squeeze()
return apply