|
3 | 3 | Convert keypoint annotations |
4 | 4 | from the Elevated Plus Maze (EPM) dataset from DLC to COCO format. |
5 | 5 |
|
6 | | -Also copy a video and its labeled frames to the target directory, |
| 6 | +Also copy a video and its labeled frames to a target directory, |
7 | 7 | organised in the pose benchmarks dataset structure. |
8 | 8 | """ |
9 | 9 |
|
|
25 | 25 | # It contains single-animal top-down videos of mice exploring an elevated plus |
26 | 26 | # maze, with keypoint annotations and predictions from DeepLabCut (DLC). |
27 | 27 | # |
28 | | -# In this notebook, we convert the DLC annotations to COCO .json format. |
| 28 | +# In this example, we convert the DLC annotations to COCO .json format. |
29 | 29 |
|
30 | 30 | # %% |
31 | | -# Specify paths |
32 | | -# ------------- |
| 31 | +# Define source and target directories |
| 32 | +# ------------------------------------ |
33 | 33 | # We specify the paths to the source DLC project directory |
34 | | -# as well as the output directory where converted COCO files will be saved. |
35 | | -# The latter will be organised in the pose benchmark dataset structure. |
| 34 | +# as well as the target directory where converted files will be saved. |
| 35 | +# The target will be organised in the pose benchmarks dataset structure. |
36 | 36 |
|
37 | | -base_dir = Path( |
| 37 | +source_base_dir = Path( |
38 | 38 | "/media/ceph-niu/neuroinformatics/sirmpilatzen/behav_data" |
39 | 39 | "/Loukia/MASTER_DoNotModify" |
40 | 40 | ) |
41 | | -dlc_project_dir = base_dir / "MouseTopDown-Loukia-2022-09-13" |
42 | | -assert dlc_project_dir.exists(), ( |
43 | | - f"DLC project dir not found: {dlc_project_dir}" |
| 41 | +source_project_dir = source_base_dir / "MouseTopDown-Loukia-2022-09-13" |
| 42 | +assert source_project_dir.exists(), ( |
| 43 | + f"DLC project directory not found: {source_project_dir}" |
44 | 44 | ) |
45 | 45 |
|
46 | | -pose_benchmarks_dir = Path("/mnt/Data/pose_benchmarks") |
47 | | -target_dir = pose_benchmarks_dir / "SWC_EPM" |
48 | | -target_dir.mkdir(parents=True, exist_ok=True) |
| 46 | +target_base_dir = Path("/mnt/Data/pose_benchmarks") |
| 47 | +target_dataset_dir = target_base_dir / "SWC-EPM" |
| 48 | +target_dataset_dir.mkdir(parents=True, exist_ok=True) |
49 | 49 |
|
50 | 50 | # %% |
51 | | -# Copy a video to target location |
52 | | -# ------------------------------- |
| 51 | +# Copy video to target location |
| 52 | +# ----------------------------- |
| 53 | +# We identify a specific video by name and copy it to the target directory |
| 54 | +# with a standardised naming convention. |
53 | 55 |
|
54 | | -# Let's identify a specific video by name |
55 | 56 | source_video_name = "M708149_EPM_20200317_165049331-converted.mp4" |
| 57 | +source_video_path = source_project_dir / "videos" / source_video_name |
56 | 58 |
|
57 | | -# Define subject, session, and view IDs |
58 | | -sub_id = "M708149" |
59 | | -ses_id = "20200317" |
60 | | -view = "topdown" |
| 59 | +# Define subject, session, and view identifiers |
| 60 | +subject_id = "M708149" |
| 61 | +session_id = "20200317" |
| 62 | +view_id = "topdown" |
| 63 | +video_id = f"sub-{subject_id}_ses-{session_id}_view-{view_id}" |
61 | 64 |
|
62 | 65 | # Create target session directory |
63 | | -target_ses_dir = target_dir / f"sub-{sub_id}_ses-{ses_id}" |
64 | | -target_ses_dir.mkdir(parents=True, exist_ok=True) |
65 | | - |
66 | | -# Copy video to target location with appropriate naming |
67 | | -video_id = f"sub-{sub_id}_ses-{ses_id}_view-{view}" |
68 | | -source_video_path = dlc_project_dir / "videos" / source_video_name |
69 | | -target_video_path = target_ses_dir / f"{video_id}.mp4" |
| 66 | +target_session_dir = target_dataset_dir / f"sub-{subject_id}_ses-{session_id}" |
| 67 | +target_session_dir.mkdir(parents=True, exist_ok=True) |
70 | 68 |
|
| 69 | +# Copy video to target location |
| 70 | +target_video_path = target_session_dir / f"{video_id}.mp4" |
71 | 71 | if not target_video_path.exists(): |
72 | 72 | shutil.copy2(source_video_path, target_video_path) |
73 | 73 | print(f"Copied video to: {target_video_path}") |
|
88 | 88 | # We fixed this by replacing the commas with slashes in the csv file. |
89 | 89 |
|
90 | 90 | source_labels_dir = ( |
91 | | - dlc_project_dir / "labeled-data" / source_video_name.replace(".mp4", "") |
| 91 | + source_project_dir / "labeled-data" / source_video_name.replace(".mp4", "") |
92 | 92 | ) |
93 | | -dlc_annotations_file = source_labels_dir / "CollectedData_Loukia.csv" |
| 93 | +source_annotations_path = source_labels_dir / "CollectedData_Loukia.csv" |
| 94 | + |
| 95 | +# Create Frames directory inside the session directory |
| 96 | +target_frames_dir = target_session_dir / "Frames" |
| 97 | +target_frames_dir.mkdir(parents=True, exist_ok=True) |
94 | 98 |
|
95 | | -out_json_path = target_ses_dir / f"{video_id}_framelabels.json" |
| 99 | +# Save COCO annotations inside the Frames directory |
| 100 | +target_annotations_path = target_frames_dir / f"{video_id}_framelabels.json" |
96 | 101 |
|
97 | 102 | annotations_to_coco( |
98 | | - input_path=dlc_annotations_file, |
99 | | - output_json_path=out_json_path, |
| 103 | + input_path=source_annotations_path, |
| 104 | + output_json_path=target_annotations_path, |
100 | 105 | coco_visibility_encoding="ternary", |
101 | 106 | ) |
| 107 | +print(f"Saved COCO annotations to: {target_annotations_path}") |
102 | 108 |
|
103 | 109 | # %% |
104 | | -# Let's also copy the frames used for labeling to the target directory |
105 | | - |
106 | | -target_frames_dir = target_ses_dir / "frames" |
107 | | -target_frames_dir.mkdir(parents=True, exist_ok=True) |
108 | | - |
109 | | -for frame_file in source_labels_dir.glob("*.png"): |
110 | | - target_frame_file = target_frames_dir / frame_file.name |
111 | | - if not target_frame_file.exists(): |
112 | | - shutil.copy2(frame_file, target_frame_file) |
| 110 | +# Copy labeled frames to target directory |
| 111 | +# --------------------------------------- |
| 112 | +# Copy the frames used for labeling and rename them to follow |
| 113 | +# the naming convention: |
| 114 | +# ``sub-{subjectID}_ses-{SessionID}_view-{ViewID}_frame-{FrameID}.png`` |
| 115 | + |
| 116 | +for source_frame_path in source_labels_dir.glob("*.png"): |
| 117 | + # Extract frame number from original filename, e.g. "img0042.png" -> "0042" |
| 118 | + frame_number = source_frame_path.stem.replace("img", "") |
| 119 | + target_frame_path = ( |
| 120 | + target_frames_dir / f"{video_id}_frame-{frame_number}.png" |
| 121 | + ) |
| 122 | + if not target_frame_path.exists(): |
| 123 | + shutil.copy2(source_frame_path, target_frame_path) |
| 124 | + |
| 125 | +print(f"Copied labeled frames to: {target_frames_dir}") |
113 | 126 |
|
114 | 127 | # %% |
0 commit comments