-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathface_infer.py
144 lines (111 loc) · 3.73 KB
/
face_infer.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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#!/user/bin/env python
#imports
from __future__ import print_function, division
import torch
import torch.nn as nn
import torch.optim as optim
from torch.optim import lr_scheduler
import numpy as np
import torchvision
from torchvision import datasets, models, transforms, utils
import time
import os
import copy
#import pandas as pd
from skimage import io, transform
from torch.utils.data import Dataset, DataLoader
import torch.nn.functional as F
from PIL import Image
#ignore warnings
import warnings
warnings.filterwarnings("ignore")
PATH=("./nn_model/faces_ft.pt")
#process image
def process_image(image_path):
#load Image
img = Image.open(image_path)
#get the dimensions of the image
width, height = img.size
#resize by keeping the aspect ratio, but changing the dimension
#so the shortest size is 255px
img = img.resize((255, int(255*(height/width))) if width < height else (int(255*(width/height)), 255))
#get the dimensions of the new image size
width, height = img.size
#set the coordinates to do a center crop of 224 x 224
left = (width - 224)/2
top = (height - 224)/2
right = (width + 224)/2
bottom = (height + 224)/2
img = img.crop((left, top, right, bottom))
#turn image into numpy array
img = np.array(img)
#make the color channel dimension first instead of last
img = img.transpose((2, 0, 1))
#make all values between 0 and 1
img = img/255
#normalize based on the preset mean and standard deviation
img[0] = (img[0] - 0.485)/0.229
img[1] = (img[1] - 0.456)/0.224
img[2] = (img[2] - 0.406)/0.225
#add a fourth dimension to the beginning to indicate batch size
img = img[np.newaxis,:]
#turn into a torch tensor
image = torch.from_numpy(img)
image = image.float()
return image
def loadAndSetup():
#data augmentation and normalization for training
#just normalization for validation
data_transforms = {
'train': transforms.Compose([
transforms.RandomResizedCrop(224),
transforms.RandomHorizontalFlip(),
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
]),
'val': transforms.Compose([
transforms.Resize(256),
transforms.CenterCrop(224),
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
]),
}
#dataloaders
data_dir = 'images/'
image_datasets = {x: datasets.ImageFolder(os.path.join(data_dir, x),
data_transforms[x])
for x in ['train', 'val']}
dataset_sizes = {x: len(image_datasets[x]) for x in ['train', 'val']}
class_names = image_datasets['train'].classes
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
model_trained = torch.load(PATH)
print("Model loaded")
return class_names, device, model_trained
def infer_face(class_names, device, model_trained):
was_training = model_trained.training
model_trained.eval()
with torch.no_grad():
inputs = process_image("image_cam.jpg")
inputs = inputs.to(device)
outputs = model_trained(inputs)
#print(class_names)
#use softmax to get confidences
m = nn.Softmax()
#print(m(outputs).cpu())
confidence_list = (m(outputs).cpu())
for x in confidence_list:
confidence_list_unpacked = x
_, preds = torch.max(outputs, 1)
for j in range(inputs.size()[0]):
#strip out non-relevant information
top = str(confidence_list_unpacked[class_names.index(class_names[preds[j]])])
top = top.replace("tensor", "")
top = top.replace("(", "")
top = top.replace(")", "")
#return prediction and confidence
return(format(class_names[preds[j]])), (float(top))
model_trained.train(mode=was_training)
#if called direct then run the function
if __name__ == '__main__':
class_names, device, model_trained = loadAndSetup()
print(infer_face(class_names, device, model_trained))