  def get_image_paths(directory):
      return [x.path for x in scandir(directory) if x.name.endswith('.jpg') or x.name.endswith('.jpeg') or x.name.endswith('.png')]
  
  
  def load_images(image_paths, convert=None):
      iter_all_images = (cv2.imread(fn) for fn in image_paths)
      if convert:
          iter_all_images = (convert(img) for img in iter_all_images)
      for i, image in enumerate(iter_all_images):
          if i == 0:
              all_images = numpy.empty((len(image_paths), ) + image.shape, dtype=image.dtype)
          all_images[i] = image
      return all_images
 
</s> remove     # output_dir.mkdir(parents=True, exist_ok=True)
 </s> add     output_dir.mkdir(parents=True, exist_ok=True)
 </s> remove def get_training_data(images, batch_size):
    indices = numpy.random.randint(len(images), size=batch_size)
    for i, index in enumerate(indices):
        image = images[index]
        image = random_transform(image, **random_transform_args)
        warped_img, target_img = random_warp(image)

        if i == 0:
            warped_images = numpy.empty(
                (batch_size,) + warped_img.shape, warped_img.dtype)
            target_images = numpy.empty(
                (batch_size,) + target_img.shape, warped_img.dtype)

        warped_images[i] = warped_img
        target_images[i] = target_img

    return warped_images, target_images
 </s> add # GAN
# random_transform_args = {
#     'rotation_range': 20,
#     'zoom_range': 0.1,
#     'shift_range': 0.05,
#     'random_flip': 0.5,
#     }
def read_image(fn, random_transform_args=random_transform_args):
    image = cv2.imread(fn) / 255.0
    image = cv2.resize(image, (256,256))
    image = random_transform( image, **random_transform_args )
    warped_img, target_img = random_warp( image )
    
    return warped_img, target_img

# A generator function that yields epoch, batchsize of warped_img and batchsize of target_img
def minibatch(data, batchsize):
    length = len(data)
    epoch = i = 0
    shuffle(data)
    while True:
        size = batchsize
        if i+size > length:
            shuffle(data)
            i = 0
            epoch+=1        
        rtn = numpy.float32([read_image(data[j]) for j in range(i,i+size)])
        i+=size
        yield epoch, rtn[:,0,:,:,:], rtn[:,1,:,:,:]       

def minibatchAB(images, batchsize):
    batch = BackgroundGenerator(minibatch(images, batchsize), 1)
    for ep1, warped_img, target_img in batch.iterator():
        yield ep1, warped_img, target_img
 </s> remove     landmarks_as_tuples = [[(p.x, p.y) for p in landmark.parts()] for landmark in landmarks]
 </s> add  </s> remove 
        self.finalize()
 </s> add     
    def get_faces(self, image):
        faces_count = 0
        for face in detect_faces(image):
            if self.filter is not None and not self.filter.check(face):
                print('Skipping not recognized face!')
                continue

            yield faces_count, face

            self.faces_detected = self.faces_detected + 1
            faces_count +=1
        
        if faces_count > 0 and self.arguments.verbose:
            print('Note: Found more than one face in an image!')
            self.verify_output = True
    
    def load_filter(self):
        filter_file = "filter.jpg" # TODO Pass as argument
        if Path(filter_file).exists():
            print('Loading reference image for filtering')
            return FaceFilter(filter_file) </s> remove     for ((top, right, bottom, left), landmarks) in zip(face_locations, landmarks_as_tuples):
        x = left
        y = top
        w = right - left
        h = bottom - top
        yield DetectedFace(frame[y: y + h, x: x + w], x, w, y, h, landmarks)
 </s> add     for ((y, right, bottom, x), landmarks) in zip(face_locations, landmarks):
        yield DetectedFace(frame[y: bottom, x: right], x, right - x, y, bottom - y, landmarks)
    def iterator(self):
        while True:
            next_item = self.queue.get()
            if next_item is None:
                break
            yield next_item
  def get_image_paths(directory):
      return [x.path for x in scandir(directory) if x.name.endswith('.jpg') or x.name.endswith('.jpeg') or x.name.endswith('.png')]
  
  
    def iterator(self):
        while True:
            next_item = self.queue.get()
            if next_item is None:
                break
            yield next_item
    def iterator(self):
        while True:
            next_item = self.queue.get()
            if next_item is None:
                break
            yield next_item
    def iterator(self):
        while True:
            next_item = self.queue.get()
            if next_item is None:
                break
            yield next_item
    def iterator(self):
        while True:
            next_item = self.queue.get()
            if next_item is None:
                break
            yield next_item
    def iterator(self):
        while True:
            next_item = self.queue.get()
            if next_item is None:
                break
            yield next_item
    def iterator(self):
        while True:
            next_item = self.queue.get()
            if next_item is None:
                break
            yield next_item
    def iterator(self):
        while True:
            next_item = self.queue.get()
            if next_item is None:
                break
            yield next_item
    def iterator(self):
        while True:
            next_item = self.queue.get()
            if next_item is None:
                break
            yield next_item
    def iterator(self):
        while True:
            next_item = self.queue.get()
            if next_item is None:
                break
            yield next_item
keep keep keep keep replace replace replace replace replace replace replace replace replace
 Adding models as plugins + Face filtering (#53) + #39 + #43 + #44 + #49 (#61)

* Making Models as plugins

* Do not reload model on each image #39 + Adding FaceFilter #53

* Adding @lukaville PR for #43 and #44 (possibly)

* Training done in a separate thread

* Better log for plugin load

* Adding a prefetch to train.py #49
(Note that we prefetch 2 batches of images, due to the queue behavior)
+ More compact logging with verbose info included

* correction of DirectoryProcessor signature

* adding missing import

* Convert with parallel preprocessing of files

* Added coverage var for trainer

Added a var with comment. Feel free to add it as argument

* corrections

* Modifying preview and normalization of image + correction

* Cleanup 
lib/utils.py