Merge branch 'next' into issue_511_opencv_unicode_paths

# Conflicts:
#	roop/processors/frame/face_enhancer.py
#	roop/processors/frame/face_swapper.py
This commit is contained in:
Pozitronik 2023-06-20 15:52:30 +04:00
commit 607719f255
11 changed files with 48 additions and 29 deletions

View File

@ -56,6 +56,7 @@ options:
execution provider
--execution-threads EXECUTION_THREADS
number of execution threads
-v, --version show program's version number and exit
```
Looking for a CLI mode? Using the -s/--source argument will make the program in cli mode.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

@ -18,6 +18,7 @@ import onnxruntime
import tensorflow
import roop.globals
import roop.metadata
import roop.ui as ui
from roop.predicter import predict_image, predict_video
from roop.processors.frame.core import get_frame_processors_modules
@ -32,28 +33,29 @@ warnings.filterwarnings('ignore', category=UserWarning, module='torchvision')
def parse_args() -> None:
signal.signal(signal.SIGINT, lambda signal_number, frame: destroy())
parser = argparse.ArgumentParser()
parser.add_argument('-s', '--source', help='select an source image', dest='source_path')
parser.add_argument('-t', '--target', help='select an target image or video', dest='target_path')
parser.add_argument('-o', '--output', help='select output file or directory', dest='output_path')
parser.add_argument('--frame-processor', help='pipeline of frame processors', dest='frame_processor', default=['face_swapper'], choices=['face_swapper', 'face_enhancer'], nargs='+')
parser.add_argument('--keep-fps', help='keep original fps', dest='keep_fps', action='store_true', default=False)
parser.add_argument('--keep-audio', help='keep original audio', dest='keep_audio', action='store_true', default=True)
parser.add_argument('--keep-frames', help='keep temporary frames', dest='keep_frames', action='store_true', default=False)
parser.add_argument('--many-faces', help='process every face', dest='many_faces', action='store_true', default=False)
parser.add_argument('--video-encoder', help='adjust output video encoder', dest='video_encoder', default='libx264', choices=['libx264', 'libx265', 'libvpx-vp9'])
parser.add_argument('--video-quality', help='adjust output video quality', dest='video_quality', type=int, default=18)
parser.add_argument('--max-memory', help='maximum amount of RAM in GB', dest='max_memory', type=int, default=suggest_max_memory())
parser.add_argument('--execution-provider', help='execution provider', dest='execution_provider', default=['cpu'], choices=suggest_execution_providers(), nargs='+')
parser.add_argument('--execution-threads', help='number of execution threads', dest='execution_threads', type=int, default=suggest_execution_threads())
program = argparse.ArgumentParser()
program.add_argument('-s', '--source', help='select an source image', dest='source_path')
program.add_argument('-t', '--target', help='select an target image or video', dest='target_path')
program.add_argument('-o', '--output', help='select output file or directory', dest='output_path')
program.add_argument('--frame-processor', help='pipeline of frame processors', dest='frame_processor', default=['face_swapper'], choices=['face_swapper', 'face_enhancer'], nargs='+')
program.add_argument('--keep-fps', help='keep original fps', dest='keep_fps', action='store_true', default=False)
program.add_argument('--keep-audio', help='keep original audio', dest='keep_audio', action='store_true', default=True)
program.add_argument('--keep-frames', help='keep temporary frames', dest='keep_frames', action='store_true', default=False)
program.add_argument('--many-faces', help='process every face', dest='many_faces', action='store_true', default=False)
program.add_argument('--video-encoder', help='adjust output video encoder', dest='video_encoder', default='libx264', choices=['libx264', 'libx265', 'libvpx-vp9'])
program.add_argument('--video-quality', help='adjust output video quality', dest='video_quality', type=int, default=18, choices=range(52), metavar='[0-51]')
program.add_argument('--max-memory', help='maximum amount of RAM in GB', dest='max_memory', type=int, default=suggest_max_memory())
program.add_argument('--execution-provider', help='execution provider', dest='execution_provider', default=['cpu'], choices=suggest_execution_providers(), nargs='+')
program.add_argument('--execution-threads', help='number of execution threads', dest='execution_threads', type=int, default=suggest_execution_threads())
program.add_argument('-v', '--version', action='version', version=f'{roop.metadata.name} {roop.metadata.version}')
# register deprecated args
parser.add_argument('-f', '--face', help=argparse.SUPPRESS, dest='source_path_deprecated')
parser.add_argument('--cpu-cores', help=argparse.SUPPRESS, dest='cpu_cores_deprecated', type=int)
parser.add_argument('--gpu-vendor', help=argparse.SUPPRESS, dest='gpu_vendor_deprecated')
parser.add_argument('--gpu-threads', help=argparse.SUPPRESS, dest='gpu_threads_deprecated', type=int)
program.add_argument('-f', '--face', help=argparse.SUPPRESS, dest='source_path_deprecated')
program.add_argument('--cpu-cores', help=argparse.SUPPRESS, dest='cpu_cores_deprecated', type=int)
program.add_argument('--gpu-vendor', help=argparse.SUPPRESS, dest='gpu_vendor_deprecated')
program.add_argument('--gpu-threads', help=argparse.SUPPRESS, dest='gpu_threads_deprecated', type=int)
args = parser.parse_args()
args = program.parse_args()
roop.globals.source_path = args.source_path
roop.globals.target_path = args.target_path

View File

@ -1,6 +1,8 @@
from typing import Any
import insightface
import roop.globals
from roop.typing import Frame
FACE_ANALYSER = None
@ -14,7 +16,7 @@ def get_face_analyser() -> Any:
return FACE_ANALYSER
def get_one_face(frame: Any) -> Any:
def get_one_face(frame: Frame) -> Any:
face = get_face_analyser().get(frame)
try:
return min(face, key=lambda x: x.bbox[0])
@ -22,7 +24,7 @@ def get_one_face(frame: Any) -> Any:
return None
def get_many_faces(frame: Any) -> Any:
def get_many_faces(frame: Frame) -> Any:
try:
return get_face_analyser().get(frame)
except IndexError:

2
roop/metadata.py Normal file
View File

@ -0,0 +1,2 @@
name = 'roop'
version = '1.0.0'

View File

@ -2,10 +2,12 @@ import numpy
import opennsfw2
from PIL import Image
from roop.typing import Frame
MAX_PROBABILITY = 0.85
def predict_frame(target_frame: Image) -> bool:
def predict_frame(target_frame: Frame) -> bool:
image = Image.fromarray(target_frame)
image = opennsfw2.preprocess_image(image, opennsfw2.Preprocessing.YAHOO)
model = opennsfw2.make_open_nsfw_model()

View File

@ -6,6 +6,7 @@ import roop.globals
import roop.processors.frame.core
from roop.core import update_status
from roop.face_analyser import get_one_face
from roop.typing import Frame, Face
from roop.utilities import conditional_download, resolve_relative_path, is_image, is_video, read_image, write_image
FACE_ENHANCER = None
@ -38,7 +39,7 @@ def get_face_enhancer() -> Any:
return FACE_ENHANCER
def enhance_face(temp_frame: Any) -> Any:
def enhance_face(temp_frame: Frame) -> Frame:
with THREAD_SEMAPHORE:
_, _, temp_frame = get_face_enhancer().enhance(
temp_frame,
@ -47,7 +48,7 @@ def enhance_face(temp_frame: Any) -> Any:
return temp_frame
def process_frame(source_face: Any, temp_frame: Any) -> Any:
def process_frame(source_face: Face, temp_frame: Frame) -> Frame:
target_face = get_one_face(temp_frame)
if target_face:
temp_frame = enhance_face(temp_frame)

View File

@ -6,6 +6,7 @@ import roop.globals
import roop.processors.frame.core
from roop.core import update_status
from roop.face_analyser import get_one_face, get_many_faces
from roop.typing import Face, Frame
from roop.utilities import conditional_download, resolve_relative_path, is_image, is_video, read_image, write_image
FACE_SWAPPER = None
@ -42,11 +43,11 @@ def get_face_swapper() -> Any:
return FACE_SWAPPER
def swap_face(source_face: Any, target_face: Any, temp_frame: Any) -> Any:
def swap_face(source_face: Face, target_face: Face, temp_frame: Frame) -> Frame:
return get_face_swapper().get(temp_frame, target_face, source_face, paste_back=True)
def process_frame(source_face: Any, temp_frame: Any) -> Any:
def process_frame(source_face: Face, temp_frame: Frame) -> Frame:
if roop.globals.many_faces:
many_faces = get_many_faces(temp_frame)
if many_faces:

7
roop/typing.py Normal file
View File

@ -0,0 +1,7 @@
from typing import Any
from insightface.app.common import Face
import numpy
Face = Face
Frame = numpy.ndarray[Any, Any]

View File

@ -6,6 +6,7 @@ import cv2
from PIL import Image, ImageOps
import roop.globals
import roop.metadata
from roop.face_analyser import get_one_face
from roop.capturer import get_video_frame, get_video_frame_total
from roop.predicter import predict_frame
@ -48,7 +49,7 @@ def create_root(start: Callable[[], None], destroy: Callable[[], None]) -> ctk.C
ctk.set_default_color_theme(resolve_relative_path('ui.json'))
root = ctk.CTk()
root.minsize(ROOT_WIDTH, ROOT_HEIGHT)
root.title('roop')
root.title(f'{roop.metadata.name} {roop.metadata.version}')
root.configure()
root.protocol('WM_DELETE_WINDOW', lambda: destroy())

View File

@ -47,13 +47,13 @@ def detect_fps(target_path: str) -> float:
def extract_frames(target_path: str) -> None:
temp_directory_path = get_temp_directory_path(target_path)
run_ffmpeg(['-i', target_path, '-pix_fmt', 'rgb24', '-sws_flags', '+accurate_rnd+full_chroma_int', '-colorspace', '1', '-color_primaries', '1', '-color_trc', '1', os.path.join(temp_directory_path, '%04d.png')])
run_ffmpeg(['-i', target_path, '-pix_fmt', 'rgb24', os.path.join(temp_directory_path, '%04d.png')])
def create_video(target_path: str, fps: float = 30.0) -> None:
temp_output_path = get_temp_output_path(target_path)
temp_directory_path = get_temp_directory_path(target_path)
run_ffmpeg(['-r', str(fps), '-i', os.path.join(temp_directory_path, '%04d.png'), '-c:v', roop.globals.video_encoder, '-crf', str(roop.globals.video_quality), '-pix_fmt', 'yuv420p', '-y', temp_output_path])
run_ffmpeg(['-r', str(fps), '-i', os.path.join(temp_directory_path, '%04d.png'), '-c:v', roop.globals.video_encoder, '-crf', str(roop.globals.video_quality), '-pix_fmt', 'yuv420p', '-vf', 'colorspace=bt709:iall=bt601-6-625:fast=1', '-y', temp_output_path])
def restore_audio(target_path: str, output_path: str) -> None: