我目前正在尝试将OpenCV与Python一起使用,以将视频从URL加载到本地主机网页上。加载的视频有点断断续续,但是主要问题是一段时间后它停止读取视频帧并显示以下错误消息。
[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'
代码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.pyimport 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()
问题最佳答案
由于video.read()
失败,导致Python崩溃。因此,image
不能传递给cv2.imencode()
。您应该检查success
中的get_frame(self)
值,并准备好使camera.get_frame()
有时不会返回有效的Jpeg。
现在,让我们了解为什么video.read()
在这种情况下失败。如果与摄像机的连接不够好并且丢失了一些数据包,则可能会发生这种情况。但是更有可能的是,您的VideoCapture
不够快,无法处理视频流。
如果您减少了视频捕获线程正在做的工作,则可能会得到改善。如another discussion中所建议,将处理卸载到单独的线程。
当前,flask服务器监听摄像头流,将其转换为一系列Jpeg,然后通过HTTP将其发送到客户端。如果您有专用于摄像机流的线程,则可能会发现服务器无法传递每个视频帧,因为编码器和HTTP传输速度太慢。因此,某些帧将被跳过。
这是有关使用flask进行视频流传输的详细文章:https://blog.miguelgrinberg.com/post/flask-video-streaming-revisited。您可以找到其他一些将视频流传输到浏览器的开源项目,而不必使用opencv和python。
关于python - OpenCV无法从视频读取图像帧,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62830178/