simba-uw-tf-dev 4.6.6__py3-none-any.whl → 4.6.7__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/data_processors/blob_location_computer.py +1 -1
- simba/data_processors/cuda/image.py +12 -8
- simba/data_processors/cuda/statistics.py +57 -18
- simba/data_processors/cuda/timeseries.py +1 -1
- simba/data_processors/egocentric_aligner.py +1 -1
- simba/feature_extractors/feature_subsets.py +2 -2
- simba/feature_extractors/straub_tail_analyzer.py +4 -4
- simba/labelling/standard_labeller.py +1 -1
- simba/mixins/geometry_mixin.py +8 -8
- simba/mixins/image_mixin.py +14 -14
- simba/mixins/statistics_mixin.py +39 -9
- simba/mixins/timeseries_features_mixin.py +1 -1
- simba/mixins/train_model_mixin.py +65 -27
- simba/model/inference_batch.py +1 -1
- simba/model/yolo_seg_inference.py +3 -3
- simba/plotting/heat_mapper_clf_mp.py +2 -2
- simba/pose_importers/simba_blob_importer.py +3 -3
- simba/roi_tools/roi_aggregate_stats_mp.py +1 -1
- simba/roi_tools/roi_clf_calculator_mp.py +1 -1
- simba/sandbox/analyze_runtimes.py +30 -30
- simba/sandbox/test_directionality.py +47 -47
- simba/sandbox/test_nonstatic_directionality.py +27 -27
- simba/sandbox/test_pycharm_cuda.py +51 -51
- simba/sandbox/test_simba_install.py +41 -41
- simba/sandbox/test_static_directionality.py +26 -26
- simba/sandbox/test_static_directionality_2d.py +26 -26
- simba/sandbox/verify_env.py +42 -42
- 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/utils/custom_feature_extractor.py +1 -1
- simba/utils/data.py +2 -2
- simba/utils/read_write.py +32 -18
- simba/utils/yolo.py +10 -1
- simba/video_processors/blob_tracking_executor.py +2 -2
- simba/video_processors/clahe_ui.py +1 -1
- simba/video_processors/egocentric_video_rotator.py +3 -3
- simba/video_processors/multi_cropper.py +1 -1
- simba/video_processors/video_processing.py +26 -9
- simba/video_processors/videos_to_frames.py +2 -2
- {simba_uw_tf_dev-4.6.6.dist-info → simba_uw_tf_dev-4.6.7.dist-info}/METADATA +3 -2
- {simba_uw_tf_dev-4.6.6.dist-info → simba_uw_tf_dev-4.6.7.dist-info}/RECORD +45 -45
- {simba_uw_tf_dev-4.6.6.dist-info → simba_uw_tf_dev-4.6.7.dist-info}/LICENSE +0 -0
- {simba_uw_tf_dev-4.6.6.dist-info → simba_uw_tf_dev-4.6.7.dist-info}/WHEEL +0 -0
- {simba_uw_tf_dev-4.6.6.dist-info → simba_uw_tf_dev-4.6.7.dist-info}/entry_points.txt +0 -0
- {simba_uw_tf_dev-4.6.6.dist-info → simba_uw_tf_dev-4.6.7.dist-info}/top_level.txt +0 -0
|
@@ -1,41 +1,41 @@
|
|
|
1
|
-
"""Test SimBA installation in conda environment"""
|
|
2
|
-
import sys
|
|
3
|
-
print(f"Python: {sys.executable}")
|
|
4
|
-
|
|
5
|
-
try:
|
|
6
|
-
import simba
|
|
7
|
-
print("✓ SimBA imported successfully!")
|
|
8
|
-
except Exception as e:
|
|
9
|
-
print(f"✗ Error importing SimBA: {e}")
|
|
10
|
-
import traceback
|
|
11
|
-
traceback.print_exc()
|
|
12
|
-
sys.exit(1)
|
|
13
|
-
|
|
14
|
-
try:
|
|
15
|
-
from simba.data_processors.cuda.geometry import is_inside_rectangle
|
|
16
|
-
print("✓ CUDA geometry functions imported!")
|
|
17
|
-
except Exception as e:
|
|
18
|
-
print(f"✗ Error importing CUDA functions: {e}")
|
|
19
|
-
import traceback
|
|
20
|
-
traceback.print_exc()
|
|
21
|
-
sys.exit(1)
|
|
22
|
-
|
|
23
|
-
try:
|
|
24
|
-
import cupy as cp
|
|
25
|
-
import numpy as np
|
|
26
|
-
print(f"✓ CuPy {cp.__version__} available")
|
|
27
|
-
|
|
28
|
-
# Quick test
|
|
29
|
-
test_points = np.array([[150, 150], [300, 300], [50, 50]], dtype=np.int32)
|
|
30
|
-
test_rect = np.array([[100, 100], [400, 400]], dtype=np.int32)
|
|
31
|
-
result = is_inside_rectangle(x=test_points, y=test_rect)
|
|
32
|
-
print(f"✓ CUDA function test passed: {result}")
|
|
33
|
-
except Exception as e:
|
|
34
|
-
print(f"✗ Error testing CUDA: {e}")
|
|
35
|
-
import traceback
|
|
36
|
-
traceback.print_exc()
|
|
37
|
-
sys.exit(1)
|
|
38
|
-
|
|
39
|
-
print("\n" + "="*50)
|
|
40
|
-
print("All tests passed! SimBA is ready to use.")
|
|
41
|
-
print("="*50)
|
|
1
|
+
"""Test SimBA installation in conda environment"""
|
|
2
|
+
import sys
|
|
3
|
+
print(f"Python: {sys.executable}")
|
|
4
|
+
|
|
5
|
+
try:
|
|
6
|
+
import simba
|
|
7
|
+
print("✓ SimBA imported successfully!")
|
|
8
|
+
except Exception as e:
|
|
9
|
+
print(f"✗ Error importing SimBA: {e}")
|
|
10
|
+
import traceback
|
|
11
|
+
traceback.print_exc()
|
|
12
|
+
sys.exit(1)
|
|
13
|
+
|
|
14
|
+
try:
|
|
15
|
+
from simba.data_processors.cuda.geometry import is_inside_rectangle
|
|
16
|
+
print("✓ CUDA geometry functions imported!")
|
|
17
|
+
except Exception as e:
|
|
18
|
+
print(f"✗ Error importing CUDA functions: {e}")
|
|
19
|
+
import traceback
|
|
20
|
+
traceback.print_exc()
|
|
21
|
+
sys.exit(1)
|
|
22
|
+
|
|
23
|
+
try:
|
|
24
|
+
import cupy as cp
|
|
25
|
+
import numpy as np
|
|
26
|
+
print(f"✓ CuPy {cp.__version__} available")
|
|
27
|
+
|
|
28
|
+
# Quick test
|
|
29
|
+
test_points = np.array([[150, 150], [300, 300], [50, 50]], dtype=np.int32)
|
|
30
|
+
test_rect = np.array([[100, 100], [400, 400]], dtype=np.int32)
|
|
31
|
+
result = is_inside_rectangle(x=test_points, y=test_rect)
|
|
32
|
+
print(f"✓ CUDA function test passed: {result}")
|
|
33
|
+
except Exception as e:
|
|
34
|
+
print(f"✗ Error testing CUDA: {e}")
|
|
35
|
+
import traceback
|
|
36
|
+
traceback.print_exc()
|
|
37
|
+
sys.exit(1)
|
|
38
|
+
|
|
39
|
+
print("\n" + "="*50)
|
|
40
|
+
print("All tests passed! SimBA is ready to use.")
|
|
41
|
+
print("="*50)
|
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
"""Test directionality_to_static_targets function"""
|
|
2
|
-
import numpy as np
|
|
3
|
-
from simba.data_processors.cuda.geometry import directionality_to_static_targets
|
|
4
|
-
|
|
5
|
-
print("Testing directionality_to_static_targets...")
|
|
6
|
-
|
|
7
|
-
left_ear = np.random.randint(0, 500, (10, 2)).astype(np.int32)
|
|
8
|
-
right_ear = np.random.randint(0, 500, (10, 2)).astype(np.int32)
|
|
9
|
-
nose = np.random.randint(0, 500, (10, 2)).astype(np.int32)
|
|
10
|
-
target = np.array([250, 250], dtype=np.int32)
|
|
11
|
-
|
|
12
|
-
print(f"target shape: {target.shape}, dtype: {target.dtype}")
|
|
13
|
-
|
|
14
|
-
try:
|
|
15
|
-
result = directionality_to_static_targets(
|
|
16
|
-
left_ear=left_ear,
|
|
17
|
-
right_ear=right_ear,
|
|
18
|
-
nose=nose,
|
|
19
|
-
target=target
|
|
20
|
-
)
|
|
21
|
-
print(f"✓ SUCCESS! Result shape: {result.shape}")
|
|
22
|
-
print(f"Result:\n{result}")
|
|
23
|
-
except Exception as e:
|
|
24
|
-
print(f"✗ Error: {e}")
|
|
25
|
-
import traceback
|
|
26
|
-
traceback.print_exc()
|
|
1
|
+
"""Test directionality_to_static_targets function"""
|
|
2
|
+
import numpy as np
|
|
3
|
+
from simba.data_processors.cuda.geometry import directionality_to_static_targets
|
|
4
|
+
|
|
5
|
+
print("Testing directionality_to_static_targets...")
|
|
6
|
+
|
|
7
|
+
left_ear = np.random.randint(0, 500, (10, 2)).astype(np.int32)
|
|
8
|
+
right_ear = np.random.randint(0, 500, (10, 2)).astype(np.int32)
|
|
9
|
+
nose = np.random.randint(0, 500, (10, 2)).astype(np.int32)
|
|
10
|
+
target = np.array([250, 250], dtype=np.int32)
|
|
11
|
+
|
|
12
|
+
print(f"target shape: {target.shape}, dtype: {target.dtype}")
|
|
13
|
+
|
|
14
|
+
try:
|
|
15
|
+
result = directionality_to_static_targets(
|
|
16
|
+
left_ear=left_ear,
|
|
17
|
+
right_ear=right_ear,
|
|
18
|
+
nose=nose,
|
|
19
|
+
target=target
|
|
20
|
+
)
|
|
21
|
+
print(f"✓ SUCCESS! Result shape: {result.shape}")
|
|
22
|
+
print(f"Result:\n{result}")
|
|
23
|
+
except Exception as e:
|
|
24
|
+
print(f"✗ Error: {e}")
|
|
25
|
+
import traceback
|
|
26
|
+
traceback.print_exc()
|
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
"""Test directionality_to_static_targets with correct 1D target"""
|
|
2
|
-
import numpy as np
|
|
3
|
-
from simba.data_processors.cuda.geometry import directionality_to_static_targets
|
|
4
|
-
|
|
5
|
-
print("Testing directionality_to_static_targets with 1D target (correct)...")
|
|
6
|
-
|
|
7
|
-
left_ear = np.random.randint(0, 500, (100, 2)).astype(np.int32)
|
|
8
|
-
right_ear = np.random.randint(0, 500, (100, 2)).astype(np.int32)
|
|
9
|
-
nose = np.random.randint(0, 500, (100, 2)).astype(np.int32)
|
|
10
|
-
target = np.array([250, 250], dtype=np.int32) # 1D array for static target
|
|
11
|
-
|
|
12
|
-
print(f"target shape: {target.shape}, dtype: {target.dtype}")
|
|
13
|
-
|
|
14
|
-
try:
|
|
15
|
-
result = directionality_to_static_targets(
|
|
16
|
-
left_ear=left_ear,
|
|
17
|
-
right_ear=right_ear,
|
|
18
|
-
nose=nose,
|
|
19
|
-
target=target
|
|
20
|
-
)
|
|
21
|
-
print(f"✓ SUCCESS! Result shape: {result.shape}")
|
|
22
|
-
print(f"First 5 results:\n{result[:5]}")
|
|
23
|
-
except Exception as e:
|
|
24
|
-
print(f"✗ Error: {e}")
|
|
25
|
-
import traceback
|
|
26
|
-
traceback.print_exc()
|
|
1
|
+
"""Test directionality_to_static_targets with correct 1D target"""
|
|
2
|
+
import numpy as np
|
|
3
|
+
from simba.data_processors.cuda.geometry import directionality_to_static_targets
|
|
4
|
+
|
|
5
|
+
print("Testing directionality_to_static_targets with 1D target (correct)...")
|
|
6
|
+
|
|
7
|
+
left_ear = np.random.randint(0, 500, (100, 2)).astype(np.int32)
|
|
8
|
+
right_ear = np.random.randint(0, 500, (100, 2)).astype(np.int32)
|
|
9
|
+
nose = np.random.randint(0, 500, (100, 2)).astype(np.int32)
|
|
10
|
+
target = np.array([250, 250], dtype=np.int32) # 1D array for static target
|
|
11
|
+
|
|
12
|
+
print(f"target shape: {target.shape}, dtype: {target.dtype}")
|
|
13
|
+
|
|
14
|
+
try:
|
|
15
|
+
result = directionality_to_static_targets(
|
|
16
|
+
left_ear=left_ear,
|
|
17
|
+
right_ear=right_ear,
|
|
18
|
+
nose=nose,
|
|
19
|
+
target=target
|
|
20
|
+
)
|
|
21
|
+
print(f"✓ SUCCESS! Result shape: {result.shape}")
|
|
22
|
+
print(f"First 5 results:\n{result[:5]}")
|
|
23
|
+
except Exception as e:
|
|
24
|
+
print(f"✗ Error: {e}")
|
|
25
|
+
import traceback
|
|
26
|
+
traceback.print_exc()
|
simba/sandbox/verify_env.py
CHANGED
|
@@ -1,42 +1,42 @@
|
|
|
1
|
-
"""Verify CUDA environment is properly configured"""
|
|
2
|
-
from numba import cuda
|
|
3
|
-
import cupy as cp
|
|
4
|
-
import numba
|
|
5
|
-
|
|
6
|
-
print("="*60)
|
|
7
|
-
print("CUDA Environment Verification")
|
|
8
|
-
print("="*60)
|
|
9
|
-
print(f"Numba version: {numba.__version__}")
|
|
10
|
-
print(f"CuPy version: {cp.__version__}")
|
|
11
|
-
print(f"CUDA available: {cuda.is_available()}")
|
|
12
|
-
if cuda.is_available():
|
|
13
|
-
print(f"CUDA devices: {len(cuda.gpus)}")
|
|
14
|
-
for i, gpu in enumerate(cuda.gpus):
|
|
15
|
-
print(f" GPU {i}: {gpu}")
|
|
16
|
-
|
|
17
|
-
# Test the function
|
|
18
|
-
print("\n" + "="*60)
|
|
19
|
-
print("Testing directionality_to_nonstatic_target...")
|
|
20
|
-
try:
|
|
21
|
-
from simba.data_processors.cuda.geometry import directionality_to_nonstatic_target
|
|
22
|
-
import numpy as np
|
|
23
|
-
|
|
24
|
-
left_ear = np.random.randint(0, 500, (10, 2)).astype(np.int32)
|
|
25
|
-
right_ear = np.random.randint(0, 500, (10, 2)).astype(np.int32)
|
|
26
|
-
nose = np.random.randint(0, 500, (10, 2)).astype(np.int32)
|
|
27
|
-
target = np.random.randint(0, 500, (10, 2)).astype(np.int32)
|
|
28
|
-
|
|
29
|
-
result = directionality_to_nonstatic_target(
|
|
30
|
-
left_ear=left_ear,
|
|
31
|
-
right_ear=right_ear,
|
|
32
|
-
nose=nose,
|
|
33
|
-
target=target
|
|
34
|
-
)
|
|
35
|
-
print(f"✓ Function works! Result shape: {result.shape}")
|
|
36
|
-
except Exception as e:
|
|
37
|
-
print(f"✗ Error: {e}")
|
|
38
|
-
import traceback
|
|
39
|
-
traceback.print_exc()
|
|
40
|
-
|
|
41
|
-
print("\n" + "="*60)
|
|
42
|
-
print("Environment is ready!")
|
|
1
|
+
"""Verify CUDA environment is properly configured"""
|
|
2
|
+
from numba import cuda
|
|
3
|
+
import cupy as cp
|
|
4
|
+
import numba
|
|
5
|
+
|
|
6
|
+
print("="*60)
|
|
7
|
+
print("CUDA Environment Verification")
|
|
8
|
+
print("="*60)
|
|
9
|
+
print(f"Numba version: {numba.__version__}")
|
|
10
|
+
print(f"CuPy version: {cp.__version__}")
|
|
11
|
+
print(f"CUDA available: {cuda.is_available()}")
|
|
12
|
+
if cuda.is_available():
|
|
13
|
+
print(f"CUDA devices: {len(cuda.gpus)}")
|
|
14
|
+
for i, gpu in enumerate(cuda.gpus):
|
|
15
|
+
print(f" GPU {i}: {gpu}")
|
|
16
|
+
|
|
17
|
+
# Test the function
|
|
18
|
+
print("\n" + "="*60)
|
|
19
|
+
print("Testing directionality_to_nonstatic_target...")
|
|
20
|
+
try:
|
|
21
|
+
from simba.data_processors.cuda.geometry import directionality_to_nonstatic_target
|
|
22
|
+
import numpy as np
|
|
23
|
+
|
|
24
|
+
left_ear = np.random.randint(0, 500, (10, 2)).astype(np.int32)
|
|
25
|
+
right_ear = np.random.randint(0, 500, (10, 2)).astype(np.int32)
|
|
26
|
+
nose = np.random.randint(0, 500, (10, 2)).astype(np.int32)
|
|
27
|
+
target = np.random.randint(0, 500, (10, 2)).astype(np.int32)
|
|
28
|
+
|
|
29
|
+
result = directionality_to_nonstatic_target(
|
|
30
|
+
left_ear=left_ear,
|
|
31
|
+
right_ear=right_ear,
|
|
32
|
+
nose=nose,
|
|
33
|
+
target=target
|
|
34
|
+
)
|
|
35
|
+
print(f"✓ Function works! Result shape: {result.shape}")
|
|
36
|
+
except Exception as e:
|
|
37
|
+
print(f"✗ Error: {e}")
|
|
38
|
+
import traceback
|
|
39
|
+
traceback.print_exc()
|
|
40
|
+
|
|
41
|
+
print("\n" + "="*60)
|
|
42
|
+
print("Environment is ready!")
|
|
@@ -54,15 +54,15 @@ class COCOKeypoints2Yolo:
|
|
|
54
54
|
:return: None
|
|
55
55
|
|
|
56
56
|
:example:
|
|
57
|
-
>>> runner = COCOKeypoints2Yolo(coco_path=r"D
|
|
57
|
+
>>> runner = COCOKeypoints2Yolo(coco_path=r"D:/cvat_annotations/frames/coco_keypoints_1/s1/annotations/s1.json", img_dir=r"D:/cvat_annotations/frames/simon", save_dir=r"D:/cvat_annotations/frames/yolo_keypoints", clahe=True)
|
|
58
58
|
>>> runner.run()
|
|
59
59
|
|
|
60
60
|
:example II:
|
|
61
|
-
>>> runner = COCOKeypoints2Yolo(coco_path=r"D
|
|
61
|
+
>>> runner = COCOKeypoints2Yolo(coco_path=r"D:/cvat_annotations/frames/coco_keypoints_1/merged.json", img_dir=r"D:/cvat_annotations/frames", save_dir=r"D:/cvat_annotations/frames/yolo", clahe=False)
|
|
62
62
|
>>> runner.run()
|
|
63
63
|
|
|
64
64
|
:example III:
|
|
65
|
-
>>> runner = COCOKeypoints2Yolo(coco_path=r"E
|
|
65
|
+
>>> runner = COCOKeypoints2Yolo(coco_path=r"E:/netholabs_videos/mosaics/subset/to_annotate/2d_mosaic_batch_1.json", img_dir=r"E:/netholabs_videos/mosaics/subset/to_annotate", save_dir=r"E:/netholabs_videos/mosaics/yolo_mdl", clahe=False)
|
|
66
66
|
>>> runner.run()
|
|
67
67
|
|
|
68
68
|
:references:
|
|
@@ -58,11 +58,11 @@ class COCOKeypoints2YoloBbox:
|
|
|
58
58
|
:return: None
|
|
59
59
|
|
|
60
60
|
:example:
|
|
61
|
-
>>> runner =
|
|
61
|
+
>>> runner = COCOKeypoints2YoloBbox(coco_path=r"D:/cvat_annotations/frames/coco_keypoints_1/s1/annotations/s1.json", img_dir=r"D:/cvat_annotations/frames/simon", save_dir=r"D:/cvat_annotations/frames/yolo_keypoints", clahe=True)
|
|
62
62
|
>>> runner.run()
|
|
63
63
|
|
|
64
64
|
:example II:
|
|
65
|
-
>>> runner =
|
|
65
|
+
>>> runner = COCOKeypoints2YoloBbox(coco_path=r"D:/cvat_annotations/frames/coco_keypoints_1/merged.json", img_dir=r"D:/cvat_annotations/frames", save_dir=r"D:/cvat_annotations/frames/yolo", clahe=False)
|
|
66
66
|
>>> runner.run()
|
|
67
67
|
|
|
68
68
|
:references:
|
|
@@ -30,7 +30,7 @@ class CustomFeatureExtractor(ConfigReader):
|
|
|
30
30
|
4. Handle cases of multiple classes and missing configuration arguments.
|
|
31
31
|
5. Invokes the feature extraction process if conditions are met.
|
|
32
32
|
|
|
33
|
-
..
|
|
33
|
+
.. note::
|
|
34
34
|
|
|
35
35
|
`Tutorial <https://github.com/sgoldenlab/simba/blob/master/docs/extractFeatures.md>`_.
|
|
36
36
|
|
simba/utils/data.py
CHANGED
|
@@ -1785,8 +1785,8 @@ def fft_lowpass_filter(data: np.ndarray, cut_off: float = 0.1) -> np.ndarray:
|
|
|
1785
1785
|
|
|
1786
1786
|
:example:
|
|
1787
1787
|
>>> from simba.utils.read_write import read_df
|
|
1788
|
-
>>> IN_PATH = r"C
|
|
1789
|
-
>>> OUT_PATH = r"C
|
|
1788
|
+
>>> IN_PATH = r"C:/troubleshooting/RAT_NOR/project_folder/csv/outlier_corrected_movement_location/2022-06-20_NOB_DOT_4.csv"
|
|
1789
|
+
>>> OUT_PATH = r"C:/troubleshooting/RAT_NOR/project_folder/csv/outlier_corrected_movement_location/2022-06-20_NOB_DOT_4_filtered.csv"
|
|
1790
1790
|
>>> df = read_df(file_path=IN_PATH)
|
|
1791
1791
|
>>> data = df.values
|
|
1792
1792
|
>>> x = fft_lowpass_filter(data=data, cut_off=0.1)
|
simba/utils/read_write.py
CHANGED
|
@@ -97,13 +97,20 @@ def read_df(file_path: Union[str, os.PathLike],
|
|
|
97
97
|
.. note::
|
|
98
98
|
For improved runtime, defaults to :external:py:meth:`pyarrow.csv.write_cs` if file type is ``csv``.
|
|
99
99
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
100
|
+
.. csv-table::
|
|
101
|
+
:header: EXPECTED RUNTIMES
|
|
102
|
+
:file: ../../docs/tables/read_df.csv
|
|
103
|
+
:widths: 10, 45, 45
|
|
104
|
+
:align: center
|
|
105
|
+
:header-rows: 1
|
|
106
|
+
|
|
107
|
+
:param str file_path: Path to data file
|
|
108
|
+
:param str file_type: Type of data. OPTIONS: 'parquet', 'csv', 'pickle'.
|
|
109
|
+
:param Optional[bool]: If the input file has an initial index column. Default: True.
|
|
110
|
+
:param Optional[List[str]] remove_columns: If not None, then remove columns in lits.
|
|
111
|
+
:param Optional[List[str]] usecols: If not None, then keep columns in list.
|
|
112
|
+
:param bool check_multiindex: check file is multi-index headers. Default: False.
|
|
113
|
+
:param int multi_index_headers_to_keep: If reading multi-index file, and we want to keep one of the dropped multi-index levels as the header in the output file, specify the index of the multiindex hader as int.
|
|
107
114
|
:return: Table data in pd.DataFrame format.
|
|
108
115
|
:rtype: pd.DataFrame
|
|
109
116
|
|
|
@@ -207,11 +214,18 @@ def write_df(df: pd.DataFrame,
|
|
|
207
214
|
.. note::
|
|
208
215
|
For improved runtime, defaults to ``pyarrow.csv`` if file_type == ``csv``.
|
|
209
216
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
217
|
+
.. csv-table::
|
|
218
|
+
:header: EXPECTED RUNTIMES
|
|
219
|
+
:file: ../../docs/tables/write_df.csv
|
|
220
|
+
:widths: 10, 45, 45
|
|
221
|
+
:align: center
|
|
222
|
+
:header-rows: 1
|
|
223
|
+
|
|
224
|
+
:param pd.DataFrame df: Pandas dataframe to save to disk.
|
|
225
|
+
:param str file_type: Type of data. OPTIONS: ``parquet``, ``csv``, ``pickle``.
|
|
226
|
+
:param str save_path: Location where to store the data.
|
|
227
|
+
:param bool check_multiindex: check if input file is multi-index headers. Default: False.
|
|
228
|
+
:param bool verbose: Prints message on completion. Default: False.
|
|
215
229
|
|
|
216
230
|
:example:
|
|
217
231
|
>>> write_df(df=df, file_type='csv', save_path='project_folder/csv/input_csv/Video_1.csv')
|
|
@@ -1130,8 +1144,8 @@ def get_file_name_info_in_directory(directory: Union[str, os.PathLike], file_typ
|
|
|
1130
1144
|
:return dict: All found files as values and file base names as keys.
|
|
1131
1145
|
|
|
1132
1146
|
:example:
|
|
1133
|
-
>>> get_file_name_info_in_directory(directory='C
|
|
1134
|
-
>>> {'Video_1': 'C
|
|
1147
|
+
>>> get_file_name_info_in_directory(directory='C:/project_folder/csv/machine_results', file_type='csv')
|
|
1148
|
+
>>> {'Video_1': 'C:/project_folder/csv/machine_results/Video_1'}
|
|
1135
1149
|
"""
|
|
1136
1150
|
|
|
1137
1151
|
results = {}
|
|
@@ -2630,7 +2644,7 @@ def bento_file_reader(file_path: Union[str, os.PathLike],
|
|
|
2630
2644
|
:rtype: Dict[str, pd.DataFrame]
|
|
2631
2645
|
|
|
2632
2646
|
:example:
|
|
2633
|
-
>>> bento_file_reader(file_path=r"C
|
|
2647
|
+
>>> bento_file_reader(file_path=r"C:/troubleshooting/bento_test/bento_files/20240812_crumpling3.annot")
|
|
2634
2648
|
"""
|
|
2635
2649
|
|
|
2636
2650
|
def _orient_columns_melt(df: pd.DataFrame) -> pd.DataFrame:
|
|
@@ -2953,7 +2967,7 @@ def labelme_to_dlc(labelme_dir: Union[str, os.PathLike],
|
|
|
2953
2967
|
:return: None
|
|
2954
2968
|
|
|
2955
2969
|
:example:
|
|
2956
|
-
>>> labelme_dir = r'D
|
|
2970
|
+
>>> labelme_dir = r'D:/ts_annotations'
|
|
2957
2971
|
>>> labelme_to_dlc(labelme_dir=labelme_dir)
|
|
2958
2972
|
"""
|
|
2959
2973
|
|
|
@@ -3597,8 +3611,8 @@ def osf_download(project_id: str, save_dir: Union[str, os.PathLike], storage: st
|
|
|
3597
3611
|
:param bool overwrite: If True, overwrite existing files. If False, skip existing files (default: False).
|
|
3598
3612
|
|
|
3599
3613
|
:example:
|
|
3600
|
-
>>> osf_download(project_id="7fgwn", save_dir=r'E
|
|
3601
|
-
>>> osf_download(project_id="kym42", save_dir=r'E
|
|
3614
|
+
>>> osf_download(project_id="7fgwn", save_dir=r'E:/rgb_white_vs_black_imgs')
|
|
3615
|
+
>>> osf_download(project_id="kym42", save_dir=r'E:/crim13_imgs', overwrite=True)
|
|
3602
3616
|
"""
|
|
3603
3617
|
|
|
3604
3618
|
_ = get_pkg_version(pkg='osfclient', raise_error=True)
|
simba/utils/yolo.py
CHANGED
|
@@ -47,6 +47,9 @@ def fit_yolo(weights_path: Union[str, os.PathLike],
|
|
|
47
47
|
`Download initial weights <https://huggingface.co/Ultralytics>`__.
|
|
48
48
|
`Example model_yaml <https://github.com/sgoldenlab/simba/blob/master/misc/ex_yolo_model.yaml>`__.
|
|
49
49
|
|
|
50
|
+
.. seealso::
|
|
51
|
+
For the recommended wrapper class with parameter validation, see :class:`simba.model.yolo_fit.FitYolo`.
|
|
52
|
+
|
|
50
53
|
:param initial_weights: Path to the pre-trained YOLO model weights (usually a `.pt` file). Example weights can be found [here](https://huggingface.co/Ultralytics).
|
|
51
54
|
:param model_yaml: YAML file containing paths to the training, validation, and testing datasets and the object class mappings. Example YAML file can be found [here](https://github.com/sgoldenlab/simba/blob/master/misc/ex_yolo_model.yaml).
|
|
52
55
|
:param save_path: Directory path where the trained model, logs, and results will be saved.
|
|
@@ -55,7 +58,7 @@ def fit_yolo(weights_path: Union[str, os.PathLike],
|
|
|
55
58
|
:return: None. The trained model and associated training logs are saved in the specified `project_path`.
|
|
56
59
|
|
|
57
60
|
:example:
|
|
58
|
-
>>> fit_yolo(initial_weights=r"C
|
|
61
|
+
>>> fit_yolo(initial_weights=r"C:/troubleshooting/coco_data/weights/yolov8n-obb.pt", data=r"C:/troubleshooting/coco_data/model.yaml", save_path=r"C:/troubleshooting/coco_data/mdl", batch=16)
|
|
59
62
|
"""
|
|
60
63
|
|
|
61
64
|
if not _is_cuda_available()[0]:
|
|
@@ -83,6 +86,9 @@ def load_yolo_model(weights_path: Union[str, os.PathLike],
|
|
|
83
86
|
"""
|
|
84
87
|
Load a YOLO model.
|
|
85
88
|
|
|
89
|
+
.. seealso::
|
|
90
|
+
For recommended wrapper classes that use this function, see :class:`simba.model.yolo_fit.FitYolo`, :class:`simba.model.yolo_inference.YoloInference`, :class:`simba.model.yolo_pose_inference.YOLOPoseInference`, :class:`simba.model.yolo_seg_inference.YOLOSegmentationInference`, and :class:`simba.model.yolo_pose_track_inference.YOLOPoseTrackInference`.
|
|
91
|
+
|
|
86
92
|
:param Union[str, os.PathLike] weights_path: Path to model weights (.pt, .engine, etc).
|
|
87
93
|
:param bool verbose: Whether to print loading info.
|
|
88
94
|
:param Optional[str] format: Export format, one of VALID_FORMATS or None to skip export.
|
|
@@ -169,6 +175,9 @@ def yolo_predict(model: YOLO,
|
|
|
169
175
|
"""
|
|
170
176
|
Produce YOLO predictions.
|
|
171
177
|
|
|
178
|
+
.. seealso::
|
|
179
|
+
For recommended wrapper classes that use this function, see :class:`simba.model.yolo_inference.YoloInference`, :class:`simba.model.yolo_pose_inference.YOLOPoseInference`, and :class:`simba.model.yolo_seg_inference.YOLOSegmentationInference`.
|
|
180
|
+
|
|
172
181
|
:param Union[str, os.PathLike] model: Loaded ultralytics.YOLO model. Returned by :func:`~simba.bounding_box_tools.yolo.model.load_yolo_model`.
|
|
173
182
|
:param Union[str, os.PathLike, np.ndarray] source: Path to video, video stream, directory, image, or image as loaded array.
|
|
174
183
|
:param bool half: Whether to use half precision (FP16) for inference to speed up processing.
|
|
@@ -87,9 +87,9 @@ class BlobTrackingExecutor():
|
|
|
87
87
|
:param bool center: If True, compute center coordinates. Default: True.
|
|
88
88
|
|
|
89
89
|
:example:
|
|
90
|
-
>>> tracker = BlobTrackingExecutor(data=r"C
|
|
90
|
+
>>> tracker = BlobTrackingExecutor(data=r"C:/troubleshooting/mitra/test/.temp/blob_definitions.pickle")
|
|
91
91
|
>>> tracker.run()
|
|
92
|
-
>>> tracker = BlobTrackingExecutor(data=r"C
|
|
92
|
+
>>> tracker = BlobTrackingExecutor(data=r"C:/troubleshooting/mitra/test/.temp/blob_definitions.pickle", batch_size=5000)
|
|
93
93
|
>>> tracker.run()
|
|
94
94
|
"""
|
|
95
95
|
|
|
@@ -29,7 +29,7 @@ def interactive_clahe_ui(data: Union[str, os.PathLike]) -> Tuple[float, int]:
|
|
|
29
29
|
:return Tuple[float, int]: Tuple containing the chosen clip limit and tile size.
|
|
30
30
|
|
|
31
31
|
:example:
|
|
32
|
-
>>> video = cv2.imread(r"D
|
|
32
|
+
>>> video = cv2.imread(r"D:/EPM/sample_2/video_1.mp4")
|
|
33
33
|
>>> interactive_clahe_ui(data=video)
|
|
34
34
|
"""
|
|
35
35
|
global original_img, font_size, x_spacer, y_spacer, txt
|
|
@@ -94,9 +94,9 @@ class EgocentricVideoRotator():
|
|
|
94
94
|
:param Optional[Union[str, os.PathLike]] save_path: The location where to store the rotated video. If None, saves the video as the same dir as the input video with the `_rotated` suffix.
|
|
95
95
|
|
|
96
96
|
:example:
|
|
97
|
-
>>> DATA_PATH = "C
|
|
98
|
-
>>> VIDEO_PATH = "C
|
|
99
|
-
>>> SAVE_PATH = "C
|
|
97
|
+
>>> DATA_PATH = "C:/501_MA142_Gi_Saline_0513.csv"
|
|
98
|
+
>>> VIDEO_PATH = "C:/501_MA142_Gi_Saline_0513.mp4"
|
|
99
|
+
>>> SAVE_PATH = "C:/501_MA142_Gi_Saline_0513_rotated.mp4"
|
|
100
100
|
>>> ANCHOR_LOC = np.array([250, 250])
|
|
101
101
|
|
|
102
102
|
>>> df = read_df(file_path=DATA_PATH, file_type='csv')
|
|
@@ -49,7 +49,7 @@ class MultiCropper(object):
|
|
|
49
49
|
|
|
50
50
|
|
|
51
51
|
:example:
|
|
52
|
-
>>> cropper = MultiCropper(file_type='mp4', input_folder=r'C
|
|
52
|
+
>>> cropper = MultiCropper(file_type='mp4', input_folder=r'C:/troubleshooting/mitra/test', output_folder=r'C:/troubleshooting/mitra/test/cropped', crop_cnt=2, gpu=True)
|
|
53
53
|
>>> cropper.run()
|
|
54
54
|
"""
|
|
55
55
|
|
|
@@ -676,7 +676,7 @@ def change_single_video_fps(file_path: Union[str, os.PathLike],
|
|
|
676
676
|
|
|
677
677
|
:param Union[str, os.PathLike] file_path: Path to video file
|
|
678
678
|
:param Union[int, float] fps: FPS of the new video file.
|
|
679
|
-
:param bool gpu: If True, use NVIDEA GPU codecs. Default False.
|
|
679
|
+
:param bool gpu: If True, use NVIDEA GPU codecs. Default False. GPU can provide significant speedup (3-4x faster) for FPS conversion, especially for longer videos.
|
|
680
680
|
:param Optional[str] codec: Video codec to use. If None, automatically selects based on file extension (libvpx-vp9 for .webm, mpeg4 for .avi, libx264 for others). Default None.
|
|
681
681
|
:param Optional[Union[str, os.PathLike]] save_path: Path where to save the converted video. If None, saves in the same directory as input file with ``_fps_{fps}`` suffix. Default None.
|
|
682
682
|
:param Optional[int] quality: Video quality (CRF value). Lower values = higher quality. Range 0-52. Default 23.
|
|
@@ -702,7 +702,7 @@ def change_single_video_fps(file_path: Union[str, os.PathLike],
|
|
|
702
702
|
else:
|
|
703
703
|
check_if_dir_exists(in_dir=os.path.dirname(save_path), raise_error=True)
|
|
704
704
|
quality = 23 if not check_int(name='quality', value=quality, min_value=0, max_value=52, raise_error=False)[0] else int(quality)
|
|
705
|
-
if verbose: print(f"Converting the FPS
|
|
705
|
+
if verbose: print(f"Converting the FPS {video_meta_data['fps']} -> {fps} for video {file_name} ...")
|
|
706
706
|
if codec is None:
|
|
707
707
|
if ext.lower() == '.webm':
|
|
708
708
|
codec = 'libvpx-vp9'
|
|
@@ -713,10 +713,14 @@ def change_single_video_fps(file_path: Union[str, os.PathLike],
|
|
|
713
713
|
if os.path.isfile(save_path):
|
|
714
714
|
FileExistWarning(msg=f"Overwriting existing file at {save_path}...", source=change_single_video_fps.__name__,)
|
|
715
715
|
if gpu:
|
|
716
|
-
cmd = f'ffmpeg -hwaccel auto -
|
|
717
|
-
|
|
716
|
+
cmd = f'ffmpeg -hwaccel auto -i "{file_path}" -vf "fps={fps}" -c:v h264_nvenc -preset p4 -cq {quality} -c:a copy "{save_path}" -loglevel error -stats -hide_banner -y'
|
|
717
|
+
result = subprocess.run(cmd, shell=True)
|
|
718
|
+
if result.returncode != 0:
|
|
719
|
+
if verbose: SimBAGPUError(msg=f'FPS convertion ({video_meta_data["fps"]}->{fps}) GPU for video {file_name} failed, using CPU instead...')
|
|
720
|
+
gpu = False
|
|
721
|
+
if not gpu:
|
|
718
722
|
cmd = f'ffmpeg -i "{file_path}" -filter:v fps=fps={fps} -c:v {codec} -crf {quality} -c:a aac "{save_path}" -loglevel error -stats -hide_banner -y'
|
|
719
|
-
|
|
723
|
+
subprocess.call(cmd, shell=True)
|
|
720
724
|
timer.stop_timer()
|
|
721
725
|
if verbose: stdout_success(msg=f'SIMBA COMPLETE: FPS of video {file_name} changed from {str(video_meta_data["fps"])} to {str(fps)} and saved in directory {save_path}', elapsed_time=timer.elapsed_time_str, source=change_single_video_fps.__name__)
|
|
722
726
|
|
|
@@ -725,7 +729,8 @@ def change_fps_of_multiple_videos(path: Union[str, os.PathLike, List[Union[str,
|
|
|
725
729
|
fps: int,
|
|
726
730
|
quality: int = 23,
|
|
727
731
|
save_dir: Optional[Union[str, os.PathLike]] = None,
|
|
728
|
-
gpu: Optional[bool] = False
|
|
732
|
+
gpu: Optional[bool] = False,
|
|
733
|
+
verbose: bool = True) -> None:
|
|
729
734
|
"""
|
|
730
735
|
Change the fps of all video files in a folder. Results are stored in the same directory as in the input files with
|
|
731
736
|
the suffix ``_fps_new_fps``.
|
|
@@ -735,6 +740,7 @@ def change_fps_of_multiple_videos(path: Union[str, os.PathLike, List[Union[str,
|
|
|
735
740
|
:param int quality: Video quality (CRF value). Lower values = higher quality. Range 0-52. Default 23.
|
|
736
741
|
:param Optional[Union[str, os.PathLike]] save_dir: If not None, then the directory where to store converted videos. If None, then stores the new videos in the same directory as the input video with the ``_fps_{fps}.file_extension`` suffix.
|
|
737
742
|
:param Optional[bool] gpu: If True, use NVIDEA GPU codecs. Default False.
|
|
743
|
+
:param bool verbose: If True, prints conversion progress. Default True.
|
|
738
744
|
:returns: None.
|
|
739
745
|
|
|
740
746
|
:example:
|
|
@@ -764,7 +770,7 @@ def change_fps_of_multiple_videos(path: Union[str, os.PathLike, List[Union[str,
|
|
|
764
770
|
video_meta_data = get_video_meta_data(video_path=file_path)
|
|
765
771
|
if int(fps) == int(video_meta_data["fps"]):
|
|
766
772
|
SameInputAndOutputWarning(msg=f"The new FPS ({fps}) is the same or lower than the original FPS ({video_meta_data['fps']}) for video {file_name}", source=change_fps_of_multiple_videos.__name__)
|
|
767
|
-
print(f"Converting FPS
|
|
773
|
+
if verbose: print(f"Converting the FPS {video_meta_data['fps']} -> {fps} for video {file_name} ...")
|
|
768
774
|
if save_dir is None:
|
|
769
775
|
save_path = os.path.join(dir_name, file_name + f"_fps_{fps}{ext}")
|
|
770
776
|
else:
|
|
@@ -772,15 +778,26 @@ def change_fps_of_multiple_videos(path: Union[str, os.PathLike, List[Union[str,
|
|
|
772
778
|
if ext.lower() == '.webm': codec = 'libvpx-vp9'
|
|
773
779
|
elif ext.lower() == '.avi': codec = 'mpeg4'
|
|
774
780
|
else: codec = 'libx264'
|
|
781
|
+
if os.path.isfile(save_path):
|
|
782
|
+
FileExistWarning(msg=f"Overwriting existing file at {save_path}...", source=change_single_video_fps.__name__, )
|
|
783
|
+
if gpu:
|
|
784
|
+
cmd = f'ffmpeg -hwaccel auto -i "{file_path}" -vf "fps={fps}" -c:v h264_nvenc -preset p4 -cq {quality} -c:a copy "{save_path}" -loglevel error -stats -hide_banner -y'
|
|
785
|
+
result = subprocess.run(cmd, shell=True)
|
|
786
|
+
if result.returncode != 0:
|
|
787
|
+
if verbose: SimBAGPUError(msg=f'FPS convertion ({video_meta_data["fps"]}->{fps}) GPU for video {file_name} failed, using CPU instead...')
|
|
788
|
+
gpu = False
|
|
789
|
+
if not gpu:
|
|
790
|
+
cmd = f'ffmpeg -i "{file_path}" -filter:v fps=fps={fps} -c:v {codec} -crf {quality} -c:a aac "{save_path}" -loglevel error -stats -hide_banner -y'
|
|
791
|
+
subprocess.call(cmd, shell=True)
|
|
775
792
|
if gpu:
|
|
776
793
|
command = f'ffmpeg -hwaccel auto -c:v h264_cuvid -i "{file_path}" -vf "fps={fps}" -c:v h264_nvenc -rc vbr -cq {quality} -c:a copy "{save_path}" -loglevel error -stats -hide_banner -y'
|
|
777
794
|
else:
|
|
778
795
|
command = f'ffmpeg -i "{file_path}" -filter:v fps=fps={fps} -c:v {codec} -crf {quality} -c:a aac "{save_path}" -loglevel error -stats -hide_banner -y'
|
|
779
796
|
subprocess.call(command, shell=True)
|
|
780
797
|
video_timer.stop_timer()
|
|
781
|
-
print(f"Video {file_name} complete (saved at {save_path})... (elapsed time: {video_timer.elapsed_time_str}s)")
|
|
798
|
+
if verbose: print(f"Video {file_name} complete (saved at {save_path})... (elapsed time: {video_timer.elapsed_time_str}s)")
|
|
782
799
|
timer.stop_timer()
|
|
783
|
-
stdout_success(msg=f"SIMBA COMPLETE: FPS of {len(video_paths)} video(s) changed to {fps}", elapsed_time=timer.elapsed_time_str, source=change_fps_of_multiple_videos.__name__,)
|
|
800
|
+
if verbose: stdout_success(msg=f"SIMBA COMPLETE: FPS of {len(video_paths)} video(s) changed to {fps}", elapsed_time=timer.elapsed_time_str, source=change_fps_of_multiple_videos.__name__,)
|
|
784
801
|
|
|
785
802
|
|
|
786
803
|
def convert_video_powerpoint_compatible_format(file_path: Union[str, os.PathLike], gpu: Optional[bool] = False) -> None:
|
|
@@ -87,8 +87,8 @@ def video_to_frames(video_path: Union[str, os.PathLike],
|
|
|
87
87
|
:return: None. Frames are saved to disk in the specified directory.
|
|
88
88
|
|
|
89
89
|
:example:
|
|
90
|
-
>>> video_to_frames(video_path=r"C
|
|
91
|
-
... save_dir=r'C
|
|
90
|
+
>>> video_to_frames(video_path=r"C:/troubleshooting/SDS_pre_post/project_folder/videos/SDI100 x ALR2 post_d7.mp4",
|
|
91
|
+
... save_dir=r'C:/troubleshooting/SDS_pre_post/project_folder/videos/test',
|
|
92
92
|
... black_and_white=False,
|
|
93
93
|
... verbose=True,
|
|
94
94
|
... img_format='webp',
|