李林 編譯自 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兼容以下熱門網絡架構:
AlexNetGoogLeNet v1(也叫Inception-5h)ResNet-34/50/…SqueezeNet v1.1VGG-based FCNENetVGG-based SSDMobileNet-based SSD
該模塊的主要貢獻者Rynikov Alexander,對這個模塊有遠大的計劃,不過,他寫的release notes是俄語的,感興趣的同學請自行谷歌翻譯著讀:https://habrahabr.ru/company/intel/blog/333612/
我認為,dnn模塊會對OpenCV社區產生很大的影響。
函數和框架
在OpenCV中使用深度學習預訓練模型,首先要安裝OpenCV 3.3,安裝過程量子位就不再詳細描述了……
下面是我們將用到的一些函數。
在dnn中從磁碟加載圖片:
cv2.dnn.blobFromImagecv2.dnn.blobFromImages
用「create」方法直接從各種框架中導出模型:
cv2.dnn.createCaffeImportercv2.dnn.createTensorFlowImportercv2.dnn.createTorchImporter
使用「讀取」方法從磁碟直接加載序列化模型:
cv2.dnn.readNetFromCaffecv2.dnn.readNetFromTensorFlowcv2.dnn.readNetFromTorchcv2.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上運行這個算法,得到結果也只需要不到一秒鐘。
再來一張:
結果如下:
再來:
結果依然不錯:
最後一個例子:
也認得不錯:
相關連結
教程原文:http://www.pyimagesearch.com/2017/08/21/deep-learning-with-opencv/