Пример #1
0
    def test_filter_against(self):
        intrvl_long1 = Interval(1., 10., 1)
        intrvl_long2 = Interval(3., 15., 2)

        intrvlshort1 = Interval(2., 2.5, 3)
        intrvlshort2 = Interval(2., 2.7, 4)
        intrvlshort3 = Interval(2.9, 3.5, 5)

        intrvlslong = IntervalList([intrvl_long2, intrvl_long1])
        intrvlsshort = IntervalList([intrvlshort1, intrvlshort2, intrvlshort3])

        intrvlsfiltered = intrvlslong.filter_against(intrvlsshort,
                                                     predicate=during_inv())
        self.assertEqual(len(intrvlsfiltered.intrvls), 1)
        self.assertEqual(intrvlsfiltered.intrvls[0].__repr__(),
                         intrvl_long1.__repr__())
Пример #2
0
# One interval for every frame whose payload is list of faces in that frame
faces_at_boundaries = IntervalList([
    (frame, frame, facelist)
    for frame, facelist in zip(frames, faces[0].load()))
]).filter_against(
    transitions,
    predicate=overlaps()
).filter(payload_satisfies(length_at_least(1)))

# Get all boundaries where there are faces before and after the boundary
boundaries_that_have_faces = transitions.filter_against(
    faces_at_boundaries, predicate=starts_inv() # Faces at the start of this transition
).filter_against(
    transitions.filter_against(
        faces_at_boundaries, predicate=finishes_inv() # Faces at the end of this transition
    ),
    predicate=equal()
)

# Annotate boundary payloads with the faces at the start/end of each transition
boundaries_starting_faces = boundaries_that_have_faces.merge(
    faces_at_boundaries, predicate = starts_inv(),
    payload_merge_op = payload_second
)
boundaries_ending_faces = boundaries_that_have_faces.merge(
    faces_at_boundaries, predicate = finishes_inv(),
    payload_merge_op = payload_second
)

# Finally, annotate boundary with a payload of the faces that start/end the
Пример #3
0
def compute_shots(microshot_boundaries, faces_scanner, frames, video):
    print('Number of microshots: ', len(microshot_boundaries))
    faces_per_frame = IntervalList([
        (frame, frame, facelist)
        for frame, facelist in zip(frames, faces_scanner)
    ])

    transitions = IntervalList([(boundary - 1, boundary, 0)
                                for boundary in microshot_boundaries])

    faces_at_boundaries = faces_per_frame.filter_against(
        transitions,
        predicate=overlaps()).filter(payload_satisfies(length_at_least(1)))

    # Get all transitions where there are faces before and after the transition
    # This IntervalList's payload is stil 0
    transitions_with_faces = transitions.filter_against(
        faces_at_boundaries, predicate=starts_inv()).filter_against(
            transitions.filter_against(faces_at_boundaries,
                                       predicate=finishes_inv()),
            predicate=equal())

    # Annotate transitions_with_faces with the list of faces before and after
    #   every transition
    transitions_with_faces_at_start_of_transition = transitions_with_faces.merge(
        faces_at_boundaries,
        predicate=starts_inv(),
        payload_merge_op=payload_second)
    transitions_with_faces_at_end_of_transition = transitions_with_faces.merge(
        faces_at_boundaries,
        predicate=finishes_inv(),
        payload_merge_op=payload_second)
    transitions_with_faces = transitions_with_faces_at_start_of_transition.merge(
        transitions_with_faces_at_end_of_transition,
        predicate=equal(),
        payload_merge_op=lambda starting_faces, ending_faces: {
            'starts': starting_faces,
            'finishes': ending_faces
        })

    # Get all the transitions where the faces at the start and the end are
    # the same
    def face_list_stays_the_same(start_finishes_payload):
        """ Define a scene graph by the face positions at the start and check
        if the face positions at the end satisfy it. """
        graph = {
            'nodes': [{
                'name':
                'face{}'.format(idx),
                'predicates': [
                    position(face.x1,
                             face.y1,
                             face.x2,
                             face.y2,
                             epsilon=POSITION_EPSILON),
                    lambda face: face['score'] > MINIMUM_FACE_PROBABILITY
                ]
            } for idx, face in enumerate(start_finishes_payload['starts'])
                      if face.score > MINIMUM_FACE_PROBABILITY],
            'edges': []
        }
        return scene_graph(graph, exact=True)([{
            'x1': face.x1,
            'y1': face.y1,
            'x2': face.x2,
            'y2': face.y2,
            'score': face.score
        } for face in start_finishes_payload['finishes']])

    bad_transitions = transitions_with_faces.filter(
        payload_satisfies(face_list_stays_the_same))
    print(bad_transitions.size())

    # Finally, compute shot boundaries
    def convert_shot_boundaries_to_shots(shot_boundary_list):
        """
        Helper function to convert an IntervalList of shot boundaries to an
        IntervalList of shots.
        
        shot_boundary_list should have the start and end of the movie as
        boundaries.
        """
        def fold_boundaries_to_shots(acc, frame):
            if acc == []:
                return [frame.copy()]
            top = acc[-1]
            top.end = frame.start - 1
            if top.length() > 0:
                acc.append(frame.copy())
            else:
                top.end = frame.start
            return acc

        return shot_boundary_list.fold_list(fold_boundaries_to_shots, [])

    # Convert microshot boundaries to IntervalList
    shot_boundaries = IntervalList([
        (boundary, boundary, 0)
        for boundary in list(set([0, video.num_frames] + microshot_boundaries))
    ])
    microshots = convert_shot_boundaries_to_shots(shot_boundaries)

    # Filter out short microshots
    short_microshots = microshots.filter_length(
        max_length=math.floor(MINIMUM_SHOT_DURATION * video.fps))
    shots = microshots.set_union(
        short_microshots.map(
            lambda i: (i.start, i.end + 1, i.payload)).coalesce()).coalesce()

    # Remove shots that start with the bad boundaries we found earlier
    bad_shots = shots.filter_against(
        bad_transitions.map(lambda i: (i.start + 1, i.end, i.payload)),
        predicate=starts_inv())
    shot_boundaries = shots.map(lambda i: (i.start, i.start, i.payload))
    shot_boundaries_without_bad_shots = shot_boundaries.minus(bad_shots)
    shots = convert_shot_boundaries_to_shots(shot_boundaries_without_bad_shots)

    return shots