主要内容
- Gstreamer
- RTSP视频流
- 多进程处理
- opencv-python
官方Demo
参考Demo
知乎-读取多个(海康\大华)网络摄像头的视频流 (使用opencv-python),解决实时读取延迟问题
github-Demo_camera_and_network
完整Demo
import cv2
import numpy as np
import time
import multiprocessing as mp
def image_put(q, user, pwd, ip):
image_width = 1920
image_height = 1080
rtsp_latency = 200
uri = "rtsp://%s:%s@%s" % (user, pwd, ip)
gst_str = ("rtspsrc location={} latency={} ! rtph264depay ! h264parse ! omxh264dec ! nvvidconv ! video/x-raw, width=(int){}, height=(int){}, format=(string)BGRx ! videoconvert ! appsink sync=false").format(uri, rtsp_latency, image_width, image_height)
cap = cv2.VideoCapture(gst_str)
if cap.isOpened():
print('HIKVISION')
while True:
q.put(cap.read()[1])
q.get() if q.qsize() > 1 else time.sleep(0.01)
def image_collect(queue_list, camera_ip_l):
# """show in single opencv-imshow window"""
# window_name = "%s_and_so_no" % camera_ip_l[0]
# cv2.namedWindow(window_name, flags=cv2.WINDOW_FREERATIO)
# while True:
# imgs = [q.get() for q in queue_list]
# imgs = np.concatenate(imgs, axis=1)
# cv2.imshow(window_name, imgs)
# cv2.waitKey(1)
"""show in multiple opencv-imshow windows"""
[cv2.namedWindow(window_name, flags=cv2.WINDOW_FREERATIO)
for window_name in camera_ip_l]
while True:
for window_name, q in zip(camera_ip_l, queue_list):
cv2.imshow(window_name, q.get())
cv2.waitKey(1)
def run_multi_camera_in_a_window():
user_name, user_pwd = "admin", "a123456"
camera_ip_l = [
"192.168.1.66", # ipv4
"192.168.1.46", # ipv4
# 多个摄像头的IP
]
mp.set_start_method(method='spawn')
# init #"spawn"、"fork"、"forkserver" 作为参数,用来指定进程启动的方式。
# "spawn"父进程启动一个新的Python解释器进程。子进程只会继承那些运行进程对象的 run() 方法所需的资源。特别是父进程中非必须的文件描述符和句柄不会被继承。可在Unix和Windows上使用。
#"fork"父进程使用 os.fork() 来产生 Python 解释器分叉。子进程在开始时实际上与父进程相同。父进程的所有资源都由子进程继承。只存在于Unix。
#"forkserver" 程序启动并选择* forkserver * 启动方法时,将启动服务器进程。从那时起,每当需要一个新进程时,父进程就会连接到服务器并请求它分叉一个新进程。
queues = [mp.Queue(maxsize=4) for _ in camera_ip_l]
processes = [mp.Process(target=image_collect, args=(queues, camera_ip_l))]
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)))
for process in processes:
process.daemon = True # setattr(process, 'deamon', True)
process.start()
for process in processes:
process.join()
if __name__ == '__main__':
run_multi_camera_in_a_window()