Medvira commited on
Commit
ef5def8
·
verified ·
1 Parent(s): d204b0e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +143 -105
app.py CHANGED
@@ -4,8 +4,14 @@ import traceback
4
  import gradio as gr
5
  import cv2 as cv
6
  import numpy as np
 
7
  import mediapipe as mp
8
- from utils import blinkRatio
 
 
 
 
 
9
 
10
  def custom_excepthook(type, value, tb):
11
  traceback.print_exception(type, value, tb)
@@ -16,18 +22,16 @@ sys.excepthook = custom_excepthook
16
  def list_overlay_images(directory):
17
  return [f for f in os.listdir(directory) if f.endswith('.png')]
18
 
19
- def process_frame(frame, overlay, alpha, LEFT_EYE, RIGHT_EYE, LEFT_IRIS, RIGHT_IRIS):
20
- rgb_frame = cv.cvtColor(frame, cv.COLOR_BGR2RGB)
21
- rgba_frame = cv.cvtColor(frame, cv.COLOR_BGR2RGBA)
22
- height, width = rgba_frame.shape[:2]
23
- results = face_mesh.process(rgb_frame)
24
- if results.multi_face_landmarks:
25
  zero_overlay = np.zeros_like(rgba_frame)
26
  mesh_points = np.array([np.multiply([p.x, p.y],
27
- [width, height]).astype(int) for p in results.multi_face_landmarks[0].landmark])
28
  iris_mask_left = np.zeros(rgba_frame.shape, dtype=np.uint8)
29
  iris_mask_right = np.zeros(rgba_frame.shape, dtype=np.uint8)
30
- _, re_ratio, le_ratio = blinkRatio(rgb_frame, mesh_points, RIGHT_EYE, LEFT_EYE)
31
  (l_cx, l_cy), l_radius = cv.minEnclosingCircle(mesh_points[LEFT_IRIS])
32
  (r_cx, r_cy), r_radius = cv.minEnclosingCircle(mesh_points[RIGHT_IRIS])
33
  center_left = (int(l_cx), int(l_cy))
@@ -60,116 +64,150 @@ def process_frame(frame, overlay, alpha, LEFT_EYE, RIGHT_EYE, LEFT_IRIS, RIGHT_I
60
  return rgba_frame
61
 
62
  def process_image(input_image, overlay_file, alpha=0.3):
63
- overlay_file = overlay_file + '.png'
64
- overlay_path = os.path.join(os.getcwd(),'overlays', overlay_file)
65
- overlay = cv.imread(overlay_path, cv.IMREAD_UNCHANGED)
66
- frame = np.array(input_image)
67
- w,h,_ = frame.shape
68
- new_h = 500
69
- new_w = int((w/h)*new_h)
70
- frame = cv.resize(frame, (new_h,new_w), interpolation=cv.INTER_NEAREST)
71
- processed_frame = process_frame(frame, overlay, alpha, LEFT_EYE, RIGHT_EYE, LEFT_IRIS, RIGHT_IRIS)
72
- return cv.cvtColor(processed_frame, cv.COLOR_BGR2RGB)
 
 
 
 
 
 
 
 
 
 
73
 
74
  def process_video(input_video, overlay_file, alpha=0.3, output_format='mp4', output_frame_rate=30):
75
- overlay_file = overlay_file + '.png'
76
- overlay_path = os.path.join(os.getcwd(),'overlays', overlay_file)
77
- overlay = cv.imread(overlay_path, cv.IMREAD_UNCHANGED)
78
- cap = cv.VideoCapture(input_video)
79
- output_path = os.path.join(os.getcwd(),f'video_processed.{output_format}')
80
- # Define the codec and create a VideoWriter object to save the processed video
81
- if (not isinstance(overlay,type(None))) & (not isinstance(cap,type(None))):
82
- # Get the dimensions of the frame, fps
83
- fps=int(output_frame_rate)
84
- if fps==0:
85
- fps = cap.get(5)
86
- ret, frame = cap.read()
87
- h,w,_ = frame.shape
88
- new_h = 500
89
- new_w = int((w/h)*new_h)
90
- fourcc = cv.VideoWriter_fourcc(*'mp4v' if output_format == 'mp4' else 'MJPG')
91
- out = cv.VideoWriter(output_path, fourcc, fps, (new_w,new_h))
92
- while(cap.isOpened()):
93
- ret, frame = cap.read()
94
- if ret == True:
95
- frame = cv.resize(frame, (new_w,new_h), interpolation=cv.INTER_NEAREST)
96
- processed_frame = process_frame(frame,overlay,alpha,LEFT_EYE, RIGHT_EYE, LEFT_IRIS, RIGHT_IRIS) # Assuming process_frame is a function that processes a single frame
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
97
  processed_frame = cv.cvtColor(processed_frame, cv.COLOR_RGBA2BGR)
98
  out.write(processed_frame)
99
- else:
100
- break
101
- cap.release()
102
- out.release()
103
- return output_path
 
 
 
 
 
104
 
105
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
106
 
107
- # Initialize face mesh once and reuse it
108
- mp_face_mesh = mp.solutions.face_mesh
109
- face_mesh = mp_face_mesh.FaceMesh(
110
- max_num_faces=1,
111
- refine_landmarks=True,
112
- min_detection_confidence=0.5,
113
- min_tracking_confidence=0.5
114
- )
115
 
116
- LEFT_EYE = [362, 382, 381, 380, 374, 373, 390, 249, 263, 466, 388, 387, 386, 385, 384, 398]
117
- RIGHT_EYE = [33, 7, 163, 144, 145, 153, 154, 155, 133, 173, 157, 158, 159, 160, 161, 246]
118
- LEFT_IRIS = [474, 475, 476, 477]
119
- RIGHT_IRIS = [469, 470, 471, 472]
120
 
121
  overlay_dir = os.path.join(os.getcwd(),'overlays')
122
  overlay_files = list_overlay_images(overlay_dir)
123
  overlay_choices = [x.split('.png')[0] for x in overlay_files]
124
- # with gr.Blocks() as demo:
125
- # with gr.Tab("Image"):
126
- # with gr.Row():
127
- # overlay_file = gr.Dropdown(choices=overlay_choices, value='Blue', label="Select a color")
128
- # # min_detection_confidence = gr.Slider(minimum=0.0, maximum=1.0, value=0.5, label="Min Detection Confidence")
129
- # # min_tracking_confidence = gr.Slider(minimum=0.0, maximum=1.0, value=0.5, label="Min Tracking Confidence")
130
- # # alpha = gr.Slider(minimum=0.0, maximum=1.0, value=0.3, label="Overlay Transparency")
131
- # with gr.Row():
132
- # input_image = gr.Image(height=500,width=400,label="Upload Image")
133
- # output_image = gr.Image(label="Processed Image")
134
- # process_image_btn = gr.Button("Process Image")
135
- # process_image_btn.click(process_image,
136
- # inputs=[input_image, overlay_file,],
137
- # outputs=output_image)
138
-
139
- # with gr.Tab("Video"):
140
- # with gr.Row():
141
- # overlay_file = gr.Dropdown(choices=overlay_choices, value='Blue', label="Select a color")
142
- # # min_detection_confidence = gr.Slider(minimum=0.0, maximum=1.0, value=0.5, label="Min Detection Confidence")
143
- # # min_tracking_confidence = gr.Slider(minimum=0.0, maximum=1.0, value=0.5, label="Min Tracking Confidence")
144
- # # alpha = gr.Slider(minimum=0.0, maximum=1.0, value=0.3, label="Overlay Transparency")
145
- # with gr.Row():
146
- # input_video = gr.Video(height=500,width=400,label="Upload Video")
147
- # output_video = gr.Video(height=500,label="Processed Video")
148
- # process_video_btn = gr.Button("Process Video")
149
- # process_video_btn.click(process_video,
150
- # inputs=[input_video, overlay_file,],
151
- # outputs=output_video)
152
-
153
- # with gr.Tab("Webcam"):
154
- # with gr.Row():
155
- # overlay_file = gr.Dropdown(choices=overlay_choices, value='Blue', label="Select a color")
156
- # # min_detection_confidence = gr.Slider(minimum=0.0, maximum=1.0, value=0.5, label="Min Detection Confidence")
157
- # # min_tracking_confidence = gr.Slider(minimum=0.0, maximum=1.0, value=0.5, label="Min Tracking Confidence")
158
- # # alpha = gr.Slider(minimum=0.0, maximum=1.0, value=0.3, label="Overlay Transparency")
159
- # with gr.Row():
160
- # # input_webcam = gr.Video(sources="webcam", label="Webcam")
161
- # webcam = gr.Image(sources="webcam",label="Processed Webcam",streaming=True)
162
- # process_webcam_btn = gr.Button("Process Webcam")
163
- # process_webcam_btn.click(process_webcam,
164
- # inputs=[webcam, overlay_file,],
165
- # outputs=webcam)
166
-
167
- # demo.launch()
168
  overlay_file = gr.Dropdown(choices=overlay_choices, value='Blue', label="Select a color")
169
- demo = gr.Interface(
170
  process_image,
171
- [gr.Image(sources=["webcam"], streaming=True),overlay_file],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
172
  "image",
173
  live=True
174
  )
175
- demo.launch()
 
 
 
 
 
4
  import gradio as gr
5
  import cv2 as cv
6
  import numpy as np
7
+ import time
8
  import mediapipe as mp
9
+ from mediapipe.tasks import python
10
+ from mediapipe.tasks.python import vision
11
+
12
+ from utils import blinkRatio,LEFT_EYE,RIGHT_EYE,LEFT_IRIS,RIGHT_IRIS
13
+
14
+
15
 
16
  def custom_excepthook(type, value, tb):
17
  traceback.print_exception(type, value, tb)
 
22
  def list_overlay_images(directory):
23
  return [f for f in os.listdir(directory) if f.endswith('.png')]
24
 
25
+ def process_frame(frame, overlay, results, frame_timestamp_ms=None, task='image', alpha=None):
26
+ if results.face_landmarks:
27
+ rgba_frame = cv.cvtColor(frame, cv.COLOR_BGR2RGBA)
28
+ height, width = rgba_frame.shape[:2]
 
 
29
  zero_overlay = np.zeros_like(rgba_frame)
30
  mesh_points = np.array([np.multiply([p.x, p.y],
31
+ [width, height]).astype(int) for p in results.face_landmarks[0]])
32
  iris_mask_left = np.zeros(rgba_frame.shape, dtype=np.uint8)
33
  iris_mask_right = np.zeros(rgba_frame.shape, dtype=np.uint8)
34
+ _, re_ratio, le_ratio = blinkRatio(frame, mesh_points, RIGHT_EYE, LEFT_EYE)
35
  (l_cx, l_cy), l_radius = cv.minEnclosingCircle(mesh_points[LEFT_IRIS])
36
  (r_cx, r_cy), r_radius = cv.minEnclosingCircle(mesh_points[RIGHT_IRIS])
37
  center_left = (int(l_cx), int(l_cy))
 
64
  return rgba_frame
65
 
66
  def process_image(input_image, overlay_file, alpha=0.3):
67
+ model_path = os.path.join(os.getcwd(),'face_landmarker.task')
68
+ BaseOptions = mp.tasks.BaseOptions
69
+ FaceLandmarker = mp.tasks.vision.FaceLandmarker
70
+ FaceLandmarkerOptions = mp.tasks.vision.FaceLandmarkerOptions
71
+ VisionRunningMode = mp.tasks.vision.RunningMode
72
+ options = FaceLandmarkerOptions(
73
+ base_options=BaseOptions(model_asset_path=model_path),
74
+ running_mode=VisionRunningMode.IMAGE)
75
+ with FaceLandmarker.create_from_options(options) as landmarker:
76
+ overlay_file = overlay_file + '.png'
77
+ overlay_path = os.path.join(os.getcwd(),'overlays', overlay_file)
78
+ overlay = cv.imread(overlay_path, cv.IMREAD_UNCHANGED)
79
+ frame = np.array(input_image)
80
+ if frame.dtype != np.uint8:
81
+ frame = (frame * 255).astype(np.uint8)
82
+ rgb_frame = cv.cvtColor(frame, cv.COLOR_BGR2RGB)
83
+ mp_frame = mp.Image(image_format=mp.ImageFormat.SRGB, data=rgb_frame)
84
+ results = landmarker.detect(mp_frame)
85
+ processed_frame = process_frame(frame=frame, overlay=overlay, results=results, alpha=alpha)
86
+ return cv.cvtColor(processed_frame, cv.COLOR_BGR2RGB)
87
 
88
  def process_video(input_video, overlay_file, alpha=0.3, output_format='mp4', output_frame_rate=30):
89
+ model_path = os.path.join(os.getcwd(), 'face_landmarker.task')
90
+ BaseOptions = mp.tasks.BaseOptions
91
+ FaceLandmarker = mp.tasks.vision.FaceLandmarker
92
+ FaceLandmarkerOptions = mp.tasks.vision.FaceLandmarkerOptions
93
+ VisionRunningMode = mp.tasks.vision.RunningMode
94
+ options = FaceLandmarkerOptions(
95
+ base_options=BaseOptions(model_asset_path=model_path),
96
+ running_mode=VisionRunningMode.VIDEO)
97
+
98
+ with FaceLandmarker.create_from_options(options) as landmarker:
99
+ overlay_file = overlay_file + '.png'
100
+ overlay_path = os.path.join(os.getcwd(), 'overlays', overlay_file)
101
+ overlay = cv.imread(overlay_path, cv.IMREAD_UNCHANGED)
102
+ cap = cv.VideoCapture(input_video)
103
+ output_path = os.path.join(os.getcwd(), f'video_processed.{output_format}')
104
+
105
+ if overlay is not None and cap.isOpened():
106
+ fps = int(output_frame_rate) if output_frame_rate > 0 else cap.get(cv.CAP_PROP_FPS)
107
+ h, w = None, None
108
+ new_h, new_w = None, None
109
+ frame_idx = 0
110
+ fourcc = cv.VideoWriter_fourcc(*'mp4v' if output_format == 'mp4' else 'MJPG')
111
+ out = cv.VideoWriter(output_path, fourcc, fps, (new_w, new_h))
112
+ start_time = time.time()
113
+
114
+ while cap.isOpened():
115
+ ret, frame = cap.read()
116
+ if not ret:
117
+ break
118
+ if h is None or w is None:
119
+ h, w, _ = frame.shape
120
+ new_h = 800
121
+ new_w = int((w / h) * new_h)
122
+ out = cv.VideoWriter(output_path, fourcc, fps, (new_w, new_h)) # Initialize output writer with correct size
123
+ frame = cv.resize(frame, (new_w, new_h), interpolation=cv.INTER_NEAREST)
124
+ if frame.dtype != np.uint8:
125
+ frame = (frame * 255).astype(np.uint8)
126
+ rgb_frame = cv.cvtColor(frame, cv.COLOR_BGR2RGB)
127
+ mp_frame = mp.Image(image_format=mp.ImageFormat.SRGB, data=rgb_frame)
128
+ timestamp = int(frame_idx * 1000 / fps) # Convert frame index to milliseconds
129
+ results = landmarker.detect_for_video(mp_frame, timestamp)
130
+ processed_frame = process_frame(frame=frame, overlay=overlay, results=results, alpha=alpha)
131
  processed_frame = cv.cvtColor(processed_frame, cv.COLOR_RGBA2BGR)
132
  out.write(processed_frame)
133
+ frame_idx += 1
134
+
135
+ cap.release()
136
+ out.release()
137
+
138
+ end_time = time.time()
139
+ execution_time = end_time - start_time
140
+ print(f"Execution time: {execution_time} seconds")
141
+
142
+ return output_path
143
 
144
 
145
+ def process_webcam(frame, overlay_file, alpha=0.3, min_detection_confidence=0.5, min_tracking_confidence=0.5):
146
+ BaseOptions = mp.tasks.BaseOptions
147
+ FaceLandmarker = mp.tasks.vision.FaceLandmarker
148
+ FaceLandmarkerOptions = mp.tasks.vision.FaceLandmarkerOptions
149
+ FaceLandmarkerResult = mp.tasks.vision.FaceLandmarkerResult
150
+ VisionRunningMode = mp.tasks.vision.RunningMode
151
+
152
+ model_path = os.path.join(os.getcwd(), 'face_landmarker.task')
153
+ overlay_file = overlay_file + '.png'
154
+ overlay_path = os.path.join(os.getcwd(), overlay_file)
155
+ overlay = cv.imread(overlay_path, cv.IMREAD_UNCHANGED)
156
+
157
+ global latest_results
158
+ latest_results = None
159
+
160
+ def return_result(result: FaceLandmarkerResult, output_image: mp.Image, timestamp_ms: int):
161
+ global latest_results
162
+ latest_results = result
163
+
164
+ options = FaceLandmarkerOptions(
165
+ base_options=BaseOptions(model_asset_path=model_path),
166
+ running_mode=VisionRunningMode.LIVE_STREAM,
167
+ result_callback=return_result)
168
+
169
+ with FaceLandmarker.create_from_options(options) as landmarker:
170
+ timestamp_ms = int(time.time() * 1000) # Current time in milliseconds
171
+ mp_image = mp.Image(image_format=mp.ImageFormat.SRGB, data=frame)
172
+ landmarker.detect_async(mp_image, timestamp_ms)
173
+
174
+ while latest_results is None:
175
+ time.sleep(0.01) # Wait for the result to be available
176
+
177
+ processed_frame = process_frame(frame, overlay, latest_results, alpha)
178
+ return processed_frame
179
 
 
 
 
 
 
 
 
 
180
 
 
 
 
 
181
 
182
  overlay_dir = os.path.join(os.getcwd(),'overlays')
183
  overlay_files = list_overlay_images(overlay_dir)
184
  overlay_choices = [x.split('.png')[0] for x in overlay_files]
185
+
186
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
187
  overlay_file = gr.Dropdown(choices=overlay_choices, value='Blue', label="Select a color")
188
+ image_interface = gr.Interface(
189
  process_image,
190
+ [gr.Image(height=500,label="Upload Image"),
191
+ gr.Dropdown(choices=overlay_choices, value='Blue', label="Select a color")],
192
+ gr.Image(height=500),
193
+ )
194
+
195
+ video_interface = gr.Interface(
196
+ process_video,
197
+ [gr.Video(height=500,label="Upload Video"),
198
+ gr.Dropdown(choices=overlay_choices, value='Blue', label="Select a color")],
199
+ gr.Video(height=500,label="Processed Video"),
200
+ )
201
+
202
+ webcam_interface = gr.Interface(
203
+ process_webcam,
204
+ [gr.Image(sources=["webcam"], streaming=True),
205
+ gr.Dropdown(choices=overlay_choices, value='Blue', label="Select a color")],
206
  "image",
207
  live=True
208
  )
209
+
210
+ demo = gr.TabbedInterface([image_interface,video_interface,webcam_interface],['Image','Video','Webcam'])
211
+
212
+
213
+ demo.launch()