Skip to content
Snippets Groups Projects
Commit 25e67e3c authored by Maria Kleppestø Mcculloch's avatar Maria Kleppestø Mcculloch
Browse files

First version

parent e663e61f
No related branches found
No related tags found
No related merge requests found
# Tested with Python 3.8.3
import os # Only used in usage_example
import sys # Only used in cli_main
import cv2 # Tested with opencv-python 4.4.0.44
import dlib # Tested with dlib 19.22.0
import numpy as np # Tested with numpy 1.18.5
def cli_main():
"""CLI entry function for usage_example"""
usage_example(
image_dir=sys.argv[1]
if len(sys.argv) > 1 else "images",
dlib_landmark_detector_path=sys.argv[2]
if len(sys.argv) > 2 else
"shape_predictor_68_face_landmarks.dat"
)
def usage_example(image_dir: str, dlib_landmark_detector_path: str):
"""The dlib_landmark_detector_path should point to the shape_predictor_68_face_landmarks.dat model
file, which is available here: http://dlib.net/files/shape_predictor_68_face_landmarks.dat.bz2
Note that the license of this model's training data excludes commercial use.
You can find additional information in the general Dlib landmark detector Python example,
available at: http://dlib.net/face_landmark_detection.py.html
"""
dlib_landmark_detector = dlib.shape_predictor(dlib_landmark_detector_path)
image_filenames = os.listdir(image_dir)
quality_scores = []
for image_filename in image_filenames:
image_path = os.path.join(image_dir, image_filename)
image = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
quality_score = compute_illumination_uniformity(image, dlib_landmark_detector)
quality_scores.append(quality_score)
print(f"Count={len(quality_scores)}"
f" Min={np.min(quality_scores)} Max={np.max(quality_scores)} Mean={np.mean(quality_scores)}")
def compute_illumination_uniformity(image, dlib_landmark_detector):
# Note that this example assumes that the image is already cropped to the face region.
# Step 1: Find the eye center points and the inter-eye center point.
dlib_landmarks = dlib_landmark_detector(image, dlib.rectangle(0, 0, image.shape[1],
image.shape[0]))
left_eye_center = (dlib_landmarks.part(37) + dlib_landmarks.part(40)) * 0.5
right_eye_center = (dlib_landmarks.part(43) + dlib_landmarks.part(46)) * 0.5
inter_eye_center = (left_eye_center + right_eye_center) * 0.5
# Step 2: Determine the slope and intercept of the dividing line.
slope = get_slope(left_eye_center, right_eye_center)
if slope != 0:
intercept = inter_eye_center.y - (slope * inter_eye_center.x)
else:
intercept = inter_eye_center.x
# Step 3: Establish disjunct per-pixel masks for the left and right half.
y_values = np.zeros(image.shape[:2])
if slope != 0:
y_values[:, :] = np.arange(image.shape[0]).reshape(image.shape[0], 1)
right_mask = y_values > (np.arange(image.shape[1]) * slope + intercept)
else:
y_values[:, :] = np.arange(image.shape[0])
right_mask = y_values > intercept
left_mask = np.logical_not(right_mask)
# Step 4: Compute the normalized histograms for the halves.
left_histogram = get_normalized_histogram(image, left_mask)
right_histogram = get_normalized_histogram(image, right_mask)
# Step 5: Return the scaled sum of the element-wise minimum of the normalized histograms as the
#quality score.
min_histogram = np.minimum(left_histogram, right_histogram)
quality_score = int(100 * np.sum(min_histogram))
return quality_score
def get_slope(point1, point2):
return -(point2.x - point1.x) / (point2.y - point1.y) if point2.y != point1.y else 0
def get_normalized_histogram(image, mask):
histogram = cv2.calcHist([image], [0], mask.astype(np.uint8), [256], [0, 256])
histogram = histogram.flatten()
histogram /= np.sum(histogram)
return histogram
if __name__ == "__main__":
cli_main()
\ No newline at end of file
...@@ -8,27 +8,77 @@ bh = BaseHandler(51, 5) ...@@ -8,27 +8,77 @@ bh = BaseHandler(51, 5)
qe = QualityEvaluator() qe = QualityEvaluator()
qual_scores = qe.getBrisqueValues(); #qual_scores = qe.getBrisqueValues()
sim_scores = np.load('data/sim_scores_noise.npy') #qual_scores_f = qe.getFocusValues()
#qual_scores_s_p = qe.getSharpnessValues("P")
#qual_scores_s_g = qe.getSharpnessValues("gp")
#qual_scores_s_psp = qe.getSharpnessValues("psp")
gens = qe.getAllGenuine(bh, sim_scores)
imps = qe.getAllImposters(bh, sim_scores)
qual_scores = np.load('data/quality_focus_norm_0.npy')
sim_scores = np.load('data/sim_scores_0_noise.npy')
# Balck Purple Blue DarkGreen Red LightGreen BlackDots '''
sim_scores_p = np.load('data/sim_scores.npy')
sim_scores_psp = np.load('data/sim_scores_psp_noise.npy')
gens_p = qe.getAllGenuine(bh, sim_scores_p)
imps_p = qe.getAllImposters(bh, sim_scores_p)
'''
gens_g = qe.getAllGenuine(bh, sim_scores)
imps_g = qe.getAllImposters(bh, sim_scores)
print("Number of imps: ", len(imps_g))
'''
gens_psp = qe.getAllGenuine(bh, sim_scores_psp)
imps_psp = qe.getAllImposters(bh, sim_scores_psp)
gen_score_aggr = [gens_p,gens_g,gens_psp]
imp_score_aggr = [imps_p,imps_g, imps_psp]
gens = []
imps = []
for i in range(len(gen_score_aggr)):
gg = gen_score_aggr[i]
ii = imp_score_aggr[i]
for j in range(len(gg)):
gens.append(gg[j])
for j in range(len(ii)):
imps.append(ii[j])
'''
# Balck Purple Blue DarkGreen Red LightGreen BlackDots
colour = [ "Kitty", "Disco", "Rabbit","Dog" , "Card", "Mickey", "Mask"] colour = [ "Kitty", "Disco", "Rabbit","Dog" , "Card", "Mickey", "Mask"]
#print(qual_scores.shape, " ", max(qual_scores), " ", min(qual_scores))
# Genereate sim scores # Genereate sim scores
for i in range(1, 5): for i in range(1, 6):
#gq,iq = qe.removeLowQualValues(sim_scores, qual_scores, bh, i) #gq,iq = qe.removeLowQualValues(sim_scores, qual_scores, bh, i)
g_p,i_p = qe.removeLowQualValues(sim_scores, qual_scores, bh, i) g_p,i_p = qe.removeLowQualValues(sim_scores, qual_scores, bh, i)
#g_p, i_p = qe.prepare(gq,iq)
print(max(i_p), " " , min(i_p))
print(len(g_p), " ", len(i_p))
#qe.plotDET(g_p, i_p, colour[i] )
qe.plotDET(gens, imps, colour[1] )
if len(i_p) != 0 and len(g_p) != 0:
print(i, ":")
print("Have gorund: " ,max(i_p) > min(i_p))
print(len(g_p), " ", len(i_p))
qe.plotDET(g_p, i_p, colour[i] )
else:
print(i, ": Empty: ", len(g_p), " || ", len(i_p))
'''
gens, imps = gens_g, imps_g
print(len(gens), " ", len(imps))
print(max(imps), " " , min(gens))
qe.plotDET(gens, imps,"Kitty" )
'''
qe.showDET() qe.showDET()
...@@ -7,7 +7,9 @@ from insightface.data import get_image as ins_get_image ...@@ -7,7 +7,9 @@ from insightface.data import get_image as ins_get_image
# Vars # Vars
#path = '/Users/krunal/Desktop/code/database' #path = '/Users/krunal/Desktop/code/database'
projectpath = 'C:/Users/maria/Desktop/Biometrics/TermPaper/imt4126-biometricqualitymetrics/' projectpath = 'C:/Users/maria/Desktop/Biometrics/TermPaper/imt4126-biometricqualitymetrics/'
imgsdir = 'img/Casia_Converted_Noise/Gaussian/' imgsdir = 'img/Casia_Converted_Noise/Gaussian_Salted/'
imgsdir_other = 'img/Casia_Converted/'
imgsdir_other_other = 'img/Casia_Converted_Noise/ScrambledEggs_l/'
# TODO change names # TODO change names
imgsnr = 51 imgsnr = 51
...@@ -32,13 +34,20 @@ handler.prepare(ctx_id=0) ...@@ -32,13 +34,20 @@ handler.prepare(ctx_id=0)
for i in range (0, imgsnr): for i in range (0, imgsnr):
subjectnr = '00' + str(i) if i<10 else '0' + str(i) subjectnr = '00' + str(i) if i<10 else '0' + str(i)
subjectdir = subjectnr + '/' subjectdir = subjectnr + '/'
fullpath = projectpath + imgsdir + subjectdir
print("Path" + imgsdir + subjectdir) print("Path" + imgsdir + subjectdir)
img_obs.append([]) img_obs.append([])
print("Read in for: " + str(i) + "-th subject") print("Read in for: " + str(i) + "-th subject")
for j in range(0, change_me): for j in range(0, change_me):
if j == 0: fullpath = projectpath + imgsdir_other + subjectdir
elif j ==1: fullpath = projectpath + imgsdir_other_other + subjectdir
else: fullpath = projectpath + imgsdir + subjectdir
#fullpath = projectpath + imgsdir + subjectdir
imgname = subjectnr + '_' + str(j) imgname = subjectnr + '_' + str(j)
#print(subjectdir + name) #print(subjectdir + name)
#convert(projectpath + 'Casia/' + subjectdir + imgname + ".bmp", imgname + ".jpg", fullpath ) #convert(projectpath + 'Casia/' + subjectdir + imgname + ".bmp", imgname + ".jpg", fullpath )
...@@ -70,7 +79,9 @@ for i in range(0, len(img_obs)): ...@@ -70,7 +79,9 @@ for i in range(0, len(img_obs)):
# Save to file # Save to file
new_array = np.array(sim_scores) new_array = np.array(sim_scores)
np.save("data/sim_scores_noise.npy", new_array) spath = "data/sim_scores_0_noise.npy"
print("Saving to: ", spath)
np.save(spath, new_array)
......
function computeBrisque() function computeBrisque()
high_path = "img/Casia_Converted"; fullpath = "img/Casia_Converted";
imgsdir = "img/Casia_Converted_Noise/Gaussian_Salted/"
imgsdir_other = "img/Casia_Converted/"
imgsdir_other_other = "img/Casia_Converted_Noise/ScrambledEggs_l/"
% For all subjects % For all subjects
for i =1:51 for i =1:51
if (i-1) <10 if (i-1) <10
nr = "0" + (i-1); nr = "0" + (i-1);
else else
...@@ -13,6 +20,14 @@ function computeBrisque() ...@@ -13,6 +20,14 @@ function computeBrisque()
sub_nr = "0" + nr; sub_nr = "0" + nr;
for j=1:5 for j=1:5
if (j == 1)
high_path = imgsdir_other;
elseif(j ==2)
high_path = imgsdir_other_other ;
else
high_path = imgsdir;
end
path = high_path + '/' + sub_nr + '/' + sub_nr + '_' + (j-1) + '.jpg'; path = high_path + '/' + sub_nr + '/' + sub_nr + '_' + (j-1) + '.jpg';
img = imread(path); img = imread(path);
......
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
#projectpath = 'C:/Users/maria/Desktop/Biometrics/TermPaper/imt4126-biometricqualitymetrics/'
#imgsdir = 'img/Casia_Converted_Noise/Gaussian_Poisson/'
#imgsdir = 'img/Casia_Converted/'
#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):
# Variables
q = QualityAssesmenet()
d = Image_Preparator()
f_list = []
s_list = []
# For each subject
for i in range (0, subnr):
subjectnr = '00' + str(i) if i<10 else '0' + str(i)
subjectdir = subjectnr + '/'
# Print("Path" + imgsdir + subjectdir)
print("Read in for: " + str(i) + "-th subject")
# Focus values
f_list.append([])
# Sharpness values
s_list.append([])
for j in range(0, samplenr):
imgsdir = 'img/Casia_Converted_Noise/Gaussian_Salted/'
imgsdir_other = 'img/Casia_Converted/'
imgsdir_other_other = 'img/Casia_Converted_Noise/ScrambledEggs_l/'
if j == 0: fullpath = projectpath + imgsdir_other + subjectdir
elif j ==1: fullpath = projectpath + imgsdir_other_other + subjectdir
else: fullpath = projectpath + imgsdir + subjectdir
imgname = subjectnr + '_' + str(j)
im = d.read_in(fullpath + imgname)
# Get segments
crop = d.segment(im)
square= d.segment_square(im)
#cv2.imwrite( "./tesytes" , im)
lum = d.luimanence(crop)
lum_s = d.luimanence(square)
f = q.de_focus(lum)
s = q.Sharpness(lum_s)
f_list[i].append(f)
s_list[i].append(s)
# Save to file
f_arr = np.array(f_list)
s_arr = np.array(s_list)
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 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)
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)
print("-----------------------------------------------")
projectpathh = 'C:/Users/maria/Desktop/Biometrics/TermPaper/imt4126-biometricqualitymetrics/'
flavor = ["Normal", "Gaussian", "Poisson", "GP", "PG", "PSP"]
calculate(projectpathh, 51, 5, "0")
function generateArtificalData(Path) function generateArtificalData(Path)
high_path_destination = "img/Casia_Converted_Noise/Gaussian"; high_path_destination = "img/Casia_Converted_Noise/Gaussian_Salted";
high_path_source = "img/Casia_Converted"; high_path_source = "img/Casia_Converted";
% For all subjects % For all subjects
for i =1:51 for i =1:51
...@@ -13,6 +13,7 @@ function generateArtificalData(Path) ...@@ -13,6 +13,7 @@ function generateArtificalData(Path)
sub_nr = "0" + nr; sub_nr = "0" + nr;
mkdir(high_path_destination + '/' + sub_nr ) mkdir(high_path_destination + '/' + sub_nr )
for j=1:5 for j=1:5
imgpath = '/' + sub_nr + '/' + sub_nr + '_' + (j-1) + '.jpg'; imgpath = '/' + sub_nr + '/' + sub_nr + '_' + (j-1) + '.jpg';
...@@ -22,9 +23,13 @@ function generateArtificalData(Path) ...@@ -22,9 +23,13 @@ function generateArtificalData(Path)
img = imread(path_source); img = imread(path_source);
i = imnoise(img,'gaussian');
imwrite(i, high_path_destination + imgpath) img = imnoise(img,'gaussian');
%img = imnoise(img,'speckle');
img = imnoise(img,'salt & pepper');
%img = imnoise(img,'poisson');
imwrite(img, high_path_destination + imgpath)
%J = imnoise(I,'gaussian') %J = imnoise(I,'gaussian')
%J = imnoise(I,'gaussian',m) %J = imnoise(I,'gaussian',m)
......
hh.m 0 → 100644
high_path_destination = "img/Casia_Converted_Noise/Poisson_Gaussian";
high_path_source = "img/Casia_Converted";
imgpath = '/001/001_0.jpg';
path_source = high_path_source + imgpath;
img = imread(path_source);
img = imnoise(img,'gaussian');
img = imnoise(img,'speckle');
img = imnoise(img,'salt & pepper');
img = imnoise(img,'poisson');
disp("jhh")
figure
imshow(img)
imgpath2 = '/004/004_0.jpg';
path_source2 = high_path_source + imgpath2;
img3 = imread(path_source2);
img3 = imnoise(img3,'gaussian');
img3 = imnoise(img3,'speckle');
img3 = imnoise(img3,'salt & pepper');
img3 = imnoise(img3,'poisson');
figure
imshow(img3)
\ No newline at end of file
...@@ -5,6 +5,11 @@ import numpy as np ...@@ -5,6 +5,11 @@ import numpy as np
from utils.baseScore import BaseHandler from utils.baseScore import BaseHandler
from DET.DET import DET from DET.DET import DET
import matplotlib.pyplot as mpl import matplotlib.pyplot as mpl
from insightface.app import FaceAnalysis
from insightface.data import get_image as ins_get_image
from matplotlib import pyplot as plt
import scipy
...@@ -31,9 +36,20 @@ class QualityEvaluator: ...@@ -31,9 +36,20 @@ class QualityEvaluator:
data[i][j] = float(data_s[i][ j]) data[i][j] = float(data_s[i][ j])
return data return data
def getFocusValues(self):
path_brisque = "data/quality_focus_norm.npy"
return np.load(path_brisque)
def getSharpnessValues(self, flavor="P"):
if flavor == "PSP" : path_brisque = "data/quality_sharpness_norm_PSP.npy"
elif flavor == "P": path_brisque = "data/quality_sharpness_norm.npy"
elif flavor == "GP": path_brisque = "data/quality_sharpness_norm_gp.npy"
elif flavor == "G": path_brisque = "data/quality_sharpness_norm_g.npy"
return np.load(path_brisque)
# Rejection set # Rejection set
...@@ -114,8 +130,9 @@ class QualityEvaluator: ...@@ -114,8 +130,9 @@ class QualityEvaluator:
return int((q1+q2)/2) return int((q1+q2)/2)
def eval_quality(self, q1: int, q2:int, k: int) -> bool: def eval_quality(self, q1: int, q2:int, k: int) -> bool:
return True #return True
#return self.H(q1, q2) == k return (q1==k or q2==k)
return self.H(q1, q2) == k
def removeLowQualValues(self, sim_scores: list, quality_scores: list, bh: BaseHandler, ql:int) -> list: def removeLowQualValues(self, sim_scores: list, quality_scores: list, bh: BaseHandler, ql:int) -> list:
#g_s, i_s = prepare(getAllGenuine(bh, sim_scores), getAllImposters(bh, sim_scores)) #g_s, i_s = prepare(getAllGenuine(bh, sim_scores), getAllImposters(bh, sim_scores))
...@@ -136,7 +153,7 @@ class QualityEvaluator: ...@@ -136,7 +153,7 @@ class QualityEvaluator:
#print("S score: " + s[1], "|| ", i, " ", j, " x ", k, " ", l) #print("S score: " + s[1], "|| ", i, " ", j, " x ", k, " ", l)
if (self.eval_quality(q1, q2, ql)): if (self.eval_quality(q1, q2, ql)):
if(i==k): if(i==k):
if k<l: g_s_new.append(float(s[0])) if j<l: g_s_new.append(float(s[0]))
else: else:
i_s_new.append(float(s[0])) i_s_new.append(float(s[0]))
...@@ -164,3 +181,78 @@ class QualityEvaluator: ...@@ -164,3 +181,78 @@ class QualityEvaluator:
return gl,il return gl,il
class QualityAssesmenet:
def __init__(self) -> None:
self.a = 0.0606690309518936
self.b = 0.01
self.c = 5.292513593982813
self.d = 1
pass
def quality_normalize(self, m):
f_norm = m
for i in range(len(f_norm)):
for j in range(len(f_norm[0])):
if f_norm[i][j] < 20: f_norm[i][j] = 1
if f_norm[i][j] < 40 and f_norm[i][j] >= 20: f_norm[i][j] = 2
if f_norm[i][j] < 60 and f_norm[i][j] >= 40: f_norm[i][j] = 3
if f_norm[i][j] < 80 and f_norm[i][j] >= 60: f_norm[i][j] = 4
if f_norm[i][j] >= 80: f_norm[i][j] = 5
return f_norm
def de_focus(self, luiminance_map):
Bs = self.mean_filter(luiminance_map)
Ds = abs(Bs - luiminance_map)
dim = Ds.shape
Blurloss = (sum(sum(Ds)))/(dim[0]*dim[1])
return (1 - self.SIGMOID(Blurloss, self.a, self.b))*100
#return Blurloss
def mean_filter(self, arr, filtersize=3):
w = np.full((filtersize, filtersize), 1.0/(filtersize*filtersize))
return scipy.ndimage.filters.convolve(arr, w)
def map_quality(raw):
return raw/100
def Sharpness(self, luiminance_map):
Ls = luiminance_map
n = len(luiminance_map)
Hm = luiminance_map
# Find mean of H
mean = np.mean(Hm)
Gm = Hm
# Subtract mean from every normalized pixel values
for i in range(len(luiminance_map)):
for j in range(len(luiminance_map[0])):
if Gm[i][j] != 0: Gm[i][j] = Gm[i][j] - mean
# Compute the covariance matrix
np_G = np.array(Gm)
np_G_t = np.transpose(np_G)
Ss = (1/(n-1))*np.matmul(np_G, np_G_t)
# Find N eigenvalues of D
eigs = np.linalg.eig(Ss)[0]
# Compute the trace sum of eigenvalues
sum = 0
for i in range(len(eigs)):
sum = sum + float(eigs[i])
return 100*(1-self.SIGMOID(sum,self.c,self.d ))
#return sum
def SIGMOID(self, x, x0, w):
return float(1/(1 + np.exp((x0-x)/w)))
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment