sandrocalzada's picture
Update app.py
446556e
raw
history blame contribute delete
No virus
3.12 kB
import streamlit as st
import face_recognition
import os
import cv2
import insightface
import pickle
from insightface.app import FaceAnalysis
from concurrent.futures import ThreadPoolExecutor
# Initialize your models to None
app = None
swapper = None
data_images = None
# Load pickle file once and keep it in memory
@st.cache_data
def load_data_images():
with open(os.path.join(os.getcwd(), 'data_images.pkl'), 'rb') as file:
return pickle.load(file)
# Lazy initialization of data_images
def get_data_images():
global data_images
if data_images is None:
data_images = load_data_images()
return data_images
# Lazy initialization for models
def prepare_models():
global app, swapper
if app is None:
app = FaceAnalysis(name='buffalo_l')
app.prepare(ctx_id=0, det_size=(640, 640))
if swapper is None:
swapper = insightface.model_zoo.get_model(os.path.join(os.getcwd(), 'inswapper_128.onnx'), download=False)
def face_swapper(image_background, image_customer):
face_customer = app.get(image_customer)[0]
faces = app.get(image_background)
for face in faces:
image_background = swapper.get(image_background, face, face_customer, paste_back=True)
return image_background
def process(image):
prepare_models() # Prepare models only when required
images_background_encoding, images_background_contents = get_data_images()['encodings'], get_data_images()['content']
image_loaded = face_recognition.load_image_file(image)
face_encoding = face_recognition.face_encodings(image_loaded)[0]
face_distances = face_recognition.face_distance(images_background_encoding, face_encoding)
tmp_distance = face_distances[0]
tmp_content = images_background_contents[0]
for face_distance, images_background_content in zip(face_distances[1:], images_background_contents[1:]):
if tmp_distance > face_distance:
tmp_distance = face_distance
tmp_content = images_background_content
output_image = face_swapper(tmp_content, image_loaded)
return output_image
image_output = None
st.title('Change Faces')
option = st.radio('How would you like to upload your image?', ('File', 'WebCam'), horizontal=True)
if option=='File':
uploaded_file = st.file_uploader('Choose your image', type=['jpg', 'png', 'jpeg'])
else:
uploaded_file = st.camera_input("Take a picture")
if uploaded_file is not None:
bytes_data = uploaded_file.getvalue()
if option == 'File':
st.image(uploaded_file)
if st.button('Process'):
with st.spinner('Processing...'):
with ThreadPoolExecutor() as executor:
future = executor.submit(process, uploaded_file)
image_output = future.result()
st.image(image_output)
if image_output is not None:
image_output_to_download = cv2.cvtColor(image_output, cv2.COLOR_BGR2RGB)
_, image_output_to_download = cv2.imencode('.jpg', image_output_to_download)
st.download_button('Download image', image_output_to_download.tobytes(), file_name=f'output_{uploaded_file.name}')