sciveo 0.1.44__tar.gz → 0.1.46__tar.gz
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.
- {sciveo-0.1.44 → sciveo-0.1.46}/PKG-INFO +1 -1
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/cli.py +4 -1
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/pipelines/server.py +12 -4
- sciveo-0.1.46/sciveo/media/tools/nvr.py +143 -0
- sciveo-0.1.46/sciveo/ml/dataset/object_detection.py +243 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/monitoring/start.py +4 -6
- sciveo-0.1.46/sciveo/tools/__init__.py +0 -0
- sciveo-0.1.46/sciveo/tools/aws/__init__.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/tools/configuration.py +18 -1
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/tools/queue.py +16 -0
- sciveo-0.1.46/sciveo/version.py +2 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo.egg-info/PKG-INFO +1 -1
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo.egg-info/SOURCES.txt +5 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/test/test_compress.py +11 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/test/test_crypto.py +11 -0
- sciveo-0.1.46/test/test_ml_datasets.py +36 -0
- sciveo-0.1.44/sciveo/version.py +0 -2
- {sciveo-0.1.44 → sciveo-0.1.46}/README.md +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/__init__.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/api/__init__.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/api/base.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/api/upload.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/common/__init__.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/common/configuration.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/common/model.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/common/optimizers.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/common/sampling.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/content/__init__.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/content/dataset.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/content/experiment.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/content/project.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/content/runner.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/__init__.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/ml/__init__.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/ml/base.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/ml/encoders/__init__.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/ml/encoders/base.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/ml/encoders/normalizer.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/ml/nlp/__init__.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/ml/nlp/search.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/ml/time_series/__init__.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/ml/time_series/dataset.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/ml/time_series/predictor.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/ml/time_series/trainer.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/ml/time_series/window_generator.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/pipelines/__init__.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/pipelines/base.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/pipelines/job_daemon.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/pipelines/layouts/__init__.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/pipelines/layouts/base.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/pipelines/pipeline.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/pipelines/postprocessors/__init__.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/pipelines/postprocessors/base.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/pipelines/postprocessors/default.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/pipelines/processors/__init__.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/pipelines/processors/audio/__init__.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/pipelines/processors/audio/audio.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/pipelines/processors/audio/audio_extractor_process.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/pipelines/processors/aws.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/pipelines/processors/base.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/pipelines/processors/file/__init__.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/pipelines/processors/file/archive.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/pipelines/processors/image/__init__.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/pipelines/processors/image/album.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/pipelines/processors/image/album_in_image.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/pipelines/processors/image/depth_esimation.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/pipelines/processors/image/embeddings.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/pipelines/processors/image/filters.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/pipelines/processors/image/generators.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/pipelines/processors/image/histogram.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/pipelines/processors/image/mask.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/pipelines/processors/image/object_detection.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/pipelines/processors/image/resize.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/pipelines/processors/image/segmentation.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/pipelines/processors/image/watermark.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/pipelines/processors/media_info.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/pipelines/processors/nlp/__init__.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/pipelines/processors/nlp/address.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/pipelines/processors/qr.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/pipelines/processors/sci/__init__.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/pipelines/processors/sci/base.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/pipelines/processors/sci/dataset.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/pipelines/processors/sci/time_series/__init__.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/pipelines/processors/sci/time_series/predictor.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/pipelines/processors/sci/time_series/trainer.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/pipelines/processors/tpu_base.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/pipelines/processors/video/__init__.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/pipelines/processors/video/generators.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/pipelines/processors/video/motion_detection.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/pipelines/processors/video/resize.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/pipelines/processors/video/video_album.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/pipelines/processors/video/video_frames.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/pipelines/processors/video/video_resample.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/pipelines/queues.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/pipelines/web/__init__.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/pipelines/web/server.py +0 -0
- {sciveo-0.1.44/sciveo/ml → sciveo-0.1.46/sciveo/media/tools}/__init__.py +0 -0
- {sciveo-0.1.44/sciveo/ml/evaluation → sciveo-0.1.46/sciveo/ml}/__init__.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/ml/base.py +0 -0
- {sciveo-0.1.44/sciveo/ml/images → sciveo-0.1.46/sciveo/ml/dataset}/__init__.py +0 -0
- {sciveo-0.1.44/sciveo/ml/nlp → sciveo-0.1.46/sciveo/ml/evaluation}/__init__.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/ml/evaluation/object_detection.py +0 -0
- {sciveo-0.1.44/sciveo/ml/nlp/tokenizers → sciveo-0.1.46/sciveo/ml/images}/__init__.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/ml/images/base.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/ml/images/description.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/ml/images/embeddings.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/ml/images/object_detection.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/ml/images/segmentation.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/ml/images/tools.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/ml/images/transformers.py +0 -0
- {sciveo-0.1.44/sciveo/ml/video → sciveo-0.1.46/sciveo/ml/nlp}/__init__.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/ml/nlp/embeddings.py +0 -0
- {sciveo-0.1.44/sciveo/monitoring → sciveo-0.1.46/sciveo/ml/nlp/tokenizers}/__init__.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/ml/nlp/tokenizers/bpe.py +0 -0
- {sciveo-0.1.44/sciveo/network → sciveo-0.1.46/sciveo/ml/video}/__init__.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/ml/video/description.py +0 -0
- {sciveo-0.1.44/sciveo/tools → sciveo-0.1.46/sciveo/monitoring}/__init__.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/monitoring/monitor.py +0 -0
- {sciveo-0.1.44/sciveo/tools/aws → sciveo-0.1.46/sciveo/network}/__init__.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/network/camera.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/network/sniffer.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/network/tools.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/tools/array.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/tools/aws/priority_queue.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/tools/aws/s3.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/tools/common.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/tools/complexity.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/tools/compress.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/tools/crypto.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/tools/daemon.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/tools/formating.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/tools/hardware.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/tools/http.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/tools/logger.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/tools/os.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/tools/random.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/tools/remote.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/tools/simple_counter.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/tools/synchronized.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo/tools/timers.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo.egg-info/dependency_links.txt +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo.egg-info/entry_points.txt +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo.egg-info/requires.txt +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/sciveo.egg-info/top_level.txt +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/setup.cfg +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/setup.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/test/test_complexity.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/test/test_configuration.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/test/test_monitoring.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/test/test_runner.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/test/test_sampling.py +0 -0
- {sciveo-0.1.44 → sciveo-0.1.46}/test/test_tokenizers.py +0 -0
|
@@ -25,7 +25,7 @@ def main():
|
|
|
25
25
|
parser.add_argument(
|
|
26
26
|
'command',
|
|
27
27
|
choices=[
|
|
28
|
-
'init', 'monitor', 'scan',
|
|
28
|
+
'init', 'monitor', 'scan', 'nvr',
|
|
29
29
|
'media-server', 'media-run'
|
|
30
30
|
],
|
|
31
31
|
help='Command to execute')
|
|
@@ -75,6 +75,9 @@ def main():
|
|
|
75
75
|
fp.write(line + '\n')
|
|
76
76
|
else:
|
|
77
77
|
info(f"init, [{base_path}] already there")
|
|
78
|
+
elif args.command == 'nvr':
|
|
79
|
+
from sciveo.media.tools.nvr import VideoRecorder
|
|
80
|
+
VideoRecorder(args.input_path).start()
|
|
78
81
|
elif args.command == 'media-server':
|
|
79
82
|
from sciveo.media.pipelines.server import __START_SCIVEO_MEDIA_SERVER__
|
|
80
83
|
__START_SCIVEO_MEDIA_SERVER__()
|
|
@@ -16,18 +16,26 @@ from sciveo.tools.logger import *
|
|
|
16
16
|
from sciveo.tools.daemon import DaemonBase
|
|
17
17
|
from sciveo.tools.os import *
|
|
18
18
|
from sciveo.tools.simple_counter import RunCounter
|
|
19
|
+
from sciveo.tools.configuration import ConfigurationArguments
|
|
19
20
|
from sciveo.tools.aws.priority_queue import SQSPriorityQueue
|
|
20
21
|
from sciveo.media.pipelines.pipeline import *
|
|
21
22
|
from sciveo.media.pipelines.queues import MediaJobState
|
|
22
23
|
|
|
23
24
|
|
|
24
25
|
class MaintenanceDaemon(DaemonBase):
|
|
25
|
-
def __init__(self,
|
|
26
|
-
|
|
26
|
+
def __init__(self, **kwargs):
|
|
27
|
+
self.arguments = ConfigurationArguments({
|
|
28
|
+
"period": 3600,
|
|
29
|
+
"run_period_files": 24,
|
|
30
|
+
"retention_period_files": 30,
|
|
31
|
+
}, **kwargs)
|
|
32
|
+
|
|
33
|
+
super().__init__(period=self.arguments["period"])
|
|
34
|
+
|
|
27
35
|
self.base_tmp_path = os.environ["WEB_MEDIA_PIPELINES_TMP_PATH"]
|
|
28
36
|
|
|
29
37
|
self.timers = [
|
|
30
|
-
RunCounter(
|
|
38
|
+
RunCounter(self.arguments['run_period_files'], lambda: run_system_cmd(f"find {self.base_tmp_path} -mtime +{self.arguments['retention_period_files']} -type f -delete")),
|
|
31
39
|
# RunCounter(3, self.print_me),
|
|
32
40
|
]
|
|
33
41
|
|
|
@@ -59,7 +67,7 @@ class MediaJobQueueDaemon(DaemonBase):
|
|
|
59
67
|
|
|
60
68
|
def __START_SCIVEO_MEDIA_SERVER__():
|
|
61
69
|
daemons = [
|
|
62
|
-
MaintenanceDaemon(period=3600),
|
|
70
|
+
MaintenanceDaemon(period=3600, run_period_files=24, retention_period_files=30),
|
|
63
71
|
MediaJobQueueDaemon(),
|
|
64
72
|
]
|
|
65
73
|
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Stanislav Georgiev, Softel Labs
|
|
3
|
+
#
|
|
4
|
+
# This is a proprietary file and may not be copied,
|
|
5
|
+
# distributed, or modified without express permission
|
|
6
|
+
# from the owner. For licensing inquiries, please
|
|
7
|
+
# contact s.georgiev@softel.bg.
|
|
8
|
+
#
|
|
9
|
+
# 2025
|
|
10
|
+
#
|
|
11
|
+
|
|
12
|
+
import os
|
|
13
|
+
import subprocess as sp
|
|
14
|
+
import time
|
|
15
|
+
import re
|
|
16
|
+
import json
|
|
17
|
+
import cv2
|
|
18
|
+
import datetime
|
|
19
|
+
|
|
20
|
+
from sciveo.tools.logger import *
|
|
21
|
+
from sciveo.tools.daemon import DaemonBase
|
|
22
|
+
from sciveo.tools.queue import TouchedFilePathQueue
|
|
23
|
+
from sciveo.tools.simple_counter import RunCounter
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class VideoCameraCaptureDaemon(DaemonBase):
|
|
27
|
+
def __init__(self, cam_id, url, dst_path, max_video_len=60, transport="tcp"):
|
|
28
|
+
super().__init__()
|
|
29
|
+
self.cam_id = cam_id
|
|
30
|
+
self.url = url
|
|
31
|
+
self.dst_path = dst_path
|
|
32
|
+
self.max_video_len = max_video_len
|
|
33
|
+
self.transport = transport
|
|
34
|
+
self.cmd = [
|
|
35
|
+
"ffmpeg",
|
|
36
|
+
"-rtsp_transport", self.transport,
|
|
37
|
+
"-i", self.url,
|
|
38
|
+
"-c", "copy",
|
|
39
|
+
"-acodec", "aac",
|
|
40
|
+
"-f", "segment",
|
|
41
|
+
"-segment_time", f"{self.max_video_len}",
|
|
42
|
+
"-reset_timestamps", "1",
|
|
43
|
+
"-strftime", "1",
|
|
44
|
+
f"{self.dst_path}/{self.cam_id}___%Y-%m-%d___%H-%M-%S.mp4"
|
|
45
|
+
]
|
|
46
|
+
|
|
47
|
+
def clear(self):
|
|
48
|
+
os.system(f"pgrep -f \"{self.url}\" |xargs kill -9")
|
|
49
|
+
|
|
50
|
+
files = [f for f in os.listdir(self.dst_path) if os.path.isfile(os.path.join(self.dst_path, f))]
|
|
51
|
+
for file_name in files:
|
|
52
|
+
if file_name.startswith(f"{self.cam_id}___"):
|
|
53
|
+
file_path = os.path.join(self.dst_path, file_name)
|
|
54
|
+
info("RM", file_path)
|
|
55
|
+
os.remove(file_path)
|
|
56
|
+
|
|
57
|
+
def loop(self):
|
|
58
|
+
info("start", self.cam_id)
|
|
59
|
+
while(True):
|
|
60
|
+
self.clear()
|
|
61
|
+
|
|
62
|
+
p = sp.Popen(self.cmd, stdout=sp.DEVNULL, stderr=sp.DEVNULL)
|
|
63
|
+
p.wait()
|
|
64
|
+
|
|
65
|
+
self.clear()
|
|
66
|
+
warning(self.cam_id, "streaming interrupted, wait to retry...")
|
|
67
|
+
time.sleep(5)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
class VideoRecorder:
|
|
71
|
+
def __init__(self, path_configuration):
|
|
72
|
+
with open(path_configuration, 'r') as fp:
|
|
73
|
+
self.configuration = json.load(fp)
|
|
74
|
+
self.cams = []
|
|
75
|
+
|
|
76
|
+
for cam_id, cam_config in self.configuration["cam"].items():
|
|
77
|
+
cam = VideoCameraCaptureDaemon(
|
|
78
|
+
cam_id, cam_config["url"],
|
|
79
|
+
self.configuration["path"]["tmp"],
|
|
80
|
+
self.configuration.get("max_video_len", 60),
|
|
81
|
+
self.configuration.get("transport", "tcp")
|
|
82
|
+
)
|
|
83
|
+
self.cams.append(cam)
|
|
84
|
+
|
|
85
|
+
self.queue = TouchedFilePathQueue(self.configuration["path"]["tmp"], period=5, touched_timeout=5)
|
|
86
|
+
self.cleaner_timer = RunCounter(1000, self.clean_old_videos)
|
|
87
|
+
|
|
88
|
+
def start(self):
|
|
89
|
+
for cam in self.cams:
|
|
90
|
+
cam.start()
|
|
91
|
+
|
|
92
|
+
time.sleep(10)
|
|
93
|
+
|
|
94
|
+
while(True):
|
|
95
|
+
try:
|
|
96
|
+
file_name, file_path = self.queue.pop()
|
|
97
|
+
debug("pop", file_name, file_path)
|
|
98
|
+
self.process_file(file_name, file_path)
|
|
99
|
+
self.cleaner_timer.run()
|
|
100
|
+
except Exception as e:
|
|
101
|
+
exception(e)
|
|
102
|
+
time.sleep(1)
|
|
103
|
+
|
|
104
|
+
def process_file(self, file_name, file_path):
|
|
105
|
+
split = file_name.split("___")
|
|
106
|
+
if len(split) == 3:
|
|
107
|
+
cam_id = split[0]
|
|
108
|
+
video_date = split[1]
|
|
109
|
+
video_file_name = split[2]
|
|
110
|
+
else:
|
|
111
|
+
warning("wrong file format, removing", file_name, file_path)
|
|
112
|
+
os.remove(file_path)
|
|
113
|
+
|
|
114
|
+
match = re.match(r"(\d{2})\-(\d{2})\-(\d{2})\.mp4", video_file_name)
|
|
115
|
+
if not match:
|
|
116
|
+
warning("Invalid filename format")
|
|
117
|
+
video_file_name_split = video_file_name.split(".")
|
|
118
|
+
video_file_name = f"{video_file_name_split[0]}-{video_file_name_split[0]}.{video_file_name_split[1]}"
|
|
119
|
+
else:
|
|
120
|
+
hh, mm, ss = map(int, match.groups())
|
|
121
|
+
start_time = datetime.datetime(2000, 1, 1, hh, mm, ss)
|
|
122
|
+
end_time = start_time + datetime.timedelta(seconds=self.configuration["max_video_len"])
|
|
123
|
+
video_file_name = f"{start_time.strftime('%H.%M.%S')}-{end_time.strftime('%H.%M.%S')}.mp4"
|
|
124
|
+
|
|
125
|
+
video_base_path = os.path.join(self.configuration["path"]["video"], cam_id, video_date)
|
|
126
|
+
video_file_path = os.path.join(video_base_path, video_file_name)
|
|
127
|
+
|
|
128
|
+
debug("MV", file_path, "=>", video_file_path)
|
|
129
|
+
os.makedirs(video_base_path, exist_ok=True)
|
|
130
|
+
os.rename(file_path, video_file_path)
|
|
131
|
+
|
|
132
|
+
def clean_old_videos(self):
|
|
133
|
+
try:
|
|
134
|
+
days = self.configuration.get("video_retention_period", 7)
|
|
135
|
+
cmd = "find {} -mtime +{} -type f -delete".format(self.configuration["path"]["video"], days)
|
|
136
|
+
debug("cmd", cmd)
|
|
137
|
+
os.system(cmd)
|
|
138
|
+
except Exception as e:
|
|
139
|
+
excprint([self], e, cmd)
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
if __name__ == '__main__':
|
|
143
|
+
VideoRecorder("./cams.json").start()
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Pavlin Georgiev, Softel Labs
|
|
3
|
+
#
|
|
4
|
+
# This is a proprietary file and may not be copied,
|
|
5
|
+
# distributed, or modified without express permission
|
|
6
|
+
# from the owner. For licensing inquiries, please
|
|
7
|
+
# contact pavlin@softel.bg.
|
|
8
|
+
#
|
|
9
|
+
# 2024
|
|
10
|
+
#
|
|
11
|
+
|
|
12
|
+
import os
|
|
13
|
+
import shutil
|
|
14
|
+
import yaml
|
|
15
|
+
import json
|
|
16
|
+
import time
|
|
17
|
+
import math
|
|
18
|
+
import numpy as np
|
|
19
|
+
|
|
20
|
+
from sciveo.tools.logger import *
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def bbox_from_yolo(yolo_bbox):
|
|
24
|
+
yolo_bbox = [float(a) for a in yolo_bbox]
|
|
25
|
+
n, cx, cy, w, h = yolo_bbox
|
|
26
|
+
x1 = cx - w / 2
|
|
27
|
+
y1 = cy - h / 2
|
|
28
|
+
x2 = cx + w / 2
|
|
29
|
+
y2 = cy + h / 2
|
|
30
|
+
return [x1, y1, x2, y2]
|
|
31
|
+
|
|
32
|
+
def bbox_to_yolo(bbox):
|
|
33
|
+
n, x1, y1, x2, y2 = bbox
|
|
34
|
+
cx = (x1 + x2) / 2
|
|
35
|
+
cy = (y1 + y2) / 2
|
|
36
|
+
w = x2 - x1
|
|
37
|
+
h = y2 - y1
|
|
38
|
+
return [n, cx, cy, w, h]
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class YOLODataset:
|
|
42
|
+
def __init__(self):
|
|
43
|
+
self.src_path = None
|
|
44
|
+
self.dst_path = None
|
|
45
|
+
|
|
46
|
+
self.classes = {}
|
|
47
|
+
self.splits = []
|
|
48
|
+
self.labels = {}
|
|
49
|
+
|
|
50
|
+
def load(self, base_path):
|
|
51
|
+
self.src_path = base_path
|
|
52
|
+
yaml_path = os.path.join(base_path, "data.yaml")
|
|
53
|
+
if not os.path.exists(yaml_path):
|
|
54
|
+
raise FileNotFoundError(f"data.yaml not found in {base_path}")
|
|
55
|
+
|
|
56
|
+
with open(yaml_path, "r") as f:
|
|
57
|
+
self.data_yaml = yaml.safe_load(f)
|
|
58
|
+
|
|
59
|
+
self.classes = self.data_yaml.get("names", {})
|
|
60
|
+
self.splits = [key for key in self.data_yaml.keys() if key not in ["names", "nc", "path"]]
|
|
61
|
+
self.labels = {split: self._load_labels_for_split(base_path, split) for split in self.splits}
|
|
62
|
+
|
|
63
|
+
def _load_labels_for_split(self, base_path, split: str):
|
|
64
|
+
images_dir = self.data_yaml.get(split)
|
|
65
|
+
labels_dir = images_dir.replace("images", "labels")
|
|
66
|
+
if not labels_dir:
|
|
67
|
+
return {}
|
|
68
|
+
|
|
69
|
+
images_path = os.path.join(base_path, images_dir)
|
|
70
|
+
labels_path = os.path.join(base_path, labels_dir)
|
|
71
|
+
if not os.path.exists(labels_path):
|
|
72
|
+
return {}
|
|
73
|
+
|
|
74
|
+
annotations = {}
|
|
75
|
+
for label_file in os.listdir(labels_path):
|
|
76
|
+
if label_file.endswith(".txt"):
|
|
77
|
+
image_id = label_file.replace(".txt", ".jpg")
|
|
78
|
+
label_path = os.path.join(labels_path, label_file)
|
|
79
|
+
|
|
80
|
+
with open(label_path, "r") as f:
|
|
81
|
+
annotations[image_id] = [line.strip().split() for line in f.readlines()]
|
|
82
|
+
|
|
83
|
+
return annotations
|
|
84
|
+
|
|
85
|
+
def save(self, base_path, classes=[], copy_images=True):
|
|
86
|
+
self.dst_path = base_path
|
|
87
|
+
os.makedirs(self.dst_path, exist_ok=True)
|
|
88
|
+
|
|
89
|
+
yaml_path = os.path.join(base_path, "data.yaml")
|
|
90
|
+
|
|
91
|
+
if not classes:
|
|
92
|
+
selected_classes = self.classes
|
|
93
|
+
else:
|
|
94
|
+
selected_classes = {idx: name for idx, name in self.classes.items() if name in classes}
|
|
95
|
+
|
|
96
|
+
class_mapping = {name: new_idx for new_idx, (idx, name) in enumerate(selected_classes.items())}
|
|
97
|
+
|
|
98
|
+
# data_yaml = {
|
|
99
|
+
# "path": "./",
|
|
100
|
+
# "names": {idx: name for idx, name in selected_classes.items()}
|
|
101
|
+
# }
|
|
102
|
+
# for split in self.splits:
|
|
103
|
+
# data_yaml[split] = f"images/{split}"
|
|
104
|
+
# with open(yaml_path, "w") as f:
|
|
105
|
+
# yaml.dump(data_yaml, f, default_flow_style=False)
|
|
106
|
+
|
|
107
|
+
with open(yaml_path, "w") as fp:
|
|
108
|
+
fp.write(" path: ./ # dataset root dir\n")
|
|
109
|
+
for split in self.splits:
|
|
110
|
+
fp.write(f" test: images/{split}\n")
|
|
111
|
+
fp.write(" names:\n")
|
|
112
|
+
for class_id, class_name in selected_classes.items():
|
|
113
|
+
fp.write(f" {class_id}: {class_name}\n")
|
|
114
|
+
|
|
115
|
+
for split, images in self.labels.items():
|
|
116
|
+
labels_path = os.path.join(base_path, "labels", split)
|
|
117
|
+
images_path = os.path.join(base_path, "images", split)
|
|
118
|
+
os.makedirs(labels_path, exist_ok=True)
|
|
119
|
+
os.makedirs(images_path, exist_ok=True)
|
|
120
|
+
|
|
121
|
+
for image_name, annotations in images.items():
|
|
122
|
+
label_file_path = os.path.join(labels_path, image_name.replace(".jpg", ".txt"))
|
|
123
|
+
|
|
124
|
+
with open(label_file_path, "w") as f:
|
|
125
|
+
for annotation in annotations:
|
|
126
|
+
class_id, *bbox = map(float, annotation)
|
|
127
|
+
class_id = int(class_id)
|
|
128
|
+
|
|
129
|
+
class_name = self.classes.get(class_id)
|
|
130
|
+
if class_name in class_mapping:
|
|
131
|
+
new_class_id = class_mapping[class_name]
|
|
132
|
+
f.write(f"{new_class_id} {' '.join(map(str, bbox))}\n")
|
|
133
|
+
|
|
134
|
+
if copy_images and self.src_path:
|
|
135
|
+
src_image_path = os.path.join(self.src_path, "images", split, image_name)
|
|
136
|
+
dst_image_path = os.path.join(images_path, image_name)
|
|
137
|
+
if not os.path.isfile(dst_image_path):
|
|
138
|
+
shutil.copy(src_image_path, dst_image_path)
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
"""
|
|
142
|
+
Object Detection Dataset
|
|
143
|
+
|
|
144
|
+
labels in splits (for example train/val/test)
|
|
145
|
+
every dataset split has image name as key which points to dict of classes as keys
|
|
146
|
+
|
|
147
|
+
labels[split][image_name][class_name] is a list of bounding boxes of same class
|
|
148
|
+
bboxes are of type nxyxy which means normalized [x1, y1, x2, y2] coordinates (upper left and down right point of the rectangle)
|
|
149
|
+
|
|
150
|
+
"""
|
|
151
|
+
class ObjectDetectionDataset:
|
|
152
|
+
def __init__(self):
|
|
153
|
+
self.classes = []
|
|
154
|
+
self.splits = []
|
|
155
|
+
self.labels = {}
|
|
156
|
+
|
|
157
|
+
self.src_path = None
|
|
158
|
+
self.dst_path = None
|
|
159
|
+
|
|
160
|
+
def save(self, base_path, copy_images=True, src_path=None):
|
|
161
|
+
if src_path is not None:
|
|
162
|
+
self.src_path = src_path
|
|
163
|
+
|
|
164
|
+
self.dst_path = base_path
|
|
165
|
+
for split in self.splits:
|
|
166
|
+
images_path = os.path.join(self.dst_path, split, "images")
|
|
167
|
+
os.makedirs(images_path, exist_ok=True)
|
|
168
|
+
|
|
169
|
+
labels_path = os.path.join(self.dst_path, split, "labels.json")
|
|
170
|
+
with open(labels_path, 'w') as fp:
|
|
171
|
+
json.dump(self.labels[split], fp, indent=2)
|
|
172
|
+
|
|
173
|
+
if copy_images and self.src_path:
|
|
174
|
+
src_images_path = os.path.join(self.src_path, "images", split)
|
|
175
|
+
for image_path, subdirs, image_files in os.walk(src_images_path):
|
|
176
|
+
for image_name in image_files:
|
|
177
|
+
src_path = os.path.join(image_path, image_name)
|
|
178
|
+
dst_path = os.path.join(images_path, image_name)
|
|
179
|
+
if not os.path.isfile(dst_path):
|
|
180
|
+
shutil.copy(src_path, dst_path)
|
|
181
|
+
|
|
182
|
+
def from_yolo(self, base_path):
|
|
183
|
+
self.src_path = base_path
|
|
184
|
+
|
|
185
|
+
self.raw = YOLODataset()
|
|
186
|
+
self.raw.load(base_path)
|
|
187
|
+
|
|
188
|
+
self.classes = []
|
|
189
|
+
for i in range(len(self.raw.classes)):
|
|
190
|
+
self.classes.append(self.raw.classes[i])
|
|
191
|
+
self.splits = self.raw.splits
|
|
192
|
+
self.image_labels = {}
|
|
193
|
+
self.labels = {}
|
|
194
|
+
for split, split_labels in self.raw.labels.items():
|
|
195
|
+
self.image_labels.setdefault(split, {})
|
|
196
|
+
self.labels.setdefault(split, {})
|
|
197
|
+
for image_id, image_labels in split_labels.items():
|
|
198
|
+
self.image_labels[split].setdefault(image_id, {})
|
|
199
|
+
for label in image_labels:
|
|
200
|
+
class_id = int(label[0])
|
|
201
|
+
class_name = self.raw.classes[class_id]
|
|
202
|
+
bbox = bbox_from_yolo(label)
|
|
203
|
+
|
|
204
|
+
self.image_labels[split][image_id].setdefault(class_name, [])
|
|
205
|
+
self.image_labels[split][image_id][class_name].append(bbox)
|
|
206
|
+
|
|
207
|
+
self.labels[split].setdefault(class_name, {})
|
|
208
|
+
self.labels[split][class_name].setdefault(image_id, [])
|
|
209
|
+
self.labels[split][class_name][image_id].append(bbox)
|
|
210
|
+
|
|
211
|
+
def stats(self):
|
|
212
|
+
result = {"datasets": {}, "count": {}, "distribution": {}}
|
|
213
|
+
for split in self.splits:
|
|
214
|
+
result["datasets"].setdefault(split, {})
|
|
215
|
+
result["count"].setdefault(split, 0)
|
|
216
|
+
for class_name in self.classes:
|
|
217
|
+
result["datasets"][split].setdefault(class_name, 0)
|
|
218
|
+
for image_name, image_labels in self.labels[split][class_name].items():
|
|
219
|
+
result["count"][split] += len(image_labels)
|
|
220
|
+
result["datasets"][split][class_name] += len(image_labels)
|
|
221
|
+
|
|
222
|
+
for split in self.splits:
|
|
223
|
+
result["distribution"].setdefault(split, [])
|
|
224
|
+
for class_name in self.classes:
|
|
225
|
+
result["distribution"][split].append({class_name: result["datasets"][split][class_name] / result["count"][split]})
|
|
226
|
+
result["distribution"][split] = sorted(result["distribution"][split], key=lambda x: list(x.values())[0], reverse=True)
|
|
227
|
+
|
|
228
|
+
return result
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
if __name__ == "__main__":
|
|
233
|
+
# ds = YOLODataset()
|
|
234
|
+
# ds.load("/Users/sgeorgiev/develop/data/newspapers/test_yolo")
|
|
235
|
+
# debug("classes", ds.classes)
|
|
236
|
+
# ds.save(f"/Users/sgeorgiev/develop/data/newspapers/tmp/job-out", classes=["block", "vertical"], copy_images=True)
|
|
237
|
+
|
|
238
|
+
ds = ObjectDetectionDataset()
|
|
239
|
+
ds.from_yolo("/Users/sgeorgiev/develop/data/newspapers/test_yolo")
|
|
240
|
+
stats = ds.stats()
|
|
241
|
+
debug("stats", stats)
|
|
242
|
+
info("distribution", stats["distribution"])
|
|
243
|
+
# ds.save("/Users/sgeorgiev/develop/data/newspapers/tmp/od-1", copy_images=False)
|
|
@@ -13,24 +13,22 @@ import os
|
|
|
13
13
|
import time
|
|
14
14
|
|
|
15
15
|
from sciveo.tools.logger import *
|
|
16
|
+
from sciveo.tools.configuration import ConfigurationArguments
|
|
16
17
|
from sciveo.monitoring.monitor import BaseMonitor
|
|
17
18
|
|
|
18
19
|
|
|
19
20
|
class MonitorStart:
|
|
20
21
|
def __init__(self, **kwargs):
|
|
21
|
-
self.
|
|
22
|
+
self.arguments = ConfigurationArguments({
|
|
22
23
|
"period": 120,
|
|
23
24
|
"block": True,
|
|
24
25
|
"fork": False,
|
|
25
26
|
"fork_type": 0,
|
|
26
27
|
"output_path": None,
|
|
27
|
-
}
|
|
28
|
-
self.arguments = {}
|
|
29
|
-
for k, v in self.default_arguments.items():
|
|
30
|
-
self.arguments[k] = kwargs.get(k, v)
|
|
28
|
+
}, **kwargs)
|
|
31
29
|
|
|
32
30
|
if len(kwargs) == 0:
|
|
33
|
-
info("sciveo monitoring default options", self.
|
|
31
|
+
info("sciveo monitoring default options", self.arguments)
|
|
34
32
|
|
|
35
33
|
def __call__(self):
|
|
36
34
|
if self.arguments["fork"] and self.arguments["block"]:
|
|
File without changes
|
|
File without changes
|
|
@@ -78,4 +78,21 @@ class GlobalConfiguration:
|
|
|
78
78
|
if file_extension == ".json":
|
|
79
79
|
self.read_json(file_path)
|
|
80
80
|
else:
|
|
81
|
-
self.read_file(file_path)
|
|
81
|
+
self.read_file(file_path)
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
class ConfigurationArguments:
|
|
85
|
+
def __init__(self, default, **kwargs) -> None:
|
|
86
|
+
self.default = default
|
|
87
|
+
self.arguments = {}
|
|
88
|
+
for k, v in self.default.items():
|
|
89
|
+
self.arguments[k] = kwargs.get(k, v)
|
|
90
|
+
|
|
91
|
+
def __getitem__(self, key):
|
|
92
|
+
return self.arguments[key]
|
|
93
|
+
|
|
94
|
+
def __len__(self):
|
|
95
|
+
return len(self.arguments)
|
|
96
|
+
|
|
97
|
+
def __repr__(self):
|
|
98
|
+
return self.arguments
|
|
@@ -29,3 +29,19 @@ class FilePathQueue:
|
|
|
29
29
|
if self.filter(file_name, file_path):
|
|
30
30
|
return file_name, file_path
|
|
31
31
|
time.sleep(self.period)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class TouchedFilePathQueue(FilePathQueue):
|
|
35
|
+
def __init__(self, path, period, touched_timeout):
|
|
36
|
+
super().__init__(path, period)
|
|
37
|
+
self.touched_timeout = touched_timeout
|
|
38
|
+
|
|
39
|
+
def filter(self, file_name, file_path):
|
|
40
|
+
return self.touched(file_path) > self.touched_timeout
|
|
41
|
+
|
|
42
|
+
def touched(self, path):
|
|
43
|
+
try:
|
|
44
|
+
last_touched = time.time() - os.path.getmtime(path)
|
|
45
|
+
except Exception:
|
|
46
|
+
last_touched = sys.maxsize
|
|
47
|
+
return last_touched
|
|
@@ -87,8 +87,12 @@ sciveo/media/pipelines/processors/video/video_frames.py
|
|
|
87
87
|
sciveo/media/pipelines/processors/video/video_resample.py
|
|
88
88
|
sciveo/media/pipelines/web/__init__.py
|
|
89
89
|
sciveo/media/pipelines/web/server.py
|
|
90
|
+
sciveo/media/tools/__init__.py
|
|
91
|
+
sciveo/media/tools/nvr.py
|
|
90
92
|
sciveo/ml/__init__.py
|
|
91
93
|
sciveo/ml/base.py
|
|
94
|
+
sciveo/ml/dataset/__init__.py
|
|
95
|
+
sciveo/ml/dataset/object_detection.py
|
|
92
96
|
sciveo/ml/evaluation/__init__.py
|
|
93
97
|
sciveo/ml/evaluation/object_detection.py
|
|
94
98
|
sciveo/ml/images/__init__.py
|
|
@@ -138,6 +142,7 @@ test/test_complexity.py
|
|
|
138
142
|
test/test_compress.py
|
|
139
143
|
test/test_configuration.py
|
|
140
144
|
test/test_crypto.py
|
|
145
|
+
test/test_ml_datasets.py
|
|
141
146
|
test/test_monitoring.py
|
|
142
147
|
test/test_runner.py
|
|
143
148
|
test/test_sampling.py
|
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Pavlin Georgiev, Softel Labs
|
|
3
|
+
#
|
|
4
|
+
# This is a proprietary file and may not be copied,
|
|
5
|
+
# distributed, or modified without express permission
|
|
6
|
+
# from the owner. For licensing inquiries, please
|
|
7
|
+
# contact pavlin@softel.bg.
|
|
8
|
+
#
|
|
9
|
+
# 2024
|
|
10
|
+
#
|
|
11
|
+
|
|
1
12
|
import unittest
|
|
2
13
|
import json
|
|
3
14
|
|
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Pavlin Georgiev, Softel Labs
|
|
3
|
+
#
|
|
4
|
+
# This is a proprietary file and may not be copied,
|
|
5
|
+
# distributed, or modified without express permission
|
|
6
|
+
# from the owner. For licensing inquiries, please
|
|
7
|
+
# contact pavlin@softel.bg.
|
|
8
|
+
#
|
|
9
|
+
# 2024
|
|
10
|
+
#
|
|
11
|
+
|
|
1
12
|
import unittest
|
|
2
13
|
|
|
3
14
|
from sciveo.tools.crypto import *
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Pavlin Georgiev, Softel Labs
|
|
3
|
+
#
|
|
4
|
+
# This is a proprietary file and may not be copied,
|
|
5
|
+
# distributed, or modified without express permission
|
|
6
|
+
# from the owner. For licensing inquiries, please
|
|
7
|
+
# contact pavlin@softel.bg.
|
|
8
|
+
#
|
|
9
|
+
# 2024
|
|
10
|
+
#
|
|
11
|
+
|
|
12
|
+
import unittest
|
|
13
|
+
import json
|
|
14
|
+
|
|
15
|
+
from sciveo.ml.dataset.object_detection import *
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class TestMLDatasets(unittest.TestCase):
|
|
19
|
+
def test_object_detection(self):
|
|
20
|
+
HOME_PATH = os.path.expanduser("~")
|
|
21
|
+
|
|
22
|
+
ds = YOLODataset()
|
|
23
|
+
ds.load(f"{HOME_PATH}/data/test_yolo")
|
|
24
|
+
debug("classes", ds.classes)
|
|
25
|
+
ds.save(f"{HOME_PATH}/data/tmp/yolo-out", classes=["block", "vertical"], copy_images=True)
|
|
26
|
+
|
|
27
|
+
ds = ObjectDetectionDataset()
|
|
28
|
+
ds.from_yolo(f"{HOME_PATH}/data/test_yolo")
|
|
29
|
+
stats = ds.stats()
|
|
30
|
+
debug("stats", stats)
|
|
31
|
+
info("distribution", stats["distribution"])
|
|
32
|
+
ds.save(f"{HOME_PATH}/data/tmp/od-1", copy_images=False)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
if __name__ == '__main__':
|
|
36
|
+
unittest.main()
|
sciveo-0.1.44/sciveo/version.py
DELETED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/pipelines/processors/audio/audio_extractor_process.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/pipelines/processors/sci/time_series/__init__.py
RENAMED
|
File without changes
|
{sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/pipelines/processors/sci/time_series/predictor.py
RENAMED
|
File without changes
|
{sciveo-0.1.44 → sciveo-0.1.46}/sciveo/media/pipelines/processors/sci/time_series/trainer.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|