def extract_faces(input_path: Path, output_path: Path, config_path: Path,
                  process_images: bool, extract_mask: bool, step_mod: int):
    assert input_path.exists(), f"No such path: {input_path}"
    assert config_path.exists(), f"No such config file: {config_path}"

    if not output_path.exists():
        logging.info(f"Creating output dir: {output_path}")
        output_path.mkdir()

    with open(str(config_path), 'r') as ymlfile:
        cfg = yaml.load(ymlfile, yaml.SafeLoader)

    face_detector = FaceDetector(cfg)
    frame_count = 0

    if process_images:
        # collected all image paths
        img_paths = image_processing.get_imgs_paths(input_path, as_str=False)

        logging.info("Running Face Extraction over images")
        # iterate over all collected image paths
        for img_path in tqdm(img_paths):
            frame_count += 1
            img = cv2.imread(str(img_path))
            if extract_mask:
                face_mask_fun(img, frame_count, face_detector,
                              output_path / f"{img_path.stem}.jpg")
            else:
                frame_extract_fun(img, frame_count, face_detector, output_path,
                                  step_mod)
    # process video
    else:
        # get a valid file from given directory
        if input_path.is_dir():
            video_files = image_processing.get_imgs_paths(input_path,
                                                          img_types=('*.gif',
                                                                     '*.webm',
                                                                     '*.mp4'),
                                                          as_str=True)
            if not video_files:
                logging.error(f"No valid video files in: {input_path}")
                sys.exit(1)
            # for now just pick first one
            input_path = Path(video_files[0])

        logging.info("Running Face Extraction over video")

        video_utils.process_video(
            str(input_path), lambda frame, frame_count: frame_extract_fun(
                frame, frame_count, face_detector, output_path, step_mod))
Esempio n. 2
0
def main(_=None):
    parser = argparse.ArgumentParser(
        description='In-place Image pre-process via ImageMagick')
    parser.add_argument('-i',
                        '--inp',
                        required=True,
                        help="input folder containing the images")

    # Parse args
    args = parser.parse_args()
    input_dir = Path(args.inp)

    image_paths = get_imgs_paths(input_dir,
                                 img_types=('*.jpg', '*.jpeg', '*.png',
                                            '*.webp'))

    for i, p in enumerate(image_paths):
        command = f'magick mogrify -resize 1600^> "{p}"'  # -format png
        subprocess.call(command, shell=True)

        img = Image.open(p)
        converter = ImageEnhance.Color(img)
        edited_img = converter.enhance(1.3)
        #edited_img = ImageEnhance.Contrast(edited_img).enhance(2)
        edited_img.save(p)
def main(_=None):
    parser = argparse.ArgumentParser(description='Video Mosaic via FFMPEG')
    parser.add_argument('-i',
                        '--inp',
                        required=True,
                        help="input folder containing the videos")
    parser.add_argument('-o', '--out', required=True, help="output path")
    parser.add_argument('--width',
                        required=True,
                        help="width of a single video cell")
    parser.add_argument('--height',
                        required=True,
                        help="height of a single video cell")
    parser.add_argument('-r',
                        '--rows',
                        required=True,
                        help="number of rows in the mosaic")
    parser.add_argument('-c',
                        '--cols',
                        required=True,
                        help="number of columns in the mosaic")

    # Parse args
    args = parser.parse_args()
    input_dir = Path(args.inp)
    width = int(args.width)
    height = int(args.height)
    nb_rows = int(args.rows)
    nb_cols = int(args.cols)

    # Validate mosaic size against number of videos
    video_paths = get_imgs_paths(input_dir,
                                 img_types=('*.mp4',
                                            '*.mkv'))[:(nb_rows * nb_cols)]
    nb_videos = len(video_paths)
    assert (nb_cols * nb_rows) <= nb_videos

    # Generate commands parts
    input_line = " ".join([f"-i {path}" for path in video_paths])
    entries_line = "; ".join([
        f"[{i}:v] setpts=PTS-STARTPTS, scale={width}x{height} [vid{i}]"
        for i in range(nb_videos)
    ])
    pos_line = "; ".join([
        f"[tmp{nb_cols*row+col}][vid{nb_cols*row+col}] "
        f"overlay=shortest=1:x={width*col}:y={width*row} [tmp{nb_cols*row+col+1}]"
        for col in range(nb_cols) for row in range(nb_rows)
    ])[:-7]
    pos_line = "[base]" + pos_line[6:]

    # Run command
    command = f'ffmpeg '\
              f'{input_line} '\
              f'-filter_complex "nullsrc=size={nb_cols*width}x{nb_rows*height} [base]; '\
              f'{entries_line}; '\
              f'{pos_line}" '\
              f'-c:v libx264 {args.out}'

    subprocess.call(command, shell=True)
Esempio n. 4
0
def main(_=None):
    parser = argparse.ArgumentParser(
        description='Image Montage via ImageMagick')
    parser.add_argument('-i',
                        '--inp',
                        required=True,
                        help="input folder containing the images")
    parser.add_argument('-o', '--out', required=True, help="output path")
    parser.add_argument('-r',
                        '--rows',
                        default=0,
                        help="number of rows in the montage")
    parser.add_argument('-c',
                        '--cols',
                        default=0,
                        help="number of columns in the montage")
    parser.add_argument('--width', help="width of a single image")
    parser.add_argument('--height', help="height of a single image")

    # Parse args
    args = parser.parse_args()
    input_dir = Path(args.inp)
    nb_rows = int(args.rows)
    nb_cols = int(args.cols)
    width = int(args.width) if args.width else (
        int(args.height) if args.height else None)
    height = int(args.height) if args.height else (width if width else None)

    # Validate mosaic size against number of videos
    image_paths = get_imgs_paths(input_dir)
    nb_images = len(image_paths)
    assert (nb_cols * nb_rows) <= nb_images

    if nb_cols == 0 and nb_rows == 0:
        nb_cols = nb_rows = int(math.sqrt(nb_images))
    else:
        if nb_cols == 0:
            nb_cols = int(nb_images / nb_rows)
        if nb_rows == 0:
            nb_rows = int(nb_images / nb_cols)

    image_paths = image_paths[:(nb_cols * nb_rows)]

    # Generate commands parts
    input_line = " ".join([f"{path}" for path in image_paths])

    geometry = f'-geometry {width}x{height}+0+0 ' if width else ''

    # Run command
    command = f'magick montage '\
              f'{input_line} '\
              f'-tile {nb_cols}x{nb_rows} '\
              f'{geometry}' \
              f'{args.out}'

    subprocess.call(command, shell=True)
def main(_=None):
    parser = argparse.ArgumentParser(description='Video Conversion via FFMPEG')
    parser.add_argument('-i', '--inp', required=True, help="input path")
    parser.add_argument('-o', '--out', required=True, help="output path")

    # Parse args
    args = parser.parse_args()
    input_dir = Path(args.inp)

    image_paths = get_imgs_paths(input_dir)

    # Generate commands parts
    input_line = " ".join([f"{path}" for path in image_paths])

    # Run command
    command = f'magick convert ' \
              f'{input_line} ' \
              f'-flatten ' \
              f'{args.out}'

    subprocess.call(command, shell=True)
Esempio n. 6
0
def main(_=None):
    logging.getLogger().setLevel(logging.INFO)

    parser = argparse.ArgumentParser(description='Face-swap. Extract Faces')

    parser.add_argument('-i',
                        metavar='input_path',
                        dest='input_path',
                        required=True)
    parser.add_argument('-o',
                        metavar='output_path',
                        dest='output_path',
                        required=True)
    parser.add_argument('-c',
                        metavar='config_path',
                        dest='config_path',
                        default=CONFIG_PATH)
    parser.add_argument('-v', dest='verbose', action='store_true')
    parser.set_defaults(verbose=False)
    parser.add_argument('--process_images',
                        dest='process_images',
                        action='store_true')
    parser.set_defaults(process_images=False)
    parser.add_argument(
        '-s',
        metavar='step_mod',
        dest='step_mod',
        default=1,
        help="Save only face for frame where frame_num%step_mod == 0")

    args = parser.parse_args()
    input_path = Path(args.input_path)
    output_path = Path(args.output_path)
    process_images = args.process_images
    config_path = Path(args.config_path)
    step_mod = int(args.step_mod)
    if args.verbose:
        logging.getLogger().setLevel(logging.DEBUG)

    if not input_path.exists():
        logging.info("No such path: {}".format(input_path))
        sys.exit(1)
    if not output_path.exists():
        logging.info("Creating output dir: {}".format(output_path))
        output_path.mkdir()
    if not config_path.exists():
        logging.info("No such config file: {}".format(config_path))
        sys.exit(1)

    with open(str(config_path), 'r') as ymlfile:
        cfg = yaml.load(ymlfile)

    face_detector = FaceDetector(cfg)
    frame_count = 0

    if process_images:
        # collected all image paths
        img_paths = image_processing.get_imgs_paths(input_path, as_str=False)

        logging.info("Running Face Extraction over images")
        # iterate over all collected image paths
        for img_path in tqdm(img_paths):
            frame_count += 1
            img = cv2.imread(str(img_path))
            frame_extract_fun(img, frame_count, face_detector, output_path,
                              step_mod)
    # process video
    else:
        # get a valid file from given directory
        if input_path.is_dir():
            video_files = image_processing.get_imgs_paths(input_path,
                                                          img_types=('*.gif',
                                                                     '*.webm',
                                                                     '*.mp4'),
                                                          as_str=True)
            if not video_files:
                logging.error("No valid video files in: {}".format(input_path))
                sys.exit(1)
            # for now just pick first one
            input_path = Path(video_files[0])

        logging.info("Running Face Extraction over video")

        video_utils.process_video(
            str(input_path), lambda frame, frame_count: frame_extract_fun(
                frame, frame_count, face_detector, output_path, step_mod))
def main(_=None):
    logging.getLogger().setLevel(logging.INFO)

    parser = argparse.ArgumentParser(
        description='Deep-Faceswap. Generative based method')

    parser.add_argument('-i',
                        metavar='input_path',
                        dest='input_path',
                        required=True)
    parser.add_argument('-o',
                        metavar='output_path',
                        dest='output_path',
                        required=True)
    parser.add_argument('--process_images',
                        dest='process_images',
                        action='store_true')
    parser.set_defaults(process_images=False)
    # sampling params
    parser.add_argument('-square',
                        dest='force_square_sample',
                        action='store_true')
    parser.set_defaults(force_square_sample=False)
    parser.add_argument('-w', dest='nb_width_cells', default=10)
    parser.add_argument('-f', dest='sampling_size_factor', default=1 / 5)
    parser.add_argument('-v', dest='verbose', action='store_true')
    parser.set_defaults(verbose=False)

    args = parser.parse_args()
    input_path = Path(args.input_path)
    output_path = Path(args.output_path)
    process_images = args.process_images
    force_square_sample = args.force_square_sample
    nb_width_cells = int(args.nb_width_cells)
    sampling_size_factor = float(args.sampling_size_factor)

    if args.verbose:
        logging.getLogger().setLevel(logging.DEBUG)

    if nb_width_cells < 3:
        logging.error("Need grid width higher than 2. Exiting")
        sys.exit(1)

    # process directly a video
    if not process_images:
        logging.info("Running selective sampling over video")
        try:
            frame_edit_fun = lambda x: selective_sampling(
                x, nb_width_cells, sampling_size_factor, force_square_sample)
            convert_video(str(input_path), str(output_path), frame_edit_fun)
        except Exception as e:
            logging.error(e)
            raise
    # or process a list of images
    else:
        # collected all image paths
        img_paths = image_processing.get_imgs_paths(input_path, as_str=False)

        # iterate over all collected image paths
        logging.info("Running selective sampling over images")
        for img_path in tqdm(img_paths):
            from_filename = img_path.name
            res_path = str(
                output_path /
                'sampled_{}.png'.format(from_filename.split('.')[0]))
            try:
                from_img = cv2.imread(str(input_path / from_filename))
                results = selective_sampling(from_img, nb_width_cells,
                                             sampling_size_factor,
                                             force_square_sample)
                cv2.imwrite(res_path, results)
            except Exception as e:
                logging.error(e)
                raise