Skip to content

Commit e760265

Browse files
committed
Make Style
1 parent d1ef8e0 commit e760265

File tree

1 file changed

+53
-39
lines changed
  • inference/core/workflows/core_steps/visualizations/icon

1 file changed

+53
-39
lines changed

inference/core/workflows/core_steps/visualizations/icon/v1.py

Lines changed: 53 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
from inference.core.workflows.execution_engine.entities.base import WorkflowImageData
1313
from inference.core.workflows.execution_engine.entities.types import (
1414
IMAGE_KIND,
15-
INTEGER_KIND,
1615
INSTANCE_SEGMENTATION_PREDICTION_KIND,
16+
INTEGER_KIND,
1717
KEYPOINT_DETECTION_PREDICTION_KIND,
1818
OBJECT_DETECTION_PREDICTION_KIND,
1919
STRING_KIND,
@@ -22,16 +22,15 @@
2222
from inference.core.workflows.prototypes.block import BlockResult, WorkflowBlockManifest
2323

2424
TYPE: str = "roboflow_core/icon_visualization@v1"
25-
SHORT_DESCRIPTION = (
26-
"Draw icons on an image either at specific static coordinates or dynamically based on detections."
27-
)
25+
SHORT_DESCRIPTION = "Draw icons on an image either at specific static coordinates or dynamically based on detections."
2826
LONG_DESCRIPTION = """
2927
The `IconVisualization` block draws icons on an image using Supervision's `sv.IconAnnotator`.
3028
It supports two modes:
3129
1. **Static Mode**: Position an icon at a fixed location (e.g., for watermarks)
3230
2. **Dynamic Mode**: Position icons based on detection coordinates
3331
"""
3432

33+
3534
class IconManifest(VisualizationManifest):
3635
type: Literal[f"{TYPE}", "IconVisualization"]
3736
model_config = ConfigDict(
@@ -173,17 +172,14 @@ class IconManifest(VisualizationManifest):
173172
def validate_mode_parameters(self) -> "IconManifest":
174173
if self.mode == "dynamic":
175174
if self.predictions is None:
176-
raise ValueError(
177-
"The 'predictions' field is required for dynamic mode"
178-
)
175+
raise ValueError("The 'predictions' field is required for dynamic mode")
179176
return self
180177

181178
@classmethod
182179
def get_execution_engine_compatibility(cls) -> Optional[str]:
183180
return ">=1.3.0,<2.0.0"
184181

185182

186-
187183
class IconVisualizationBlockV1(VisualizationBlock):
188184
def __init__(self, *args, **kwargs):
189185
super().__init__(*args, **kwargs)
@@ -224,28 +220,39 @@ def run(
224220
) -> BlockResult:
225221
annotated_image = image.numpy_image.copy() if copy_image else image.numpy_image
226222
icon_np = icon.numpy_image.copy()
227-
223+
224+
import os
228225
import tempfile
226+
229227
import cv2
230-
import os
231-
228+
232229
# WorkflowImageData loses alpha channels when loading images.
233230
# Try to recover them from the original source.
234231
if icon_np.shape[2] == 3:
235232
# Try reloading from file with IMREAD_UNCHANGED
236-
if hasattr(icon, '_image_reference') and icon._image_reference and \
237-
not icon._image_reference.startswith('http'):
233+
if (
234+
hasattr(icon, "_image_reference")
235+
and icon._image_reference
236+
and not icon._image_reference.startswith("http")
237+
):
238238
try:
239-
icon_with_alpha = cv2.imread(icon._image_reference, cv2.IMREAD_UNCHANGED)
239+
icon_with_alpha = cv2.imread(
240+
icon._image_reference, cv2.IMREAD_UNCHANGED
241+
)
240242
if icon_with_alpha is not None and icon_with_alpha.shape[2] == 4:
241243
icon_np = icon_with_alpha
242244
except:
243245
pass
244-
246+
245247
# Try decoding base64 with alpha preserved
246-
if icon_np.shape[2] == 3 and hasattr(icon, '_base64_image') and icon._base64_image:
248+
if (
249+
icon_np.shape[2] == 3
250+
and hasattr(icon, "_base64_image")
251+
and icon._base64_image
252+
):
247253
try:
248254
import base64
255+
249256
image_bytes = base64.b64decode(icon._base64_image)
250257
nparr = np.frombuffer(image_bytes, np.uint8)
251258
decoded = cv2.imdecode(nparr, cv2.IMREAD_UNCHANGED)
@@ -256,30 +263,40 @@ def run(
256263
icon_np = decoded
257264
except:
258265
pass
259-
266+
260267
with tempfile.NamedTemporaryFile(suffix=".png", delete=False) as f:
261268
# Ensure proper format for IconAnnotator
262269
if len(icon_np.shape) == 2:
263270
icon_np = cv2.cvtColor(icon_np, cv2.COLOR_GRAY2BGR)
264-
alpha = np.ones((icon_np.shape[0], icon_np.shape[1], 1), dtype=icon_np.dtype) * 255
271+
alpha = (
272+
np.ones(
273+
(icon_np.shape[0], icon_np.shape[1], 1), dtype=icon_np.dtype
274+
)
275+
* 255
276+
)
265277
icon_np = np.concatenate([icon_np, alpha], axis=2)
266278
elif icon_np.shape[2] == 3:
267-
alpha = np.ones((icon_np.shape[0], icon_np.shape[1], 1), dtype=icon_np.dtype) * 255
279+
alpha = (
280+
np.ones(
281+
(icon_np.shape[0], icon_np.shape[1], 1), dtype=icon_np.dtype
282+
)
283+
* 255
284+
)
268285
icon_np = np.concatenate([icon_np, alpha], axis=2)
269-
286+
270287
cv2.imwrite(f.name, icon_np)
271288
icon_path = f.name
272-
289+
273290
try:
274291
if mode == "static":
275292
img_height, img_width = annotated_image.shape[:2]
276-
293+
277294
# Handle negative positioning (from right/bottom edges)
278295
if x_position < 0:
279296
actual_x = img_width + x_position - icon_width
280297
else:
281298
actual_x = x_position
282-
299+
283300
if y_position < 0:
284301
actual_y = img_height + y_position - icon_height
285302
else:
@@ -288,48 +305,45 @@ def run(
288305
# IconAnnotator expects a detection, so create one at the desired position
289306
center_x = actual_x + icon_width // 2
290307
center_y = actual_y + icon_height // 2
291-
308+
292309
static_detections = sv.Detections(
293-
xyxy=np.array([[
294-
center_x - 1,
295-
center_y - 1,
296-
center_x + 1,
297-
center_y + 1
298-
]], dtype=np.float64),
310+
xyxy=np.array(
311+
[[center_x - 1, center_y - 1, center_x + 1, center_y + 1]],
312+
dtype=np.float64,
313+
),
299314
class_id=np.array([0]),
300315
confidence=np.array([1.0]),
301316
)
302-
317+
303318
annotator = sv.IconAnnotator(
304319
icon_resolution_wh=(icon_width, icon_height),
305320
icon_position=sv.Position.CENTER,
306321
)
307-
322+
308323
annotated_image = annotator.annotate(
309324
scene=annotated_image,
310325
detections=static_detections,
311-
icon_path=icon_path
326+
icon_path=icon_path,
312327
)
313-
328+
314329
elif mode == "dynamic" and predictions is not None and len(predictions) > 0:
315330
annotator = self.getAnnotator(
316331
icon_width=icon_width,
317332
icon_height=icon_height,
318333
position=position,
319334
)
320-
335+
321336
if annotator is not None:
322337
annotated_image = annotator.annotate(
323338
scene=annotated_image,
324339
detections=predictions,
325-
icon_path=icon_path
340+
icon_path=icon_path,
326341
)
327342
finally:
328343
os.unlink(icon_path)
329-
344+
330345
return {
331346
OUTPUT_IMAGE_KEY: WorkflowImageData.copy_and_replace(
332-
origin_image_data=image,
333-
numpy_image=annotated_image
347+
origin_image_data=image, numpy_image=annotated_image
334348
)
335349
}

0 commit comments

Comments
 (0)