? Videostreaming con Flask y OpenCV | Python
En este post podrás encontrar los programas realizados en el videotutorial: ? Videostreaming con Flask y OpenCV | Python en el que construimos una pequeña aplicación Web con ayuda de Flask y OpenCV. ?? Esta aplicación consta de un videostreaming/video en directo, en el cual hemos aplicado detección facial. ¡Anímate a probarlo!.
¡Vamos con la programación!
Para una explicación más detallada del programa que veremos a continuación, por favor dirígete al videotutorial de mi canal.
Aplicación web con Flask y OpenCV
from flask import Flask from flask import render_template from flask import Response import cv2 app = Flask(__name__) cap = cv2.VideoCapture(0, cv2.CAP_DSHOW) face_detector = cv2.CascadeClassifier(cv2.data.haarcascades + "haarcascade_frontalface_default.xml") def generate(): while True: ret, frame = cap.read() if ret: gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) faces = face_detector.detectMultiScale(gray, 1.3, 5) for (x, y, w, h) in faces: cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2) (flag, encodedImage) = cv2.imencode(".jpg", frame) if not flag: continue yield(b'--frame\r\n' b'Content-Type: image/jpeg\r\n\r\n' + bytearray(encodedImage) + b'\r\n') @app.route("/") def index(): return render_template("index.html") @app.route("/video_feed") def video_feed(): return Response(generate(), mimetype = "multipart/x-mixed-replace; boundary=frame") if __name__ == "__main__": app.run(debug=False) cap.release()
Plantilla HTML
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Videostreaming</title> <style> .container{ margin: 0; padding: 0; width: 100%; height: 100vh; background-color: #E2D8F8; color: black; text-align: center; } </style> </head> <body class = "container"> <h1>Video en directo</h1> <img src="{{ url_for('video_feed') }}"> </body> </html>
Referencias
LINK DEBUG = TRUE/FALSE PARA VISUALIZAR VIDEOSTREAMING:
? https://stackoverflow.com/questions/61047207/opencv-videocapture-does-not-work-in-flask-project-but-works-in-basic-example
? https://www.pyimagesearch.com/2019/09/02/opencv-stream-video-to-web-browser-html-page/
? https://blog.miguelgrinberg.com/post/video-streaming-with-flask/page/5
? https://medium.datadriveninvestor.com/video-streaming-using-flask-and-opencv-c464bf8473d6
? https://towardsdatascience.com/video-streaming-in-web-browsers-with-opencv-flask-93a38846fe00
? https://stackoverflow.com/questions/231767/what-does-the-yield-keyword-do
? https://docs.opencv.org/3.4/d4/da8/group__imgcodecs.html#ga461f9ac09887e47797a54567df3b8b63
Documentación y recursos FLASK:
? https://flask.palletsprojects.com/en/2.0.x/
? Video: https://www.youtube.com/watch?v=Yz1gUwXPPJw
Documentación y recursos HTML:
? Video: https://www.youtube.com/watch?v=rbuYtrNUxg4
? https://www.w3schools.com/html/
? https://escuelamarenostrum.com/que-son-las-etiquetas-html/
Exelente aporte, aqui dejo las modificaciones para realizar la misma tarea pero usando Django
face_manager_proyect/
|–manage.py
|–face_manager_proyect/
|–__init__.py
|–settings.py # se usa
|–urls.py #se usa
|–wsgi.py
|–face_manager_app/
|–__init__.py
|–admin.py
|–migrations.py
|–models.py
|–templates/
|–index.html # se usa
|–views.py # se usa
|–urls.py # se usa
*face_manager_proyect/face_manager_proyect/settings.py
INSTALLED_APPS = [
‘django.contrib.admin’,
‘django.contrib.auth’,
‘django.contrib.contenttypes’,
‘django.contrib.sessions’,
‘django.contrib.messages’,
‘django.contrib.staticfiles’,
‘face_manager_app’, # agregar
]
TEMPLATES = [
{
‘BACKEND’: ‘django.template.backends.django.DjangoTemplates’,
…
‘APP_DIRS’: True,
…
},
]
*face_manager_proyect/face_manager_proyect/urls.py
from django.contrib import admin
from django.urls import path
from django.urls import include # new
urlpatterns = [
path(‘admin/’, admin.site.urls),
path(»,include(‘face_manager_app.urls’)) # new
]
*face_manager_proyect/face_manager_app/urls.py
from django.urls import path
from .import views
urlpatterns = [
path(», views.index, name=’index’),
path(‘video_feed’, views.video_feed, name=’video_feed’),
]
*face_manager_proyect/face_manager_app/views.py
import cv2
from django.shortcuts import render
from django.http.response import StreamingHttpResponse
class VideoCamera(object):
def __init__(self):
self.cap = cv2.VideoCapture(0, cv2.CAP_DSHOW)
self.face_detector = cv2.CascadeClassifier(cv2.data.haarcascades + «haarcascade_frontalface_default.xml»)
def __del__(self):
self.cap.release()
def get_frame(self):
ret, frame = self.cap.read()
if ret:
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
faces = self.face_detector.detectMultiScale(gray, 1.3, 5)
for (x, y, w, h) in faces:
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
(flag, encodedImage) = cv2.imencode(«.jpg», frame)
return flag, encodedImage
def generate(camera):
while True:
flag, encodedImage = camera.get_frame()
if not flag:
continue
yield(b’–frame\r\n’ b’Content-Type: image/jpeg\r\n\r\n’ + bytearray(encodedImage) + b’\r\n’)
def index(request):
return render(request, ‘face_manager_app/index.html’)
def video_feed(request):
return StreamingHttpResponse(
generate(VideoCamera()),
content_type=’multipart/x-mixed-replace; boundary=frame’
)
*face_manager_proyect/face_manager_app/template/index.html
Live video stream
Live Video Stream
buenas muy buena explicacion pero tengo problemas a produccion en cuestion del videocapture(0) como se podria solucionar?
Hola Fabricio muchas gracias. Cuéntame, qué error obtienes?
Hola, en caso de que quisiera publicar alguna app utilizando flask y opencv, como podría utilizar la cámara del usuario mediante el navegador, ya que intente desplegar mi propia app utilizando tu método y no fue posible abrir la cámara, muy seguramente debido a que utilizo la cámara web local
Hola, me han ayudado mucho tus videos, en caso de que quisiera agregar un botón para grabar el video, que tendría que hacer?
Hola Gabi, gracias por compartir. Hice el ejemplo y me funcionó Ok… me quedó dando vueltas el tema del debug. Encontré una explicación y solución. Esto se debe a que cuando se ejecuta con debug, se ejecutan dos procesos en el Sistema Operativo, una solución es:
if os.environ.get(«WERKZEUG_RUN_MAIN») or Flask.debug is False:
cap = cv2.VideoCapture(0, cv2.CAP_DSHOW)
Por otro lado, al principio no me funcionaba en Ubuntu 18 y esto se debió a que CAP_DSHOW implica DirectShow (Windows) En este caso, por portabilidad es mejor utilizar CAP_ANY u omitir el segundo parámetro.
Saludos y muchas gracias nuevamente
Hola Gabi, el código que envié hace un momento no funcionó para uno de los casos, mis disculpas por no probar todo antes. La implmentación que me funcióno con debug=False o degub = True es esta
«`
«»»
Tutorial original
https://omes-va.com/videostreaming-flask-opencv-python/
«»»
import os
import cv2
from flask import Flask, Response, render_template
app = Flask(__name__)
face_detector = cv2.CascadeClassifier(
cv2.data.haarcascades + «haarcascade_frontalface_default.xml»
)
def generate(cap):
while True:
ret, frame = cap.read()
if ret:
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
faces = face_detector.detectMultiScale(gray, 1.3, 5)
for x, y, w, h in faces:
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
(flag, encodedImage) = cv2.imencode(«.jpg», frame)
if not flag:
continue
yield (
b»–frame\r\n»
b»Content-Type: image/jpeg\r\n\r\n» + bytearray(encodedImage) + b»\r\n»
)
@app.route(«/»)
def index():
return render_template(«index.html»)
@app.route(«/video_feed»)
def video_feed():
if os.environ.get(«WERKZEUG_RUN_MAIN») or app.debug is False:
cap = cv2.VideoCapture(0, cv2.CAP_ANY)
return Response(generate(cap), mimetype=»multipart/x-mixed-replace; boundary=frame»)
if __name__ == «__main__»:
app.run(debug=True)
«`