欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

如何使用Python和OpenCV進(jìn)行實時目標(biāo)檢測實例詳解

 更新時間:2024年11月18日 10:03:24   作者:WenJGo  
這篇文章介紹了一個使用Python和OpenCV實現(xiàn)實時視頻流目標(biāo)檢測的程序,程序使用預(yù)訓(xùn)練的YOLOv3模型,并通過多線程處理提高性能,代碼展示了如何導(dǎo)入庫、初始化參數(shù)、加載模型、處理視頻幀以及顯示結(jié)果,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下

簡介

這段程序是一個Python腳本,它使用了OpenCV庫和預(yù)訓(xùn)練的YOLOv3模型來實現(xiàn)實時視頻流的目標(biāo)檢測。它首先從攝像頭捕獲視頻流,并使用線程池處理每一幀圖像。在每一幀中,程序都會檢測和識別不同的對象,并用不同的顏色顯示結(jié)果。使用了非極大值抑制技術(shù)刪除重復(fù)的檢測框,并利用了并發(fā)處理技術(shù)以提高性能。最后,他還顯示了每秒處理的幀數(shù)(FPS)。我們可以通過按'q'鍵來結(jié)束程序。這個程序展示了一種有效的使用深度學(xué)習(xí)模型進(jìn)行實時視覺任務(wù)的方法。        

代碼介紹

這段代碼是使用OpenCV和Python編寫的,主要用于實時視頻流處理和目標(biāo)檢測。代碼的核心是使用訓(xùn)練好的YOLOv3模型來識別和定位視頻幀中的對象。下面是對整個流程的詳細(xì)解釋:

  • 導(dǎo)入庫:首先,導(dǎo)入所需的庫,包括cv2(OpenCV),numpy(用于科學(xué)計算),time(時間管理),以及concurrent.futures(用于并發(fā)執(zhí)行)。

  • 初始化參數(shù):設(shè)置檢測參數(shù),包括置信度閾值(用于過濾掉那些置信度低于閾值的檢測結(jié)果),非極大值抑制(NMS)閾值(用于去除重復(fù)的檢測框),以及輸入圖像的寬和高。

  • 加載模型和類別:通過使用cv2.dnn.readNet加載預(yù)訓(xùn)練的YOLOv3模型,并從coco.names文件中加載可以識別的類名列表。

  • 顏色列表:為每個可識別的類別創(chuàng)建一個隨機(jī)顏色列表,這用于在檢測到的對象周圍繪制彩色的邊界框。

  • 視頻捕獲:打開攝像頭進(jìn)行視頻流的捕獲。

  • 多線程處理:初始化ThreadPoolExecutor以并發(fā)執(zhí)行多個任務(wù)。這里定義了兩個函數(shù)fetch_frameprocess_frame。fetch_frame用于從視頻流中獲取一幀圖像,而process_frame則用于處理圖像并執(zhí)行目標(biāo)檢測。

  • 目標(biāo)檢測流程

    • 轉(zhuǎn)換輸入幀:將輸入幀轉(zhuǎn)換為模型所需要的格式(blob),包括縮放、顏色空間轉(zhuǎn)換等。
    • 執(zhí)行檢測:調(diào)用神經(jīng)網(wǎng)絡(luò)模型執(zhí)行前向傳播,獲取檢測結(jié)果。
    • 過濾結(jié)果:根據(jù)置信度閾值和NMS閾值過濾掉一部分檢測結(jié)果,消除低置信度以及重復(fù)的檢測框。
    • 繪制邊界框和類別標(biāo)簽:在原圖上繪制檢測到的對象的邊界框,并顯示類別名稱和置信度。
  • 顯示結(jié)果:在屏幕上實時顯示處理后的視頻幀,并計算顯示FPS(每秒幀數(shù))。

  • 程序退出:等待我們按q鍵退出,并在退出前釋放資源,包括攝像頭和窗口。

這段代碼的設(shè)計利用了異步處理技術(shù)(通過ThreadPoolExecutor)來提高處理視頻流的效率,使得幀的捕獲和處理能夠并行執(zhí)行,從而盡可能提高FPS。

為什么這樣做,主要是我的電腦沒有獨立GPU,所以,呃,只能動點這中方法了,但是說實話并沒有什么實質(zhì)性的提升,難受了。

代碼拆解講解

我們將使用預(yù)訓(xùn)練的 YOLOv3 模型進(jìn)行目標(biāo)檢測,并使用 Python 的 concurrent.futures 庫來并行處理視頻幀的讀取和模型推理,以優(yōu)化程序的執(zhí)行速度。

感謝YOLO,雖然現(xiàn)在已經(jīng)發(fā)展到v8了,但是我們這里使用v3還是足夠了。

1.首先,讓我們導(dǎo)入需要用到的庫:

import cv2
import numpy as np
import time
from concurrent.futures import ThreadPoolExecutor

2.然后,設(shè)置兩個閾值:conf_threshold 和 nms_threshold,以及圖片的寬度和高度:

conf_threshold = 0.5
nms_threshold = 0.4
Width = 416
Height = 416

3.接下來,我們加載預(yù)訓(xùn)練的 YOLOv3 模型,并加載識別的類名:

net = cv2.dnn.readNet('../needFiles/yolov3.weights', '../needFiles/yolov3.cfg')
with open('../needFiles/coco.names', 'r') as f:
    classes = f.read().strip().split('\n')

4.然后,我們創(chuàng)建一個顏色列表,以在最后的目標(biāo)檢測結(jié)果中為不同的類別繪制不同的顏色:

color_list = np.random.uniform(0, 255, size=(len(classes), 3))

5.下一步,我們定義兩個函數(shù) fetch_frame 和 process_frame

fetch_frame 用于從視頻對象讀取一幀;而 process_frame 則將讀取到的幀輸入到 YOLOv3 模型中,然后處理獲得的輸出結(jié)果,并在幀上繪制物體檢測結(jié)果:

def fetch_frame(cap):
    ...
def process_frame(frame):
    ...

6.在主循環(huán)中,我們使用 ThreadPoolExecutor 實現(xiàn)了并行處理讀取幀和模型推理的操作。

這樣可以使讀取下一幀的操作和模型推理操作同時進(jìn)行,從而顯著地加快了處理速度:

executor = ThreadPoolExecutor(max_workers=2)
frame_future = executor.submit(fetch_frame, cap)

while True:
    ...
    ret, frame, height, width, channels = frame_future.result()
    frame_future = executor.submit(fetch_frame, cap)
    processed_frame = executor.submit(process_frame, frame).result()
    ...

7.退出程序

在這段代碼的最后,如果你按下 q 鍵退出主循環(huán),視頻讀取對象將會被釋放,所有的窗口也將被銷毀:

if cv2.waitKey(1) & 0xFF == ord('q'):
    break
...
cap.release()
cv2.destroyAllWindows()

總體代碼

# 導(dǎo)入必要的庫
import cv2
import numpy as np
import time
from concurrent.futures import ThreadPoolExecutor

# 設(shè)置置信度閾值和非極大值抑制(NMS)閾值
conf_threshold = 0.5
nms_threshold = 0.4
Width = 416
Height = 416

# 加載預(yù)訓(xùn)練的 YOLOv3 模型
net = cv2.dnn.readNet('../needFiles/yolov3.weights', '../needFiles/yolov3.cfg')

# 加載可識別的類名
with open('../needFiles/coco.names', 'r') as f:
    classes = f.read().strip().split('\n')

# 為不同的類別創(chuàng)建一個顏色列表
color_list = np.random.uniform(0, 255, size=(len(classes), 3))

# 打開攝像頭進(jìn)行視頻幀的捕獲
cap = cv2.VideoCapture(0)

# 初始化一個ThreadPoolExecutor用于多線程處理
executor = ThreadPoolExecutor(max_workers=2)


# 定義fetch_frame函數(shù),從視頻流中獲取視頻幀
def fetch_frame(cap):
    ret, frame = cap.read()  # 讀取一幀圖像
    height, width, channels = frame.shape  # 獲取圖像的尺寸和通道信息
    return ret, frame, height, width, channels


# 定義process_frame函數(shù),處理每幀圖像并進(jìn)行目標(biāo)檢測
def process_frame(frame):
    # 將幀轉(zhuǎn)換為模型的輸入格式
    blob = cv2.dnn.blobFromImage(frame, 1 / 255.0, (416, 416), swapRB=True, crop=False)
    net.setInput(blob)
    output_layers = net.getUnconnectedOutLayersNames()  # 獲取輸出層的名字
    layer_outputs = net.forward(output_layers)  # 進(jìn)行前向傳播,獲取檢測結(jié)果

    boxes = []  # 用于存儲檢測到的邊界框
    confidences = []  # 用于存儲邊界框的置信度
    class_ids = []  # 用于存儲邊界框的類別ID

    # 循環(huán)每個輸出層的檢測結(jié)果
    for output in layer_outputs:
        for detection in output:
            scores = detection[5:]  # 獲取類別的得分
            class_id = np.argmax(scores)  # 獲取得分最高的類別ID
            confidence = scores[class_id]  # 獲取得分最高的置信度

            # 過濾低置信度的檢測結(jié)果
            if confidence > conf_threshold:
                center_x = int(detection[0] * width)
                center_y = int(detection[1] * height)
                w = int(detection[2] * width)
                h = int(detection[3] * height)

                # 計算邊界框的位置和尺寸
                x = int(center_x - w / 2)
                y = int(center_y - h / 2)

                # 將邊界框的位置、尺寸、置信度和類別ID添加到列表中
                boxes.append([x, y, w, h])
                confidences.append(float(confidence))
                class_ids.append(class_id)

    # 使用非極大值抑制去除重疊的邊界框
    indices = cv2.dnn.NMSBoxes(boxes, confidences, conf_threshold, nms_threshold)

    # 在原圖上繪制邊界框和類別標(biāo)簽
    for i in indices.flatten():
        box = boxes[i]
        x = box[0]
        y = box[1]
        w = box[2]
        h = box[3]
        label = str(classes[class_ids[i]])
        color = color_list[class_ids[i]]
        cv2.rectangle(frame, (x, y), (x + w, y + h), color, 2)
        cv2.putText(frame, label, (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 2)

    return frame


# 在進(jìn)入循環(huán)前,先讀取一幀以開始異步處理
frame_future = executor.submit(fetch_frame, cap)

# 主循環(huán)
while True:
    start = time.time()  # 記錄開始處理的時間點
    # 獲取當(dāng)前幀和相應(yīng)信息
    ret, frame, height, width, channels = frame_future.result()

    # 異步讀取下一幀
    frame_future = executor.submit(fetch_frame, cap)

    # 如果當(dāng)前幀讀取成功,則繼續(xù)處理
    if ret:
        # 使用線程池異步處理當(dāng)前幀
        processed_frame = executor.submit(process_frame, frame).result()

        # 計算FPS
        end = time.time()
        fps = 1 / (end - start)
        # 在處理好的幀上顯示FPS
        cv2.putText(processed_frame, "FPS: " + str(round(fps, 2)), (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0),
                    2)
        # 顯示處理好的幀
        cv2.imshow('frame', processed_frame)

        # 如果我們按下 ‘q' 鍵,退出循環(huán)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
    else:
        break  # 如果幀沒有被成功讀取,退出循環(huán)

# 釋放視頻捕獲對象和銷毀所有OpenCV窗口
cap.release()
cv2.destroyAllWindows()

效果展示

這個效果還是不錯的哈,就是這個硬件性能跟不上,要是有獨顯就好了。 

使用GPU說明

當(dāng)然了,為了在大學(xué)時期狠狠的獎勵自己四年游戲,很多同學(xué)應(yīng)該都是購買的游戲本,那么恭喜你,你的硬件非常的完美,那么這里你可以看一下。

如何操作

如果你想利用 GPU 加速你的目標(biāo)檢測代碼,主要更改會集中在如何讓 OpenCV 利用你的 GPU。不幸的是,OpenCV 的 dnn 模塊默認(rèn)使用 CPU 進(jìn)行計算。想要使用 GPU,首要條件是你需要有一個支持 CUDA 的 NVIDIA GPU。

從 OpenCV 4.2 版本開始,dnn 模塊添加了對 CUDA 的支持,但實現(xiàn)這一點需要確保你的 OpenCV 是用 CUDA 支持構(gòu)建的。如果你自己編譯 OpenCV,確保在編譯時啟用了 CUDA 支持。

以下是如何更改你的代碼以利用 CUDA 的基本步驟:

1.在讀取模型時啟用 CUDA:

替換代碼中的 readNet 調(diào)用,使用 readNetFromDarknet 并添加代碼來設(shè)置網(wǎng)絡(luò)的首選后端和目標(biāo)為 CUDA。

   # 加載預(yù)訓(xùn)練的 YOLOv3 模型
   net = cv2.dnn.readNetFromDarknet('../needFiles/yolov3.cfg', '../needFiles/yolov3.weights')
   
   # 啟用 CUDA
   net.setPreferableBackend(cv2.dnn.DNN_BACKEND_CUDA)
   net.setPreferableTarget(cv2.dnn.DNN_TARGET_CUDA)

2.其它代碼不需要做太多修改:

使用CUDA優(yōu)化后,主要是模型推理過程(即net.forward()的調(diào)用)會更快。數(shù)據(jù)準(zhǔn)備和后處理(例如非極大值抑制)的代碼不需要太多修改,因為它們?nèi)匀辉?CPU 上執(zhí)行。

這些改動僅在你已有 OpenCV 版本支持 CUDA,并且你的系統(tǒng)擁有合適的 NVIDIA GPU 時有效。如果你的環(huán)境滿足這些條件,這樣的更改可以顯著加快模型推理的速度,尤其是在進(jìn)行視頻流處理時。

最后,你一定要確定你的環(huán)境(包括 NVIDIA 驅(qū)動程序和 CUDA Toolkit)被正確設(shè)置以支持 GPU 加速。如果你對如何編譯支持 CUDA 的 OpenCV 或如何配置你的系統(tǒng)環(huán)境有任何疑問,我建議查閱 OpenCV 官方文檔和 NVIDIA 的 CUDA 安裝指導(dǎo),因為我真的沒有仔細(xì)研究過。

總結(jié)        

希望這篇博客對你有所幫助。最后我想說,雖然NVIDIA對我們的學(xué)習(xí)有幫助,但是我還是想說。

到此這篇關(guān)于如何使用Python和OpenCV進(jìn)行實時目標(biāo)檢測的文章就介紹到這了,更多相關(guān)Python和OpenCV實時目標(biāo)檢測內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Python工程師必考的6個經(jīng)典面試題

    Python工程師必考的6個經(jīng)典面試題

    在本篇文章里小編給大家分享的是一篇關(guān)于6個Python工程師必考的面試題,有需要的朋友們可以參考學(xué)習(xí)下。
    2020-06-06
  • Python實現(xiàn)用networkx繪制MultiDiGraph

    Python實現(xiàn)用networkx繪制MultiDiGraph

    這篇文章主要介紹了Python實現(xiàn)用networkx繪制MultiDiGraph方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-02-02
  • python使用pandas讀xlsx文件的實現(xiàn)

    python使用pandas讀xlsx文件的實現(xiàn)

    這篇文章主要介紹了python使用pandas讀xlsx文件的實現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • 用python寫一個windows消息提醒小程序

    用python寫一個windows消息提醒小程序

    上班時,由于自己經(jīng)常coding到忘記時間,經(jīng)常會一坐坐很久,搞的勞資腰都不好了,所以沒事閑的寫了個久坐提醒的小程序,文中有詳細(xì)的代碼示例,講解的非常詳細(xì),感興趣的朋友可以參考下
    2023-12-12
  • python運行其他程序的實現(xiàn)方法

    python運行其他程序的實現(xiàn)方法

    這篇文章主要介紹了python運行其他程序的實現(xiàn)方法的相關(guān)資料,需要的朋友可以參考下
    2017-07-07
  • pytorch 把MNIST數(shù)據(jù)集轉(zhuǎn)換成圖片和txt的方法

    pytorch 把MNIST數(shù)據(jù)集轉(zhuǎn)換成圖片和txt的方法

    這篇文章主要介紹了pytorch 把MNIST數(shù)據(jù)集轉(zhuǎn)換成圖片和txt的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-05-05
  • 使用pycharm創(chuàng)建Django項目失敗的解決方案

    使用pycharm創(chuàng)建Django項目失敗的解決方案

    使用PyCharm創(chuàng)建Django項目時遇到無法運行的問題,可以檢查Python的安裝路徑設(shè)置是否正確,在PyCharm的設(shè)置中找到項目解釋器的位置,確保路徑正確,如果不確定Python的安裝位置,可以在命令提示符中使用“where Python”命令查詢
    2024-09-09
  • python實現(xiàn)音樂下載的統(tǒng)計

    python實現(xiàn)音樂下載的統(tǒng)計

    這篇文章主要為大家詳細(xì)介紹了python實現(xiàn)音樂下載的統(tǒng)計,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-06-06
  • Python3中l(wèi)ambda表達(dá)式與函數(shù)式編程講解

    Python3中l(wèi)ambda表達(dá)式與函數(shù)式編程講解

    今天小編就為大家分享一篇關(guān)于Python3中l(wèi)ambda表達(dá)式與函數(shù)式編程講解,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-01-01
  • 詳解python里的命名規(guī)范

    詳解python里的命名規(guī)范

    這篇文章主要介紹了詳解python里的命名規(guī)范,命名應(yīng)當(dāng)盡量使用全拼寫的單詞,縮寫的情況文章中也給大家提到,需要的朋友參考下吧
    2018-07-07

最新評論