日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python视频延迟严重_利用多进程降低opencv视频延迟处理rtsp视频流

發布時間:2025/3/12 python 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python视频延迟严重_利用多进程降低opencv视频延迟处理rtsp视频流 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Python多進程opencv

前幾天遇到了一個問題,利用opencv程序調取rtsp視頻流,因為處理程序要消耗的CPU時間過于長,VideoCapture的read是按幀讀取,所以經常導致內存溢出,延時還高得出奇。

所以想到是不是可以利用多進程把讀取視頻和處理視頻分開,這樣就可以消除因處理圖片所導致的延遲。

所用庫

multiprocessing

gc

opencv-python

os

實現方法

一開始是想用多線程,但是因為GIL的存在,像實時處理視頻這樣的CPU密集型任務多線程等于沒用。然后就選擇了多進程。

然后要考慮怎樣在兩個進程中傳參的問題:

multiprocessing中有Quaue、SimpleQuaue等進程間傳參類,還有Manager這個大管家。

Quaue這一類都是嚴格的數據結構隊列類型

Manager比較特殊,它提供了可以在進程間傳遞的列表、字典等python原生類型

還要考慮怎樣才能達到處理進程可以在讀取進程中得到最新的一幀:

其實VideoCapture是一個天生的隊列,先進先出。如果要達到實時獲得最新幀的目的,就需要棧來存儲視頻幀,而不是隊列。

這樣的話,Quaue這一大類就都沒有可能了,肯定不能用它來傳參。

提到棧突然想到了python的列表,它的append和pop操作完全可以當”不嚴格“的棧來用。所以順理成章地multiprocessing.Manager.list就是最好的進程間傳參類型。

再就是傳參棧自動清理的問題,壓棧頻率肯定是要比出棧頻率高的,時間一長就會在棧中積累大量無法出棧的視頻幀,會導致程序崩潰,這就需要有一個自動清理機制:

設置一個傳參棧容量,每當達到這個容量就直接把棧清空,再利用gc庫手動發起一次python垃圾回收。這樣就不會導致嚴重的內存溢出和程序崩潰。

實現代碼

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:xxx@192.168.1.102:554", 100))

pr = Process(target=read, args=(q,))

# 啟動子進程pw,寫入:

pw.start()

# 啟動子進程pr,讀取:

pr.start()

# 等待pr結束:

pr.join()

# pw進程里是死循環,無法等待其結束,只能強行終止:

pw.terminate()

實際上這個程序就是把VideoCapture的隊列讀取改成了棧讀取。這個程序可以寫成一個類,來作為一個新形式的VideoCapture。

TODO

并沒有加入進程鎖,只是有一些防止棧空出棧的判斷,這樣并不能達到進程安全。最好還是加鎖

總結

以上是生活随笔為你收集整理的python视频延迟严重_利用多进程降低opencv视频延迟处理rtsp视频流的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。