pytorch多进程multiprocessing处理视频流

场景: 采用深度学习的方案处理视频流的任务,比如:视频跟踪,视频中的行人检测,车辆检测等其他任务,一般会采用opencv读取视频流,然后再一帧一帧的处理。
问题: 但是在这个过程中由于算力的限制,计算的速度会小于视频帧读取的速度,就是会出现计算结果延时的情况,但是采用cv2.VideoCapture()读取的时候,它会逐帧读取,就是它不是每次读取最新的帧,所以时间久了,这个队列就会溢出,程序就会自动停止。

解决思路

  1. 主要的思路就是用python的multiprocessing多进程或pytorch的multiprocessing,在我的例子中二者是通用的。
  2. 同时在__main__中要加上mp.set_start_method(‘spawn’)
  3. 注意pytorch模型的初始化,要保证每个进程都分别初始化了自己的模型,就是你有多少个进程,那么就要启动几个模型

其中的第3点是非常关键的,平时的python多进程只需要注意第一点就好了。

Code

class mulProcessone_camera(object):
    """
    data:2019-06-11
    use:采用多线程的方式来读取摄像头的视频,模拟达到实时的效果
    """
    def __init__(self, vediopath):
        self.vedio_path = vediopath
        

    def image_put(self, q):
        cap = cv2.VideoCapture('rtsp://admin:[email protected]:1554/h264/ch1/main/av_stream')
        if cap.isOpened():
            print('HIKVISION')
        else:
            cap = cv2.VideoCapture('rtsp://admin:[email protected]:1554/h264/ch1/main/av_stream')
            print('DaHua')

        while True:
            if q.qsize() > 2:               # 第3张图片的时候,队列就吐出一张只有两张了
                q.get() 
            else:
                pass

            print(q.qsize())
            q.put(cap.read()[1])            # 3张图片,到达队列的maxsize


    def image_get(self, q):
        # cv2.namedWindow('window', flags=cv2.WINDOW_FREERATIO)
        self.processfunc = Detector()           # 分别初始化
        while True:
            try:
                frame = q.get()                     # 获得图像
                # frame = cv2.resize(frame, (640,360))
                self.processfunc.detect(frame)  # 让他一直启动
            except:
                print('wrong with deepsort qsize:%d'%q.qsize())


    def run_single_camera(self):          # 启动服务
        queue = mp.Queue(maxsize=3)
        self.processes = [mp.Process(target=self.image_put, args=(queue,)),
                    mp.Process(target=self.image_get, args=(queue,))]

        [process.start() for process in self.processes]
        [process.join() for process in self.processes]


    def endprocess(self):
        [process.terminate() for process in self.processes]
        [process.join() for process in self.processes]


def main(vedio_path):
    mulp = mulProcessone_camera(vedio_path)
    mulp.run_single_camera()                    # 启动服务
    mulp.endprocess()                           # 结束进程
            


if __name__=="__main__":
    mp.set_start_method('spawn')
    vedio_path = 'rtsp://admin:[email protected]:1554/h264/ch1/main/av_stream'
    main(vedio_path)

解释:

  1. self.processfunc = Detector() ,这个就是pytorch推理模型类的初始化,这句可以放两个位置,分别是 image_put(从视频流中获得一张图像压入队列)和image_get(从队列中获得一张图片,并用pytorch模型进行处理),self.processfunc 可以放在以上两个函数的while True的前面,这样process.start()启动进行时,就是启动[mp.Process(target=self.image_put, args=(queue,)), mp.Process(target=self.image_get, args=(queue,))]其中的目标函数。
  2. image_put和image_get中分别有个while True,所以process.start()启动的时候,就是执行的其中的内容。

reference

  1. 读取多个(海康\大华)网络摄像头的视频流 (使用opencv-python),解决实时读取延迟问题

你可能感兴趣的:(pytorch)