sciveo 0.1.45__tar.gz → 0.1.47__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.
Files changed (152) hide show
  1. {sciveo-0.1.45 → sciveo-0.1.47}/PKG-INFO +1 -1
  2. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/cli.py +15 -1
  3. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/pipelines/server.py +12 -4
  4. sciveo-0.1.47/sciveo/ml/dataset/object_detection.py +273 -0
  5. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/ml/evaluation/object_detection.py +35 -22
  6. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/ml/nlp/embeddings.py +1 -1
  7. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/monitoring/start.py +4 -6
  8. sciveo-0.1.47/sciveo/tools/aws/__init__.py +0 -0
  9. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/tools/configuration.py +18 -1
  10. sciveo-0.1.47/sciveo/version.py +2 -0
  11. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo.egg-info/PKG-INFO +1 -1
  12. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo.egg-info/SOURCES.txt +3 -0
  13. {sciveo-0.1.45 → sciveo-0.1.47}/test/test_compress.py +11 -0
  14. {sciveo-0.1.45 → sciveo-0.1.47}/test/test_crypto.py +11 -0
  15. sciveo-0.1.47/test/test_ml_datasets.py +46 -0
  16. sciveo-0.1.45/sciveo/version.py +0 -2
  17. {sciveo-0.1.45 → sciveo-0.1.47}/README.md +0 -0
  18. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/__init__.py +0 -0
  19. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/api/__init__.py +0 -0
  20. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/api/base.py +0 -0
  21. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/api/upload.py +0 -0
  22. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/common/__init__.py +0 -0
  23. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/common/configuration.py +0 -0
  24. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/common/model.py +0 -0
  25. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/common/optimizers.py +0 -0
  26. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/common/sampling.py +0 -0
  27. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/content/__init__.py +0 -0
  28. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/content/dataset.py +0 -0
  29. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/content/experiment.py +0 -0
  30. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/content/project.py +0 -0
  31. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/content/runner.py +0 -0
  32. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/__init__.py +0 -0
  33. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/ml/__init__.py +0 -0
  34. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/ml/base.py +0 -0
  35. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/ml/encoders/__init__.py +0 -0
  36. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/ml/encoders/base.py +0 -0
  37. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/ml/encoders/normalizer.py +0 -0
  38. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/ml/nlp/__init__.py +0 -0
  39. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/ml/nlp/search.py +0 -0
  40. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/ml/time_series/__init__.py +0 -0
  41. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/ml/time_series/dataset.py +0 -0
  42. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/ml/time_series/predictor.py +0 -0
  43. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/ml/time_series/trainer.py +0 -0
  44. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/ml/time_series/window_generator.py +0 -0
  45. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/pipelines/__init__.py +0 -0
  46. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/pipelines/base.py +0 -0
  47. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/pipelines/job_daemon.py +0 -0
  48. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/pipelines/layouts/__init__.py +0 -0
  49. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/pipelines/layouts/base.py +0 -0
  50. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/pipelines/pipeline.py +0 -0
  51. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/pipelines/postprocessors/__init__.py +0 -0
  52. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/pipelines/postprocessors/base.py +0 -0
  53. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/pipelines/postprocessors/default.py +0 -0
  54. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/pipelines/processors/__init__.py +0 -0
  55. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/pipelines/processors/audio/__init__.py +0 -0
  56. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/pipelines/processors/audio/audio.py +0 -0
  57. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/pipelines/processors/audio/audio_extractor_process.py +0 -0
  58. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/pipelines/processors/aws.py +0 -0
  59. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/pipelines/processors/base.py +0 -0
  60. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/pipelines/processors/file/__init__.py +0 -0
  61. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/pipelines/processors/file/archive.py +0 -0
  62. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/pipelines/processors/image/__init__.py +0 -0
  63. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/pipelines/processors/image/album.py +0 -0
  64. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/pipelines/processors/image/album_in_image.py +0 -0
  65. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/pipelines/processors/image/depth_esimation.py +0 -0
  66. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/pipelines/processors/image/embeddings.py +0 -0
  67. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/pipelines/processors/image/filters.py +0 -0
  68. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/pipelines/processors/image/generators.py +0 -0
  69. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/pipelines/processors/image/histogram.py +0 -0
  70. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/pipelines/processors/image/mask.py +0 -0
  71. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/pipelines/processors/image/object_detection.py +0 -0
  72. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/pipelines/processors/image/resize.py +0 -0
  73. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/pipelines/processors/image/segmentation.py +0 -0
  74. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/pipelines/processors/image/watermark.py +0 -0
  75. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/pipelines/processors/media_info.py +0 -0
  76. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/pipelines/processors/nlp/__init__.py +0 -0
  77. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/pipelines/processors/nlp/address.py +0 -0
  78. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/pipelines/processors/qr.py +0 -0
  79. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/pipelines/processors/sci/__init__.py +0 -0
  80. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/pipelines/processors/sci/base.py +0 -0
  81. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/pipelines/processors/sci/dataset.py +0 -0
  82. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/pipelines/processors/sci/time_series/__init__.py +0 -0
  83. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/pipelines/processors/sci/time_series/predictor.py +0 -0
  84. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/pipelines/processors/sci/time_series/trainer.py +0 -0
  85. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/pipelines/processors/tpu_base.py +0 -0
  86. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/pipelines/processors/video/__init__.py +0 -0
  87. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/pipelines/processors/video/generators.py +0 -0
  88. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/pipelines/processors/video/motion_detection.py +0 -0
  89. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/pipelines/processors/video/resize.py +0 -0
  90. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/pipelines/processors/video/video_album.py +0 -0
  91. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/pipelines/processors/video/video_frames.py +0 -0
  92. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/pipelines/processors/video/video_resample.py +0 -0
  93. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/pipelines/queues.py +0 -0
  94. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/pipelines/web/__init__.py +0 -0
  95. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/pipelines/web/server.py +0 -0
  96. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/tools/__init__.py +0 -0
  97. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/media/tools/nvr.py +0 -0
  98. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/ml/__init__.py +0 -0
  99. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/ml/base.py +0 -0
  100. {sciveo-0.1.45/sciveo/ml/evaluation → sciveo-0.1.47/sciveo/ml/dataset}/__init__.py +0 -0
  101. {sciveo-0.1.45/sciveo/ml/images → sciveo-0.1.47/sciveo/ml/evaluation}/__init__.py +0 -0
  102. {sciveo-0.1.45/sciveo/ml/nlp → sciveo-0.1.47/sciveo/ml/images}/__init__.py +0 -0
  103. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/ml/images/base.py +0 -0
  104. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/ml/images/description.py +0 -0
  105. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/ml/images/embeddings.py +0 -0
  106. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/ml/images/object_detection.py +0 -0
  107. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/ml/images/segmentation.py +0 -0
  108. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/ml/images/tools.py +0 -0
  109. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/ml/images/transformers.py +0 -0
  110. {sciveo-0.1.45/sciveo/ml/nlp/tokenizers → sciveo-0.1.47/sciveo/ml/nlp}/__init__.py +0 -0
  111. {sciveo-0.1.45/sciveo/ml/video → sciveo-0.1.47/sciveo/ml/nlp/tokenizers}/__init__.py +0 -0
  112. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/ml/nlp/tokenizers/bpe.py +0 -0
  113. {sciveo-0.1.45/sciveo/monitoring → sciveo-0.1.47/sciveo/ml/video}/__init__.py +0 -0
  114. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/ml/video/description.py +0 -0
  115. {sciveo-0.1.45/sciveo/network → sciveo-0.1.47/sciveo/monitoring}/__init__.py +0 -0
  116. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/monitoring/monitor.py +0 -0
  117. {sciveo-0.1.45/sciveo/tools → sciveo-0.1.47/sciveo/network}/__init__.py +0 -0
  118. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/network/camera.py +0 -0
  119. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/network/sniffer.py +0 -0
  120. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/network/tools.py +0 -0
  121. {sciveo-0.1.45/sciveo/tools/aws → sciveo-0.1.47/sciveo/tools}/__init__.py +0 -0
  122. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/tools/array.py +0 -0
  123. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/tools/aws/priority_queue.py +0 -0
  124. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/tools/aws/s3.py +0 -0
  125. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/tools/common.py +0 -0
  126. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/tools/complexity.py +0 -0
  127. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/tools/compress.py +0 -0
  128. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/tools/crypto.py +0 -0
  129. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/tools/daemon.py +0 -0
  130. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/tools/formating.py +0 -0
  131. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/tools/hardware.py +0 -0
  132. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/tools/http.py +0 -0
  133. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/tools/logger.py +0 -0
  134. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/tools/os.py +0 -0
  135. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/tools/queue.py +0 -0
  136. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/tools/random.py +0 -0
  137. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/tools/remote.py +0 -0
  138. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/tools/simple_counter.py +0 -0
  139. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/tools/synchronized.py +0 -0
  140. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo/tools/timers.py +0 -0
  141. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo.egg-info/dependency_links.txt +0 -0
  142. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo.egg-info/entry_points.txt +0 -0
  143. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo.egg-info/requires.txt +0 -0
  144. {sciveo-0.1.45 → sciveo-0.1.47}/sciveo.egg-info/top_level.txt +0 -0
  145. {sciveo-0.1.45 → sciveo-0.1.47}/setup.cfg +0 -0
  146. {sciveo-0.1.45 → sciveo-0.1.47}/setup.py +0 -0
  147. {sciveo-0.1.45 → sciveo-0.1.47}/test/test_complexity.py +0 -0
  148. {sciveo-0.1.45 → sciveo-0.1.47}/test/test_configuration.py +0 -0
  149. {sciveo-0.1.45 → sciveo-0.1.47}/test/test_monitoring.py +0 -0
  150. {sciveo-0.1.45 → sciveo-0.1.47}/test/test_runner.py +0 -0
  151. {sciveo-0.1.45 → sciveo-0.1.47}/test/test_sampling.py +0 -0
  152. {sciveo-0.1.45 → sciveo-0.1.47}/test/test_tokenizers.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sciveo
3
- Version: 0.1.45
3
+ Version: 0.1.47
4
4
  Description-Content-Type: text/markdown
5
5
  Provides-Extra: mon
6
6
  Provides-Extra: net
@@ -11,6 +11,7 @@
11
11
  #
12
12
 
13
13
  import os
14
+ import time
14
15
  import json
15
16
  import argparse
16
17
 
@@ -26,7 +27,8 @@ def main():
26
27
  'command',
27
28
  choices=[
28
29
  'init', 'monitor', 'scan', 'nvr',
29
- 'media-server', 'media-run'
30
+ 'media-server', 'media-run',
31
+ 'maintenance'
30
32
  ],
31
33
  help='Command to execute')
32
34
 
@@ -47,6 +49,9 @@ def main():
47
49
  parser.add_argument('--processor', type=str, help='Processor name')
48
50
  parser.add_argument('--src', type=str, default=None, help='Source')
49
51
  parser.add_argument('--dst', type=str, default=None, help='Destination')
52
+ parser.add_argument('--value', type=float, help='Value')
53
+ parser.add_argument('--threshold', type=float, help='Threshold')
54
+ parser.add_argument('--execute', type=str, default=None, help='Execute command')
50
55
 
51
56
  args = parser.parse_args()
52
57
 
@@ -85,6 +90,15 @@ def main():
85
90
  if args.processor == "audio-plot":
86
91
  from sciveo.media.pipelines.processors.audio.audio_extractor_process import plot_audio
87
92
  plot_audio(args.width, args.height, args.rate, args.input_path, args.output_path)
93
+ elif args.command == 'maintenance':
94
+ from sciveo.monitoring.process.memory import MemoryMonitorCommandDaemon
95
+ daemons = []
96
+ if args.execute is not None:
97
+ daemons.append(MemoryMonitorCommandDaemon(threshold_percent=args.threshold, period=args.period, command=args.execute))
98
+ for daemon in daemons:
99
+ daemon.start()
100
+ while(True):
101
+ time.sleep(3600)
88
102
  else:
89
103
  warning(args.command, "not implemented")
90
104
 
@@ -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, period=3600):
26
- super().__init__(period=period)
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(24, lambda: run_system_cmd(f"find {self.base_tmp_path} -mtime +30 -type f -delete")),
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,273 @@
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
+ from sciveo.ml.evaluation.object_detection import *
22
+
23
+
24
+ def xcycwh_to_xyxy(bbox):
25
+ cx, cy, w, h = 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 xyxy_to_xcycwh(bbox):
33
+ 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 [cx, cy, w, h]
39
+
40
+ def bbox_from_yolo(yolo_bbox):
41
+ yolo_bbox = [float(a) for a in yolo_bbox]
42
+ n, cx, cy, w, h = yolo_bbox
43
+ return xcycwh_to_xyxy([cx, cy, w, h])
44
+
45
+ def bbox_to_yolo(bbox):
46
+ n, x1, y1, x2, y2 = bbox
47
+ cx, cy, w, h = xyxy_to_xcycwh([x1, y1, x2, y2])
48
+ return [n, cx, cy, w, h]
49
+
50
+
51
+ class YOLODataset:
52
+ def __init__(self):
53
+ self.src_path = None
54
+ self.dst_path = None
55
+
56
+ self.classes = {}
57
+ self.splits = []
58
+ self.labels = {}
59
+
60
+ def load(self, base_path):
61
+ self.src_path = base_path
62
+ yaml_path = os.path.join(base_path, "data.yaml")
63
+ if not os.path.exists(yaml_path):
64
+ raise FileNotFoundError(f"data.yaml not found in {base_path}")
65
+
66
+ with open(yaml_path, "r") as f:
67
+ self.data_yaml = yaml.safe_load(f)
68
+
69
+ self.classes = self.data_yaml.get("names", {})
70
+ self.splits = [key for key in self.data_yaml.keys() if key not in ["names", "nc", "path"]]
71
+ self.labels = {split: self._load_labels_for_split(base_path, split) for split in self.splits}
72
+
73
+ def _load_labels_for_split(self, base_path, split: str):
74
+ images_dir = self.data_yaml.get(split)
75
+ labels_dir = images_dir.replace("images", "labels")
76
+ if not labels_dir:
77
+ return {}
78
+
79
+ images_path = os.path.join(base_path, images_dir)
80
+ labels_path = os.path.join(base_path, labels_dir)
81
+ if not os.path.exists(labels_path):
82
+ return {}
83
+
84
+ annotations = {}
85
+ for label_file in os.listdir(labels_path):
86
+ if label_file.endswith(".txt"):
87
+ image_id = label_file.replace(".txt", ".jpg")
88
+ label_path = os.path.join(labels_path, label_file)
89
+
90
+ with open(label_path, "r") as f:
91
+ annotations[image_id] = [line.strip().split() for line in f.readlines()]
92
+
93
+ return annotations
94
+
95
+ def save(self, base_path, classes=[], copy_images=True):
96
+ self.dst_path = base_path
97
+ os.makedirs(self.dst_path, exist_ok=True)
98
+
99
+ yaml_path = os.path.join(base_path, "data.yaml")
100
+
101
+ if not classes:
102
+ selected_classes = self.classes
103
+ else:
104
+ selected_classes = {idx: name for idx, name in self.classes.items() if name in classes}
105
+
106
+ class_mapping = {name: new_idx for new_idx, (idx, name) in enumerate(selected_classes.items())}
107
+
108
+ # data_yaml = {
109
+ # "path": "./",
110
+ # "names": {idx: name for idx, name in selected_classes.items()}
111
+ # }
112
+ # for split in self.splits:
113
+ # data_yaml[split] = f"images/{split}"
114
+ # with open(yaml_path, "w") as f:
115
+ # yaml.dump(data_yaml, f, default_flow_style=False)
116
+
117
+ with open(yaml_path, "w") as fp:
118
+ fp.write(" path: ./ # dataset root dir\n")
119
+ for split in self.splits:
120
+ fp.write(f" test: images/{split}\n")
121
+ fp.write(" names:\n")
122
+ for class_id, class_name in selected_classes.items():
123
+ fp.write(f" {class_id}: {class_name}\n")
124
+
125
+ for split, images in self.labels.items():
126
+ labels_path = os.path.join(base_path, "labels", split)
127
+ images_path = os.path.join(base_path, "images", split)
128
+ os.makedirs(labels_path, exist_ok=True)
129
+ os.makedirs(images_path, exist_ok=True)
130
+
131
+ for image_name, annotations in images.items():
132
+ label_file_path = os.path.join(labels_path, image_name.replace(".jpg", ".txt"))
133
+
134
+ with open(label_file_path, "w") as f:
135
+ for annotation in annotations:
136
+ class_id, *bbox = map(float, annotation)
137
+ class_id = int(class_id)
138
+
139
+ class_name = self.classes.get(class_id)
140
+ if class_name in class_mapping:
141
+ new_class_id = class_mapping[class_name]
142
+ f.write(f"{new_class_id} {' '.join(map(str, bbox))}\n")
143
+
144
+ if copy_images and self.src_path:
145
+ src_image_path = os.path.join(self.src_path, "images", split, image_name)
146
+ dst_image_path = os.path.join(images_path, image_name)
147
+ if not os.path.isfile(dst_image_path):
148
+ shutil.copy(src_image_path, dst_image_path)
149
+
150
+
151
+ """
152
+ Object Detection Dataset
153
+
154
+ labels in splits (for example train/val/test)
155
+ every dataset split has image name as key which points to dict of classes as keys
156
+
157
+ labels[split][image_name][class_name] is a list of bounding boxes of same class
158
+ bboxes are of type nxyxy which means normalized [x1, y1, x2, y2] coordinates (upper left and down right point of the rectangle)
159
+
160
+ """
161
+ class ObjectDetectionDataset:
162
+ def __init__(self):
163
+ self.classes = []
164
+ self.splits = []
165
+ self.labels = {}
166
+
167
+ self.src_path = None
168
+ self.dst_path = None
169
+
170
+ def save(self, base_path, copy_images=True, src_path=None):
171
+ if src_path is not None:
172
+ self.src_path = src_path
173
+
174
+ self.dst_path = base_path
175
+ for split in self.splits:
176
+ images_path = os.path.join(self.dst_path, split, "images")
177
+ os.makedirs(images_path, exist_ok=True)
178
+
179
+ labels_path = os.path.join(self.dst_path, split, "labels.json")
180
+ with open(labels_path, 'w') as fp:
181
+ json.dump(self.labels[split], fp, indent=2)
182
+
183
+ if copy_images and self.src_path:
184
+ src_images_path = os.path.join(self.src_path, "images", split)
185
+ for image_path, subdirs, image_files in os.walk(src_images_path):
186
+ for image_name in image_files:
187
+ src_path = os.path.join(image_path, image_name)
188
+ dst_path = os.path.join(images_path, image_name)
189
+ if not os.path.isfile(dst_path):
190
+ shutil.copy(src_path, dst_path)
191
+
192
+ def from_yolo(self, base_path):
193
+ self.src_path = base_path
194
+
195
+ self.raw = YOLODataset()
196
+ self.raw.load(base_path)
197
+
198
+ self.classes = []
199
+ for i in range(len(self.raw.classes)):
200
+ self.classes.append(self.raw.classes[i])
201
+ self.splits = self.raw.splits
202
+ self.image_labels = {}
203
+ self.labels = {}
204
+ for split, split_labels in self.raw.labels.items():
205
+ self.image_labels.setdefault(split, {})
206
+ self.labels.setdefault(split, {})
207
+ for image_id, image_labels in split_labels.items():
208
+ self.image_labels[split].setdefault(image_id, {})
209
+ for label in image_labels:
210
+ class_id = int(label[0])
211
+ class_name = self.raw.classes[class_id]
212
+ bbox = bbox_from_yolo(label)
213
+
214
+ self.image_labels[split][image_id].setdefault(class_name, [])
215
+ self.image_labels[split][image_id][class_name].append(bbox)
216
+
217
+ self.labels[split].setdefault(class_name, {})
218
+ self.labels[split][class_name].setdefault(image_id, [])
219
+ self.labels[split][class_name][image_id].append(bbox)
220
+
221
+ def stats(self):
222
+ result = {"datasets": {}, "count": {}, "distribution": {}}
223
+ for split in self.splits:
224
+ result["datasets"].setdefault(split, {})
225
+ result["count"].setdefault(split, 0)
226
+ for class_name in self.classes:
227
+ result["datasets"][split].setdefault(class_name, 0)
228
+ for image_name, image_labels in self.labels[split][class_name].items():
229
+ result["count"][split] += len(image_labels)
230
+ result["datasets"][split][class_name] += len(image_labels)
231
+
232
+ for split in self.splits:
233
+ result["distribution"].setdefault(split, [])
234
+ for class_name in self.classes:
235
+ result["distribution"][split].append({class_name: result["datasets"][split][class_name] / result["count"][split]})
236
+ result["distribution"][split] = sorted(result["distribution"][split], key=lambda x: list(x.values())[0], reverse=True)
237
+
238
+ return result
239
+
240
+
241
+ class EvalObjectDetectionDataset(EvalObjectDetection):
242
+ def __init__(self, predictions, labels, split="test"):
243
+ self.split = split
244
+ super().__init__(predictions.image_labels[split], labels.image_labels[split], predictions.classes)
245
+ self.from_datasets()
246
+
247
+ """
248
+ Converted predictions of type [{"class 1": [x1,y1,x2,y2, confidence]}, ...]
249
+ Boxes of type xyxyn + confidence
250
+
251
+ Converted Labels of type [{"class 1": [[x1,y1,x2,y2],...], "class 2": [[], [],...]...}]
252
+ Boxes of type xyxyn
253
+ """
254
+ def from_datasets(self):
255
+ self.converted_predictions = []
256
+ self.converted_labels = []
257
+
258
+ list_prediction_images = list(self.predictions.keys())
259
+ list_prediction_images.sort()
260
+ list_labels_images = list(self.labels.keys())
261
+ list_labels_images.sort()
262
+ if not all(a == b for a, b in zip(list_prediction_images, list_labels_images)):
263
+ error("predictions and labels differ")
264
+ return
265
+
266
+ for image_name in list_prediction_images:
267
+ self.converted_labels.append(self.labels[image_name])
268
+ current_image_prediction = {}
269
+ for class_name, class_prediction in self.predictions[image_name].items():
270
+ current_image_prediction[class_name] = class_prediction
271
+ for i, current_class_prediction in enumerate(current_image_prediction[class_name]):
272
+ current_image_prediction[class_name][i].append(1.0)
273
+ self.converted_predictions.append(current_image_prediction)
@@ -17,6 +17,28 @@ from sciveo.tools.logger import *
17
17
  from sciveo.ml.images.object_detection import *
18
18
 
19
19
 
20
+ def compute_iou_xyxy(box1, box2):
21
+ """
22
+ box1, box2: [x1, y1, x2, y2] format.
23
+ Returns the IoU between the two boxes.
24
+ """
25
+ x1_inter = max(box1[0], box2[0])
26
+ y1_inter = max(box1[1], box2[1])
27
+ x2_inter = min(box1[2], box2[2])
28
+ y2_inter = min(box1[3], box2[3])
29
+
30
+ inter_area = max(0, x2_inter - x1_inter) * max(0, y2_inter - y1_inter)
31
+ box1_area = (box1[2] - box1[0]) * (box1[3] - box1[1])
32
+ box2_area = (box2[2] - box2[0]) * (box2[3] - box2[1])
33
+ union_area = box1_area + box2_area - inter_area
34
+
35
+ if union_area == 0:
36
+ return 0.0
37
+
38
+ return inter_area / union_area
39
+
40
+
41
+
20
42
  """
21
43
 
22
44
  Object Detection Evaluation
@@ -39,6 +61,10 @@ class EvalObjectDetection:
39
61
  boxes = predicted.boxes
40
62
  class_names = predicted.names
41
63
 
64
+ """
65
+ Converted predictions of type [{"class 1": [x1,y1,x2,y2, confidence]}, ...]
66
+ Boxes of type xyxyn + confidence
67
+ """
42
68
  converted_prediction = {}
43
69
  for i in range(len(boxes)):
44
70
  class_id = int(boxes.cls[i].item())
@@ -53,7 +79,14 @@ class EvalObjectDetection:
53
79
  converted_prediction[label_class].append(box_confidence)
54
80
  self.converted_predictions.append(converted_prediction)
55
81
 
56
- # TODO: currently labels of type [ {"class 1": [ ['x1':x1,'y1':y1,'x2':x2,'y2':y2] ... ], "class 2": [ ['x1':x1,'y1':y1,'x2':x2,'y2':y2] ... ]} ... ]
82
+ self._convert_labels_dict()
83
+
84
+ """
85
+ Labels of type [ {"class 1": [ ['x1':x1,'y1':y1,'x2':x2,'y2':y2] ... ], "class 2": [ ['x1':x1,'y1':y1,'x2':x2,'y2':y2] ... ]} ... ]
86
+ Converted Labels of type [{"class 1": [[x1,y1,x2,y2],...], "class 2": [[], [],...]...}]
87
+ Boxes of type xyxyn
88
+ """
89
+ def _convert_labels_dict(self):
57
90
  self.converted_labels = []
58
91
  for label in self.labels:
59
92
  converted_label = {}
@@ -63,26 +96,6 @@ class EvalObjectDetection:
63
96
  converted_label[class_name].append([box['x1'], box['y1'], box['x2'], box['y2']])
64
97
  self.converted_labels.append(converted_label)
65
98
 
66
- def compute_iou(self, box1, box2):
67
- """
68
- box1, box2: [x1, y1, x2, y2] format.
69
- Returns the IoU between the two boxes.
70
- """
71
- x1_inter = max(box1[0], box2[0])
72
- y1_inter = max(box1[1], box2[1])
73
- x2_inter = min(box1[2], box2[2])
74
- y2_inter = min(box1[3], box2[3])
75
-
76
- inter_area = max(0, x2_inter - x1_inter) * max(0, y2_inter - y1_inter)
77
- box1_area = (box1[2] - box1[0]) * (box1[3] - box1[1])
78
- box2_area = (box2[2] - box2[0]) * (box2[3] - box2[1])
79
- union_area = box1_area + box2_area - inter_area
80
-
81
- if union_area == 0:
82
- return 0.0
83
-
84
- return inter_area / union_area
85
-
86
99
  def compute_ap(self, class_name, confidence_threshold=0.0):
87
100
  """
88
101
  Calculate the Average Precision based on IoU and confidence scores.
@@ -108,7 +121,7 @@ class EvalObjectDetection:
108
121
  gt_match = None
109
122
 
110
123
  for label_box in current_labels:
111
- iou = self.compute_iou(prediction_box[:4], label_box)
124
+ iou = compute_iou_xyxy(prediction_box[:4], label_box)
112
125
  if iou > 0.5 and iou >= max_iou:
113
126
  max_iou = iou
114
127
  gt_match = label_box
@@ -132,7 +132,7 @@ class TextEmbedding(BaseML):
132
132
 
133
133
 
134
134
  class SentenceEmbedding(TextEmbedding):
135
- def __init__(self, model_name='BAAI/bge-m3', cache_dir=None, device=None) -> None:
135
+ def __init__(self, model_name='softel/sentence-bge-v1.3', cache_dir=None, device=None) -> None:
136
136
  super().__init__(model_name=model_name, cache_dir=cache_dir, device=device)
137
137
  self.model = None
138
138
  self.max_tokens = 8192
@@ -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.default_arguments = {
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.default_arguments)
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
@@ -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
@@ -0,0 +1,2 @@
1
+
2
+ __version__ = '0.1.47'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sciveo
3
- Version: 0.1.45
3
+ Version: 0.1.47
4
4
  Description-Content-Type: text/markdown
5
5
  Provides-Extra: mon
6
6
  Provides-Extra: net
@@ -91,6 +91,8 @@ sciveo/media/tools/__init__.py
91
91
  sciveo/media/tools/nvr.py
92
92
  sciveo/ml/__init__.py
93
93
  sciveo/ml/base.py
94
+ sciveo/ml/dataset/__init__.py
95
+ sciveo/ml/dataset/object_detection.py
94
96
  sciveo/ml/evaluation/__init__.py
95
97
  sciveo/ml/evaluation/object_detection.py
96
98
  sciveo/ml/images/__init__.py
@@ -140,6 +142,7 @@ test/test_complexity.py
140
142
  test/test_compress.py
141
143
  test/test_configuration.py
142
144
  test/test_crypto.py
145
+ test/test_ml_datasets.py
143
146
  test/test_monitoring.py
144
147
  test/test_runner.py
145
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,46 @@
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=False)
26
+
27
+ ds1 = ObjectDetectionDataset()
28
+ ds1.from_yolo(f"{HOME_PATH}/data/test_yolo")
29
+ stats = ds1.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
+ ds2 = ObjectDetectionDataset()
35
+ ds2.from_yolo(f"{HOME_PATH}/data/job-1")
36
+ stats2 = ds2.stats()
37
+ debug("stats", stats2)
38
+ info("distribution", stats2["distribution"])
39
+
40
+ evaluator = EvalObjectDetectionDataset(ds1, ds2)
41
+ scores = evaluator.evaluate()
42
+ debug("eval", scores)
43
+
44
+
45
+ if __name__ == '__main__':
46
+ unittest.main()
@@ -1,2 +0,0 @@
1
-
2
- __version__ = '0.1.45'
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