web-dev-qa-db-fra.com

Diffusez le cadre OpenCV en HTML en Python

J'essaie de lire une vidéo à partir d'une URL en opencv (Python), puis de la traiter image par image, puis de l'envoyer à une page HTML.

Mais je ne reçois que la première image, après quoi le programme donne l'erreur suivante enter image description here

Ceci est mon fichier principal (main.py)

from flask import Flask, render_template, Response
from camera import VideoCamera
import pdb
app = Flask(__name__)

@app.route('/')
def index():
    return render_template('index.html')

def gen(camera):
    while True:
        frame = camera.get_frame()
        yield (b'--frame\r\n'
                b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n')

@app.route('/video_feed')
def video_feed():
    return Response(gen(VideoCamera()),
                    mimetype='multipart/x-mixed-replace; boundary=frame')

if __name__ == '__main__':
    app.run(Host='127.0.0.1', debug=True)

Et c'est le camera.py fichier:

    import cv2
    import urllib
    import pdb
    import numpy as np

    face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
    #https://github.com/Itseez/opencv/blob/master/data/haarcascades/haarcascade_eye.xml
    eye_cascade = cv2.CascadeClassifier('haarcascade_eye.xml')

    class VideoCamera(object):
        def __init__(self):
            # Using OpenCV to capture from device 0. If you have trouble capturing
            # from a webcam, comment the line below out and use a video file
            # instead.
            self.video = urllib.urlopen('http://192.168.10.12:8080/video')   #cv2.VideoCapture(0)
            # If you decide to use video.mp4, you must have this file in the folder
            # as the main.py.
            # self.video = cv2.VideoCapture('video.mp4')

        def __del__(self):
            self.video.release()

        def get_frame(self):

            bytes=''
            while True:
                # pdb.set_trace()
                bytes+=self.video.read(1024)
                a = bytes.find('\xff\xd8')
                b = bytes.find('\xff\xd9')
                if a!=-1 and b!=-1:
                    jpg = bytes[a:b+2]
                    bytes= bytes[b+2:]

                    img = cv2.imdecode(np.fromstring(jpg, dtype=np.uint8),cv2.IMREAD_COLOR) 
                    # pdb.set_trace()
                    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
                    faces = face_cascade.detectMultiScale(gray, 1.3, 5)
                    for (x,y,w,h) in faces:
                        cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
                        roi_gray = gray[y:y+h, x:x+w]
                        roi_color = img[y:y+h, x:x+w]

                    ret, jpeg = cv2.imencode('.jpg', img)
                    return jpeg.tobytes()

Je ne reçois que la première image (illustrée ci-dessous): enter image description here

12
Obiii

Je suis sûr que vous avez résolu votre erreur maintenant, mais c'est pour les autres personnes qui visitent cette question:

écrire c'est votre fichier camera.py

ne vous trompez pas avec la méthode draw_box, c'est juste un carré personnalisé que j'utilise. Vous pouvez utiliser le cv2.rectangle normal pour créer des rectangles sur les faces.

import cv2


WHITE = [255, 255, 255]
face_cascade = cv2.CascadeClassifier('Haar/haarcascade_frontalcatface.xml')
eye_cascade = cv2.CascadeClassifier('Haar/haarcascade_eye.xml')


def draw_box(Image, x, y, w, h):
    cv2.line(Image, (x, y), (x + int(w / 5), y), WHITE, 2)
    cv2.line(Image, (x + int((w / 5) * 4), y), (x + w, y), WHITE, 2)
    cv2.line(Image, (x, y), (x, y + int(h / 5)), WHITE, 2)
    cv2.line(Image, (x + w, y), (x + w, y + int(h / 5)), WHITE, 2)
    cv2.line(Image, (x, (y + int(h / 5 * 4))), (x, y + h), WHITE, 2)
    cv2.line(Image, (x, (y + h)), (x + int(w / 5), y + h), WHITE, 2)
    cv2.line(Image, (x + int((w / 5) * 4), y + h), (x + w, y + h), WHITE, 2)
    cv2.line(Image, (x + w, (y + int(h / 5 * 4))), (x + w, y + h), WHITE, 2)


class VideoCamera(object):
    def __init__(self):
        self.video = cv2.VideoCapture(0)

    def __del__(self):
        self.video.release()

    def get_frame(self):
        success, image = self.video.read()
        # We are using Motion JPEG, but OpenCV defaults to capture raw images,
        # so we must encode it into JPEG in order to correctly display the
        # video stream.

        gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        faces = face_cascade.detectMultiScale(gray, 1.3, 5)
        for (x, y, w, h) in faces:
           gray_face = cv2.resize((gray[y:y + h, x:x + w]), (110, 110))
            eyes = eye_cascade.detectMultiScale(gray_face)
            for (ex, ey, ew, eh) in eyes:

                draw_box(gray, x, y, w, h)

        ret, jpeg = cv2.imencode('.jpg', gray)

        return jpeg.tobytes()
6
Kushal Parikh