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

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.


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)

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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.