Skip to content

Commit caaaeee

Browse files
author
Csaba Bolyos
committed
fixed regexp
1 parent f032f25 commit caaaeee

1 file changed

Lines changed: 60 additions & 42 deletions

File tree

sowlv2/video_utils.py

Lines changed: 60 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,59 @@ def images_to_video(image_files, video_path, fps=30):
6767
video_writer.release()
6868
print(f"Saved video {video_path}")
6969

70+
def _parse_mask_filename(fname):
71+
"""
72+
Parse a mask filename to extract sam_id_token and core_prompt_slug.
73+
Returns (sam_id_token, core_prompt_slug) or (None, None) if not matched.
74+
"""
75+
# Example: 000001_obj1_dog_mask.png
76+
match = re.match(r"^\d+_(obj\d+)_([a-zA-Z0-9_]+)_mask\.png$", fname)
77+
if match:
78+
return match.group(1), match.group(2)
79+
# Fallback: 000001_obj1_mask.png (no prompt)
80+
match_simple = re.match(r"^\d+_(obj\d+)_mask\.png$", fname)
81+
if match_simple:
82+
return match_simple.group(1), None
83+
return None, None
84+
85+
def _collect_unique_tracked_objects(mask_files):
86+
"""
87+
Collect unique (sam_id_token, core_prompt_slug) pairs from mask filenames.
88+
Returns a dict with keys as (sam_id_token, core_prompt_slug).
89+
"""
90+
unique_tracked_objects = {}
91+
for f_path in mask_files:
92+
fname = os.path.basename(f_path)
93+
sam_id_token, core_prompt_slug = _parse_mask_filename(fname)
94+
if sam_id_token is not None:
95+
key = (sam_id_token, core_prompt_slug)
96+
if key not in unique_tracked_objects:
97+
unique_tracked_objects[key] = {
98+
"sam_id_token": sam_id_token,
99+
"core_prompt_slug": core_prompt_slug
100+
}
101+
else:
102+
print(f"Warning: Filename {fname} did not match expected pattern.")
103+
return unique_tracked_objects
104+
105+
def _get_obj_files(output_dir, sam_id_token, core_prompt_slug):
106+
"""
107+
Get sorted mask and overlay files for a given object.
108+
"""
109+
if core_prompt_slug:
110+
mask_pattern = os.path.join(
111+
output_dir, f"*_{sam_id_token}_{core_prompt_slug}_mask.png")
112+
overlay_pattern = os.path.join(
113+
output_dir, f"*_{sam_id_token}_{core_prompt_slug}_overlay.png")
114+
video_prefix = f"{sam_id_token}_{core_prompt_slug}"
115+
else:
116+
mask_pattern = os.path.join(output_dir, f"*_{sam_id_token}_mask.png")
117+
overlay_pattern = os.path.join(output_dir, f"*_{sam_id_token}_overlay.png")
118+
video_prefix = sam_id_token
119+
mask_files = sorted(glob(mask_pattern))
120+
overlay_files = sorted(glob(overlay_pattern))
121+
return mask_files, overlay_files, video_prefix
122+
70123
def generate_per_object_videos(output_dir, fps=30):
71124
"""
72125
Generate per-object videos from mask and overlay images.
@@ -80,57 +133,22 @@ def generate_per_object_videos(output_dir, fps=30):
80133
print(f"No mask files found in {output_dir} matching pattern.")
81134
return
82135

83-
# Store unique combinations of (sam_id_token, core_prompt_slug)
84-
# sam_id_token is like "obj1", core_prompt_slug is like "dog" or "a_red_bicycle"
85-
unique_tracked_objects = {}
86-
87-
# Regex to parse filenames like "000001_obj1_dog_mask.png"
88-
# or "000001_obj1_a_red_bicycle_mask.png"
89-
# Group 1: (obj\d+) - e.g., "obj1"
90-
# Group 2: ([^_]+(?:_[^_]+)*) - e.g., "dog" or "a_red_bicycle"
91-
filename_parser = re.compile(r"^\d+_(obj\d+)_([^_]+(?:_[^_]+)*)_mask\.png$")
92-
93-
for f_path in all_mask_files:
94-
fname = os.path.basename(f_path)
95-
match = filename_parser.match(fname)
96-
if match:
97-
sam_id_token = match.group(1) # e.g., "obj1"
98-
core_prompt_slug = match.group(2) # e.g., "dog" or "a_red_bicycle"
99-
100-
# Use a tuple to uniquely identify the tracked object
101-
object_key = (sam_id_token, core_prompt_slug)
102-
if object_key not in unique_tracked_objects:
103-
unique_tracked_objects[object_key] = {
104-
"sam_id_token": sam_id_token,
105-
"core_prompt_slug": core_prompt_slug
106-
}
107-
else:
108-
print(f"Warning: Filename {fname} did not match expected pattern.")
109-
continue
110-
136+
unique_tracked_objects = _collect_unique_tracked_objects(all_mask_files)
111137
if not unique_tracked_objects:
112138
print(f"No objects successfully parsed from filenames in {output_dir}.")
113139
return
114140

115-
for key in sorted(list(unique_tracked_objects.keys())): # Sort for deterministic order
141+
for key in sorted(unique_tracked_objects.keys()):
116142
obj_info = unique_tracked_objects[key]
117143
sam_id_token = obj_info["sam_id_token"]
118144
core_prompt_slug = obj_info["core_prompt_slug"]
119145

120-
# Construct glob patterns that include both sam_id_token and core_prompt_slug
121-
obj_mask_files_pattern = os.path.join(
122-
output_dir, f"*_{sam_id_token}_{core_prompt_slug}_mask.png")
123-
obj_overlay_files_pattern = os.path.join(
124-
output_dir, f"*_{sam_id_token}_{core_prompt_slug}_overlay.png")
125-
126-
obj_mask_files = sorted(glob(obj_mask_files_pattern))
127-
obj_overlay_files = sorted(glob(obj_overlay_files_pattern))
128-
129-
# Create a descriptive prefix for the video files
130-
video_file_prefix = f"{sam_id_token}_{core_prompt_slug}"
146+
mask_files, overlay_files, video_file_prefix = _get_obj_files(
147+
output_dir, sam_id_token, core_prompt_slug
148+
)
131149

132150
mask_video_path = os.path.join(output_dir, f"{video_file_prefix}_mask_video.mp4")
133151
overlay_video_path = os.path.join(output_dir, f"{video_file_prefix}_overlay_video.mp4")
134152

135-
images_to_video(obj_mask_files, mask_video_path, fps)
136-
images_to_video(obj_overlay_files, overlay_video_path, fps)
153+
images_to_video(mask_files, mask_video_path, fps)
154+
images_to_video(overlay_files, overlay_video_path, fps)

0 commit comments

Comments
 (0)