EngAbod commited on
Commit
167ec34
·
1 Parent(s): 3930505

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +322 -17
app.py CHANGED
@@ -1,42 +1,347 @@
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
-
13
  # Create a circular mask with the same shape
14
  mask = np.zeros((height, width), dtype=np.uint8)
15
  circle_center = (width // 2, height // 2)
16
  circle_radius = min(width, height) // 2
17
  cv2.circle(mask, circle_center, circle_radius, 255, thickness=-1)
18
-
19
  # Create a black background with the same shape as the original image
20
  black_background = np.zeros_like(img)
21
-
22
  # Calculate the position to center the image within the circular form
23
  x_position = circle_center[0] - (width // 2)
24
  y_position = circle_center[1] - (height // 2)
25
-
26
  # Paste the original image onto the black background
27
  black_background[y_position:y_position + height, x_position:x_position + width] = img
28
-
29
  # Apply the mask to the centered image
30
  result = cv2.bitwise_and(black_background, black_background, mask=mask)
31
-
32
  return result
33
 
34
- st.title("Blake-Style Image Converter")
35
- picture = st.camera_input("Take a picture")
36
 
37
- if picture:
38
- # Convert the uploaded image to a Blake-style image
39
- blake_image = create_blake_image(picture)
 
 
 
 
 
 
 
 
 
 
 
 
 
40
 
41
- # Display the result
42
- 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
+
137
  # Get the shape of the original image
138
  height, width, _ = img.shape
139
+
140
  # Create a circular mask with the same shape
141
  mask = np.zeros((height, width), dtype=np.uint8)
142
  circle_center = (width // 2, height // 2)
143
  circle_radius = min(width, height) // 2
144
  cv2.circle(mask, circle_center, circle_radius, 255, thickness=-1)
145
+
146
  # Create a black background with the same shape as the original image
147
  black_background = np.zeros_like(img)
148
+
149
  # Calculate the position to center the image within the circular form
150
  x_position = circle_center[0] - (width // 2)
151
  y_position = circle_center[1] - (height // 2)
152
+
153
  # Paste the original image onto the black background
154
  black_background[y_position:y_position + height, x_position:x_position + width] = img
155
+
156
  # Apply the mask to the centered image
157
  result = cv2.bitwise_and(black_background, black_background, mask=mask)
158
+
159
  return result
160
 
 
 
161
 
162
+ # Continue with the rest of your processing
163
+
164
+ class VideoProcessor:
165
+ num_bins = 256
166
+ video_stopped = False
167
+
168
+ def recv(self, frame):
169
+ frm = frame.to_ndarray(format="bgr24")
170
+ frm = cv2.flip(frm,1)
171
+ gray_image = cv2.cvtColor(frm, cv2.COLOR_BGR2GRAY)
172
+ average_brightness = cv2.mean(gray_image)[0]
173
+ text3 = str(average_brightness)
174
+ cv2.putText(frm, text3, (10, 90), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255))
175
+ flag = 0
176
+ # # Denoise the image using Gaussian blur (optional)
177
+ # frm = cv2.GaussianBlur(frm, (5, 5), 0)
178
 
179
+ # # Enhance image quality by increasing contrast and brightness
180
+ # alpha = 1.5 # Contrast control (1.0 means no change)
181
+ # beta = 30 # Brightness control (0 means no change)
182
+ # enhanced_image = cv2.convertScaleAbs(frm, alpha=alpha, beta=beta)
183
+ # frm = enhanced_image
184
+
185
+ if average_brightness < 100:
186
+ text = "Bad Light, increase the light"
187
+ cv2.putText(frm, text, (20, 50), cv2.FONT_HERSHEY_SIMPLEX, 2, (255, 0, 0))
188
+ return av.VideoFrame.from_ndarray(frm, format='bgr24')
189
+ else:
190
+ rgb_frame = cv2.cvtColor(frm, cv2.COLOR_BGR2RGB)
191
+ results = face_mesh.process(rgb_frame)
192
+ img_h, img_w, img_c = frm.shape
193
+ face_3d = []
194
+ face_2d = []
195
+
196
+ if results.multi_face_landmarks:
197
+ for landmarks in results.multi_face_landmarks:
198
+ text = "No Face"
199
+ for idx, lm in enumerate(landmarks.landmark):
200
+ if idx == 33 or idx == 263 or idx == 1 or idx == 61 or idx == 291 or idx == 199:
201
+ if idx == 1:
202
+ nose_2d = (lm.x * img_w, lm.y * img_h)
203
+ nose_3d = (lm.x * img_w, lm.y * img_h, lm.z * 3000)
204
+ x, y = int(lm.x * img_w), int(lm.y * img_h)
205
+
206
+
207
+ # Get the 2d coordinate
208
+ face_2d.append([x, y])
209
+
210
+
211
+ # Get 3d coordinate
212
+ face_3d.append([x, y, lm.z])
213
+
214
+ # Convert to numpy array
215
+ # Error from
216
+ face_2d = np.array(face_2d, dtype=np.float32)
217
+ face_3d = np.array(face_3d, dtype=np.float32)
218
+
219
+ # The camera matrix
220
+ focal_length = 1 * img_w
221
+ cam_matrix = np.array([[focal_length, 0, img_h / 2],
222
+ [0, focal_length, img_w / 2],
223
+ [0, 0, 1]])
224
+
225
+ # The distance matrix
226
+ dist_matrix = np.zeros((4, 1), dtype=np.float64)
227
+
228
+ #solve PnP
229
+ success, rot_vec, trans_vec = cv2.solvePnP(face_3d, face_2d, cam_matrix, dist_matrix)
230
+
231
+ #get rotational matrix
232
+ rmat ,jac = cv2.Rodrigues(rot_vec)
233
+
234
+ #Get angles1
235
+ angles, mtxR, mtxQ, Qx, Qy, Qz = cv2.RQDecomp3x3(rmat)
236
+
237
+ #get y rotation degree
238
+ x = angles[0] * 360
239
+ y = angles[1] * 360
240
+ z = angles[2] * 360
241
+ # see where the user's head tilting
242
+ if y < -10:
243
+ text = "Look Right"
244
+ elif y > 10:
245
+ text = "Look Left"
246
+ elif x < -10:
247
+ text = "Look Up"
248
+ elif x > 10:
249
+ text = "Look Down"
250
+ else:
251
+ features_list=[]
252
+ features_list2=[]
253
+ # Check if there are face landmarks detected
254
+ gray = cv2.cvtColor(frm, cv2.COLOR_BGR2GRAY)
255
+
256
+
257
+ # Detect faces using cascade classifier
258
+ face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
259
+ faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))
260
+ expansion_factor = 1.5
261
+ num_bins = 256
262
+ biggest_face = None
263
+ biggest_area = 0
264
+ target_size = (512,512)
265
+ for (x, y, w, h) in faces:
266
+ # Calculate the expanded dimensions
267
+ expanded_x = max(0, int(x - (w * (expansion_factor - 1) / 2)))
268
+ expanded_y = max(0, int(y - (h * (expansion_factor - 1) / 2)))
269
+ expanded_w = min(img_w, int(w * expansion_factor))
270
+ expanded_h = min(img_h, int(h * expansion_factor))
271
+
272
+ # Crop the expanded face region from the frame
273
+ current_area = expanded_w * expanded_h
274
+ if current_area > biggest_area:
275
+ biggest_area = current_area
276
+ biggest_face = frm[expanded_y:expanded_y + expanded_h, expanded_x:expanded_x + expanded_w]
277
+ # biggest_face = frm[y:y + h, x:x + w]
278
+ resized_face = cv2.resize(biggest_face, target_size)
279
+ if biggest_face is not None:
280
+
281
+ # Perform spatial pyramid feature extraction
282
+ rgb_features = spatial_pyramid(cv2.cvtColor(resized_face, cv2.COLOR_BGR2RGB), num_bins)
283
+ hsv_features = spatial_pyramid(cv2.cvtColor(resized_face, cv2.COLOR_BGR2HSV), num_bins)
284
+ ycbcr_features = spatial_pyramid(cv2.cvtColor(resized_face, cv2.COLOR_BGR2YCrCb), num_bins)
285
+
286
+
287
+ if rgb_features.size > 0 and hsv_features.size > 0 and ycbcr_features.size > 0:
288
+ combined_features = np.concatenate((rgb_features, hsv_features, ycbcr_features))
289
+ features_list.append(combined_features)
290
+ if len(features_list) > 0:
291
+ X_array = np.array(features_list)
292
+ print(X_array.shape)
293
+ X_test_array_reshaped = np.expand_dims(X_array, axis=-1)
294
+ prediction = model.predict(X_test_array_reshaped)
295
+ # predection2 = model2.predict(X_test_array_reshaped)
296
+ if prediction >= 0.1:
297
+ text = "Real Live Person"
298
+ text2 = str(prediction[0])
299
+ cv2.putText(frm, text2, (10, 70), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255))
300
+ flag = 1
301
+ # st.text("Real Live Person")
302
+ # self.video_stopped = True
303
+ #save current resized_face
304
+ else:
305
+ text= "Not Live Image"
306
+ text2 = str(prediction[0])
307
+ cv2.putText(frm, text2, (10, 70), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255))
308
+ # st.text("Not Live Image")
309
+ # self.video_stopped = True
310
+ # else:
311
+ # text = "Fake Image"
312
+
313
+ # Display the nose direction
314
+ nose_3d_projection, jacobian = cv2.projectPoints(nose_3d, rot_vec, trans_vec, cam_matrix, dist_matrix, dist_matrix)
315
+
316
+ p1 = (int(nose_2d[0]), int(nose_2d[1]))
317
+ p2 = (int(nose_2d[0] + y*10), int(nose_2d[1] - x * 10))
318
+
319
+ cv2.line(frm, p1, p2, (255,0,0), 3)
320
+
321
+ cv2.putText(frm, text, (20, 50), cv2.FONT_HERSHEY_SIMPLEX, 2, (0, 0, 255), thickness=3, lineType=cv2.LINE_AA)
322
+ cv2.putText(frm, "x :" + str(np.round(x,2)), (500, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,0,255), 2)
323
+ cv2.putText(frm, "y :" + str(np.round(x,2)), (500, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,0,255), 2)
324
+ cv2.putText(frm, "z :" + str(np.round(x,2)), (500, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,0,255), 2)
325
+
326
+
327
+ mp_drawing.draw_landmarks(
328
+ image=frm,
329
+ landmark_list=landmarks,
330
+ connections=mp_face_mesh.FACEMESH_TESSELATION,
331
+ landmark_drawing_spec=drawing_spec,
332
+ connection_drawing_spec=drawing_spec,
333
+ )
334
+ else:
335
+ text = "There is no Face"
336
+ # Add the text to the image
337
+ if flag == 1:
338
+ cv2.putText(frm, text, (20, 50), cv2.FONT_HERSHEY_SIMPLEX, 2, (0, 255, 0))
339
+ else:
340
+ cv2.putText(frm, text, (20, 50), cv2.FONT_HERSHEY_SIMPLEX, 2, (0, 0, 255))
341
+ frm = create_blake_image(frm)
342
+ return av.VideoFrame.from_ndarray(frm, format='bgr24')
343
+ # Inside your Streamlit app
344
+
345
+ st.title("التركيز على وسط الشاشة")
346
+
347
+ webrtc_streamer(key="example", video_processor_factory=VideoProcessor,media_stream_constraints={"video": True, "audio": False},rtc_configuration={"iceServers": get_ice_servers()},)