streamlit-label-kit 0.0.9__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- streamlit_label_kit/LabelToolKit/__init__.py +16 -0
- streamlit_label_kit/LabelToolKit/annotation.py +169 -0
- streamlit_label_kit/LabelToolKit/detection.py +293 -0
- streamlit_label_kit/LabelToolKit/frontend/build/asset-manifest.json +10 -0
- streamlit_label_kit/LabelToolKit/frontend/build/bootstrap.min.css +9500 -0
- streamlit_label_kit/LabelToolKit/frontend/build/index.html +1 -0
- streamlit_label_kit/LabelToolKit/frontend/build/static/js/main.1def89e5.js +3 -0
- streamlit_label_kit/LabelToolKit/frontend/build/static/js/main.1def89e5.js.LICENSE.txt +110 -0
- streamlit_label_kit/LabelToolKit/frontend/build/static/js/main.1def89e5.js.map +1 -0
- streamlit_label_kit/__init__.py +6 -0
- streamlit_label_kit-0.0.9.dist-info/LICENSE +339 -0
- streamlit_label_kit-0.0.9.dist-info/METADATA +67 -0
- streamlit_label_kit-0.0.9.dist-info/RECORD +15 -0
- streamlit_label_kit-0.0.9.dist-info/WHEEL +5 -0
- streamlit_label_kit-0.0.9.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import streamlit.components.v1 as components
|
|
3
|
+
from typing import List
|
|
4
|
+
|
|
5
|
+
import numpy as np
|
|
6
|
+
import matplotlib.pyplot as plt
|
|
7
|
+
from streamlit_label_kit import IS_RELEASE
|
|
8
|
+
|
|
9
|
+
if IS_RELEASE:
|
|
10
|
+
absolute_path = os.path.dirname(os.path.abspath(__file__))
|
|
11
|
+
build_path = os.path.join(absolute_path, "frontend/build")
|
|
12
|
+
_component_func = components.declare_component("st-label-kit", path=build_path)
|
|
13
|
+
else:
|
|
14
|
+
_component_func = components.declare_component(
|
|
15
|
+
"st-label-kit", url="http://localhost:3000"
|
|
16
|
+
)
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
from streamlit.components.v1.components import CustomComponent
|
|
2
|
+
from typing import List
|
|
3
|
+
|
|
4
|
+
import streamlit.elements.image as st_image
|
|
5
|
+
from PIL import Image
|
|
6
|
+
import numpy as np
|
|
7
|
+
import matplotlib.pyplot as plt
|
|
8
|
+
from hashlib import md5
|
|
9
|
+
from typing import Literal, Union
|
|
10
|
+
|
|
11
|
+
from . import _component_func
|
|
12
|
+
|
|
13
|
+
def get_colormap(label_names, colormap_name="gist_rainbow"):
|
|
14
|
+
colormap = {}
|
|
15
|
+
cmap = plt.get_cmap(colormap_name)
|
|
16
|
+
for idx, l in enumerate(label_names):
|
|
17
|
+
rgb = [int(d) for d in np.array(cmap(float(idx) / len(label_names))) * 255][:3]
|
|
18
|
+
colormap[l] = "#%02x%02x%02x" % tuple(rgb)
|
|
19
|
+
return colormap
|
|
20
|
+
|
|
21
|
+
SELECT_HEIGHT = 60
|
|
22
|
+
RADIO_HEGIHT = 34
|
|
23
|
+
UI_HEIGHT = 34
|
|
24
|
+
UI_WIDTH = 168
|
|
25
|
+
|
|
26
|
+
def _calc_size(size) :
|
|
27
|
+
if isinstance(size, (int, float)):
|
|
28
|
+
return size, size
|
|
29
|
+
|
|
30
|
+
match size:
|
|
31
|
+
case "small":
|
|
32
|
+
ui_height = UI_HEIGHT
|
|
33
|
+
ui_width = UI_WIDTH
|
|
34
|
+
case "medium":
|
|
35
|
+
ui_height = int(2 * UI_HEIGHT)
|
|
36
|
+
ui_width = int(1.25 * UI_WIDTH)
|
|
37
|
+
case "large":
|
|
38
|
+
ui_height = int(4 * UI_HEIGHT)
|
|
39
|
+
ui_width = int(1.5 * UI_WIDTH)
|
|
40
|
+
case _:
|
|
41
|
+
ui_height = int(2 * UI_HEIGHT)
|
|
42
|
+
ui_width = int(1.25 * UI_WIDTH)
|
|
43
|
+
|
|
44
|
+
return ui_height, ui_width
|
|
45
|
+
|
|
46
|
+
def annotation(
|
|
47
|
+
|
|
48
|
+
# add "Output Mode" = "px values", **"relative values mode", "yolo", etc.
|
|
49
|
+
# "original pixel value mode", "resized pixel value mode" ==> on output, give metadata as well.
|
|
50
|
+
image_path: str = None,
|
|
51
|
+
label_list: list[str] = [],
|
|
52
|
+
default_label_index: int=None,
|
|
53
|
+
image_height: int=512,
|
|
54
|
+
image_width: int=512,
|
|
55
|
+
|
|
56
|
+
classification: bool = False,
|
|
57
|
+
multi_select: bool = False,
|
|
58
|
+
|
|
59
|
+
ui_position: Literal["right", "left"] = "right",
|
|
60
|
+
class_select_position: Literal["right", "left", "bottom"] = None,
|
|
61
|
+
meta_editor_position: Literal["right", "left"] = None,
|
|
62
|
+
|
|
63
|
+
class_select_type: Literal["select", "radio"] = "radio",
|
|
64
|
+
meta_editor: bool = False,
|
|
65
|
+
edit_description: bool = False,
|
|
66
|
+
|
|
67
|
+
ui_size: Literal["small", "medium", "large"]= "small",
|
|
68
|
+
ui_left_size: Union[Literal["small", "medium", "large"], int] = None,
|
|
69
|
+
ui_bottom_size: Union[Literal["small", "medium", "large"], int] = None,
|
|
70
|
+
ui_right_size: Union[Literal["small", "medium", "large"], int] = None,
|
|
71
|
+
|
|
72
|
+
ui_bottom_fill_width: bool = False,
|
|
73
|
+
ui_height: int = None,
|
|
74
|
+
|
|
75
|
+
read_only: bool = False,
|
|
76
|
+
|
|
77
|
+
key=None,
|
|
78
|
+
) -> CustomComponent:
|
|
79
|
+
if (image_path):
|
|
80
|
+
image = Image.open(image_path)
|
|
81
|
+
image.thumbnail(size=(image_width, image_height))
|
|
82
|
+
|
|
83
|
+
if (not classification and not meta_editor):
|
|
84
|
+
return None
|
|
85
|
+
|
|
86
|
+
_class_select_pos = class_select_position or ui_position
|
|
87
|
+
_meta_editor_pos = meta_editor_position or ui_position
|
|
88
|
+
_edit_meta = not edit_description and meta_editor
|
|
89
|
+
|
|
90
|
+
_ui_height, _ui_width = _calc_size(ui_size)
|
|
91
|
+
_, _left_size = _calc_size(ui_left_size or ui_size)
|
|
92
|
+
_bottom_size, _ = _calc_size(ui_bottom_size or ui_size)
|
|
93
|
+
_, _right_size = _calc_size(ui_right_size or ui_size)
|
|
94
|
+
|
|
95
|
+
_select_type = "radio" if class_select_type != "select" else "select"
|
|
96
|
+
|
|
97
|
+
if image_path == None:
|
|
98
|
+
_image_url = ""
|
|
99
|
+
_default_label_list = []
|
|
100
|
+
_image_size = [0,0]
|
|
101
|
+
|
|
102
|
+
else:
|
|
103
|
+
_image_url = st_image.image_to_url(
|
|
104
|
+
image,
|
|
105
|
+
image.size[0],
|
|
106
|
+
True,
|
|
107
|
+
"RGB",
|
|
108
|
+
"PNG",
|
|
109
|
+
f"annotation-{md5(image.tobytes()).hexdigest()}-{key}",
|
|
110
|
+
)
|
|
111
|
+
_image_size = image.size
|
|
112
|
+
if _image_url.startswith("/"):
|
|
113
|
+
_image_url = _image_url[1:]
|
|
114
|
+
|
|
115
|
+
if multi_select and isinstance(default_label_index, list):
|
|
116
|
+
_default_label_list = [label_list[i] for i in default_label_index]
|
|
117
|
+
else:
|
|
118
|
+
_default_label_list = []
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
if ui_bottom_fill_width:
|
|
122
|
+
_ui_width = "100vw"
|
|
123
|
+
|
|
124
|
+
if ui_height:
|
|
125
|
+
_ui_height = ui_height
|
|
126
|
+
|
|
127
|
+
component_value = _component_func(
|
|
128
|
+
image_url=_image_url,
|
|
129
|
+
image_size=_image_size,
|
|
130
|
+
label_list=label_list,
|
|
131
|
+
|
|
132
|
+
ui_height=_ui_height,
|
|
133
|
+
ui_width=_ui_width,
|
|
134
|
+
|
|
135
|
+
default_label_idx=default_label_index,
|
|
136
|
+
key=key,
|
|
137
|
+
|
|
138
|
+
multi_select=multi_select,
|
|
139
|
+
|
|
140
|
+
edit_class=classification,
|
|
141
|
+
edit_meta=_edit_meta,
|
|
142
|
+
edit_description=meta_editor and edit_description,
|
|
143
|
+
|
|
144
|
+
class_select_type=_select_type,
|
|
145
|
+
meta_editor=meta_editor,
|
|
146
|
+
|
|
147
|
+
class_select_position=_class_select_pos,
|
|
148
|
+
meta_editor_position=_meta_editor_pos,
|
|
149
|
+
|
|
150
|
+
ui_left_size=_left_size,
|
|
151
|
+
ui_bottom_size=_bottom_size,
|
|
152
|
+
ui_right_size=_right_size,
|
|
153
|
+
|
|
154
|
+
read_only=read_only,
|
|
155
|
+
|
|
156
|
+
default_multi_label_list=_default_label_list,
|
|
157
|
+
label_type="annotation"
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
# component_value = _component_func(
|
|
161
|
+
# image_url=image_url,
|
|
162
|
+
# image_size=image.size,
|
|
163
|
+
# label_list=label_list,
|
|
164
|
+
# ui_width=ui_width,
|
|
165
|
+
# ui_height=RADIO_HEGIHT,
|
|
166
|
+
# key=image_url,
|
|
167
|
+
# label_type="detection"
|
|
168
|
+
# )
|
|
169
|
+
return component_value
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import streamlit.components.v1 as components
|
|
3
|
+
from streamlit.components.v1.components import CustomComponent
|
|
4
|
+
from typing import List
|
|
5
|
+
|
|
6
|
+
import streamlit as st
|
|
7
|
+
import streamlit.elements.image as st_image
|
|
8
|
+
from PIL import Image
|
|
9
|
+
import numpy as np
|
|
10
|
+
import matplotlib.pyplot as plt
|
|
11
|
+
from hashlib import md5
|
|
12
|
+
from typing import Literal, Union
|
|
13
|
+
|
|
14
|
+
from .__init__ import _component_func
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def _get_colormap(label_names, colormap_name="gist_rainbow"):
|
|
18
|
+
colormap = {}
|
|
19
|
+
cmap = plt.get_cmap(colormap_name)
|
|
20
|
+
for idx, l in enumerate(label_names):
|
|
21
|
+
rgb = [int(d) for d in np.array(cmap(float(idx) / len(label_names))) * 255][:3]
|
|
22
|
+
colormap[l] = "#%02x%02x%02x" % tuple(rgb)
|
|
23
|
+
return colormap
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
SELECT_HEIGHT = 60
|
|
27
|
+
RADIO_HEGIHT = 34
|
|
28
|
+
UI_HEIGHT = 34
|
|
29
|
+
UI_WIDTH = 198
|
|
30
|
+
|
|
31
|
+
#'''
|
|
32
|
+
# bboxes:
|
|
33
|
+
# [[x,y,w,h],[x,y,w,h]]
|
|
34
|
+
# labels:
|
|
35
|
+
# [0,3]
|
|
36
|
+
#'''
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def convert_bbox_format(
|
|
40
|
+
bbox: tuple[float, float, float, float],
|
|
41
|
+
input_format: Literal["XYWH", "XYXY", "CXYWH"],
|
|
42
|
+
output_format: Literal["XYWH", "XYXY", "CXYWH"],
|
|
43
|
+
) -> tuple[float, float, float, float]:
|
|
44
|
+
"""
|
|
45
|
+
Convert bounding box between specified formats.
|
|
46
|
+
|
|
47
|
+
Args:
|
|
48
|
+
bbox (Tuple[float, float, float, float]): The bounding box coordinates.
|
|
49
|
+
input_format (str): The format of the input bounding box.
|
|
50
|
+
output_format (str): The format to convert the bounding box to.
|
|
51
|
+
|
|
52
|
+
Returns:
|
|
53
|
+
Tuple[float, float, float, float]: The bounding box in the new format.
|
|
54
|
+
"""
|
|
55
|
+
if input_format == output_format:
|
|
56
|
+
return bbox
|
|
57
|
+
|
|
58
|
+
x, y, w, h = 0, 0, 0, 0
|
|
59
|
+
|
|
60
|
+
# Unpack the bounding box based on the input format
|
|
61
|
+
if input_format == "XYXY":
|
|
62
|
+
x1, y1, x2, y2 = bbox
|
|
63
|
+
x, y, w, h = x1, y1, x2 - x1, y2 - y1
|
|
64
|
+
elif input_format == "XYWH":
|
|
65
|
+
x, y, w, h = bbox
|
|
66
|
+
elif input_format == "CXYWH":
|
|
67
|
+
cx, cy, w, h = bbox
|
|
68
|
+
x, y = cx - w / 2, cy - h / 2
|
|
69
|
+
|
|
70
|
+
# Convert to the output format
|
|
71
|
+
if output_format == "XYXY":
|
|
72
|
+
x1, y1, x2, y2 = x, y, x + w, y + h
|
|
73
|
+
return (x1, y1, x2, y2)
|
|
74
|
+
elif output_format == "XYWH":
|
|
75
|
+
return (x, y, w, h)
|
|
76
|
+
elif output_format == "CXYWH":
|
|
77
|
+
cx, cy = x + w / 2, y + h / 2
|
|
78
|
+
return (cx, cy, w, h)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def relative_to_absolute(
|
|
82
|
+
bbox: tuple[float, float, float, float], image_width: int, image_height: int
|
|
83
|
+
) -> tuple[float, float, float, float]:
|
|
84
|
+
"""
|
|
85
|
+
Convert relative bbox coordinates to absolute pixel coordinates.
|
|
86
|
+
|
|
87
|
+
Args:
|
|
88
|
+
bbox (Tuple[float, float, float, float]): The bounding box in relative format.
|
|
89
|
+
image_width (int): The width of the image in pixels.
|
|
90
|
+
image_height (int): The height of the image in pixels.
|
|
91
|
+
|
|
92
|
+
Returns:
|
|
93
|
+
Tuple[float, float, float, float]: The bounding box in absolute pixel coordinates.
|
|
94
|
+
"""
|
|
95
|
+
rx1, ry1, rx2, ry2 = bbox # Assuming bbox in format REL_XYXY
|
|
96
|
+
ax1, ay1 = rx1 * image_width, ry1 * image_height
|
|
97
|
+
ax2, ay2 = rx2 * image_width, ry2 * image_height
|
|
98
|
+
return (ax1, ay1, ax2, ay2)
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def absolute_to_relative(
|
|
102
|
+
bbox: tuple[float, float, float, float], image_width: int, image_height: int
|
|
103
|
+
) -> tuple[float, float, float, float]:
|
|
104
|
+
"""
|
|
105
|
+
Convert absolute pixel bbox coordinates to relative coordinates.
|
|
106
|
+
|
|
107
|
+
Args:
|
|
108
|
+
bbox (Tuple[float, float, float, float]): The bounding box in absolute pixel format.
|
|
109
|
+
image_width (int): The width of the image in pixels.
|
|
110
|
+
image_height (int): The height of the image in pixels.
|
|
111
|
+
|
|
112
|
+
Returns:
|
|
113
|
+
Tuple[float, float, float, float]: The bounding box in relative coordinates.
|
|
114
|
+
"""
|
|
115
|
+
ax1, ay1, ax2, ay2 = bbox # Assuming bbox in format XYXY
|
|
116
|
+
rx1, ry1 = ax1 / image_width, ay1 / image_height
|
|
117
|
+
rx2, ry2 = ax2 / image_width, ay2 / image_height
|
|
118
|
+
return (rx1, ry1, rx2, ry2)
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def _calc_size(size):
|
|
122
|
+
if isinstance(size, (int, float)):
|
|
123
|
+
return size, size
|
|
124
|
+
|
|
125
|
+
match size:
|
|
126
|
+
case "small":
|
|
127
|
+
ui_height = UI_HEIGHT
|
|
128
|
+
ui_width = UI_WIDTH
|
|
129
|
+
case "medium":
|
|
130
|
+
ui_height = int(2 * UI_HEIGHT)
|
|
131
|
+
ui_width = int(1.25 * UI_WIDTH)
|
|
132
|
+
case "large":
|
|
133
|
+
ui_height = int(4 * UI_HEIGHT)
|
|
134
|
+
ui_width = int(1.5 * UI_WIDTH)
|
|
135
|
+
case _:
|
|
136
|
+
ui_height = int(2 * UI_HEIGHT)
|
|
137
|
+
ui_width = int(1.25 * UI_WIDTH)
|
|
138
|
+
|
|
139
|
+
return ui_height, ui_width
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def detection(
|
|
143
|
+
image_path,
|
|
144
|
+
label_list,
|
|
145
|
+
bboxes=None,
|
|
146
|
+
labels=[],
|
|
147
|
+
read_only=False,
|
|
148
|
+
infoDict={},
|
|
149
|
+
metaDatas: list[list[str]] = [],
|
|
150
|
+
bbox_format: Literal["XYWH", "XYXY", "CXYWH", "REL_XYWH", "REL_XYXY"] = "XYWH",
|
|
151
|
+
image_height=512,
|
|
152
|
+
image_width=512,
|
|
153
|
+
line_width=1.0,
|
|
154
|
+
ui_position: Literal["right", "left"] = "right",
|
|
155
|
+
class_select_position: Literal["right", "left", "bottom"] = None,
|
|
156
|
+
item_editor_position: Literal["right", "left"] = None,
|
|
157
|
+
item_selector_position: Literal["right", "left"] = None,
|
|
158
|
+
class_select_type: Literal["select", "radio"] = "select",
|
|
159
|
+
item_editor: bool = True,
|
|
160
|
+
item_selector: bool = True,
|
|
161
|
+
edit_meta: bool = True,
|
|
162
|
+
edit_description: bool = False,
|
|
163
|
+
ui_size: Literal["small", "medium", "large"] = "small",
|
|
164
|
+
ui_left_size: Union[Literal["small", "medium", "large"], int] = None,
|
|
165
|
+
ui_bottom_size: Union[Literal["small", "medium", "large"], int] = None,
|
|
166
|
+
ui_right_size: Union[Literal["small", "medium", "large"], int] = None,
|
|
167
|
+
key=None,
|
|
168
|
+
) -> CustomComponent:
|
|
169
|
+
|
|
170
|
+
# Load Image and convert size
|
|
171
|
+
image = Image.open(image_path)
|
|
172
|
+
original_image_size = image.size
|
|
173
|
+
image.thumbnail(size=(image_width, image_height))
|
|
174
|
+
|
|
175
|
+
image_url = st_image.image_to_url(
|
|
176
|
+
image,
|
|
177
|
+
image.size[0],
|
|
178
|
+
True,
|
|
179
|
+
"RGB",
|
|
180
|
+
"PNG",
|
|
181
|
+
f"annotation-{md5(image.tobytes()).hexdigest()}-{key}",
|
|
182
|
+
)
|
|
183
|
+
if image_url.startswith("/"):
|
|
184
|
+
image_url = image_url[1:]
|
|
185
|
+
|
|
186
|
+
color_map = _get_colormap(label_list, colormap_name="gist_rainbow")
|
|
187
|
+
|
|
188
|
+
resized_image_size = image.size
|
|
189
|
+
scale = original_image_size[0] / resized_image_size[0]
|
|
190
|
+
|
|
191
|
+
# Configure UI position and size
|
|
192
|
+
_class_select_pos = class_select_position or ui_position
|
|
193
|
+
_item_editor_pos = item_editor_position or ui_position
|
|
194
|
+
_item_selector_pos = item_selector_position or ui_position
|
|
195
|
+
_edit_meta = not edit_description
|
|
196
|
+
|
|
197
|
+
_, _left_size = _calc_size(ui_left_size or ui_size)
|
|
198
|
+
_bottom_size, _ = _calc_size(ui_bottom_size or ui_size)
|
|
199
|
+
_, _right_size = _calc_size(ui_right_size or ui_size)
|
|
200
|
+
|
|
201
|
+
_select_type = "radio" if class_select_type != "select" else "select"
|
|
202
|
+
|
|
203
|
+
# Configure default labels, metaDatas
|
|
204
|
+
num_bboxes = len(bboxes)
|
|
205
|
+
if len(labels) > num_bboxes:
|
|
206
|
+
labels = labels[:num_bboxes]
|
|
207
|
+
else:
|
|
208
|
+
labels.extend(["0"] * (num_bboxes - len(labels)))
|
|
209
|
+
|
|
210
|
+
if len(metaDatas) > num_bboxes:
|
|
211
|
+
metaDatas = metaDatas[:num_bboxes]
|
|
212
|
+
else:
|
|
213
|
+
metaDatas.extend([[]] * (num_bboxes - len(metaDatas)))
|
|
214
|
+
|
|
215
|
+
# Convert BBOX Format to XYWH
|
|
216
|
+
if "REL" in bbox_format:
|
|
217
|
+
bboxes = [
|
|
218
|
+
relative_to_absolute(bbox, original_image_size[0], original_image_size[1])
|
|
219
|
+
for bbox in bboxes
|
|
220
|
+
]
|
|
221
|
+
original_format = bbox_format.replace("REL_", "")
|
|
222
|
+
else:
|
|
223
|
+
original_format = bbox_format
|
|
224
|
+
bboxes = [convert_bbox_format(bbox, original_format, "XYWH") for bbox in bboxes]
|
|
225
|
+
|
|
226
|
+
bbox_info = [
|
|
227
|
+
{
|
|
228
|
+
"bbox": [b / scale for b in item[0]],
|
|
229
|
+
"label_id": item[1],
|
|
230
|
+
"label": label_list[item[1]],
|
|
231
|
+
"meta": item[2],
|
|
232
|
+
}
|
|
233
|
+
for item in zip(bboxes, labels, metaDatas)
|
|
234
|
+
]
|
|
235
|
+
|
|
236
|
+
component_value = _component_func(
|
|
237
|
+
image_url=image_url,
|
|
238
|
+
image_size=image.size,
|
|
239
|
+
label_list=label_list,
|
|
240
|
+
bbox_info=bbox_info,
|
|
241
|
+
color_map=color_map,
|
|
242
|
+
line_width=line_width,
|
|
243
|
+
ui_width=20,
|
|
244
|
+
ui_height=20,
|
|
245
|
+
edit_meta=_edit_meta,
|
|
246
|
+
edit_description=True,
|
|
247
|
+
class_select_type=_select_type,
|
|
248
|
+
item_editor=item_editor,
|
|
249
|
+
item_selector=item_selector,
|
|
250
|
+
class_select_position=_class_select_pos,
|
|
251
|
+
item_editor_position=_item_editor_pos,
|
|
252
|
+
item_selector_position=_item_selector_pos,
|
|
253
|
+
ui_left_size=_left_size,
|
|
254
|
+
ui_bottom_size=_bottom_size,
|
|
255
|
+
ui_right_size=_right_size,
|
|
256
|
+
key=key,
|
|
257
|
+
read_only=read_only,
|
|
258
|
+
label_type="detection",
|
|
259
|
+
)
|
|
260
|
+
|
|
261
|
+
bboxes = None
|
|
262
|
+
if component_value is not None:
|
|
263
|
+
bboxes = component_value["bbox"]
|
|
264
|
+
bboxes = [
|
|
265
|
+
{
|
|
266
|
+
"bbox": [b * scale for b in item["bbox"]],
|
|
267
|
+
"label_id": item["label_id"],
|
|
268
|
+
"label": item["label"],
|
|
269
|
+
"meta": item["meta"],
|
|
270
|
+
}
|
|
271
|
+
for item in bboxes
|
|
272
|
+
]
|
|
273
|
+
|
|
274
|
+
# Convert back to original format
|
|
275
|
+
if "REL" in bbox_format:
|
|
276
|
+
bboxes = [
|
|
277
|
+
convert_bbox_format(bbox["bbox"], "XYWH", original_format)
|
|
278
|
+
for bbox in bboxes
|
|
279
|
+
]
|
|
280
|
+
bboxes = [
|
|
281
|
+
absolute_to_relative(bbox, original_image_size[0], original_image_size[1])
|
|
282
|
+
for bbox in bboxes
|
|
283
|
+
]
|
|
284
|
+
else:
|
|
285
|
+
bboxes = [
|
|
286
|
+
convert_bbox_format(bbox["bbox"], "XYWH", original_format)
|
|
287
|
+
for bbox in bboxes
|
|
288
|
+
]
|
|
289
|
+
|
|
290
|
+
return {
|
|
291
|
+
"bbox": bboxes,
|
|
292
|
+
"image_size": original_image_size,
|
|
293
|
+
}
|