1
0
Fork 0
mirror of https://github.com/deepfakes/faceswap synced 2025-06-08 03:26:47 -04:00
faceswap/scripts/extract.py
torzdf e76ab16bfe
Effmpeg preview, MTCNN Extractor. HiRes model fixes (#458)
* Add preview functionality to effmpeg.  (#435)

* Add preview functionality to effmpeg.

effmpeg tool:
Preview for actions that have a video output now available.
Preview does not work when muxing audio.

* Model json unicode fix1 (#443)

* fixed Windows 10 path error while loading weights

* - fixed TypeError: the JSON object must be str, not 'bytes' with OriginalHighRes Model

* MTCNN Extractor and Extraction refactor (#453)

* implement mtcnn extractor

* mtcnn refactor and vram management changes

* cli arguments update for mtcnn/dlib split

* Add mtcnn models to gitignore

* Change multiprocessing on extract

* GUI changes to handle nargs defaults

* Early exit bugfix (#455)

* Fix extract early termination bug

* Fix extract early exit bug

* Multi face detection bugfix (#456)

* Multi face extraction fix

* Original high res cleanup 1 (#457)

* slight model re-factoring
  - removed excess threading code
  - added random kernel initialization to dense layer

* Slight OriginalHighRes re-factoring an code cleanup
2018-07-03 10:42:58 +02:00

133 lines
5 KiB
Python

#!/usr/bin python3
""" The script to run the extract process of faceswap """
import os
import sys
from pathlib import Path
from tqdm import tqdm
from lib.gpu_stats import GPUStats
from lib.multithreading import pool_process
from scripts.fsmedia import Alignments, Faces, Images, Utils
tqdm.monitor_interval = 0 # workaround for TqdmSynchronisationWarning
class Extract(object):
""" The extract process. """
def __init__(self, arguments):
self.args = arguments
self.images = Images(self.args)
self.faces = Faces(self.args)
self.alignments = Alignments(self.args)
self.output_dir = self.faces.output_dir
self.export_face = True
def process(self):
""" Perform the extraction process """
print('Starting, this may take a while...')
Utils.set_verbosity(self.args.verbose)
if self.args.multiprocess and GPUStats().device_count == 0:
# TODO Checking that there is no available GPU is not
# necessarily an indicator of whether the user is actually
# using the CPU. Maybe look to implement further checks on
# dlib/tensorflow compilations
self.extract_multi_process()
else:
self.extract_single_process()
self.alignments.write_alignments(self.faces.faces_detected)
images, faces = Utils.finalize(self.images.images_found,
self.faces.num_faces_detected,
self.faces.verify_output)
self.images.images_found = images
self.faces.num_faces_detected = faces
def extract_single_process(self):
""" Run extraction in a single process """
for filename in tqdm(self.images.input_images, file=sys.stdout):
filename, faces = self.process_single_image(filename)
self.faces.faces_detected[os.path.basename(filename)] = faces
def extract_multi_process(self):
""" Run the extraction on the correct number of processes """
for filename, faces in tqdm(
pool_process(
self.process_single_image,
self.images.input_images),
total=self.images.images_found,
file=sys.stdout):
self.faces.num_faces_detected += 1
self.faces.faces_detected[os.path.basename(filename)] = faces
def process_single_image(self, filename):
""" Detect faces in an image. Rotate the image the specified amount
until at least one face is found, or until image rotations are
depleted.
Once at least one face has been detected, pass to
process_single_face to process the individual faces """
retval = filename, list()
try:
image = Utils.cv2_read_write('read', filename)
for angle in self.images.rotation_angles:
currentimage = Utils.rotate_image_by_angle(image, angle)
faces = self.faces.get_faces(currentimage, angle)
process_faces = [(idx, face) for idx, face in faces]
if process_faces and angle != 0 and self.args.verbose:
print("found face(s) by rotating image "
"{} degrees".format(angle))
if process_faces:
break
final_faces = [self.process_single_face(idx,
face,
filename,
currentimage)
for idx, face in process_faces]
retval = filename, final_faces
except Exception as err:
if self.args.verbose:
print("Failed to extract from image: "
"{}. Reason: {}".format(filename, err))
return retval
def process_single_face(self, idx, face, filename, image):
""" Perform processing on found faces """
output_file = self.output_dir / Path(
filename).stem if self.export_face else None
self.faces.draw_landmarks_on_face(face, image)
resized_face, t_mat = self.faces.extractor.extract(
image,
face,
256,
self.faces.align_eyes)
blurry_file = self.faces.detect_blurry_faces(face,
t_mat,
resized_face,
filename)
output_file = blurry_file if blurry_file else output_file
if self.export_face:
filename = "{}_{}{}".format(str(output_file),
str(idx),
Path(filename).suffix)
Utils.cv2_read_write('write', filename, resized_face)
return {"r": face.r,
"x": face.x,
"w": face.w,
"y": face.y,
"h": face.h,
"landmarksXY": face.landmarks_as_xy()}