Skip to content

Commit bd18d2e

Browse files
Support swapping multiple faces from a single source image into multiple faces in a target image
1 parent a9558e3 commit bd18d2e

File tree

2 files changed

+26
-15
lines changed

2 files changed

+26
-15
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,3 +164,5 @@ checkpoints
164164
CodeFormer
165165
test_input.json
166166
*.jpg
167+
*.jpeg
168+
*.png

rp_handler.py

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -71,20 +71,16 @@ def get_many_faces(face_analyser,
7171

7272

7373
def swap_face(face_swapper,
74-
face_analyser,
75-
source_img,
74+
source_faces,
7675
target_faces,
7776
source_index,
7877
target_index,
7978
temp_frame):
8079
"""
8180
paste source_face on target image
8281
"""
82+
source_face = source_faces[source_index]
8383
target_face = target_faces[target_index]
84-
source_face = get_one_face(face_analyser, cv2.cvtColor(np.array(source_img[source_index]), cv2.COLOR_RGB2BGR))
85-
if source_face is None:
86-
logger.error('No source face found')
87-
raise Exception('No source face found!')
8884

8985
return face_swapper.get(temp_frame, target_face, source_face, paste_back=True)
9086

@@ -106,34 +102,45 @@ def process(source_img: Union[Image.Image, List],
106102

107103
# detect faces that will be replaced in target_img
108104
target_faces = get_many_faces(face_analyser, target_img)
105+
109106
if target_faces is not None:
110107
temp_frame = copy.deepcopy(target_img)
111108
if isinstance(source_img, list) and len(source_img) == len(target_faces):
112109
logger.info('Replacing the faces in the target image from left to right by order')
113110
for i in range(len(target_faces)):
111+
source_faces = get_many_faces(face_analyser, cv2.cvtColor(np.array(source_img[i]), cv2.COLOR_RGB2BGR))
114112
source_index = i
115113
target_index = i
116114

117115
temp_frame = swap_face(
118116
face_swapper,
119-
face_analyser,
120-
source_img,
117+
source_faces,
121118
target_faces,
122119
source_index,
123120
target_index,
124121
temp_frame
125122
)
126-
else:
123+
elif len(source_img) == 1:
124+
# detect source faces that will be replaced into the target image
125+
source_faces = get_many_faces(face_analyser, cv2.cvtColor(np.array(source_img[0]), cv2.COLOR_RGB2BGR))
126+
127127
if target_index == -1:
128-
logger.info('Replacing all faces in the target image to the face in the source image')
128+
if len(source_faces) > 1 and len(source_faces) != len(target_faces):
129+
logger.error('Number of faces in the source image and target image must match')
130+
raise Exception('Number of faces in the source image and target image must match')
131+
132+
if len(source_faces) == 1:
133+
logger.info('Replacing all faces in target image with the same face from the source image')
134+
else:
135+
print('Replacing all faces in the target image with the faces from the source image')
136+
129137
for i in range(len(target_faces)):
130-
source_index = 0
138+
source_index = 0 if len(source_faces) == 1 else i
131139
target_index = i
132140

133141
temp_frame = swap_face(
134142
face_swapper,
135-
face_analyser,
136-
source_img,
143+
source_faces,
137144
target_faces,
138145
source_index,
139146
target_index,
@@ -145,13 +152,15 @@ def process(source_img: Union[Image.Image, List],
145152

146153
temp_frame = swap_face(
147154
face_swapper,
148-
face_analyser,
149-
source_img,
155+
source_faces,
150156
target_faces,
151157
source_index,
152158
target_index,
153159
temp_frame
154160
)
161+
else:
162+
logger.error('Unsupported face configuration')
163+
raise Exception('Unsupported face configuration')
155164
result = temp_frame
156165
else:
157166
logger.error('No target faces found')

0 commit comments

Comments
 (0)