          """
          Estimate the amount of blur an image has with the variance of the Laplacian.
          Normalize by pixel number to offset the effect of image size on pixel gradients & variance
          """
          image = read_image(image_file, raise_error=True)
          if image.ndim == 3:
              image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
          blur_map = cv2.Laplacian(image, cv2.CV_32F)
          score = np.var(blur_map) / np.sqrt(image.shape[0] * image.shape[1])
          return score
 
</s> remove     def estimate_blur(image_file):
 </s> add     def estimate_blur(image): </s> remove     @staticmethod
    def get_landmarks(filename):
        """ Extract the face from a frame (If not alignments file found) """
        image = read_image(filename, raise_error=True)
        feed = Sort.alignment_dict(image)
        feed["filename"] = filename
        queue_manager.get_queue("in").put(feed)
        face = queue_manager.get_queue("out").get()
        landmarks = face["detected_faces"][0].landmarks_xy
        return landmarks
 </s> add     def _get_landmarks(self):
        """ Multi-threaded, parallel and sequentially ordered landmark loader """
        self.launch_aligner()
        filename_list, image_list = self._get_images()
        feed_list = list(map(Sort.alignment_dict, filename_list, image_list))
        landmarks = np.zeros((len(feed_list), 68, 2), dtype='float32')

        logger.info("Finding landmarks in images...")
        for feed in tqdm(feed_list, desc="Putting...", file=sys.stdout):
            queue_manager.get_queue("in").put(feed)
        for index, _ in enumerate(tqdm(landmarks, desc="Aligning...", file=sys.stdout)):
            face = queue_manager.get_queue("out").get()
            landmarks[index] = np.array(face["detected_faces"][0].landmarks_xy)

        return filename_list, image_list, landmarks

    def _get_images(self):
        """ Multi-threaded, parallel and sequentially ordered image loader """
        logger.info("Loading images...")
        filename_list = self.find_images(self.args.input_dir)
        with futures.ThreadPoolExecutor() as executor:
            image_list = list(tqdm(executor.map(read_image, filename_list),
                                   desc="Loading Images...",
                                   file=sys.stdout,
                                   total=len(filename_list)))

        return filename_list, image_list </s> remove     def alignment_dict(image):
 </s> add     def alignment_dict(filename, image): </s> remove         for i in tqdm(range(len(sorted_list)),
                      desc="Splicing",
                      file=sys.stdout):
 </s> add         for i in tqdm(range(len(sorted_list)), desc="Splicing", file=sys.stdout): </s> remove         input_dir = self.args.input_dir

        logger.info("Sorting by blur...")
        img_list = [[img, self.estimate_blur(img)]
                    for img in
                    tqdm(self.find_images(input_dir),
                         desc="Loading",
                         file=sys.stdout)]
        logger.info("Sorting...")
 </s> add         logger.info("Sorting by estimated image blur...")
        filename_list, image_list = self._get_images()
          """
          Estimate the amount of blur an image has with the variance of the Laplacian.
          Normalize by pixel number to offset the effect of image size on pixel gradients & variance
          """

          if image.ndim == 3:
              image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
          blur_map = cv2.Laplacian(image, cv2.CV_32F)
          score = np.var(blur_map) / np.sqrt(image.shape[0] * image.shape[1])
          return score
keep keep keep keep replace keep keep keep keep keep
 ENHANCEMENT: Sort image multi-threading and code clarity (#912)

* Use multi-threaded loading

* fast reload

* remove landmark stub

* saves

* correct face sort

* pep8 
tools/sort.py