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

如何使用Python和OpenCV進行實時目標檢測實例詳解

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

簡介

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

代碼介紹

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

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

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

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

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

  • 視頻捕獲:打開攝像頭進行視頻流的捕獲。

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

  • 目標檢測流程

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

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

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

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

代碼拆解講解

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

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

1.首先,讓我們導入需要用到的庫:

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

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

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

3.接下來,我們加載預訓練的 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)建一個顏色列表,以在最后的目標檢測結果中為不同的類別繪制不同的顏色:

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

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

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

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

6.在主循環(huán)中,我們使用 ThreadPoolExecutor 實現(xià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()

總體代碼

# 導入必要的庫
import cv2
import numpy as np
import time
from concurrent.futures import ThreadPoolExecutor

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

# 加載預訓練的 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))

# 打開攝像頭進行視頻幀的捕獲
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ù),處理每幀圖像并進行目標檢測
def process_frame(frame):
    # 將幀轉換為模型的輸入格式
    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)  # 進行前向傳播,獲取檢測結果

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

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

            # 過濾低置信度的檢測結果
            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)

    # 在原圖上繪制邊界框和類別標簽
    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


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

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

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

    # 如果當前幀讀取成功,則繼續(xù)處理
    if ret:
        # 使用線程池異步處理當前幀
        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說明

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

如何操作

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

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

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

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

替換代碼中的 readNet 調用,使用 readNetFromDarknet 并添加代碼來設置網(wǎng)絡的首選后端和目標為 CUDA。

   # 加載預訓練的 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()的調用)會更快。數(shù)據(jù)準備和后處理(例如非極大值抑制)的代碼不需要太多修改,因為它們仍然在 CPU 上執(zhí)行。

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

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

總結        

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

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

相關文章

  • Python sorted對list和dict排序

    Python sorted對list和dict排序

    這篇文章主要介紹了Python sorted對list和dict排序,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-06-06
  • python使用datetime模塊處理日期時間及常用功能詳解

    python使用datetime模塊處理日期時間及常用功能詳解

    datetime模塊是Python標準庫中用于處理日期和時間的模塊,在本節(jié)中,我們將介紹datetime模塊的一些常用功能,并通過實例代碼詳細講解每個知識點,有需要的朋友可以借鑒參考下,希望能夠有所幫助
    2023-06-06
  • Python實現(xiàn)根據(jù)IP地址和子網(wǎng)掩碼算出網(wǎng)段的方法

    Python實現(xiàn)根據(jù)IP地址和子網(wǎng)掩碼算出網(wǎng)段的方法

    這篇文章主要介紹了Python實現(xiàn)根據(jù)IP地址和子網(wǎng)掩碼算出網(wǎng)段的方法,涉及Python基于Linux平臺的字符串操作技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-07-07
  • python 把列表轉化為字符串的方法

    python 把列表轉化為字符串的方法

    今天小編就為大家分享一篇python 把列表轉化為字符串的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-10-10
  • Python實現(xiàn)自動簽到腳本功能

    Python實現(xiàn)自動簽到腳本功能

    這篇文章主要介紹了Python實現(xiàn)自動簽到腳本,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-08-08
  • Python+Matplotlib繪制3D圖像的示例詳解

    Python+Matplotlib繪制3D圖像的示例詳解

    這篇文章主要為大家介紹了如何使用python matplotlib繪制繪制出一系列酷炫的3D圖像,例如:3D散點圖,3D曲線圖等,感興趣的可以了解一下
    2022-04-04
  • python寫xml文件的操作實例

    python寫xml文件的操作實例

    這篇文章主要介紹了python寫xml文件的操作實例,是非常常見的實用技巧,需要的朋友可以參考下
    2014-10-10
  • 11月編程語言排行榜 Python逆襲C#上升到第4

    11月編程語言排行榜 Python逆襲C#上升到第4

    11月編程語言排行榜 Python逆襲C#上升到第4,無論在哪個榜單中 Python 都是保持著非同尋常的增長速度,為什么Python增長的這么快
    2017-11-11
  • flask應用部署到服務器的方法

    flask應用部署到服務器的方法

    這篇文章主要介紹了flask應用部署到服務器的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-07-07
  • Python 根據(jù)數(shù)據(jù)模板創(chuàng)建shapefile的實現(xiàn)

    Python 根據(jù)數(shù)據(jù)模板創(chuàng)建shapefile的實現(xiàn)

    今天小編就為大家分享一篇Python 根據(jù)數(shù)據(jù)模板創(chuàng)建shapefile的實現(xiàn),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-11-11

最新評論

岳阳市| 汉沽区| 尚志市| 梁平县| 车险| 洛川县| 崇仁县| 绍兴市| 山东| 会宁县| 新密市| 进贤县| 酒泉市| 克什克腾旗| 沾化县| 兴和县| 政和县| 西畴县| 太原市| 连江县| 宁南县| 涞水县| 正镶白旗| 蕉岭县| 双流县| 邻水| 饶阳县| 和平区| 灵宝市| 福鼎市| 漳平市| 沂源县| 滨海县| 涡阳县| 乐平市| 永定县| 鄂托克前旗| 天门市| 新安县| 宝丰县| 方山县|