Skip to content

Commit

Permalink
frame-range option for convert (deepfakes#90)
Browse files Browse the repository at this point in the history
* extended arguments for convert re deepfakes#85

* forgot to change helptext for extended arguments.

* Added -fr --frame-range argument to convert

accepts a list of frame ranges like `-fr 40-50 90-100`

still writes out frames that havent been converted.

* added --discard-frames argument

--discard-frames discards frames not included in --frame-range instead
of writing them out unchanged.
  • Loading branch information
gdunstone authored Feb 1, 2018
1 parent 7e7cf0b commit 0f8d9db
Showing 1 changed file with 47 additions and 4 deletions.
51 changes: 47 additions & 4 deletions scripts/convert.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import cv2

import re
from pathlib import Path
from lib.cli import DirectoryProcessor, FullPaths
from lib.utils import BackgroundGenerator
Expand All @@ -17,7 +17,7 @@ def create_parser(self, subparser, command, description):
epilog="Questions and feedback: \
https://github.com/deepfakes/faceswap-playground"
)

def add_optional_arguments(self, parser):
parser.add_argument('-m', '--model-dir',
action=FullPaths,
Expand All @@ -38,6 +38,20 @@ def add_optional_arguments(self, parser):
default="Masked",
help="Converter to use.")

parser.add_argument('-fr', '--frame-ranges',
nargs="+",
type=str,
help="""frame ranges to apply transfer to. eg for frames 10 to 50 and 90 to 100 use --frame-ranges 10-50 90-100.
Files must have the framenumber as the last number in the name!"""
)

parser.add_argument('-d', '--discard-frames',
action="store_true",
dest="discard_frames",
default=False,
help="when use with --frame-ranges discards frames that are not processed instead of writing them out unchanged."
)

parser.add_argument('-b', '--blur-size',
type=int,
default=2,
Expand Down Expand Up @@ -86,6 +100,7 @@ def process(self):
if not model.load(self.arguments.swap_model):
print('Model Not Found! A valid model must be provided to continue!')
exit(1)

converter = PluginLoader.get_converter(conv_name)(model.converter(False),
blur_size=self.arguments.blur_size,
seamless_clone=self.arguments.seamless_clone,
Expand All @@ -96,16 +111,44 @@ def process(self):
)

batch = BackgroundGenerator(self.prepare_images(), 1)

# frame ranges stuff...
self.frame_ranges = None
# split out the frame ranges and parse out "min" and "max" values
minmax = {
"min": 0, # never any frames less than 0
"max": float("inf")
}
if self.arguments.frame_ranges:
self.frame_ranges = [tuple(map(lambda q: minmax[q] if q in minmax.keys() else int(q), v.split("-"))) for v in self.arguments.frame_ranges]

# last number regex. I know regex is hacky, but its reliablyhacky(tm).
self.imageidxre = re.compile(r'(\d+)(?!.*\d)')

for item in batch.iterator():
self.convert(converter, item)

def convert(self, converter, item):
try:
(filename, image, faces) = item
for idx, face in faces:
image = converter.patch_image(image, face)
skip = False
try:
if self.frame_ranges is not None:
# grab the index with last number regex
idx = int(self.imageidxre.findall(filename)[0])
# only skip if the current index is not between any of the frame ranges.
skip = not any(map(lambda b: b[0]<=idx<=b[1], self.frame_ranges))
except:
# if we error, dont skip
skip = False

if not skip: # process as normal
for idx, face in faces:
image = converter.patch_image(image, face)

output_file = self.output_dir / Path(filename).name
if self.arguments.discard_frames and skip:
return
cv2.imwrite(str(output_file), image)
except Exception as e:
print('Failed to convert image: {}. Reason: {}'.format(filename, e))
Expand Down

0 comments on commit 0f8d9db

Please sign in to comment.