实时读取视频流(封面使用五个摄像头是因为我手头最多只有五个),解决实时读取延迟卡顿问题
做计算机视觉的算法开发,可能会碰到实时获取图像并处理的问题,我写了一个简单的实例,可以实时读取多个网络摄像头。运行视频预览如下↓ (可以看到视频播放流畅,达到30fps,同时延迟小于0.3s)
实时读取多个网络摄像头
2018-06-17 初版 Yonv1943 2018-06-25 小修改,deamon,setattr(), if is_opened
2018-07-02 添加单摄像头run(): # single camera,和多摄像头run_multi_camera()
2018-11-21 单线程读取单个摄像头,多进程读取多个摄像头
2019-02-14 将“多线程”改正为“多进程”谢谢 的纠正
2019-05-04 增加大华摄像头rtsp协议 我在标题里不小心用爱发电了,为了公平起见,我把海康竞争对手大华也加上去。网络摄像头基本都支持rtsp协议,所以可以用本方法读取。
2019-07-04 增加将多个摄像头的画面有序地读取到同一个程序 run_multi_camera_in_a_window()
2019-09-06 回复评论:目标检测
2019-10-17 回复评论:图片刚放进去队列就取出来,队列里面岂不是没有图片?
2019-10-31 回复评论:网络卡顿而无法获取视频信息,这个应该怎么处理?
2019-11-13 回复评论:为何有 ipv4 与ipv6两种地址?
完整版Demo:
实现上述功能的完整示例Demo (已经尽可能短),你也可以在我的GitHub上下载到最新的代码,如果星星多,那么我还会继续加功能:
import cv2
import time
import multiprocessing as mp
"""
Source: Yonv1943 2018-06-17
https://github.com/Yonv1943/Python/tree/master/Demo
"""
def image_put(q, name, pwd, ip, channel=1):
cap = cv2.VideoCapture("rtsp://%s:%s@%s//Streaming/Channels/%d" % (name, pwd, ip, channel))
if cap.isOpened():
print('HIKVISION')
else:
cap = cv2.VideoCapture("rtsp://%s:%s@%s/cam/realmonitor?channel=%d&subtype=0" % (name, pwd, ip, channel))
print('DaHua')
while True:
q.put(cap.read()[1])
q.get() if q.qsize() > 1 else time.sleep(0.01)
def image_get(q, window_name):
cv2.namedWindow(window_name, flags=cv2.WINDOW_FREERATIO)
while True:
frame = q.get()
cv2.imshow(window_name, frame)
cv2.waitKey(1)
def run_multi_camera():
# user_name, user_pwd = "admin", "password"
user_name, user_pwd = "admin", "admin123456"
camera_ip_l = [
"172.20.114.26", # ipv4
"[fe80::3aaf:29ff:fed3:d260]", # ipv6
# 把你的摄像头的地址放到这里,如果是ipv6,那么需要加一个中括号。
]
mp.set_start_method(method='spawn') # init
queues = [mp.Queue(maxsize=4) for _ in camera_ip_l]
processes = []
for queue, camera_ip in zip(queues, camera_ip_l):
processes.append(mp.Process(target=image_put, args=(queue, user_name,