Face/test.py

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