          # Note: we take only first face, so the reference file should only contain one face.
          self.encodings = list(map(lambda im: face_recognition.face_encodings(im)[0], images))
          self.nencodings = list(map(lambda im: face_recognition.face_encodings(im)[0], nimages))
          self.threshold = threshold
          logger.trace("encodings: %s", self.encodings)
          logger.trace("nencodings: %s", self.nencodings)
          logger.debug("Initialized %s", self.__class__.__name__)
  
      def check(self, detected_face):
          """ Check Face
              we could use detected landmarks, but I did not manage to do so.
 
</s> remove                      "threshold: %s)", self.__class__.__name__, reference_file_paths,
                     nreference_file_paths, threshold)
        images = list(map(face_recognition.load_image_file, reference_file_paths))
        nimages = list(map(face_recognition.load_image_file, nreference_file_paths))
        # Note: we take only first face, so the reference file should only contain one face.
        self.encodings = list(map(lambda im: face_recognition.face_encodings(im)[0], images))
        self.nencodings = list(map(lambda im: face_recognition.face_encodings(im)[0], nimages))
 </s> add                      "detector: %s, aligner: %s. loglevel: %s, multiprocess: %s, threshold: %s)",
                     self.__class__.__name__, reference_file_paths, nreference_file_paths,
                     detector, aligner, loglevel, multiprocess, threshold)
        git_model_id = 7
        model_filename = ["vgg_face_v1.caffemodel", "vgg_face_v1.prototxt"]

        self.input_size = 224
        self.numeric_loglevel = get_loglevel(loglevel)
        self.vgg_face = self.get_model(git_model_id, model_filename)
        self.filters = self.load_images(reference_file_paths, nreference_file_paths)
        self.align_faces(detector, aligner, loglevel, multiprocess)
        self.get_filter_encodings()
 </s> remove         """ Check Face
            we could use detected landmarks, but I did not manage to do so.
            TODO The copy/paste below should help """
 </s> add         """ Check the extracted Face """
 </s> remove     """ Face filter for extraction """
    def __init__(self, reference_file_paths, nreference_file_paths, threshold=0.6):
 </s> add     """ Face filter for extraction
        NB: we take only first face, so the reference file should only contain one face. """

    def __init__(self, reference_file_paths, nreference_file_paths, detector, aligner, loglevel,
                 multiprocess=False, threshold=0.4):
 </s> remove         encodings = face_recognition.face_encodings(detected_face.image)
        if not encodings:
            logger.verbose("No face encodings found")
            return False

        if self.encodings:
            distances = list(face_recognition.face_distance(self.encodings, encodings[0]))
            logger.trace("Distances: %s", distances)
            distance = avg(distances)
            logger.trace("Average Distance: %s", distance)
            mindistance = min(distances)
            logger.trace("Minimum Distance: %s", mindistance)
            if distance > self.threshold:
                logger.verbose("Distance above threshold: %f < %f", distance, self.threshold)
                return False
        if self.nencodings:
            ndistances = list(face_recognition.face_distance(self.nencodings, encodings[0]))
            logger.trace("nDistances: %s", ndistances)
            ndistance = avg(ndistances)
            logger.trace("Average nDistance: %s", ndistance)
            nmindistance = min(ndistances)
            logger.trace("Minimum nDistance: %s", nmindistance)
            if not self.encodings and ndistance < self.threshold:
                logger.verbose("nDistance below threshold: %f < %f", ndistance, self.threshold)
                return False
            if self.encodings:
                if mindistance > nmindistance:
                    logger.verbose("Distance to negative sample is smaller")
                    return False
                if distance > ndistance:
                    logger.verbose("Average distance to negative sample is smaller")
                    return False
                # k-nn classifier
                var_k = min(5, min(len(distances), len(ndistances)) + 1)
                var_n = sum(list(map(lambda x: x[0],
                                     list(sorted([(1, d) for d in distances] +
                                                 [(0, d) for d in ndistances],
                                                 key=lambda x: x[1]))[:var_k])))
                ratio = var_n/var_k
                if ratio < 0.5:
                    logger.verbose("K-nn is %.2f", ratio)
                    return False
        return True


# # Copy/Paste (mostly) from private method in face_recognition
# face_recognition_model = face_recognition_models.face_recognition_model_location()
# face_encoder = dlib.face_recognition_model_v1(face_recognition_model)

# def convert(detected_face):
#     return np.array(face_encoder.compute_face_descriptor(detected_face.image,
#                                                          detected_face.landmarks,
#                                                          1))
# # end of Copy/Paste
 </s> add         distances = {"filter": list(), "nfilter": list()}
        encodings = self.predict(detected_face.aligned_face)
        for filt in self.filters.values():
            similarity = self.find_cosine_similiarity(filt["encoding"], encodings)
            distances[filt["type"]].append(similarity)

        avgs = {key: avg(val) if val else None for key, val in distances.items()}
        mins = {key: min(val) if val else None for key, val in distances.items()}
        # Filter
        if distances["filter"] and avgs["filter"] > self.threshold:
            msg = "Rejecting filter face: {} > {}".format(round(avgs["filter"], 2), self.threshold)
            retval = False
        # nFilter no Filter
        elif not distances["filter"] and avgs["nfilter"] < self.threshold:
            msg = "Rejecting nFilter face: {} < {}".format(round(avgs["nfilter"], 2),
                                                           self.threshold)
            retval = False
        # Filter with nFilter
        elif distances["filter"] and distances["nfilter"] and mins["filter"] > mins["nfilter"]:
            msg = ("Rejecting face as distance from nfilter sample is smaller: (filter: {}, "
                   "nfilter: {})".format(round(mins["filter"], 2), round(mins["nfilter"], 2)))
            retval = False
        elif distances["filter"] and distances["nfilter"] and avgs["filter"] > avgs["nfilter"]:
            msg = ("Rejecting face as average distance from nfilter sample is smaller: (filter: "
                   "{}, nfilter: {})".format(round(mins["filter"], 2), round(mins["nfilter"], 2)))
            retval = False
        elif distances["filter"] and distances["nfilter"]:
            # k-nn classifier
            var_k = min(5, min(len(distances["filter"]), len(distances["nfilter"])) + 1)
            var_n = sum(list(map(lambda x: x[0],
                                 list(sorted([(1, d) for d in distances["filter"]] +
                                             [(0, d) for d in distances["nfilter"]],
                                             key=lambda x: x[1]))[:var_k])))
            ratio = var_n/var_k
            if ratio < 0.5:
                msg = ("Rejecting face as k-nearest neighbors classification is less than "
                       "0.5: {}".format(round(ratio, 2)))
                retval = False
        else:
            msg = None
            retval = True
        if msg:
            logger.verbose(msg)
        else:
            logger.trace("Accepted face: (similarity: %s, threshold: %s)",
                         distances, self.threshold)
        return retval

    @staticmethod
    def find_cosine_similiarity(source_face, test_face):
        """ Find the cosine similarity between a source face and a test face """
        var_a = np.matmul(np.transpose(source_face), test_face)
        var_b = np.sum(np.multiply(source_face, source_face))
        var_c = np.sum(np.multiply(test_face, test_face))
        return 1 - (var_a / (np.sqrt(var_b) * np.sqrt(var_c)))
 </s> remove         filter_lists = kwargs["filter_lists"]
        ref_threshold = kwargs.get("ref_threshold", 0.6)
        self.filter = self.load_face_filter(filter_lists, ref_threshold)
 </s> add         logger.info("Extracting and aligning face for Face Filter...")
        self.filter = self.load_face_filter(**kwargs)
          # Note: we take only first face, so the reference file should only contain one face.
          self.encodings = list(map(lambda im: face_recognition.face_encodings(im)[0], images))
          self.nencodings = list(map(lambda im: face_recognition.face_encodings(im)[0], nimages))
          self.threshold = threshold


          logger.debug("Initialized %s", self.__class__.__name__)
  
      def check(self, detected_face):
          """ Check Face
              we could use detected landmarks, but I did not manage to do so.
keep keep keep keep replace replace keep keep keep keep keep
 Face filter vgg face (#724)

* Implement extraction pipeline

* Face filter to vgg_face. Resume partial model downloads

* On-the-fly conversion to extraction pipeline

* Move git model ids from get_model to model definition 
lib/face_filter.py