supervisely 6.73.225__py3-none-any.whl → 6.73.226__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.
Potentially problematic release.
This version of supervisely might be problematic. Click here for more details.
- supervisely/api/app_api.py +14 -8
- supervisely/nn/inference/inference.py +45 -4
- supervisely/nn/inference/semantic_segmentation/semantic_segmentation.py +38 -8
- {supervisely-6.73.225.dist-info → supervisely-6.73.226.dist-info}/METADATA +1 -1
- {supervisely-6.73.225.dist-info → supervisely-6.73.226.dist-info}/RECORD +9 -9
- {supervisely-6.73.225.dist-info → supervisely-6.73.226.dist-info}/LICENSE +0 -0
- {supervisely-6.73.225.dist-info → supervisely-6.73.226.dist-info}/WHEEL +0 -0
- {supervisely-6.73.225.dist-info → supervisely-6.73.226.dist-info}/entry_points.txt +0 -0
- {supervisely-6.73.225.dist-info → supervisely-6.73.226.dist-info}/top_level.txt +0 -0
supervisely/api/app_api.py
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
from __future__ import annotations
|
|
3
3
|
|
|
4
4
|
import json
|
|
5
|
+
import time
|
|
5
6
|
from dataclasses import dataclass
|
|
6
7
|
from time import sleep
|
|
7
8
|
from typing import Any, Dict, List, NamedTuple, Optional, Union
|
|
@@ -536,10 +537,7 @@ class AppApi(TaskApi):
|
|
|
536
537
|
self._enabled = True
|
|
537
538
|
if is_development():
|
|
538
539
|
self._enabled = False
|
|
539
|
-
|
|
540
|
-
"Workflow is disabled in development mode. "
|
|
541
|
-
"To enable it, use `api.app.workflow.enable()` right after Api initialization."
|
|
542
|
-
)
|
|
540
|
+
self.__last_warning_time = None
|
|
543
541
|
|
|
544
542
|
def enable(self):
|
|
545
543
|
"""Enable the workflow functionality."""
|
|
@@ -574,10 +572,18 @@ class AppApi(TaskApi):
|
|
|
574
572
|
if min_instance_version is not None
|
|
575
573
|
else self._min_instance_version
|
|
576
574
|
)
|
|
577
|
-
if (
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
575
|
+
if not self.is_enabled():
|
|
576
|
+
if (
|
|
577
|
+
self.__last_warning_time is None
|
|
578
|
+
or time.monotonic() - self.__last_warning_time > 60
|
|
579
|
+
):
|
|
580
|
+
self.__last_warning_time = time.monotonic()
|
|
581
|
+
logger.warning(
|
|
582
|
+
"Workflow is disabled in development mode. "
|
|
583
|
+
"To enable it, use `api.app.workflow.enable()` right after Api initialization."
|
|
584
|
+
)
|
|
585
|
+
return
|
|
586
|
+
if not check_workflow_compatibility(self._api, version_to_check):
|
|
581
587
|
logger.info(f"Workflow method `{func.__name__}` is disabled.")
|
|
582
588
|
return
|
|
583
589
|
return func(self, *args, **kwargs)
|
|
@@ -574,10 +574,15 @@ class Inference:
|
|
|
574
574
|
for prediction in predictions:
|
|
575
575
|
if (
|
|
576
576
|
not classes_whitelist in (None, "all")
|
|
577
|
+
and hasattr(prediction, "class_name")
|
|
577
578
|
and prediction.class_name not in classes_whitelist
|
|
578
579
|
):
|
|
579
580
|
continue
|
|
580
|
-
|
|
581
|
+
if "classes_whitelist" in inspect.signature(self._create_label).parameters:
|
|
582
|
+
# pylint: disable=unexpected-keyword-arg
|
|
583
|
+
label = self._create_label(prediction, classes_whitelist) # pylint: disable=too-many-function-args
|
|
584
|
+
else:
|
|
585
|
+
label = self._create_label(prediction)
|
|
581
586
|
if label is None:
|
|
582
587
|
# for example empty mask
|
|
583
588
|
continue
|
|
@@ -2543,17 +2548,52 @@ def clean_up_cuda():
|
|
|
2543
2548
|
logger.debug("Error in clean_up_cuda.", exc_info=True)
|
|
2544
2549
|
|
|
2545
2550
|
|
|
2551
|
+
def _fix_classes_names(meta: ProjectMeta, ann: Annotation):
|
|
2552
|
+
def _replace_strip(s, chars: str, replacement: str = "_") -> str:
|
|
2553
|
+
replace_pattern = f"^[{re.escape(chars)}]+|[{re.escape(chars)}]+$"
|
|
2554
|
+
return re.sub(replace_pattern, replacement, s)
|
|
2555
|
+
|
|
2556
|
+
replaced_classes_in_meta = []
|
|
2557
|
+
for obj_class in meta.obj_classes:
|
|
2558
|
+
obj_class_name = _replace_strip(obj_class.name, " ", "")
|
|
2559
|
+
if obj_class_name != obj_class.name:
|
|
2560
|
+
new_obj_class = obj_class.clone(name=obj_class_name)
|
|
2561
|
+
meta = meta.delete_obj_class(obj_class.name)
|
|
2562
|
+
meta = meta.add_obj_class(new_obj_class)
|
|
2563
|
+
replaced_classes_in_meta.append((obj_class.name, obj_class_name))
|
|
2564
|
+
replaced_classes_in_ann = set()
|
|
2565
|
+
new_labels = []
|
|
2566
|
+
for label in ann.labels:
|
|
2567
|
+
obj_class = label.obj_class
|
|
2568
|
+
obj_class_name = _replace_strip(obj_class.name, " ", "")
|
|
2569
|
+
if obj_class_name != obj_class.name:
|
|
2570
|
+
new_obj_class = obj_class.clone(name=obj_class_name)
|
|
2571
|
+
label = label.clone(obj_class=new_obj_class)
|
|
2572
|
+
replaced_classes_in_ann.add((obj_class.name, obj_class_name))
|
|
2573
|
+
new_labels.append(label)
|
|
2574
|
+
ann = ann.clone(labels=new_labels)
|
|
2575
|
+
return meta, ann, replaced_classes_in_meta, list(replaced_classes_in_ann)
|
|
2576
|
+
|
|
2577
|
+
|
|
2546
2578
|
def update_meta_and_ann(meta: ProjectMeta, ann: Annotation):
|
|
2547
2579
|
"""Update project meta and annotation to match each other
|
|
2548
2580
|
If obj class or tag meta from annotation conflicts with project meta
|
|
2549
2581
|
add suffix to obj class or tag meta.
|
|
2550
2582
|
Return tuple of updated project meta, annotation and boolean flag if meta was changed."""
|
|
2551
|
-
obj_classes_suffixes =
|
|
2552
|
-
tag_meta_suffixes =
|
|
2583
|
+
obj_classes_suffixes = ["_nn"]
|
|
2584
|
+
tag_meta_suffixes = ["_nn"]
|
|
2553
2585
|
ann_obj_classes = {}
|
|
2554
2586
|
ann_tag_metas = {}
|
|
2555
2587
|
meta_changed = False
|
|
2556
2588
|
|
|
2589
|
+
meta, ann, replaced_classes_in_meta, replaced_classes_in_ann = _fix_classes_names(meta, ann)
|
|
2590
|
+
if replaced_classes_in_meta:
|
|
2591
|
+
meta_changed = True
|
|
2592
|
+
logger.warning(
|
|
2593
|
+
"Some classes names were fixed in project meta",
|
|
2594
|
+
extra={"replaced_classes": {old: new for old, new in replaced_classes_in_meta}},
|
|
2595
|
+
)
|
|
2596
|
+
|
|
2557
2597
|
# get all obj classes and tag metas from annotation
|
|
2558
2598
|
for label in ann.labels:
|
|
2559
2599
|
ann_obj_classes[label.obj_class.name] = label.obj_class
|
|
@@ -2563,7 +2603,8 @@ def update_meta_and_ann(meta: ProjectMeta, ann: Annotation):
|
|
|
2563
2603
|
ann_tag_metas[tag.meta.name] = tag.meta
|
|
2564
2604
|
|
|
2565
2605
|
# check if obj classes are in project meta
|
|
2566
|
-
# if not, add them
|
|
2606
|
+
# if not, add them.
|
|
2607
|
+
# if shape is different, add them with suffix
|
|
2567
2608
|
changed_obj_classes = {}
|
|
2568
2609
|
for ann_obj_class in ann_obj_classes.values():
|
|
2569
2610
|
if meta.get_obj_class(ann_obj_class.name) is None:
|
|
@@ -3,9 +3,11 @@ from typing import Any, Dict, List
|
|
|
3
3
|
import numpy as np
|
|
4
4
|
|
|
5
5
|
from supervisely.annotation.label import Label
|
|
6
|
+
from supervisely.annotation.obj_class import ObjClass
|
|
6
7
|
from supervisely.geometry.bitmap import Bitmap
|
|
7
8
|
from supervisely.nn.inference.inference import Inference
|
|
8
9
|
from supervisely.nn.prediction_dto import PredictionSegmentation
|
|
10
|
+
from supervisely.project.project_meta import ProjectMeta
|
|
9
11
|
from supervisely.sly_logger import logger
|
|
10
12
|
|
|
11
13
|
|
|
@@ -24,20 +26,48 @@ class SemanticSegmentation(Inference):
|
|
|
24
26
|
def _get_obj_class_shape(self):
|
|
25
27
|
return Bitmap
|
|
26
28
|
|
|
27
|
-
def
|
|
28
|
-
|
|
29
|
+
def _find_bg_class_index(self, class_names: List[str]):
|
|
30
|
+
possible_bg_names = ["background", "bg", "unlabeled", "neutral", "__bg__"]
|
|
31
|
+
bg_class_index = None
|
|
32
|
+
for i, name in enumerate(class_names):
|
|
33
|
+
if name in possible_bg_names:
|
|
34
|
+
bg_class_index = i
|
|
35
|
+
break
|
|
36
|
+
return bg_class_index
|
|
37
|
+
|
|
38
|
+
def _add_default_bg_class(self, meta: ProjectMeta):
|
|
39
|
+
default_bg_class_name = "__bg__"
|
|
40
|
+
obj_class = meta.get_obj_class(default_bg_class_name)
|
|
41
|
+
if obj_class is None:
|
|
42
|
+
obj_class = ObjClass(default_bg_class_name, self._get_obj_class_shape())
|
|
43
|
+
meta = meta.add_obj_class(obj_class)
|
|
44
|
+
return meta, obj_class
|
|
45
|
+
|
|
46
|
+
def _get_or_create_bg_obj_class(self, classes):
|
|
47
|
+
bg_class_index = self._find_bg_class_index(classes)
|
|
48
|
+
if bg_class_index is None:
|
|
49
|
+
self._model_meta, bg_obj_class = self._add_default_bg_class(self.model_meta)
|
|
50
|
+
else:
|
|
51
|
+
bg_class_name = classes[bg_class_index]
|
|
52
|
+
bg_obj_class = self.model_meta.get_obj_class(bg_class_name)
|
|
53
|
+
return bg_obj_class
|
|
54
|
+
|
|
55
|
+
def _create_label(self, dto: PredictionSegmentation, classes_whitelist: List[str] = None):
|
|
56
|
+
classes = self.get_classes()
|
|
57
|
+
|
|
58
|
+
image_classes_indexes = np.unique(dto.mask)
|
|
29
59
|
labels = []
|
|
30
|
-
for class_idx in
|
|
60
|
+
for class_idx in image_classes_indexes:
|
|
31
61
|
class_mask = dto.mask == class_idx
|
|
32
|
-
class_name =
|
|
33
|
-
|
|
62
|
+
class_name = classes[class_idx]
|
|
63
|
+
if classes_whitelist not in (None, "all") and class_name not in classes_whitelist:
|
|
64
|
+
obj_class = self._get_or_create_bg_obj_class(classes)
|
|
65
|
+
else:
|
|
66
|
+
obj_class = self.model_meta.get_obj_class(class_name)
|
|
34
67
|
if obj_class is None:
|
|
35
68
|
raise KeyError(
|
|
36
69
|
f"Class {class_name} not found in model classes {self.get_classes()}"
|
|
37
70
|
)
|
|
38
|
-
if not class_mask.any(): # skip empty masks
|
|
39
|
-
logger.debug(f"Mask of class {class_name} is empty and will be sklipped")
|
|
40
|
-
return None
|
|
41
71
|
geometry = Bitmap(class_mask, extra_validation=False)
|
|
42
72
|
label = Label(geometry, obj_class)
|
|
43
73
|
labels.append(label)
|
|
@@ -23,7 +23,7 @@ supervisely/api/advanced_api.py,sha256=Nd5cCnHFWc3PSUrCtENxTGtDjS37_lCHXsgXvUI3T
|
|
|
23
23
|
supervisely/api/agent_api.py,sha256=ShWAIlXcWXcyI9fqVuP5GZVCigCMJmjnvdGUfLspD6Y,8890
|
|
24
24
|
supervisely/api/annotation_api.py,sha256=Eps-Jf10_SQFy7DjghUnyiM6DcVJBsamHDViRAXv2fg,51403
|
|
25
25
|
supervisely/api/api.py,sha256=Jvc0nQqu6q4-1ey26AJiCcw96BzqP0ORBQqsoKO7gOI,60633
|
|
26
|
-
supervisely/api/app_api.py,sha256=
|
|
26
|
+
supervisely/api/app_api.py,sha256=hjoL24Nc1POlIqz5bkpMBij5D-cwCHvkznkaGpODyzA,67086
|
|
27
27
|
supervisely/api/dataset_api.py,sha256=7iwAyz3pmzFG2i072gLdXjczfBGbyj-V_rRl7Tx-V30,37944
|
|
28
28
|
supervisely/api/file_api.py,sha256=UQM5susk1DMgmEEZZq4tiMCKbglKYl8MqiZn1iPLqus,76821
|
|
29
29
|
supervisely/api/github_api.py,sha256=NIexNjEer9H5rf5sw2LEZd7C1WR-tK4t6IZzsgeAAwQ,623
|
|
@@ -817,7 +817,7 @@ supervisely/nn/benchmark/visualization/widgets/table/__init__.py,sha256=47DEQpj8
|
|
|
817
817
|
supervisely/nn/benchmark/visualization/widgets/table/table.py,sha256=YiCpt-mdINJnNBWsUTPkRR_9w09Ne2Y0n93DY8vsE8I,4090
|
|
818
818
|
supervisely/nn/inference/__init__.py,sha256=mtEci4Puu-fRXDnGn8RP47o97rv3VTE0hjbYO34Zwqg,1622
|
|
819
819
|
supervisely/nn/inference/cache.py,sha256=WylgHgPQRIoA_RDks8FyKgHqeZZ_YFoyddxkVvOX2YQ,25713
|
|
820
|
-
supervisely/nn/inference/inference.py,sha256=
|
|
820
|
+
supervisely/nn/inference/inference.py,sha256=jqhugSdwrKPyimiSxGvsJYLTjAyrxVmOl2FNql6f4aA,116982
|
|
821
821
|
supervisely/nn/inference/session.py,sha256=jmkkxbe2kH-lEgUU6Afh62jP68dxfhF5v6OGDfLU62E,35757
|
|
822
822
|
supervisely/nn/inference/video_inference.py,sha256=8Bshjr6rDyLay5Za8IB8Dr6FURMO2R_v7aELasO8pR4,5746
|
|
823
823
|
supervisely/nn/inference/gui/__init__.py,sha256=e3RKi93bI1r_0Dkvs_gaR1p_jkzkBMNjrcx-RVlm93k,88
|
|
@@ -846,7 +846,7 @@ supervisely/nn/inference/promptable_segmentation/promptable_segmentation.py,sha2
|
|
|
846
846
|
supervisely/nn/inference/salient_object_segmentation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
847
847
|
supervisely/nn/inference/salient_object_segmentation/salient_object_segmentation.py,sha256=fbTcI2GNXLD7JzFos05XqFDQCa57csaoYQFakYJRZh8,8136
|
|
848
848
|
supervisely/nn/inference/semantic_segmentation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
849
|
-
supervisely/nn/inference/semantic_segmentation/semantic_segmentation.py,sha256=
|
|
849
|
+
supervisely/nn/inference/semantic_segmentation/semantic_segmentation.py,sha256=xpmViSYm1v_ZxlYyqiD_DiB7_LEynv9ZoU0t2QHEx8A,3370
|
|
850
850
|
supervisely/nn/inference/tracking/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
851
851
|
supervisely/nn/inference/tracking/bbox_tracking.py,sha256=URWGoYrCRN3yC4MyLx2_eZziZYwX6mPA8OLJqUOsAgA,15307
|
|
852
852
|
supervisely/nn/inference/tracking/functional.py,sha256=LpVu2gvOOpr9D_uvwTPZey1wUCAhV-E20RPKmCSIrK4,1774
|
|
@@ -997,9 +997,9 @@ supervisely/worker_proto/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZ
|
|
|
997
997
|
supervisely/worker_proto/worker_api_pb2.py,sha256=VQfi5JRBHs2pFCK1snec3JECgGnua3Xjqw_-b3aFxuM,59142
|
|
998
998
|
supervisely/worker_proto/worker_api_pb2_grpc.py,sha256=3BwQXOaP9qpdi0Dt9EKG--Lm8KGN0C5AgmUfRv77_Jk,28940
|
|
999
999
|
supervisely_lib/__init__.py,sha256=7-3QnN8Zf0wj8NCr2oJmqoQWMKKPKTECvjH9pd2S5vY,159
|
|
1000
|
-
supervisely-6.73.
|
|
1001
|
-
supervisely-6.73.
|
|
1002
|
-
supervisely-6.73.
|
|
1003
|
-
supervisely-6.73.
|
|
1004
|
-
supervisely-6.73.
|
|
1005
|
-
supervisely-6.73.
|
|
1000
|
+
supervisely-6.73.226.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
1001
|
+
supervisely-6.73.226.dist-info/METADATA,sha256=MFZ1QnRu-QzhumIcVsb7aQvcfXiXxcbQ_dX9mrVG1tk,33150
|
|
1002
|
+
supervisely-6.73.226.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
|
|
1003
|
+
supervisely-6.73.226.dist-info/entry_points.txt,sha256=U96-5Hxrp2ApRjnCoUiUhWMqijqh8zLR03sEhWtAcms,102
|
|
1004
|
+
supervisely-6.73.226.dist-info/top_level.txt,sha256=kcFVwb7SXtfqZifrZaSE3owHExX4gcNYe7Q2uoby084,28
|
|
1005
|
+
supervisely-6.73.226.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|