jarondon82 commited on
Commit
33bb295
·
1 Parent(s): a0de189

Corregir error OpenCV de resize en detección de rostros

Browse files
Files changed (1) hide show
  1. streamlit_app.py +96 -38
streamlit_app.py CHANGED
@@ -114,45 +114,75 @@ def main():
114
 
115
  # Function for detecting faces in an image
116
  def detect_face_dnn(net, frame, conf_threshold=0.5):
117
- blob = cv2.dnn.blobFromImage(frame, 1.0, (300, 300), [104, 117, 123], False, False)
118
- net.setInput(blob)
119
- detections = net.forward()
120
-
121
- # Procesar las detecciones para devolver una lista de bounding boxes
122
- bboxes = []
123
- frame_h = frame.shape[0]
124
- frame_w = frame.shape[1]
125
-
126
- for i in range(detections.shape[2]):
127
- confidence = detections[0, 0, i, 2]
128
- if confidence > conf_threshold:
129
- x1 = int(detections[0, 0, i, 3] * frame_w)
130
- y1 = int(detections[0, 0, i, 4] * frame_h)
131
- x2 = int(detections[0, 0, i, 5] * frame_w)
132
- y2 = int(detections[0, 0, i, 6] * frame_h)
133
-
134
- # Asegurarse de que las coordenadas estén dentro de los límites de la imagen
135
- x1 = max(0, min(x1, frame_w - 1))
136
- y1 = max(0, min(y1, frame_h - 1))
137
- x2 = max(0, min(x2, frame_w - 1))
138
- y2 = max(0, min(y2, frame_h - 1))
139
 
140
- # Añadir el bounding box y la confianza
141
- bboxes.append([x1, y1, x2, y2, confidence])
142
-
143
- return bboxes
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
144
 
145
  # Function for processing face detections
146
  def process_face_detections(frame, detections, conf_threshold=0.5, bbox_color=(0, 255, 0)):
147
  # Create a copy for drawing on
148
  result_frame = frame.copy()
149
 
150
- # Filtrar detecciones por umbral de confianza
151
- bboxes = []
152
- for detection in detections:
153
- if len(detection) == 5: # Asegurarse de que la detección tiene el formato correcto
154
- x1, y1, x2, y2, confidence = detection
155
- if confidence >= conf_threshold:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
156
  # Dibujar el bounding box
157
  cv2.rectangle(result_frame, (x1, y1), (x2, y2), bbox_color, 2)
158
 
@@ -162,6 +192,20 @@ def main():
162
 
163
  # Añadir a la lista de bounding boxes
164
  bboxes.append([x1, y1, x2, y2, confidence])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
165
 
166
  return result_frame, bboxes
167
 
@@ -2171,13 +2215,21 @@ def main():
2171
  return av.VideoFrame.from_ndarray(img, format="bgr24")
2172
 
2173
  try:
 
 
 
 
 
 
 
 
2174
  # Reducir tamaño del frame para procesamiento más rápido
2175
  scale_factor = 0.5
2176
- small_img = cv2.resize(img, (0, 0), fx=scale_factor, fy=scale_factor)
 
2177
 
2178
- # Detect faces
2179
- detections = detect_face_dnn(face_net, small_img, confidence_threshold)
2180
- _, bboxes = process_face_detections(small_img, detections, confidence_threshold)
2181
 
2182
  # Ajustar bounding boxes al tamaño original
2183
  original_bboxes = []
@@ -2216,8 +2268,14 @@ def main():
2216
  return av.VideoFrame.from_ndarray(result_frame, format="bgr24")
2217
 
2218
  except Exception as e:
2219
- print(f"Error en procesamiento de video: {e}")
2220
- return av.VideoFrame.from_ndarray(img, format="bgr24")
 
 
 
 
 
 
2221
 
2222
  # Display WebRTC streamer
2223
  webrtc_ctx = webrtc_streamer(
 
114
 
115
  # Function for detecting faces in an image
116
  def detect_face_dnn(net, frame, conf_threshold=0.5):
117
+ """
118
+ Detecta rostros usando el modelo DNN y devuelve las detecciones.
119
+ """
120
+ try:
121
+ # Verificar que el frame sea válido
122
+ if frame is None or frame.size == 0 or frame.shape[0] == 0 or frame.shape[1] == 0:
123
+ return []
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
124
 
125
+ # Crear blob a partir del frame (redimensionar a 300x300, escalar, etc.)
126
+ blob = cv2.dnn.blobFromImage(frame, 1.0, (300, 300), [104, 117, 123], False, False)
127
+
128
+ # Establecer la entrada para la red neuronal
129
+ net.setInput(blob)
130
+
131
+ # Realizar la detección
132
+ detections = net.forward()
133
+
134
+ # Procesar las detecciones para devolver una lista de bounding boxes
135
+ bboxes = []
136
+ frame_h = frame.shape[0]
137
+ frame_w = frame.shape[1]
138
+
139
+ for i in range(detections.shape[2]):
140
+ confidence = detections[0, 0, i, 2]
141
+ if confidence > conf_threshold:
142
+ x1 = int(detections[0, 0, i, 3] * frame_w)
143
+ y1 = int(detections[0, 0, i, 4] * frame_h)
144
+ x2 = int(detections[0, 0, i, 5] * frame_w)
145
+ y2 = int(detections[0, 0, i, 6] * frame_h)
146
+
147
+ # Asegurarse de que las coordenadas estén dentro de los límites
148
+ x1 = max(0, min(x1, frame_w - 1))
149
+ y1 = max(0, min(y1, frame_h - 1))
150
+ x2 = max(0, min(x2, frame_w - 1))
151
+ y2 = max(0, min(y2, frame_h - 1))
152
+
153
+ # Añadir el bounding box y la confianza
154
+ bboxes.append([x1, y1, x2, y2, confidence])
155
+
156
+ return bboxes
157
+ except Exception as e:
158
+ st.error(f"Error en la detección de rostros: {e}")
159
+ return []
160
 
161
  # Function for processing face detections
162
  def process_face_detections(frame, detections, conf_threshold=0.5, bbox_color=(0, 255, 0)):
163
  # Create a copy for drawing on
164
  result_frame = frame.copy()
165
 
166
+ # Procesar detecciones si son del formato original
167
+ if isinstance(detections, np.ndarray) and len(detections.shape) == 4:
168
+ bboxes = []
169
+ frame_h = frame.shape[0]
170
+ frame_w = frame.shape[1]
171
+
172
+ for i in range(detections.shape[2]):
173
+ confidence = detections[0, 0, i, 2]
174
+ if confidence > conf_threshold:
175
+ x1 = int(detections[0, 0, i, 3] * frame_w)
176
+ y1 = int(detections[0, 0, i, 4] * frame_h)
177
+ x2 = int(detections[0, 0, i, 5] * frame_w)
178
+ y2 = int(detections[0, 0, i, 6] * frame_h)
179
+
180
+ # Asegurarse de que las coordenadas estén dentro de los límites
181
+ x1 = max(0, min(x1, frame_w - 1))
182
+ y1 = max(0, min(y1, frame_h - 1))
183
+ x2 = max(0, min(x2, frame_w - 1))
184
+ y2 = max(0, min(y2, frame_h - 1))
185
+
186
  # Dibujar el bounding box
187
  cv2.rectangle(result_frame, (x1, y1), (x2, y2), bbox_color, 2)
188
 
 
192
 
193
  # Añadir a la lista de bounding boxes
194
  bboxes.append([x1, y1, x2, y2, confidence])
195
+ else:
196
+ # Si ya es una lista de bounding boxes (formato nuevo)
197
+ bboxes = detections
198
+ # Dibujar bounding boxes
199
+ for bbox in bboxes:
200
+ if len(bbox) == 5: # Asegurarse de que el bounding box tiene el formato correcto
201
+ x1, y1, x2, y2, confidence = bbox
202
+ if confidence >= conf_threshold:
203
+ # Dibujar el bounding box
204
+ cv2.rectangle(result_frame, (x1, y1), (x2, y2), bbox_color, 2)
205
+
206
+ # Añadir texto con la confianza
207
+ label = f"{confidence:.2f}"
208
+ cv2.putText(result_frame, label, (x1, y1-10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, bbox_color, 2)
209
 
210
  return result_frame, bboxes
211
 
 
2215
  return av.VideoFrame.from_ndarray(img, format="bgr24")
2216
 
2217
  try:
2218
+ # Verificar que la imagen no sea nula
2219
+ if img is None or img.size == 0 or img.shape[0] == 0 or img.shape[1] == 0:
2220
+ # Si la imagen es inválida, devolver un frame en blanco
2221
+ blank_frame = np.ones((480, 640, 3), dtype=np.uint8) * 255
2222
+ cv2.putText(blank_frame, "Error: Invalid frame", (50, 240),
2223
+ cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
2224
+ return av.VideoFrame.from_ndarray(blank_frame, format="bgr24")
2225
+
2226
  # Reducir tamaño del frame para procesamiento más rápido
2227
  scale_factor = 0.5
2228
+ h, w = img.shape[:2]
2229
+ small_img = cv2.resize(img, (int(w * scale_factor), int(h * scale_factor)))
2230
 
2231
+ # Detect faces - la función ahora devuelve directamente los bboxes
2232
+ bboxes = detect_face_dnn(face_net, small_img, confidence_threshold)
 
2233
 
2234
  # Ajustar bounding boxes al tamaño original
2235
  original_bboxes = []
 
2268
  return av.VideoFrame.from_ndarray(result_frame, format="bgr24")
2269
 
2270
  except Exception as e:
2271
+ # En caso de cualquier error, mostrar mensaje en la imagen
2272
+ error_frame = np.ones((480, 640, 3), dtype=np.uint8) * 255
2273
+ error_msg = f"Error: {str(e)}"
2274
+ cv2.putText(error_frame, error_msg[:50], (20, 240),
2275
+ cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
2276
+ cv2.putText(error_frame, "Intente usar opciones alternativas", (20, 280),
2277
+ cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
2278
+ return av.VideoFrame.from_ndarray(error_frame, format="bgr24")
2279
 
2280
  # Display WebRTC streamer
2281
  webrtc_ctx = webrtc_streamer(