Python (Flask) 页面刷新导致 OpenCv 相机对象出现问题

Python (Flask) refresh on page gives problem with OpenCv camera object

我有 python 个带有 Flask 框架的应用程序。我在我的索引页面上显示来自摄像头的视频流:

  <img id="bg2" src="{{ url_for('video') }}" width="400px" height="400px">

一切正常,但如果我直接刷新页面,奇怪的事情就会开始发生。如果我转到另一个页面并返回索引,一切也都有效。 这些是我得到的错误(每次都是其中之一):

error for object 0x7fc579e00240: pointer being freed was not allocated

Assertion fctx->async_lock failed at libavcodec/pthread_frame.c:155

segmentation fault 11

这是数据来自的端点:

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

def video_stream():
    global video_camera # Line 1 ----------------------

    if video_camera == None: # Line 2 ----------------------
        video_camera = VideoCamera()

    while True:
        frame = video_camera.get_frame()

        if frame != None:
            yield (b'--frame\r\n'
                   b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n')

如果我删除注释行,一切正常,但由于新对象的不断初始化,它又慢又重。

这是我的相机对象,如果有帮助的话

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

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

    def get_frame(self):
        ret, frame = self.cap.read()
        print(ret)
        if ret:
            ret, jpeg = cv2.imencode('.jpg', frame)
            return jpeg.tobytes()

好的,一种解决方案是不使用全局对象。 这是新的 video_stream() 函数:

def video_stream():
    video_camera = VideoCamera();
    ...

另一种可能的解决方案是像这样使用线程锁:

def video_stream():
    global video_camera
    if video_camera == None:
        video_camera = VideoCamera()

    while True:
        with lock:
            frame = video_camera.get_frame()

            if frame != None:
                global_frame = frame
                yield (b'--frame\r\n'
                       b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n')