bit-guber commited on
Commit
dbb07a8
1 Parent(s): 95c021e

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +216 -0
app.py ADDED
@@ -0,0 +1,216 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import cv2
2
+ from transformers import ViTImageProcessor, ViTForImageClassification, AutoModelForImageClassification, AutoImageProcessor
3
+ import torch
4
+ import numpy as np
5
+
6
+ torch.backends.cudnn.benchmark = True
7
+
8
+ import urllib.request
9
+ path = 'https://raw.githubusercontent.com/opencv/opencv/master/data/haarcascades/haarcascade_frontalface_default.xml'
10
+ urllib.request.urlretrieve(path, path.split('/')[-1])
11
+
12
+ face_cascade = cv2.CascadeClassifier('./haarcascade_frontalface_default.xml')
13
+
14
+ class Base:
15
+ size = 224
16
+ scale = 1. / 255.
17
+ mean = np.array( [ .5 ] * 3 ).reshape( 1, 1, 1, -1)
18
+ std = np.array( [ .5 ] * 3 ).reshape( 1, 1, 1, -1)
19
+ resample = 2
20
+
21
+ class ethnicityConfig(Base):
22
+ size = 384
23
+
24
+ class maskConfig(Base):
25
+ resample = 3
26
+ mean = np.array( [ .485 ] * 3 ).reshape( 1, 1, 1, -1)
27
+ std = np.array( [ .229 ] * 3 ).reshape( 1, 1, 1, -1)
28
+
29
+
30
+ AGE = "nateraw/vit-age-classifier"
31
+ GENDER = 'rizvandwiki/gender-classification-2'
32
+ ETHNICITY = 'cledoux42/Ethnicity_Test_v003'
33
+ MASK = 'DamarJati/Face-Mask-Detection'
34
+ BLUR = 'WT-MM/vit-base-blur'
35
+ BEARD = 'dima806/beard_face_image_detection'
36
+
37
+
38
+ device = 'cuda' if torch.cuda.is_available() else 'cpu'
39
+ # base_processor = ViTImageProcessor.from_pretrained( global_path + 'base_processor' )
40
+ age_model = ViTForImageClassification.from_pretrained( AGE ).to(device)
41
+ gender_model = ViTForImageClassification.from_pretrained( GENDER ).to(device)
42
+ beard_model = ViTForImageClassification.from_pretrained( BEARD ).to(device)
43
+ blur_model = ViTForImageClassification.from_pretrained( BLUR ).to(device)
44
+
45
+ # ethnicity_precessor = ViTImageProcessor.from_pretrained( global_path + 'ethnicity' )
46
+ ethnicity_model= ViTForImageClassification.from_pretrained( ETHNICITY ).to(device)
47
+
48
+ # mask_processor = ViTImageProcessor.from_pretrained( global_path + 'mask' )
49
+ mask_model = AutoModelForImageClassification.from_pretrained( MASK ).to(device)
50
+
51
+
52
+ from PIL import Image
53
+ def normalize( data, mean, std ): # (batchs, nchannels, height, width)
54
+ data = (data - mean ) / std
55
+ return data.astype(np.float32)
56
+
57
+ def resize( image, size = 224, resample = 2 ):
58
+ # if isinstance(iamge, np.ndarray):
59
+ # image = Image.fromarray( image, mode = 'RGB' )
60
+
61
+ image = image.resize( (size, size), resample = resample )
62
+
63
+ return np.array( image )
64
+
65
+ def rescale( data, scale = Base.scale ):
66
+ return data * scale
67
+
68
+ # resize
69
+ # rescale
70
+ # normalize
71
+
72
+ def ParallelBatchsPredict( data, MODELS, nbatchs = 16 ):
73
+
74
+ total = data.shape[0]
75
+ # for change channel axis to first format
76
+ data = np.transpose( data, ( 0, 3, 1, 2 ) )
77
+ count = 0
78
+ batchs = [ [] for i in range(len(MODELS)) ]
79
+ for i in range( 0, total, nbatchs ):
80
+ batch = data[i:i+nbatchs]
81
+ count += batch.shape[0]
82
+ with torch.no_grad():
83
+ batch = torch.from_numpy( batch ).to(device)
84
+ for _, model in enumerate(MODELS):
85
+ logits = model( batch ).logits.softmax(1).argmax(1).tolist()
86
+ for x in logits:
87
+ batchs[_].append( model.config.id2label[ x ] )
88
+
89
+ assert count == total
90
+ return batchs
91
+ # model arrange
92
+ # age
93
+ # gender
94
+ # blur
95
+ # beard
96
+ # changle processor
97
+ # Ethnicity
98
+ # change processor
99
+ # Mask
100
+ def AnalysisFeatures(rawFaces): # list[ PIL.Image ]
101
+
102
+ if len(rawFaces) == 0:
103
+ return [ [] ]* 6
104
+ baseProcessed = np.array([ resize(x, size = Base.size, resample = Base.resample ) for x in rawFaces])
105
+ baseProcessed = rescale( baseProcessed )
106
+ baseProcessed = normalize( baseProcessed, Base.mean, Base.std )
107
+
108
+ ages, genders, beards, blurs = ParallelBatchsPredict(baseProcessed, [age_model, gender_model, beard_model, blur_model] )
109
+
110
+ EthncityProcessed = np.array([ resize(x, size = ethnicityConfig.size, resample = ethnicityConfig.resample ) for x in rawFaces])
111
+ EthncityProcessed = rescale( EthncityProcessed )
112
+ EthncityProcessed = normalize( EthncityProcessed, ethnicityConfig.mean, ethnicityConfig.std )
113
+
114
+ ethncities = ParallelBatchsPredict(EthncityProcessed, [ethnicity_model])[0]
115
+
116
+
117
+ MaskProcessed = np.array([ resize(x, size = maskConfig.size, resample = maskConfig.resample ) for x in rawFaces])
118
+ MaskProcessed = rescale( MaskProcessed )
119
+ MaskProcessed = normalize( MaskProcessed, maskConfig.mean, maskConfig.std )
120
+
121
+ masks = ParallelBatchsPredict(MaskProcessed, [mask_model])[0]
122
+
123
+ beards = [True if beard == 'Beard' else False for beard in beards]
124
+ blurs = [True if blur == 'blurry' else False for blur in blurs]
125
+ masks = [True if mask == 'WithMask' else False for mask in masks]
126
+
127
+ return ages, genders, beards, blurs, ethncities, masks
128
+
129
+
130
+ import gradio as gr
131
+
132
+ def frameWrapper( facesCo, ages, genders, beards, blurs, ethncities, masks ):
133
+ return { 'identifiedPersonCount': len(facesCo), 'value': [ { 'coordinate': { 'x': x, 'y': y, 'h': h, 'w':w }, 'ageGroup': age, 'gender': gender, 'beardPresent':beard, 'blurOccur': blur, 'ethncity': ethncity, 'maskPresent': mask } for (x, y, w, h), age, gender, beard, blur, ethncity, mask in zip( facesCo, ages, genders, beards, blurs, ethncities, masks ) ] }
134
+
135
+ def postProcessed( rawfaces, maximunSize, minSize = 30 ):
136
+ faces = []
137
+ for (x, y, w, h) in rawfaces:
138
+ x1 = x if x<maximunSize[0] else maximunSize[0]
139
+ y1 = y if y<maximunSize[1] else maximunSize[1]
140
+ x2 = w+x if w+x<maximunSize[0] else maximunSize[0]
141
+ y2 = h+y if h+y<maximunSize[1] else maximunSize[1]
142
+
143
+ if x2-x1 > minSize and y2-y1 >minSize:
144
+ faces.append( (x, y, w, h) )
145
+ return faces
146
+ def image_inference(image):
147
+
148
+ if sum(image.shape) == 0:
149
+ return { 'ErrorFound': 'ImageNotFound' }
150
+ # Convert into grayscale
151
+ gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
152
+ # Detect faces
153
+ rawfaces = face_cascade.detectMultiScale(gray, 1.05, 5, minSize = (30, 30))
154
+ image = np.asarray( image )
155
+ # Draw rectangle around the faces
156
+ rawfaces = postProcessed( rawfaces, image.shape[:2] )
157
+
158
+ faces = [ image[x:w+x, y:h+y].copy() for (x, y, w, h) in rawfaces ]
159
+ faces = [ Image.fromarray(x, mode = 'RGB') for x in faces ]
160
+ ages, genders, beards, blurs, ethncities, masks = AnalysisFeatures( faces )
161
+
162
+ # annotatedImage = image.copy()
163
+ # for (x, y, w, h) in rawfaces:
164
+ # cv2.rectangle(annotatedImage, (x, y), (x+w, y+h), (255, 0, 0), 2)
165
+
166
+ # return Image.fromarray(annotatedImage, mode = 'RGB'), frameWrapper( rawfaces, ages, genders, beards, blurs, ethncities, masks )
167
+ return frameWrapper( rawfaces, ages, genders, beards, blurs, ethncities, masks )
168
+ def video_inference(video_path):
169
+
170
+ global_facesCo = []
171
+ global_faces = []
172
+ cap = cv2.VideoCapture(video_path)
173
+ frameCount = 0
174
+ while(cap.isOpened()):
175
+ _, img = cap.read()
176
+
177
+ try:
178
+ # Convert into grayscale
179
+ gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
180
+ except:
181
+ break
182
+ # Detect faces
183
+ rawfaces = face_cascade.detectMultiScale(gray, 1.05, 6, minSize = (30, 30))
184
+ image = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
185
+ image = np.asarray( image )
186
+
187
+ rawfaces = postProcessed( rawfaces, image.shape[:2] )
188
+
189
+ # Draw rectangle around the faces
190
+ # https://stackoverflow.com/questions/15589517/how-to-crop-an-image-in-opencv-using-python for fliping axis
191
+ global_facesCo.append( rawfaces )
192
+ for (x, y, w, h) in rawfaces:
193
+ face = image[x:w+x, y:h+y].copy()
194
+ global_faces.append(Image.fromarray( face , mode = 'RGB') )
195
+
196
+ ages, genders, beards, blurs, ethncities, masks = AnalysisFeatures( global_faces )
197
+
198
+ total_extraction = []
199
+ for facesCo in global_facedsCo:
200
+ length = len(facesCo)
201
+
202
+ total_extraction.append( frameWrapper( facesCo, ages[:length], genders[:length], beards[:length], blurs[:length], ethncities[:length], masks[:length] ) )
203
+
204
+ ages, genders, beards, blurs, ethncities, masks = ages[length:], genders[length:], beards[length:], blurs[length:], ethncities[length:], masks[length:]
205
+ return total_extraction
206
+
207
+ css = """
208
+ .outputJSON{
209
+ overflow: scroll;
210
+ }
211
+ """
212
+ imageHander = gr.Interface( fn = image_inference, inputs = gr.Image(type="numpy", sources = 'upload'), outputs = gr.JSON(elem_classes = 'outputJSON'), css = css )
213
+ videoHander = gr.Interface( fn = video_inference, inputs = gr.Video(sources = 'upload', max_length = 30, include_audio = False), outputs = 'json' )
214
+ demo = gr.TabbedInterface( [imageHander, videoHander] )
215
+
216
+ demo.launch()