supervisely 6.73.261__py3-none-any.whl → 6.73.263__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/__init__.py +1 -1
- supervisely/api/app_api.py +166 -46
- supervisely/api/module_api.py +6 -0
- supervisely/nn/inference/cache.py +65 -15
- supervisely/nn/inference/inference.py +1 -0
- supervisely/nn/inference/tracking/bbox_tracking.py +62 -7
- supervisely/nn/inference/tracking/tracker_interface.py +1 -1
- {supervisely-6.73.261.dist-info → supervisely-6.73.263.dist-info}/METADATA +1 -1
- {supervisely-6.73.261.dist-info → supervisely-6.73.263.dist-info}/RECORD +13 -13
- {supervisely-6.73.261.dist-info → supervisely-6.73.263.dist-info}/LICENSE +0 -0
- {supervisely-6.73.261.dist-info → supervisely-6.73.263.dist-info}/WHEEL +0 -0
- {supervisely-6.73.261.dist-info → supervisely-6.73.263.dist-info}/entry_points.txt +0 -0
- {supervisely-6.73.261.dist-info → supervisely-6.73.263.dist-info}/top_level.txt +0 -0
supervisely/__init__.py
CHANGED
|
@@ -309,4 +309,4 @@ except Exception as e:
|
|
|
309
309
|
# If new changes in Supervisely Python SDK require upgrade of the Supervisely instance
|
|
310
310
|
# set a new value for the environment variable MINIMUM_INSTANCE_VERSION_FOR_SDK, otherwise
|
|
311
311
|
# users can face compatibility issues, if the instance version is lower than the SDK version.
|
|
312
|
-
os.environ["MINIMUM_INSTANCE_VERSION_FOR_SDK"] = "6.12.
|
|
312
|
+
os.environ["MINIMUM_INSTANCE_VERSION_FOR_SDK"] = "6.12.17"
|
supervisely/api/app_api.py
CHANGED
|
@@ -1212,17 +1212,80 @@ class AppApi(TaskApi):
|
|
|
1212
1212
|
|
|
1213
1213
|
def get_list(
|
|
1214
1214
|
self,
|
|
1215
|
-
team_id,
|
|
1216
|
-
filter=None,
|
|
1217
|
-
context=None,
|
|
1218
|
-
repository_key=None,
|
|
1219
|
-
show_disabled=False,
|
|
1220
|
-
integrated_into=None,
|
|
1221
|
-
session_tags=None,
|
|
1222
|
-
only_running=False,
|
|
1223
|
-
with_shared=True,
|
|
1215
|
+
team_id: int,
|
|
1216
|
+
filter: Optional[List[dict]] = None,
|
|
1217
|
+
context: Optional[List[str]] = None,
|
|
1218
|
+
repository_key: Optional[str] = None,
|
|
1219
|
+
show_disabled: bool = False,
|
|
1220
|
+
integrated_into: Optional[List[str]] = None,
|
|
1221
|
+
session_tags: Optional[List[str]] = None,
|
|
1222
|
+
only_running: bool = False,
|
|
1223
|
+
with_shared: bool = True,
|
|
1224
|
+
force_all_sessions: bool = True,
|
|
1224
1225
|
) -> List[AppInfo]:
|
|
1225
|
-
"""
|
|
1226
|
+
"""
|
|
1227
|
+
Get list of applications for the specified team.
|
|
1228
|
+
|
|
1229
|
+
:param team_id: team id
|
|
1230
|
+
:type team_id: int
|
|
1231
|
+
:param filter: list of filters
|
|
1232
|
+
:type filter: Optional[List[dict]]
|
|
1233
|
+
:param context: list of application contexts
|
|
1234
|
+
:type context: Optional[List[str]]
|
|
1235
|
+
:param repository_key: repository key
|
|
1236
|
+
:type repository_key: Optional[str]
|
|
1237
|
+
:param show_disabled: show disabled applications
|
|
1238
|
+
:type show_disabled: bool
|
|
1239
|
+
:param integrated_into: destination of the application.
|
|
1240
|
+
Available values: "panel", "files", "standalone", "data_commander",
|
|
1241
|
+
"image_annotation_tool", "video_annotation_tool",
|
|
1242
|
+
"dicom_annotation_tool", "pointcloud_annotation_tool"
|
|
1243
|
+
:type integrated_into: Optional[List[str]]
|
|
1244
|
+
:param session_tags: list of session tags
|
|
1245
|
+
:type session_tags: Optional[List[str]]
|
|
1246
|
+
:param only_running: show only running applications (status is one of "queued"/"consumed"/"started"/"deployed")
|
|
1247
|
+
:type only_running: bool
|
|
1248
|
+
:param with_shared: include shared applications
|
|
1249
|
+
:type with_shared: bool
|
|
1250
|
+
:param force_all_sessions: force to get all sessions (tasks) for each application.
|
|
1251
|
+
Works only if only_running is False.
|
|
1252
|
+
Note that it can be a long operation.
|
|
1253
|
+
:type force_all_sessions: bool
|
|
1254
|
+
|
|
1255
|
+
:return: list of applications
|
|
1256
|
+
:rtype: List[AppInfo]
|
|
1257
|
+
|
|
1258
|
+
|
|
1259
|
+
:Usage example:
|
|
1260
|
+
|
|
1261
|
+
.. code-block:: python
|
|
1262
|
+
|
|
1263
|
+
import supervisely as sly
|
|
1264
|
+
|
|
1265
|
+
os.environ['SERVER_ADDRESS'] = 'https://app.supervisely.com'
|
|
1266
|
+
os.environ['API_TOKEN'] = 'Your Supervisely API Token'
|
|
1267
|
+
api = sly.Api.from_env()
|
|
1268
|
+
|
|
1269
|
+
team_id = 447
|
|
1270
|
+
|
|
1271
|
+
# Get list of all applications (including all tasks in `tasks` field)
|
|
1272
|
+
apps = api.app.get_list(team_id=team_id)
|
|
1273
|
+
|
|
1274
|
+
# Get list of all applications (only running tasks included in `tasks` field)
|
|
1275
|
+
apps = api.app.get_list(team_id=team_id, force_all_sessions=False)
|
|
1276
|
+
|
|
1277
|
+
# Get list of only running applications
|
|
1278
|
+
apps = api.app.get_list(team_id=team_id, only_running=True)
|
|
1279
|
+
|
|
1280
|
+
# Get list of applications with specific filters
|
|
1281
|
+
filter = [{"field": "moduleId", "operator": "=", "value": 428}]
|
|
1282
|
+
apps = api.app.get_list(team_id=team_id, filter=filter)
|
|
1283
|
+
"""
|
|
1284
|
+
|
|
1285
|
+
if only_running is True:
|
|
1286
|
+
# no need to get all sessions if only running sessions are requested
|
|
1287
|
+
# (`force_all_sessions` has higher priority than only_running)
|
|
1288
|
+
force_all_sessions = False
|
|
1226
1289
|
|
|
1227
1290
|
return self.get_list_all_pages(
|
|
1228
1291
|
method="apps.list",
|
|
@@ -1240,6 +1303,7 @@ class AppApi(TaskApi):
|
|
|
1240
1303
|
"onlyRunning": only_running,
|
|
1241
1304
|
"showDisabled": show_disabled,
|
|
1242
1305
|
"withShared": with_shared,
|
|
1306
|
+
"forceAllSessions": force_all_sessions,
|
|
1243
1307
|
},
|
|
1244
1308
|
)
|
|
1245
1309
|
|
|
@@ -1479,49 +1543,105 @@ class AppApi(TaskApi):
|
|
|
1479
1543
|
|
|
1480
1544
|
def get_sessions(
|
|
1481
1545
|
self,
|
|
1482
|
-
team_id,
|
|
1483
|
-
module_id,
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1546
|
+
team_id: int,
|
|
1547
|
+
module_id: int,
|
|
1548
|
+
show_disabled: bool = False,
|
|
1549
|
+
session_name: Optional[str] = None,
|
|
1550
|
+
statuses: Optional[List[TaskApi.Status]] = None,
|
|
1551
|
+
with_shared: bool = False,
|
|
1488
1552
|
) -> List[SessionInfo]:
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1553
|
+
"""
|
|
1554
|
+
Get list of sessions (tasks) for the specified team and module.
|
|
1555
|
+
|
|
1556
|
+
:param team_id: team id
|
|
1557
|
+
:type team_id: int
|
|
1558
|
+
:param module_id: application module id
|
|
1559
|
+
:type module_id: int
|
|
1560
|
+
:param show_disabled: show disabled applications
|
|
1561
|
+
:type show_disabled: bool
|
|
1562
|
+
:param session_name: session name to filter sessions
|
|
1563
|
+
:type session_name: Optional[str]
|
|
1564
|
+
:param statuses: list of statuses to filter sessions
|
|
1565
|
+
:type statuses: Optional[List[TaskApi.Status]]
|
|
1566
|
+
:param with_shared: include shared application sessions
|
|
1567
|
+
:type with_shared: bool
|
|
1568
|
+
|
|
1569
|
+
:return: list of sessions
|
|
1570
|
+
:rtype: List[SessionInfo]
|
|
1571
|
+
|
|
1572
|
+
:Usage example:
|
|
1573
|
+
|
|
1574
|
+
.. code-block:: python
|
|
1575
|
+
|
|
1576
|
+
import supervisely as sly
|
|
1577
|
+
|
|
1578
|
+
os.environ['SERVER_ADDRESS'] = 'https://app.supervisely.com'
|
|
1579
|
+
os.environ['API_TOKEN'] = 'Your Supervisely API Token'
|
|
1580
|
+
api = sly.Api.from_env()
|
|
1581
|
+
|
|
1582
|
+
team_id = 447
|
|
1583
|
+
module_id = 428
|
|
1584
|
+
|
|
1585
|
+
# Get list of all sessions for the specified team and module ID
|
|
1586
|
+
sessions = api.app.get_sessions(team_id, module_id)
|
|
1587
|
+
|
|
1588
|
+
# Get list of sessions with specific statuses
|
|
1589
|
+
from supervisely.api.task_api import TaskApi
|
|
1590
|
+
|
|
1591
|
+
statuses = [TaskApi.Status.STARTED]
|
|
1592
|
+
sessions = api.app.get_sessions(team_id, module_id, statuses=statuses)
|
|
1593
|
+
"""
|
|
1594
|
+
|
|
1595
|
+
infos_json = self.get_list(
|
|
1596
|
+
team_id,
|
|
1597
|
+
filter=[
|
|
1598
|
+
{
|
|
1599
|
+
ApiField.FIELD: ApiField.MODULE_ID,
|
|
1600
|
+
ApiField.OPERATOR: "=",
|
|
1601
|
+
ApiField.VALUE: module_id,
|
|
1602
|
+
}
|
|
1603
|
+
],
|
|
1604
|
+
with_shared=with_shared,
|
|
1605
|
+
only_running=False,
|
|
1606
|
+
force_all_sessions=False,
|
|
1499
1607
|
)
|
|
1500
|
-
if len(infos_json)
|
|
1501
|
-
# raise KeyError(f"App [module_id = {module_id}] not found in team {team_id}")
|
|
1502
|
-
return []
|
|
1503
|
-
if len(infos_json) > 1:
|
|
1608
|
+
if len(infos_json) > 1 and with_shared is False:
|
|
1504
1609
|
raise KeyError(
|
|
1505
1610
|
f"Apps list in team is broken: app [module_id = {module_id}] added to team {team_id} multiple times"
|
|
1506
1611
|
)
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1612
|
+
sessions = []
|
|
1613
|
+
for app in infos_json:
|
|
1614
|
+
data = {
|
|
1615
|
+
ApiField.TEAM_ID: team_id,
|
|
1616
|
+
ApiField.APP_ID: app.id,
|
|
1617
|
+
# ApiField.ONLY_RUNNING: False,
|
|
1618
|
+
ApiField.SHOW_DISABLED: show_disabled,
|
|
1619
|
+
ApiField.WITH_SHARED: with_shared,
|
|
1620
|
+
ApiField.SORT: ApiField.STARTED_AT,
|
|
1621
|
+
ApiField.SORT_ORDER: "desc",
|
|
1622
|
+
}
|
|
1623
|
+
if statuses is not None:
|
|
1624
|
+
data[ApiField.FILTER] = [
|
|
1625
|
+
{
|
|
1626
|
+
ApiField.FIELD: ApiField.STATUS,
|
|
1627
|
+
ApiField.OPERATOR: "in",
|
|
1628
|
+
ApiField.VALUE: [str(s) for s in statuses],
|
|
1629
|
+
}
|
|
1630
|
+
]
|
|
1631
|
+
sessions.extend(
|
|
1632
|
+
self.get_list_all_pages(
|
|
1633
|
+
method="apps.tasks.list",
|
|
1634
|
+
data=data,
|
|
1635
|
+
convert_json_info_cb=lambda x: x,
|
|
1636
|
+
)
|
|
1637
|
+
)
|
|
1638
|
+
session_infos = []
|
|
1515
1639
|
for session in sessions:
|
|
1516
|
-
to_add = True
|
|
1517
1640
|
if session_name is not None and session["meta"]["name"] != session_name:
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
session["moduleId"] = module_id
|
|
1523
|
-
dev_tasks.append(SessionInfo.from_json(session))
|
|
1524
|
-
return dev_tasks
|
|
1641
|
+
continue
|
|
1642
|
+
session["moduleId"] = module_id
|
|
1643
|
+
session_infos.append(SessionInfo.from_json(session))
|
|
1644
|
+
return session_infos
|
|
1525
1645
|
|
|
1526
1646
|
def start(
|
|
1527
1647
|
self,
|
supervisely/api/module_api.py
CHANGED
|
@@ -596,6 +596,12 @@ class ApiField:
|
|
|
596
596
|
""""""
|
|
597
597
|
CLEAR_LOCAL_DATA_SOURCE = "clearLocalDataSource"
|
|
598
598
|
""""""
|
|
599
|
+
ONLY_RUNNING = "onlyRunning"
|
|
600
|
+
""""""
|
|
601
|
+
SHOW_DISABLED = "showDisabled"
|
|
602
|
+
""""""
|
|
603
|
+
WITH_SHARED = "withShared"
|
|
604
|
+
""""""
|
|
599
605
|
|
|
600
606
|
|
|
601
607
|
def _get_single_item(items):
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import json
|
|
2
2
|
import shutil
|
|
3
|
+
import time
|
|
3
4
|
from concurrent.futures import ThreadPoolExecutor, as_completed
|
|
4
5
|
from enum import Enum
|
|
5
6
|
from logging import Logger
|
|
6
7
|
from pathlib import Path
|
|
7
8
|
from threading import Lock, Thread
|
|
8
|
-
from time import sleep
|
|
9
9
|
from typing import Any, Callable, Generator, List, Optional, Tuple, Union
|
|
10
10
|
|
|
11
11
|
import cv2
|
|
@@ -140,7 +140,7 @@ class PersistentImageTTLCache(TTLCache):
|
|
|
140
140
|
self[video_id] = video_path
|
|
141
141
|
if src_video_path != str(video_path):
|
|
142
142
|
shutil.move(src_video_path, str(video_path))
|
|
143
|
-
sly.logger.debug(f"
|
|
143
|
+
sly.logger.debug(f"Video #{video_id} saved to {video_path}", extra={"video_id": video_id})
|
|
144
144
|
|
|
145
145
|
def get_video_path(self, video_id: int) -> Path:
|
|
146
146
|
return self[video_id]
|
|
@@ -197,12 +197,14 @@ class InferenceImageCache:
|
|
|
197
197
|
ttl: int,
|
|
198
198
|
is_persistent: bool = True,
|
|
199
199
|
base_folder: str = sly.env.smart_cache_container_dir(),
|
|
200
|
+
log_progress: bool = False,
|
|
200
201
|
) -> None:
|
|
201
202
|
self.is_persistent = is_persistent
|
|
202
203
|
self._maxsize = maxsize
|
|
203
204
|
self._ttl = ttl
|
|
204
205
|
self._lock = Lock()
|
|
205
|
-
self._load_queue = CacheOut(10 * 60)
|
|
206
|
+
self._load_queue = CacheOut(ttl=10 * 60)
|
|
207
|
+
self.log_progress = log_progress
|
|
206
208
|
|
|
207
209
|
if is_persistent:
|
|
208
210
|
self._data_dir = Path(base_folder)
|
|
@@ -342,11 +344,13 @@ class InferenceImageCache:
|
|
|
342
344
|
Thread(
|
|
343
345
|
target=self.download_video,
|
|
344
346
|
args=(api, video_id),
|
|
345
|
-
kwargs={"return_images": False},
|
|
347
|
+
kwargs={**kwargs, "return_images": False},
|
|
346
348
|
).start()
|
|
347
349
|
elif redownload_video:
|
|
348
350
|
Thread(
|
|
349
|
-
target=self.download_video,
|
|
351
|
+
target=self.download_video,
|
|
352
|
+
args=(api, video_id),
|
|
353
|
+
kwargs={**kwargs, "return_images": False},
|
|
350
354
|
).start()
|
|
351
355
|
|
|
352
356
|
def name_constuctor(frame_index: int):
|
|
@@ -371,6 +375,7 @@ class InferenceImageCache:
|
|
|
371
375
|
with self._lock:
|
|
372
376
|
self._cache.save_video(video_id, str(video_path))
|
|
373
377
|
self._load_queue.delete(video_id)
|
|
378
|
+
sly.logger.debug(f"Video #{video_id} added to cache", extra={"video_id": video_id})
|
|
374
379
|
else:
|
|
375
380
|
cap = cv2.VideoCapture(str(video_path))
|
|
376
381
|
frame_index = 0
|
|
@@ -396,17 +401,57 @@ class InferenceImageCache:
|
|
|
396
401
|
"""
|
|
397
402
|
return_images = kwargs.get("return_images", True)
|
|
398
403
|
progress_cb = kwargs.get("progress_cb", None)
|
|
404
|
+
video_info = kwargs.get("video_info", api.video.get_info_by_id(video_id))
|
|
399
405
|
|
|
400
|
-
video_info = api.video.get_info_by_id(video_id)
|
|
401
406
|
self._wait_if_in_queue(video_id, api.logger)
|
|
402
407
|
if not video_id in self._cache:
|
|
408
|
+
download_time = time.monotonic()
|
|
403
409
|
self._load_queue.set(video_id, video_id)
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
+
try:
|
|
411
|
+
sly.logger.debug("Downloading video #%s", video_id)
|
|
412
|
+
if progress_cb is None and self.log_progress:
|
|
413
|
+
size = video_info.file_meta.get("size", None)
|
|
414
|
+
if size is None:
|
|
415
|
+
size = "unknown"
|
|
416
|
+
else:
|
|
417
|
+
size = int(size)
|
|
418
|
+
|
|
419
|
+
prog_n = 0
|
|
420
|
+
prog_t = time.monotonic()
|
|
421
|
+
|
|
422
|
+
def _progress_cb(n):
|
|
423
|
+
nonlocal prog_n
|
|
424
|
+
nonlocal prog_t
|
|
425
|
+
prog_n += n
|
|
426
|
+
cur_t = time.monotonic()
|
|
427
|
+
if cur_t - prog_t > 3 or (isinstance(size, int) and prog_n >= size):
|
|
428
|
+
prog_t = cur_t
|
|
429
|
+
percent_str = ""
|
|
430
|
+
if isinstance(size, int):
|
|
431
|
+
percent_str = f" ({(prog_n*100) // size}%)"
|
|
432
|
+
prog_str = (
|
|
433
|
+
f"{(prog_n / 1000000):.2f}/{(size / 1000000):.2f} MB{percent_str}"
|
|
434
|
+
)
|
|
435
|
+
sly.logger.debug(
|
|
436
|
+
"Downloading video #%s: %s",
|
|
437
|
+
video_id,
|
|
438
|
+
prog_str,
|
|
439
|
+
)
|
|
440
|
+
|
|
441
|
+
progress_cb = _progress_cb
|
|
442
|
+
temp_video_path = Path("/tmp/smart_cache").joinpath(
|
|
443
|
+
f"_{sly.rand_str(6)}_" + video_info.name
|
|
444
|
+
)
|
|
445
|
+
api.video.download_path(video_id, temp_video_path, progress_cb=progress_cb)
|
|
446
|
+
self.add_video_to_cache(video_id, temp_video_path)
|
|
447
|
+
download_time = time.monotonic() - download_time
|
|
448
|
+
api.logger.debug(
|
|
449
|
+
f"Video #{video_id} downloaded to cache in {download_time:.2f} sec",
|
|
450
|
+
extra={"video_id": video_id, "download_time": download_time},
|
|
451
|
+
)
|
|
452
|
+
except Exception as e:
|
|
453
|
+
self._load_queue.delete(video_id)
|
|
454
|
+
raise e
|
|
410
455
|
if return_images:
|
|
411
456
|
return self.get_frames_from_cache(video_id, list(range(video_info.frames_count)))
|
|
412
457
|
|
|
@@ -664,6 +709,7 @@ class InferenceImageCache:
|
|
|
664
709
|
for pos, image in executor.map(get_one_image, items):
|
|
665
710
|
all_frames[pos] = image
|
|
666
711
|
|
|
712
|
+
download_time = time.monotonic()
|
|
667
713
|
if len(indexes_to_load) > 0:
|
|
668
714
|
for id_or_hash, image in load_generator(indexes_to_load):
|
|
669
715
|
name = name_cunstructor(id_or_hash)
|
|
@@ -672,9 +718,13 @@ class InferenceImageCache:
|
|
|
672
718
|
if return_images:
|
|
673
719
|
pos = pos_by_name[name]
|
|
674
720
|
all_frames[pos] = image
|
|
721
|
+
download_time = time.monotonic() - download_time
|
|
675
722
|
|
|
676
723
|
# logger.debug(f"All stored files: {sorted(os.listdir(self.tmp_path))}")
|
|
677
|
-
logger.debug(
|
|
724
|
+
logger.debug(
|
|
725
|
+
f"Images/Frames added to cache: {indexes_to_load} in {download_time:.2f} sec",
|
|
726
|
+
extra={"indexes": indexes_to_load, "download_time": download_time},
|
|
727
|
+
)
|
|
678
728
|
logger.debug(f"Images/Frames found in cache: {set(indexes).difference(indexes_to_load)}")
|
|
679
729
|
|
|
680
730
|
if return_images:
|
|
@@ -686,8 +736,8 @@ class InferenceImageCache:
|
|
|
686
736
|
logger.debug(f"Waiting for other task to load {name}")
|
|
687
737
|
|
|
688
738
|
while name in self._load_queue:
|
|
689
|
-
# TODO: sleep if slowdown
|
|
690
|
-
sleep(0.1)
|
|
739
|
+
# TODO: time.sleep if slowdown
|
|
740
|
+
time.sleep(0.1)
|
|
691
741
|
continue
|
|
692
742
|
|
|
693
743
|
def download_frames_to_paths(self, api, video_id, frame_indexes, paths, progress_cb=None):
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import functools
|
|
2
2
|
import json
|
|
3
3
|
import time
|
|
4
|
+
import uuid
|
|
4
5
|
from pathlib import Path
|
|
5
6
|
from queue import Queue
|
|
6
7
|
from threading import Event, Thread
|
|
@@ -154,7 +155,8 @@ class BBoxTracking(Inference):
|
|
|
154
155
|
raise
|
|
155
156
|
stop_upload_event.set()
|
|
156
157
|
|
|
157
|
-
def _track_api(self, api: sly.Api, context: dict):
|
|
158
|
+
def _track_api(self, api: sly.Api, context: dict, request_uuid: str = None):
|
|
159
|
+
track_t = time.monotonic()
|
|
158
160
|
# unused fields:
|
|
159
161
|
context["trackId"] = "auto"
|
|
160
162
|
context["objectIds"] = []
|
|
@@ -193,15 +195,27 @@ class BBoxTracking(Inference):
|
|
|
193
195
|
video_id=video_interface.video_id,
|
|
194
196
|
)
|
|
195
197
|
|
|
196
|
-
api.logger.info("Start tracking.")
|
|
197
|
-
|
|
198
198
|
predictions = []
|
|
199
|
-
|
|
199
|
+
frames_n = video_interface.frames_count
|
|
200
|
+
box_n = len(input_bboxes)
|
|
201
|
+
geom_t = time.monotonic()
|
|
202
|
+
api.logger.info(
|
|
203
|
+
"Start tracking.",
|
|
204
|
+
extra={
|
|
205
|
+
"video_id": video_interface.video_id,
|
|
206
|
+
"frame_range": range_of_frames,
|
|
207
|
+
"geometries_count": box_n,
|
|
208
|
+
"frames_count": frames_n,
|
|
209
|
+
"request_uuid": request_uuid,
|
|
210
|
+
},
|
|
211
|
+
)
|
|
212
|
+
for box_i, input_geom in enumerate(input_bboxes, 1):
|
|
200
213
|
input_bbox = input_geom["data"]
|
|
201
214
|
bbox = sly.Rectangle.from_json(input_bbox)
|
|
202
215
|
predictions_for_object = []
|
|
203
216
|
init = False
|
|
204
|
-
|
|
217
|
+
frame_t = time.monotonic()
|
|
218
|
+
for frame_i, _ in enumerate(video_interface.frames_loader_generator(), 1):
|
|
205
219
|
imgs = video_interface.frames
|
|
206
220
|
target = PredictionBBox(
|
|
207
221
|
"", # TODO: can this be useful?
|
|
@@ -224,10 +238,40 @@ class BBoxTracking(Inference):
|
|
|
224
238
|
predictions_for_object.append(
|
|
225
239
|
{"type": sly_geometry.geometry_name(), "data": sly_geometry.to_json()}
|
|
226
240
|
)
|
|
241
|
+
api.logger.debug(
|
|
242
|
+
"Frame processed. Geometry: [%d / %d]. Frame: [%d / %d]",
|
|
243
|
+
box_i,
|
|
244
|
+
box_n,
|
|
245
|
+
frame_i,
|
|
246
|
+
frames_n,
|
|
247
|
+
extra={
|
|
248
|
+
"geometry_index": box_i,
|
|
249
|
+
"frame_index": frame_i,
|
|
250
|
+
"processing_time": time.monotonic() - frame_t,
|
|
251
|
+
"request_uuid": request_uuid,
|
|
252
|
+
},
|
|
253
|
+
)
|
|
254
|
+
frame_t = time.monotonic()
|
|
255
|
+
|
|
227
256
|
predictions.append(predictions_for_object)
|
|
257
|
+
api.logger.info(
|
|
258
|
+
"Geometry processed. Progress: [%d / %d]",
|
|
259
|
+
box_i,
|
|
260
|
+
box_n,
|
|
261
|
+
extra={
|
|
262
|
+
"geometry_index": box_i,
|
|
263
|
+
"processing_time": time.monotonic() - geom_t,
|
|
264
|
+
"request_uuid": request_uuid,
|
|
265
|
+
},
|
|
266
|
+
)
|
|
267
|
+
geom_t = time.monotonic()
|
|
228
268
|
|
|
229
269
|
# predictions must be NxK bboxes: N=number of frames, K=number of objects
|
|
230
270
|
predictions = list(map(list, zip(*predictions)))
|
|
271
|
+
api.logger.info(
|
|
272
|
+
"Tracking finished.",
|
|
273
|
+
extra={"tracking_time": time.monotonic() - track_t, "request_uuid": request_uuid},
|
|
274
|
+
)
|
|
231
275
|
return predictions
|
|
232
276
|
|
|
233
277
|
def _inference(self, frames: List[np.ndarray], geometries: List[Geometry], settings: dict):
|
|
@@ -322,8 +366,19 @@ class BBoxTracking(Inference):
|
|
|
322
366
|
|
|
323
367
|
@server.post("/track-api")
|
|
324
368
|
def track_api(request: Request):
|
|
325
|
-
|
|
326
|
-
|
|
369
|
+
inference_request_uuid = uuid.uuid5(
|
|
370
|
+
namespace=uuid.NAMESPACE_URL, name=f"{time.time()}"
|
|
371
|
+
).hex
|
|
372
|
+
sly.logger.info(
|
|
373
|
+
"Received track-api request.", extra={"request_uuid": inference_request_uuid}
|
|
374
|
+
)
|
|
375
|
+
result = self._track_api(
|
|
376
|
+
request.state.api, request.state.context, request_uuid=inference_request_uuid
|
|
377
|
+
)
|
|
378
|
+
sly.logger.info(
|
|
379
|
+
"Track-api request processed.", extra={"request_uuid": inference_request_uuid}
|
|
380
|
+
)
|
|
381
|
+
return result
|
|
327
382
|
|
|
328
383
|
@server.post("/track-api-files")
|
|
329
384
|
def track_api_files(
|
|
@@ -73,7 +73,7 @@ class TrackerInterface:
|
|
|
73
73
|
|
|
74
74
|
self.geometries[start_fig] = geometries[-1]
|
|
75
75
|
|
|
76
|
-
def frames_loader_generator(self, batch_size=
|
|
76
|
+
def frames_loader_generator(self, batch_size=4) -> Generator[None, None, None]:
|
|
77
77
|
if self.load_all_frames:
|
|
78
78
|
self._cur_frames_indexes = self.frames_indexes
|
|
79
79
|
yield
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
supervisely/README.md,sha256=XM-DiMC6To3I9RjQZ0c61905EFRR_jnCUx2q3uNR-X8,3331
|
|
2
|
-
supervisely/__init__.py,sha256=
|
|
2
|
+
supervisely/__init__.py,sha256=x83gx4W-dVuR8-6vthw5nZptfR0k_1FLQfXs7H36c3Q,10800
|
|
3
3
|
supervisely/_utils.py,sha256=I4nZ0L7NS6144r-CQ2VJvLeUJZ1bCi4pYXH4Gxo3-D4,15763
|
|
4
4
|
supervisely/function_wrapper.py,sha256=R5YajTQ0GnRp2vtjwfC9hINkzQc0JiyGsu8TER373xY,1912
|
|
5
5
|
supervisely/sly_logger.py,sha256=LG1wTyyctyEKuCuKM2IKf_SMPH7BzkTsFdO-0tnorzg,6225
|
|
@@ -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=kB9l0NhQEkunGDC9fWjNzf5DdhqRF1tv-RRnIbkV2k0,64941
|
|
25
25
|
supervisely/api/api.py,sha256=0dgPx_eizoCEFzfT8YH9uh1kq-OJwjrV5fBGD7uZ7E4,65840
|
|
26
|
-
supervisely/api/app_api.py,sha256
|
|
26
|
+
supervisely/api/app_api.py,sha256=RsbVej8WxWVn9cNo5s3Fqd1symsCdsfOaKVBKEUapRY,71927
|
|
27
27
|
supervisely/api/dataset_api.py,sha256=eovT6l62jgjlRyCZ6IvoudUBfDxv9Hjj3Ap8IuCLd7I,41290
|
|
28
28
|
supervisely/api/file_api.py,sha256=7yWt8lRQ4UfLmnMZ9T18UXzu8jihrtHtcqi6GZJG-0w,83414
|
|
29
29
|
supervisely/api/github_api.py,sha256=NIexNjEer9H5rf5sw2LEZd7C1WR-tK4t6IZzsgeAAwQ,623
|
|
@@ -32,7 +32,7 @@ supervisely/api/image_api.py,sha256=2cki-IzA5jnN3QqqdSIbIbHJhDWxFGYxXY94WqBOoio,
|
|
|
32
32
|
supervisely/api/import_storage_api.py,sha256=BDCgmR0Hv6OoiRHLCVPKt3iDxSVlQp1WrnKhAK_Zl84,460
|
|
33
33
|
supervisely/api/issues_api.py,sha256=BqDJXmNoTzwc3xe6_-mA7FDFC5QQ-ahGbXk_HmpkSeQ,17925
|
|
34
34
|
supervisely/api/labeling_job_api.py,sha256=odnzZjp29yM16Gq-FYkv-OA4WFMNJCLFo4qSikW2A7c,56280
|
|
35
|
-
supervisely/api/module_api.py,sha256=
|
|
35
|
+
supervisely/api/module_api.py,sha256=8z7K6K77fa9oijnix4vnCADJwe5nZtsDiWKZTWc_yuI,43273
|
|
36
36
|
supervisely/api/neural_network_api.py,sha256=ktPVRO4Jeulougio8F0mioJJHwRJcX250Djp1wBoQ9c,7620
|
|
37
37
|
supervisely/api/object_class_api.py,sha256=-rQcKwhBw3iL9KNH9c1ROgoimgWM1ls6Wi_tb1R-MzY,7683
|
|
38
38
|
supervisely/api/plugin_api.py,sha256=TlfrosdRuYG4NUxk92QiQoVaOdztFspPpygyVa3M3zk,5283
|
|
@@ -858,8 +858,8 @@ supervisely/nn/benchmark/visualization/widgets/sidebar/sidebar.py,sha256=tKPURRS
|
|
|
858
858
|
supervisely/nn/benchmark/visualization/widgets/table/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
859
859
|
supervisely/nn/benchmark/visualization/widgets/table/table.py,sha256=atmDnF1Af6qLQBUjLhK18RMDKAYlxnsuVHMSEa5a-e8,4319
|
|
860
860
|
supervisely/nn/inference/__init__.py,sha256=mtEci4Puu-fRXDnGn8RP47o97rv3VTE0hjbYO34Zwqg,1622
|
|
861
|
-
supervisely/nn/inference/cache.py,sha256=
|
|
862
|
-
supervisely/nn/inference/inference.py,sha256=
|
|
861
|
+
supervisely/nn/inference/cache.py,sha256=_pPSpkl8Wkqkiidn0vu6kWE19cngd80av--jncHxMEQ,30510
|
|
862
|
+
supervisely/nn/inference/inference.py,sha256=8MrOen2oyYIKiVqy0WbBTwABJZss9MLQ70EwX0e_-es,128895
|
|
863
863
|
supervisely/nn/inference/session.py,sha256=jmkkxbe2kH-lEgUU6Afh62jP68dxfhF5v6OGDfLU62E,35757
|
|
864
864
|
supervisely/nn/inference/video_inference.py,sha256=8Bshjr6rDyLay5Za8IB8Dr6FURMO2R_v7aELasO8pR4,5746
|
|
865
865
|
supervisely/nn/inference/gui/__init__.py,sha256=wCxd-lF5Zhcwsis-wScDA8n1Gk_1O00PKgDviUZ3F1U,221
|
|
@@ -892,13 +892,13 @@ supervisely/nn/inference/salient_object_segmentation/salient_object_segmentation
|
|
|
892
892
|
supervisely/nn/inference/semantic_segmentation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
893
893
|
supervisely/nn/inference/semantic_segmentation/semantic_segmentation.py,sha256=xpmViSYm1v_ZxlYyqiD_DiB7_LEynv9ZoU0t2QHEx8A,3370
|
|
894
894
|
supervisely/nn/inference/tracking/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
895
|
-
supervisely/nn/inference/tracking/bbox_tracking.py,sha256=
|
|
895
|
+
supervisely/nn/inference/tracking/bbox_tracking.py,sha256=EBEwLczXugCSYaIUFxB33h7SOIkPDEBWLhr_TbASNOA,17441
|
|
896
896
|
supervisely/nn/inference/tracking/functional.py,sha256=LpVu2gvOOpr9D_uvwTPZey1wUCAhV-E20RPKmCSIrK4,1774
|
|
897
897
|
supervisely/nn/inference/tracking/mask_tracking.py,sha256=qL9eUSqhzJwJMYaAzXX31oOu9EgdnGbsNwK9pOlV148,19610
|
|
898
898
|
supervisely/nn/inference/tracking/object_tracking_3d.py,sha256=Kqvx1qe1G8F1VtdBiy2HJ251rJU6s3LWhj0ZedhrmUw,4327
|
|
899
899
|
supervisely/nn/inference/tracking/point_tracking.py,sha256=Dweiq3dJUuwlFYnJbyx28L3IisNeg-1KQf2mBHrr7yI,22050
|
|
900
900
|
supervisely/nn/inference/tracking/tracker3d_interface.py,sha256=7yIkNO9rgkzQuyXUUccLwqlv5k7RPbxTqz9uI4FylLE,2781
|
|
901
|
-
supervisely/nn/inference/tracking/tracker_interface.py,sha256=
|
|
901
|
+
supervisely/nn/inference/tracking/tracker_interface.py,sha256=FXI9f0I5Tb5HN7l8fvxJ5wJ-QYuKyxfXiDpfXRLsSq4,10766
|
|
902
902
|
supervisely/nn/legacy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
903
903
|
supervisely/nn/legacy/config.py,sha256=TKdyGtURJKzKoyydCZAfujoUnbC0SO8GeVLTSnoyS_w,2994
|
|
904
904
|
supervisely/nn/legacy/dataset.py,sha256=-56EI6OYbkTWx4y8hOgD76y47zUoJNjGFyZ6JaP8iqg,6055
|
|
@@ -1057,9 +1057,9 @@ supervisely/worker_proto/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZ
|
|
|
1057
1057
|
supervisely/worker_proto/worker_api_pb2.py,sha256=VQfi5JRBHs2pFCK1snec3JECgGnua3Xjqw_-b3aFxuM,59142
|
|
1058
1058
|
supervisely/worker_proto/worker_api_pb2_grpc.py,sha256=3BwQXOaP9qpdi0Dt9EKG--Lm8KGN0C5AgmUfRv77_Jk,28940
|
|
1059
1059
|
supervisely_lib/__init__.py,sha256=7-3QnN8Zf0wj8NCr2oJmqoQWMKKPKTECvjH9pd2S5vY,159
|
|
1060
|
-
supervisely-6.73.
|
|
1061
|
-
supervisely-6.73.
|
|
1062
|
-
supervisely-6.73.
|
|
1063
|
-
supervisely-6.73.
|
|
1064
|
-
supervisely-6.73.
|
|
1065
|
-
supervisely-6.73.
|
|
1060
|
+
supervisely-6.73.263.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
1061
|
+
supervisely-6.73.263.dist-info/METADATA,sha256=M3YKXXtM4dpAgiB1GET6JjPaejX6M-qq4mmSAu4wis8,33573
|
|
1062
|
+
supervisely-6.73.263.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
|
|
1063
|
+
supervisely-6.73.263.dist-info/entry_points.txt,sha256=U96-5Hxrp2ApRjnCoUiUhWMqijqh8zLR03sEhWtAcms,102
|
|
1064
|
+
supervisely-6.73.263.dist-info/top_level.txt,sha256=kcFVwb7SXtfqZifrZaSE3owHExX4gcNYe7Q2uoby084,28
|
|
1065
|
+
supervisely-6.73.263.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|