Commit d19bbb8b authored by Maria Kleppestø Mcculloch's avatar Maria Kleppestø Mcculloch
Browse files

Added EDC calculation

parent 25e67e3c
from re import S
from webbrowser import get
import numpy as np
from DET.DET import DET
import matplotlib.pyplot as mpl
from matplotlib import pyplot as plt
from scipy.special import erfinv
'''
Computes the EDC (error versus discard) specifically for quality values.
This works for discrete quality values where the value is a scalar
Heavily based on provided DET curve script.
Also called ERC (error versus reject)
'''
class EDC:
def __init__(self, lowerbound, higherbound, fixed_fmnr_threshold = 0.3, metricname="") -> None:
self.lowb = lowerbound
self.highb = higherbound
self.threshold = fixed_fmnr_threshold
if metricname != "": self.title = "EDC-Curve for " + metricname
else: self.title = "EDC-Curve"
pass
def _fmnr(self, sims):
sims_sorted_inx = np.argsort(sims, kind='mergesort')
sims_sorted = sims[sims_sorted_inx]
# FMNR
length= len(sims_sorted)
inx = 0
breaks = False
while(inx < length and not breaks ):
if(sims_sorted[inx] > self.threshold):
breaks = True
inx =inx +1
fnmr = (inx-1)/length
return fnmr
def plotEDC(self, gens, qual_gens):
# Init starting values
x = []
y = []
totnumValues = gens.shape[0]
totRemoved = 0
curr_gen = []
curr_quals = []
curr_gen.append([gens])
curr_quals.append([qual_gens])
x.append(0)
y.append(self._fmnr(gens))
print(" j " , self._fmnr(gens))
indx = 0
# Run for all combinations of (u,v)
for u in range(self.lowb+1, self.highb + 1):
## Calculate for (u, lower_bound)
round_gens = curr_gen[u-self.lowb-1][0]
round_quals = curr_quals[u-self.lowb-1][0]
# Remove values
r_0, fnmr, q_inx_spliced = self.discardValues(round_gens, round_quals[:, 0], u)
totRemoved = totRemoved + r_0
totRemoved_v_round = totRemoved
# Set new scores
# new_gens = curr_gen[u-self.lowb-1][new_indices]
#new_quals = curr_quals[u-self.lowb-1][new_indices]
new_quals = round_quals[q_inx_spliced]
new_gens = round_gens[q_inx_spliced]
curr_gen.append([new_gens])
curr_quals.append([new_quals])
# Calculate r
r = totRemoved/totnumValues
x.append(r)
y.append(fnmr)
print("(",u, ", ", 1, ") -> FNMR: ",fnmr, " || ", len(q_inx_spliced))
for v in range(self.lowb +1 , self.highb + 1):
# Remove values
# Calculate r and v on those left
round_gens = curr_gen[u-self.lowb][v-self.lowb-1]
round_quals = curr_quals[u-self.lowb][v-self.lowb-1]
# calculate the rejection rate
r_0, fnmr,q_inx_spliced = self.discardValues(round_gens, round_quals[:, 1], v)
totRemoved_v_round = totRemoved_v_round + r_0
r = totRemoved_v_round/totnumValues
# Append
x.append(r)
y.append(fnmr)
print("(",u, ", ", v, ") -> FNMR: ",fnmr, " || ", len(q_inx_spliced))
new_gens = round_gens[q_inx_spliced]
new_quals = round_quals[q_inx_spliced]
curr_gen[u-self.lowb].append(new_gens)
curr_quals[u-self.lowb].append(new_quals)
x = np.array(x)
y = np.array(y)
print(x)
print(y)
print("\n")
indx = np.argsort(x, axis=0)
x_sort = x[indx]
y_sort = y[indx]
print(x_sort)
print(y_sort)
# Sort for x
mpl.plot(x_sort, y_sort, label="label", color=(0.3, 0.3, 0.0), linestyle='-', linewidth=1)
return
def discardValues(self, sims, quals, level):
total_scores = len(sims)
# Sort by quality value
q_inx = np.argsort(quals, kind='mergesort')
quals_sorted = quals[q_inx]
# Remove low quality values
inx = 0
breaks = False
while(inx < total_scores and not breaks ):
if(quals_sorted[inx] >= level):
breaks = True
inx =inx +1
q_inx_spliced = q_inx[inx-1:]
# Calculate fmnr
sims_spliced= sims[q_inx_spliced]
sims_spliced_sorted_inx = np.argsort(sims_spliced, kind='mergesort')
sims_spliced_sorted = sims_spliced[sims_spliced_sorted_inx]
# FMNR
tot_not_rejected = len(q_inx_spliced)
inx = 0
breaks = False
while(inx < len(sims_spliced_sorted) and not breaks ):
if(sims_spliced_sorted[inx] > self.threshold):
breaks = True
inx =inx +1
fnmr = (inx-1)/tot_not_rejected
return total_scores- tot_not_rejected, fnmr, q_inx_spliced
def setup(self):
"""
Creates empty DET plot figure
"""
self.figure = mpl.figure()
'''
ax = self.figure.add_subplot(111)
ax.set_aspect('equal')
mpl.axis([
self.axes_transform(self.x_limits[0]),
self.axes_transform(self.x_limits[1]),
self.axes_transform(self.y_limits[0]),
self.axes_transform(self.y_limits[1])])
ax.set_xticks(self.axes_transform(self.x_ticks))
ax.set_xticklabels(self.x_ticklabels, size='x-small')
ax.set_yticks(self.axes_transform(self.y_ticks))
ax.set_yticklabels(self.y_ticklabels, size='x-small')
mpl.grid(True) # grid_color = '#b0b0b0'
'''
mpl.xlabel("Percentage Removed")
mpl.ylabel("FNMR (False Non Match Rate)")
mpl.title(self.title)
'''
mpl.gca().set_xlim(
left = self.axes_transform(self.x_limits[0]),
right = self.axes_transform(self.x_limits[1])
)
mpl.gca().set_ylim(
bottom = self.axes_transform(self.y_limits[0]),
top = self.axes_transform(self.y_limits[1])
)
mpl.gca().set_aspect('equal')
'''
def showEDC(self):
# Show curve
mpl.show()
return
from qualityEvaluation import QualityEvaluator
from qualityEvaluation import QualityTemp
from utils.baseScore import BaseHandler
import numpy as np
......@@ -6,7 +6,7 @@ import numpy as np
# Deals with similarity scores
bh = BaseHandler(51, 5)
qe = QualityEvaluator()
qe = QualityTemp()
#qual_scores = qe.getBrisqueValues()
#qual_scores_f = qe.getFocusValues()
......@@ -18,6 +18,7 @@ qe = QualityEvaluator()
qual_scores = np.load('data/quality_focus_norm_0.npy')
sim_scores = np.load('data/sim_scores_0_noise.npy')
print("Length: ", len(qual_scores))
'''
sim_scores_p = np.load('data/sim_scores.npy')
sim_scores_psp = np.load('data/sim_scores_psp_noise.npy')
......@@ -63,8 +64,6 @@ for i in range(1, 6):
#gq,iq = qe.removeLowQualValues(sim_scores, qual_scores, bh, i)
g_p,i_p = qe.removeLowQualValues(sim_scores, qual_scores, bh, i)
if len(i_p) != 0 and len(g_p) != 0:
......
import imp
import cv2
import numpy as np
import insightface
from insightface.app import FaceAnalysis
from insightface.data import get_image as ins_get_image
from qualityEvaluation import QualityEvaluator
# Vars
#path = '/Users/krunal/Desktop/code/database'
......@@ -11,10 +13,21 @@ imgsdir = 'img/Casia_Converted_Noise/Gaussian_Salted/'
imgsdir_other = 'img/Casia_Converted/'
imgsdir_other_other = 'img/Casia_Converted_Noise/ScrambledEggs_l/'
params = [51, 5]
# Init Evaulator
QualEval = QualityEvaluator("ArcFaceCasiaV2")
QualEval.ArcFace_init()
# Read in dataset
QualEval.readInDataset(params, projectpath, imgsdir, "subjectnr/subjectnr_samplenr", "ArcFaceCasia", True ) # V5 eller V2
# TODO change names
imgsnr = 51
change_me = 5
img_obs = []
img_obs = QualEval.getImgObs()
class img_o:
def __init__(self, img, face, name ):
......@@ -23,6 +36,7 @@ class img_o:
self.feat = None
self.name = name
'''
# Set up detector and recognizer
app = FaceAnalysis(providers=['CUDAExecutionProvider', 'CPUExecutionProvider'])
app.prepare(ctx_id=0, det_size=(640, 640))
......@@ -57,6 +71,10 @@ for i in range (0, imgsnr):
imgob.feat = handler.get(imgob.img, imgob.face[0])
img_obs[i].append(imgob)
'''
handler = QualEval.handler
app = QualEval.app
# Calculate sim scores
sim_scores = []
......@@ -81,7 +99,7 @@ for i in range(0, len(img_obs)):
new_array = np.array(sim_scores)
spath = "data/sim_scores_0_noise.npy"
print("Saving to: ", spath)
np.save(spath, new_array)
#np.save(spath, new_array)
......
......@@ -4,9 +4,7 @@ import cv2
import numpy as np
from insightface.app import FaceAnalysis
from insightface.data import get_image as ins_get_image
from matplotlib import pyplot as plt
import scipy
from qualityEvaluation import QualityAssesmenet
from qualityEvaluation import QualityAssesmenet, Image_Preparator
......@@ -18,104 +16,14 @@ from qualityEvaluation import QualityAssesmenet
#fullpath = projectpath + "img1" #imgsdir + "001/001_1"
#fullpath = projectpath + imgsdir + "001/001_1"
class Image_Preparator:
def __init__(self) -> None:
self.app = FaceAnalysis(allowed_modules=['detection']) # enable detection model only
self.app.prepare(ctx_id=0, det_size=(640, 640))
pass
def read_in(self, path: str):
image = ins_get_image(path)
return image
def segment(self, image):
face = self.app.get(image)
box = face[0].bbox.astype(np.int)
# xy
# Top left (box[0], box[1]), yl xt,
# Bottom Left (box[2], box[3]) yr, xb
# xt:xb yl:yr
crop_img = image[box[1]:box[3], box[0]:box[2]].copy()
return crop_img
def segment_square(self, image):
face = self.app.get(image)
box = face[0].bbox.astype(np.int)
# Determine smallest dimension
x = box[3] - box[1]
y = box[2] - box[0]
diff = abs(x-y)
if (np.mod(diff,2)!=0):
diff1 = int(diff/2) +1
diff2 = int(diff/2)
else:
diff1 = int(diff/2)
diff2 = int(diff/2)
#Mod smallest dimension
if x < y:
box[3] = box[3] +diff1
box[1] = box[1] -diff2
elif y<x:
box[2] = box[2] + diff1
box[0] = box[0] - diff2
return image[box[1]:box[3], box[0]:box[2]].copy()
def draw(self, img, dest):
faces = self.app.get(img)
rimg = self.app.draw_on(img, faces)
cv2.imwrite(dest, rimg)
def luimanence(self, image):
lum = np.zeros(shape=(len(image), len(image[0])))
for i in range(len(image)):
for j in range(len(image[0])):
convert = False
t = 0.04045
npx = [0,0,0]
# Normalize each pixel
for k in range(3):
nc = image[i][j][k]/255
if(nc <= t): convert = True
# Perform Gamma Inversion
if(convert):
if(nc > t):
nc = (nc + 0.055)/1.0558
else:
nc = nc/ 12.92
nc = pow(nc, 2.4)
npx[k] = nc
# Calculate luiminance
#if sum(npx) > 1: print(npx)
lum[i][j] = 0.2126*npx[0]+ 0.7152*npx[1] + 0.0722*npx[2]
return lum
def ColorConvert(V):
return -1
def calculate(projectpath, subnr, samplenr, flavor):
def calculate(projectpath, subnr, samplenr, flavor, app):
# Variables
q = QualityAssesmenet()
d = Image_Preparator()
d = Image_Preparator(app)
f_list = []
s_list = []
......@@ -144,6 +52,7 @@ def calculate(projectpath, subnr, samplenr, flavor):
elif j ==1: fullpath = projectpath + imgsdir_other_other + subjectdir
else: fullpath = projectpath + imgsdir + subjectdir
fullpath = projectpath + imgsdir + subjectdir
imgname = subjectnr + '_' + str(j)
im = d.read_in(fullpath + imgname)
......@@ -163,48 +72,62 @@ def calculate(projectpath, subnr, samplenr, flavor):
f_list[i].append(f)
s_list[i].append(s)
print(s_list)
# Save to file
f_arr = np.array(f_list)
s_arr = np.array(s_list)
#f_arr = np.array(f_list)
#s_arr = np.array(s_list)
spath = "data/quality_sharpness_" + flavor+ ".npy"
fpath = "data/quality_focus_" + flavor+ ".npy"
#spath = "data/quality_sharpness_" + flavor+ ".npy"
#fpath = "data/quality_focus_" + flavor+ ".npy"
print("Avg s: ", np.mean(s_arr))
print("Std s: ", np.std(s_arr))
#print("Avg s: ", np.mean(s_arr))
#print("Std s: ", np.std(s_arr))
print("Avg f: ", np.mean(f_arr))
print("Std f: ", np.std(f_arr))
#print("Avg f: ", np.mean(f_arr))
#print("Std f: ", np.std(f_arr))
#np.save(fpath, f_arr)
#np.save(spath, s_arr)
f_norm = q.quality_normalize(f_arr)
s_norm = q.quality_normalize(s_arr)
#f_norm = q.quality_normalize(f_arr)
#s_norm = q.quality_normalize(s_arr)
fpath = "data/quality_focus_norm_" + flavor+ ".npy"
print("Saving to: ", fpath)
np.save(fpath, f_norm)
#fpath = "data/quality_focus_norm_" + flavor+ ".npy"
#print("Saving to: ", fpath)
#np.save(fpath, f_norm)
spath = "data/quality_sharpness_norm_" + flavor+ ".npy"
print("Saving to: ", spath)
np.save(spath, s_norm)
#spath = "data/quality_sharpness_norm_" + flavor+ ".npy"
#print("Saving to: ", spath)
#np.save(spath, s_norm)
print("-----------------------------------------------")
projectpathh = 'C:/Users/maria/Desktop/Biometrics/TermPaper/imt4126-biometricqualitymetrics/'
imgsdir_o = 'img/Casia_Converted_Noise/Gaussian_Salted/'
flavor = ["Normal", "Gaussian", "Poisson", "GP", "PG", "PSP"]
calculate(projectpathh, 51, 5, "0")
app = FaceAnalysis(allowed_modules=['detection']) # enable detection model only
app.prepare(ctx_id=0, det_size=(640, 640))
calculate(projectpathh, 51, 5, "0", app)
'''
app = FaceAnalysis(allowed_modules=['detection']) # enable detection model only
app.prepare(ctx_id=0, det_size=(640, 640))
m = QualityMetric("sharpness", app)
m.calculate(projectpath,imgsdir_o, 51, 5, True)
print(m.getQualityValues())
'''
from urllib.request import BaseHandler
from qualityEvaluation import QualityEvaluator, QualityMetric
from insightface.app import FaceAnalysis
from insightface.data import get_image as ins_get_image
from EDC import EDC
import numpy as np
from qualityEvaluation import QualityTemp
from utils.baseScore import BaseHandler
import matplotlib.pyplot as mpl
# Init vars
params = [51, 5]
projectpath = 'C:/Users/maria/Desktop/Biometrics/TermPaper/imt4126-biometricqualitymetrics/'
imgsdir = 'img/Casia_Converted_Noise/Gaussian_Salted/'
imgsdir_other = 'img/Casia_Converted/'
imgsdir_other_other = 'img/Casia_Converted_Noise/ScrambledEggs_l/'
# Init Evaulator
print("--* Initing Evaulator")
#QualEval = QualityEvaluator("ArcFaceCasiaTesting", projectpath, imgsdir)
print("-- * Initing Arcface")
#QualEval.ArcFace_init()
print("--* Reading in Dataset")
# Read in dataset
#QualEval.readInDataset(params, projectpath, imgsdir, "subjectnr/subjectnr_samplenr", "ArcFaceCasiaMedley", True ) # V5 eller V2
#Compute baseline
print("--* Computing Baselines")
#QualEval.ComputeBaselines()
print("--* Saving Baselines")
#QualEval.SaveBaslines()
# Compute metrics
print("--* Detecting Init")
#QualEval.Detection_Arcface_init()
print("--* Computing metrics")
#QualEval.ComputeMetric("sharpness")
#QualEval.SaveMetric("sharpness")
print("--* Plotting Metrics")
#QualEval.PlotMetric("EDC", "sharpness",subnr=51, sampnr=5)
#QualEval.PlotDETCurve(51,5)
# Print curves
# QualEval.PlotMetric("DET", "sharpness")
def test():
edc = EDC(1,5,0.6, metricname="Sharpness")
'''
qials= np.array([ 5, 4, 4, 4, 4, 2, 5, 2, 3, 3, 4, 5, 6, 3, 2, 3, 4, 5, 4, 5])
q_2 = np.array([ 4, 4, 3, 5, 3, 3, 5, 3, 3, 4, 3, 3, 2, 4, 3, 3, 3, 5, 2, 4])
gens = np.array([0.00,0.50,0.23,0.66,0.54,0.30,0.95,0.23,0.50,0.67,0.65,0.96,0.45,0.11,0.14,0,31,0.02,0.09,0.27,0.32])
quals = np.transpose(np.array([qials, q_2]))
perfect_q1 = np.array([ 1, 4, 2, 4, 4, 2, 5, 2, 3, 4, 4, 5, 5, 1, 2, 3, 1, 1, 2, 2])
perfect_q2 = np.array([ 1, 3, 3, 5, 4, 3, 5, 3, 3, 4, 3, 4, 4, 1, 1, 2, 1, 1, 2, 3])
gens = np.array([0.00,0.50,0.23,0.66,0.54,0.30,0.95,0.23,0.50,0.67,0.65,0.96,0.45,0.11,0.14,0,31,0.02,0.09,0.27,0.32])
quals = np.transpose(np.array([perfect_q1, perfect_q2]))
'''
qu = QualityTemp(True)
bh = BaseHandler(51, 5)
sims = np.load("data/sim_scores_0_noise.npy")
quals = np.load("data/quality_sharpness_norm_0.npy")
quals = qu.getBrisqueValues()
gens, quals = qu.getAllGenuine(bh, sims, quals)
gens = np.array(gens)
quals = np.array(quals)
edc.setup()
edc.plotEDC(gens, quals )
edc.showEDC()
'''
qu = QualityTemp(True)
bh = BaseHandler(51, 5)
sims = np.load("data/sim_scores_0_noise.npy")
quals = np.load("data/quality_sharpness_norm_0.npy")
gens, quals = qu.getAllGenuine(bh, sims, quals)
gens = np.array(gens)
quals = np.array(quals)
ii = np.argsort(quals[:,0], kind='mergesort')
gens_s = gens[ii]
quals_s = quals[ii,0]
#for i in range(len(gens_s)):
# print(gens_s[i], ": " , quals_s[i])
mpl.figure()
mpl.plot(quals_s, gens_s, label="label", color=(0.3, 0.3, 0.0), linestyle='-', linewidth=1)
print(quals_s)
#mpl.plot(gens_s, quals_s[:,0], label="label", color=(0.3, 0.0, 0.3), linestyle='-', linewidth=1)
mpl.show()
'''
test()