| import os |
| import urllib.request |
| from flask import Flask, request, send_file, render_template_string |
| from PIL import Image |
| import numpy as np |
| import onnxruntime as ort |
| import cv2 |
| import uuid |
|
|
| |
| MODEL_URL = "https://huggingface.co/thebiglaskowski/inswapper_128.onnx/resolve/main/inswapper_128.onnx" |
| MODEL_PATH = "inswapper_128.onnx" |
| UPLOAD_FOLDER = "uploads" |
| RESULT_FOLDER = "results" |
|
|
| |
| if not os.path.exists(MODEL_PATH): |
| print("Downloading model...") |
| urllib.request.urlretrieve(MODEL_URL, MODEL_PATH) |
| print("Download complete.") |
|
|
| |
| os.makedirs(UPLOAD_FOLDER, exist_ok=True) |
| os.makedirs(RESULT_FOLDER, exist_ok=True) |
|
|
| |
| session = ort.InferenceSession(MODEL_PATH, providers=["CPUExecutionProvider"]) |
|
|
| app = Flask(__name__) |
|
|
| |
| def preprocess_image(image_path): |
| image = cv2.imread(image_path) |
| image = cv2.resize(image, (128, 128)) |
| image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) |
| image = image.astype(np.float32) / 255.0 |
| image = np.transpose(image, (2, 0, 1)) |
| image = np.expand_dims(image, axis=0) |
| return image |
|
|
| |
| def postprocess_image(output): |
| output = output.squeeze(0) |
| output = np.transpose(output, (1, 2, 0)) |
| output = (output * 255.0).clip(0, 255).astype(np.uint8) |
| return output |
|
|
| HTML_PAGE = """ |
| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>Real-Time Face Swap</title> |
| <style> |
| body { font-family: Arial; text-align: center; padding: 20px; background: #f9f9f9; } |
| input[type=file] { margin: 10px; } |
| img { max-width: 300px; margin: 10px; border-radius: 8px; } |
| button { padding: 10px 20px; font-size: 16px; cursor: pointer; margin-top: 10px; } |
| </style> |
| </head> |
| <body> |
| <h1>Real-Time Face Swap</h1> |
| <form id="uploadForm"> |
| <label>Source Image:</label><br> |
| <input type="file" name="source" id="source" accept="image/*" required><br> |
| <label>Target Image:</label><br> |
| <input type="file" name="target" id="target" accept="image/*" required><br> |
| <button type="submit">Swap Faces</button> |
| </form> |
| <div id="result"></div> |
| |
| <script> |
| const form = document.getElementById('uploadForm'); |
| const resultDiv = document.getElementById('result'); |
| |
| form.addEventListener('submit', async function(e) { |
| e.preventDefault(); |
| const formData = new FormData(); |
| formData.append("source", document.getElementById("source").files[0]); |
| formData.append("target", document.getElementById("target").files[0]); |
| |
| resultDiv.innerHTML = "<p>Processing...</p>"; |
| |
| const response = await fetch("/swap", { |
| method: "POST", |
| body: formData |
| }); |
| |
| if (!response.ok) { |
| resultDiv.innerHTML = "<p>Error: " + (await response.text()) + "</p>"; |
| return; |
| } |
| |
| const blob = await response.blob(); |
| const url = URL.createObjectURL(blob); |
| resultDiv.innerHTML = `<h3>Result:</h3><img src="${url}" alt="Swapped Image">`; |
| }); |
| </script> |
| </body> |
| </html> |
| """ |
|
|
| @app.route('/') |
| def index(): |
| return render_template_string(HTML_PAGE) |
|
|
| @app.route('/swap', methods=['POST']) |
| def swap(): |
| if 'source' not in request.files or 'target' not in request.files: |
| return {"error": "Please upload both source and target images."}, 400 |
|
|
| source_file = request.files['source'] |
| target_file = request.files['target'] |
| source_path = os.path.join(UPLOAD_FOLDER, f"src_{uuid.uuid4().hex}.jpg") |
| target_path = os.path.join(UPLOAD_FOLDER, f"tgt_{uuid.uuid4().hex}.jpg") |
| source_file.save(source_path) |
| target_file.save(target_path) |
|
|
| src_input = preprocess_image(source_path) |
| tgt_input = preprocess_image(target_path) |
|
|
| try: |
| output = session.run(None, {"src": src_input, "tgt": tgt_input}) |
| except Exception as e: |
| return {"error": str(e)}, 500 |
|
|
| result = postprocess_image(output[0]) |
| result_path = os.path.join(RESULT_FOLDER, f"result_{uuid.uuid4().hex}.jpg") |
| Image.fromarray(result).save(result_path) |
| return send_file(result_path, mimetype='image/jpeg') |
|
|
| if __name__ == '__main__': |
| app.run(host='0.0.0.0', port=7860, debug=False) |