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

opencv-python+yolov3實(shí)現(xiàn)目標(biāo)檢測(cè)

 更新時(shí)間:2021年06月11日 11:41:33   作者:小塞  
因?yàn)樽罱娜蝿?wù)有用到目標(biāo)檢測(cè),快速地了解了目標(biāo)檢測(cè)這一任務(wù),并且實(shí)現(xiàn)了使用opencv進(jìn)行目標(biāo)檢測(cè)。感興趣的可以了解一下

因?yàn)樽罱娜蝿?wù)有用到目標(biāo)檢測(cè),所以昨天晚上、今天上午搞了一下,快速地了解了目標(biāo)檢測(cè)這一任務(wù),并且實(shí)現(xiàn)了使用opencv進(jìn)行目標(biāo)檢測(cè)。

網(wǎng)上資料挺亂的,感覺(jué)在搜資源上浪費(fèi)了我不少時(shí)間,所以我寫(xiě)這篇博客,把我這段時(shí)間了解到的東西整理起來(lái),供有緣的讀者參考學(xué)習(xí)。

目標(biāo)檢測(cè)概況

目標(biāo)檢測(cè)是?

目標(biāo)檢測(cè),粗略來(lái)說(shuō)就是:輸入圖片/視頻,經(jīng)過(guò)處理,得到:目標(biāo)的位置信息(比如左上角和右下角的坐標(biāo))、目標(biāo)的預(yù)測(cè)類別、目標(biāo)的預(yù)測(cè)置信度(confidence)。

拿Faster R-CNN這個(gè)算法舉例:輸入一個(gè)batch(batch size也可以為1)的圖片或者視頻,網(wǎng)絡(luò)直接的outputs是這樣的:
[batchId, classId, confidence, left, top, right, bottom],batchId, classId, confidence, left, top, right, bottom都是標(biāo)量。
batchId表示這一個(gè)batch中,這張圖片的id(也即index),后四個(gè)標(biāo)量即目標(biāo)的位置信息:左上角像素點(diǎn)和右下角像素點(diǎn)的坐標(biāo)。

目標(biāo)檢測(cè)算法?

按照歷史脈絡(luò)來(lái)談:

手工特征提取算法,如VJ、HOG、DPM

R-CNN算法(2014),最早的基于深度學(xué)習(xí)的目標(biāo)檢測(cè)器之一,其結(jié)構(gòu)是兩級(jí)網(wǎng)絡(luò):1)首先需要諸如選擇性搜索之類的算法來(lái)提出可能包含對(duì)象的候選邊界框;2)然后將這些區(qū)域傳遞到CNN算法進(jìn)行分類;

R-CNN算法存在的問(wèn)題是其仿真很慢,并且不是完整的端到端的目標(biāo)檢測(cè)器。

Fast R-CNN算法(2014末),對(duì)原始R-CNN進(jìn)行了相當(dāng)大的改進(jìn):提高準(zhǔn)確度,并減少執(zhí)行正向傳遞所花費(fèi)的時(shí)間。

但是,該模型仍然依賴于外部區(qū)域搜索算法。

faster R-CNN算法(2015),真正的端到端深度學(xué)習(xí)目標(biāo)檢測(cè)器。刪除了選擇性搜索的要求,而是依賴于

(1)完全卷積的區(qū)域提議網(wǎng)絡(luò)(RPN, Region Purpose Network),可以預(yù)測(cè)對(duì)象邊界框和“對(duì)象”分?jǐn)?shù)(量化它是一個(gè)區(qū)域的可能性的分?jǐn)?shù))。

(2)然后將RPN的輸出傳遞到R-CNN組件以進(jìn)行最終分類和標(biāo)記。

R-CNN系列算法,都采取了two-stage策略。特點(diǎn)是:雖然檢測(cè)結(jié)果一般都非常準(zhǔn)確,但仿真速度非常慢,即使是在GPU上也僅獲得5 FPS。

one-stage方法有:yolo(2015)、SSD(2015末),以及在這兩個(gè)算法基礎(chǔ)上改進(jìn)的各論文提出的算法。這些算法的基本思路是:均勻地在圖片的不同位置進(jìn)行密集抽樣,抽樣時(shí)可以采用不同尺度和長(zhǎng)寬比,然后利用CNN提取特征后直接進(jìn)行分類與回歸。

整個(gè)過(guò)程只需要一步,所以其優(yōu)勢(shì)是速度快,但是訓(xùn)練比較困難。

yolov3(2018)是yolo作者提出的第三個(gè)版本(之前還提過(guò)yolov2和它們的tinny版本,tinny版本經(jīng)過(guò)壓縮更快但是也降低了準(zhǔn)確率)。yolov3支持80類物體的目標(biāo)檢測(cè),完整列表[戳這里]: https://github.com/pjreddie/darknet/blob/master/data/coco.names

時(shí)間線:

yolov3模型簡(jiǎn)介

性能介紹

首先,套路,yolov3很強(qiáng)大(不強(qiáng)大我用它干啥呢)。速度上,它比 R-CNN 快 1000 倍,比 Fast R-CNN 快 100 倍。檢測(cè)準(zhǔn)確率上,它不是最準(zhǔn)的:YOLOv3-608比 DSSD 更高,接近 FPN。但是它的速度不到后二者的1/3。

從下圖也可以看出:

架構(gòu)介紹

可以看出,他是一系列卷積、殘差、上采樣組成的。特點(diǎn)在于,它將預(yù)測(cè)分在三個(gè)尺度(Scale)進(jìn)行(見(jiàn)圖中三個(gè)彩色框),也在三個(gè)scale分別輸出。

opencv-python實(shí)現(xiàn)

why opencv?

opencv( 3.4.2+版本)的dnn(Deep Neural Network-DNN)模塊封裝了Darknet框架,這個(gè)框架是

自己寫(xiě)的,它由封裝了yolo算法。因?yàn)檫@么一層關(guān)系,我們可以使用opencv方便地使用yolo的各個(gè)版本,而且有數(shù)據(jù)(見(jiàn)下)證明OpenCV的DNN模塊在 CPU的實(shí)現(xiàn)速度比使用 OpenML 的 Darknet 快9倍。

正文

我會(huì)先結(jié)合腳本片段講解,再給出該腳本的完整代碼,講解。

引庫(kù)

import numpy as np
import cv2 as cv
import os
import time

參數(shù):

yolo_dir = '/home/hessesummer/github/NTS-Net-my/yolov3'  # YOLO文件路徑
weightsPath = os.path.join(yolo_dir, 'yolov3.weights')  # 權(quán)重文件
configPath = os.path.join(yolo_dir, 'yolov3.cfg')  # 配置文件
labelsPath = os.path.join(yolo_dir, 'coco.names')  # label名稱
imgPath = os.path.join(yolo_dir, 'test.jpg')  # 測(cè)試圖像
CONFIDENCE = 0.5  # 過(guò)濾弱檢測(cè)的最小概率
THRESHOLD = 0.4  # 非最大值抑制閾值

權(quán)重文件、配置文件、label名稱的下載地址:

wget https://pjreddie.com/media/files/yolov3.weights
wget https://github.com/pjreddie/darknet/blob/master/cfg/yolov3.cfg
wget https://github.com/pjreddie/darknet/blob/master/data/coco.names

簡(jiǎn)單來(lái)說(shuō):

過(guò)濾弱檢測(cè)的最小概率:置信度小于這個(gè)值的輸出都不要了;
非最大值抑制閾值:允許框框重疊的程度(多框框檢測(cè)同一個(gè)物體),供下面的NMS算法使用,該算法會(huì)根據(jù)該值將有重疊的框框合并。值為0時(shí),不允許框框重疊。默認(rèn)值是0.3。

詳細(xì)來(lái)說(shuō):

我沒(méi)查。您自己感興趣再了解吧。

重頭戲1:

# 加載網(wǎng)絡(luò)、配置權(quán)重
net = cv.dnn.readNetFromDarknet(configPath, weightsPath)  ## 利用下載的文件
# print("[INFO] loading YOLO from disk...") ## 可以打印下信息

# 加載圖片、轉(zhuǎn)為blob格式、送入網(wǎng)絡(luò)輸入層
img = cv.imread(imgPath)
blobImg = cv.dnn.blobFromImage(img, 1.0/255.0, (416, 416), None, True, False)  ## net需要的輸入是blob格式的,用blobFromImage這個(gè)函數(shù)來(lái)轉(zhuǎn)格式
net.setInput(blobImg)  ## 調(diào)用setInput函數(shù)將圖片送入輸入層

# 獲取網(wǎng)絡(luò)輸出層信息(所有輸出層的名字),設(shè)定并前向傳播
outInfo = net.getUnconnectedOutLayersNames()  ## 前面的yolov3架構(gòu)也講了,yolo在每個(gè)scale都有輸出,outInfo是每個(gè)scale的名字信息,供net.forward使用
# start = time.time()
layerOutputs = net.forward(outInfo)  # 得到各個(gè)輸出層的、各個(gè)檢測(cè)框等信息,是二維結(jié)構(gòu)。
# end = time.time()
# print("[INFO] YOLO took {:.6f} seconds".format(end - start)) ## 可以打印下信息

layerOutputs是二維結(jié)構(gòu),第0維代表哪個(gè)輸出層,第1維代表各個(gè)檢測(cè)框。

其他的我都在注釋里講解了。

重頭戲2:

# 拿到圖片尺寸
(H, W) = img.shape[:2]

供下面使用:

# 過(guò)濾layerOutputs
# layerOutputs的第1維的元素內(nèi)容: [center_x, center_y, width, height, objectness, N-class score data]
# 過(guò)濾后的結(jié)果放入:
boxes = [] # 所有邊界框(各層結(jié)果放一起)
confidences = [] # 所有置信度
classIDs = [] # 所有分類ID

# # 1)過(guò)濾掉置信度低的框框
for out in layerOutputs:  # 各個(gè)輸出層
    for detection in out:  # 各個(gè)框框
        # 拿到置信度
        scores = detection[5:]  # 各個(gè)類別的置信度
        classID = np.argmax(scores)  # 最高置信度的id即為分類id
        confidence = scores[classID]  # 拿到置信度

        # 根據(jù)置信度篩查
        if confidence > CONFIDENCE:
            box = detection[0:4] * np.array([W, H, W, H])  # 將邊界框放會(huì)圖片尺寸
            (centerX, centerY, width, height) = box.astype("int")
            x = int(centerX - (width / 2))
            y = int(centerY - (height / 2))
            boxes.append([x, y, int(width), int(height)])
            confidences.append(float(confidence))
            classIDs.append(classID)

# # 2)應(yīng)用非最大值抑制(non-maxima suppression,nms)進(jìn)一步篩掉
idxs = cv.dnn.NMSBoxes(boxes, confidences, CONFIDENCE, THRESHOLD) # boxes中,保留的box的索引index存入idxs

這里的NMS算法就是前面提到的NMS算法。

應(yīng)用檢測(cè)結(jié)果,這里是畫(huà)出框框。

# 得到labels列表
with open(labelsPath, 'rt') as f:
    labels = f.read().rstrip('\n').split('\n')

供下面使用:

# 應(yīng)用檢測(cè)結(jié)果
np.random.seed(42)
COLORS = np.random.randint(0, 255, size=(len(labels), 3), dtype="uint8")  # 框框顯示顏色,每一類有不同的顏色,每種顏色都是由RGB三個(gè)值組成的,所以size為(len(labels), 3)
if len(idxs) > 0:
    for i in idxs.flatten(): # indxs是二維的,第0維是輸出層,所以這里把它展平成1維
        (x, y) = (boxes[i][0], boxes[i][1])
        (w, h) = (boxes[i][2], boxes[i][3])

        color = [int(c) for c in COLORS[classIDs[i]]]
        cv.rectangle(img, (x, y), (x+w, y+h), color, 2)  # 線條粗細(xì)為2px
        text = "{}: {:.4f}".format(labels[classIDs[i]], confidences[i])
        cv.putText(img, text, (x, y-5), cv.FONT_HERSHEY_SIMPLEX, 0.5, color, 2)  # cv.FONT_HERSHEY_SIMPLEX字體風(fēng)格、0.5字體大小、粗細(xì)2px
cv.imshow('目標(biāo)檢測(cè)結(jié)果', img)
cv.waitKey(0)

第一部分講解結(jié)束,下面放完整代碼:

import numpy as np
import cv2 as cv
import os
import time

yolo_dir = '/home/hessesummer/github/NTS-Net-my/yolov3'  # YOLO文件路徑
weightsPath = os.path.join(yolo_dir, 'yolov3.weights')  # 權(quán)重文件
configPath = os.path.join(yolo_dir, 'yolov3.cfg')  # 配置文件
labelsPath = os.path.join(yolo_dir, 'coco.names')  # label名稱
imgPath = os.path.join(yolo_dir, 'test.jpg')  # 測(cè)試圖像
CONFIDENCE = 0.5  # 過(guò)濾弱檢測(cè)的最小概率
THRESHOLD = 0.4  # 非最大值抑制閾值

# 加載網(wǎng)絡(luò)、配置權(quán)重
net = cv.dnn.readNetFromDarknet(configPath, weightsPath)  # #  利用下載的文件
print("[INFO] loading YOLO from disk...")  # # 可以打印下信息

# 加載圖片、轉(zhuǎn)為blob格式、送入網(wǎng)絡(luò)輸入層
img = cv.imread(imgPath)
blobImg = cv.dnn.blobFromImage(img, 1.0/255.0, (416, 416), None, True, False)   # # net需要的輸入是blob格式的,用blobFromImage這個(gè)函數(shù)來(lái)轉(zhuǎn)格式
net.setInput(blobImg)  # # 調(diào)用setInput函數(shù)將圖片送入輸入層

# 獲取網(wǎng)絡(luò)輸出層信息(所有輸出層的名字),設(shè)定并前向傳播
outInfo = net.getUnconnectedOutLayersNames()  # # 前面的yolov3架構(gòu)也講了,yolo在每個(gè)scale都有輸出,outInfo是每個(gè)scale的名字信息,供net.forward使用
start = time.time()
layerOutputs = net.forward(outInfo)  # 得到各個(gè)輸出層的、各個(gè)檢測(cè)框等信息,是二維結(jié)構(gòu)。
end = time.time()
print("[INFO] YOLO took {:.6f} seconds".format(end - start))  # # 可以打印下信息

# 拿到圖片尺寸
(H, W) = img.shape[:2]
# 過(guò)濾layerOutputs
# layerOutputs的第1維的元素內(nèi)容: [center_x, center_y, width, height, objectness, N-class score data]
# 過(guò)濾后的結(jié)果放入:
boxes = [] # 所有邊界框(各層結(jié)果放一起)
confidences = [] # 所有置信度
classIDs = [] # 所有分類ID

# # 1)過(guò)濾掉置信度低的框框
for out in layerOutputs:  # 各個(gè)輸出層
    for detection in out:  # 各個(gè)框框
        # 拿到置信度
        scores = detection[5:]  # 各個(gè)類別的置信度
        classID = np.argmax(scores)  # 最高置信度的id即為分類id
        confidence = scores[classID]  # 拿到置信度

        # 根據(jù)置信度篩查
        if confidence > CONFIDENCE:
            box = detection[0:4] * np.array([W, H, W, H])  # 將邊界框放會(huì)圖片尺寸
            (centerX, centerY, width, height) = box.astype("int")
            x = int(centerX - (width / 2))
            y = int(centerY - (height / 2))
            boxes.append([x, y, int(width), int(height)])
            confidences.append(float(confidence))
            classIDs.append(classID)

# # 2)應(yīng)用非最大值抑制(non-maxima suppression,nms)進(jìn)一步篩掉
idxs = cv.dnn.NMSBoxes(boxes, confidences, CONFIDENCE, THRESHOLD) # boxes中,保留的box的索引index存入idxs
# 得到labels列表
with open(labelsPath, 'rt') as f:
    labels = f.read().rstrip('\n').split('\n')
# 應(yīng)用檢測(cè)結(jié)果
np.random.seed(42)
COLORS = np.random.randint(0, 255, size=(len(labels), 3), dtype="uint8")  # 框框顯示顏色,每一類有不同的顏色,每種顏色都是由RGB三個(gè)值組成的,所以size為(len(labels), 3)
if len(idxs) > 0:
    for i in idxs.flatten():  # indxs是二維的,第0維是輸出層,所以這里把它展平成1維
        (x, y) = (boxes[i][0], boxes[i][1])
        (w, h) = (boxes[i][2], boxes[i][3])

        color = [int(c) for c in COLORS[classIDs[i]]]
        cv.rectangle(img, (x, y), (x+w, y+h), color, 2)  # 線條粗細(xì)為2px
        text = "{}: {:.4f}".format(labels[classIDs[i]], confidences[i])
        cv.putText(img, text, (x, y-5), cv.FONT_HERSHEY_SIMPLEX, 0.5, color, 2)  # cv.FONT_HERSHEY_SIMPLEX字體風(fēng)格、0.5字體大小、粗細(xì)2px
cv.imshow('detected image', img)
cv.waitKey(0)

結(jié)果:

到此這篇關(guān)于opencv-python+yolov3實(shí)現(xiàn)目標(biāo)檢測(cè)的文章就介紹到這了,更多相關(guān)opencv yolov3目標(biāo)檢測(cè)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Python關(guān)于excel和shp的使用在matplotlib

    Python關(guān)于excel和shp的使用在matplotlib

    今天小編就為大家分享一篇關(guān)于Python關(guān)于excel和shp的使用在matplotlib,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2019-01-01
  • 基于Python爬取素材網(wǎng)站音頻文件

    基于Python爬取素材網(wǎng)站音頻文件

    這篇文章主要介紹了基于Python爬取素材網(wǎng)站音頻文件,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-10-10
  • Python下劃線命名模式

    Python下劃線命名模式

    下劃線前綴的含義是告知其他程序員:以單個(gè)下劃線開(kāi)頭的變量或方法僅供內(nèi)部使用,該約定在PEP 8中有定義,這篇文章主要介紹了Python下劃線命名模式,需要的朋友可以參考下
    2023-10-10
  • Python Numpy學(xué)習(xí)之索引及切片的使用方法

    Python Numpy學(xué)習(xí)之索引及切片的使用方法

    數(shù)組中的元素可以通過(guò)索引以及切片的手段進(jìn)行訪問(wèn)或者修改,和列表的切片操作一樣。本文將詳細(xì)為大家介紹一下Python中的科學(xué)計(jì)算庫(kù)-Numpy的索引及切片的使用方法
    2022-01-01
  • Python連接Oracle的多種方式小結(jié)

    Python連接Oracle的多種方式小結(jié)

    Oracle數(shù)據(jù)庫(kù)是一種強(qiáng)大的企業(yè)級(jí)關(guān)系數(shù)據(jù)庫(kù)管理系統(tǒng)(RDBMS),而Python是一門流行的編程語(yǔ)言,兩者的結(jié)合可以提供出色的數(shù)據(jù)管理和分析能力,本教程將詳細(xì)介紹如何在Python中連接Oracle數(shù)據(jù)庫(kù),需要的朋友可以參考下
    2024-08-08
  • python實(shí)現(xiàn)大戰(zhàn)外星人小游戲?qū)嵗a

    python實(shí)現(xiàn)大戰(zhàn)外星人小游戲?qū)嵗a

    這篇文章主要介紹了python實(shí)現(xiàn)大戰(zhàn)外星人小游戲,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-12-12
  • python生成密碼字典的方法

    python生成密碼字典的方法

    今天小編就為大家分享一篇python生成密碼字典的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-07-07
  • 在Python中操作字典之setdefault()方法的使用

    在Python中操作字典之setdefault()方法的使用

    這篇文章主要介紹了在Python中操作字典之setdefault()方法的使用,是Python入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2015-05-05
  • python跨文件使用全局變量的實(shí)現(xiàn)

    python跨文件使用全局變量的實(shí)現(xiàn)

    本文主要介紹了python跨文件使用全局變量的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-03-03
  • Python進(jìn)行數(shù)組的排序、倒序、截取方式

    Python進(jìn)行數(shù)組的排序、倒序、截取方式

    這篇文章主要介紹了Python進(jìn)行數(shù)組的排序、倒序、截取方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-02-02

最新評(píng)論