Spaces:
Runtime error
Runtime error
Commit
·
c7f3cc6
1
Parent(s):
863a84e
app.py
Browse files
app.py
ADDED
@@ -0,0 +1,211 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import numpy as np
|
2 |
+
from glob import glob
|
3 |
+
import cv2
|
4 |
+
import gradio as gr
|
5 |
+
import torch
|
6 |
+
import torchvision.models as models
|
7 |
+
from PIL import Image
|
8 |
+
import torch.optim as optim
|
9 |
+
import torchvision.transforms as transforms
|
10 |
+
from torchvision import datasets
|
11 |
+
from PIL import ImageFile
|
12 |
+
import torch.nn as nn
|
13 |
+
from collections import OrderedDict
|
14 |
+
|
15 |
+
dog_files = np.array(glob('dogImages/*/*/*'))
|
16 |
+
human_files = np.array(glob('lfw/*/*'))
|
17 |
+
|
18 |
+
# Human face detector using OpenCV
|
19 |
+
def detector_humanface(image_path):
|
20 |
+
# Loading color image (RGB)
|
21 |
+
image = cv2.imread(image_path)
|
22 |
+
# Converting color image to grayscale
|
23 |
+
grayscale_img = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
|
24 |
+
# Taking pre-trained human face detector classifier
|
25 |
+
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_alt.xml')
|
26 |
+
# finding face in grayscale image
|
27 |
+
faces = face_cascade.detectMultiScale(grayscale_img)
|
28 |
+
return len(faces) > 0
|
29 |
+
|
30 |
+
# detecting dogs using pre-trained model
|
31 |
+
vggmodel = models.vgg16(pretrained=True)
|
32 |
+
|
33 |
+
# check if CUDA is available
|
34 |
+
use_cuda = torch.cuda.is_available()
|
35 |
+
|
36 |
+
# move model to GPU if CUDA is available
|
37 |
+
if use_cuda:
|
38 |
+
vggmodel = vggmodel.cuda()
|
39 |
+
|
40 |
+
# detecting dog in an image
|
41 |
+
def vgg_model(img_path):
|
42 |
+
# move model to GPU if CUDA is available
|
43 |
+
use_cuda = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
|
44 |
+
# image = Image.open(img_path)
|
45 |
+
image = img_path
|
46 |
+
transform = transforms.Compose([transforms.ToTensor()])
|
47 |
+
tensor_image = transform(image)
|
48 |
+
image_tranformation = transforms.Compose(
|
49 |
+
[
|
50 |
+
transforms.CenterCrop(224),
|
51 |
+
transforms.ToTensor(),
|
52 |
+
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) # normalizing each channel RGB
|
53 |
+
]
|
54 |
+
)
|
55 |
+
|
56 |
+
# changing the dimension using unsqueeze & taking all tensors into size one list
|
57 |
+
transformed_img = image_tranformation(image).unsqueeze(0).to(use_cuda)
|
58 |
+
detected_dog = vggmodel(transformed_img)
|
59 |
+
_, pred = torch.max(detected_dog, 1)
|
60 |
+
# return the index of predicted class
|
61 |
+
return pred[0]
|
62 |
+
|
63 |
+
def dog_detector(img_path):
|
64 |
+
index = vgg_model(img_path)
|
65 |
+
if index>=151 and index<=268:
|
66 |
+
return True
|
67 |
+
else: False
|
68 |
+
|
69 |
+
# Set PIL to be tolerant of image files that are truncated.
|
70 |
+
ImageFile.LOAD_TRUNCATED_IMAGES = True
|
71 |
+
|
72 |
+
train_dir = 'dogImages/train'
|
73 |
+
test_dir = 'dogImages/test'
|
74 |
+
valid_dir = 'dogImages/valid'
|
75 |
+
|
76 |
+
# Transforms for the training, validation, and testing sets
|
77 |
+
train_transforms = transforms.Compose([
|
78 |
+
transforms.RandomRotation(40),
|
79 |
+
transforms.RandomResizedCrop(224),
|
80 |
+
transforms.RandomHorizontalFlip(),
|
81 |
+
transforms.ToTensor(),
|
82 |
+
transforms.Normalize([0.485, 0.456, 0.406],
|
83 |
+
[0.229, 0.224, 0.225])
|
84 |
+
])
|
85 |
+
|
86 |
+
valid_transforms = transforms.Compose([transforms.Resize(224),
|
87 |
+
transforms.CenterCrop(224),
|
88 |
+
transforms.ToTensor(),
|
89 |
+
transforms.Normalize([0.485, 0.456, 0.406],
|
90 |
+
[0.229, 0.224, 0.225])])
|
91 |
+
test_transforms = transforms.Compose([transforms.Resize(224),
|
92 |
+
transforms.CenterCrop(224),
|
93 |
+
transforms.ToTensor(),
|
94 |
+
transforms.Normalize([0.485, 0.456, 0.406],
|
95 |
+
[0.229, 0.224, 0.225])])
|
96 |
+
|
97 |
+
# Dataloaders
|
98 |
+
train_folder = datasets.ImageFolder(train_dir, transform=train_transforms)
|
99 |
+
valid_folder = datasets.ImageFolder(valid_dir, transform=valid_transforms)
|
100 |
+
test_folder = datasets.ImageFolder(test_dir, transform=test_transforms)
|
101 |
+
|
102 |
+
# DataLoaders
|
103 |
+
train_dataloaders = torch.utils.data.DataLoader(train_folder, batch_size=65, shuffle=True)
|
104 |
+
valid_dataloaders = torch.utils.data.DataLoader(valid_folder, batch_size=35, shuffle=True)
|
105 |
+
test_dataloaders = torch.utils.data.DataLoader(test_folder, batch_size= 68, shuffle=True)
|
106 |
+
|
107 |
+
model = models.resnet152(pretrained=True)
|
108 |
+
|
109 |
+
# Freeze training for all "feature" layers -> turning off computing gradient for each parameter
|
110 |
+
for param in model.parameters():
|
111 |
+
param.requires_grad_(False)
|
112 |
+
|
113 |
+
# Building classifier
|
114 |
+
# Next adding my own layers after features layers for
|
115 |
+
# training purpose which is to be customised according to output labels available
|
116 |
+
pre_trained_classifier = nn.Sequential(
|
117 |
+
OrderedDict(
|
118 |
+
[
|
119 |
+
('fc1', nn.Linear(2048, 1000)),
|
120 |
+
('relu', nn.ReLU()),
|
121 |
+
('dropout', nn.Dropout(p=0.5)),
|
122 |
+
('fc2', nn.Linear(1000, 133)),
|
123 |
+
('output', nn.LogSoftmax(dim=1))
|
124 |
+
]
|
125 |
+
)
|
126 |
+
)
|
127 |
+
|
128 |
+
model.fc = pre_trained_classifier
|
129 |
+
|
130 |
+
# move model to GPU if CUDA is available
|
131 |
+
if use_cuda:
|
132 |
+
model = model.cuda()
|
133 |
+
|
134 |
+
loss_fun = nn.CrossEntropyLoss()
|
135 |
+
optimizer = optim.SGD(model.fc.parameters(), lr=0.01, momentum=0.9)
|
136 |
+
scheduler = optim.lr_scheduler.ExponentialLR(optimizer, gamma=0.9)
|
137 |
+
|
138 |
+
|
139 |
+
# load the model that got the best validation accuracy
|
140 |
+
model.load_state_dict(torch.load('save_trained_model.pt', map_location=torch.device('cpu')))
|
141 |
+
|
142 |
+
# list of class names (breed names of dogs)
|
143 |
+
class_names_breed = [breed[4:].replace("_", " ") for breed in train_folder.classes]
|
144 |
+
|
145 |
+
# function that takes a dog image & returns the breed of that dog in the image
|
146 |
+
def predict_dog_breed(image_path):
|
147 |
+
# img = Image.open(image_path)
|
148 |
+
img = image_path
|
149 |
+
|
150 |
+
model.to('cpu')
|
151 |
+
|
152 |
+
# pre-processing the input image
|
153 |
+
transform_image = transforms.Compose(
|
154 |
+
[ transforms.Resize(256),
|
155 |
+
transforms.CenterCrop(224),
|
156 |
+
transforms.ToTensor()
|
157 |
+
]
|
158 |
+
)
|
159 |
+
|
160 |
+
processed_image = transform_image(img).unsqueeze(0)
|
161 |
+
|
162 |
+
# feedforward : feeding to trained model
|
163 |
+
output = model(processed_image)
|
164 |
+
|
165 |
+
# taking the prediction
|
166 |
+
_, pred = torch.max(output, dim=1)
|
167 |
+
|
168 |
+
return class_names_breed[pred[0]]
|
169 |
+
|
170 |
+
# checking if prediction is correct or not
|
171 |
+
def run_app(image_path):
|
172 |
+
# img = Image.open(image_path)
|
173 |
+
img = image_path
|
174 |
+
out_str = ""
|
175 |
+
|
176 |
+
### handle cases for a human face, dog, and neither
|
177 |
+
if dog_detector(image_path) == True:
|
178 |
+
out_str = "Hi, This Dog's Breed is " + str(predict_dog_breed(image_path))
|
179 |
+
return out_str
|
180 |
+
elif detector_humanface(image_path) == True:
|
181 |
+
out_str = "hello, human! You look like a " + str(predict_dog_breed(image_path)) + " Breed"
|
182 |
+
return out_str
|
183 |
+
else:
|
184 |
+
out_str = 'Error... No Dog or Human Face present!! Nothing Detected!!'
|
185 |
+
return out_str
|
186 |
+
|
187 |
+
demo = gr.Blocks()
|
188 |
+
|
189 |
+
with demo:
|
190 |
+
gr.Markdown(
|
191 |
+
"""
|
192 |
+
### Find the breed for dog image or resembling breed for human Image!
|
193 |
+
|
194 |
+
Enter the image of a dog or human and check its resembling breed...
|
195 |
+
|
196 |
+
If uploaded image is of Dog : it will give its Breed
|
197 |
+
|
198 |
+
Else If uploaded image is of Human: it will give its resembling breed of dog
|
199 |
+
""")
|
200 |
+
|
201 |
+
inp = gr.Image(type='pil')
|
202 |
+
out1 = gr.Textbox()
|
203 |
+
# out2 = gr.Image(type="pil")
|
204 |
+
#out = gr.Gallery()
|
205 |
+
submit = gr.Button("Generate")
|
206 |
+
|
207 |
+
submit.click(fn=run_app,
|
208 |
+
inputs=inp,
|
209 |
+
outputs=[out1])
|
210 |
+
|
211 |
+
demo.launch(enable_queue=True, debug=True)
|