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)
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])
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)