Pra*_*ava 26 python opencv mjpeg ip-camera live-streaming
下面给出了为从IP Camera获取实时流而编写的代码.
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
Run Code Online (Sandbox Code Playgroud)
在运行代码时,我得到的输出是:
Cam not found
Run Code Online (Sandbox Code Playgroud)
我哪里错了?另外,为什么帧无?转换有问题吗?
Zaw*_*Lin 77
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)
Run Code Online (Sandbox Code Playgroud)
我刚刚看到你提到你有c ++代码正常工作,如果是这样你的相机也可以在python中工作.上面的代码手动解析mjpeg流而不依赖opencv,因为在我的一些项目中,无论我做什么(c ++,python),opencv都不会打开url.
HTTP上的Mjpeg是多部分/ x混合替换边界帧信息,而jpeg数据只是以二进制形式发送.所以你真的不需要关心http协议头.所有jpeg帧都以标记开头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)
Run Code Online (Sandbox Code Playgroud)
关于保存文件的问题,是的,文件可以直接保存并使用相同的方法重新打开,只需很小的修改.例如,您可以执行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)
Run Code Online (Sandbox Code Playgroud)
当然,您正在保存大量冗余的http标头,您可能希望将其删除.或者如果你有额外的CPU功率,可能只是先编码为h264.但是,如果摄像机正在向http标头帧添加一些元数据,例如频道,时间戳等,那么保留它们可能很有用.
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()
Run Code Online (Sandbox Code Playgroud)
bug*_*123 35
首先,请注意,你应该先尝试简单地使用OpenCV中的视频捕捉功能直接,如cv2.VideoCapture('http://localhost:8080/frame.mjpg')
!
这对我来说很好用:
import cv2
cap = cv2.VideoCapture('http://localhost:8080/frame.mjpg')
while True:
ret, frame = cap.read()
cv2.imshow('Video', frame)
if cv2.waitKey(1) == 27:
exit(0)
Run Code Online (Sandbox Code Playgroud)
不管怎么说,这里ZAW林的解决方案移植到OpenCV的3(唯一的变化是cv2.CV_LOAD_IMAGE_COLOR
,以cv2.IMREAD_COLOR
和Python 3(字符串VS字节处理改变及urllib的):
import cv2
import urllib.request
import numpy as np
stream = urllib.request.urlopen('http://localhost:8080/frame.mjpg')
bytes = bytes()
while True:
bytes += stream.read(1024)
a = bytes.find(b'\xff\xd8')
b = bytes.find(b'\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.IMREAD_COLOR)
cv2.imshow('i', i)
if cv2.waitKey(1) == 27:
exit(0)
Run Code Online (Sandbox Code Playgroud)
Var*_*rji 10
以下是使用Python 3 请求模块而不是urllib的答案.
不使用urllib的原因是它无法正确解释像这样的URL http://user:pass@ipaddress:port
在urllib中添加身份验证参数比请求模块更复杂.
这是一个使用请求模块的简洁解决方案:
import cv2
import requests
import numpy as np
r = requests.get('http://192.168.1.xx/mjpeg.cgi', auth=('user', 'password'), stream=True)
if(r.status_code == 200):
bytes = bytes()
for chunk in r.iter_content(chunk_size=1024):
bytes += chunk
a = bytes.find(b'\xff\xd8')
b = bytes.find(b'\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.IMREAD_COLOR)
cv2.imshow('i', i)
if cv2.waitKey(1) == 27:
exit(0)
else:
print("Received unexpected status code {}".format(r.status_code))
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
74410 次 |
最近记录: |