简体   繁体   English

OpenCV 无法从视频中读取图像帧

[英]OpenCV unable to read image frames from video

I am currently trying to use OpenCV with Python to load a video from a url onto a localhost webpage.我目前正在尝试使用 OpenCV 和 Python 将视频从 url 加载到本地主机网页上。 The loaded video is a little choppy but the main problem is that it stops reading the video frames after a while and displays the following error message.加载的视频有点断断续续,但主要问题是它会在一段时间后停止读取视频帧并显示以下错误消息。

[h264 @ 0955e140] error while decoding MB 87 29, bytestream -5
[h264 @ 0955e500] left block unavailable for requested intra4x4 mode -1
[h264 @ 0955e500] error while decoding MB 0 44, bytestream 126
Debugging middleware caught exception in streamed response at a point where response headers were already sent.
Traceback (most recent call last):
  File "C:\Users\\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\werkzeug\wsgi.py", line 506, in __next__
    return self._next()
  File "C:\Users\\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\werkzeug\wrappers\base_response.py", line 45, in _iter_encoded
    for item in iterable:
  File "C:\Users\\Downloads\VideoStreamingFlask\main.py", line 12, in gen
    frame = camera.get_frame()
  File "C:\Users\\Downloads\VideoStreamingFlask\camera.py", line 13, in get_frame
    ret, jpeg = cv2.imencode('.jpg', image)
cv2.error: OpenCV(4.3.0) C:\projects\opencv-python\opencv\modules\imgcodecs\src\loadsave.cpp:919: error: (-215:Assertion failed) !image.empty() in function 'cv::imencode'

Code代码

main.py主文件

from flask import Flask, render_template, Response
from camera import VideoCamera

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='0.0.0.0', debug=True)

camera.py相机.py

import cv2

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

    def __del__(self):
        self.video.release()
    
    def get_frame(self):
        success, image = self.video.read()
        ret, jpeg = cv2.imencode('.jpg', image)
        return jpeg.tobytes()

Questions问题

  1. What might be causing the problem here?什么可能导致这里的问题?
  2. How do I make the video less choppy?如何使视频不那么断断续续?

The crash in your python happened because video.read() failed.您的 python 发生崩溃是因为video.read()失败。 Therefore, image can not be passed to cv2.imencode() .因此, image不能传递给cv2.imencode() You should check the success value in get_frame(self) and be prepared that sometimes camera.get_frame() will not return a valid Jpeg.您应该检查get_frame(self)中的success值,并准备好有时camera.get_frame()不会返回有效的 Jpeg。

Now, let's understand why video.read() failed in this case.现在,让我们了解为什么video.read()在这种情况下会失败。 This could happen if the connection to the camera was not good enough and some packets got lost.如果与相机的连接不够好并且某些数据包丢失,则可能会发生这种情况。 But more likely, your VideoCapture was not fast enough to handle the video stream.但更有可能的是,您的VideoCapture速度不够快,无法处理视频 stream。

This could be improved if you reduce the work that the video capture thread is doing.如果您减少视频捕获线程正在做的工作,这可能会得到改善。 As suggested in another discussion , offload processing to a separate thread.正如另一个讨论中所建议的,将处理卸载到单独的线程。

Currently, your flask server listens to camera stream, converts it to a series of Jpegs, and sends them to the client over HTTP.目前,您的 flask 服务器监听摄像头 stream,将其转换为一系列 Jpeg,并通过 HTTP 发送给客户端。 If you have a thread dedicated to camera stream, you may find that your server cannot pass every video frame, because the encoder and HTTP transport are too slow.如果你有一个专门用于相机 stream 的线程,你可能会发现你的服务器无法传递每个视频帧,因为编码器和 HTTP 传输太慢了。 So, some frames will be skipped.因此,将跳过一些帧。

Here is a detailed article about video streaming with flask: https://blog.miguelgrinberg.com/post/flask-video-streaming-revisited .这是一篇关于 flask 的视频流的详细文章: https://blog.miguelgrinberg.com/post/flask-video-streaming-revisited You can find some other open-source projects that stream video to browser, not necessarily with opencv and python.你可以找到一些其他的开源项目,stream 视频到浏览器,不一定是 opencv 和 python。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM