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上執行這個演算法,得到結果也只需要不到一秒鐘。
再來一張:
結果如下:
再來:
結果依然不錯:
最後一個例子:
也認得不錯: