| from typing import List |
|
|
| from facefusion.common_helper import get_first, get_last |
| from facefusion.face_creator import get_static_faces, refill_faces |
| from facefusion.face_helper import calculate_bounding_box_overlap |
| from facefusion.types import Face, FaceTrack, Score, VisionFrame |
|
|
|
|
| def track_faces(vision_frames : List[VisionFrame], score : Score) -> List[Face]: |
| target_index = len(vision_frames) // 2 |
| face_tracks = create_face_tracks(vision_frames, score) |
| temp_faces = [] |
|
|
| for face_track in face_tracks: |
| track_indices = sorted(face_track) |
| track_index_first = get_first(track_indices) |
| track_index_last = get_last(track_indices) |
| track_range = range(track_index_first, track_index_last + 1) |
|
|
| if target_index in track_range: |
| fill_faces = [] |
|
|
| for index in track_range: |
| fill_faces.append(face_track.get(index)) |
|
|
| temp_faces.append(refill_faces(fill_faces)[target_index - track_index_first]) |
|
|
| return temp_faces |
|
|
|
|
| def create_face_tracks(vision_frames : List[VisionFrame], score : Score) -> List[FaceTrack]: |
| face_tracks : List[FaceTrack] = [] |
|
|
| for frame_index, vision_frame in enumerate(vision_frames): |
| for face in get_static_faces([ vision_frame ]): |
| face_track = select_face_track(face_tracks, face, score) |
|
|
| if face_track: |
| face_track[frame_index] = face |
| else: |
| face_tracks.append( |
| { |
| frame_index : face |
| }) |
|
|
| return face_tracks |
|
|
|
|
| def select_face_track(face_tracks : List[FaceTrack], face : Face, score : Score) -> FaceTrack: |
| select_track : FaceTrack = {} |
| select_score = score |
|
|
| for face_track in face_tracks: |
| track_face = face_track.get(get_last(face_track)) |
| track_score = calculate_bounding_box_overlap(face.bounding_box, track_face.bounding_box) |
|
|
| if track_score > select_score: |
| select_score = track_score |
| select_track = face_track |
|
|
| return select_track |
|
|