2017-07-04 90 views
2

我正嘗試從opencv(Python)中的URL中讀取視頻,然後逐幀處理它,然後將其發送到HTML頁面。在Python中將OpenCV幀流式傳輸到HTML

但我只得到了第一幀,之後,該方案提供了以下錯誤enter image description here

這是我的主文件(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) 

這是camera.py文件:

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() 

我只得到第一幀(如下所示): enter image description here

+0

請參閱本https://stackoverflow.com/questions/44611874/stream-realtime-video-between-2-computers-using-python –

+0

請你的錯誤粘貼到一個代碼塊中的你的問題截圖控制檯不應該使用 – SiHa

+1

嗨,先生!你解決了這個問題嗎?如果是,那麼如何?我也有同樣的問題。謝謝! –

回答

-1

使用小尺寸讀取.read()函數中的字節。

0

我相信你現在已經解決了你的錯誤,但是這是誰訪問了這個問題其他人:

寫,這是你的camera.py文件

不要被迷惑draw_box方法,它只是我正在使用的自定義廣場。您可以使用普通的cv2.rectangle在面上製作矩形。

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()