jarondon82 commited on
Commit
ef29226
·
1 Parent(s): 44a87dc

fix: [Lunes 25/03/2024 15:30] Mejorada la detección de ojos y sonrisas - Optimización de parámetros y regiones de interés

Browse files
Files changed (1) hide show
  1. streamlit_app.py +47 -143
streamlit_app.py CHANGED
@@ -174,8 +174,6 @@ def main():
174
 
175
  for bbox in bboxes:
176
  x1, y1, x2, y2, _ = bbox
177
- roi_gray = gray[y1:y2, x1:x2]
178
- roi_color = result_frame[y1:y2, x1:x2]
179
  face_width = x2 - x1
180
  face_height = y2 - y1
181
 
@@ -183,170 +181,76 @@ def main():
183
  if detect_eyes:
184
  # Adjust region of interest to focus on the upper part of the face
185
  upper_face_y1 = y1
186
- upper_face_y2 = y1 + int(face_height * 0.55) # Slightly reduced to focus more on the eye area
187
 
188
- # For profile faces, we need to search the entire upper region
189
- # as well as the left and right sides separately
 
190
 
191
- # Full upper region for profile faces
192
- upper_face_roi_gray = gray[upper_face_y1:upper_face_y2, x1:x2]
193
- upper_face_roi_color = result_frame[upper_face_y1:upper_face_y2, x1:x2]
194
-
195
- # Split the upper region into two halves (left and right) to search for eyes individually
196
- mid_x = x1 + face_width // 2
197
- left_eye_roi_gray = gray[upper_face_y1:upper_face_y2, x1:mid_x]
198
- right_eye_roi_gray = gray[upper_face_y1:upper_face_y2, mid_x:x2]
199
-
200
- left_eye_roi_color = result_frame[upper_face_y1:upper_face_y2, x1:mid_x]
201
- right_eye_roi_color = result_frame[upper_face_y1:upper_face_y2, mid_x:x2]
202
-
203
- # Apply histogram equalization and contrast enhancement for all regions
204
- if upper_face_roi_gray.size > 0:
205
- upper_face_roi_gray = cv2.equalizeHist(upper_face_roi_gray)
206
-
207
- # Enhance contrast
208
  clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
209
- upper_face_roi_gray = clahe.apply(upper_face_roi_gray)
210
 
211
- # First try to detect eyes in the full upper region (for profile faces)
212
- full_eyes = eye_cascade.detectMultiScale(
213
- upper_face_roi_gray,
214
- scaleFactor=1.02, # More sensitive for profile faces
215
- minNeighbors=max(1, eye_sensitivity-3), # Even more sensitive
216
- minSize=(int(face_width * 0.07), int(face_width * 0.07)),
217
- maxSize=(int(face_width * 0.3), int(face_width * 0.3))
218
  )
219
 
220
- # If we found eyes in the full region, use those
221
- if len(full_eyes) > 0:
222
- # Sort by size (area) and take up to 2 largest
223
- full_eyes = sorted(full_eyes, key=lambda e: e[2] * e[3], reverse=True)
224
- full_eyes = full_eyes[:2] # Take at most 2 eyes
225
 
226
- for ex, ey, ew, eh in full_eyes:
227
- eye_count += 1
228
- cv2.rectangle(upper_face_roi_color, (ex, ey), (ex+ew, ey+eh), (255, 0, 0), 2)
229
- cv2.putText(upper_face_roi_color, "Eye", (ex, ey-5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 2)
230
- else:
231
- # If no eyes found in full region, try left and right separately
232
- if left_eye_roi_gray.size > 0:
233
- left_eye_roi_gray = cv2.equalizeHist(left_eye_roi_gray)
234
- left_eye_roi_gray = clahe.apply(left_eye_roi_gray)
235
-
236
- left_eyes = eye_cascade.detectMultiScale(
237
- left_eye_roi_gray,
238
- scaleFactor=1.03,
239
- minNeighbors=max(1, eye_sensitivity-2),
240
- minSize=(int(face_width * 0.08), int(face_width * 0.08)),
241
- maxSize=(int(face_width * 0.25), int(face_width * 0.25))
242
- )
243
-
244
- if len(left_eyes) > 0:
245
- # Sort by size and take the largest
246
- left_eyes = sorted(left_eyes, key=lambda e: e[2] * e[3], reverse=True)
247
- left_eye = left_eyes[0]
248
  eye_count += 1
249
-
250
- # Draw rectangle for the left eye
251
- ex, ey, ew, eh = left_eye
252
- cv2.rectangle(left_eye_roi_color, (ex, ey), (ex+ew, ey+eh), (255, 0, 0), 2)
253
- cv2.putText(left_eye_roi_color, "Eye", (ex, ey-5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 2)
254
-
255
- if right_eye_roi_gray.size > 0:
256
- right_eye_roi_gray = cv2.equalizeHist(right_eye_roi_gray)
257
- right_eye_roi_gray = clahe.apply(right_eye_roi_gray)
258
-
259
- right_eyes = eye_cascade.detectMultiScale(
260
- right_eye_roi_gray,
261
- scaleFactor=1.03,
262
- minNeighbors=max(1, eye_sensitivity-2),
263
- minSize=(int(face_width * 0.08), int(face_width * 0.08)),
264
- maxSize=(int(face_width * 0.25), int(face_width * 0.25))
265
- )
266
-
267
- if len(right_eyes) > 0:
268
- # Sort by size and take the largest
269
- right_eyes = sorted(right_eyes, key=lambda e: e[2] * e[3], reverse=True)
270
- right_eye = right_eyes[0]
271
- eye_count += 1
272
-
273
- # Draw rectangle for the right eye
274
- ex, ey, ew, eh = right_eye
275
- cv2.rectangle(right_eye_roi_color, (ex, ey), (ex+ew, ey+eh), (255, 0, 0), 2)
276
- cv2.putText(right_eye_roi_color, "Eye", (ex, ey-5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 2)
277
 
278
  # Detect smile if enabled
279
  if detect_smile:
280
- # For profile faces, we need to adjust the region of interest
281
- # Try multiple regions to improve detection
 
282
 
283
- # Standard region (middle to bottom)
284
- lower_face_y1 = y1 + int(face_height * 0.5)
285
- lower_face_roi_gray = gray[lower_face_y1:y2, x1:x2]
286
- lower_face_roi_color = result_frame[lower_face_y1:y2, x1:x2]
287
 
288
- # Alternative region (lower third)
289
- alt_lower_face_y1 = y1 + int(face_height * 0.65)
290
- alt_lower_face_roi_gray = gray[alt_lower_face_y1:y2, x1:x2]
291
-
292
- # Apply histogram equalization and enhance contrast
293
- smile_detected = False
294
-
295
- if lower_face_roi_gray.size > 0:
296
- lower_face_roi_gray = cv2.equalizeHist(lower_face_roi_gray)
297
  clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
298
- lower_face_roi_gray = clahe.apply(lower_face_roi_gray)
299
 
300
- # Try with standard parameters
301
  smiles = smile_cascade.detectMultiScale(
302
- lower_face_roi_gray,
303
- scaleFactor=1.2,
304
- minNeighbors=smile_sensitivity,
305
- minSize=(int(face_width * 0.25), int(face_width * 0.15)),
306
- maxSize=(int(face_width * 0.7), int(face_width * 0.4))
307
  )
308
 
 
309
  if len(smiles) > 0:
310
  # Sort by size and take the largest
311
  smiles = sorted(smiles, key=lambda s: s[2] * s[3], reverse=True)
312
  sx, sy, sw, sh = smiles[0]
313
 
314
- # Increment smile counter
315
- smile_count += 1
316
- smile_detected = True
317
-
318
- # Draw rectangle for the smile
319
- cv2.rectangle(lower_face_roi_color, (sx, sy), (sx+sw, sy+sh), (0, 0, 255), 2)
320
- cv2.putText(lower_face_roi_color, "Smile", (sx, sy-5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)
321
-
322
- # If no smile detected in standard region, try alternative region
323
- if not smile_detected and alt_lower_face_roi_gray.size > 0:
324
- alt_lower_face_roi_gray = cv2.equalizeHist(alt_lower_face_roi_gray)
325
- alt_lower_face_roi_gray = clahe.apply(alt_lower_face_roi_gray)
326
-
327
- # Try with more sensitive parameters
328
- alt_smiles = smile_cascade.detectMultiScale(
329
- alt_lower_face_roi_gray,
330
- scaleFactor=1.1,
331
- minNeighbors=max(1, smile_sensitivity-5), # More sensitive
332
- minSize=(int(face_width * 0.2), int(face_width * 0.1)),
333
- maxSize=(int(face_width * 0.6), int(face_width * 0.3))
334
- )
335
-
336
- if len(alt_smiles) > 0:
337
- # Sort by size and take the largest
338
- alt_smiles = sorted(alt_smiles, key=lambda s: s[2] * s[3], reverse=True)
339
- sx, sy, sw, sh = alt_smiles[0]
340
-
341
- # Adjust coordinates for the alternative region
342
- adjusted_sy = sy + (alt_lower_face_y1 - lower_face_y1)
343
-
344
- # Increment smile counter
345
- smile_count += 1
346
-
347
- # Draw rectangle for the smile (in the original lower face ROI)
348
- cv2.rectangle(lower_face_roi_color, (sx, adjusted_sy), (sx+sw, adjusted_sy+sh), (0, 0, 255), 2)
349
- cv2.putText(lower_face_roi_color, "Smile", (sx, adjusted_sy-5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)
350
 
351
  return result_frame, eye_count, smile_count
352
 
 
174
 
175
  for bbox in bboxes:
176
  x1, y1, x2, y2, _ = bbox
 
 
177
  face_width = x2 - x1
178
  face_height = y2 - y1
179
 
 
181
  if detect_eyes:
182
  # Adjust region of interest to focus on the upper part of the face
183
  upper_face_y1 = y1
184
+ upper_face_y2 = y1 + int(face_height * 0.45) # Reduced to focus more on the eye area
185
 
186
+ # Extract ROI for eyes
187
+ eye_roi_gray = gray[upper_face_y1:upper_face_y2, x1:x2]
188
+ eye_roi_color = result_frame[upper_face_y1:upper_face_y2, x1:x2]
189
 
190
+ if eye_roi_gray.size > 0:
191
+ # Enhance contrast for better detection
192
+ eye_roi_gray = cv2.equalizeHist(eye_roi_gray)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
193
  clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
194
+ eye_roi_gray = clahe.apply(eye_roi_gray)
195
 
196
+ # Detect eyes with adjusted parameters
197
+ eyes = eye_cascade.detectMultiScale(
198
+ eye_roi_gray,
199
+ scaleFactor=1.05,
200
+ minNeighbors=max(3, eye_sensitivity),
201
+ minSize=(int(face_width * 0.1), int(face_width * 0.1)),
202
+ maxSize=(int(face_width * 0.25), int(face_width * 0.25))
203
  )
204
 
205
+ # Process detected eyes
206
+ if len(eyes) > 0:
207
+ # Sort by size and position
208
+ eyes = sorted(eyes, key=lambda e: (e[2] * e[3], -e[1])) # Sort by size and vertical position
209
+ eyes = eyes[:2] # Take at most 2 largest eyes
210
 
211
+ for (ex, ey, ew, eh) in eyes:
212
+ # Validate eye size and position
213
+ if ew * eh > (face_width * face_height * 0.01): # Minimum size threshold
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
214
  eye_count += 1
215
+ cv2.rectangle(eye_roi_color, (ex, ey), (ex+ew, ey+eh), (255, 0, 0), 2)
216
+ cv2.putText(eye_roi_color, "Eye", (ex, ey-5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 2)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
217
 
218
  # Detect smile if enabled
219
  if detect_smile:
220
+ # Adjust region of interest for smile detection
221
+ lower_face_y1 = y1 + int(face_height * 0.5) # Start from middle of face
222
+ lower_face_y2 = y2
223
 
224
+ # Extract ROI for smile
225
+ smile_roi_gray = gray[lower_face_y1:lower_face_y2, x1:x2]
226
+ smile_roi_color = result_frame[lower_face_y1:lower_face_y2, x1:x2]
 
227
 
228
+ if smile_roi_gray.size > 0:
229
+ # Enhance contrast for better detection
230
+ smile_roi_gray = cv2.equalizeHist(smile_roi_gray)
 
 
 
 
 
 
231
  clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
232
+ smile_roi_gray = clahe.apply(smile_roi_gray)
233
 
234
+ # Detect smiles with adjusted parameters
235
  smiles = smile_cascade.detectMultiScale(
236
+ smile_roi_gray,
237
+ scaleFactor=1.1,
238
+ minNeighbors=max(5, smile_sensitivity),
239
+ minSize=(int(face_width * 0.3), int(face_width * 0.15)),
240
+ maxSize=(int(face_width * 0.6), int(face_width * 0.3))
241
  )
242
 
243
+ # Process detected smiles
244
  if len(smiles) > 0:
245
  # Sort by size and take the largest
246
  smiles = sorted(smiles, key=lambda s: s[2] * s[3], reverse=True)
247
  sx, sy, sw, sh = smiles[0]
248
 
249
+ # Validate smile size and position
250
+ if sw * sh > (face_width * face_height * 0.05): # Minimum size threshold
251
+ smile_count += 1
252
+ cv2.rectangle(smile_roi_color, (sx, sy), (sx+sw, sy+sh), (0, 0, 255), 2)
253
+ cv2.putText(smile_roi_color, "Smile", (sx, sy-5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
254
 
255
  return result_frame, eye_count, smile_count
256