¿Cómo acceder a la cámara web en OpenCV en PythonAnywhere a través de Javascript?

8

He desarrollado una aplicación web en Django que tiene un método de visualización que contiene el código OpevCV que, cuando se activa, abre la cámara web del usuario para detectar su cara. Esta aplicación funciona bien en mi servidor local, pero cuando la he alojado en PythonAnywhere dice que la cámara no se encuentra ya que mi alojamiento de PA no sirve una cámara.
Entonces, alguien me sugirió que abriera la cámara web a través de JavaScript, ya que trata con la máquina del cliente y luego pasa su feed a la máquina del servidor, que es mi alojamiento.
Pero como soy un novato en Python, no puedo entender cómo realizar la tarea anterior. Encontré este fragmento de código js pero no sé cómo y dónde agregarlo en mi aplicación Django.

Código para obtener el feed con Javascript

var video = document.querySelector("#videoElement");

if (navigator.mediaDevices.getUserMedia) {
    navigator.mediaDevices.getUserMedia({video: true}).then(function(stream) {
      video.srcObject = stream;
  }).catch(function(err0r) {
      console.log("Something went wrong!");
  });
}

Mi código de Python para abrir la cámara y detectar caras es el siguiente (funciona en el servidor local)

import cv2

cascade = cv2.CascadeClassifier('./haarcascade_frontalface_default.xml')

cam = cv2.VideoCapture(0)


while True:
    ret, frame = cam.read()
    frame = cv2.flip(frame, 1)

    if ret:
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

        faces = cascade.detectMultiScale(gray, scaleFactor=1.3, minNeighbors=3)

        for (x, y, w, h) in faces:
            cropped = cv2.resize(frame[y:y+h, x:x+w], (198,198))
            cv2.rectangle(frame, (x, y), (x+w, y+h), (255, 0, 0), 2)

        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
            cv2.destroyAllWindows()

        cv2.imshow('Stream', frame)

Cualquier ayuda es apreciada. Gracias de antemano

Aayush Gupta
fuente

Respuestas:

1

Solía ​​hacer algo similar, el esquema que usé fue el siguiente:

Flujo de datos

Como ya sabe, necesitamos JavaScript para obtener la imagen del usuario de la cámara web. Encontre un articulo que nos muestra cómo hacerlo, puede usar solo el lado frontal (el archivo HTML) si desea usar Django. Ese código es para obtener imágenes y codificarlo en base64 (cadena) y enviarlo a través de websocket.

Después de eso, queremos que Django sirva websocket. En el pasado, lo hice con Flask, no con Django, pero puedes ver cómo puedes crear un servidor websocket usando django-channel .

Para el último paso, necesita una función con su código OpenCV. Necesita decodificar base64 y convertirlo a opencv

def modify_picture(img_data):
    # decode image
    img = from_b64(img_data)

    # your OpenCV filter
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    # encode image to base64
    return to_b64(gray)

Y, por supuesto, no necesita while Truey cv2.imshow, pero devuelva la versión base64 de su nueva imagen. Espero eso ayude.


Actualización: escribo un código de muestra en mi github . No en Django, pero aún en Python. Espero que te dé más información.

Tegar
fuente
Hola, llevará algún tiempo probar su solución, pero aún así acepto sus esfuerzos, ya que hay un límite de tiempo. gracias por tu ayuda
Aayush Gupta
Hola, estoy luchando un poco para implementar este. ¡Me encantaría saber si alguien tiene éxito!
Joesmaker
1
hola @Joesmaker, acabo de poner una implementación de muestra para el concepto. Puedes ver la respuesta actualizada.
Tegar
@Tegar Hola, gracias por compartir!
Joesmaker
@Tegar, intenté usar tu código git, pero cuando el servidor se activa después del golpe, aparece una matriz en blanco que dice eso{ details: not found }
Aayush Gupta,
-1

Necesita obtener la transmisión de video en vivo usando javascript, luego alimentar esa transmisión a opencv2 para que funcione.

Uso: obtenga videostream en vivo en nodejs

Obtendrá una URL "http://localhost:3000"que puede usar en el código de Python de la siguiente manera:

import cv2

cascade = cv2.CascadeClassifier('./haarcascade_frontalface_default.xml')

cam = cv2.VideoCapture('http://localhost:3000')


while True:
    ret, frame = cam.read()
    frame = cv2.flip(frame, 1)

    if ret:
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

        faces = cascade.detectMultiScale(gray, scaleFactor=1.3, minNeighbors=3)

        for (x, y, w, h) in faces:
            cropped = cv2.resize(frame[y:y+h, x:x+w], (198,198))
            cv2.rectangle(frame, (x, y), (x+w, y+h), (255, 0, 0), 2)

        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
            cv2.destroyAllWindows()

        cv2.imshow('Stream', frame)
Sunil Lama
fuente
Hola, la solución que ha proporcionado transmite el video desde un archivo y no desde mi cámara web en vivo.
Aayush Gupta
Hubiera sido genial si me hubieras dado una respuesta relevante a mi código. En realidad, la solución anterior no me funciona
Aayush Gupta