EngAbod commited on
Commit
ae45eb6
·
1 Parent(s): b795261

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +315 -13
app.py CHANGED
@@ -1,12 +1,139 @@
1
- import streamlit as st
2
- import numpy as np
3
  import cv2
4
- from io import BytesIO
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
  def create_blake_image(input_image):
7
  # Read the image from the BytesIO object
8
- img = cv2.imdecode(np.frombuffer(input_image.read(), np.uint8), -1)
9
-
10
  # Get the shape of the original image
11
  height, width, _ = img.shape
12
 
@@ -20,13 +147,188 @@ def create_blake_image(input_image):
20
  result = cv2.bitwise_and(img, img, mask=mask)
21
 
22
  return result
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
 
24
- st.title("Blake-Style Image Converter")
25
- picture = st.camera_input("Take a picture")
26
-
27
- if picture:
28
- # Convert the uploaded image to a Blake-style image
29
- blake_image = create_blake_image(picture)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
 
31
- # Display the result
32
- st.image(blake_image, caption="Blake-Style Image", use_column_width=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from turn import get_ice_servers
2
+
3
  import cv2
4
+ import mediapipe as mp
5
+ import numpy as np
6
+ import time
7
+ import math
8
+ import streamlit as st
9
+ import av
10
+
11
+ from tensorflow.keras.models import load_model
12
+ from scipy.signal import convolve2d
13
+ from skimage import color
14
+ from skimage import io
15
+ from sklearn.metrics import accuracy_score
16
+
17
+ # VECTORIZATION the u factor
18
+ import matplotlib.pyplot as plt
19
+ import os
20
+ import torch
21
+ import torchvision.transforms as transforms
22
+ import torchvision.models as models
23
+ from PIL import Image
24
+ from tensorflow.keras.models import Sequential
25
+ from tensorflow.keras.layers import Dense, Conv1D, MaxPooling1D, Flatten, Dropout
26
+ from tensorflow.keras.optimizers import Adam
27
+ from streamlit_webrtc import webrtc_streamer
28
+
29
+ num_bins = 256
30
+
31
+ mp_face_mesh = mp.solutions.face_mesh
32
+ face_mesh = mp_face_mesh.FaceMesh(min_detection_confidence=0.5, min_tracking_confidence=0.5)
33
+ mp_drawing = mp.solutions.drawing_utils
34
+ drawing_spec = mp_drawing.DrawingSpec(thickness=1, circle_radius=1)
35
+
36
+ # Load the model
37
+ model = load_model('best_model_HQ_v9.h5')
38
+ # model2 = load_model('best_model_HQ_v9.h5')
39
+ def u_sliding_factor(image_channel, P):
40
+ result = np.zeros(image_channel.shape, np.float32)
41
+
42
+ # Define the sliding window size
43
+ window_size = (3, 3)
44
+
45
+ # Create the convolution kernel
46
+ kernel = np.ones(window_size, np.float32)
47
+ kernel[1, 1] = 0
48
+ kernel = kernel / (2 * P)
49
+ kernal2 = np.zeros(window_size, np.float32)
50
+ kernal2[1, 1] = 1
51
+ kernal2 = kernal2 / 2
52
+
53
+ # Perform the convolution using scipy's convolve2d
54
+ convolution_matrix = cv2.filter2D(image_channel, -1, kernel) + cv2.filter2D(image_channel, -1, kernal2)
55
+ result = convolution_matrix[1:-1, 1:-1]
56
+
57
+ return result.astype(np.float32)
58
+
59
+ def C_list_calculate(P):
60
+ C = []
61
+ for count in range(1, 9):
62
+ c_value = ((P - count) * (count - 1)) / math.floor(((P - 1) / 2)**2)
63
+ C.append(c_value)
64
+ return C
65
+
66
+ def ED_LBP_Sliding_Matrix(I, P):
67
+ # Define the amount of padding
68
+ padding_amount = 1
69
+
70
+ # Pad the array with zeros
71
+ I = np.pad(I, pad_width=padding_amount, mode='constant')
72
+ K = (2**P) - 1
73
+ C_list = C_list_calculate(8)
74
+ u_fac_matrix = u_sliding_factor(I.astype(np.float32), P)
75
+ slid_factor = np.zeros((u_fac_matrix.shape), np.float32)
76
+ m, n = u_fac_matrix.shape
77
+ ED_LBP = np.zeros(u_fac_matrix.shape, np.float32)
78
+ ED_LBP_matrix = np.zeros((u_fac_matrix.shape), np.float32)
79
+ K_matrix = np.ones(u_fac_matrix.shape).astype(np.float32) * K
80
+ offsets = [(0, 1), (0, 2), (1, 2), (2, 2), (2, 1), (2, 0), (1, 0), (0, 0)]
81
+ count = 1
82
+
83
+ for offset in offsets:
84
+ row_offset, col_offset = offset
85
+ sliding_matrix = I[row_offset:row_offset + m, col_offset:col_offset + n].astype(np.float32) - u_fac_matrix.astype(np.float32)
86
+ slid_factor = np.maximum(sliding_matrix, 0).astype(np.float32)
87
+ k_norm = K_matrix.astype(np.float32) - u_fac_matrix.astype(np.float32)
88
+ k_norm_nonzero = np.where(k_norm == 0, 1e-10, k_norm)
89
+ A_factor = np.where(k_norm != 0, slid_factor / k_norm_nonzero, 0)
90
+ ED_LBP_matrix = (A_factor.astype(np.float32) * C_list[count - 1]) + np.ones(A_factor.shape).astype(np.float32)
91
+ ED_LBP = ED_LBP + np.where(sliding_matrix >= 0, 2**((count - 1) * ED_LBP_matrix.astype(np.float32)), 0)
92
+ count = count + 1
93
+
94
+ ED_LBP = np.where(ED_LBP > 255, 255, np.round(ED_LBP))
95
+
96
+ return ED_LBP.astype(int)
97
+
98
+ def compute_histogram(image, num_bins):
99
+ hist = cv2.calcHist([image], [0], None, [num_bins], [0, num_bins])
100
+ hist = hist / hist.sum() # Normalize the histogram
101
+ return hist
102
+
103
+ def spatial_pyramid(image, num_bins):
104
+ ED_LBP_image = np.zeros((image.shape), np.int16)
105
+ num_channels = image.shape[2]
106
+ histograms = []
107
 
108
+ for channel in range(num_channels):
109
+ ED_LBP_image[:, :, channel] = ED_LBP_Sliding_Matrix(image[:, :, channel].astype(np.int16), 8)
110
+
111
+ # Level 0: Compute histogram for the entire channel
112
+ H1_channel = compute_histogram(ED_LBP_image[:, :, channel].astype(np.uint8), num_bins).ravel()
113
+
114
+ # Level 2: Compute histograms for 4x4 grids
115
+ grid_size = 4
116
+ H2_channel = np.empty((grid_size, grid_size, num_bins))
117
+ grid_height, grid_width = ED_LBP_image[:, :, channel].shape[0] // grid_size, ED_LBP_image[:, :, channel].shape[1] // grid_size
118
+ for m in range(grid_size):
119
+ for n in range(grid_size):
120
+ grid_image = ED_LBP_image[m * grid_height: (m + 1) * grid_height,
121
+ n * grid_width: (n + 1) * grid_width, channel]
122
+ H2_channel[m, n] = compute_histogram(grid_image.astype(np.uint8), num_bins).ravel()
123
+
124
+ H2_channel = H2_channel.reshape(-1)
125
+
126
+ # Concatenate histograms from level 0 and level 2
127
+ Hs_channel = np.concatenate((H1_channel, H2_channel))
128
+ histograms.append(Hs_channel)
129
+
130
+ # Concatenate histograms from all channels
131
+ feature_vector = np.concatenate(histograms)
132
+ return feature_vector
133
  def create_blake_image(input_image):
134
  # Read the image from the BytesIO object
135
+ # img = cv2.imdecode(np.frombuffer(input_image.read(), np.uint8), -1)
136
+ img = input_image
137
  # Get the shape of the original image
138
  height, width, _ = img.shape
139
 
 
147
  result = cv2.bitwise_and(img, img, mask=mask)
148
 
149
  return result
150
+ class VideoProcessor:
151
+ num_bins = 256
152
+ video_stopped = False
153
+
154
+ def recv(self, frame):
155
+ frm = frame.to_ndarray(format="bgr24")
156
+ frm = cv2.flip(frm,1)
157
+ gray_image = cv2.cvtColor(frm, cv2.COLOR_BGR2GRAY)
158
+ average_brightness = cv2.mean(gray_image)[0]
159
+ text3 = str(average_brightness)
160
+ cv2.putText(frm, text3, (10, 90), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255))
161
+ flag = 0
162
+ # # Denoise the image using Gaussian blur (optional)
163
+ # frm = cv2.GaussianBlur(frm, (5, 5), 0)
164
+
165
+ # # Enhance image quality by increasing contrast and brightness
166
+ # alpha = 1.5 # Contrast control (1.0 means no change)
167
+ # beta = 30 # Brightness control (0 means no change)
168
+ # enhanced_image = cv2.convertScaleAbs(frm, alpha=alpha, beta=beta)
169
+ # frm = enhanced_image
170
 
171
+ if average_brightness < 100:
172
+ text = "Bad Light, increase the light"
173
+ cv2.putText(frm, text, (20, 50), cv2.FONT_HERSHEY_SIMPLEX, 2, (255, 0, 0))
174
+ return av.VideoFrame.from_ndarray(frm, format='bgr24')
175
+ else:
176
+ rgb_frame = cv2.cvtColor(frm, cv2.COLOR_BGR2RGB)
177
+ results = face_mesh.process(rgb_frame)
178
+ img_h, img_w, img_c = frm.shape
179
+ face_3d = []
180
+ face_2d = []
181
+
182
+ if results.multi_face_landmarks:
183
+ for landmarks in results.multi_face_landmarks:
184
+ text = "No Face"
185
+ for idx, lm in enumerate(landmarks.landmark):
186
+ if idx == 33 or idx == 263 or idx == 1 or idx == 61 or idx == 291 or idx == 199:
187
+ if idx == 1:
188
+ nose_2d = (lm.x * img_w, lm.y * img_h)
189
+ nose_3d = (lm.x * img_w, lm.y * img_h, lm.z * 3000)
190
+ x, y = int(lm.x * img_w), int(lm.y * img_h)
191
+
192
+
193
+ # Get the 2d coordinate
194
+ face_2d.append([x, y])
195
+
196
 
197
+ # Get 3d coordinate
198
+ face_3d.append([x, y, lm.z])
199
+
200
+ # Convert to numpy array
201
+ # Error from
202
+ face_2d = np.array(face_2d, dtype=np.float32)
203
+ face_3d = np.array(face_3d, dtype=np.float32)
204
+
205
+ # The camera matrix
206
+ focal_length = 1 * img_w
207
+ cam_matrix = np.array([[focal_length, 0, img_h / 2],
208
+ [0, focal_length, img_w / 2],
209
+ [0, 0, 1]])
210
+
211
+ # The distance matrix
212
+ dist_matrix = np.zeros((4, 1), dtype=np.float64)
213
+
214
+ #solve PnP
215
+ success, rot_vec, trans_vec = cv2.solvePnP(face_3d, face_2d, cam_matrix, dist_matrix)
216
+
217
+ #get rotational matrix
218
+ rmat ,jac = cv2.Rodrigues(rot_vec)
219
+
220
+ #Get angles1
221
+ angles, mtxR, mtxQ, Qx, Qy, Qz = cv2.RQDecomp3x3(rmat)
222
+
223
+ #get y rotation degree
224
+ x = angles[0] * 360
225
+ y = angles[1] * 360
226
+ z = angles[2] * 360
227
+ # see where the user's head tilting
228
+ if y < -10:
229
+ text = "Look Right"
230
+ elif y > 10:
231
+ text = "Look Left"
232
+ elif x < -10:
233
+ text = "Look Up"
234
+ elif x > 10:
235
+ text = "Look Down"
236
+ else:
237
+ features_list=[]
238
+ features_list2=[]
239
+ # Check if there are face landmarks detected
240
+ gray = cv2.cvtColor(frm, cv2.COLOR_BGR2GRAY)
241
+
242
+
243
+ # Detect faces using cascade classifier
244
+ face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
245
+ faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))
246
+ expansion_factor = 1.5
247
+ num_bins = 256
248
+ biggest_face = None
249
+ biggest_area = 0
250
+ target_size = (512,512)
251
+ for (x, y, w, h) in faces:
252
+ # Calculate the expanded dimensions
253
+ expanded_x = max(0, int(x - (w * (expansion_factor - 1) / 2)))
254
+ expanded_y = max(0, int(y - (h * (expansion_factor - 1) / 2)))
255
+ expanded_w = min(img_w, int(w * expansion_factor))
256
+ expanded_h = min(img_h, int(h * expansion_factor))
257
+
258
+ # Crop the expanded face region from the frame
259
+ current_area = expanded_w * expanded_h
260
+ if current_area > biggest_area:
261
+ biggest_area = current_area
262
+ biggest_face = frm[expanded_y:expanded_y + expanded_h, expanded_x:expanded_x + expanded_w]
263
+ # biggest_face = frm[y:y + h, x:x + w]
264
+ resized_face = cv2.resize(biggest_face, target_size)
265
+ if biggest_face is not None:
266
+
267
+ # Perform spatial pyramid feature extraction
268
+ rgb_features = spatial_pyramid(cv2.cvtColor(resized_face, cv2.COLOR_BGR2RGB), num_bins)
269
+ hsv_features = spatial_pyramid(cv2.cvtColor(resized_face, cv2.COLOR_BGR2HSV), num_bins)
270
+ ycbcr_features = spatial_pyramid(cv2.cvtColor(resized_face, cv2.COLOR_BGR2YCrCb), num_bins)
271
+
272
+
273
+ if rgb_features.size > 0 and hsv_features.size > 0 and ycbcr_features.size > 0:
274
+ combined_features = np.concatenate((rgb_features, hsv_features, ycbcr_features))
275
+ features_list.append(combined_features)
276
+ if len(features_list) > 0:
277
+ X_array = np.array(features_list)
278
+ print(X_array.shape)
279
+ X_test_array_reshaped = np.expand_dims(X_array, axis=-1)
280
+ prediction = model.predict(X_test_array_reshaped)
281
+ # predection2 = model2.predict(X_test_array_reshaped)
282
+ if prediction >= 0.1:
283
+ text = "Real Live Person"
284
+ text2 = str(prediction[0])
285
+ cv2.putText(frm, text2, (10, 70), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255))
286
+ flag = 1
287
+ # st.text("Real Live Person")
288
+ # self.video_stopped = True
289
+ #save current resized_face
290
+ else:
291
+ text= "Not Live Image"
292
+ text2 = str(prediction[0])
293
+ cv2.putText(frm, text2, (10, 70), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255))
294
+ # st.text("Not Live Image")
295
+ # self.video_stopped = True
296
+ # else:
297
+ # text = "Fake Image"
298
+
299
+ # Display the nose direction
300
+ nose_3d_projection, jacobian = cv2.projectPoints(nose_3d, rot_vec, trans_vec, cam_matrix, dist_matrix, dist_matrix)
301
+
302
+ p1 = (int(nose_2d[0]), int(nose_2d[1]))
303
+ p2 = (int(nose_2d[0] + y*10), int(nose_2d[1] - x * 10))
304
+
305
+ cv2.line(frm, p1, p2, (255,0,0), 3)
306
+
307
+ cv2.putText(frm, text, (20, 50), cv2.FONT_HERSHEY_SIMPLEX, 2, (0, 0, 255), thickness=3, lineType=cv2.LINE_AA)
308
+ cv2.putText(frm, "x :" + str(np.round(x,2)), (500, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,0,255), 2)
309
+ cv2.putText(frm, "y :" + str(np.round(x,2)), (500, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,0,255), 2)
310
+ cv2.putText(frm, "z :" + str(np.round(x,2)), (500, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,0,255), 2)
311
+
312
+
313
+ mp_drawing.draw_landmarks(
314
+ image=frm,
315
+ landmark_list=landmarks,
316
+ connections=mp_face_mesh.FACEMESH_TESSELATION,
317
+ landmark_drawing_spec=drawing_spec,
318
+ connection_drawing_spec=drawing_spec,
319
+ )
320
+ else:
321
+ text = "There is no Face"
322
+ # Add the text to the image
323
+ if flag == 1:
324
+ cv2.putText(frm, text, (20, 50), cv2.FONT_HERSHEY_SIMPLEX, 2, (0, 255, 0))
325
+ else:
326
+ cv2.putText(frm, text, (20, 50), cv2.FONT_HERSHEY_SIMPLEX, 2, (0, 0, 255))
327
+ frm3 = create_blake_image(frm)
328
+ frm = frm3.to_ndarray(format="bgr24")
329
+ return av.VideoFrame.from_ndarray(frm, format='bgr24')
330
+ # Inside your Streamlit app
331
+
332
+ st.title("التركيز على وسط الشاشة")
333
+
334
+ webrtc_streamer(key="example", video_processor_factory=VideoProcessor,media_stream_constraints={"video": True, "audio": False},rtc_configuration={"iceServers": get_ice_servers()},)