192 lines
6.3 KiB
Python
192 lines
6.3 KiB
Python
import itertools
|
|
import os
|
|
import time
|
|
|
|
import torch
|
|
import cv2
|
|
import numpy as np
|
|
from backbones import iresnet50,iresnet18,iresnet100
|
|
|
|
# print(torch.cuda.is_available())
|
|
def load_image(img_path):
|
|
img = cv2.imread(img_path)
|
|
#print(img)
|
|
#img2 = np.fliplr(img)
|
|
#print(img2.shape)
|
|
img = img.transpose((2, 0, 1))
|
|
#img2 = img2.transpose((2, 0, 1))
|
|
img = img[np.newaxis, :, :, :]
|
|
#img2 = img2[np.newaxis, :, :, :]
|
|
#img = np.concatenate((img,img2))
|
|
img = np.array(img, dtype=np.float32)
|
|
img -= 127.5
|
|
img /= 127.5
|
|
return img
|
|
|
|
def findEuclideanDistance(source_representation, test_representation):
|
|
euclidean_distance = source_representation - test_representation
|
|
euclidean_distance = np.sum(np.multiply(euclidean_distance, euclidean_distance))
|
|
euclidean_distance = np.sqrt(euclidean_distance)
|
|
return euclidean_distance
|
|
|
|
def findCosineDistance(source_representation, test_representation):
|
|
a = np.matmul(np.transpose(source_representation), test_representation)
|
|
b = np.sum(np.multiply(source_representation, source_representation))
|
|
c = np.sum(np.multiply(test_representation, test_representation))
|
|
return 1 - (a / (np.sqrt(b) * np.sqrt(c)))
|
|
|
|
def l2_normalize(x):
|
|
return x / np.sqrt(np.sum(np.multiply(x, x)))
|
|
|
|
def cosin_metric(x1, x2):
|
|
return np.dot(x1, x2) / (np.linalg.norm(x1) * np.linalg.norm(x2))
|
|
|
|
def get_file_list(file_name):
|
|
file1 = []
|
|
file2 = []
|
|
code = []
|
|
with open(file_name,"r") as f:
|
|
file_list = f.readlines()
|
|
for i in file_list:
|
|
data = i.replace("\n","").split(" ")
|
|
file1.append(data[0])
|
|
file2.append(data[1])
|
|
code.append(data[2])
|
|
return file1,file2,code
|
|
|
|
def load_list_images(file_list):
|
|
all = np.zeros((len(file_list),3,112,112),dtype=np.float32)
|
|
count = 0
|
|
for img_path in file_list:
|
|
img = cv2.imread(img_path)
|
|
img = img.transpose((2, 0, 1))
|
|
img = img[np.newaxis, :, :, :]
|
|
all[count] = img
|
|
count = count + 1
|
|
all -= 127.5
|
|
all /= 127.5
|
|
return all
|
|
|
|
def threshold_acc(distance,code):
|
|
#thresholds = np.arange(24,36,0.1)
|
|
thresholds = np.arange(0.5,2, 0.1)
|
|
total = len(code)
|
|
max_acc = 0
|
|
threshold = 0
|
|
code_net = []
|
|
for i in thresholds:
|
|
for ds in distance:
|
|
if ds < i:
|
|
code_net.append(1)
|
|
else:
|
|
code_net.append(0)
|
|
right = np.sum(code==code_net)
|
|
#print(threshold, max_acc)
|
|
if right/total > max_acc:
|
|
max_acc = right / total
|
|
threshold = i
|
|
code_net = []
|
|
return threshold,max_acc
|
|
|
|
def reject_and_error(distance,code):
|
|
total = len(code)
|
|
threshold = 1.20
|
|
code_net = []
|
|
reject = 0
|
|
error = 0
|
|
for ds in distance:
|
|
if ds < threshold:
|
|
code_net.append(1)
|
|
else:
|
|
code_net.append(0)
|
|
right = np.sum(code==code_net)
|
|
max_acc = right / total
|
|
#print(max_acc,threshold)
|
|
for i in range(total):
|
|
if code[i] == 1:
|
|
if code_net[i] == 0:
|
|
reject += 1
|
|
else:
|
|
if code_net[i] == 1:
|
|
error += 1
|
|
return reject,error,right
|
|
# if __name__=='__main__':
|
|
# img1 = load_image("D:\Download\out\centerface_test\Adolfo_Rodriguez_Saa\Adolfo_Rodriguez_Saa_0002.jpg")
|
|
# img1 = torch.from_numpy(img1)
|
|
# #print(img1.shape)
|
|
# #print(img1)
|
|
# img2 = load_image("D:\Download\out\centerface_database\Dario_Franchitti\Dario_Franchitti_0001.jpg")
|
|
# img2 = torch.from_numpy(img2)
|
|
# model = iresnet100()
|
|
# model.load_state_dict(torch.load("./model/backbone100.pth",map_location="cpu"))
|
|
# #print(model)
|
|
# model.eval()
|
|
# with torch.no_grad():
|
|
# start_time = time.time()
|
|
# pred1 = model(img1)
|
|
# #print(pred1.shape)
|
|
# #print(pred1)
|
|
# pred2 = model(img2)
|
|
# pred1 = pred1.numpy()
|
|
# #print(pred1.shape)
|
|
# pred2 = pred2.numpy()
|
|
# distance = findEuclideanDistance(l2_normalize(pred1),l2_normalize(pred2))
|
|
# end_time = time.time()
|
|
# print("EuclideanDistance is :" + str(distance))
|
|
# if distance < 1.20:
|
|
# print("对比两张相同的人脸用时:"+str(end_time - start_time))
|
|
# else:
|
|
# print("对比两张不同的人脸用时:" + str(end_time - start_time))
|
|
|
|
|
|
if __name__=='__main__':
|
|
model = iresnet100()
|
|
model.load_state_dict(torch.load("./model/backbone100.pth", map_location="cpu"))
|
|
model.eval()
|
|
file1, file2, code = get_file_list("pairs.txt")
|
|
code = np.array(code,dtype=np.int)
|
|
img = load_list_images(file1)
|
|
print(img.shape)
|
|
img = torch.from_numpy(img)
|
|
img2 = load_list_images(file2)
|
|
img2 = torch.from_numpy(img2)
|
|
batch_size = 128
|
|
now = 0
|
|
number = len(code)
|
|
distance = []
|
|
with torch.no_grad():
|
|
start_time = time.time()
|
|
while now < number:
|
|
if now + batch_size < number:
|
|
pred1 = model(img[now:now + batch_size])
|
|
pred2 = model(img2[now:now + batch_size])
|
|
else:
|
|
pred1 = model(img[now:])
|
|
pred2 = model(img2[now:])
|
|
now = now + batch_size
|
|
pred1 = pred1.numpy()
|
|
pred2 = pred2.numpy()
|
|
print("batch"+str(now))
|
|
for i in range(len(pred1)):
|
|
#distance.append(findEuclideanDistance(pred1[i], pred2[i]))
|
|
distance.append(findEuclideanDistance(l2_normalize(pred1[i]), l2_normalize(pred2[i])))
|
|
end_time = time.time()
|
|
distance = np.array(distance)
|
|
print("对比两张人脸平均用时:" + str((end_time - start_time) / number))
|
|
#print(distance)
|
|
# threshold,max_acc = threshold_acc(distance,code)
|
|
# print(threshold,max_acc)
|
|
reject, error,right = reject_and_error(distance, code)
|
|
print("正确人脸对数量:"+str(right)+" 正确率:"+str(right/number))
|
|
print("拒识人脸对数量:" + str(reject) + " 拒识率:" + str(2*reject / number))
|
|
print("误识人脸对数量:" + str(error) + " 误识率:" + str(2 * error / number))
|
|
|
|
# sublist = ['zdz','bbb','aaa']
|
|
# for item in itertools.combinations(sublist, 2):
|
|
# for name in item:
|
|
# print(name)
|
|
# path = "D:\Download\out\output2\Alan_Trammell\Alan_Trammell_0001.jpg"
|
|
# path = path.split("\\")
|
|
# print(path)
|
|
# print(os.path.join(path[0],path[1],path[2],path[3],path[4]))
|