多进程解决多路视频流卡帧、掉帧、延时等问题
利用python代码实现不同厂家摄像头同时实时录制并存储
本代码参考: link,文章作者实现读取多个(海康\大华)网络摄像头的视频流 (使用opencv-python),解决实时读取延迟问题。
本人因项目需求两个摄像机(枪机+球机)同时录制交通监控视频。传统代码可实现单个摄像头实时录制,遇到多视频流会存在通道堵塞,高延时、掉帧、卡帧等诸多问题,在使用link代码时,出现视频流中断的问题。故本文在作者多进程实现多摄像头实时监控的基础上改进视频存放、抓取的代码,实现了多个摄像头实时监测并存储的任务。
本文完整代码如下
import cv2
import time
import multiprocessing as mp
def image_put(q, name, pwd, ip, channel=101):
cap = cv2.VideoCapture("rtsp://%s:%s@%s//Streaming/Channels/%d" \
% (name, pwd, ip, channel))
fps = cap.get(cv2.CAP_PROP_FPS)
print('fps: ', fps)
if cap.isOpened():
print('HIKVISION1')
else:
cap = cv2.VideoCapture("rtsp://%s:%s@%s//Streaming/Channels/%d" \
% (name, pwd, ip, channel))
fps = cap.get(cv2.CAP_PROP_FPS)
print('fps: ', fps)
print('HIKVISION2')
while cap.isOpened():
# print('cap.read()[0]:', cap.read()[0])
ret, frame = cap.read()
# print('ret:', ret)
frame = cv2.resize(frame, (1920, 1080))
if not ret:
cap = cv2.VideoCapture("rtsp://%s:%s@%s//Streaming/Channels/%d" \
% (name, pwd, ip, channel))
print('HIKVISION2')
ret, frame = cap.read()
frame = cv2.resize(frame, (1920,1080))
q.put(frame)
# print('q.qsize():', q.qsize())
q.get() if q.qsize() > 1 else time.sleep(0.01)
def image_get(q, window_name):
cv2.namedWindow(window_name, cv2.WINDOW_NORMAL)
fourcc = cv2.VideoWriter_fourcc(*'XVID')
path = "D:/test/" + window_name + ".avi"
out = cv2.VideoWriter(path, fourcc, 20.0, (1920, 1080), True)
while True:
frame = q.get()
out.write(frame)
cv2.imshow(window_name, frame)
cv2.waitKey(1)
def run_multi_camera():
# user_name, user_pwd = "admin", "password"
user_name, user_pwd = "admin", "用户密码"
camera_ip_l = [
"192.168.1.67", # ipv4(改成自己的)
"192.168.1.64", # ipv4(改成自己的)
# 把你的摄像头的地址放到这里,如果是ipv6,那么需要加一个中括号。
]
mp.set_start_method(method='spawn') # init
queues = [mp.Queue(maxsize=2) 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, user_pwd, camera_ip)))
processes.append(mp.Process(target=image_get, args=(queue, camera_ip)))
for process in processes:
process.daemon = True
process.start()
for process in processes:
process.join()
if __name__ == '__main__':
run_multi_camera()
分模块解读
多进程run_multi_camera()
多进程函数下,将所要使用的设备信息输入对应位置(摄像头可以多个),用户名、密码、设备ip地址自行设置。本人手头两个摄像头,队列参数maxsize=2。
python多进程讲解link
图像放入image_put
不同厂家的摄像头rtsp协议:
video_stream_path = “rtsp://%s:%s@%s/h264/ch%s/main/av_stream” %(user, pwd, ip, channel) # HIKIVISION old version 2015
video_stream_path = “rtsp://%s:%s@%s//Streaming/Channels/%d” % (user, pwd, ip, channel) # HIKIVISION new version 2017
video_stream_path = “rtsp://%s:%s@%s/cam/realmonitor?channel=%d&subtype=0” % (user, pwd, ip, channel) # dahua
本人使用的是海康威视的摄像头
图像提取image_get
设置视频编码格式,设置存储路径(这里我是以摄像头ip地址命名文件)