diff --git a/python/MMU2-eye10.png b/python/MMU2-eye10.png new file mode 100644 index 0000000..632bc12 Binary files /dev/null and b/python/MMU2-eye10.png differ diff --git a/python/calculate_dist_mat_mmu2.py b/python/calculate_dist_mat_mmu2.py new file mode 100644 index 0000000..a09eadf --- /dev/null +++ b/python/calculate_dist_mat_mmu2.py @@ -0,0 +1,117 @@ +#------------------------------------------------------------------------------ +# Libraries +#------------------------------------------------------------------------------ +import os +import numpy as np +from glob import glob +from time import time +from random import shuffle +from matplotlib import pyplot as plt +from itertools import repeat +from multiprocessing import Pool, cpu_count + +from fnc.extractFeature import extractFeature +from fnc.matching import calHammingDist + + +#------------------------------------------------------------------------------ +# Parameters +#------------------------------------------------------------------------------ +CASIA1_DIR = "/home/antiaegis/Downloads/Iris-Recognition/MMU2" +EYELASHES_THRES = 10 +N_IMAGES = 5 + + +#------------------------------------------------------------------------------ +# Pool function of extracting feature +#------------------------------------------------------------------------------ +def pool_func_extract_feature(args): + im_filename, eyelashes_thres, use_multiprocess = args + + template, mask, im_filename = extractFeature( + im_filename=im_filename, + eyelashes_thres=eyelashes_thres, + use_multiprocess=use_multiprocess, + ) + return template, mask, im_filename + + +#------------------------------------------------------------------------------ +# Pool function of calculating Hamming distance +#------------------------------------------------------------------------------ +def pool_func_calHammingDist(args): + template1, mask1, template2, mask2 = args + dist = calHammingDist(template1, mask1, template2, mask2) + return dist + + +#------------------------------------------------------------------------------ +# Main execution +#------------------------------------------------------------------------------ +# Get identities of MMU2 dataset +identities = glob(os.path.join(CASIA1_DIR, "**")) +identities = sorted([os.path.basename(identity) for identity in identities]) +n_identities = len(identities) +print("Number of identities:", n_identities) + + +# Construct a dictionary of files +files_dict = {} +image_files = [] +for identity in identities: + if identity=="50": + continue + + files = glob(os.path.join(CASIA1_DIR, identity, "*.*")) + shuffle(files) + files_dict[identity] = files[:N_IMAGES] + # print("Identity %s: %d images" % (identity, len(files_dict[identity]))) + image_files += files[:N_IMAGES] + +n_image_files = len(image_files) +print("Number of image files:", n_image_files) + + +# Extract features +args = zip(image_files, repeat(EYELASHES_THRES), repeat(False)) +pools = Pool(processes=cpu_count()) + +start_time = time() +features = list(pools.map(pool_func_extract_feature, args)) +finish_time = time() +print("Extraction time: %.3f [s]" % (finish_time-start_time)) + + +# Calculate the distances +args = [] +for i in range(n_image_files): + for j in range(n_image_files): + if i>=j: + continue + + arg = (features[i][0], features[i][1], features[j][0], features[j][1]) + args.append(arg) +print("Number of pairs:", len(args)) + +start_time = time() +distances = pools.map(pool_func_calHammingDist, args) +finish_time = time() +print("Extraction time: %.3f [s]" % (finish_time-start_time)) + + +# Construct a distance matrix +dist_mat = np.zeros([n_image_files, n_image_files]) +k = 0 +for i in range(n_image_files): + for j in range(n_image_files): + if ij: + dist_mat[i, j] = dist_mat[j, i] + +np.save("dist_mat_mmu2.npy", dist_mat) + +plt.figure() +plt.imshow(dist_mat) +plt.show() \ No newline at end of file diff --git a/python/dist_mat_mmu2.npy b/python/dist_mat_mmu2.npy new file mode 100644 index 0000000..b4d4a2b Binary files /dev/null and b/python/dist_mat_mmu2.npy differ diff --git a/python/eval_thres_mmu2.py b/python/eval_thres_mmu2.py new file mode 100644 index 0000000..6798cc6 --- /dev/null +++ b/python/eval_thres_mmu2.py @@ -0,0 +1,49 @@ +#------------------------------------------------------------------------------ +# Libraries +#------------------------------------------------------------------------------ +import numpy as np +from matplotlib import pyplot as plt + + +#------------------------------------------------------------------------------ +# Parameters +#------------------------------------------------------------------------------ +DIST_MAT_FILE = "dist_mat_mmu2.npy" +THRESHOLDS = np.linspace(start=0.0, stop=1.0, num=100) +NUM_IMAGES = 5 + + +#------------------------------------------------------------------------------ +# Main execution +#------------------------------------------------------------------------------ +dist_mat = np.load(DIST_MAT_FILE) + +ground_truth = np.zeros_like(dist_mat, dtype=int) +for i in range(ground_truth.shape[0]): + for j in range(ground_truth.shape[1]): + if i//NUM_IMAGES == j//NUM_IMAGES: + ground_truth[i, j] = 1 + +accuracies, precisions, recalls, fscores = [], [], [], [] +for threshold in THRESHOLDS: + decision_map = (dist_mat<=threshold).astype(int) + accuracy = (decision_map==ground_truth).sum() / ground_truth.size + precision = (ground_truth*decision_map).sum() / decision_map.sum() + recall = (ground_truth*decision_map).sum() / ground_truth.sum() + fscore = 2*precision*recall / (precision+recall) + accuracies.append(accuracy) + precisions.append(precision) + recalls.append(recall) + fscores.append(fscore) + +print("Max fscore:", max(fscores)) +print("Best threshold:", THRESHOLDS[fscores.index(max(fscores))]) + +plt.figure() +plt.plot(THRESHOLDS, accuracies, "-or") +plt.plot(THRESHOLDS, precisions, "-vb") +plt.plot(THRESHOLDS, recalls, "-*g") +plt.plot(THRESHOLDS, fscores, "-sc") +plt.legend(["accuracy", "precision", "recall", "fscore"]) +plt.grid(True) +plt.show() \ No newline at end of file diff --git a/python/fnc/__pycache__/boundary.cpython-36.pyc b/python/fnc/__pycache__/boundary.cpython-36.pyc index b8c65a1..58608c0 100644 Binary files a/python/fnc/__pycache__/boundary.cpython-36.pyc and b/python/fnc/__pycache__/boundary.cpython-36.pyc differ diff --git a/python/fnc/__pycache__/encode.cpython-36.pyc b/python/fnc/__pycache__/encode.cpython-36.pyc index ab07be0..ca0971b 100644 Binary files a/python/fnc/__pycache__/encode.cpython-36.pyc and b/python/fnc/__pycache__/encode.cpython-36.pyc differ diff --git a/python/fnc/__pycache__/extractFeature.cpython-36.pyc b/python/fnc/__pycache__/extractFeature.cpython-36.pyc index ce39dcc..6a98b4a 100644 Binary files a/python/fnc/__pycache__/extractFeature.cpython-36.pyc and b/python/fnc/__pycache__/extractFeature.cpython-36.pyc differ diff --git a/python/fnc/__pycache__/line.cpython-36.pyc b/python/fnc/__pycache__/line.cpython-36.pyc index 213d0e4..e251275 100644 Binary files a/python/fnc/__pycache__/line.cpython-36.pyc and b/python/fnc/__pycache__/line.cpython-36.pyc differ diff --git a/python/fnc/__pycache__/matching.cpython-36.pyc b/python/fnc/__pycache__/matching.cpython-36.pyc index 094f46e..1b24a2c 100644 Binary files a/python/fnc/__pycache__/matching.cpython-36.pyc and b/python/fnc/__pycache__/matching.cpython-36.pyc differ diff --git a/python/fnc/__pycache__/normalize.cpython-36.pyc b/python/fnc/__pycache__/normalize.cpython-36.pyc index d3e7c2c..47d7252 100644 Binary files a/python/fnc/__pycache__/normalize.cpython-36.pyc and b/python/fnc/__pycache__/normalize.cpython-36.pyc differ diff --git a/python/fnc/__pycache__/segment.cpython-36.pyc b/python/fnc/__pycache__/segment.cpython-36.pyc index 7d30412..bec31f7 100644 Binary files a/python/fnc/__pycache__/segment.cpython-36.pyc and b/python/fnc/__pycache__/segment.cpython-36.pyc differ