如何使用 OpenCV (Python) 捕获视频流

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26691189/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 00:52:36  来源:igfitidea点击:

How to Capture Video Stream with OpenCV (Python)

pythonopencvvideostreaminglive-streaming

提问by NoamR

I want to process mms video stream with OpenCV using Python. The stream comes from an IP camera I have no control over (traffic monitor). The stream is available as mms or mmst schemes -

我想使用 Python 使用 OpenCV 处理 mms 视频流。流来自我无法控制的 IP 摄像机(流量监视器)。该流可用作 mms 或 mmst 方案 -

mms://194.90.203.111/cam2

plays on both VLC and Windows Media Player.

在 VLC 和 Windows Media Player 上播放。

mmst://194.90.203.111/cam2

works only on VLC. I've tried to change the scheme to HTTP by re-streaming with FFmpeg and VLC but it didn't work.

仅适用于 VLC。我试图通过使用 FFmpeg 和 VLC 重新流式传输将方案更改为 HTTP,但它没有用。

As far as I understand, mms is using Windows Media Video to encode the stream. No luck adding '.mjpeg' at the end of the URI. I've yet to find what types of streaming are accepted by OpenCV.

据我了解,mms 使用 Windows Media Video 对流进行编码。在 URI 的末尾添加“.mjpeg”没有运气。我还没有找到 OpenCV 接受哪些类型的流。

Here's my code -

这是我的代码 -

import cv2, platform
#import numpy as np

cam = "mms://194.90.203.111/cam2"
#cam = 0 # Use  local webcam.

cap = cv2.VideoCapture(cam)
if not cap:
    print("!!! Failed VideoCapture: invalid parameter!")

while(True):
    # Capture frame-by-frame
    ret, current_frame = cap.read()
    if type(current_frame) == type(None):
        print("!!! Couldn't read frame!")
        break

    # Display the resulting frame
    cv2.imshow('frame',current_frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# release the capture
cap.release()
cv2.destroyAllWindows()

The What am I missing? What type of video streams can OpenCV capture? Is there an elegant solution without scheme change or transcoding?

我错过了什么?OpenCV 可以捕获什么类型的视频流?有没有不改变方案或转码的优雅解决方案?

Thanks!

谢谢!

Python ver 2.7.8, OpenCV's ver 2.4.9, Both x86. Win7 x64

Python 2.7.8 版,OpenCV 2.4.9 版,x86 版本。Win7 x64

采纳答案by NoamR

Solved using FFmpeg and FFserver. Note FFserver only works on Linux. The solution uses python code from hereas suggested by Ryan.

使用 FFmpeg 和 FFserver 解决。注意 FFserver 仅适用于 Linux。根据Ryan 的建议,该解决方案使用来自此处的python 代码。

Flow is as follows -

流程如下——

  • Start FFserver background process using the desired configuration (mjpeg in this case).
  • FFmpeg input is the mmst stream, output stream to localhost.
  • Run python script to open the localhost stream and decode frame by frame.
  • 使用所需的配置(本例中为 mjpeg)启动 FFserver 后台进程。
  • FFmpeg 输入是 mmst 流,输出流到 localhost。
  • 运行python脚本打开本地主机流并逐帧解码。

Run FFserver

运行FF服务器

ffserver -d -f /etc/ffserver.conf

On a second terminal run FFmpeg

在第二个终端上运行 FFmpeg

ffmpeg -i mmst://194.90.203.111/cam2 http://localhost:8090/cam2.ffm

The Python code. In this case, the code will open a window with the video stream.

Python 代码。在这种情况下,代码将打开一个包含视频流的窗口。

import cv2, platform
import numpy as np
import urllib
import os

cam2 = "http://localhost:8090/cam2.mjpeg"

stream=urllib.urlopen(cam2)
bytes=''
while True:
    # to read mjpeg frame -
    bytes+=stream.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:]
    frame = cv2.imdecode(np.fromstring(jpg, dtype=np.uint8),cv2.CV_LOAD_IMAGE_COLOR)
    # we now have frame stored in frame.

    cv2.imshow('cam2',frame)

    # Press 'q' to quit 
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cv2.destroyAllWindows()

ffserver.config -

ffserver.config -

Port 8090
BindAddress 0.0.0.0
MaxClients 10
MaxBandWidth 50000
CustomLog -
#NoDaemon

<Feed cam2.ffm>
    File /tmp/cam2.ffm
    FileMaxSize 1G
    ACL allow 127.0.0.1
    ACL allow localhost
</Feed>
<Stream cam2.mjpeg>
    Feed cam2.ffm
    Format mpjpeg
    VideoFrameRate 25
    VideoBitRate 10240
    VideoBufferSize 20480
    VideoSize 320x240
    VideoQMin 3
    VideoQMax 31
    NoAudio
    Strict -1
</Stream>
<Stream stat.html>
    Format status
    # Only allow local people to get the status
    ACL allow localhost
    ACL allow 192.168.0.0 192.168.255.255
</Stream>
<Redirect index.html>
    URL http://www.ffmpeg.org/
</Redirect>

Note that this ffserver.config needs more fine tuning, but they work rather well and produce a frame very close to source with only a little frame freeze.

请注意,此 ffserver.config 需要更多微调,但它们工作得很好,并且生成的帧非常接近源,只有一点帧冻结。