              'shift_range': 0,
              'random_flip': 0
          }
  
          zoom = self.trainer.model.IMAGE_SHAPE[0] // 64 if hasattr(self.trainer.model, 'IMAGE_SHAPE') else 1
  
          generator = lib.training_data.TrainingDataGenerator(random_transform_args, 160, zoom)
          batch = generator.minibatchAB(input_images, batch_size, doShuffle=False)
  
          return next(batch)[2]
 
</s> remove         generator = lib.training_data.TrainingDataGenerator(random_transform_args, 160, zoom)
        batch = generator.minibatchAB(input_images, batch_size, doShuffle=False)
 </s> add         generator = TrainingDataGenerator(random_transform_args, 160, zoom)
        batch = generator.minibatchAB(input_images, batch_size,
                                      doShuffle=False) </s> remove         batch = lib.utils.BackgroundGenerator(self.minibatch(images, batchsize, doShuffle), 1)
 </s> add         batch = BackgroundGenerator(self.minibatch(images, batchsize, doShuffle), 1)
 </s> remove     def have_face(self, filename):
        """ return path of images that have faces """
        return os.path.basename(filename) in self.faces_detected

    def get_faces(self, image, rotation=0):
        """ Extract the faces from an image """
        faces_count = 0
        faces = detect_faces(image,
                             self.args.detector,
                             self.args.verbose,
                             rotation=rotation,
                             dlib_buffer=self.args.dlib_buffer,
                             mtcnn_kwargs=self.mtcnn_kwargs)

        for face in faces:
            if self.filter and not self.filter.check(face):
                if self.args.verbose:
                    print("Skipping not recognized face!")
                continue
            yield faces_count, face

            self.num_faces_detected += 1
            faces_count += 1

        if faces_count > 1 and self.args.verbose:
            self.verify_output = True

    def get_faces_alignments(self, filename, image):
        """ Retrieve the face alignments from an image """
        faces_count = 0
        faces = self.faces_detected[os.path.basename(filename)]
        for rawface in faces:
            face = DetectedFace(**rawface)
            # Rotate the image if necessary
            # NB: Rotation of landmarks now occurs at extract stage
            # This is here for legacy alignments
            if face.r != 0:
                image, _ = rotate_image_by_angle(image, face.r)
            face.image = image[face.y: face.y + face.h,
                               face.x: face.x + face.w]
            if self.filter and not self.filter.check(face):
                if self.args.verbose:
                    print("Skipping not recognized face!")
                continue
 </s> add class Images():
    """ Holds the full frames/images """
    def __init__(self, arguments):
        self.args = arguments
        self.input_images = self.get_input_images()
        self.images_found = len(self.input_images) </s> remove         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
 </s> add         if self.plugins.is_parallel:
            self.plugins.launch_aligner()
            self.plugins.launch_detector()

        if not self.plugins.is_parallel:
            self.run_detection(to_process)
            self.plugins.launch_aligner()

        for faces in tqdm(self.plugins.detect_faces(extract_pass="align"),
                          total=to_process,
                          file=sys.stdout,
                          desc="Extracting faces"):

            exception = faces.get("exception", False)
            if exception:
                break
            filename = faces["filename"]

            faces["output_file"] = self.output_dir / Path(filename).stem

            self.post_process.do_actions(faces)

            faces_count = len(faces["detected_faces"])
            if self.args.verbose and faces_count == 0:
                print("Warning: No faces were detected in image: "
                      "{}".format(os.path.basename(filename)))

            if not self.verify_output and faces_count > 1:
                self.verify_output = True

            self.process_faces(filename, faces)

        zoom = 1
        if hasattr(self.trainer.model, 'IMAGE_SHAPE'):
            zoom = self.trainer.model.IMAGE_SHAPE[0] // 64
              'shift_range': 0,
              'random_flip': 0
          }
  
        zoom = 1
        if hasattr(self.trainer.model, 'IMAGE_SHAPE'):
            zoom = self.trainer.model.IMAGE_SHAPE[0] // 64
  
          generator = lib.training_data.TrainingDataGenerator(random_transform_args, 160, zoom)
          batch = generator.minibatchAB(input_images, batch_size, doShuffle=False)
  
          return next(batch)[2]
keep keep keep keep replace keep keep keep keep keep
 Extraction - Speed improvements (#522) (#523)

* Extraction - Speed improvements (#522)

* Initial Plugin restructure

* Detectors to plugins. Detector speed improvements

* Re-implement dlib aligner, remove models, FAN to TF. Parallel processing

* Update manual, update convert, implement parallel/serial switching

* linting + fix cuda check (setup.py). requirements update keras 2.2.4

* Add extract size option. Fix dlib hog init

* GUI: Increase tooltip width

* Update alignment tool to support new DetectedFace

* Add skip existing faces option

* Fix sort tool to new plugin structure

* remove old align plugin

* fix convert -skip faces bug

* Fix convert skipping no faces frames

* Convert - draw onto transparent layer

* Fix blur threshold bug

* fix skip_faces convert bug

* Fix training 
lib/utils.py