-
Hello, We're trying to train a bottom-up w/ ID model and ran into the following error: We train directly from the CLI using a python file, which you can find (along with the video and slp file) in this folder: We normally use Sleap v.1.1.1 - but I also tried it in v.1.2.9 and get the same error. Thank you for your help! |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 2 replies
-
This error comes from our manual merge of 2 .slp files using this code which is based on a function made by Talmo. def merge_slp_files(fname_slp1, fname_slp2):
#
fname_hybrid_video = fname_slp1[:-4]+"_merged.avi"
#
merged_video = sleap.load_video(fname_hybrid_video)
print(merged_video)
#
fname_hybrid_slp = fname_hybrid_video[:-4] + ".slp"
#
slp_files = [fname_slp1,
fname_slp2
]
n_frames = 0
all_frames = []
reference_tracks = {}
first_labels = None
for slp_file in slp_files:
# Load saved labels.
labels = sleap.load_file(slp_file)#, match_to=first_labels)
if first_labels is None:
first_labels = labels
new_frames = []
for i, lf in enumerate(labels):
# Update reference to merged video.
lf.video = merged_video
# Update frame index to the frame number within the merged video.
lf.frame_idx = n_frames + i
# # Update the track reference to use the reference tracks to prevent duplication.
for instance in lf:
if instance.track is not None:
if instance.track.name in reference_tracks:
instance.track = reference_tracks[instance.track.name]
else:
reference_tracks[instance.track.name] = instance.track
# Append the labeled frame to the list of frames we're keeping from these labels.
new_frames.append(lf)
all_frames.extend(new_frames)
n_frames += len(new_frames)
merged_labels = sleap.Labels(all_frames)
# save stuff
merged_labels.save(fname_hybrid_slp)
print("DONE...")
#
merge_slp_files(fname_human_slp,
fname_idswitch_slp) |
Beta Was this translation helpful? Give feedback.
-
We have seen this problem occur when the labels file references more than one instance of We have a piece of code for loading a new skeleton into the project which will delete old skeletons: Lines 1722 to 1867 in c4861e3 Can you add the function: def compare_skeletons(
skeleton: Skeleton, new_skeleton: Skeleton
) -> Tuple[List[str], List[str]]:
delete_nodes = []
add_nodes = []
if skeleton.node_names != new_skeleton.node_names:
# Compare skeletons
base_nodes = skeleton.node_names
new_nodes = new_skeleton.node_names
delete_nodes = [node for node in base_nodes if node not in new_nodes]
add_nodes = [node for node in new_nodes if node not in base_nodes]
return delete_nodes, add_nodes and try: def merge_slp_files(fname_slp1, fname_slp2):
#
fname_hybrid_video = fname_slp1[:-4]+"_merged.avi"
#
merged_video = sleap.load_video(fname_hybrid_video)
print(merged_video)
#
fname_hybrid_slp = fname_hybrid_video[:-4] + ".slp"
# Load labels
slp_files = [fname_slp1,
fname_slp2
]
first_labels = sleap.load_file(slp_files[0])
slp_labels = [first_labels, sleap.load_file(slp_files[1])]#match_to=first_labels)]
# Compare skeletons
assert len(slp_labels[0].skeletons) <= 1 # Ensure each project only has a single skeleton
assert len(slp_labels[1].skeletons) <= 1
delete_nodes, add_nodes = compare_skeleton(slp_labels[0].skeleton, slp_labels[1].skeleton)
assert len(delete_nodes) == 0 # Ensure project skeletons are identical
assert len(add_nodes) == 0
the_skeleton = slp_labels[0].skeleton or slp_labels[1].skeleton
n_frames = 0
all_frames = []
reference_tracks = {}
for labels in slp_labels:
new_frames = []
for i, lf in enumerate(labels):
# Update reference to merged video.
lf.video = merged_video
# Update frame index to the frame number within the merged video.
lf.frame_idx = n_frames + i
# # Update the track reference to use the reference tracks to prevent duplication.
for instance in lf:
if instance.track is not None:
if instance.track.name in reference_tracks:
instance.track = reference_tracks[instance.track.name]
else:
reference_tracks[instance.track.name] = instance.track
# Set the instance to reference the correct instance of `Skeleton`
instance.skeleton = the_skeleton
# Append the labeled frame to the list of frames we're keeping from these labels.
new_frames.append(lf)
all_frames.extend(new_frames)
n_frames += len(new_frames)
merged_labels = sleap.Labels(all_frames)
# save stuff
merged_labels.save(fname_hybrid_slp)
print("DONE...")
#
merge_slp_files(fname_human_slp,
fname_idswitch_slp) Thanks, |
Beta Was this translation helpful? Give feedback.
-
Hi all, Just jumping in here with a quick suggestion -- on this line: slp_labels = [first_labels, sleap.load_file(slp_files[1])]#match_to=first_labels)] Do you remember why we commented the slp_labels = [first_labels, sleap.load_file(slp_files[1], match_to=first_labels)]] The Give that a spin and if it doesn't work just keep troubleshooting as per @roomrys's suggestions. Another thing to try is to just force the labels to have a single skeleton: merged_labels = sleap.Labels(all_frames)
merged_labels.skeletons = [the_skeleton]
assert all([inst.skeleton == the_skeleton for inst in merged_labels.instances()]) It's a bit concerning that this is happening in the first place since it means there's more than one skeleton in the instances, but the |
Beta Was this translation helpful? Give feedback.
Hi all,
Just jumping in here with a quick suggestion -- on this line:
Do you remember why we commented the
#match_to=first_labels
? Have you tried with that bit included? i.e.:The
match_to
should handle merging skeletons -- it just doesn't currently deal with duplicate tracks (see #1083).Give that a spin and if it doesn't work just keep troubleshooting as per @roomrys's suggestions.
Another thing to try is to just force the labels to have a single skeleton: