Spaces:
Runtime error
Runtime error
import os | |
import cv2 | |
import matplotlib.pyplot as plt | |
from face_enhancer import load_face_enhancer_model | |
def validate_image(img): | |
if not os.path.exists(img): | |
raise ValueError(f'Image {img} does not exist') | |
# check if img is a valid image file | |
if not os.path.isfile(img): | |
raise ValueError(f'Image {img} is not a valid image file') | |
# validate it to be jpg jpeg, png formats | |
if not img.lower().endswith(('.jpg', '.jpeg', '.png')): | |
raise ValueError(f'Image {img} is not a valid image file') | |
def cpu_warning(device): | |
if device == "cpu": | |
print("Using CPU for face enhancer. If you have a GPU, you can set device='cuda' to speed up the process. You can also set enhance=False to skip the enhancement.") | |
def swap_n_show(img1_fn, img2_fn, app, swapper, | |
plot_before=False, plot_after=True, enhance=False, enhancer='REAL-ESRGAN 2x',device="cpu"): | |
validate_image(img1_fn) | |
validate_image(img2_fn) | |
img1 = cv2.imread(img1_fn) | |
img2 = cv2.imread(img2_fn) | |
if plot_before: | |
fig, axs = plt.subplots(1, 2, figsize=(10, 5)) | |
axs[0].imshow(img1[:,:,::-1]) | |
axs[0].axis('off') | |
axs[1].imshow(img2[:,:,::-1]) | |
axs[1].axis('off') | |
plt.show() | |
# Do the swap | |
face1 = app.get(img1)[0] | |
face2 = app.get(img2)[0] | |
img1_ = img1.copy() | |
img2_ = img2.copy() | |
if plot_after: | |
img1_ = swapper.get(img1_, face1, face2, paste_back=True) | |
img2_ = swapper.get(img2_, face2, face1, paste_back=True) | |
if enhance: | |
cpu_warning(device) | |
model, model_runner = load_face_enhancer_model(enhancer,device) | |
img1_ = model_runner(img1_, model) | |
img2_ = model_runner(img2_, model) | |
fig, axs = plt.subplots(1, 2, figsize=(10, 5)) | |
axs[0].imshow(img1_[:,:,::-1]) | |
axs[0].axis('off') | |
axs[1].imshow(img2_[:,:,::-1]) | |
axs[1].axis('off') | |
plt.show() | |
return img1_, img2_ | |
def swap_n_show_same_img(img1_fn, | |
app, swapper, | |
plot_before=False, | |
plot_after=True, enhance=False, enhancer='REAL-ESRGAN 2x',device="cpu"): | |
validate_image(img1_fn) | |
img1 = cv2.imread(img1_fn) | |
if plot_before: | |
fig, ax = plt.subplots(1, 1, figsize=(10, 5)) | |
ax.imshow(img1[:,:,::-1]) | |
ax.axis('off') | |
plt.show() | |
# Do the swap | |
faces = app.get(img1) | |
face1, face2 = faces[0], faces[1] | |
img1_ = img1.copy() | |
if plot_after: | |
img1_ = swapper.get(img1_, face1, face2, paste_back=True) | |
img1_ = swapper.get(img1_, face2, face1, paste_back=True) | |
if enhance: | |
cpu_warning(device) | |
model, model_runner = load_face_enhancer_model(enhancer,device) | |
img1_ = model_runner(img1_, model) | |
fig, ax = plt.subplots(1, 1, figsize=(10, 5)) | |
ax.imshow(img1_[:,:,::-1]) | |
ax.axis('off') | |
plt.show() | |
return img1_ | |
def swap_face_single(img1_fn, img2_fn, app, swapper, | |
plot_before=False, plot_after=True, enhance=False, enhancer='REAL-ESRGAN 2x',device="cpu"): | |
validate_image(img1_fn) | |
validate_image(img2_fn) | |
img1 = cv2.imread(img1_fn) | |
img2 = cv2.imread(img2_fn) | |
if plot_before: | |
axs = plt.subplots(1, 2, figsize=(10, 5)) | |
axs[0].imshow(img1[:,:,::-1]) | |
axs[0].axis('off') | |
axs[1].imshow(img2[:,:,::-1]) | |
axs[1].axis('off') | |
plt.show() | |
# Do the swap | |
face1 = app.get(img1)[0] | |
face2 = app.get(img2)[0] | |
img1_ = img1.copy() | |
if plot_after: | |
img1_ = swapper.get(img1_, face1, face2, paste_back=True) | |
if enhance: | |
cpu_warning(device) | |
model, model_runner = load_face_enhancer_model(enhancer,device) | |
img1_ = model_runner(img1_, model) | |
# Save the image | |
output_fn = os.path.join('outputs', os.path.basename(img1_fn)) | |
cv2.imwrite(output_fn, img1_) | |
print(f'Image saved to {output_fn}') | |
return img1_ | |
def fine_face_swap(img1_fn, img2_fn, app, swapper,enhance=False, enhancer='REAL-ESRGAN 2x',device="cpu"): | |
img1 = cv2.imread(img1_fn) | |
facesimg1 = app.get(img1) | |
total_faces_img1 = len(facesimg1) | |
if total_faces_img1 > 1: | |
print(f'{total_faces_img1} faces detected') | |
fig, axs = plt.subplots(1, total_faces_img1, figsize=(12, 5)) | |
for i, face in enumerate(facesimg1): | |
bbox = face['bbox'] | |
bbox = [int(b) for b in bbox] | |
axs[i].imshow(img1[bbox[1]:bbox[3],bbox[0]:bbox[2],::-1]) | |
axs[i].axis('off') | |
axs[i].set_title(f'Face {i+1}') | |
plt.suptitle('Select a face to swap') | |
plt.show() | |
else: | |
print(f'{total_faces_img1} face detected') | |
bbox = facesimg1[0]['bbox'] | |
bbox = [int(b) for b in bbox] | |
plt.imshow(img1[bbox[1]:bbox[3],bbox[0]:bbox[2],::-1]) | |
plt.axis('off') | |
plt.title('Face 1') | |
plt.show() | |
# Select a face from img1 | |
face_idximg1 = int(input(f'Enter face number (1-{total_faces_img1}): ')) | |
if face_idximg1 < 1 or face_idximg1 > total_faces_img1: | |
raise ValueError(f'Invalid face number {face_idximg1}') | |
face = facesimg1[face_idximg1-1] | |
bbox = face['bbox'] | |
bbox = [int(b) for b in bbox] | |
face_img = img1[bbox[1]:bbox[3],bbox[0]:bbox[2],::-1] | |
plt.imshow(face_img) | |
plt.axis('off') | |
plt.title(f'Face {face_idximg1}') | |
plt.suptitle('Selected face') | |
plt.show() | |
img2 = cv2.imread(img2_fn) | |
facesimg2 = app.get(img2) | |
total_faces_img2 = len(facesimg2) | |
if total_faces_img2 > 1: | |
print(f'{total_faces_img2} faces detected') | |
fig, axs = plt.subplots(1, total_faces_img2, figsize=(12, 5)) | |
for i, face in enumerate(facesimg2): | |
bbox = face['bbox'] | |
bbox = [int(b) for b in bbox] | |
axs[i].imshow(img2[bbox[1]:bbox[3],bbox[0]:bbox[2],::-1]) | |
axs[i].axis('off') | |
axs[i].set_title(f'Face {i+1}') | |
plt.suptitle('Select a face to swap') | |
plt.show() | |
else: | |
print(f'{total_faces_img2} face detected') | |
bbox = facesimg2[0]['bbox'] | |
bbox = [int(b) for b in bbox] | |
plt.imshow(img2[bbox[1]:bbox[3],bbox[0]:bbox[2],::-1]) | |
plt.axis('off') | |
plt.title('Face 1') | |
plt.show() | |
# Select a face from img2 | |
face_idximg2 = int(input(f'Enter face number (1-{total_faces_img2}): ')) | |
if face_idximg2 < 1 or face_idximg2 > total_faces_img2: | |
raise ValueError(f'Invalid face number {face_idximg2}') | |
face = facesimg2[face_idximg2-1] | |
bbox = face['bbox'] | |
bbox = [int(b) for b in bbox] | |
face_img = img2[bbox[1]:bbox[3],bbox[0]:bbox[2],::-1] | |
plt.imshow(face_img) | |
plt.axis('off') | |
plt.title(f'Face {face_idximg2}') | |
plt.suptitle('Selected face') | |
plt.show() | |
# source face | |
face1 = app.get(img1)[face_idximg1-1] | |
face2 = app.get(img2)[face_idximg2-1] | |
img1_ = img1.copy() | |
img1_ = swapper.get(img1_, face1, face2, paste_back=True) | |
if enhance: | |
cpu_warning(device) | |
model, model_runner = load_face_enhancer_model(enhancer,device) | |
img1_ = model_runner(img1_, model) | |
# Save the image | |
output_fn = os.path.join('outputs', os.path.basename(img1_fn)) | |
cv2.imwrite(output_fn, img1_) | |
print(f'Image saved to {output_fn}') | |
return img1_ |