当前位置: 首页 > 面试题库 >

如何从IP摄像机解析mjpeg http流?

张兴旺
2023-03-14
问题内容

下面给出的是用于从IP摄像机获取实时流的代码。

from cv2 import *
from cv2 import cv
import urllib
import numpy as np
k=0
capture=cv.CaptureFromFile("http://IPADDRESS of the camera/axis-cgi/mjpg/video.cgi")
namedWindow("Display",1)

while True:
    frame=cv.QueryFrame(capture)
    if frame is None:
        print 'Cam not found'
        break
    else:
        cv.ShowImage("Display", frame)
    if k==0x1b:
        print 'Esc. Exiting'
        break

在运行代码时,我得到的输出是:

Cam not found

我要去哪里错了?另外,为什么这里没有框架?转换有问题吗?


问题答案:
import cv2
import urllib 
import numpy as np

stream = urllib.urlopen('http://localhost:8080/frame.mjpg')
bytes = ''
while True:
    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:]
        i = cv2.imdecode(np.fromstring(jpg, dtype=np.uint8), cv2.CV_LOAD_IMAGE_COLOR)
        cv2.imshow('i', i)
        if cv2.waitKey(1) == 27:
            exit(0)

编辑(说明)

我刚刚看到您提到您的c
代码正在运行,如果是这样的话,您的相机也可以在python中运行。上面的代码无需依赖opencv即可手动解析mjpeg流,因为在我的某些项目中,无论我做什么(c

,python),URL都不会被opencv打开。

通过http的Mjpeg是具有边界帧信息的multipart / x-mixed-
replace,而jpeg数据只是以二进制形式发送。因此,您实际上不需要关心HTTP协议标头。所有jpeg帧均以marker开头,以0xff 0xd8结尾0xff 0xd9。因此,以上代码从http流中提取了此类帧,并对其进行了逐一解码。像下面一样。

...(http)
0xff 0xd8      --|
[jpeg data]      |--this part is extracted and decoded
0xff 0xd9      --|
...(http)
0xff 0xd8      --|
[jpeg data]      |--this part is extracted and decoded
0xff 0xd9      --|
...(http)

编辑2(从mjpg文件读取)

关于保存文件的问题,可以,只需很小的修改就可以使用相同的方法直接保存并重新打开文件。例如,您会做的curl http://IPCAM > output.mjpg
,然后更改行,stream=urllib.urlopen('http://localhost:8080/frame.mjpg')以便代码变为

import cv2
import urllib 
import numpy as np

stream = open('output.mjpg', 'rb')
bytes = ''
while True:
    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:]
        i = cv2.imdecode(np.fromstring(jpg, dtype=np.uint8), cv2.CV_LOAD_IMAGE_COLOR)
        cv2.imshow('i', i)
        if cv2.waitKey(1) == 27:
            exit(0)

当然,您会节省很多多余的http标头,您可能希望将其删除。或者,如果您具有额外的cpu功能,则可以先编码为h264。但是,如果摄像机将一些元数据添加到http标头帧,例如通道,时间戳等,则保留它们可能会很有用。

编辑3(tkinter接口)

import cv2
import urllib 
import numpy as np
import Tkinter
from PIL import Image, ImageTk
import threading

root = Tkinter.Tk()
image_label = Tkinter.Label(root)  
image_label.pack()

def cvloop():    
    stream=open('output.mjpg', 'rb')
    bytes = ''
    while True:
        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:]
            i = cv2.imdecode(np.fromstring(jpg, dtype=np.uint8), cv2.CV_LOAD_IMAGE_COLOR)            
            tki = ImageTk.PhotoImage(Image.fromarray(cv2.cvtColor(i, cv2.COLOR_BGR2RGB)))
            image_label.configure(image=tki)                
            image_label._backbuffer_ = tki  #avoid flicker caused by premature gc
            cv2.imshow('i', i)
        if cv2.waitKey(1) == 27:
            exit(0)

thread = threading.Thread(target=cvloop)
thread.start()
root.mainloop()


 类似资料:
  • 我有这个IP摄像机Nexus CCTV 235FW。我再也连接不上它了。我能重置它吗?我想这是在我修改了管理员密码之后发生的。它是连接的以为WiFi,但我也试过用电缆,没有任何运气。 我也试着用搜索工具搜索相机,但还是没有运气。 另一件事,我甚至看不到摄像头在路由器的列表上连接的单位。 希望任何人能帮助我。

  • 我正在使用Ubuntu 16.04,ZoneMinder V1.29.1与这个docker和这个相机(海康威视红外全景鱼眼)。我可以连接到相机,我得到了设置等的相机界面。问题是实时视图需要一个依赖于windows的插件,这就是为什么我想使用ZoneMinder。 现在我根据本指南配置了所有内容。基本上,我必须添加一个监视器,将源设置为remote,将协议设置为rtsp,将方法设置为RTP/rtsp

  • 我正在尝试使用GStreamer将RTMP/RTSP流连接到v4l2loopback虚拟设备。 工程1-RTMP至AutoVideoSink,sudo gst-launch-1.0 rtspsrc位置=rtsp://192.168.xxx.xxx/live/av0 ! decodebin!自动视频接收器sudo gst-launch-1.0 rtmpsrc位置=rtmp://192.168.xxx

  • 我想在WebRTC上使用IP摄像机。然而,webrtc似乎只支持网络摄像头。所以我尝试将IP摄像机的流转换为虚拟网络摄像机。 我找到了像IP摄像机适配器这样的软件,但它们不太好用(每秒2-3帧,延迟2秒),它们只在Windows上工作,我更喜欢使用Linux(如果可能的话)。 我尝试FFMPEG/AVCONV: > 首先,我使用v4l2loopback创建了一个虚拟设备(命令为:)。虚拟设备会被检

  • 我正在尝试获取我网络上的摄像头产生的流。主要问题是这台相机产生的流是H264流。我四处寻找管理这种流的最佳方法,我发现mediacodec是最合适的类。不幸的是,这个API的文档很差,但尽管如此,我还是找到了一些资源,从中获得了这个类的基本信息,并编写了以下代码。 公共类DecodeActivity扩展Activity实现SurfaceHolder.Callback{ (20736):无法实例化类

  • 问题内容: 如何访问我的IP摄像机流? 用于显示标准网络摄像头流的代码是 除了IP摄像机,我该如何做同样的事情? 我的系统: Python 2.7.14 OpenCV 2.4.9 Teledyne Dalsa Genie Nano XL相机 帮助将不胜感激 您可以将视频捕获对象用作 问题答案: 我回答了我自己的问题,报告了什么似乎是Python OpenCV中访问IP摄像机的 最全面的 总体过程。