1. 程式人生 > >OpenCV+深度學習預訓練模型,簡單搞定影象識別 | 教程

OpenCV+深度學習預訓練模型,簡單搞定影象識別 | 教程

轉載:https://mp.weixin.qq.com/s/J6eo4MRQY7jLo7P-b3nvJg

李林 編譯自 pyimagesearch
作者 Adrian Rosebrock
量子位 報道 | 公眾號 QbitAI

OpenCV是一個2000年釋出的開源計算機視覺庫,有進行物體識別、影象分割、人臉識別、動作識別等多種功能,可以在Linux、Windows、Android、Mac OS等作業系統上執行,以輕量級、高效著稱,且提供多種語言介面。

而OpenCV最近一次版本更新,為我們帶來了更好的深度學習支援,在OpenCV中使用預訓練的深度學習模型變得非常容易。

pyimagesearch網站今天釋出了一份用OpenCV+深度學習預訓練模型做影象識別的教程,量子位編譯整理如下:

最近,OpenCV 3.3剛剛正式釋出,對深度學習(dnn模組)提供了更好的支援,dnn模組目前支援Caffe、TensorFlow、Torch、PyTorch等深度學習框架。

另外,新版本中使用預訓練深度學習模型的API同時相容C++和Python,讓系列操作變得非常簡便:

  • 從硬碟載入模型;

  • 對輸入影象進行預處理;

  • 將影象輸入網路,獲取輸出的分類。

當然,我們不能、也不該用OpenCV訓練深度學習模型,但這個新版本讓我們能把用深度學習框架訓練好了的模型拿來,高效地用在OpenCV之中。

這篇文章就展示瞭如何用ImageNet上預訓練的深度學習模型來識別影象。

OpenCV 3.3中的深度學習

自OpenCV 3.1版以來,dnn模組一直是opencv_contrib庫的一部分,在3.3版中,它被提到了主倉庫中。

用OpenCV 3.3,可以很好地利用深度學習預訓練模型,將它們作為分類器。

新版OpenCV相容以下熱門網路架構:

  • AlexNet

  • GoogLeNet v1(也叫Inception-5h)

  • ResNet-34/50/…

  • SqueezeNet v1.1

  • VGG-based FCN

  • ENet

  • VGG-based SSD

  • MobileNet-based SSD

該模組的主要貢獻者Rynikov Alexander,對這個模組有遠大的計劃,不過,他寫的release notes是俄語的,感興趣的同學請自行谷歌翻譯著讀:https://habrahabr.ru/company/intel/blog/333612/

我認為,dnn模組會對OpenCV社群產生很大的影響。

函式和框架

在OpenCV中使用深度學習預訓練模型,首先要安裝OpenCV 3.3,安裝過程量子位就不再詳細描述了……

下面是我們將用到的一些函式。

在dnn中從磁碟載入圖片:

  • cv2.dnn.blobFromImage

  • cv2.dnn.blobFromImages

用“create”方法直接從各種框架中匯出模型:

  • cv2.dnn.createCaffeImporter

  • cv2.dnn.createTensorFlowImporter

  • cv2.dnn.createTorchImporter

使用“讀取”方法從磁碟直接載入序列化模型:

  • cv2.dnn.readNetFromCaffe

  • cv2.dnn.readNetFromTensorFlow

  • cv2.dnn.readNetFromTorch

  • cv2.dnn.readhTorchBlob

從磁碟載入完模型之後,可以用.forward方法來向前傳播我們的影象,獲取分類結果。

用OpenCV和深度學習給影象分類

接下來,我們來學習如何用Python、OpenCV和一個預訓練過的Caffe模型來進行影象識別。

下文用到的深度學習模型是在ImageNet上預訓練過的GoogleLeNet。GoogleLeNet出自Szegedy等人2014年的論文Going Deeper with Convolutions,詳情見:https://arxiv.org/abs/1409.4842

首先,開啟一個新檔案,將其命名為deep_learning_with_opencv.py,插入如下程式碼,來匯入我們需要的包:

然後拆解命令列引數:

其中第8行ap = argparse.ArgumentParser()是用來建立引數解析器的,接下來的程式碼用來建立4個命令列引數:

  • —image:輸入影象的路徑;

  • —prototxt:Caffe部署prototxt的路徑

  • —model:預訓練的Caffe模型,例如網路權重等;

  • —labels:ImageNet標籤的路徑,例如syn-sets。

我們在建立引數之後,將它們解析並存在一個變數args中,供稍後使用。

接下來,載入輸入影象和標籤:

第20行從磁碟載入了影象,第23行和24行載入了這些標籤:

搞定了標籤之後,我們來看一下dnn模組:

注意上面程式碼中的註釋,我們使用cv2.dnn.blobFromImage執行mean subtraction來對輸入影象進行歸一化,從而產生一個已知的blob形狀。

然後從磁碟載入我們的模型:

我們用cv2.dnn.readNetFromCaffe來載入Caffe模型定義prototxt,以及預訓練模型。

接下來,我們以blob為輸入,在神經網路中完成一次正向傳播:

請注意:我們不是在訓練CNN,而是在使用預訓練模型,因此只需要將blob從網路中傳遞過去,來獲取結果,不需要反向傳播。

最後,我們來為輸入影象取出5個排名最高的預測結果:

我們可以用NumPy來選取排名前5的結果,然後將他們顯示出來:

分類結果

我們已經在OpenCV中用Python程式碼實現了深度學習影象識別,現在,可以拿一些圖片來試一試。

開啟你的終端,執行以下命令:

就會得到這樣的結果:

OpenCV和GoogleLeNet正確地認出了比格小獵犬,排名第一的結果是正確的,之後的4項結果相關度也很高。

在CPU上執行這個演算法,得到結果也只需要不到一秒鐘。

再來一張:

結果如下:

再來:

結果依然不錯:

最後一個例子:

也認得不錯: