| from chain_img_processor import ChainImgProcessor, ChainImgPlugin |
| from roop.face_helper import get_one_face, get_many_faces, swap_face |
| import os |
| from roop.utilities import compute_cosine_distance |
|
|
| modname = os.path.basename(__file__)[:-3] |
|
|
| |
| def start(core:ChainImgProcessor): |
| manifest = { |
| "name": "Faceswap", |
| "version": "1.0", |
|
|
| "default_options": { |
| "swap_mode": "selected", |
| "max_distance": 0.65, |
| }, |
| "img_processor": { |
| "faceswap": Faceswap |
| } |
| } |
| return manifest |
|
|
| def start_with_options(core:ChainImgProcessor, manifest:dict): |
| pass |
|
|
|
|
| class Faceswap(ChainImgPlugin): |
|
|
| def init_plugin(self): |
| pass |
|
|
|
|
| def process(self, frame, params:dict): |
| if not "input_face_datas" in params or len(params["input_face_datas"]) < 1: |
| params["face_detected"] = False |
| return frame |
| |
| temp_frame = frame |
| params["face_detected"] = True |
| params["processed_faces"] = [] |
|
|
| if params["swap_mode"] == "first": |
| face = get_one_face(frame) |
| if face is None: |
| params["face_detected"] = False |
| return frame |
| params["processed_faces"].append(face) |
| frame = swap_face(params["input_face_datas"][0], face, frame) |
| return frame |
|
|
| else: |
| faces = get_many_faces(frame) |
| if(len(faces) < 1): |
| params["face_detected"] = False |
| return frame |
| |
| dist_threshold = params["face_distance_threshold"] |
|
|
| if params["swap_mode"] == "all": |
| for sf in params["input_face_datas"]: |
| for face in faces: |
| params["processed_faces"].append(face) |
| temp_frame = swap_face(sf, face, temp_frame) |
| return temp_frame |
| |
| elif params["swap_mode"] == "selected": |
| for i,tf in enumerate(params["target_face_datas"]): |
| for face in faces: |
| if compute_cosine_distance(tf.embedding, face.embedding) <= dist_threshold: |
| temp_frame = swap_face(params["input_face_datas"][i], face, temp_frame) |
| params["processed_faces"].append(face) |
| break |
|
|
| elif params["swap_mode"] == "all_female" or params["swap_mode"] == "all_male": |
| gender = 'F' if params["swap_mode"] == "all_female" else 'M' |
| face_found = False |
| for face in faces: |
| if face.sex == gender: |
| face_found = True |
| if face_found: |
| params["processed_faces"].append(face) |
| temp_frame = swap_face(params["input_face_datas"][0], face, temp_frame) |
| face_found = False |
|
|
| return temp_frame |
|
|