Example #1
0
def main():

    siamese = Siamese()
    siamese.load_model()
    EONS = 10
    for k in range(EONS):
        print('======= Eon %d/%d ======== ' % (k, EONS))
        pairs_train = get_all_pairs()
        pairs_test = get_all_pairs()
        print('Pairs:', len(pairs_train))
        shuffle(pairs_train)
        pos = [x for x in pairs_train if x.label == 1]
        print('Pos:', len(pos))
        neg = [x for x in pairs_train if x.label == 0]
        print('Neg:', len(neg))
        print((len(pos) + len(neg)))
        train_model(siamese, pairs_train, pairs_test)
Example #2
0
file = pd.read_csv('embed.csv')
# print(file['className'].unique())

means = []

for column_name in file['className'].unique():
    means.append(row_mean(file, column_name))

print(np.shape(means))

# for k in range(len(means)-1):
#    for j in range(k, len(means)):
#        dist = np.sqrt(np.sum((means[k] - means[j])**2))
#        print(k, j, dist)

siamese = Siamese()
siamese.load_model()

image = [np.array(Image.open('image_test.jpg')) / 255.0]
print(np.shape(image))
pred = siamese.test_model(image)

dists = []
for k in range(len(means)):
    dist = np.sqrt(np.sum((means[k] - pred)**2))
    print(k, dist)
    dists.append(dist)

print('Class:', np.argmin(dists))
class Evaluation():
    def __init__(self, dataset_path="datasets/lfw-dataset", img_size=(36, 36)):
        self.super_resolution = SuperResolution(
            model_path=os.getenv("SUPER_RESOLUTION_DIR"))
        self.detector = Detector(os.getenv("DETECTOR_DIR"))
        self.face_extractor = FacenetExtractor(
            model_path=os.getenv("EXTRACTOR_DIR"))
        self.utils = Utils(super_resolution=self.super_resolution)
        self.dataset_path = dataset_path
        self.input_size = (160, 160)
        self.img_size = img_size
        self.face_extractor.init_model()
        self.classifier = Siamese()
        self.classifier.load_model(os.getenv("CLASSIFIER_DIR"))

    def evaluate(
        self,
        match_test="matchpairsDevTest.csv",
        mismatch_test="mismatchpairsDevTest.csv",
    ):
        match_test = np.genfromtxt(os.path.join(self.dataset_path, match_test),
                                   delimiter=",",
                                   dtype=None,
                                   skip_header=1)
        mismatch_test = np.genfromtxt(os.path.join(self.dataset_path,
                                                   mismatch_test),
                                      delimiter=",",
                                      dtype=None,
                                      skip_header=1)

        times1, accuracies1 = self.evaluate_data(match_test, True)
        times2, accuracies2 = self.evaluate_data(mismatch_test, False)

        print("Average time {}".format(np.mean(times1 + times2)))
        print("Average accuracies {}".format(np.mean(accuracies1 +
                                                     accuracies2)))

    def write_undetected(self, image, imagename, method="mtcnn"):
        path = os.path.join(os.getcwd(),
                            "results/undetected/{}".format(method), imagename)
        cv2.imwrite(path, image)

    def write_result(self,
                     image1,
                     image2,
                     imagename,
                     is_match,
                     size="12x12",
                     result="unrecognized"):
        if (is_match):
            path = os.path.join(os.getcwd(), "results/{}/match".format(result),
                                size, imagename)
        else:
            path = os.path.join(os.getcwd(),
                                "results/{}/mismatch".format(result), size,
                                imagename)
        vis = np.concatenate((image1, image2), axis=0)
        cv2.imwrite(path, vis)

    def evaluate_data(self, dataset, is_match):
        times = []
        accuracies = []

        for idx, data in tqdm(enumerate(dataset), total=len(dataset)):
            path1, path2 = self.get_images_path(data, is_match)

            uncropped_image1 = cv2.imread(path1)
            uncropped_image2 = cv2.imread(path2)
            image1, image2 = uncropped_image1, uncropped_image2

            execution_time1 = 0
            execution_time2 = 0
            start_time = time.time()
            try:
                image1 = self.detector.detect(uncropped_image1)[0][0]
                image2 = self.detector.detect(uncropped_image2)[0][0]
            except IndexError:
                if (image1.shape == uncropped_image1.shape):
                    self.write_undetected(uncropped_image1,
                                          os.path.basename(path1),
                                          method="mtcnn")
                if (image2.shape == uncropped_image2.shape):
                    self.write_undetected(uncropped_image2,
                                          os.path.basename(path2),
                                          method="mtcnn")
                accuracies.append(0)
                continue

            execution_time1 += (time.time() - start_time)
            execution_time2 += (time.time() - start_time)

            sr_1 = cv2.resize(image1,
                              self.img_size,
                              interpolation=cv2.INTER_CUBIC)

            start_time = time.time()
            sr_1 = self.utils.resize_image(sr_1, size=self.input_size)
            execution_time1 += (time.time() - start_time)

            sr_2 = cv2.resize(image2,
                              self.img_size,
                              interpolation=cv2.INTER_CUBIC)

            sample_image2 = cv2.resize(sr_2,
                                       self.input_size,
                                       interpolation=cv2.INTER_CUBIC)

            start_time = time.time()
            sr_2 = self.utils.resize_image(sr_2, size=self.input_size)
            execution_time2 += (time.time() - start_time)

            start_time = time.time()
            sr_1 = self.face_extractor.get_embedding(sr_1)
            execution_time1 += (time.time() - start_time)

            start_time = time.time()
            sr_2 = self.face_extractor.get_embedding(sr_2)
            execution_time2 += (time.time() - start_time)

            image1 = self.utils.resize_image(image1, size=self.input_size)
            image2 = self.utils.resize_image(image2, size=self.input_size)

            sample_image1 = np.copy(image1)

            image1 = self.face_extractor.get_embedding(image1)
            image2 = self.face_extractor.get_embedding(image2)

            classifier = self.classifier.get_model()

            start_time = time.time()
            result1 = classifier.evaluate(
                [sr_1.reshape(1, 128),
                 image2.reshape(1, 128)], [1 if is_match else 0])
            execution_time1 += (time.time() - start_time)

            start_time = time.time()
            result2 = classifier.evaluate(
                [sr_2.reshape(1, 128),
                 image1.reshape(1, 128)], [1 if is_match else 0])
            execution_time2 += (time.time() - start_time)

            if (result2[1] < 0.5):
                self.write_result(sample_image1,
                                  sample_image2,
                                  "{}.jpg".format(idx + 1),
                                  is_match,
                                  size="36x36",
                                  result="unrecognized")
            else:
                self.write_result(sample_image1,
                                  sample_image2,
                                  "{}.jpg".format(idx + 1),
                                  is_match,
                                  size="36x36",
                                  result="recognized")

            accuracies.append(result1[1])
            accuracies.append(result2[1])

            times.append(execution_time1)
            times.append(execution_time2)

        return times, accuracies

    def get_images_path(self, pair, is_match):
        if (is_match):
            image_dir = os.path.join(self.dataset_path, "lfw-deepfunneled",
                                     pair[0].astype("str"))
            image_list = os.listdir(image_dir)
            return os.path.join(image_dir,
                                image_list[pair[1] - 1]), os.path.join(
                                    image_dir, image_list[pair[2] - 1])
        else:
            image_dir1 = os.path.join(self.dataset_path, "lfw-deepfunneled",
                                      pair[0].astype("str"))
            image_list1 = os.listdir(image_dir1)

            image_dir2 = os.path.join(self.dataset_path, "lfw-deepfunneled",
                                      pair[2].astype("str"))
            image_list2 = os.listdir(image_dir2)

            return os.path.join(image_dir1,
                                image_list1[pair[1] - 1]), os.path.join(
                                    image_dir2, image_list2[pair[3] - 1])
Example #4
0
class Core():
    def __init__(self):
        self.super_resolution = SuperResolution(
            model_path=os.getenv("SUPER_RESOLUTION_DIR"))
        self.detector = Detector(os.getenv("DETECTOR_DIR"))
        self.extractor = FacenetExtractor(
            model_path=os.getenv("EXTRACTOR_DIR"))
        self.extractor.init_model()
        self.utils = Utils(super_resolution=self.super_resolution,
                           extractor=self.extractor)
        self.classifier = Siamese()
        self.classifier.load_model(os.getenv("CLASSIFIER_DIR"))
        self.db = DbConnection()

    def save_embedding(self, image, name):
        embedding = self.utils.extract_embedding(image)
        identity = Identity(name, embedding.tolist())
        self.db.insert_identity(vars(identity))
        print("Successfully save face embedding to database")

    def find_identity(self, image):
        embedding = self.utils.extract_embedding(image)
        identities = []
        for identity in self.db.get_identities():
            i_embedding = np.asarray(identity["face_embedding"])
            prediction = self.classifier.predict(
                [embedding.reshape(1, 128),
                 i_embedding.reshape(1, 128)])
            identities.append({
                "_id": identity["_id"],
                "name": identity["name"],
                "prediction": prediction
            })
        identities = list(filter(lambda el: el["prediction"] > 0.5,
                                 identities))
        if len(identities) == 0:
            return None
        recognized_identity = max(identities, key=lambda i: i["prediction"])
        return recognized_identity

    def one_shot_learning(self, image_path=None, identity_name=""):
        if (image_path):
            image = cv2.imread(image_path)
            cropped_images, _ = self.detector.detect(image)
            if (len(cropped_images)):
                cropped_image = cropped_images[0]
                self.save_embedding(cropped_image, identity_name)
            else:
                print("No face is found")
                return
        else:
            cap = cv2.VideoCapture(0)
            while (True):
                ret, frame = cap.read()
                cv2.imshow('frame', frame)
                cv2.waitKey(1)
                detected_faces, _ = self.detector.detect(frame)
                if (len(detected_faces)):
                    detected_face = detected_faces[0]
                    self.save_embedding(detected_face, identity_name)
                    break

            cap.release()
            cv2.destroyAllWindows()

    def save_timestamp(self, identities, threshold=None):
        current_t = time.time()
        identities_id = [
            identity["_id"] for identity in identities if identity is not None
        ]
        identities_id = list(set(identities_id))
        for logtime in self.db.get_logtimes({"left_time": None}):
            if logtime["identity_id"] not in identities_id:
                self.db.set_logtime({"_id": logtime["_id"]},
                                    {"left_time": current_t})
            else:
                identities_id.remove(logtime["identity_id"])

        for logtime in self.db.get_logtimes(
            {"left_time": {
                "$gte": current_t - threshold
            }}):
            if logtime["identity_id"] in identities_id:
                self.db.set_logtime({"_id": logtime["_id"]},
                                    {"left_time": None})
                identities_id.remove(logtime["identity_id"])

        for identity_id in identities_id:
            log_time = Logtime(identity_id, current_t, None)
            self.db.insert_logtime(vars(log_time))

    def recognition_summary(self, start_time, end_time):
        self.db.set_logtime({"left_time": None}, {"left_time": end_time})
        print("=== Recognition Summary ===")
        for logtime in self.db.get_logtimes({
                "enter_time": {
                    "$gte": start_time
                },
                "left_time": {
                    "$lte": end_time
                }
        }):
            identity = self.db.get_identities(opt={
                "_id": logtime["identity_id"]
            }).next()
            print("{} ({}). start:{}. end:{}.".format(
                identity["name"], identity["_id"],
                time.strftime('%Y-%m-%d %H:%M:%S',
                              time.localtime(logtime["enter_time"])),
                time.strftime('%Y-%m-%d %H:%M:%S',
                              time.localtime(logtime["left_time"]))))

    def recognition_log(self, threshold, video_path=None):
        cap = cv2.VideoCapture(video_path or 0)
        start_time = time.time()
        while (True if not video_path else cap.isOpened()):
            _, frame = cap.read()
            faces, boxes = self.detector.detect(frame)
            identities = []
            for face in faces:
                identity = self.find_identity(face)
                identities.append(identity)

            self.save_timestamp(identities, threshold)

            for idx, box in enumerate(boxes):
                cv2.rectangle(frame, (box[0], box[1]), (box[2], box[3]),
                              (255, 0, 0), 2)
                if (not identities[idx]):
                    name = "Unidentified"
                else:
                    name = identities[idx]["name"]
                cv2.putText(frame, name, (box[0], box[1]),
                            cv2.FONT_HERSHEY_SIMPLEX, 0.8, (255, 0, 0), 2,
                            cv2.LINE_AA)
            cv2.imshow('frame', frame)
            key = cv2.waitKey(30)
            if key == 27:
                break
        end_time = time.time()
        self.recognition_summary(start_time, end_time)