首页 文章

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

提问于
浏览
6

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

mms://194.90.203.111/cam2

在VLC和Windows Media Player上播放 .

mmst://194.90.203.111/cam2

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

据我所知,mms正在使用Windows Media Video对流进行编码 . 没有运气在URI的末尾添加'.mjpeg' . 我还没有找到OpenCV接受哪种类型的流媒体 .

这是我的代码 -

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

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

谢谢!

Python ver 2.7.8,OpenCV的ver 2.4.9,两者都是x86 . Win7 x64

1 回答

  • 7

    使用FFmpeg和FFserver解决 . 注意FFserver仅适用于Linux . 该解决方案使用here中的python代码,如Ryan所示 .

    流量如下 -

    • 使用所需配置启动FFserver后台进程(本例中为mjpeg) .

    • FFmpeg输入是mmst流,输出到localhost的流 .

    • 运行python脚本以打开localhost流并逐帧解码 .

    运行FFserver

    ffserver -d -f /etc/ffserver.conf
    

    在第二个终端上运行FFmpeg

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

    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 -

    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>
    

    请注意,这个ffserver.config需要更多的微调,但它们工作得相当好,并且产生一个非常靠近源的帧,只有一点帧冻结 .

相关问题