Skip to content
This repository has been archived by the owner on Aug 29, 2023. It is now read-only.

Added output directory selector and colab gdrive mount option #34

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ celerybeat.pid
# Environments
.env
.venv
.idea/
env/
venv/
ENV/
Expand Down
20 changes: 18 additions & 2 deletions app.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from refacer import Refacer
import argparse
import ngrok
import os

parser = argparse.ArgumentParser(description='Refacer')
parser.add_argument("--max_num_faces", type=int, help="Max number of faces on UI", default=5)
Expand All @@ -10,6 +11,7 @@
parser.add_argument("--server_name", type=str, help="Server IP address", default="127.0.0.1")
parser.add_argument("--server_port", type=int, help="Server port", default=7860)
parser.add_argument("--colab_performance", help="Use in colab for better performance", default=False,action="store_true")
parser.add_argument("--output_path", help="Specifies output folder", default="")
parser.add_argument("--ngrok", type=str, help="Use ngrok", default=None)
parser.add_argument("--ngrok_region", type=str, help="ngrok region", default="us")
args = parser.parse_args()
Expand Down Expand Up @@ -51,6 +53,9 @@ def run(*vars):
origins=vars[1:(num_faces+1)]
destinations=vars[(num_faces+1):(num_faces*2)+1]
thresholds=vars[(num_faces*2)+1:]
out=vars[-1]

os.makedirs(out, exist_ok=True)

faces = []
for k in range(0,num_faces):
Expand All @@ -61,11 +66,19 @@ def run(*vars):
'threshold':thresholds[k]
})

return refacer.reface(video_path,faces)
return refacer.reface(video_path,out,faces)

origin = []
destination = []
thresholds = []
output_path = args.output_path if args.output_path else "./out/"
outs = []


def update_out_dir(val):
print(f"New output path is '{val}'")
return val


with gr.Blocks() as demo:
with gr.Row():
Expand All @@ -83,8 +96,11 @@ def run(*vars):
thresholds.append(gr.Slider(label="Threshold",minimum=0.0,maximum=1.0,value=0.2))
with gr.Row():
button=gr.Button("Reface", variant="primary")
with gr.Row():
tb_output_path = gr.Textbox(value=output_path,label="Output path")
tb_output_path.change(fn=update_out_dir, inputs=tb_output_path)

button.click(fn=run,inputs=[video]+origin+destination+thresholds,outputs=[video2])
button.click(fn=run,inputs=[video]+origin+destination+thresholds+[tb_output_path],outputs=[video2])

if args.ngrok is not None:
connect(args.ngrok, args.server_port, {'region': args.ngrok_region, 'authtoken_from_env': False})
Expand Down
176 changes: 117 additions & 59 deletions notebooks/Refacer_colab.ipynb
Original file line number Diff line number Diff line change
@@ -1,65 +1,123 @@
{
"cells": [
{
"attachments": {},
"cell_type": "markdown",
"metadata": {
"id": "ghPlUjrD_xmd"
},
"source": [
"# Refacer\n",
"\n",
"[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/xaviviro/refacer/blob/master/notebooks/Refacer_colab.ipynb)\n",
"\n",
"[Refacer](https://github.com/xaviviro/refacer) is an amazing tool that allows you to create deepfakes with multiple faces, giving you the option to choose which face to replace, all in one click!\n",
"\n",
"If you find Refacer helpful, consider giving it a star on [GitHub](https://github.com/xaviviro/refacer) Your support helps to keep the project going!\n",
"\n",
"Before using this Colab or the Refacer tool, please make sure to read the [Disclaimer](https://github.com/xaviviro/refacer#disclaimer) in the GitHub repository. It's very important to understand the terms of use, and the ethical implications of creating deepfakes.\n",
"\n",
"In this Colab, you'll be able to try out Refacer without needing to install anything on your own machine. Enjoy!\n",
"\n",
"*If you encounter any issues or have any suggestions, feel free to [open an issue](https://github.com/xaviviro/refacer/issues/new) on the GitHub repository.*"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "r-vlpYRr_6W7",
"outputId": "2f2ba046-082f-422c-a391-3d6991276830"
},
"outputs": [],
"source": [
"!pip uninstall numpy -y -q\n",
"!pip install --disable-pip-version-check --root-user-action=ignore ngrok numpy==1.24.3 onnxruntime-gpu gradio insightface==0.7.3 ffmpeg_python opencv_python -q --force\n",
"\n",
"!git clone https://github.com/xaviviro/refacer.git\n",
"%cd refacer\n",
"\n",
"!wget --content-disposition \"https://huggingface.co/deepinsight/inswapper/resolve/main/inswapper_128.onnx\"\n",
"\n",
"!python app.py --share_gradio --colab_performance\n"
]
"cells": [
{
"attachments": {},
"cell_type": "markdown",
"metadata": {
"id": "ghPlUjrD_xmd",
"pycharm": {
"name": "#%% md\n"
}
},
"source": [
"# Refacer\n",
"\n",
"[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/xaviviro/refacer/blob/master/notebooks/Refacer_colab.ipynb)\n",
"\n",
"[Refacer](https://github.com/xaviviro/refacer) is an amazing tool that allows you to create deepfakes with multiple faces, giving you the option to choose which face to replace, all in one click!\n",
"\n",
"If you find Refacer helpful, consider giving it a star on [GitHub](https://github.com/xaviviro/refacer) Your support helps to keep the project going!\n",
"\n",
"Before using this Colab or the Refacer tool, please make sure to read the [Disclaimer](https://github.com/xaviviro/refacer#disclaimer) in the GitHub repository. It's very important to understand the terms of use, and the ethical implications of creating deepfakes.\n",
"\n",
"In this Colab, you'll be able to try out Refacer without needing to install anything on your own machine. Enjoy!\n",
"\n",
"*If you encounter any issues or have any suggestions, feel free to [open an issue](https://github.com/xaviviro/refacer/issues/new) on the GitHub repository.*"
]
},
{
"cell_type": "code",
"execution_count": null,
"outputs": [],
"source": [
"import os\n",
"\n",
"# @markdown ## Mount Google Drive\n",
"mount_path = \"/content/drive\"\n",
"mount_gdrive = True # @param {type:\"boolean\"}\n",
"gdrive_data_path = f\"{mount_path}/MyDrive/AI/refacer\" # @param {type:\"string\"}\n",
"\n",
"if mount_gdrive:\n",
" from google.colab import drive\n",
" drive.mount(mount_path, force_remount=False)\n",
" os.makedirs(gdrive_data_path, exist_ok=True)\n",
"else:\n",
" gdrive_data_path = \"./out\""
],
"metadata": {
"collapsed": false,
"pycharm": {
"name": "#%%\n"
}
],
"metadata": {
"accelerator": "GPU",
}
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"machine_shape": "hm",
"provenance": []
},
"kernelspec": {
"display_name": "Python 3",
"name": "python3"
"base_uri": "https://localhost:8080/"
},
"language_info": {
"name": "python"
"id": "r-vlpYRr_6W7",
"outputId": "2f2ba046-082f-422c-a391-3d6991276830",
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"# @markdown ## Prepare environment\n",
"!pip uninstall numpy -y -q\n",
"!pip install --disable-pip-version-check --root-user-action=ignore ngrok numpy==1.24.3 onnxruntime-gpu gradio insightface==0.7.3 ffmpeg_python opencv_python -q --force"
]
},
{
"cell_type": "code",
"execution_count": null,
"outputs": [],
"source": [
"# @markdown ## Get sources\n",
"!git clone -b out_dir_selector_gdrive https://github.com/adufftpc/refacer.git\n",
"%cd refacer\n",
"\n",
"!wget --content-disposition \"https://huggingface.co/deepinsight/inswapper/resolve/main/inswapper_128.onnx\""
],
"metadata": {
"collapsed": false,
"pycharm": {
"name": "#%%\n"
}
}
},
{
"cell_type": "code",
"execution_count": null,
"outputs": [],
"source": [
"!python app.py --share_gradio --colab_performance --output_path $gdrive_data_path"
],
"metadata": {
"collapsed": false,
"pycharm": {
"name": "#%%\n"
}
}
}
],
"metadata": {
"accelerator": "GPU",
"colab": {
"machine_shape": "hm",
"provenance": []
},
"kernelspec": {
"display_name": "Python 3",
"name": "python3"
},
"nbformat": 4,
"nbformat_minor": 0
}
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
28 changes: 24 additions & 4 deletions refacer.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,16 +116,35 @@ def prepare_faces(self, faces):
self.replacement_faces.append((feat_original,_faces[0],face_threshold))

def __convert_video(self,video_path,output_video_path):
def get_next_filename(path, suffix=""):
fname, ext = os.path.splitext(path)
if suffix:
suffix = f"_{suffix}"
fname += f"_%03d{suffix}.mp4"

i = 1
while os.path.exists(fname % i):
i = i * 2

left, right = (i // 2, i)
while left + 1 < right:
mid = (left + right) // 2 # interval midpoint
left, right = (mid, right) if os.path.exists(fname % mid) else (left, mid)

return fname % right

if self.video_has_audio:
print("Merging audio with the refaced video...")
new_path = output_video_path + str(random.randint(0,999)) + "_c.mp4"
new_path = get_next_filename(output_video_path, "c")
#stream = ffmpeg.input(output_video_path)
in1 = ffmpeg.input(output_video_path)
in2 = ffmpeg.input(video_path)
out = ffmpeg.output(in1.video, in2.audio, new_path,video_bitrate=self.ffmpeg_video_bitrate,vcodec=self.ffmpeg_video_encoder)
out.run(overwrite_output=True,quiet=True)
os.remove(output_video_path)
else:
new_path = output_video_path
new_path = get_next_filename(output_video_path)
os.rename(output_video_path, new_path)
print("The video doesn't have audio, so post-processing is not necessary")

print(f"The process has finished.\nThe refaced video can be found at {os.path.abspath(new_path)}")
Expand Down Expand Up @@ -173,9 +192,10 @@ def __check_video_has_audio(self,video_path):
if audio_stream is not None:
self.video_has_audio = True

def reface(self, video_path, faces):
def reface(self, video_path, out_dir, faces):
self.__check_video_has_audio(video_path)
output_video_path = os.path.join('out',Path(video_path).name)

output_video_path = os.path.join(out_dir,Path(video_path).name)
self.prepare_faces(faces)

cap = cv2.VideoCapture(video_path)
Expand Down