-
Notifications
You must be signed in to change notification settings - Fork 0
/
test.py
118 lines (105 loc) · 3.94 KB
/
test.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import torch
import pickle
import torch.nn as nn
from torchvision import transforms
from PIL import Image
from data import *
from parameters import *
import cv2
import numpy as np
from loss import *
from faceDetector import *
from torch.utils.data import DataLoader
import torch.nn.functional as F
import os
def load_path():
with open("./path_dict.p", "rb") as f:
paths = pickle.load(f)
return paths
def load_face(paths):
faces = []
for key in paths.keys():
paths[key] = paths[key].replace("\\", "/")
faces.append(key)
return faces
def load_images(paths, transform):
images = {}
for key in paths.keys():
li = []
if os.path.exists(paths[key]):
for img in os.listdir(paths[key]):
image = Image.open(os.path.join(paths[key],img)).convert("RGB")
image = transform(image)
li.append(image)
images[key] = li
return images
def img_to_encoding(image_path, model, transform, device):
image = Image.open(image_path).convert("RGB")
image_tensor = transform(image).unsqueeze(0).to(device) # Move the tensor to the same device as the model
with torch.no_grad():
return model(image_tensor)
def verify(image_path, identity, database, model, transform, device):
min_dist = 1000
image_tensor = img_to_encoding(image_path, model, transform, device)
for pic in database:
dist = F.cosine_similarity(image_tensor, pic)
if dist < min_dist:
min_dist = dist
print(identity + ' : ' +str(min_dist)+ ' ' + str(len(database)))
if min_dist<THRESHOLD:
door_open = True
else:
door_open = False
return min_dist, door_open
def load_database(faces, paths, model, transform, device):
database = {}
for face in faces:
database[face] = []
for face in faces:
if os.path.exists(paths[face]):
for img in os.listdir(paths[face]):
database[face].append(img_to_encoding(os.path.join(paths[face],img), model, transform, device))
return database
def faceRecognition(faceDetector, image_path, database, faces, model, transform, device):
image = cv2.imread(image_path)
gray_img = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
output_path = "test_image"
for (x, y, w, h) in faceRects:
roi = image[y:y+h,x:x+w]
roi = cv2.cvtColor(roi, cv2.COLOR_BGR2RGB)
roi = cv2.resize(roi,(IMAGE_SIZE, IMAGE_SIZE))
min_dist = 1000
identity = ""
detected = False
for face in range(len(faces)):
person = faces[face]
dist, detected = verify(image_path, person, database[person], model, transform, device)
if detected and dist < min_dist:
min_dist = dist
identity = person
image_path = os.path.join(output_path, f"{identity}.jpg")
if detected:
cv2.rectangle(image, (x, y), (x+w, y+h), (0, 255, 0), 2)
cv2.putText(image, identity, (x+ (w//2),y-2), cv2.FONT_HERSHEY_SIMPLEX, 1.0, (0, 0, 255), lineType=cv2.LINE_AA)
cv2.imread(image_path, image)
def main():
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = torch.hub.load('pytorch/vision:v0.10.0', 'mobilenet_v2', pretrained=True)
model = model.to(device)
model.load_state_dict(torch.load("facenet_model.pth"))
model.eval()
transform = transforms.Compose([
transforms.Resize(IMAGE_SIZE),
transforms.RandomHorizontalFlip(),
transforms.ToTensor(),
transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5])
])
image_path = r'test_image/1.jpeg'
fd = faceDetector('haarcascade_frontalface_default.xml')
paths = load_path()
faces = load_face(paths)
images = load_images(paths, transform)
database = load_database(faces, paths, model, transform, device)
faceRecognition(fd, image_path, database, faces, model, transform, device)
if __name__ == "__main__":
main()