使用OpenCV Python流式传输多个IP摄像头会导致延迟

2024-09-30 06:31:45 发布

您现在位置:Python中文网/ 问答频道 /正文

我们希望定期从rtmp流中检索帧。为此,我们有两个IP摄像头,并使用两个单独的线程不断刷新帧。主程序创建两个流,然后在每个线程上调用:getFrame(),以从每个摄影机检索最后一帧。系统运行3秒,从每个流中收集3帧(间隔1秒)。最后,程序将图像写入磁盘

我们注意到在检索帧时存在延迟。当我们在时间x请求帧时,检索到的帧是几秒钟前的帧。每个摄像头的延迟不同,并且随着以下代码中添加的摄像头数量的增加而增加

我们已经调查了一些事情: -我们的想法是在初始化期间填充OpenCV的缓冲区。因此,在启动主程序之前,我们尝试通过调用grab()方法50次来从缓冲区中删除图像。 -我们使用Python队列存储帧,然后只获取添加到队列中的最后一帧

相机日期时间与NTP同步,并显示在图像中。将此日期时间与请求帧的日期时间进行比较,会导致不一致的延迟。对于两个摄像头,这在2到10秒之间变化。(有点类似于两个摄像头的OpenCV初始时间)

该代码正在Nvidia JetsonNano上运行

我们使用以下内容在本地存储图像,并给出:写入时间、相机编号和历元/迭代作为文件名:

def write_local(frames, epoch, names):
    for camera_number, image in enumerate(frames):
        name = names[camera_number]
        path = Path(".")
        if type(image) == np.ndarray:
            with io.BytesIO() as in_mem_file:
                path = path / "test_{0}_{1}_{2}.jpg".format(epoch, name, datetime.now().strftime("%d/%m/%Y %H:%M:%S").replace(" ", "_").replace('/', '-'))
                image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
                image = Image.fromarray(image)
                image.save(in_mem_file, format='jpeg')
                image.seek(0)
                path.write_bytes(in_mem_file.getbuffer()) 

我们使用以下对象对多个rtmp链接进行流式传输:

class CameraStream:

    def __init__(self, rtmp_link=None):
        self.currentFrame = None
        self.CAMERA_WIDTH = 2560
        self.CAMERA_HEIGHT = 1920

        self.capture = cv2.VideoCapture(rtmp_link)
        self.capture.set(cv2.CAP_PROP_FRAME_WIDTH, self.CAMERA_WIDTH)
        self.capture.set(cv2.CAP_PROP_FRAME_HEIGHT, self.CAMERA_HEIGHT)
        self.capture.set(cv2.CAP_PROP_BUFFERSIZE, 1)

    def start(self):
        self.start_time = time.time()
        Thread(target=self.updateFrame, args=()).start()

    def updateFrame(self):       
        while(True):
            ret, self.current_frame = self.capture.read()

    def getFrame(self):
        return self.current_frame

初始化相机的:

wig_0 = webcamImageGetter(rtmp_link= 'rtmp://..')
wig_0.start()

wig_1 = webcamImageGetter(rtmp_link= 'rtmp://..')
wig_1.start()

启动会话并每秒从相机收集一帧

s = time.time()
time_sinds_last = 0
current_frames = []
while time.time() - s < 100:
    if time.time() - s > 1:
        # print the datetime when the frame is requested
        print(datetime.now().strftime("%d/%m/%Y %H:%M:%S").replace(" ", "_").replace('/', '-'))
        # Collect frames and store in current_frames
        current_frames += [([wig_0.getFrame(), wig_1.getFrame()], len(current_frames), ['1_1', '1_2'])]
        s = time.time()

     # Stop after 3 epochs/iterations
     if len(current_frames) > 3:
        break
# write current frames to disk
for x in current_frames:
    write_local(frames=x[0], epoch=x[1], names=x[2])

Tags: inimageselfframestimedef时间current

热门问题