def simple_predictions(): video = Video.from_filename("video.mp4") skeleton = Skeleton() skeleton.add_node("a") skeleton.add_node("b") track_a = Track(0, "a") track_b = Track(0, "b") labels = Labels() instances = [] instances.append( PredictedInstance( skeleton=skeleton, score=2, track=track_a, points=dict(a=PredictedPoint(1, 1, score=0.5), b=PredictedPoint(1, 1, score=0.5)), )) instances.append( PredictedInstance( skeleton=skeleton, score=5, track=track_b, points=dict(a=PredictedPoint(1, 1, score=0.7), b=PredictedPoint(1, 1, score=0.7)), )) labeled_frame = LabeledFrame(video, frame_idx=0, instances=instances) labels.append(labeled_frame) instances = [] instances.append( PredictedInstance( skeleton=skeleton, score=3, track=track_a, points=dict(a=PredictedPoint(4, 5, score=1.5), b=PredictedPoint(1, 1, score=1.0)), )) instances.append( PredictedInstance( skeleton=skeleton, score=6, track=track_b, points=dict(a=PredictedPoint(6, 13, score=1.7), b=PredictedPoint(1, 1, score=1.0)), )) labeled_frame = LabeledFrame(video, frame_idx=1, instances=instances) labels.append(labeled_frame) return labels
def skeleton(): # Create a simple skeleton object skeleton = Skeleton("Fly") skeleton.add_node("head") skeleton.add_node("thorax") skeleton.add_node("abdomen") skeleton.add_node("left-wing") skeleton.add_node("right-wing") skeleton.add_edge(source="head", destination="thorax") skeleton.add_edge(source="thorax", destination="abdomen") skeleton.add_edge(source="thorax", destination="left-wing") skeleton.add_edge(source="thorax", destination="right-wing") skeleton.add_symmetry(node1="left-wing", node2="right-wing") return skeleton
def test_merge_predictions(): dummy_video_a = Video.from_filename("foo.mp4") dummy_video_b = Video.from_filename("foo.mp4") dummy_skeleton_a = Skeleton() dummy_skeleton_a.add_node("node") dummy_skeleton_b = Skeleton() dummy_skeleton_b.add_node("node") dummy_instances_a = [] dummy_instances_a.append( Instance(skeleton=dummy_skeleton_a, points=dict(node=Point(1, 1))) ) dummy_instances_a.append( Instance(skeleton=dummy_skeleton_a, points=dict(node=Point(2, 2))) ) labels_a = Labels() labels_a.append( LabeledFrame(dummy_video_a, frame_idx=0, instances=dummy_instances_a) ) dummy_instances_b = [] dummy_instances_b.append( Instance(skeleton=dummy_skeleton_b, points=dict(node=Point(1, 1))) ) dummy_instances_b.append( PredictedInstance( skeleton=dummy_skeleton_b, points=dict(node=Point(3, 3)), score=1 ) ) labels_b = Labels() labels_b.append( LabeledFrame(dummy_video_b, frame_idx=0, instances=dummy_instances_b) ) # Frames have one redundant instance (perfect match) and all the # non-matching instances are different types (one predicted, one not). merged, extra_a, extra_b = Labels.complex_merge_between(labels_a, labels_b) assert len(merged[dummy_video_a]) == 1 assert len(merged[dummy_video_a][0]) == 1 # the predicted instance was merged assert not extra_a assert not extra_b
def test_labels_merge(): dummy_video = Video(backend=MediaVideo) dummy_skeleton = Skeleton() dummy_skeleton.add_node("node") labels = Labels() dummy_frames = [] # Add 10 instances with different points (so they aren't "redundant") for i in range(10): instance = Instance(skeleton=dummy_skeleton, points=dict(node=Point(i, i))) dummy_frame = LabeledFrame(dummy_video, frame_idx=0, instances=[instance]) dummy_frames.append(dummy_frame) labels.labeled_frames.extend(dummy_frames) assert len(labels) == 10 assert len(labels.labeled_frames[0].instances) == 1 labels.merge_matching_frames() assert len(labels) == 1 assert len(labels.labeled_frames[0].instances) == 10
def test_complex_merge(): dummy_video_a = Video.from_filename("foo.mp4") dummy_video_b = Video.from_filename("foo.mp4") dummy_skeleton_a = Skeleton() dummy_skeleton_a.add_node("node") dummy_skeleton_b = Skeleton() dummy_skeleton_b.add_node("node") dummy_instances_a = [] dummy_instances_a.append( Instance(skeleton=dummy_skeleton_a, points=dict(node=Point(1, 1)))) dummy_instances_a.append( Instance(skeleton=dummy_skeleton_a, points=dict(node=Point(2, 2)))) labels_a = Labels() labels_a.append( LabeledFrame(dummy_video_a, frame_idx=0, instances=dummy_instances_a)) dummy_instances_b = [] dummy_instances_b.append( Instance(skeleton=dummy_skeleton_b, points=dict(node=Point(1, 1)))) dummy_instances_b.append( Instance(skeleton=dummy_skeleton_b, points=dict(node=Point(3, 3)))) labels_b = Labels() labels_b.append( LabeledFrame(dummy_video_b, frame_idx=0, instances=dummy_instances_b)) # conflict labels_b.append( LabeledFrame(dummy_video_b, frame_idx=1, instances=dummy_instances_b)) # clean merged, extra_a, extra_b = Labels.complex_merge_between(labels_a, labels_b) # Check that we have the cleanly merged frame assert dummy_video_a in merged assert len(merged[dummy_video_a]) == 1 # one merged frame assert len(merged[dummy_video_a][1]) == 2 # with two instances # Check that labels_a includes redundant and clean assert len(labels_a.labeled_frames) == 2 assert len(labels_a.labeled_frames[0].instances) == 1 assert labels_a.labeled_frames[0].instances[0].points[0].x == 1 assert len(labels_a.labeled_frames[1].instances) == 2 assert labels_a.labeled_frames[1].instances[0].points[0].x == 1 assert labels_a.labeled_frames[1].instances[1].points[0].x == 3 # Check that extra_a/b includes the appropriate conflicting instance assert len(extra_a) == 1 assert len(extra_b) == 1 assert len(extra_a[0].instances) == 1 assert len(extra_b[0].instances) == 1 assert extra_a[0].instances[0].points[0].x == 2 assert extra_b[0].instances[0].points[0].x == 3 # Check that objects were unified assert extra_a[0].video == extra_b[0].video # Check resolving the conflict using new Labels.finish_complex_merge(labels_a, extra_b) assert len(labels_a.labeled_frames) == 2 assert len(labels_a.labeled_frames[0].instances) == 2 assert labels_a.labeled_frames[0].instances[1].points[0].x == 3
def test_arborescence(): skeleton = Skeleton() skeleton.add_node("a") skeleton.add_node("b") skeleton.add_node("c") # linear: a -> b -> c skeleton.add_edge("a", "b") skeleton.add_edge("b", "c") assert skeleton.is_arborescence skeleton = Skeleton() skeleton.add_node("a") skeleton.add_node("b") skeleton.add_node("c") # two branches from a: a -> b and a -> c skeleton.add_edge("a", "b") skeleton.add_edge("a", "c") assert skeleton.is_arborescence skeleton = Skeleton() skeleton.add_node("a") skeleton.add_node("b") skeleton.add_node("c") # no edges so too many roots assert not skeleton.is_arborescence assert sorted((n.name for n in skeleton.root_nodes)) == ["a", "b", "c"] # still too many roots: a and c skeleton.add_edge("a", "b") assert not skeleton.is_arborescence assert sorted((n.name for n in skeleton.root_nodes)) == ["a", "c"] skeleton = Skeleton() skeleton.add_node("a") skeleton.add_node("b") skeleton.add_node("c") # cycle skeleton.add_edge("a", "b") skeleton.add_edge("b", "c") skeleton.add_edge("c", "a") assert not skeleton.is_arborescence assert len(skeleton.cycles) == 1 assert len(skeleton.root_nodes) == 0 skeleton = Skeleton() skeleton.add_node("a") skeleton.add_node("b") skeleton.add_node("c") skeleton.add_node("d") # diamond, too many sources leading to d skeleton.add_edge("a", "b") skeleton.add_edge("a", "c") skeleton.add_edge("b", "d") skeleton.add_edge("c", "d") assert not skeleton.is_arborescence assert len(skeleton.cycles) == 0 assert len(skeleton.root_nodes) == 1 assert len(skeleton.in_degree_over_one) == 1