OpenCV3.3深度學習模塊(DNN)應用-圖像分類

2021-02-25 OpenCV學堂
DNN模塊介紹

在OpenCV3.3版本發布中把DNN模塊從擴展模塊移到了OpenCV正式發布模塊中,當前DNN模塊最早來自Tiny-dnn,可以加載預先訓練好的Caffe模型數據,OpenCV做了近一步擴展支持所有主流的深度學習框架訓練生成與導出模型數據加載,常見的有如下:

Caffe

TensorFlow

Torch/PyTorch 

OpenCV中DNN模塊已經支持與測試過這些常見的網絡模塊

AlexNet

GoogLeNet v1 (also referred to as Inception-5h)

ResNet-34/50/...

SqueezeNet v1.1

VGG-based FCN (semantical segmentation network)

ENet (lightweight semantical segmentation network)

VGG-based SSD (object detection network)

MobileNet-based SSD (light-weight object detection network)

一:GoogleNet Caffe模型數據說明

OpenCV通過支持加載這些預先訓練好的模型,實現圖像分類、對象檢測、語義分割、風格遷移等功能。支持Android/iOS等移動端平臺開發。下面我們就以OpenCV3.3 使用Caffe的GoogleNet數據模型為例,實現對圖像常見分類,OpenCV3.3的DNN模塊使用的模型支持1000種常見圖像分類、googlenet深度學習網絡模型是2014圖像分類比賽的冠軍、首先是下載相關的數據模型文件

其中prototxt是一個文本的JSON文件、一看就明白啦,另外一個文件二進位文件。文本文件只有你下載了OpenCV3.3解壓縮之後就會在對應的目錄發現。模型文件需要從以下地址下載即可: http://dl.caffe.berkeleyvision.org/bvlc_googlenet.caffemodel

二:編程實現

首先我們需要加載它官方指定的一張測試圖像space_shuttle.jpg 是一張太空梭的圖片、OpenCV中加載圖像的代碼如下:

   Mat testImage = imread("D:/vcprojects/images/dnn/football.jpg");

   if (testImage.empty()) {

       printf("could not load image...\n");

       return -1;

   }

然後我們需要聲明模型數據的路徑與標記數據路徑,加載創建網絡模型,代碼實現如下:

   // create googlenet with caffemodel text and bin

   Net net = dnn::readNetFromCaffe(modelTxt, modelBin);

   if (net.empty())

   {

       std::cerr << "Can't load network by using the following files: " << std::endl;

       std::cerr << "prototxt:   " << modelTxt << std::endl;

       std::cerr << "caffemodel: " << modelBin << std::endl;

       return -1;

   }

   // 讀取分類數據

   vector<String> labels = readClasslabels();

   //GoogLeNet accepts only 224x224 RGB-images

   Mat inputBlob = blobFromImage(testImage, 1, Size(224, 224), Scalar(104, 117, 123));

然後開始分類預測,根據prototxt中的開始的要求,我們需要輸入迭代10次,輸出預測分類的結果,代碼實現如下:

// 支持1000個圖像分類檢測

   Mat prob;

   // 循環10+

   for (int i = 0; i < 10; i++)

   {

       // 輸入

       net.setInput(inputBlob, "data");        

       // 分類預測

       prob = net.forward("prob");

   }

   // 讀取分類索引,最大與最小值

   Mat probMat = prob.reshape(1, 1); //reshape the blob to 1x1000 matrix // 1000個分類

   Point classNumber;

   double classProb;

   minMaxLoc(probMat, NULL, &classProb, NULL, &classNumber); // 可能性最大的一個

   int classIdx = classNumber.x; // 分類索引號

   printf("\n current image classification : %s, possible : %.2f \n", labels.at(classIdx).c_str(), classProb);

   putText(testImage, labels.at(classIdx), Point(20, 20), FONT_HERSHEY_SIMPLEX, 0.75, Scalar(0, 0, 255), 2, 8);

   imshow("Image Category", testImage);

其中讀取圖像分類索引與文本描述的方法代碼如下:

vector<String> readClasslabels() {

   std::vector<String> classNames;

   std::ifstream fp(labelFile);

   if (!fp.is_open())

   {

       std::cerr << "File with classes labels not found: " << labelFile << std::endl;

       exit(-1);

   }

   std::string name;

   while (!fp.eof())

   {

       std::getline(fp, name);

       if (name.length())

           classNames.push_back(name.substr(name.find(' ') + 1));

   }

   fp.close();

   return classNames;

}

三:效果顯示

太空梭測試圖像

霸氣威武的J10戰鬥機

玩具店

足球場上

四:完全的原始碼

#include <opencv2/opencv.hpp>

#include <opencv2/dnn.hpp>

#include <iostream>

using namespace cv;

using namespace cv::dnn;

using namespace std;

String modelTxt = "D:/vcprojects/images/dnn/bvlc_googlenet.prototxt";

String modelBin = "D:/vcprojects/images/dnn/bvlc_googlenet.caffemodel";

String labelFile = "D:/vcprojects/images/dnn/synset_words.txt";

vector<String> readClasslabels();

int main(int argc, char** argv) {

   Mat testImage = imread("D:/vcprojects/images/dnn/football.jpg");

   if (testImage.empty()) {

       printf("could not load image...\n");

       return -1;

   }

   // create googlenet with caffemodel text and bin

   Net net = dnn::readNetFromCaffe(modelTxt, modelBin);

   if (net.empty())

   {

       std::cerr << "Can't load network by using the following files: " << std::endl;

       std::cerr << "prototxt:   " << modelTxt << std::endl;

       std::cerr << "caffemodel: " << modelBin << std::endl;

       return -1;

   }

   // 讀取分類數據

   vector<String> labels = readClasslabels();

   //GoogLeNet accepts only 224x224 RGB-images

   Mat inputBlob = blobFromImage(testImage, 1, Size(224, 224), Scalar(104, 117, 123));

   // 支持1000個圖像分類檢測

   Mat prob;

   // 循環10+

   for (int i = 0; i < 10; i++)

   {

       // 輸入

       net.setInput(inputBlob, "data");        

       // 分類預測

       prob = net.forward("prob");

   }

   // 讀取分類索引,最大與最小值

   Mat probMat = prob.reshape(1, 1); //reshape the blob to 1x1000 matrix // 1000個分類

   Point classNumber;

   double classProb;

   minMaxLoc(probMat, NULL, &classProb, NULL, &classNumber); // 可能性最大的一個

   int classIdx = classNumber.x; // 分類索引號

   printf("\n current image classification : %s, possible : %.2f \n", labels.at(classIdx).c_str(), classProb);

   putText(testImage, labels.at(classIdx), Point(20, 20), FONT_HERSHEY_SIMPLEX, 0.75, Scalar(0, 0, 255), 2, 8);

   imshow("Image Category", testImage);

   waitKey(0);

   return 0;

}

/* 讀取圖像的1000個分類標記文本數據 */

vector<String> readClasslabels() {

   std::vector<String> classNames;

   std::ifstream fp(labelFile);

   if (!fp.is_open())

   {

       std::cerr << "File with classes labels not found: " << labelFile << std::endl;

       exit(-1);

   }

   std::string name;

   while (!fp.eof())

   {

       std::getline(fp, name);

       if (name.length())

           classNames.push_back(name.substr(name.find(' ') + 1));

   }

   fp.close();

   return classNames;

}

居不隱者,思不遠也;

身不危者,志不廣也!


關注【OpenCV學堂】

長按或者掃碼下面二維碼即可關注

+OpenCV學習群 376281510

進群暗號:OpenCV

相關焦點

  • OpenCV DNN模塊官方教程(一)加載Caffe模型做圖像分類
    OpenCV DNN模塊官方教程地址如下,可以查看各個對應的使用方法。
  • 強強聯合,OpenCV搭載飛槳模型,幫你輕鬆玩轉深度學習
    下一個版本OpenCV 5.0 不僅僅支持常規的圖像分類、目標檢測、圖像分割和風格遷移功能,還將引入多個CV方向任務。飛槳(PaddlePaddle)以百度多年的深度學習技術研究和業務應用為基礎,集深度學習核心訓練和推理框架、基礎模型庫、端到端開發套件和豐富的工具組件於一體,是中國首個自主研發、功能豐富、開源開放的產業級深度學習平臺。
  • 實用教程詳解:模型部署,用DNN模塊部署YOLOv5目標檢測(附原始碼)
    三、DNN模塊部署Yolov5用opencv的dnn模塊做yolov5目標檢測的程序,包含兩個步驟:1)、把pytorch的訓練模型pth文件轉換到onnx文件;2)、opencv的dnn模塊讀取onnx文件做前向計算。
  • 使用c++ opencv調用tensorflow訓練好的卷積神經網絡
    在OpenCV3.3版本發布中把DNN模塊從擴展模塊移到了OpenCV正式發布模塊中,DNN模塊最早來自Tiny-dnn,可以加載預先訓練好的
  • Opencv+TF-Slim實現圖像分類及深度特徵提取
    本文將用Opencv的dnn模塊調用預訓練的InceptionV4模型進行圖像分類及深度特徵的提取。首先需要下載tensorflow的model模塊,地址為https:slim位於 \models-master\research\slim路徑下在https:下載預訓練的分類模型,如圖下載InceptionV4的Checkpoint
  • Tensorflow + OpenCV4 安全帽檢測模型訓練與推理
    8image = cv.imread("D:/123.jpg") 9h, w = image.shape[:2]10cv.imshow("input", image)1112# 加載模型,執行推理13net = cv.dnn.readNetFromTensorflow(model, config)14blob = cv.dnn.blobFromImage
  • OpenCV 3.0之後三年半,OpenCV 4.0出爐
    core 模塊中的 Persistence(用於存儲和加載 XML、YAML 或 JSON 格式的結構化數據)可以完全使用 C++ 來重新實現,因此這裡的 C API 也被移除。添加了新模塊 G-API,它可作為基於圖的高效圖像處理流程。dnn 模塊包括實驗用 Vulkan 後端,且支持 ONNX 格式的網絡。
  • OpenCV 3.0 三年半後,OpenCV 4.0 終於出爐
    core 模塊中的 Persistence(用於存儲和加載 XML、YAML 或 JSON 格式的結構化數據)可以完全使用 C++ 來重新實現,因此這裡的 C API 也被移除。添加了新模塊 G-API,它可作為基於圖的高效圖像處理流程。dnn 模塊包括實驗用 Vulkan 後端,且支持 ONNX 格式的網絡。
  • OpenCV DNN模塊——從TensorFlow模型導出到OpenCV部署詳解
    據博主所知,目前大部分的相機開發包並不支持Python語言,而主流的深度學習框架都是基於Python語言,訓練好的模型難以部署到自己的軟體中。OpenCV官方提供了語義分割,目標檢測以及分類的解碼例程,可以查看下方參考資料[1]。
  • 基於OpenCV和深度學習的人臉檢測
    在今天的博客文章的其餘部分,我將討論:這個「隱藏」的深度學習人臉檢測器存在於OpenCV圖書館如何使用OpenCV和深度學習進行圖像中的人臉檢測如何利用OpenCV和深度學習實現視頻中的人臉檢測正如我們將看到,很容易交換Haar級聯為他們更準確的深度學習臉部檢測器同行。
  • C++ OpenCV Contrib模塊LBF人臉特徵點檢測
    #思路1加載OpenCV DNN和FacemarkLBF的模型(FacemarkLBF在OpenCVr的Contrib模塊中)2使用DNN人臉檢測獲取圖像中所有人臉的矩形框3調用FaceMarkLBF中的fit針對Mat和上面獲得的人臉矩形框進行特徵點檢測,檢測的結果存放為vector<vector
  • [OpenCV實戰]45 基於OpenCV實現圖像哈希算法
    在實際應用中,圖像哈希算法可以用於圖片檢索,重複圖片剔除,以圖搜圖以及圖片相似度比較。為什麼圖像哈希算法能夠評估兩幅圖像的相似性,這就需要從哈希值說起,哈希值計算算法的本質就是對原始數據進行有損壓縮,有損壓縮後的固定字長能夠作為唯一標識來標識原始數據,這個唯一標識就是哈希值。通常改變原始數據任意一個部分,哈希值都將不同。
  • 深度學習「CV」學習實踐指南!
    故其可以與opencv或pillow結合使用,只需要傳入像素值矩陣,matplotlib便可以接手處理接下來想要完成的操作。PIL即Python Imaging Library,而pillow是PIL的一個分支。pillow提供了常見的圖像讀取和處理的操作,它比opencv更為輕巧,且可以與ipython notebook無縫集成。
  • 模板識別:使用OpenCV實現基於特徵的圖像對齊
    在許多文檔處理應用程式中,第一步是將掃描或拍攝的文檔與模板對齊。例如,如果要編寫自動表單閱讀器,最好先將表單與其模板對齊,然後根據模板中的固定位置讀取欄位。在一些醫學應用中,可以把多次拍攝的照片拼接起來。圖像對齊最有趣的應用可能是創建全景圖。在這種情況下,兩個圖像不是平面的圖像而是3D場景的圖像。通常,3D對齊需要深度信息。
  • 深度學習「CV」實踐指南!
    故其可以與opencv或pillow結合使用,只需要傳入像素值矩陣,matplotlib便可以接手處理接下來想要完成的操作。PIL即Python Imaging Library,而pillow是PIL的一個分支。pillow提供了常見的圖像讀取和處理的操作,它比opencv更為輕巧,且可以與ipython notebook無縫集成。
  • 輕鬆學Pytorch-使用ResNet50實現圖像分類
    Hello大家好,這篇文章給大家詳細介紹一下pytorch中最重要的組件torchvision,它包含了常見的數據集、模型架構與預訓練模型權重文件、常見圖像變換、計算機視覺任務訓練。可以是說是pytorch中非常有用的模型遷移學習神器。本文將會介紹如何使用torchvison的預訓練模型ResNet50實現圖像分類。
  • 輕鬆學 Pytorch:使用 ResNet50 實現圖像分類
    Hello大家好,這篇文章給大家詳細介紹一下pytorch中最重要的組件torchvision,它包含了常見的數據集、模型架構與預訓練模型權重文件、常見圖像變換、計算機視覺任務訓練。可以是說是pytorch中非常有用的模型遷移學習神器。本文將會介紹如何使用torchvison的預訓練模型ResNet50實現圖像分類。
  • 使用Python+OpenCV實現圖像數據採集
    conda create -n opencv python=3.6這將在Python版本3.6中創建一個名為opencv的新環境,可以用正在使用的任何版本替換它。你可以測試實例是否能夠連接到你的相機(如果沒有,請檢查你的設置以確保應用程式可以訪問它)。cap = cv2.VideoCapture(0)if not (cap.isOpened()): print("Video device not connected.")最後,是時候拍照了。
  • Python+OpenCV的基礎圖像處理操作匯總
    圖像處理是對圖像進行的技術操作與分析,比如為了得到增強的圖像或提取一些有用的信息而進行的一系列操作。隨著我們的發展,許多應用程式使用圖像/幀/視頻作為輸入,對它們進行預處理,並將其輸入到設備或軟體或腳本中。