前几天遇到了一个问题,利用opencv程序调取rtsp视频流,因为处理程序要消耗的CPU时间过于长,VideoCapture的read是按帧读取,所以经常导致内存溢出,延时还高得出奇。
所以想到是不是可以利用多进程把读取视频和处理视频分开,这样就可以消除因处理图片所导致的延迟。
multiprocessing
gc
opencv-python
os
import os
import cv2
import gc
from multiprocessing import Process, Manager
# 向共享缓冲栈中写入数据:
def write(stack, cam, top: int) -> None:
"""
:param cam: 摄像头参数
:param stack: Manager.list对象
:param top: 缓冲栈容量
:return: None
"""
print('Process to write: %s' % os.getpid())
cap = cv2.VideoCapture(cam)
while True:
_, img = cap.read()
if _:
stack.append(img)
# 每到一定容量清空一次缓冲栈
# 利用gc库,手动清理内存垃圾,防止内存溢出
if len(stack) >= top:
del stack[:]
gc.collect()
# 在缓冲栈中读取数据:
def read(stack) -> None:
print('Process to read: %s' % os.getpid())
while True:
if len(stack) != 0:
value = stack.pop()
cv2.imshow("img", value)
key = cv2.waitKey(1) & 0xFF
if key == ord('q'):
break
if __name__ == '__main__':
# 父进程创建缓冲栈,并传给各个子进程:
q = Manager().list()
pw = Process(target=write, args=(q, "rtsp://xxx:[email protected]:554", 100))
pr = Process(target=read, args=(q,))
# 启动子进程pw,写入:
pw.start()
# 启动子进程pr,读取:
pr.start()
# 等待pr结束:
pr.join()
# pw进程里是死循环,无法等待其结束,只能强行终止:
pw.terminate()
实际上这个程序就是把VideoCapture的队列读取改成了栈读取。这个程序可以写成一个类,来作为一个新形式的VideoCapture。
并没有加入进程锁,只是有一些防止栈空出栈的判断,这样并不能达到进程安全。最好还是加锁