最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python開發(fā)中OpenCV視頻流的多線程處理方式詳解

 更新時(shí)間:2025年05月14日 09:36:40   作者:知來者逆  
在做視覺類項(xiàng)目中,常常需要在Python環(huán)境下使用OpenCV讀取本地的還是網(wǎng)絡(luò)攝像頭的視頻流,之后再調(diào)入各種模型,所以本文我們就來聊聊OpenCV視頻流的多線程處理方式吧

前言

在做視覺類項(xiàng)目中,常常需要在Python環(huán)境下使用OpenCV讀取本地的還是網(wǎng)絡(luò)攝像頭的視頻流,之后再調(diào)入各種模型,如目標(biāo)分類、目標(biāo)檢測(cè),人臉識(shí)別等等。如果使用單線程處理,很多時(shí)候會(huì)出現(xiàn)比較嚴(yán)重的時(shí)延,如果算力吃緊,模型推理所占用的更長(zhǎng)的話,這種延遲感會(huì)更加明顯,會(huì)出現(xiàn)卡幀的現(xiàn)象。在這種情況下,往往要把代碼從單線程改為了多線程,即單獨(dú)用一個(gè)線程實(shí)時(shí)捕獲視頻幀,主線程在需要時(shí)從子線程拷貝最近的幀使用即可。

單線程處理視頻流時(shí),如果目標(biāo)檢測(cè)模型較大或者任務(wù)復(fù)雜,會(huì)影響處理速度。而使用多線程,讓視頻捕獲和目標(biāo)檢測(cè)分別在各自的線程中運(yùn)行,能夠更充分地利用 CPU 的多核心處理能力,提高整體的處理效率和實(shí)時(shí)性。

在實(shí)時(shí)視頻處理中,特別是涉及到深度學(xué)習(xí)模型推理這種計(jì)算密集型的任務(wù)時(shí),多線程確實(shí)能夠帶來顯著的性能提升。通過將視頻捕獲和處理分開,可以避免由于處理時(shí)間過長(zhǎng)而導(dǎo)致的幀丟失或延遲。

一、多線程

在 Python 中,可以使用 threading 模塊來實(shí)現(xiàn)多線程。下面是一個(gè)簡(jiǎn)單的例子,演示了如何在 Python 中創(chuàng)建和使用多線程:

1、導(dǎo)入 threading 模塊

首先導(dǎo)入 Python 的 threading 模塊,它提供了多線程編程所需的功能。

import threading

2、創(chuàng)建線程執(zhí)行函數(shù)

定義一個(gè)函數(shù),作為線程的執(zhí)行體。這個(gè)函數(shù)將會(huì)在每個(gè)線程中運(yùn)行。在函數(shù)內(nèi)編寫希望線程執(zhí)行的代碼邏輯。

def my_function():
    # Your code here
    pass

3、創(chuàng)建線程對(duì)象

使用 threading.Thread() 創(chuàng)建一個(gè)線程對(duì)象,將目標(biāo)函數(shù)指定為剛才定義的函數(shù),并傳入所需參數(shù)。

my_thread = threading.Thread(target=my_function, args=(arg1, arg2)) # 傳入?yún)?shù) args

4、動(dòng)線程

使用 start() 方法啟動(dòng)線程。

my_thread.start()

5、等待線程執(zhí)行完成

使用 join() 方法等待線程執(zhí)行完畢。這會(huì)讓主線程等待子線程的結(jié)束。

my_thread.join()

6、示例

以下是一個(gè)簡(jiǎn)單的示例,演示了如何使用多線程:

import threading
import time

# 線程執(zhí)行體函數(shù)
def print_numbers():
    for i in range(5):
        print(f"Child Thread: {i}")
        time.sleep(1)

# 創(chuàng)建線程對(duì)象
thread = threading.Thread(target=print_numbers)

# 啟動(dòng)線程
thread.start()

# 主線程中的其他操作
for i in range(5):
    print(f"Main Thread: {i}")
    time.sleep(0.5)

# 等待子線程執(zhí)行結(jié)束
thread.join()

print("Main Thread exiting...")

print_numbers() 函數(shù)是子線程的執(zhí)行體,在子線程中打印數(shù)字。主線程在啟動(dòng)子線程后,會(huì)同時(shí)進(jìn)行自己的任務(wù)。最后通過 join() 方法等待子線程結(jié)束。

二、視頻處理

一般視頻處理代碼分為兩部分:從相機(jī)讀取下一個(gè)可用幀以及對(duì)幀進(jìn)行圖像處理,例如把圖像送到Y(jié)olov5目標(biāo)檢測(cè)模型進(jìn)行檢測(cè)。

在沒有多線程的程序中,按順序讀取下一幀并進(jìn)行處理。程序等待下一幀可用,然后對(duì)其進(jìn)行必要的處理。讀取幀所需的時(shí)間主要取決于請(qǐng)求、等待下一個(gè)視頻幀,并將其從相機(jī)傳輸?shù)絻?nèi)存的時(shí)間。無論是在 CPU 還是 GPU 上,對(duì)視頻幀進(jìn)行計(jì)算所需的時(shí)間都占據(jù)了視頻處理所花費(fèi)的大部分時(shí)間。

然而,在具有多線程的程序中,讀取下一幀并對(duì)其進(jìn)行處理不需要按順序進(jìn)行。當(dāng)一個(gè)線程執(zhí)行讀取下一幀的任務(wù)時(shí),主線程可以使用 CPU 或 GPU 來處理最后一個(gè)讀取的幀。通過這種方式,這兩個(gè)任務(wù)可以重疊執(zhí)行,從而減少讀取和處理幀的總時(shí)間。

1.視頻單線程處理

# importing required libraries 
import cv2 
import time# opening video capture stream
vcap = cv2.VideoCapture(0)
if vcap.isOpened() is False :
    print("[Exiting]: Error accessing webcam stream.")
    exit(0)
fps_input_stream = int(vcap.get(5))
print("FPS of webcam hardware/input stream: {}".format(fps_input_stream))
grabbed, frame = vcap.read() # reading single frame for initialization/ hardware warm-up# processing frames in input stream
num_frames_processed = 0 
start = time.time()
while True :
    grabbed, frame = vcap.read()
    if grabbed is False :
        print('[Exiting] No more frames to read')
        break# adding a delay for simulating time taken for processing a frame 
    delay = 0.03 # delay value in seconds. so, delay=1 is equivalent to 1 second 
    time.sleep(delay) 
    num_frames_processed += 1cv2.imshow('frame' , frame)
    key = cv2.waitKey(1)
    if key == ord('q'):
        break
end = time.time()# printing time elapsed and fps 
elapsed = end-start
fps = num_frames_processed/elapsed 
print("FPS: {} , Elapsed Time: {} , Frames Processed: {}".format(fps, elapsed, num_frames_processed))# releasing input stream , closing all windows 
vcap.release()
cv2.destroyAllWindows()

2.視頻多線程處理

# importing required libraries 
import cv2 
import time 
from threading import Thread # library for implementing multi-threaded processing# defining a helper class for implementing multi-threaded processing 
class WebcamStream :
    def __init__(self, stream_id=0):
        self.stream_id = stream_id   # default is 0 for primary camera 
        
        # opening video capture stream 
        self.vcap      = cv2.VideoCapture(self.stream_id)
        if self.vcap.isOpened() is False :
            print("[Exiting]: Error accessing webcam stream.")
            exit(0)
        fps_input_stream = int(self.vcap.get(5))
        print("FPS of webcam hardware/input stream: {}".format(fps_input_stream))
            
        # reading a single frame from vcap stream for initializing 
        self.grabbed , self.frame = self.vcap.read()
        if self.grabbed is False :
            print('[Exiting] No more frames to read')
            exit(0)# self.stopped is set to False when frames are being read from self.vcap stream 
        self.stopped = True# reference to the thread for reading next available frame from input stream 
        self.t = Thread(target=self.update, args=())
        self.t.daemon = True # daemon threads keep running in the background while the program is executing 
        
    # method for starting the thread for grabbing next available frame in input stream 
    def start(self):
        self.stopped = False
        self.t.start()# method for reading next frame 
    def update(self):
        while True :
            if self.stopped is True :
                break
            self.grabbed , self.frame = self.vcap.read()
            if self.grabbed is False :
                print('[Exiting] No more frames to read')
                self.stopped = True
                break 
        self.vcap.release()# method for returning latest read frame 
    def read(self):
        return self.frame# method called to stop reading frames 
    def stop(self):
        self.stopped = True# initializing and starting multi-threaded webcam capture input stream 
webcam_stream = WebcamStream(stream_id=0) #  stream_id = 0 is for primary camera 
webcam_stream.start()# processing frames in input stream
num_frames_processed = 0 
start = time.time()
while True :
    if webcam_stream.stopped is True :
        break
    else :
        frame = webcam_stream.read()# adding a delay for simulating time taken for processing a frame 
    delay = 0.03 # delay value in seconds. so, delay=1 is equivalent to 1 second 
    time.sleep(delay) 
    num_frames_processed += 1cv2.imshow('frame' , frame)
    key = cv2.waitKey(1)
    if key == ord('q'):
        break
end = time.time()
webcam_stream.stop() # stop the webcam stream# printing time elapsed and fps 
elapsed = end-start
fps = num_frames_processed/elapsed 
print("FPS: {} , Elapsed Time: {} , Frames Processed: {}".format(fps, elapsed, num_frames_processed))# closing all windows 
cv2.destroyAllWindows()

上面的代碼創(chuàng)建了一個(gè) WebcamStream 類,其中包含了多線程讀取相機(jī)幀的邏輯。在主循環(huán)中,它仍然以順序方式處理每個(gè)幀,但是讀取幀的線程是在后臺(tái)運(yùn)行的。

但上面的代碼提升速度的同時(shí),還有以下有改進(jìn)的問題:

  • 處理多個(gè)幀的邏輯: 代碼在主循環(huán)中每次處理幀時(shí)都有一個(gè)固定的延遲 time.sleep(delay),這并不真實(shí)地模擬出幀處理的時(shí)間。應(yīng)該考慮記錄每個(gè)幀的時(shí)間戳,并在處理完幀后計(jì)算幀處理的實(shí)際時(shí)間。
  • 多線程下的幀處理: 雖然視頻流讀取部分在單獨(dú)的線程中,但是主循環(huán)仍然是順序執(zhí)行的,它等待每個(gè)幀進(jìn)行處理。在多線程環(huán)境中,也許值得考慮在單獨(dú)的線程中對(duì)幀進(jìn)行處理。
  • 內(nèi)存和資源管理: 確保在程序退出時(shí)釋放所有資源,特別是在多線程環(huán)境中,需要小心確保線程的安全退出。
  • 代碼結(jié)構(gòu)和注釋: 為了更好地可讀性和維護(hù)性,添加一些注釋來解釋每個(gè)函數(shù)和方法的作用,以及代碼塊的意圖。

3.多線程代碼優(yōu)化

去除固定延遲的處理方式: 代碼在處理每一幀時(shí)都有固定的延遲??紤]使用實(shí)際幀處理時(shí)間的方法,而不是使用固定的延遲。這可以通過記錄每個(gè)幀的時(shí)間戳來實(shí)現(xiàn)。

并行處理視頻幀: 在主線程中按順序處理每一幀。在多線程環(huán)境下,可以考慮使用多個(gè)線程并行處理視頻幀,以加快處理速度。

資源釋放: 在程序結(jié)束時(shí),確保釋放所有資源。這包括在適當(dāng)?shù)臅r(shí)候關(guān)閉視頻流、終止線程等。

import cv2 
import time 
from threading import Thread

class WebcamStream:
    def __init__(self, stream_id=0):
        self.stream_id = stream_id
        self.vcap = cv2.VideoCapture(self.stream_id)
        if not self.vcap.isOpened():
            print("[Exiting]: Error accessing webcam stream.")
            exit(0)
        self.fps_input_stream = int(self.vcap.get(cv2.CAP_PROP_FPS))
        print("FPS of webcam hardware/input stream: {}".format(self.fps_input_stream))
        self.grabbed, self.frame = self.vcap.read()
        if not self.grabbed:
            print('[Exiting] No more frames to read')
            exit(0)
        self.stopped = False
        self.t = Thread(target=self.update, args=())
        self.t.daemon = True
        self.t.start()

    def update(self):
        while not self.stopped:
            grabbed, frame = self.vcap.read()
            if not grabbed:
                print('[Exiting] No more frames to read')
                self.stopped = True
                break
            self.frame = frame

    def read(self):
        return self.frame

    def stop(self):
        self.stopped = True
        self.t.join()
        self.vcap.release()

webcam_stream = WebcamStream(stream_id=0)
num_frames_processed = 0
start = time.time()
while True:
    frame = webcam_stream.read()
    if webcam_stream.stopped:
        break
    delay = 0.03
    time.sleep(delay)
    num_frames_processed += 1
    cv2.imshow('frame', frame)
    key = cv2.waitKey(1)
    if key == ord('q'):
        break
end = time.time()
webcam_stream.stop()
elapsed = end - start
fps = num_frames_processed / elapsed
print("FPS: {} , Elapsed Time: {} , Frames Processed: {}".format(fps, elapsed, num_frames_processed))
cv2.destroyAllWindows()

以上就是Python開發(fā)中OpenCV視頻流的多線程處理方式詳解的詳細(xì)內(nèi)容,更多關(guān)于Python OpenCV視頻流處理的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • python web框架的總結(jié)

    python web框架的總結(jié)

    在本篇文章里小編給大家整理的是一篇關(guān)于python web框架的總結(jié)內(nèi)容,有興趣的朋友們可以學(xué)習(xí)參考下。
    2021-03-03
  • python Kmeans算法原理深入解析

    python Kmeans算法原理深入解析

    這篇文章主要介紹了python Kmeans算法深入解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-08-08
  • Python 正則表達(dá)式爬蟲使用案例解析

    Python 正則表達(dá)式爬蟲使用案例解析

    這篇文章主要介紹了Python 正則表達(dá)式爬蟲使用案例解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-09-09
  • Python完美還原超級(jí)瑪麗游戲附代碼與視頻

    Python完美還原超級(jí)瑪麗游戲附代碼與視頻

    讀萬卷書不如行萬里路,只學(xué)書上的理論是遠(yuǎn)遠(yuǎn)不夠的,只有在實(shí)戰(zhàn)中才能獲得能力的提升,本篇文章手把手帶你用Python實(shí)現(xiàn)超級(jí)瑪麗,90后的回憶老游戲,快來看戴帽子的大胡子穿著背帶褲的馬里奧
    2021-11-11
  • Python 中 -m 的典型用法、原理解析與發(fā)展演變

    Python 中 -m 的典型用法、原理解析與發(fā)展演變

    這篇文章主要介紹了Python 中 -m 的典型用法、原理解析與發(fā)展演變,需要的朋友可以參考下
    2019-11-11
  • wxPython實(shí)現(xiàn)列表增刪改查功能

    wxPython實(shí)現(xiàn)列表增刪改查功能

    這篇文章主要為大家詳細(xì)介紹了wxPython實(shí)現(xiàn)列表增刪改查功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-11-11
  • YOLOv5小目標(biāo)切圖檢測(cè)的思路與方法

    YOLOv5小目標(biāo)切圖檢測(cè)的思路與方法

    目標(biāo)檢測(cè)Yolo算法是非常經(jīng)典且應(yīng)用廣泛的算法,下面這篇文章主要給大家介紹了關(guān)于YOLOv5小目標(biāo)切圖檢測(cè)的思路與方法,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-12-12
  • 完美解決Pycharm中matplotlib畫圖中文亂碼問題

    完美解決Pycharm中matplotlib畫圖中文亂碼問題

    這篇文章主要介紹了完美解決Pycharm中matplotlib畫圖中文亂碼問題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-01-01
  • Python?如何調(diào)用手機(jī)攝像頭

    Python?如何調(diào)用手機(jī)攝像頭

    本文介紹了如何使用Python和OpenCV庫在電腦上通過網(wǎng)絡(luò)連接查看和控制安卓手機(jī)攝像頭,詳細(xì)步驟包括安裝IP攝像頭服務(wù)器軟件,在同一局域網(wǎng)中連接手機(jī)和電腦,編寫Python腳本捕獲攝像頭數(shù)據(jù),以及保存照片等操作,感興趣的朋友跟隨小編一起看看吧
    2024-09-09
  • 對(duì)sklearn的使用之?dāng)?shù)據(jù)集的拆分與訓(xùn)練詳解(python3.6)

    對(duì)sklearn的使用之?dāng)?shù)據(jù)集的拆分與訓(xùn)練詳解(python3.6)

    今天小編就為大家分享一篇對(duì)sklearn的使用之?dāng)?shù)據(jù)集的拆分與訓(xùn)練詳解(python3.6),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2018-12-12

最新評(píng)論

临潭县| 永登县| 南部县| 井研县| 南平市| 宜章县| 拜泉县| 北辰区| 寻甸| 方山县| 逊克县| 阿荣旗| 新河县| 鄄城县| 安丘市| 台安县| 石屏县| 南平市| 那坡县| 繁峙县| 荔浦县| 满城县| 沾化县| 华亭县| 吴江市| 五指山市| 博爱县| 新龙县| 拜城县| 兴国县| 永顺县| 沧州市| 克什克腾旗| 兴宁市| 伊宁市| 海城市| 德令哈市| 施秉县| 信丰县| 理塘县| 兰坪|