          module = PluginLoader._import("Extract_{0}".format(name))
          return getattr(module, "Extract")
      
      @staticmethod
      def get_converter(name="Adjust"):
          module = PluginLoader._import("Convert_{0}".format(name))
          return getattr(module, "Convert")
      
      @staticmethod
      def _import(name):
          return __import__(name, globals(), locals(), [], 1)
 
</s> remove     def _import(name):
        return __import__(name, globals(), locals(), [], 1)
 </s> add     def get_model(name):
        return PluginLoader._import("Model", "Model_{0}".format(name))
    
    @staticmethod
    def get_trainer(name):
        return PluginLoader._import("Trainer", "Model_{0}".format(name))
    
    @staticmethod
    def _import(attr, name):
        print("Loading {} from {} plugin...".format(attr, name))
        module = __import__(name, globals(), locals(), [], 1)
        return getattr(module, attr)
 </s> remove     def get_extractor(name="Align"):
        module = PluginLoader._import("Extract_{0}".format(name))
        return getattr(module, "Extract")
 </s> add     def get_extractor(name):
        return PluginLoader._import("Extract", "Extract_{0}".format(name))
 </s> remove     # output_dir.mkdir(parents=True, exist_ok=True)
 </s> add     output_dir.mkdir(parents=True, exist_ok=True)
 </s> remove     return umeyama( numpy.array(face.landmarks[17:]), landmarks_2D, True )[0:2]
 </s> add     return umeyama( numpy.array(face.landmarksAsXY()[17:]), landmarks_2D, True )[0:2] </s> remove 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> add     def iterator(self):
        while True:
            next_item = self.queue.get()
            if next_item is None:
                break
            yield next_item
    def get_converter(name):
        return PluginLoader._import("Convert", "Convert_{0}".format(name))

          module = PluginLoader._import("Extract_{0}".format(name))
          return getattr(module, "Extract")
      
      @staticmethod
    def get_converter(name):
        return PluginLoader._import("Convert", "Convert_{0}".format(name))
    def get_converter(name):
        return PluginLoader._import("Convert", "Convert_{0}".format(name))
    def get_converter(name):
        return PluginLoader._import("Convert", "Convert_{0}".format(name))
      
      @staticmethod
      def _import(name):
          return __import__(name, globals(), locals(), [], 1)
keep keep keep keep replace replace replace keep keep keep keep
 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 
plugins/PluginLoader.py