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

Opencv-DNN模塊之官方指導:利用DNN模塊實現(xiàn)深度學習應(yīng)用:分類、分割、檢測、跟蹤等

這篇具有很好參考價值的文章主要介紹了Opencv-DNN模塊之官方指導:利用DNN模塊實現(xiàn)深度學習應(yīng)用:分類、分割、檢測、跟蹤等。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

本文根據(jù) Deep Learning with OpenCV DNN Module: A Definitive Guide 中相關(guān)內(nèi)容進行翻譯整理而得,用于今后的學習和工程。

?

§00 ??言
--- ??機器視覺研究領(lǐng)域從上個世紀六十年后期就已創(chuàng)立。圖像分類和物體檢測是計算機視覺領(lǐng)域中的一些最古老的的問題,研究者為解決它進行了幾十年的努力?;谏窠?jīng)網(wǎng)絡(luò)和深度學習計算機在某些領(lǐng)域中對圖像的認識和理解已經(jīng)達到了很高的精度,誰知在一些場合超過了人類。OpenCV中的DNN是學習神經(jīng)網(wǎng)絡(luò)和深度學校的非常棒的起點。由于OpenCV針對CPU進行算法性能上的提升,計時用戶沒有強大的GPU 也能夠非常容易的開始。

??希望這個博文能夠成為你學習深度學習算法的好的起點。

Opencv-DNN模塊之官方指導:利用DNN模塊實現(xiàn)深度學習應(yīng)用:分類、分割、檢測、跟蹤等

▲ 圖1 使用OpenCV中的DNN模塊基于深度學習實現(xiàn)圖像分類和目標檢測的示例圖像

??除了理論部分,我們還提供了基于OpenCV DNN的動手實驗經(jīng)驗。下面會討論圖片以及實時視頻中的分類、物體檢測算法細節(jié)。

??下面讓我們進入OpenCV DNN模塊實現(xiàn)深度學習解決機器視覺問題。

?

§01 OpenCVDNN模塊


??們知道OpenCV 是機器視覺最好的算法庫。此外它還能夠運行深度學習推理的功能。最棒的部分就是可以從不同的學習框架中加載不同的模型,通過它可以實現(xiàn)多個深度學習功能。 從OpenCV 3.3版本之后就提供了加載不同學習框架模型的支持。當然現(xiàn)在還有很多新的用戶并沒有注意到OpenCV這個超級棒的特性,這樣就可能丟失很多有趣和良好的學習機遇。

1.1 為什么選擇OpenCV DNN模塊?

??OpenCV只是支持圖片和視頻的深度學習推理,它并不只是模型的細調(diào)和訓練。盡管如此,OpenCV DNN模塊仍然可以作為初學者涉足機器視覺深度學習的非??斓钠鹗键c,進行鼓搗相關(guān)的算法。

??OpenCV 的DNN模塊中的 一個非常厲害之處就是針對Intel處理器進行了高度優(yōu)化。在目標檢測和圖像分割應(yīng)用中,對于實時視頻圖像進行模型推理的過程中可以獲得很好的處理幀速(FPS)。通過DNN模塊使用特定框架下預訓練模型經(jīng)常會得到更高的FPS。比如我們可以對比不同框架下的圖像分類處理速度。

Opencv-DNN模塊之官方指導:利用DNN模塊實現(xiàn)深度學習應(yīng)用:分類、分割、檢測、跟蹤等

▲ 圖1.1.1 圖像分類處理速度(三幅圖像的平均速度)

??上面就是對比了三中不同的框架下圖像分類的推理速度。

??上面的結(jié)果就是對于DenseNet121模型的推理時間的對比。令人驚訝的是 OpenCV比起在TensorFlow下的最初實現(xiàn)速度高了一大截,只是比Pytorch模型慢了那么一點點。實際操作中, Tensorflow推理時間大約1秒鐘,使用OpenCV的推理時間則小于200ms。

??上述對比結(jié)果使用了博文寫作時最新的OpenCV版本進行測量的。他們是:

對比結(jié)果軟件版本:

PyTorch:1.8.0
OpenCV:4.5.1
TensorFlow:2.4

??所有的測試都是在Google Colab中完成的,所使用的是Intel Xeon 2.3GHz處理器。

??在物體檢測中對比也是這樣。

Opencv-DNN模塊之官方指導:利用DNN模塊實現(xiàn)深度學習應(yīng)用:分類、分割、檢測、跟蹤等

▲ 圖1.1.2 視頻中物體檢測幀速對比

??基于CPU對比不同學習框架模型在物體檢測中的速度。

??上面圖標顯示了利用 Tiny YOLOv4 在原始Karknet框架以及OpenCV上處理視頻中的目標檢測速度。性能指標是在Gen Laptop CPU(2.6GHz 時鐘頻率)下進行測量的??梢钥吹綄τ谙嗤囊曨l OpenCV的DNN模塊可以達到35FPS,但Darknet利用OpenMP和AVX編譯后的模型只能達到15FPS。 如果DarkNet不使用OpenMP, AVX進行優(yōu)化,運行Tiny YOLOv4只能達到3FPS。考慮到我們使用的原始Darknet Tiny YOLOv4模型在兩種情況下的對比,這種差別是非常巨大的。

??上圖顯示了OpenCV DNN模塊在CPU工作環(huán)境下的實用性和強大能力。在CPU上的快速推理使其可以在算力受限的情況下作為邊端設(shè)備部署網(wǎng)絡(luò)模型的優(yōu)異工具。 基于ARM處理器的邊端設(shè)備就是一個最好的例證。下面的圖表說明了這一切:

Opencv-DNN模塊之官方指導:利用DNN模塊實現(xiàn)深度學習應(yīng)用:分類、分割、檢測、跟蹤等

▲ 圖1.1.3 在Raspberry Pi 3B運行的不同框架下不同模型的處理速度對比圖

??從上圖可以看到不同的狂階我和模型在Reapberry Pi 3B中運行速度的對比。對比結(jié)果非常顯著。在SqueezeNet, MObileNet模型中, OpenCV比其他框架在處理速度上逗號。 對于GoogLeNet,OpenCV性能排在第二,TensorFlow的性能最好。 對于Network,OpenCV RasPBerryrFPS性能最差。

??上面幾個圖標顯示了優(yōu)化后的OpenCV 對于神經(jīng)網(wǎng)絡(luò)推理的速度是多么的快。因此也說明了為什么學習OpenCV DNN的理由。

1.2 OpenCV NN提供的深度學習功能

??我們知道利用OpenCV DNN模塊我們可以對圖像和視頻完成基于深度學習的計算機視覺推理。下面看看OpenCV DNN所支持的功能列表。令人感興趣的時候我們所有想到大多數(shù)的深度學習和計算機視覺任務(wù)OpenCV DNN都支持, 下面列表證明了這個想法:
??1. 圖像分類;
??2. 目標檢測;
??3. 圖像分割;
??4. 文字檢測和識別;
??5. 姿態(tài)估計;
??6. 深度估計
??7. 人臉驗證和檢測;
??8. 人體重新識別;

??上面全面的列表給出了很多深度學習實際應(yīng)用場景??梢酝ㄟ^訪問 OpenCV 功能庫 WiKi 網(wǎng)頁 中相關(guān)信息了解更多內(nèi)容。

??重要的是很多模塊的選擇依賴于系統(tǒng)硬件,計算能力(后面我們將會討論)。 對于每種應(yīng)用,可以通過選擇當今最好的但計算復雜模型 到 可以運行在邊端(嵌入式)設(shè)備中的簡易模型。

??顯然在一個博文中很難對上面所列寫的各種模型都討論到。因此,我們選擇目標檢測和人體姿態(tài)估計進行詳細討論,來初步了解在OpenCV DNN模塊中如何進行模型選擇。

1.2.1 OpenCV DNN支持的不同模型列表

??為了支持上面討論的應(yīng)用,我們需要很多預先訓練好的模型。而且的確存在著一些可供選擇的SOTA 模型。下面表格列出了用于不同場合的深度學習模型。

Image Classification Object Detection Image Segmentation Text detection and recognition Human Pose estimation Person and face detection
Alexnet MobileNet SSD DeepLab Easy OCR Open Pose Open Face
GoogLeNet VGG SSD UNet CRNN Alpha Pose Torchreid
VGG Faster R-CNN FCN ? ? Mobile FaceNet
ResNet EfficientDet ? ? ? OpenCV
FaceDetector
SqueezeNet ? ? ? ? ?
DenseNet ? ? ? ? ?
ShuffleNet ? ? ? ? ?
EfficientNet ? ? ? ? ?

??上面的表格雖然給出的模型很多但并未窮盡OpenCV DNN模塊中所有的模型。仍然還有很多網(wǎng)絡(luò)模型上述表格中并沒有給出。就像前面所示,列出所有模型并進行討論在一個博文中無法完成。上述表格只是告訴我們一個可行的方法去何選擇計算機視覺中不同的深度學習模型。

1.3 OpenCVDNN 支持的深度學習框架

??看到上面各種模型,腦子突然蹦出一個問題:是不是這些模型都可以由一個單一框架支持?實際上,并不是這樣。

??OpenCV DNN支持很多流行的深度學習框架。下面鋸齒OpenCV DNN中所支持的深度學習框架。

1.3.1 Caffe

??在利用OpenCV DNN 調(diào)用Caffe中的預訓練模型是,我們需要狂歌事情。一個就是 model.caffemodel 文件,其中包含了預訓練權(quán)重。 另外一個就是模型架構(gòu)穩(wěn)健,后綴為 。prototxt。 這是一個JSON結(jié)構(gòu)類似的問唄文件,包含了所有的網(wǎng)絡(luò)層的定義。如果想得到這個文件清晰的結(jié)構(gòu),可以訪問 這個鏈接

1.3.2 TensorFlow

??使用基于TensorFlow預訓練的模型,我們需要兩個文件。 一個是模型權(quán)重參數(shù)文件,另一個是定義有模型配置的protobuf文件。權(quán)重參數(shù)文件的后綴為 .pd,也就是protobuf文件,存儲有所有預訓練的網(wǎng)絡(luò)參數(shù)。 如果之前你使用過TensorFlow,你知道 .pb 文件就是模型的檢查點,即 在模型存儲以及權(quán)系數(shù)固定之后存儲的文件。 模型配置在 protobuf文件中,具有 .pbtxt 文件后綴。

??注意:在Tensorflow的新的版本中,網(wǎng)絡(luò)參數(shù)文件不再使用 .pb的文件格式。如果你使用自己存儲的模型的話,文件的格式可能是 .ckpt 或者 .h5 格式,此時在使用OpenCV DNN之前需要一些中間步驟進行處理。這種情況下,帥看到模型轉(zhuǎn)換成 ONNX格式,然后在轉(zhuǎn)換成 .pb格式,這樣可以保證所有結(jié)果都和所期望的那樣。

1.3.3 Torch和PyTorch

??為了載入Torch 模型文件,我們需要包含有預訓練權(quán)重參數(shù)的文件。通常這個文件具有 .t7 或者 .net的文件后綴。最新的Torch版本的網(wǎng)絡(luò)模型具有 .pth 的文件后綴。將這些文件首先轉(zhuǎn)換成 ONNX是最好的處理方法。轉(zhuǎn)換成ONNX文件之后,你可以直接通過OpenCV DNN所支持的ONNX模型方式載入網(wǎng)絡(luò)。

1.3.4 Darknet

??OpenCV DNN 也支持著名的 DarkNet學習框架。 如果你使用過官方的基于Darknet學習框架的YOLO模型就可以了解這一點。

??通常,我們通過具有 .weights 后綴的文件來載入 Darknet模型。Darknet模型的網(wǎng)絡(luò)配置文件的后綴是 .cfg。

1.3.5 轉(zhuǎn)換成ONNX格式

??可以通過軟件工具將來自于 Keras 或者Pytorch的網(wǎng)絡(luò)模型轉(zhuǎn)換成 ONNX 格式文件。在OpenCV DNN 中不能夠直接使用來自于Keras, Pytorch學習框架中的網(wǎng)絡(luò)模型。通常將這些模型轉(zhuǎn)換成ONNX的格式(Open Neural Network Exchange),這樣可以使用他們,甚至將它們轉(zhuǎn)換成其他學習框架中的模型,比如 TensorFlow, PyTorch。

??在OpenCV DNN中我們需要后綴為 .onnx 的權(quán)重參數(shù)文件來載入 ONNX 模型。

??通過訪問 OpenCV 官方文件 來了解不同的學習框架,他們權(quán)重闡述文件以及配置文件。

??最有可能的是,上面所列舉的包括有所有著名深度學習框架。通過訪問 官方Wiki網(wǎng)頁 了解OpenCV DNN所支持的完整學習框架思想。

??這里所見到的所有模型都是經(jīng)過OpenCV DNN 模塊完美測試過的。理論上,前面所有學習框架下的網(wǎng)絡(luò)都可以在DNN模塊中工作。我們只需要找到正確的權(quán)重參數(shù)文件以及相應(yīng)的神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)文件即可。通過本教程的代碼部分就可以清楚所有的事情了。

??我們將會覆蓋足夠的理論。下面進入博文的代碼部分。首先我們需要一個圖像分類的完整OpenCV DNN的使用過程。接著就是基于DNN模塊的目標檢測。

?

§02 圖像分類


??是一個基于OpenCV DNN軟件模塊的圖像分類的完整指導書。

2.1 網(wǎng)絡(luò)模型

??在這部分,我們將使用OpenCV DNN 模塊完成圖像的分類。對于每一部將會講解,完成整個程序之后你就會對所有的過程了如指掌。

??我們將使用在Caffe學習框架中的神經(jīng)網(wǎng)絡(luò)模型,它在著名數(shù)據(jù)集 ImageNet上經(jīng)過預訓練。使用 NeseNet121神經(jīng)網(wǎng)絡(luò)完成分類任務(wù)。 這個模型的優(yōu)勢在于它經(jīng)過了包含有1000中物品的ImageNet數(shù)據(jù)集合訓練,所以不管我們想要分類什么物品,它早已包含在模型中了。這讓我們可以在更大的范圍內(nèi)選擇圖像。

??我們將使用下面的圖像進行分類。

Opencv-DNN模塊之官方指導:利用DNN模塊實現(xiàn)深度學習應(yīng)用:分類、分割、檢測、跟蹤等

▲ 圖2.1 將用于OpenCV DNN 模型進行圖像分類的樣例圖像

2.2 實現(xiàn)步驟

??簡單來講,我們將采用以下步驟完成圖像分類。
??1. 從磁盤讀入文件的名稱,獲取所需標簽;
??2. 從磁盤讀入預訓練的神經(jīng)網(wǎng)絡(luò);
??3. 但圖片讀入并轉(zhuǎn)換成深度學習網(wǎng)絡(luò)所需要的正確格式;
??4. 把輸入圖像在網(wǎng)絡(luò)中前向傳遞獲得網(wǎng)絡(luò)的輸出結(jié)果;

??下面我們通過代碼來演示每一步的操作

2.2.1 導入模型并加載類別文本文件

??對于Python編程,我們需要載入OpenCV 和Numpy模塊。對于C++來說,我們需要包括 OpenCV, OpenCV DNN 的靜態(tài)庫。

  • Python
import cv2
import numpy as np
  • C++
#include <iostream>
#include <fstream>
#include <opencv2/opencv.hpp>
#include <opencv2/dnn.hpp>
#include <opencv2/dnn/all_layers.hpp>
 
using namespace std;
using namespace cv;
using namespace dnn;

??記住,所使用的 DenseNet21 模型已經(jīng)在1000中類別的ImageNet數(shù)據(jù)集合進行預訓練過。所以需要將這1000中物品調(diào)入內(nèi)存這樣便于訪問它們,通常這些類別信息存儲在TEXT文件中。 其中一個這種文件為:classification_classes_ILSVRC2012.txt 文件。包含有所有的類別名稱,格式如下:

tench, Tinca tinca
goldfish, Carassius auratus
great white shark, white shark, man-eater, man-eating shark, Carcharodon carcharias
tiger shark, Galeocerdo cuvieri
hammerhead, hammerhead shark
...

??文件的每一行包含有所有針對一個圖片的所有標簽或者類別名稱。比如,第一行包括有 tench, Tinca Tinca。對于這個同樣的魚它有兩個名字。類似,第二行也是對應(yīng)的金魚有兩個名稱。 通常情況下第一個名稱是被大多數(shù)人最常用到的名字。

??下面我們展示如何將text文件讀入內(nèi)存,并將第一個名稱抽取出來作為圖像分類的標簽。

  • Python
# read the ImageNet class names
with open('../../input/classification_classes_ILSVRC2012.txt', 'r') as f:
   image_net_names = f.read().split('\n')
# final class names (just the first word of the many ImageNet names for one image)
class_names = [name.split(',')[0] for name in image_net_names]

  • C++
std::vector<std::string> class_names;
   ifstream ifs(string("../../input/classification_classes_ILSVRC2012.txt").c_str());
   string line;
   while (getline(ifs, line))
   {
       class_names.push_back(line);
   } 

??首先,我們通過讀入模式打開包含有所有類別名稱的文件,將它們分割成新的一行行文本。現(xiàn)在將所有的類都安裝下面的格式存儲在 image_net_names 列表中。

[‘tench, Tinca tinca’, ‘goldfish, Carassius auratus’, ‘great white shark, white shark, man-eater, man-eating shark’, ...]

 
 
  • 1

??然而對于每一行,我們只需要第一個名稱。這就是第二句代碼的功能。對于 image_net_names列表中每個元素,將它們使用逗號(,)作為分隔符號進行分割,只保留第一個元素即可。這些名稱存儲在 class_names的列表中。至此,這個名稱列表看起來為:

['tench', 'goldfish', 'great white shark', 'tiger shark', 'hammerhead',]

 
 
  • 1

2.2.2 從磁盤載入預訓練的DenseNet121

??正如前面所述,我們使用在Caffe學習框架中已經(jīng)預訓練好的DenseNet121網(wǎng)絡(luò)。 我們需要相應(yīng)的模型權(quán)重文件(.caffemodel)以及模型配置文件(.prototxt)。

??下面看一下相應(yīng)的代碼并對載入模型的部分進行解釋。

  • Python
# load the neural network model
model = cv2.dnn.readNet(model='../../input/DenseNet_121.caffemodel',
    config='../../input/DenseNet_121.prototxt', framework='Caffe')
  • C++
// load the neural network model
   auto model = readNet("../../input/DenseNet_121.prototxt",
                       "../../input/DenseNet_121.caffemodel",
                       "Caffe");

??你可以看到我們使用了OpenCV DNN中的 readNet() 函數(shù),這個函數(shù)需要提供如下輸入?yún)?shù):

  • odel: This is the path to the pre-trained weights file. In our case, it is the pre-trained Caffe model.
  • config: This is the path to the model configuration file and it is the Caffe model’s .prototxt file in this case.
  • framework: Finally, we need to provide the framework name that we are loading the models from. For us, it is the Caffe framework.

??除了 readNet() 函數(shù)之外, DNN模塊還提供了從特定學習框架中載入模型的函數(shù)。這些函數(shù)無需提供 framework 參數(shù),下面給出了這些函數(shù):

  • readNetFromCaffe(): This is used to load pre-trained Caffe models and accepts two arguments. They are the path to the prototxt file and the path to the Caffe model file.
  • readNetFromTensorflow(): We can use this function to directly load the TensorFlow pre-trained models. This also accepts two arguments. One is the path to the frozen model graph and the other is the path to the model architecture protobuf text file.
  • readNetFromTorch(): We can use this to load Torch and PyTorch models which have been saved using the torch.save() function. We need to provide the model path as the argument.
  • readNetFromDarknet(): This is used to load the models trained using the DarkNet framework. We need to provide two arguments here as well. One of the path to the model weights and the other is the path to the model configuration file.
  • readNetFromONNX(): We can use this to load ONNX models and we only need to provide the path to the ONNX model file.

??本文中使用 readNet() 來載入預訓練好的模型。后面在目標檢測中也是用readNet()函數(shù)。

2.2.3 讀入圖片并轉(zhuǎn)換成網(wǎng)絡(luò)輸入格式

??我們通過 OpenCV中的 imread() 函數(shù)讀入圖片。注意,有些細節(jié)需要我們關(guān)注。使用DNN 模塊載入的預訓練好的模型并不能夠直接使用讀入圖像數(shù)據(jù)。需要預先進行預處理一下。

??下面讓我們先把代碼碼好,這樣就比較容易討論技術(shù)細節(jié)了。

  • Python
# load the image from disk
image = cv2.imread('../../input/image_1.jpg')
# create blob from image
blob = cv2.dnn.blobFromImage(image=image, scalefactor=0.01, size=(224, 224), mean=(104, 117, 123))

  • C++
// load the image from disk
Mat image = imread("../../input/image_1.jpg");
// create blob from image
Mat blob = blobFromImage(image, 0.01, Size(224, 224), Scalar(104, 117, 123));

??在讀取文件之前,我們假設(shè)讀入的圖像在 input 目錄中,該目錄在當前目錄前兩級父目錄中。下面的步驟非常重要,使用 blobFromImage() 函數(shù),將輸入圖像轉(zhuǎn)換成模型所需要的格式。下面是函數(shù)參數(shù)的解釋:

  • image: This is the input image that we just read above using the imread() function.
  • calefactor: This value scales the image by the provided value. It has a default value of 1 which means that no scaling is performed.
  • ize: This is the size that the image will be resized to. We have provided the size as 224×224 as most classification models trained on the ImageNet dataset expect this size only.
  • an: The mean argument is pretty important. These are actually the mean values that are subtracted from the image’s RGB color channels. This normalizes the input and makes the final input invariance to different illumination scales.

??有一個事情想需要提一下。那就是所有的深度學習模型都希望輸入數(shù)據(jù)都是成批次的。然而這里我們只有一張圖片。不管怎樣, blob 的輸出格式我們得到的矩陣為[1,3,224,224],blockFromImage() 函數(shù)輸出的結(jié)果是在原來的彩色圖像(3維)的基礎(chǔ)上又增加了一維。這就是神經(jīng)網(wǎng)絡(luò)模型所需要到正確輸入格式。

2.2.4 將輸入圖像在模型中前向傳播

??現(xiàn)在網(wǎng)絡(luò)輸入已經(jīng)準備好了,我們可以利用網(wǎng)絡(luò)進行預測了,這個過程也是吧輸入圖像在網(wǎng)絡(luò)各層中前向進行傳播。

  • Python
# set the input blob for the neural network
model.setInput(blob)
# forward pass image blog through the model
outputs = model.forward()

網(wǎng)絡(luò)預測需要兩個步驟:

  • 首先,將網(wǎng)絡(luò)的輸入中加載圖像數(shù)據(jù);
  • 接著使用forward()函數(shù)將輸入數(shù)據(jù)前向通過網(wǎng)絡(luò)模型,可以獲得網(wǎng)絡(luò)所有的輸出。

上面的代碼就是完成了兩個步驟。

在 outputs 中存儲著網(wǎng)絡(luò)的所有輸出。在獲得正確的分類類別之前,還有一些需要與處理得步驟。

現(xiàn)在 outputs 還是一個向量 (1,1000,1,1,)。從其中抽取對應(yīng)的類別還比較困難。因此,下面的代碼,將 outputs進行重新排列,這里便于我們獲得正確的類別標簽并通過 label ID 映射到類別名稱。

  • python
final_outputs = outputs[0]
# make all the outputs 1D
final_outputs = final_outputs.reshape(1000, 1)
# get the class label
label_id = np.argmax(final_outputs)
# convert the output scores to softmax probabilities
probs = np.exp(final_outputs) / np.sum(np.exp(final_outputs))
# get the final highest probability
final_prob = np.max(probs) * 100.
# map the max confidence to the class label names
out_name = class_names[label_id]
out_text = f"{out_name}, {final_prob:.3f}"
# put the class name text on top of the image
cv2.putText(image, out_text, (25, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
cv2.imshow('Image', image)
cv2.waitKey(0)
cv2.imwrite('result_image.jpg', image)

  • C++
// set the input blob for the neural network
model.setInput(blob);
// forward pass the image blob through the model
Mat outputs = model.forward(); 
Point classIdPoint;
double final_prob;
minMaxLoc(outputs.reshape(1, 1), 0, &final_prob, 0, &classIdPoint);
int label_id = classIdPoint.x; 
// Print predicted class.
string out_text = format("%s, %.3f", (class_names[label_id].c_str()), final_prob);
// put the class name text on top of the image
putText(image, out_text, Point(25, 50), FONT_HERSHEY_SIMPLEX, 1, Scalar(0, 255, 0), 2);
imshow("Image", image);
imwrite("result_image.jpg", image);

??Outputs 經(jīng)過變形(reshape)之后,形成 (1000,1)的形狀,表示一個1000行,1列的矩陣,每一行對應(yīng)的一個類別的得分,對應(yīng)的數(shù)值舉例為:

[[-1.44623446e+00]
[-6.37421310e-01]
 [-1.04836571e+00]
 [-8.40160131e-01]]

??從其中查找到最大的一個類別所在的行,將其存儲在 label_id 中。注意,這里的得分并不是真正意義上的概率。我們需要通過 softmax 來獲得最高得分標簽所對應(yīng)的分類概率。

??在上面的Python代碼中,我們使用下面的代碼進行了 softmax概率轉(zhuǎn)換。

np.exp(final_outputs) / np.sum(np.exp(final_outputs))

 
 
  • 1

??然后,將最高得分概率乘以100,得到預測分數(shù)的百分比。

??最后一步就是在圖像上標注出預測類別名稱以及對應(yīng)的百分比。我們將圖像進行顯示并存儲在磁盤上。

??在執(zhí)行完代碼之后,我們可以獲得下面的輸出。

Opencv-DNN模塊之官方指導:利用DNN模塊實現(xiàn)深度學習應(yīng)用:分類、分割、檢測、跟蹤等

▲ 圖2.2.1 DenseNet121網(wǎng)絡(luò)的輸出結(jié)果:名稱Tiger,預測的分:91.030

??上面的結(jié)果顯示通過DenseNet121對于輸入的圖像進行預測,種類為Tiger,概率為91%,這是一個相當不錯的分類結(jié)果。

??通過上面的討論,我們知道如何通過 OpenCV DNN模塊來進行圖像分類,所使用的網(wǎng)絡(luò)為 DenseNet121。通過對于每一部的討論我們很好了解了DNN模塊工作的細節(jié)。

??下面我們將使用 OpenCV DNN 模塊完成目標檢測任務(wù)。

?

§03 目標檢測


??使用OpenCV DNN模塊我們可以比較輕松的在深度學習和機器視覺中完成目標檢測任務(wù)。就像分類一樣,我們需要載入圖像,適當?shù)哪P?,將輸入在模型中前向傳輸獲得預測結(jié)果。只是對于目標檢測任務(wù)的預處理過程和對結(jié)果進行標注顯示部分略有不同而已。通過下面博文我們會展示所有實現(xiàn)細節(jié)。

??我們先從圖像中物品檢測開始。

3.1 利用OpenCV DNN進行物體檢測

??與圖像分類一樣,這里我們還是使用預先訓練好的模型。 這個模型在MS COCO數(shù)據(jù)集合上已經(jīng)預先訓練好了,這也是當前深度學習中的物體檢測算法測試數(shù)據(jù)集合。

??MS COCO可以檢測大約80個種類的物體。包括有 人、小轎車、牙刷等。數(shù)據(jù)集合中包含了日常所能碰到的80中物品。通過TEXT文件載入MS COCO 數(shù)據(jù)集合中的所有類別標簽用于后面的物體檢測。

??下面的圖片用于物體檢測算法。
Opencv-DNN模塊之官方指導:利用DNN模塊實現(xiàn)深度學習應(yīng)用:分類、分割、檢測、跟蹤等

▲ 圖3.1 用于物體檢測的圖片。圖片中包含有多種物體的聚集,包括有人物,自行車,雙輪車等。這對測試模型的性能非常好

??我們使用 MobileNet SSD(Single Shot Detector)模型,它在MS COCO數(shù)據(jù)集合利用TensorFlow深度學習框架進行訓練過。SSD模型相對于其他物體檢測來說運行速度比較快。而且,MobileNet 基礎(chǔ)網(wǎng)絡(luò)也使得它的計算量較小。因此,這也是一個學習OpenCV DNN 進行物體檢測的一個良好的開始網(wǎng)絡(luò)。

??下面看看相應(yīng)的實現(xiàn)代碼。

  • Python
import cv2
import numpy as np
  • C++
#include <iostream>
#include <fstream>
#include <opencv2/opencv.hpp>
#include <opencv2/dnn.hpp>
#include <opencv2/dnn/all_layers.hpp>
 
using namespace std;
using namespace cv;
using namespace dnn;
  • 在Python語言代碼中,我們導入 cv2, numpy軟件模塊;

  • 在 C++中,導入 OpenCV, OpenCV DNN 庫頭文件;

  • Python

# load the COCO class names
with open('object_detection_classes_coco.txt', 'r') as f:
   class_names = f.read().split('\n')
 
# get a different color array for each of the classes
COLORS = np.random.uniform(0, 255, size=(len(class_names), 3))

  • C++
std::vector<std::string> class_names;
   ifstream ifs(string("../../../input/object_detection_classes_coco.txt").c_str());
string line;
while (getline(ifs, line))
{
    class_names.push_back(line);
}

??接下來我們讀入 object_detection_classes_coco.txt文件,其中每一行包含有所有類別名稱。將它們存儲在class_names列表中。

??class_names列表的內(nèi)容如下:

['person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus', 'train', 'truck', 'boat', 'traffic light','book', 'clock', 'vase', 'scissors', 'teddy bear', 'hair drier', 'toothbrush', '']

 
 
  • 1

??此外,我們利用 COLORS數(shù)組來獲得一些元組陣列,每個元組包含有三個隨機的整型數(shù)字,表示了隨機的顏色。他們將會在后面用于框定每個種類目標。 對于不同的類別物品我們最好使用不同的顏色,這將便于我們在最后的圖像結(jié)果中來區(qū)分不同的種類物品。

3.1.1 載入MobileNet模型并準備輸入

??通過 readNet()載入 MobileNet SSD 模型,這個函數(shù)前面我們是用過。

  • Python
# load the DNN model
model = cv2.dnn.readNet(model='frozen_inference_graph.pb', 
               config='ssd_mobilenet_v2_coco_2018_03_29.pbtxt.txt',framework='TensorFlow')
  • C++
// load the neural network model
auto model = readNet("../../../input/frozen_inference_graph.pb",
"../../../input/ssd_mobilenet_v2_coco_2018_03_29.pbtxt.txt", "TensorFlow");

??上面的代碼中:

  • 模型參數(shù)接收固定推理圖文件路徑, 與訓練模型包含有網(wǎng)絡(luò)權(quán)重參數(shù);
  • config 參數(shù)接收模型配置文件路徑,這是一個 protobuf 文本文件包含有網(wǎng)絡(luò)的配置信息;
  • 最后,通過聲明 frameworkwz='TensorFlow’,來表明模型預訓練的學習框架;

??接下來,我們單從磁盤讀入圖片并進行格式轉(zhuǎn)換,形成網(wǎng)絡(luò)的輸入。

  • Python
# read the image from disk
image = cv2.imread('../../input/image_2.jpg')
image_height, image_width, _ = image.shape
# create blob from image
blob = cv2.dnn.blobFromImage(image=image, size=(300, 300), mean=(104, 117, 123), swapRB=True)
# set the blob to the model
model.setInput(blob)
# forward pass through the model to carry out the detection
output = model.forward()

  • C++
// read the image from disk
Mat image = imread("../../../input/image_2.jpg");
int image_height = image.cols;
int image_width = image.rows;
//create blob from image
Mat blob = blobFromImage(image, 1.0, Size(300, 300), Scalar(127.5, 127.5, 127.5),true, false);
//create blob from image
model.setInput(blob);
//forward pass through the model to carry out the detection
Mat output = model.forward();
Mat detectionMat(output.size[2], output.size[3], CV_32F, output.ptr<float>());

??對于目標檢測,我們使用 blobFromImage()函數(shù)中的 位差別參數(shù)。

  • 輸入尺寸為 300×300,這是SSD模型在所有訓練框架中所期望的輸入尺寸。對于TensorFlow也是一樣的。
  • 使用 swapRB參數(shù),進行顏色通道轉(zhuǎn)換。在OpenCV中,彩色圖像使用BGR格式,但對于目標檢測網(wǎng)絡(luò)則希望輸入為RGB格式。所以 swapRB參數(shù)將交換R,B顏色通道使其成為RGB格式。

3.1.2 網(wǎng)絡(luò)結(jié)果輸出

??將數(shù)據(jù)設(shè)置為MobileNet SSD網(wǎng)絡(luò)的輸入塊,并前向傳播,使用forward() 函數(shù)完成網(wǎng)絡(luò)預測。

??output數(shù)據(jù)結(jié)構(gòu)為:

[[[[0.00000000e+00 1.00000000e+00 9.72869813e-01 2.06566155e-02 1.11088693e-01 2.40461200e-01 7.53399074e-01]]]]

 
 
  • 1
  • 索引1包含有所有類別標簽,從1 到80.
  • 索引2 包含有置信得分。雖然并不是概率,也代表了模型對于物體所屬種類的置信度。
  • 最后四個數(shù)值,前兩個是x,y,表示物體置框位置坐標,后兩個代表框的寬和高度。

3.1.3 循環(huán)檢測所有目標并進行標定

??下面對于output中的所有檢測結(jié)果并使用方框進行標注。下面代碼演示了對檢測結(jié)果循環(huán)標注過程。

  • Python
# loop over each of the detection
for detection in output[0, 0, :, :]:
   # extract the confidence of the detection
   confidence = detection[2]
   # draw bounding boxes only if the detection confidence is above...
   # ... a certain threshold, else skip
   if confidence > .4:
       # get the class id
       class_id = detection[1]
       # map the class id to the class
       class_name = class_names[int(class_id)-1]
       color = COLORS[int(class_id)]
       # get the bounding box coordinates
       box_x = detection[3] * image_width
       box_y = detection[4] * image_height
       # get the bounding box width and height
       box_width = detection[5] * image_width
       box_height = detection[6] * image_height
       # draw a rectangle around each detected object
       cv2.rectangle(image, (int(box_x), int(box_y)), (int(box_width), int(box_height)), color, thickness=2)
       # put the FPS text on top of the frame
       cv2.putText(image, class_name, (int(box_x), int(box_y - 5)), cv2.FONT_HERSHEY_SIMPLEX, 1, color, 2)
 
cv2.imshow('image', image)
cv2.imwrite('image_result.jpg', image)
cv2.waitKey(0)
cv2.destroyAllWindows()

  • C++
for (int i = 0; i < detectionMat.rows; i++){
       int class_id = detectionMat.at<float>(i, 1);
       float confidence = detectionMat.at<float>(i, 2);
      
       // Check if the detection is of good quality
       if (confidence > 0.4){
           int box_x = static_cast<int>(detectionMat.at<float>(i, 3) * image.cols);
           int box_y = static_cast<int>(detectionMat.at<float>(i, 4) * image.rows);
           int box_width = static_cast<int>(detectionMat.at<float>(i, 5) * image.cols - box_x);
           int box_height = static_cast<int>(detectionMat.at<float>(i, 6) * image.rows - box_y);
           rectangle(image, Point(box_x, box_y), Point(box_x+box_width, box_y+box_height), Scalar(255,255,255), 2);
           putText(image, class_names[class_id-1].c_str(), Point(box_x, box_y-5), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0,255,255), 1);
       }
   }   
 
   imshow("image", image);
   imwrite("image_result.jpg", image);
   waitKey(0);
   destroyAllWindows();

  • 在 for循環(huán)中,我們抽取了當前檢測目標的置信度,這可以通過索引2來獲得;
  • 接著通過if來判斷物體的置信度是否高于一個閾值。對于那些置信度改與0.4 的結(jié)果進一步處理;
  • 獲得類別的ID,并映射到MS COCO 類別名稱列表。獲得單個用的對于當前種類繪制它的位置方框,并在方框頂部放置類別名稱;
  • 通過抽取方框位置和寬高獲得對應(yīng)的矩形參數(shù);
  • 最后一步在圖像中繪制矩形,并在矩形上部輸出類別文字。

??這就是使用OpenCV DNN進行物體檢測所有步驟。執(zhí)行完代碼可以獲得如下的結(jié)果:

Opencv-DNN模塊之官方指導:利用DNN模塊實現(xiàn)深度學習應(yīng)用:分類、分割、檢測、跟蹤等

▲ 圖3.1.2 利用MobileNet SSD進行物體檢測。模型將圖片中幾乎所有的物體都進行了檢測,然而可以注意到一些檢測結(jié)果是錯誤的

??在上面的檢測結(jié)果圖像中,可以看到效果還是不錯的。網(wǎng)絡(luò)模型將圖片中的所有可見物體都進行了檢測。然后也存在著一些錯誤的預測。比如 MobileNet SSD模型把右側(cè)的自行車標注成摩托車。 MobileNet SSD 模型在應(yīng)用于實際場景中,為了加快速度有可能會產(chǎn)生更多的這類錯誤。

??上面是在圖片中進行物體檢測。為了使得對OpenCV DNN模塊了解更多,下面我們在視頻中進行物體檢測。

3.2 視頻中物體檢測

??在視頻中檢測物體的代碼與圖像中物體檢測相同,只是進行少數(shù)的變化。

??實現(xiàn)代碼中有少量的代碼與圖像物體檢測是一樣的。下面先完成這部分。

  • Python
import cv2
import time
import numpy as np
 
# load the COCO class names
with open('object_detection_classes_coco.txt', 'r') as f:
   class_names = f.read().split('\n')
 
# get a different color array for each of the classes
COLORS = np.random.uniform(0, 255, size=(len(class_names), 3))
 
# load the DNN model
model = cv2.dnn.readNet(model='frozen_inference_graph.pb',                        config='ssd_mobilenet_v2_coco_2018_03_29.pbtxt.txt',framework='TensorFlow')
 
# capture the video
cap = cv2.VideoCapture('../../input/video_1.mp4')
# get the video frames' width and height for proper saving of videos
frame_width = int(cap.get(3))
frame_height = int(cap.get(4))
# create the `VideoWriter()` object
out = cv2.VideoWriter('video_result.mp4', cv2.VideoWriter_fourcc(*'mp4v'), 30, (frame_width, frame_height))

  • C++
#include <iostream>
#include <fstream>
#include <opencv2/opencv.hpp>
#include <opencv2/dnn.hpp>
#include <opencv2/dnn/all_layers.hpp>
 
using namespace std;
using namespace cv;
using namespace dnn;
 
int main(int, char**) {
   std::vector<std::string> class_names;
   ifstream ifs(string("../../../input/object_detection_classes_coco.txt").c_str());
   string line;
   while (getline(ifs, line))
   {
       class_names.push_back(line);
   } 
  
   // load the neural network model
   auto model = readNet("../../../input/frozen_inference_graph.pb",
"../../../input/ssd_mobilenet_v2_coco_2018_03_29.pbtxt.txt","TensorFlow");
 
   // capture the video
   VideoCapture cap("../../../input/video_1.mp4");
   // get the video frames' width and height for proper saving of videos
   int frame_width = static_cast<int>(cap.get(3));
   int frame_height = static_cast<int>(cap.get(4));
   // create the `VideoWriter()` object
   VideoWriter out("video_result.avi", VideoWriter::fourcc('M', 'J', 'P', 'G'), 30, Size(frame_width, frame_height));

??可以看到代碼絕大部分是相同的。 我們使用了相同的 MS COCO 類別文件,以及 MobileNet SSD模型。

??取代圖像讀取,我們使用 VideoCapture()對象來捕獲視頻幀。我們也創(chuàng)建了 VideoWrite() 對象,用于存儲視頻幀。

3.2.1 對于視頻每一幀進行物體檢測

??到現(xiàn)在為止,我們已經(jīng)準備好了視頻,MobileNet SSD 網(wǎng)絡(luò)模型。下面就是對于視頻的每一幀都進行物體檢測,這里把視頻幀看成一幅幅圖像。

  • Python
# detect objects in each frame of the video
while cap.isOpened():
   ret, frame = cap.read()
   if ret:
       image = frame
       image_height, image_width, _ = image.shape
       # create blob from image
       blob = cv2.dnn.blobFromImage(image=image, size=(300, 300), mean=(104, 117, 123), swapRB=True)
       # start time to calculate FPS
       start = time.time()
       model.setInput(blob)
       output = model.forward()       
       # end time after detection
       end = time.time()
       # calculate the FPS for current frame detection
       fps = 1 / (end-start)
       # loop over each of the detections
       for detection in output[0, 0, :, :]:
           # extract the confidence of the detection
           confidence = detection[2]
           # draw bounding boxes only if the detection confidence is above...
           # ... a certain threshold, else skip
           if confidence > .4:
               # get the class id
               class_id = detection[1]
               # map the class id to the class
               class_name = class_names[int(class_id)-1]
               color = COLORS[int(class_id)]
               # get the bounding box coordinates
               box_x = detection[3] * image_width
               box_y = detection[4] * image_height
               # get the bounding box width and height
               box_width = detection[5] * image_width
               box_height = detection[6] * image_height
               # draw a rectangle around each detected object
               cv2.rectangle(image, (int(box_x), int(box_y)), (int(box_width), int(box_height)), color, thickness=2)
               # put the class name text on the detected object
               cv2.putText(image, class_name, (int(box_x), int(box_y - 5)), cv2.FONT_HERSHEY_SIMPLEX, 1, color, 2)
               # put the FPS text on top of the frame
               cv2.putText(image, f"{fps:.2f} FPS", (20, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
      
       cv2.imshow('image', image)
       out.write(image)
       if cv2.waitKey(10) & 0xFF == ord('q'):
           break
   else:
       break
 
cap.release()
cv2.destroyAllWindows()

  • C++
while (cap.isOpened()) {
       Mat image;
       bool isSuccess = cap.read(image);
       if (! isSucess) break;
      
       int image_height = image.cols;
       int image_width = image.rows;
       //create blob from image
       Mat blob = blobFromImage(image, 1.0, Size(300, 300), Scalar(127.5, 127.5, 127.5),
                               true, false);
       //create blob from image
       model.setInput(blob);
       //forward pass through the model to carry out the detection
       Mat output = model.forward();
      
       Mat detectionMat(output.size[2], output.size[3], CV_32F, output.ptr<float>());
      
       for (int i = 0; i < detectionMat.rows; i++){
           int class_id = detectionMat.at<float>(i, 1);
           float confidence = detectionMat.at<float>(i, 2);
 
           // Check if the detection is of good quality
           if (confidence > 0.4){
               int box_x = static_cast<int>(detectionMat.at<float>(i, 3) * image.cols);
               int box_y = static_cast<int>(detectionMat.at<float>(i, 4) * image.rows);
               int box_width = static_cast<int>(detectionMat.at<float>(i, 5) * image.cols - box_x);
               int box_height = static_cast<int>(detectionMat.at<float>(i, 6) * image.rows - box_y);
               rectangle(image, Point(box_x, box_y), Point(box_x+box_width, box_y+box_height), Scalar(255,255,255), 2);
               putText(image, class_names[class_id-1].c_str(), Point(box_x, box_y-5), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0,255,255), 1);
           }
       }
      
       imshow("image", image);
       out.write(image);
       int k = waitKey(10);
       if (k == 113){
           break;
       }
   }
 
cap.release();
destroyAllWindows();
}

??上面代碼中,模型在每一幀都進行了物體檢測直到最后一幀。需要注意的是:

  • 在處理開始幀之前存儲了起始系統(tǒng)時間,并在檢測之后也把系統(tǒng)時間進行了存儲;
  • 利用上面的時間可以幫助我們計算FPS(Frames Per Seconds)。將計算出的FPS存儲在 fps。
  • 代碼的最后一部分,將fps參數(shù)寫在當前幀的頂部,可以讓我們了解到使用OpenCV DNN 運行 MobileNet SSD網(wǎng)絡(luò)可以獲得什么樣的處理速度。
  • 最后,在屏幕上顯示每一幀的處理結(jié)果并將它們存儲在磁盤中。
    ??執(zhí)行上面的代碼可以獲得如下的輸出:

Opencv-DNN模塊之官方指導:利用DNN模塊實現(xiàn)深度學習應(yīng)用:分類、分割、檢測、跟蹤等

▲ 圖3.2.1 視頻物體檢測結(jié)果

??在 i7 Gen八代筆記本電腦CPU上可以獲得大約33fps。對于檢測數(shù)量來講結(jié)果還不錯。 模型可以把場景中的所有行人,車輛甚至交通燈都能夠檢測。對于一些小的物品,比如手提包和背包的檢測還存在缺陷。33FPS的檢測速度是在檢測精度和減少小物品檢測方面做得折中所獲得的速度。

3.3 GPU上的推理

??可以在GPU上運行所有的分類和檢測網(wǎng)絡(luò),我們需要從帶有GPU的源工程中對OpenCV DNN模塊進行重新編譯。

  • 如果在Ubuntu,訪問 LearnOpenCV.com 了解帶有GPU編譯OpenCV。
  • 在Windows下,訪問這個 鏈接 了解帶有GPU編譯OpenCV。

??在GPU上運行推理,我們需要對C++,Python代碼做些小的修改。

??Python:
??net.setPreferableBackend(cv2.dnn.DNN_BACKEND_CUDA)
??net.setPreferableTarget(cv2.dnn.DNN_TARGET_CUDA)

??C++:
??net.setPreferableBackend(DNN_BACKEND_CUDA);
??net.setPreferableTarget(DNN_TARGET_CUDA);

??在將神經(jīng)網(wǎng)絡(luò)模型在入職前添加上面兩行代碼。第一行保證網(wǎng)絡(luò)在支持 CUDE GPU模塊的情況下將會使用CUDA。

??第二行代碼表示所有的王落集村將會在GPU中進行,而不是CPU。 使用CUDA來使能GPU,相比于CPU可以在物體檢測中獲得更高的FPS。對于普通的圖片,推理過程耗時也比CPU中縮短很多。

?

※ 總??結(jié) ※


??們介紹并討論了為什么選擇OpenCV DNN模塊。通過圖表對比了相關(guān)性能表現(xiàn)。看到OpenCV DNN所支持的不同的深度學習功能,模型以及學習框架。

??通過實操代碼討論了使用OpenCV DNN模塊完成圖像分類以及物體檢測任務(wù),還看到利用OpenCV DNN 在視頻中檢測物體。

4.1 關(guān)鍵知識點

??1. 人工神經(jīng)網(wǎng)絡(luò)和深度學習已經(jīng)使得計算機在理解和認知圖像的精度得到了極大提高。某些場合甚至超過了人類的水平。
??2. OpenCV DNN 模塊:
* 選擇OpenCV DNN進行模型推理是一個良好的選擇,尤其是在Intel處理器中;
* 安裝方便;
* 具有很多成熟可用的模型算法,能夠?qū)Ω洞蠖鄶?shù)常見的問題;
* 盡管DNN模塊還不具備訓練網(wǎng)絡(luò)的能力,但對于 邊端設(shè)備應(yīng)用具有很強的支持功能。

??希望你喜歡這個博文并能夠?qū)penCV DNN 模塊有了基礎(chǔ)的了解。將你的經(jīng)驗分享在下面的評論區(qū)吧。


■ 相關(guān)文獻鏈接:

  • OpenCV 功能庫 WiKi 網(wǎng)頁
  • 這個鏈接
  • OpenCV 官方文件
  • LearnOpenCV.com
  • 鏈接

重點參考!?。 肙penCV DNN模塊進行深度學習:一個最好使用指導書文章來源地址http://www.zghlxwxcb.cn/news/detail-453417.html

到了這里,關(guān)于Opencv-DNN模塊之官方指導:利用DNN模塊實現(xiàn)深度學習應(yīng)用:分類、分割、檢測、跟蹤等的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

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

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

相關(guān)文章

  • OpenCV DNN模塊推理YOLOv5 ONNX模型方法

    本文檔主要描述 python 平臺,使用 opencv-python 深度神經(jīng)網(wǎng)絡(luò)模塊 dnn ,推理 YOLOv5 模型的方法。 文檔主要包含以下內(nèi)容: opencv-python 模塊的安裝 YOLOv5 模型格式的說明 ONNX 格式模型的加載 圖片數(shù)據(jù)的預處理 模型推理 推理結(jié)果后處理,包括 NMS , cxcywh 坐標轉(zhuǎn)換為 xyxy 坐標等 關(guān)鍵方

    2024年02月16日
    瀏覽(26)
  • opencv dnn模塊 示例(19) 目標檢測 object_detection 之 yolox

    opencv dnn模塊 示例(19) 目標檢測 object_detection 之 yolox

    YOLOX是曠視科技在2021年發(fā)表,對標YOLO v5。YOLOX中引入了當年的黑科技主要有三點,decoupled head、anchor-free以及advanced label assigning strategy(SimOTA)。YOLOX的性能如何呢,可以參考原論文圖一如下圖所示。YOLOX比當年的YOLO v5略好一點,并且利用YOLOX獲得當年的Streaming Perception Challenge第一

    2024年02月06日
    瀏覽(20)
  • opencv dnn模塊 示例(16) 目標檢測 object_detection 之 yolov4

    opencv dnn模塊 示例(16) 目標檢測 object_detection 之 yolov4

    博客【opencv dnn模塊 示例(3) 目標檢測 object_detection (2) YOLO object detection】 測試了yolov3 及之前系列的模型,有在博客【opencv dnn模塊 示例(15) opencv4.2版本dnn支持cuda加速(vs2015異常解決)】 說明了如何使用dnn模塊進行cuda加速推理。 本文說明yolo v4的網(wǎng)絡(luò)改進和測試情況。 yolo v1~

    2024年02月07日
    瀏覽(23)
  • opencv dnn模塊 示例(25) 目標檢測 object_detection 之 yolov9

    opencv dnn模塊 示例(25) 目標檢測 object_detection 之 yolov9

    YOLOv9 是 YOLOv7 研究團隊推出的最新目標檢測網(wǎng)絡(luò),它是 YOLO(You Only Look Once)系列的最新迭代。YOLOv9 在設(shè)計上旨在解決深度學習中信息瓶頸問題,并提高模型在不同任務(wù)上的準確性和參數(shù)效率。 Programmable Gradient Information (PGI) :YOLOv9 引入了可編程梯度信息(PGI)的概念,這是

    2024年04月29日
    瀏覽(36)
  • 解決Opencv dnn模塊無法使用onnx模型的問題(將onnx的動態(tài)輸入改成靜態(tài))

    解決Opencv dnn模塊無法使用onnx模型的問題(將onnx的動態(tài)輸入改成靜態(tài))

    最近做人臉識別項目,想只用OpenCV自帶的人臉檢測和識別模塊實現(xiàn),使用OpenCV傳統(tǒng)方法:Haar級聯(lián)分類器人臉檢測+LBPH算法人臉識別的教程已經(jīng)有了,于是想著用OpenCV中的dnn模塊來實現(xiàn),dnn實現(xiàn)人臉檢測也有(詳細教程可見我的這篇博客https://blog.csdn.net/weixin_42149550/article/detai

    2024年02月05日
    瀏覽(19)
  • 用opencv的DNN模塊做Yolov5目標檢測(純干貨,源碼已上傳Github)

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

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

    2024年02月02日
    瀏覽(27)
  • 【圖像分割】【深度學習】SAM官方Pytorch代碼-各模塊的功能解析

    【圖像分割】【深度學習】SAM官方Pytorch代碼-各模塊的功能解析

    Segment Anything:建立了迄今為止最大的分割數(shù)據(jù)集,在1100萬張圖像上有超過1億個掩碼,模型的設(shè)計和訓練是靈活的,其重要的特點是Zero-shot(零樣本遷移性)轉(zhuǎn)移到新的圖像分布和任務(wù),一個圖像分割新的任務(wù)、模型和數(shù)據(jù)集。SAM由三個部分組成:一個強大的圖像編碼器(Image

    2024年02月11日
    瀏覽(19)
  • LabVIEW快速實現(xiàn)OpenCV DNN(YunNet)的人臉檢測(含源碼)

    LabVIEW快速實現(xiàn)OpenCV DNN(YunNet)的人臉檢測(含源碼)

    ????博客主頁: virobotics的CSDN博客:LabVIEW深度學習、人工智能博主 ??所屬專欄:『LabVIEW深度學習實戰(zhàn)』 ??上期文章: LabVIEW AI視覺工具包OpenCV Mat基本用法和屬性 ??如覺得博主文章寫的不錯或?qū)δ阌兴鶐椭脑挘€望大家多多支持呀! 歡迎大家?關(guān)注、??點贊、?收

    2024年02月09日
    瀏覽(36)
  • 基于深度學習、機器學習,對抗生成網(wǎng)絡(luò),OpenCV,圖像處理,卷積神經(jīng)網(wǎng)絡(luò)計算機畢業(yè)設(shè)計選題指導

    開發(fā)一個實時手勢識別系統(tǒng),使用卷積神經(jīng)網(wǎng)絡(luò)(CNN)和深度學習技術(shù),能夠識別用戶的手勢并將其映射到計算機操作,如控制游戲、音量調(diào)整等。這個項目需要涵蓋圖像處理、神經(jīng)網(wǎng)絡(luò)訓練和實時計算等方面的知識。 利用深度學習模型,設(shè)計一個人臉識別系統(tǒng),可以識別人

    2024年02月07日
    瀏覽(97)
  • 開發(fā)指導—利用組件&插值器動畫實現(xiàn) HarmonyOS 動效

    開發(fā)指導—利用組件&插值器動畫實現(xiàn) HarmonyOS 動效

    在組件上創(chuàng)建和運行動畫的快捷方式。具體用法請參考通用方法。 通過調(diào)用 animate 方法獲得 animation 對象,animation 對象支持動畫屬性、動畫方法和動畫事件。 說明 ●?使用 animate 方法時必須傳入 Keyframes 和 Options 參數(shù)。 ●?多次調(diào)用 animate 方法時,采用 replace 策略,即最后一

    2024年02月09日
    瀏覽(22)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

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

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包