simba-uw-tf-dev 4.5.8__py3-none-any.whl → 4.7.1__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.
- simba/SimBA.py +2 -2
- simba/assets/.recent_projects.txt +1 -0
- simba/assets/icons/frames_2.png +0 -0
- simba/assets/lookups/tooptips.json +15 -1
- simba/data_processors/agg_clf_counter_mp.py +52 -53
- simba/data_processors/blob_location_computer.py +1 -1
- simba/data_processors/circling_detector.py +30 -13
- simba/data_processors/cuda/geometry.py +45 -27
- simba/data_processors/cuda/image.py +1648 -1598
- simba/data_processors/cuda/statistics.py +72 -26
- simba/data_processors/cuda/timeseries.py +1 -1
- simba/data_processors/cue_light_analyzer.py +5 -9
- simba/data_processors/egocentric_aligner.py +25 -7
- simba/data_processors/freezing_detector.py +55 -47
- simba/data_processors/kleinberg_calculator.py +61 -29
- simba/feature_extractors/feature_subsets.py +14 -7
- simba/feature_extractors/mitra_feature_extractor.py +2 -2
- simba/feature_extractors/straub_tail_analyzer.py +4 -6
- simba/labelling/standard_labeller.py +1 -1
- simba/mixins/config_reader.py +5 -2
- simba/mixins/geometry_mixin.py +22 -36
- simba/mixins/image_mixin.py +24 -28
- simba/mixins/plotting_mixin.py +28 -10
- simba/mixins/statistics_mixin.py +48 -11
- simba/mixins/timeseries_features_mixin.py +1 -1
- simba/mixins/train_model_mixin.py +67 -29
- simba/model/inference_batch.py +1 -1
- simba/model/yolo_seg_inference.py +3 -3
- simba/outlier_tools/skip_outlier_correction.py +1 -1
- simba/plotting/ROI_feature_visualizer_mp.py +3 -5
- simba/plotting/clf_validator_mp.py +4 -5
- simba/plotting/cue_light_visualizer.py +6 -7
- simba/plotting/directing_animals_visualizer_mp.py +2 -3
- simba/plotting/distance_plotter_mp.py +378 -378
- simba/plotting/frame_mergerer_ffmpeg.py +137 -196
- simba/plotting/gantt_creator.py +29 -10
- simba/plotting/gantt_creator_mp.py +96 -33
- simba/plotting/geometry_plotter.py +270 -272
- simba/plotting/heat_mapper_clf_mp.py +4 -6
- simba/plotting/heat_mapper_location_mp.py +2 -2
- simba/plotting/light_dark_box_plotter.py +2 -2
- simba/plotting/path_plotter_mp.py +26 -29
- simba/plotting/plot_clf_results_mp.py +455 -454
- simba/plotting/pose_plotter_mp.py +28 -29
- simba/plotting/probability_plot_creator_mp.py +288 -288
- simba/plotting/roi_plotter_mp.py +31 -31
- simba/plotting/single_run_model_validation_video_mp.py +427 -427
- simba/plotting/spontaneous_alternation_plotter.py +2 -3
- simba/plotting/yolo_pose_track_visualizer.py +32 -27
- simba/plotting/yolo_pose_visualizer.py +35 -36
- simba/plotting/yolo_seg_visualizer.py +2 -3
- simba/pose_importers/simba_blob_importer.py +3 -3
- simba/roi_tools/roi_aggregate_stats_mp.py +5 -4
- simba/roi_tools/roi_clf_calculator_mp.py +4 -4
- simba/sandbox/analyze_runtimes.py +30 -0
- simba/sandbox/cuda/egocentric_rotator.py +374 -0
- simba/sandbox/get_cpu_pool.py +5 -0
- simba/sandbox/proboscis_to_tip.py +28 -0
- simba/sandbox/test_directionality.py +47 -0
- simba/sandbox/test_nonstatic_directionality.py +27 -0
- simba/sandbox/test_pycharm_cuda.py +51 -0
- simba/sandbox/test_simba_install.py +41 -0
- simba/sandbox/test_static_directionality.py +26 -0
- simba/sandbox/test_static_directionality_2d.py +26 -0
- simba/sandbox/verify_env.py +42 -0
- simba/third_party_label_appenders/transform/coco_keypoints_to_yolo.py +3 -3
- simba/third_party_label_appenders/transform/coco_keypoints_to_yolo_bbox.py +2 -2
- simba/ui/pop_ups/clf_add_remove_print_pop_up.py +37 -30
- simba/ui/pop_ups/clf_plot_pop_up.py +2 -2
- simba/ui/pop_ups/egocentric_alignment_pop_up.py +20 -21
- simba/ui/pop_ups/fsttc_pop_up.py +27 -25
- simba/ui/pop_ups/gantt_pop_up.py +31 -6
- simba/ui/pop_ups/interpolate_pop_up.py +2 -4
- simba/ui/pop_ups/kleinberg_pop_up.py +39 -40
- simba/ui/pop_ups/multiple_videos_to_frames_popup.py +10 -11
- simba/ui/pop_ups/single_video_to_frames_popup.py +10 -10
- simba/ui/pop_ups/video_processing_pop_up.py +186 -174
- simba/ui/tkinter_functions.py +10 -1
- simba/utils/custom_feature_extractor.py +1 -1
- simba/utils/data.py +90 -14
- simba/utils/enums.py +1 -0
- simba/utils/errors.py +441 -440
- simba/utils/lookups.py +1203 -1203
- simba/utils/printing.py +124 -124
- simba/utils/read_write.py +3769 -3721
- simba/utils/yolo.py +10 -1
- simba/video_processors/blob_tracking_executor.py +2 -2
- simba/video_processors/clahe_ui.py +66 -23
- simba/video_processors/egocentric_video_rotator.py +46 -44
- simba/video_processors/multi_cropper.py +1 -1
- simba/video_processors/video_processing.py +5264 -5300
- simba/video_processors/videos_to_frames.py +43 -32
- {simba_uw_tf_dev-4.5.8.dist-info → simba_uw_tf_dev-4.7.1.dist-info}/METADATA +4 -3
- {simba_uw_tf_dev-4.5.8.dist-info → simba_uw_tf_dev-4.7.1.dist-info}/RECORD +98 -86
- {simba_uw_tf_dev-4.5.8.dist-info → simba_uw_tf_dev-4.7.1.dist-info}/LICENSE +0 -0
- {simba_uw_tf_dev-4.5.8.dist-info → simba_uw_tf_dev-4.7.1.dist-info}/WHEEL +0 -0
- {simba_uw_tf_dev-4.5.8.dist-info → simba_uw_tf_dev-4.7.1.dist-info}/entry_points.txt +0 -0
- {simba_uw_tf_dev-4.5.8.dist-info → simba_uw_tf_dev-4.7.1.dist-info}/top_level.txt +0 -0
|
@@ -1,196 +1,137 @@
|
|
|
1
|
-
__author__ = "Simon Nilsson; sronilsson@gmail.com"
|
|
2
|
-
|
|
3
|
-
import os
|
|
4
|
-
import shutil
|
|
5
|
-
from datetime import datetime
|
|
6
|
-
from typing import List, Optional, Union
|
|
7
|
-
|
|
8
|
-
try:
|
|
9
|
-
from typing import Literal
|
|
10
|
-
except ImportError:
|
|
11
|
-
from typing_extensions import Literal
|
|
12
|
-
|
|
13
|
-
from simba.mixins.config_reader import ConfigReader
|
|
14
|
-
from simba.utils.checks import (check_ffmpeg_available,
|
|
15
|
-
check_file_exist_and_readable, check_int,
|
|
16
|
-
check_nvidea_gpu_available, check_str,
|
|
17
|
-
check_valid_lst)
|
|
18
|
-
from simba.utils.enums import Paths, TagNames
|
|
19
|
-
from simba.utils.errors import FFMPEGCodecGPUError
|
|
20
|
-
from simba.utils.printing import SimbaTimer, log_event, stdout_success
|
|
21
|
-
from simba.utils.read_write import copy_files_to_directory, get_fn_ext
|
|
22
|
-
from simba.video_processors.video_processing import (
|
|
23
|
-
horizontal_video_concatenator, mixed_mosaic_concatenator,
|
|
24
|
-
mosaic_concatenator, vertical_video_concatenator)
|
|
25
|
-
|
|
26
|
-
HORIZONTAL = "horizontal"
|
|
27
|
-
VERTICAL = "vertical"
|
|
28
|
-
MOSAIC = "mosaic"
|
|
29
|
-
MIXED_MOSAIC = "mixed_mosaic"
|
|
30
|
-
ACCEPTED_TYPES = [HORIZONTAL, VERTICAL, MOSAIC, MIXED_MOSAIC]
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
class FrameMergererFFmpeg(ConfigReader):
|
|
34
|
-
"""
|
|
35
|
-
Merge separate visualizations of classifications, descriptive statistics etc., into single video mosaic.
|
|
36
|
-
|
|
37
|
-
.. note::
|
|
38
|
-
`GitHub tutorial <https://github.com/sgoldenlab/simba/blob/master/docs/tutorial.md#step-12-merge-frames>`_.
|
|
39
|
-
|
|
40
|
-
.. image:: _static/img/mosaic_videos.gif
|
|
41
|
-
:width: 600
|
|
42
|
-
:align: center
|
|
43
|
-
|
|
44
|
-
:parameter str config_path: Optional path to SimBA project config file in Configparser format.
|
|
45
|
-
:parameter Literal["horizontal", "vertical", "mosaic", "mixed_mosaic"] concat_type: Type of concatenation. OPTIONS: 'horizontal', 'vertical', 'mosaic', 'mixed_mosaic'.
|
|
46
|
-
:parameter List[Union[str, os.PathLike]] video_paths: List with videos to concatenate.
|
|
47
|
-
:
|
|
48
|
-
:parameter int
|
|
49
|
-
:parameter
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
>>>
|
|
54
|
-
>>> merger.
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
if gpu and not check_nvidea_gpu_available():
|
|
68
|
-
raise FFMPEGCodecGPUError(
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
)
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
width_px=self.video_width,
|
|
139
|
-
gpu=self.gpu,
|
|
140
|
-
verbose=True,
|
|
141
|
-
)
|
|
142
|
-
elif self.concat_type == MOSAIC:
|
|
143
|
-
_ = mosaic_concatenator(
|
|
144
|
-
video_paths=self.video_paths,
|
|
145
|
-
save_path=self.output_path,
|
|
146
|
-
width_px=self.video_width,
|
|
147
|
-
height_px=self.video_height,
|
|
148
|
-
gpu=self.gpu,
|
|
149
|
-
verbose=True,
|
|
150
|
-
)
|
|
151
|
-
else:
|
|
152
|
-
_ = mixed_mosaic_concatenator(
|
|
153
|
-
video_paths=self.video_paths,
|
|
154
|
-
save_path=self.output_path,
|
|
155
|
-
gpu=self.gpu,
|
|
156
|
-
verbose=True,
|
|
157
|
-
)
|
|
158
|
-
self.timer.stop_timer()
|
|
159
|
-
stdout_success(
|
|
160
|
-
msg=f"Merged video saved at {self.output_path}",
|
|
161
|
-
source=self.__class__.__name__,
|
|
162
|
-
elapsed_time=self.timer.elapsed_time_str,
|
|
163
|
-
)
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
# videos = ['/Users/simon/Desktop/envs/simba/troubleshooting/mouse_open_field/project_folder/videos/SI_DAY3_308_CD1_PRESENT_downsampled.mp4', '/Users/simon/Desktop/envs/simba/troubleshooting/mouse_open_field/project_folder/videos/SI_DAY3_308_CD1_PRESENT_downsampled.mp4']
|
|
167
|
-
#
|
|
168
|
-
# merger = FrameMergererFFmpeg(config_path='/Users/simon/Desktop/envs/simba/troubleshooting/two_black_animals_14bp/project_folder/project_config.ini',
|
|
169
|
-
# video_paths=videos,
|
|
170
|
-
# video_height=600,
|
|
171
|
-
# video_width=600,
|
|
172
|
-
# concat_type='vertical') #horizontal, vertical, mosaic, mixed_mosaic
|
|
173
|
-
# merger.run()
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
#
|
|
177
|
-
# FrameMergererFFmpeg(config_path=None,
|
|
178
|
-
# frame_types={'Video 1': '/Users/simon/Desktop/envs/troubleshooting/two_black_animals_14bp/project_folder/videos/Together_1.avi',
|
|
179
|
-
# 'Video 2': '/Users/simon/Desktop/envs/troubleshooting/two_black_animals_14bp/project_folder/videos/Together_1.avi'},
|
|
180
|
-
# video_height=640,
|
|
181
|
-
# video_width=480,
|
|
182
|
-
# concat_type='vertical') #horizontal, vertical, mosaic, mixed_mosaic
|
|
183
|
-
#
|
|
184
|
-
#
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
# FrameMergererFFmpeg(config_path=None,
|
|
188
|
-
# frame_types={'Video 1': r'C:\Users\Nape_Computer_2\Desktop\test_videos\Box1_PM2_day_5_20211104T171021.mp4',
|
|
189
|
-
# 'Video 2': r'C:\Users\Nape_Computer_2\Desktop\test_videos\Box1_PM2_day_5_20211104T171021.mp4',
|
|
190
|
-
# 'Video 3': r'C:\Users\Nape_Computer_2\Desktop\test_videos\Box1_PM2_day_5_20211104T171021.mp4',
|
|
191
|
-
# 'Video 4': r'C:\Users\Nape_Computer_2\Desktop\test_videos\Box1_PM2_day_5_20211104T171021.mp4'},
|
|
192
|
-
# video_height=640,
|
|
193
|
-
# video_width=480,
|
|
194
|
-
# concat_type='mixed_mosaic',
|
|
195
|
-
# gpu=False) #horizontal, vertical, mosaic, mixed_mosaic
|
|
196
|
-
#
|
|
1
|
+
__author__ = "Simon Nilsson; sronilsson@gmail.com"
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
import shutil
|
|
5
|
+
from datetime import datetime
|
|
6
|
+
from typing import List, Optional, Union
|
|
7
|
+
|
|
8
|
+
try:
|
|
9
|
+
from typing import Literal
|
|
10
|
+
except ImportError:
|
|
11
|
+
from typing_extensions import Literal
|
|
12
|
+
|
|
13
|
+
from simba.mixins.config_reader import ConfigReader
|
|
14
|
+
from simba.utils.checks import (check_ffmpeg_available,
|
|
15
|
+
check_file_exist_and_readable, check_int,
|
|
16
|
+
check_nvidea_gpu_available, check_str,
|
|
17
|
+
check_valid_boolean, check_valid_lst)
|
|
18
|
+
from simba.utils.enums import Paths, TagNames
|
|
19
|
+
from simba.utils.errors import FFMPEGCodecGPUError
|
|
20
|
+
from simba.utils.printing import SimbaTimer, log_event, stdout_success
|
|
21
|
+
from simba.utils.read_write import copy_files_to_directory, get_fn_ext
|
|
22
|
+
from simba.video_processors.video_processing import (
|
|
23
|
+
horizontal_video_concatenator, mixed_mosaic_concatenator,
|
|
24
|
+
mosaic_concatenator, vertical_video_concatenator)
|
|
25
|
+
|
|
26
|
+
HORIZONTAL = "horizontal"
|
|
27
|
+
VERTICAL = "vertical"
|
|
28
|
+
MOSAIC = "mosaic"
|
|
29
|
+
MIXED_MOSAIC = "mixed_mosaic"
|
|
30
|
+
ACCEPTED_TYPES = [HORIZONTAL, VERTICAL, MOSAIC, MIXED_MOSAIC]
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class FrameMergererFFmpeg(ConfigReader):
|
|
34
|
+
"""
|
|
35
|
+
Merge separate visualizations of classifications, descriptive statistics etc., into single video mosaic.
|
|
36
|
+
|
|
37
|
+
.. note::
|
|
38
|
+
`GitHub tutorial <https://github.com/sgoldenlab/simba/blob/master/docs/tutorial.md#step-12-merge-frames>`_.
|
|
39
|
+
|
|
40
|
+
.. image:: _static/img/mosaic_videos.gif
|
|
41
|
+
:width: 600
|
|
42
|
+
:align: center
|
|
43
|
+
|
|
44
|
+
:parameter str config_path: Optional path to SimBA project config file in Configparser format.
|
|
45
|
+
:parameter Literal["horizontal", "vertical", "mosaic", "mixed_mosaic"] concat_type: Type of concatenation. OPTIONS: 'horizontal', 'vertical', 'mosaic', 'mixed_mosaic'.
|
|
46
|
+
:parameter List[Union[str, os.PathLike]] video_paths: List with videos to concatenate.
|
|
47
|
+
:param int quality: Video quality (CRF value). Lower values = higher quality. Range 0-52. Default 23.
|
|
48
|
+
:parameter Optional[int] video_height: Optional height of the canatenated videos. Required if concat concat_type is not mixed_mosaic.
|
|
49
|
+
:parameter int video_width: Optional wisth of the canatenated videos. Required if concat concat_type is not mixed_mosaic.
|
|
50
|
+
:parameter Optional[bool] gpu: If True, use NVIDEA FFMpeg GPU codecs. Default False.
|
|
51
|
+
|
|
52
|
+
:example:
|
|
53
|
+
>>> video_paths = ['/Users/simon/Desktop/envs/simba/troubleshooting/mouse_open_field/project_folder/videos/SI_DAY3_308_CD1_PRESENT_downsampled.mp4', '/Users/simon/Desktop/envs/simba/troubleshooting/mouse_open_field/project_folder/videos/SI_DAY3_308_CD1_PRESENT_downsampled.mp4']
|
|
54
|
+
>>> merger = FrameMergererFFmpeg(config_path='/Users/simon/Desktop/envs/simba/troubleshooting/two_black_animals_14bp/project_folder/project_config.ini', video_paths=videos, video_height=600, video_width=600, concat_type='mosaic')
|
|
55
|
+
>>> merger.run()
|
|
56
|
+
"""
|
|
57
|
+
|
|
58
|
+
def __init__( self,
|
|
59
|
+
concat_type: Literal["horizontal", "vertical", "mosaic", "mixed_mosaic"],
|
|
60
|
+
video_paths: List[Union[str, os.PathLike]],
|
|
61
|
+
video_height: Optional[int] = None,
|
|
62
|
+
video_width: Optional[int] = None,
|
|
63
|
+
config_path: Optional[str] = None,
|
|
64
|
+
quality: int = 23,
|
|
65
|
+
gpu: bool = False):
|
|
66
|
+
|
|
67
|
+
if gpu and not check_nvidea_gpu_available():
|
|
68
|
+
raise FFMPEGCodecGPUError(msg="NVIDEA GPU not available (as evaluated by nvidea-smi returning None", source=self.__class__.__name__)
|
|
69
|
+
check_ffmpeg_available()
|
|
70
|
+
check_str(name=f"{FrameMergererFFmpeg.__name__} concat_type", value=concat_type, options=ACCEPTED_TYPES)
|
|
71
|
+
check_valid_lst(data=video_paths, source=f"{self.__class__.__name__} video_paths", valid_dtypes=(str,), min_len=2)
|
|
72
|
+
check_valid_boolean(value=gpu, source=f'{self.__class__.__name__} gpu', raise_error=True)
|
|
73
|
+
self.quality = 23 if not check_int(name='quality', value=quality, min_value=0, max_value=52, raise_error=False)[0] else int(quality)
|
|
74
|
+
for i in video_paths:
|
|
75
|
+
check_file_exist_and_readable(file_path=i)
|
|
76
|
+
if concat_type != MIXED_MOSAIC:
|
|
77
|
+
check_int(name=f"{FrameMergererFFmpeg.__name__} video_height", value=video_height, min_value=0)
|
|
78
|
+
check_int(name=f"{FrameMergererFFmpeg.__name__} video_width", value=video_height, min_value=0)
|
|
79
|
+
if config_path is not None:
|
|
80
|
+
ConfigReader.__init__(self, config_path=config_path)
|
|
81
|
+
log_event(logger_name=str(__class__.__name__), log_type=TagNames.CLASS_INIT.value, msg=self.create_log_msg_from_init_args(locals=locals()))
|
|
82
|
+
self.output_dir = os.path.join(self.project_path, Paths.CONCAT_VIDEOS_DIR.value)
|
|
83
|
+
self.output_path = os.path.join(self.project_path, Paths.CONCAT_VIDEOS_DIR.value, f"merged_video_{self.datetime}.mp4")
|
|
84
|
+
else:
|
|
85
|
+
self.timer = SimbaTimer(start=True)
|
|
86
|
+
self.datetime = datetime.now().strftime("%Y%m%d%H%M%S")
|
|
87
|
+
self.output_dir, _, _ = get_fn_ext(filepath=video_paths[0])
|
|
88
|
+
self.output_path = os.path.join(self.output_dir, f"merged_video_{self.datetime}.mp4")
|
|
89
|
+
|
|
90
|
+
self.video_height, self.video_width, self.gpu = video_height, video_width, gpu
|
|
91
|
+
self.video_paths, self.concat_type = video_paths, concat_type
|
|
92
|
+
if not os.path.exists(self.output_dir): os.makedirs(self.output_dir)
|
|
93
|
+
|
|
94
|
+
def run(self):
|
|
95
|
+
if self.concat_type == HORIZONTAL:
|
|
96
|
+
_ = horizontal_video_concatenator(video_paths=self.video_paths, save_path=self.output_path, height_px=self.video_height, gpu=self.gpu, quality=self.quality, verbose=True)
|
|
97
|
+
elif self.concat_type == VERTICAL:
|
|
98
|
+
_ = vertical_video_concatenator(video_paths=self.video_paths, save_path=self.output_path, width_px=self.video_width, gpu=self.gpu, quality=self.quality, verbose=True)
|
|
99
|
+
elif self.concat_type == MOSAIC:
|
|
100
|
+
_ = mosaic_concatenator(video_paths=self.video_paths, save_path=self.output_path, width_px=self.video_width, height_px=self.video_height, gpu=self.gpu, quality=self.quality, verbose=True)
|
|
101
|
+
else:
|
|
102
|
+
_ = mixed_mosaic_concatenator(video_paths=self.video_paths, save_path=self.output_path, gpu=self.gpu, verbose=True)
|
|
103
|
+
self.timer.stop_timer()
|
|
104
|
+
stdout_success(msg=f"Merged video saved at {self.output_path}", source=self.__class__.__name__, elapsed_time=self.timer.elapsed_time_str)
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
# videos = ['/Users/simon/Desktop/envs/simba/troubleshooting/mouse_open_field/project_folder/videos/SI_DAY3_308_CD1_PRESENT_downsampled.mp4', '/Users/simon/Desktop/envs/simba/troubleshooting/mouse_open_field/project_folder/videos/SI_DAY3_308_CD1_PRESENT_downsampled.mp4']
|
|
108
|
+
#
|
|
109
|
+
# merger = FrameMergererFFmpeg(config_path='/Users/simon/Desktop/envs/simba/troubleshooting/two_black_animals_14bp/project_folder/project_config.ini',
|
|
110
|
+
# video_paths=videos,
|
|
111
|
+
# video_height=600,
|
|
112
|
+
# video_width=600,
|
|
113
|
+
# concat_type='vertical') #horizontal, vertical, mosaic, mixed_mosaic
|
|
114
|
+
# merger.run()
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
#
|
|
118
|
+
# FrameMergererFFmpeg(config_path=None,
|
|
119
|
+
# frame_types={'Video 1': '/Users/simon/Desktop/envs/troubleshooting/two_black_animals_14bp/project_folder/videos/Together_1.avi',
|
|
120
|
+
# 'Video 2': '/Users/simon/Desktop/envs/troubleshooting/two_black_animals_14bp/project_folder/videos/Together_1.avi'},
|
|
121
|
+
# video_height=640,
|
|
122
|
+
# video_width=480,
|
|
123
|
+
# concat_type='vertical') #horizontal, vertical, mosaic, mixed_mosaic
|
|
124
|
+
#
|
|
125
|
+
#
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
# FrameMergererFFmpeg(config_path=None,
|
|
129
|
+
# frame_types={'Video 1': r'C:\Users\Nape_Computer_2\Desktop\test_videos\Box1_PM2_day_5_20211104T171021.mp4',
|
|
130
|
+
# 'Video 2': r'C:\Users\Nape_Computer_2\Desktop\test_videos\Box1_PM2_day_5_20211104T171021.mp4',
|
|
131
|
+
# 'Video 3': r'C:\Users\Nape_Computer_2\Desktop\test_videos\Box1_PM2_day_5_20211104T171021.mp4',
|
|
132
|
+
# 'Video 4': r'C:\Users\Nape_Computer_2\Desktop\test_videos\Box1_PM2_day_5_20211104T171021.mp4'},
|
|
133
|
+
# video_height=640,
|
|
134
|
+
# video_width=480,
|
|
135
|
+
# concat_type='mixed_mosaic',
|
|
136
|
+
# gpu=False) #horizontal, vertical, mosaic, mixed_mosaic
|
|
137
|
+
#
|
simba/plotting/gantt_creator.py
CHANGED
|
@@ -2,6 +2,7 @@ __author__ = "Simon Nilsson; sronilsson@gmail.com"
|
|
|
2
2
|
|
|
3
3
|
import os
|
|
4
4
|
import shutil
|
|
5
|
+
from copy import deepcopy
|
|
5
6
|
from typing import List, Optional, Union
|
|
6
7
|
|
|
7
8
|
import cv2
|
|
@@ -16,7 +17,7 @@ from simba.utils.checks import (
|
|
|
16
17
|
from simba.utils.data import create_color_palette, detect_bouts
|
|
17
18
|
from simba.utils.enums import Formats, Options
|
|
18
19
|
from simba.utils.errors import NoSpecifiedOutputError
|
|
19
|
-
from simba.utils.lookups import get_named_colors
|
|
20
|
+
from simba.utils.lookups import get_fonts, get_named_colors
|
|
20
21
|
from simba.utils.printing import stdout_success
|
|
21
22
|
from simba.utils.read_write import get_fn_ext, read_df
|
|
22
23
|
|
|
@@ -60,16 +61,18 @@ class GanttCreatorSingleProcess(ConfigReader, PlottingMixin):
|
|
|
60
61
|
|
|
61
62
|
def __init__(self,
|
|
62
63
|
config_path: Union[str, os.PathLike],
|
|
63
|
-
data_paths: List[Union[str, os.PathLike]],
|
|
64
|
+
data_paths: Optional[Union[Union[str, os.PathLike], List[Union[str, os.PathLike]]]] = None,
|
|
64
65
|
width: int = 640,
|
|
65
66
|
height: int = 480,
|
|
66
67
|
font_size: int = 8,
|
|
67
68
|
font_rotation: int = 45,
|
|
69
|
+
font: Optional[str] = None,
|
|
68
70
|
palette: str = 'Set1',
|
|
69
|
-
frame_setting:
|
|
70
|
-
video_setting:
|
|
71
|
-
last_frm_setting:
|
|
72
|
-
hhmmss:
|
|
71
|
+
frame_setting: bool = False,
|
|
72
|
+
video_setting: bool = False,
|
|
73
|
+
last_frm_setting: bool = True,
|
|
74
|
+
hhmmss: bool = True,
|
|
75
|
+
clf_names: Optional[List[str]] = None):
|
|
73
76
|
|
|
74
77
|
if ((frame_setting != True) and (video_setting != True) and (last_frm_setting != True)):
|
|
75
78
|
raise NoSpecifiedOutputError(msg="SIMBA ERROR: Please select gantt videos, frames, and/or last frame.")
|
|
@@ -78,7 +81,13 @@ class GanttCreatorSingleProcess(ConfigReader, PlottingMixin):
|
|
|
78
81
|
check_int(value=height, min_value=1, name=f'{self.__class__.__name__} height')
|
|
79
82
|
check_int(value=font_size, min_value=1, name=f'{self.__class__.__name__} font_size')
|
|
80
83
|
check_int(value=font_rotation, min_value=0, max_value=180, name=f'{self.__class__.__name__} font_rotation')
|
|
81
|
-
|
|
84
|
+
if isinstance(data_paths, list):
|
|
85
|
+
check_valid_lst(data=data_paths, source=f'{self.__class__.__name__} data_paths', valid_dtypes=(str,), min_len=1)
|
|
86
|
+
elif isinstance(data_paths, str):
|
|
87
|
+
check_file_exist_and_readable(file_path=data_paths)
|
|
88
|
+
data_paths = [data_paths]
|
|
89
|
+
else:
|
|
90
|
+
data_paths = deepcopy(self.machine_results_paths)
|
|
82
91
|
check_valid_boolean(value=hhmmss, source=f'{self.__class__.__name__} hhmmss', raise_error=False)
|
|
83
92
|
palettes = Options.PALETTE_OPTIONS_CATEGORICAL.value + Options.PALETTE_OPTIONS.value
|
|
84
93
|
check_str(name=f'{self.__class__.__name__} palette', value=palette, options=palettes)
|
|
@@ -90,7 +99,12 @@ class GanttCreatorSingleProcess(ConfigReader, PlottingMixin):
|
|
|
90
99
|
if not os.path.exists(self.gantt_plot_dir): os.makedirs(self.gantt_plot_dir)
|
|
91
100
|
self.frame_setting, self.video_setting, self.last_frm_setting = frame_setting, video_setting, last_frm_setting
|
|
92
101
|
self.width, self.height, self.font_size, self.font_rotation = width, height, font_size, font_rotation
|
|
93
|
-
|
|
102
|
+
if font is not None:
|
|
103
|
+
check_str(name=f'{self.__class__.__name__} font', value=font, options=list(get_fonts().keys()), raise_error=True)
|
|
104
|
+
if clf_names is not None:
|
|
105
|
+
check_valid_lst(data=clf_names, source=f'{self.__class__.__name__} clf_names', valid_dtypes=(str,), valid_values=self.clf_names, min_len=1, raise_error=True)
|
|
106
|
+
self.clf_names = clf_names
|
|
107
|
+
self.data_paths, self.hhmmss, self.font = data_paths, hhmmss, font
|
|
94
108
|
self.colours = get_named_colors()
|
|
95
109
|
self.colour_tuple_x = list(np.arange(3.5, 203.5, 5))
|
|
96
110
|
|
|
@@ -121,6 +135,7 @@ class GanttCreatorSingleProcess(ConfigReader, PlottingMixin):
|
|
|
121
135
|
font_size=self.font_size,
|
|
122
136
|
font_rotation=self.font_rotation,
|
|
123
137
|
video_name=self.video_name,
|
|
138
|
+
font=self.font,
|
|
124
139
|
save_path=os.path.join(self.gantt_plot_dir, f"{self.video_name }_final_image.png"),
|
|
125
140
|
palette=self.clr_lst,
|
|
126
141
|
hhmmss=self.hhmmss)
|
|
@@ -135,6 +150,7 @@ class GanttCreatorSingleProcess(ConfigReader, PlottingMixin):
|
|
|
135
150
|
width=self.width,
|
|
136
151
|
height=self.height,
|
|
137
152
|
font_size=self.font_size,
|
|
153
|
+
font=self.font,
|
|
138
154
|
font_rotation=self.font_rotation,
|
|
139
155
|
video_name=self.video_name,
|
|
140
156
|
palette=self.clr_lst,
|
|
@@ -156,13 +172,16 @@ class GanttCreatorSingleProcess(ConfigReader, PlottingMixin):
|
|
|
156
172
|
# test = GanttCreatorSingleProcess(config_path=r"C:\troubleshooting\mitra\project_folder\project_config.ini",
|
|
157
173
|
# frame_setting=False,
|
|
158
174
|
# video_setting=False,
|
|
159
|
-
# data_paths=[r"C:\troubleshooting\mitra\project_folder\csv\machine_results\
|
|
175
|
+
# data_paths=[r"C:\troubleshooting\mitra\project_folder\csv\machine_results\501_MA142_Gi_CNO_0516.csv"],
|
|
160
176
|
# last_frm_setting=True,
|
|
161
177
|
# width=640,
|
|
162
178
|
# height= 480,
|
|
163
179
|
# font_size=10,
|
|
180
|
+
# font=None,
|
|
164
181
|
# font_rotation=45,
|
|
165
|
-
#
|
|
182
|
+
# hhmmss=False,
|
|
183
|
+
# palette='Set1',
|
|
184
|
+
# clf_names=['straub_tail'])
|
|
166
185
|
# test.run()
|
|
167
186
|
|
|
168
187
|
|