Como acessar a webcam no OpenCV no PythonAnywhere através de Javascript?

8

Eu desenvolvi um WebApplication no Django que possui um método de exibição que contém o código OpevCV que, quando acionado, abre a Webcam do usuário para detectar sua face. Este aplicativo funciona bem no meu servidor local, mas quando eu o hospedei no PythonAnywhere, ele diz que a câmera não foi encontrada, pois a minha hospedagem PA não atende a uma câmera.
Então alguém me sugeriu abrir a webcam através de javascript, pois ela lida com a máquina cliente e depois passar o feed para a máquina servidor, que é minha hospedagem.
Mas como eu sou novato em Python, não consigo descobrir como executar a tarefa acima. Encontrei esse código js, ​​mas não sei como e onde adicioná-lo no meu Django App.

Código para obter o feed com 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!");
  });
}

Meu código Python para abrir a câmera e detectar rostos é o seguinte (funciona no 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)

Qualquer ajuda é apreciada. Agradeço antecipadamente

Aayush Gupta
fonte

Respostas:

1

Eu costumava fazer algo semelhante, o esquema que usei foi o seguinte:

Fluxo de dados

Como você já sabe, precisamos de javascript para obter a imagem do usuário na webcam. Encontrei um artigo que mostra como fazer isso; você pode usar apenas o lado da interface (o arquivo HTML) se quiser usar o Django. Esse código é para obter imagens e codificá-lo para base64 (string) e enviá-lo via websocket.

Depois disso, queremos que o Django sirva o websocket. No passado, eu fiz isso com o Flask, não com o Django, mas você pode ver como criar um servidor websocket usando o django-channel .

Para a última etapa, você precisa de uma função com seu código OpenCV. Você precisa decodificar base64 e convertê-lo em 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)

E, claro, você não precisa while Truee cv2.imshow, mas retorne a versão base64 da sua nova imagem. Espero que ajude.


Atualização: escrevo um código de exemplo no meu github . Não no Django, mas ainda em Python. Espero que isso lhe dê mais informações.

Tegar
fonte
oi vai demorar algum tempo para tentar a sua solução, mas ainda estou aceitando seus esforços, pois há um limite de tempo. obrigado pela sua ajuda
Aayush Gupta
Oi, estou lutando um pouco para implementar este. Gostaria de saber se alguém consegue!
Joesmaker 24/02
1
oi @ Joesmaker, acabei de colocar uma amostra de implementação para o conceito. Você pode ver a resposta atualizada.
Tegar 26/02
@Tegar Ei, obrigado por compartilhar!
Joesmaker 27/02
@ Tegar eu tentei usar o seu código git, mas quando o servidor é acionado após o acerto, uma matriz em branco aparece dizendo isso:{ details: not found }
Aayush Gupta
-1

Você precisa obter o streaming de vídeo ao vivo usando javascript e alimente esse fluxo ao opencv2 para que ele funcione.

Use: obtenha transmissão de vídeo ao vivo no nodejs

Você receberá um URL como o "http://localhost:3000"qual você pode usar no código python da seguinte maneira:

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
fonte
oi, a solução que você forneceu transmite o vídeo de um arquivo e não da minha webcam ao vivo.
Aayush Gupta
teria sido ótimo se você pudesse me dar uma resposta relevante ao meu código. na verdade, a solução acima não está funcionando para mim
Aayush Gupta 24/02