国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

用opencv的DNN模塊做Yolov5目標(biāo)檢測(純干貨,源碼已上傳Github)

這篇具有很好參考價值的文章主要介紹了用opencv的DNN模塊做Yolov5目標(biāo)檢測(純干貨,源碼已上傳Github)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

用opencv的DNN模塊做Yolov5目標(biāo)檢測(純干貨,源碼已上傳Github),opencv,dnn,YOLO,人工智能,目標(biāo)檢測,python,keras

最近在微信公眾號里看到多篇講解yolov5在openvino部署做目標(biāo)檢測文章,但是沒看到過用opencv的dnn模塊做yolov5目標(biāo)檢測的。于是,我就想著編寫一套用opencv的dnn模塊做yolov5目標(biāo)檢測的程序。在編寫這套程序時,遇到的bug和解決辦法,在這篇文章里講述一下。

用opencv的DNN模塊做Yolov5目標(biāo)檢測(純干貨,源碼已上傳Github),opencv,dnn,YOLO,人工智能,目標(biāo)檢測,python,keras

在yolov5之前的yolov3和yolov4的官方代碼都是基于darknet框架的實現(xiàn)的,因此opencv的dnn模塊做目標(biāo)檢測時,讀取的是.cfg和.weight文件,那時候編寫程序很順暢,沒有遇到bug。但是yolov5的官方代碼(https://github.com/ultralytics/yolov5)是基于pytorch框架實現(xiàn)的,但是opencv的dnn模塊不支持讀取pytorch的訓(xùn)練模型文件的。如果想要把pytorch的訓(xùn)練模型.pth文件加載到opencv的dnn模塊里,需要先把pytorch的訓(xùn)練模型.pth文件轉(zhuǎn)換到.onnx文件,然后才能載入到opencv的dnn模塊里。

因此,用opencv的dnn模塊做yolov5目標(biāo)檢測的程序,包含兩個步驟:(1).把pytorch的訓(xùn)練模型.pth文件轉(zhuǎn)換到.onnx文件。(2).opencv的dnn模塊讀取.onnx文件做前向計算。

(1).把pytorch的訓(xùn)練模型.pth文件轉(zhuǎn)換到.onnx文件

在做這一步時,我得吐槽一下官方代碼:https://github.com/ultralytics/yolov5,這套程序里的代碼混亂,在pytorch里,通常是在.py文件里定義網(wǎng)絡(luò)結(jié)構(gòu)的,但是官方代碼是在.yaml文件定義網(wǎng)絡(luò)結(jié)構(gòu),利用pytorch動態(tài)圖特性,解析.yaml文件自動生成網(wǎng)絡(luò)結(jié)構(gòu)。在.yaml文件里有depth_multiple和width_multiple,它是控制網(wǎng)絡(luò)的深度和寬度的參數(shù)。這么做的好處是能夠靈活的配置網(wǎng)絡(luò)結(jié)構(gòu),但是不利于理解網(wǎng)絡(luò)結(jié)構(gòu),假如你想設(shè)斷點查看某一層的參數(shù)和輸出數(shù)值,那就沒辦法了。因此,在我編寫的轉(zhuǎn)換到.onnx文件的程序里,網(wǎng)絡(luò)結(jié)構(gòu)是在.py文件里定義的。其次,在官方代碼里,還有一個奇葩的地方,那就是.pth文件。起初,我下載官方代碼到本地運行時,torch.load讀取.pth文件總是出錯,后來把pytorch升級到1.7,就讀取成功了??梢钥吹桨姹炯嫒菪圆缓茫@是它的一個不足之處。設(shè)斷點查看讀取的.pth文件里的內(nèi)容,可以看到ultralytics的.pt文件里既存儲有模型參數(shù),也存儲有網(wǎng)絡(luò)結(jié)構(gòu),還儲存了一些超參數(shù),包括anchors,stride等等的。第一次見到有這種操作的,通常情況下,.pth文件里只存儲了訓(xùn)練模型參數(shù)的。

查看models\yolo.py里的Detect類,在構(gòu)造函數(shù)里,有這么兩行代碼:

用opencv的DNN模塊做Yolov5目標(biāo)檢測(純干貨,源碼已上傳Github),opencv,dnn,YOLO,人工智能,目標(biāo)檢測,python,keras

我嘗試過把這兩行代碼改成self.anchors = a 和 self.anchor_grid = a.clone().view(self.nl, 1, -1, 1, 1, 2),程序依然能正常運行,但是torch.save保存模型文件后,可以看到.pth文件里沒有存儲anchors和anchor_grid了,在百度搜索register_buffer,解釋是:pytorch中register_buffer模型保存和加載的時候可以寫入和讀出。

在這兩行代碼的下一行:

用opencv的DNN模塊做Yolov5目標(biāo)檢測(純干貨,源碼已上傳Github),opencv,dnn,YOLO,人工智能,目標(biāo)檢測,python,keras

它的作用是做特征圖的輸出通道對齊,通過1x1卷積把三種尺度特征圖的輸出通道都調(diào)整到 num_anchors*(num_classes+5)。

閱讀Detect類的forward函數(shù)代碼,可以看出它的作用是根據(jù)偏移公式計算出預(yù)測框的中心坐標(biāo)和高寬,這里需要注意的是,計算高和寬的代碼:

pwh = (ps[:, 2:4].sigmoid() * 2) ** 2 * anchors[i]

沒有采用exp操作,而是直接乘上anchors[i],這是yolov5與yolov3v4的一個最大區(qū)別(還有一個區(qū)別就是在訓(xùn)練階段的loss函數(shù)里,yolov5采用鄰域的正樣本anchor匹配策略,增加了正樣本。其它的是一些小區(qū)別,比如yolov5的第一個模塊采用FOCUS把輸入數(shù)據(jù)2倍下采樣切分成4份,在channel維度進(jìn)行拼接,然后進(jìn)行卷積操作,yolov5的激活函數(shù)沒有使用Mish)。

現(xiàn)在可以明白Detect類的作用是計算預(yù)測框的中心坐標(biāo)和高寬,簡單來說就是生成proposal,作為后續(xù)NMS的輸入,進(jìn)而輸出最終的檢測框。我覺得在Detect類里定義的1x1卷積是不恰當(dāng)?shù)模瑧?yīng)該把它定義在Detect類的外面,緊鄰著Detect類之前定義1x1卷積。

在官方代碼里,有轉(zhuǎn)換到onnx文件的程序:

python models/export.py --weights yolov5s.pt --img 640 --batch 1

在pytorch1.7版本里,程序是能正常運行生成onnx文件的。觀察export.py里的代碼,在執(zhí)行torch.onnx.export之前,有這么一段代碼:

用opencv的DNN模塊做Yolov5目標(biāo)檢測(純干貨,源碼已上傳Github),opencv,dnn,YOLO,人工智能,目標(biāo)檢測,python,keras

注意其中的for循環(huán),我試驗過注釋掉它,重新運行就會出錯,打印出的錯誤如下:

用opencv的DNN模塊做Yolov5目標(biāo)檢測(純干貨,源碼已上傳Github),opencv,dnn,YOLO,人工智能,目標(biāo)檢測,python,keras

由此可見,這段for循環(huán)代碼是必需的。SiLU其實就是swish激活函數(shù),而在onnx模型里是不直接支持swish算子的,因此在轉(zhuǎn)換生成onnx文件時,SiLU激活函數(shù)不能直接使用nn.Module里提供的接口,而需要自定義實現(xiàn)它。

(2).opencv的dnn模塊讀取.onnx文件做前向計算

在生成.onnx文件后,就可以用opencv的dnn模塊里的cv2.dnn.readNet讀取它。然而,在讀取時,出現(xiàn)了如下錯誤:

我在百度搜索這個問題的解決辦法,看到一篇知乎文章(Pytorch轉(zhuǎn)ONNX-實戰(zhàn)篇2(實戰(zhàn)踩坑總結(jié)) - 知乎),文章里講述的第一條:

用opencv的DNN模塊做Yolov5目標(biāo)檢測(純干貨,源碼已上傳Github),opencv,dnn,YOLO,人工智能,目標(biāo)檢測,python,keras

于是查看yolov5的代碼,在common.py文件的Focus類,torch.cat的輸入里有4次切片操作,代碼如下:

用opencv的DNN模塊做Yolov5目標(biāo)檢測(純干貨,源碼已上傳Github),opencv,dnn,YOLO,人工智能,目標(biāo)檢測,python,keras

那么現(xiàn)在需要更換索引式的切片操作,觀察到注釋的Contract類,它就是用view和permute函數(shù)完成切片操作的,于是修改代碼如下:

用opencv的DNN模塊做Yolov5目標(biāo)檢測(純干貨,源碼已上傳Github),opencv,dnn,YOLO,人工智能,目標(biāo)檢測,python,keras

其次,在models\yolo.py里的Detect類里,也有切片操作,代碼如下:

用opencv的DNN模塊做Yolov5目標(biāo)檢測(純干貨,源碼已上傳Github),opencv,dnn,YOLO,人工智能,目標(biāo)檢測,python,keras

前面說過,Detect類的作用是計算預(yù)測框的中心坐標(biāo)和高寬,生成proposal,這個是屬于后處理的,因此不需要把它寫入到onnx文件里。

總結(jié)一下,按照上面的截圖代碼,修改Focus類,把Detect類里面的1x1卷積定義在緊鄰著Detect類之前的外面,然后去掉Detect類,組成新的model,作為torch.onnx.export的輸入,

torch.onnx.export(model, inputs, output_onnx, verbose=False, opset_version=12, input_names=[‘images’], output_names=[‘out0’, ‘out1’, ‘out2’])

最后生成的onnx文件,opencv的dnn模塊就能成功讀取了,接下來對照Detect類里的forward函數(shù),用python或者C++編寫計算預(yù)測框的中心坐標(biāo)和高寬的功能。

周末這兩天,我在win10+cpu機器里編寫了用opencv的dnn模塊做yolov5目標(biāo)檢測的程序,包含Python和C++兩個版本的。程序都調(diào)試通過了,運行結(jié)果也是正確的。我把這套代碼發(fā)布在github上,地址是:

https://github.com/hpc203/yolov5-dnn-cpp-python

后處理模塊,python版本用numpy array實現(xiàn)的,C++版本的用vector和數(shù)組實現(xiàn)的,整套程序只依賴opencv庫(opencv4版本以上的)就能正常運行,徹底擺脫對深度學(xué)習(xí)框架pytorch,tensorflow,caffe,mxnet等等的依賴。用openvino作目標(biāo)檢測,需要把onnx文件轉(zhuǎn)換到.bin和.xml文件,相比于用dnn模塊加載onnx文件做目標(biāo)檢測是多了一個步驟的。因此,我就想編寫一套用opencv的dnn模塊做yolov5目標(biāo)檢測的程序,用opencv的dnn模塊做深度學(xué)習(xí)目標(biāo)檢測,在win10和ubuntu,在cpu和gpu上都能運行,可見dnn模塊的通用性更好,很接地氣。

生成yolov5s_param.pth 的步驟,首先下載https://github.com/ultralytics/yolov5?的源碼到本地,在yolov5-master主目錄(注意不是我發(fā)布的github代碼目錄)里新建一個.py文件,把下面的代碼復(fù)制到.py文件里

import torch
from collections import OrderedDict
import pickle
import os

device = 'cuda' if torch.cuda.is_available() else 'cpu'

if __name__=='__main__':
    choices = ['yolov5s', 'yolov5l', 'yolov5m', 'yolov5x']
    modelfile = choices[0]+'.pt'
    utl_model = torch.load(modelfile, map_location=device)
    utl_param = utl_model['model'].model
    torch.save(utl_param.state_dict(), os.path.splitext(modelfile)[0]+'_param.pth')
    own_state = utl_param.state_dict()
    print(len(own_state))

    numpy_param = OrderedDict()
    for name in own_state:
        numpy_param[name] = own_state[name].data.cpu().numpy()
    print(len(numpy_param))
    with open(os.path.splitext(modelfile)[0]+'_numpy_param.pkl', 'wb') as fw:
????????pickle.dump(numpy_param,?fw)

運行這個.py文件,這時候就可以生成yolov5s_param.pth文件。之所以要進(jìn)行這一步,我在上面講到過:ultralytics的.pt文件里既存儲有模型參數(shù),也存儲有網(wǎng)絡(luò)結(jié)構(gòu),還儲存了一些超參數(shù),包括anchors,stride等等的。torch.load加載ultralytics的官方.pt文件,也就是utl_model = torch.load(modelfile, map_location=device)這行代碼,在這行代碼后設(shè)斷點查看utl_model里的內(nèi)容,截圖如下

用opencv的DNN模塊做Yolov5目標(biāo)檢測(純干貨,源碼已上傳Github),opencv,dnn,YOLO,人工智能,目標(biāo)檢測,python,keras

可以看到utl_model里含有既存儲有模型參數(shù),也存儲有網(wǎng)絡(luò)結(jié)構(gòu),還儲存了一些超參數(shù)等等的,這會嚴(yán)重影響轉(zhuǎn)onnx文件。此外,我還發(fā)現(xiàn),如果pytorch的版本低于1.7,那么在torch.load加載.pt文件時就會出錯的。

因此在程序里,我把模型參數(shù)轉(zhuǎn)換到cpu.numpy形式的,最后保存在.pkl文件里。這時候在win10系統(tǒng)cpu環(huán)境里,即使你的電腦沒有安裝pytorch,也能通過python程序訪問到模型參數(shù)。

pytorch轉(zhuǎn)onnx常見坑:

  1. onnx只能輸出靜態(tài)圖,因此不支持if-else分支。一次只能走一個分支。如果代碼中有if-else語句,需要改寫。
  2. onnx不支持步長為2的切片。例如a[::2,::2]
  3. onnx不支持對切片對象賦值。例如a[0,:,:,:]=b, 可以用torch.cat改寫
  4. onnx里面的resize要求output shape必須為常量??梢杂靡韵麓a解決:

if isinstance(size, torch.Size):
??? size = tuple(int(x) for x in size)

此外,在torch.onnx.export(model, inputs, output_onnx)的輸入?yún)?shù)model里,應(yīng)該只包含網(wǎng)絡(luò)結(jié)構(gòu),也就是說model里只含有nn.Conv2d, nn.MaxPool2d, nn.BatchNorm2d, F.relu等等的這些算子組件,而不應(yīng)該含有后處理模塊的。圖像預(yù)處理和后處理模塊需要自己使用C++或者Python編程實現(xiàn)。

在明白了這些之后,在轉(zhuǎn)換生成onnx文件,你需要執(zhí)行兩個步驟,第一步把原始訓(xùn)練模型.pt文件里的參數(shù)保存到新的.pth文件里,第二步編寫yolov5.py文件,把yolov5的往來結(jié)構(gòu)定義在.py文件里,此時需要注意網(wǎng)絡(luò)結(jié)構(gòu)里不能包含切片對象賦值操作,F(xiàn).interpolate里的size參數(shù)需要加int強制轉(zhuǎn)換。在執(zhí)行完這兩步之后才能生成一個opencv能成功讀取并且做前向推理的onnx文件。

不過,最近我發(fā)現(xiàn)在yolov5-pytorch程序里,其實可以直接把原始訓(xùn)練模型.pt文件轉(zhuǎn)換生成onnx文件的,而且我在一個yolov5檢測人臉+關(guān)鍵點的程序里實驗成功了。

這套程序發(fā)布在github上,地址是 :

https://github.com/hpc203/yolov5-face-landmarks-opencv

https://github.com/hpc203/yolov5-face-landmarks-opencv-v2

這套程序只依賴opencv庫就可以運行yolov5檢測人臉+關(guān)鍵點,程序依然是包含C++和Python兩個版本的,這套程序里還有一個轉(zhuǎn)換生成onnx文件的python程序文件。只需運行這一個.py文件就可以生成onnx文件,而不需要之前講的那樣執(zhí)行兩個步驟,這樣大大簡化了生成onnx文件的流程,使用方法可以閱讀程序里的README文檔。

在這個新的轉(zhuǎn)換生成onnx文件的程序里,需要重新定義yolov5網(wǎng)絡(luò)結(jié)構(gòu),主要是修改第一個模塊Focus,用Contract類替換索引式的切片操作,在最后一個模塊Detect類里,只保留三個1x1卷積,剩下的make_grid和decode屬于后處理,不能包含在網(wǎng)絡(luò)結(jié)構(gòu)里,代碼截圖如下

用opencv的DNN模塊做Yolov5目標(biāo)檢測(純干貨,源碼已上傳Github),opencv,dnn,YOLO,人工智能,目標(biāo)檢測,python,keras

如果要轉(zhuǎn)換生成onnx文件,需要設(shè)置export = True,這時候Detect模塊的forward就只進(jìn)行1x1卷積,這時的網(wǎng)絡(luò)結(jié)構(gòu)就可以作為torch.onnx.export(model, inputs, output_onnx)的輸入?yún)?shù)model。不過由于ultralytics的yolov5代碼倉庫幾乎每天都在更新,因此你現(xiàn)在看到的ultralytics的yolov5里的Detect類很有可能不是這么寫的,那這是需要你手動修改程序,然后再運行。

看到最近曠視發(fā)布的anchor-free系列的YOLOX,而在github開源的代碼里,并沒有使用opencv部署的程序。因此,我就編寫了一套使用OpenCV部署YOLOX的程序,支持YOLOX-S、YOLOX-M、YOLOX-L、YOLOX-X、YOLOX-Darknet53五種結(jié)構(gòu),包含C++和Python兩種版本的程序?qū)崿F(xiàn)。在今天我在github發(fā)布了這套程序,地址是

https://github.com/hpc203/yolox-opencv-dnn

在曠視發(fā)布的YOLOX代碼里,提供了在COCO數(shù)據(jù)集上訓(xùn)練出來的.pth模型文件,并且也提供了導(dǎo)出onnx模型的export_onnx.py文件,起初我運行export_onnx.py生成onnx文件之后Opencv讀取onnx文件失敗了,報錯原因跟文章最開始的第(2)節(jié)里的一樣,這說明在YOLOX的網(wǎng)絡(luò)結(jié)構(gòu)里有切片操作,經(jīng)過搜索后,在 yolox\models\network_blocks.py 里有個Focus類,它跟YOLOv5里的Focus是一樣的,都是把輸入張量切分成4份,然后concat+conv。這時按照第(2)節(jié)里講述的解決辦法,修改Focus類,重新運行export_onnx.py生成onnx文件,Opencv讀取onnx文件就不會再出錯了。

在github發(fā)布了一套使用OpenCV部署Yolo-FastestV2的程序,依然是包含C++和Python兩種版本的程序?qū)崿F(xiàn)。地址是

https://github.com/hpc203/yolo-fastestv2-opencv

經(jīng)過運行,體驗到這個Yolo-FastestV2的速度確實很快,而且onnx文件只有957kb大小,不超過1M。在官方代碼https://github.com/dog-qiuqiu/Yolo-FastestV2里,學(xué)習(xí)它的網(wǎng)絡(luò)結(jié)構(gòu)。設(shè)斷點調(diào)試,查看中間變量可以看到,在model/detector.py,網(wǎng)絡(luò)輸出了6個張量

用opencv的DNN模塊做Yolov5目標(biāo)檢測(純干貨,源碼已上傳Github),opencv,dnn,YOLO,人工智能,目標(biāo)檢測,python,keras

它們的形狀分別是

torch.Size([1, 12, 22, 22])
torch.Size([1, 3, 22, 22])
torch.Size([1, 80, 22, 22])
torch.Size([1, 12, 11, 11])
torch.Size([1, 3, 11, 11])
torch.Size([1, 80, 11, 11])

結(jié)合配置文件data/coco.data,可以看到模型輸入是352x352的圖片,而輸出有22x22和11x11這兩種尺度的特征圖,這說明Yolo-FastestV2的輸出只有縮放16倍和縮放32倍這兩種尺度的特征圖,比yolov3,v4,v5系列的都要少一個尺度特征圖。其次在配置文件data/coco.data還可以看到anchor一共有6個,分別給兩個尺度特征圖里的網(wǎng)格點分配3個。觀察輸出的6個張量的形狀信息,很明顯前3個張量是22x22尺度特征圖的檢測框坐標(biāo)回歸量bbox_reg,檢測框目標(biāo)置信度obj_conf,檢測框類別置信度cls_conf。由于給每個網(wǎng)格點分配3個anchor,檢測框坐標(biāo)包含(center_x, center_y, width, height),因此維數(shù)是43=12,這也就明白了bbox_reg的第1個維度是12,obj_conf的第1個維度是3,而COCO數(shù)據(jù)集有80類,那么cls_conf的第1個維度應(yīng)該是380=240,但是在上面調(diào)試信息里顯示的是80類。繼續(xù)設(shè)斷點調(diào)試代碼,在utils/utils.py里,第326行有這么一行代碼

用opencv的DNN模塊做Yolov5目標(biāo)檢測(純干貨,源碼已上傳Github),opencv,dnn,YOLO,人工智能,目標(biāo)檢測,python,keras

類別置信度復(fù)制了3份,結(jié)合這個后處理代碼,可以看出類別置信度對3個anchor是共享的。

在觀察出Yolo-FastestV2的這些特性之后,可以理解為何它的速度快和模型文件小的原因了。主要是因為它的輸入圖片尺寸比傳統(tǒng)yolov3,v4,v5系列的要小,它的輸出特征圖尺寸個數(shù),也比傳統(tǒng)yolo的要少,最后對網(wǎng)格點上的3個anchor是共享類別置信度的,這也減少了特種通道數(shù)。

8月29日,我在github發(fā)布了一套使用OpenCV部署全景駕駛感知網(wǎng)絡(luò)YOLOP,可同時處理交通目標(biāo)檢測、可駕駛區(qū)域分割、車道線檢測,三項視覺感知任務(wù),依然是包含C++和Python兩種版本的程序?qū)崿F(xiàn)。地址是:

https://github.com/hpc203/YOLOP-opencv-dnn

在這里我講一下生成onnx文件需要注意的地方,YOLOP的官方代碼地址是 https://github.com/hustvl/YOLOP ?,它是華中科技大學(xué)視覺團(tuán)隊發(fā)布的,它的代碼是使用pytorch作為深度學(xué)習(xí)框架。仔細(xì)閱讀和運行調(diào)試他的代碼,可以看出,它的代碼是在ultralytics的yolov5里修改的,添加了可行駛區(qū)域分割和車道線分割這兩個分割頭,在bdd100k數(shù)據(jù)集上的訓(xùn)練的,不過YOLOP的檢測類別只保留了bdd100k數(shù)據(jù)集里的車輛這一個類別。生成onnx文件,第一步是把我發(fā)布的代碼里的export_onnx.py拷貝到https://github.com/hustvl/YOLOP的主目錄里。第二步,在https://github.com/hustvl/YOLOP的主目錄里,打開lib/models/common.py,首先修改Focus類,原始的Focus類的forward函數(shù)里是由切片操作的,那么這時按照第(2)節(jié)里講述的解決辦法,修改Focus類,示例代碼如下

class Contract(nn.Module):
    # Contract width-height into channels, i.e. x(1,64,80,80) to x(1,256,40,40)
    def __init__(self, gain=2):
        super().__init__()
        self.gain = gain
    def forward(self, x):
        N, C, H, W = x.size()  # assert (H / s == 0) and (W / s == 0), 'Indivisible gain'
        s = self.gain
        x = x.view(N, C, H // s, s, W // s, s)  # x(1,64,40,2,40,2)
        x = x.permute(0, 3, 5, 1, 2, 4).contiguous()  # x(1,2,2,64,40,40)
        return x.view(N, C * s * s, H // s, W // s)  # x(1,256,40,40)

class Focus(nn.Module):
    # Focus wh information into c-space
    # slice concat conv
    def __init__(self, c1, c2, k=1, s=1, p=None, g=1, act=True):  # ch_in, ch_out, kernel, stride, padding, groups
        super(Focus, self).__init__()
        self.conv = Conv(c1 * 4, c2, k, s, p, g, act)
        self.contract = Contract(gain=2)
    def forward(self, x):  # x(b,c,w,h) -> y(b,4c,w/2,h/2)
        # return self.conv(torch.cat([x[..., ::2, ::2], x[..., 1::2, ::2], x[..., ::2, 1::2], x[..., 1::2, 1::2]], 1))
        return self.conv(self.contract(x))

接下來修改Detect類里的forward函數(shù),示例代碼如下

def forward(self, x):
    if not torch.onnx.is_in_onnx_export():
        z = []  # inference output
        for i in range(self.nl):
            x[i] = self.m[i](x[i])  # conv
            # print(str(i)+str(x[i].shape))
            bs, _, ny, nx = x[i].shape  # x(bs,255,w,w) to x(bs,3,w,w,85)
            x[i] = x[i].view(bs, self.na, self.no, ny, nx).permute(0, 1, 3, 4, 2).contiguous()
            # print(str(i)+str(x[i].shape))

            if not self.training:  # inference
                if self.grid[i].shape[2:4] != x[i].shape[2:4]:
                    self.grid[i] = self._make_grid(nx, ny).to(x[i].device)
                y = x[i].sigmoid()
                # print("**")
                # print(y.shape) #[1, 3, w, h, 85]
                # print(self.grid[i].shape) #[1, 3, w, h, 2]
                y[..., 0:2] = (y[..., 0:2] * 2. - 0.5 + self.grid[i].to(x[i].device)) * self.stride[i]  # xy
                y[..., 2:4] = (y[..., 2:4] * 2) ** 2 * self.anchor_grid[i]  # wh
                """print("**")
                print(y.shape)  #[1, 3, w, h, 85]
                print(y.view(bs, -1, self.no).shape) #[1, 3*w*h, 85]"""
                z.append(y.view(bs, -1, self.no))
        return x if self.training else (torch.cat(z, 1), x)
    else:
        for i in range(self.nl):
            x[i] = self.m[i](x[i])  # conv
            # print(str(i)+str(x[i].shape))
            bs, _, ny, nx = x[i].shape  # x(bs,255,w,w) to x(bs,3,w,w,85)
            x[i] = x[i].view(bs, self.na, self.no, ny, nx).permute(0, 1, 3, 4, 2).contiguous()
            x[i] = torch.sigmoid(x[i])
            x[i] = x[i].view(-1, self.no)
????????return?torch.cat(x,?dim=0)

RUBY 復(fù)制 全屏

修改完之后,運行export_onnx.py就能生成onnx文件,并且opencv讀取正常的。

9月18日,我在github上發(fā)布了一套使用ONNXRuntime部署anchor-free系列的YOLOR,依然是包含C++和Python兩種版本的程序。起初我是想使用OpenCV部署的,但是opencv讀取onnx文件總是出錯,于是我換用ONNXRuntime部署。地址是:

https://github.com/hpc203/yolor-onnxruntime文章來源地址http://www.zghlxwxcb.cn/news/detail-787287.html

到了這里,關(guān)于用opencv的DNN模塊做Yolov5目標(biāo)檢測(純干貨,源碼已上傳Github)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • OpenCV之YOLOv5目標(biāo)檢測

    OpenCV之YOLOv5目標(biāo)檢測

    ?? 個人主頁: 風(fēng)間琉璃 ?? 版權(quán): ?本文由【風(fēng)間琉璃】原創(chuàng)、在CSDN首發(fā)、需要轉(zhuǎn)載請聯(lián)系博主 ?? 如果文章對你有幫助、 歡迎關(guān)注、 點贊、 收藏(一鍵三連) 和 訂閱專欄 哦 目錄 前言 一、YOLOv5簡介 二、預(yù)處理 1.獲取分類名 2.獲取輸出層名稱 3.圖像尺度變換 三、模型加載

    2024年01月20日
    瀏覽(27)
  • yolov5檢測小目標(biāo)(附源碼)

    yolov5檢測小目標(biāo)(附源碼)

    6.30 更新切割后的小圖片的label數(shù)據(jù)處理 前言 yolov5大家都熟悉,通用性很強,但針對一些小目標(biāo)檢測的效果很差。 YOLOv5算法在訓(xùn)練模型的過程中,默認(rèn)設(shè)置的圖片大小為640x640像素(img-size),為了檢測小目標(biāo)時,如果只是簡單地將img-size改為4000*4000大小,那么所需要的內(nèi)存會變

    2024年02月03日
    瀏覽(19)
  • 【解惑筆記】樹莓派+OpenCV+YOLOv5目標(biāo)檢測(Pytorch框架)

    【解惑筆記】樹莓派+OpenCV+YOLOv5目標(biāo)檢測(Pytorch框架)

    ?-【學(xué)習(xí)資料】 子豪兄的零基礎(chǔ)樹莓派教程 https://github.com/TommyZihao/ZihaoTutorialOfRaspberryPi/blob/master/%E7%AC%AC2%E8%AE%B2%EF%BC%9A%E6%A0%91%E8%8E%93%E6%B4%BE%E6%96%B0%E6%89%8B%E6%97%A0%E7%97%9B%E5%BC%80%E6%9C%BA%E6%8C%87%E5%8D%97.md#%E7%83%A7%E5%BD%95%E9%95%9C%E5%83%8F 第2講:樹莓派新手無痛開機指南【子豪兄的樹莓派

    2024年02月14日
    瀏覽(19)
  • 【問題記錄】樹莓派+OpenCV+YOLOv5目標(biāo)檢測(Pytorch框架)

    【問題記錄】樹莓派+OpenCV+YOLOv5目標(biāo)檢測(Pytorch框架)

    ?-【學(xué)習(xí)資料】 子豪兄的零基礎(chǔ)樹莓派教程 https://github.com/TommyZihao/ZihaoTutorialOfRaspberryPi/blob/master/%E7%AC%AC2%E8%AE%B2%EF%BC%9A%E6%A0%91%E8%8E%93%E6%B4%BE%E6%96%B0%E6%89%8B%E6%97%A0%E7%97%9B%E5%BC%80%E6%9C%BA%E6%8C%87%E5%8D%97.md#%E7%83%A7%E5%BD%95%E9%95%9C%E5%83%8F 第2講:樹莓派新手無痛開機指南【子豪兄的樹莓派

    2024年02月02日
    瀏覽(28)
  • 基于YOLOv5 來訓(xùn)練頭盔目標(biāo)檢測-附源碼

    建筑工地頭部頭盔檢測,基于目標(biāo)檢測工地安全帽和禁入危險區(qū)域識別系統(tǒng),????附Y(jié)OLOv5訓(xùn)練自己的數(shù)據(jù)集超詳細(xì)教程?。。?目錄 指標(biāo) yolov5s 為基礎(chǔ)訓(xùn)練,epoch = 50 yolov5m 為基礎(chǔ)訓(xùn)練,epoch = 100

    2024年02月13日
    瀏覽(23)
  • Opencv C++實現(xiàn)yolov5部署onnx模型完成目標(biāo)檢測

    頭文件 命名空間 結(jié)構(gòu)體 Net_config 里面存了三個閾值和模型地址,其中 置信度 ,顧名思義,看檢測出來的物體的精準(zhǔn)度。以測量值為中心,在一定范圍內(nèi),真值出現(xiàn)在該范圍內(nèi)的幾率。 endsWith()函數(shù) 判斷sub是不是s的子串 anchors_640圖像接收數(shù)組 根據(jù)圖像大小,選擇相應(yīng)長度的

    2024年02月13日
    瀏覽(25)
  • 目標(biāo)檢測算法——YOLOv5/v7改進(jìn)之結(jié)合最強視覺識別模塊CotNet(Transformer)
  • 【YOLOv7/YOLOv5系列改進(jìn)NO.53】融入CFPNet網(wǎng)絡(luò)中的ECVBlock模塊,提升小目標(biāo)檢測能力

    作為當(dāng)前先進(jìn)的深度學(xué)習(xí)目標(biāo)檢測算法YOLOv7,已經(jīng)集合了大量的trick,但是還是有提高和改進(jìn)的空間,針對具體應(yīng)用場景下的檢測難點,可以不同的改進(jìn)方法。此后的系列文章,將重點對YOLOv7的如何改進(jìn)進(jìn)行詳細(xì)的介紹,目的是為了給那些搞科研的同學(xué)需要創(chuàng)新點或者搞工程

    2024年02月09日
    瀏覽(25)
  • yolov5 opencv dnn部署自己的模型

    yolov5 opencv dnn部署自己的模型

    github開源代碼地址 yolov5官網(wǎng)還提供的dnn、tensorrt推理鏈接 本人使用的opencv c++ github代碼,代碼作者非本人,也是上面作者推薦的鏈接之一 如果想要嘗試直接運行源碼中的yolo.cpp文件和yolov5s.pt推理sample.mp4,請參考這個鏈接的介紹 使用github源碼結(jié)合自己導(dǎo)出的onnx模型推理自己的

    2024年01月23日
    瀏覽(48)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包