OpenCV入门及应用案例:手把手教你做DNN图像分类
導(dǎo)讀:本文將介紹OpenCV的源碼結(jié)構(gòu)、OpenCV深度學(xué)習(xí)應(yīng)用的典型流程,以及深度學(xué)習(xí)和OpenCV DNN(Deep Neural Networks,深度神經(jīng)網(wǎng)絡(luò))模塊的背景知識(shí),讓讀者可以快速認(rèn)識(shí)OpenCV,消除神秘感,同時(shí)對(duì)計(jì)算機(jī)視覺從傳統(tǒng)算法到深度學(xué)習(xí)算法的演進(jìn)歷史有所了解。
作者:吳至文 郭葉軍 宗煒 李鵬 趙娟
來源:大數(shù)據(jù)DT(ID:hzdashuju)
OpenCV是一個(gè)計(jì)算機(jī)視覺開源庫,提供了處理圖像和視頻的能力。OpenCV的影響力非常大,有超過47 000的社區(qū)用戶,以及超過1400萬次的下載量。其應(yīng)用領(lǐng)域橫跨圖像處理、交互式藝術(shù)、視頻監(jiān)督、地圖拼接和高級(jí)機(jī)器人等。作為一個(gè)有十幾年歷史的開源項(xiàng)目,OpenCV擁有廣大的用戶群體和開發(fā)者群體。
在數(shù)字的世界中,一幅圖像由多個(gè)點(diǎn)(像素)組成。圖像處理就是對(duì)其中一個(gè)像素或者一個(gè)區(qū)域內(nèi)的像素(塊)進(jìn)行處理。無論是初學(xué)者還是富有經(jīng)驗(yàn)的研發(fā)人員,他們都需要借助軟件工具來分析這些像素和圖像塊,OpenCV則是其中最常用、最重要的一個(gè)軟件工具。
OpenCV成為最主要的圖像處理工具包,是因?yàn)樗δ荦R全,支持目前主流的圖像、視頻處理算法,而且對(duì)外提供C++、Python和Java的接口,用戶調(diào)用方便。本書的代碼分析、示例程序及環(huán)境搭建基于OpenCV 4.1版本,源代碼位于GitHub的OpenCV倉庫。
01 OpenCV庫
OpenCV由各種不同組件組成。OpenCV源代碼主要由OpenCV core(核心庫)、opencv_contrib和opencv_extra等子倉庫組成。近些年,OpenCV的主倉庫增加了深度學(xué)習(xí)相關(guān)的子倉庫:OpenVINO(即DLDT, Deep Learning Deployment Toolkit)、open_model_zoo,以及標(biāo)注工具CVAT等。
下面分別介紹3個(gè)主要的代碼庫:OpenCV core、opencv_contrib、opencv_extra。
1. 核心庫OpenCV core
核心庫是OpenCV的主要算法來源。OpenCV采用模塊化結(jié)構(gòu)設(shè)計(jì),包含了多個(gè)共享或者靜態(tài)庫。目前OpenCV核心庫提供了很多組件,如下所示。
核心功能模塊:這是一個(gè)小巧而高效的模塊,定義了基礎(chǔ)的數(shù)據(jù)結(jié)構(gòu),包含緊密多尺度向量矩陣和一些供其他模塊使用的基礎(chǔ)函數(shù)
圖像處理模塊:它包括了線性和非線性的圖像濾波、幾何圖像變換(圖像縮放、仿射變換、透視矯正、通用的基于表格的像素映射)、色域變換及直方圖生成與分析等
視頻:這是一個(gè)視頻分析模塊,包含運(yùn)動(dòng)檢測、背景減除和對(duì)象追蹤等算法
calib3d:包含基礎(chǔ)的多視角幾何算法、單個(gè)和立體相機(jī)標(biāo)定算法、對(duì)象姿勢預(yù)測算法、立體一致性算法,以及3D元素重建
Features2d:圖像顯著特征檢測、特征點(diǎn)描述和匹配
Objdetect:對(duì)象檢測和預(yù)先定義的類別檢測(如臉、眼、杯子、人、車等)
Highgui:提供了比較容易使用的UI接口
Video I/O:提供了基本的視頻存取訪問和編解碼功能
GPU:為不同的OpenCV算法模塊提供GPU加速算法
其他:如FLANN和Google測試封裝層、Python綁定等
2. opencv_contrib
opencv_contrib代碼庫主要用于管理新功能模塊的開發(fā)。該庫的設(shè)計(jì)主要基于以下考慮:處于初始開發(fā)階段的功能模塊,它的API定義會(huì)經(jīng)常變化,各種測試也不夠全面。
為了不影響OpenCV核心模塊的穩(wěn)定性,這些新功能模塊會(huì)發(fā)布到opencv_contrib中。等到模塊足夠成熟并且在社區(qū)得到了足夠的關(guān)注和使用之后,這個(gè)模塊便會(huì)被移到OpenCV核心庫,這意味著核心庫開發(fā)團(tuán)隊(duì)將會(huì)對(duì)該模塊進(jìn)行全面的測試,保證這個(gè)模塊具有產(chǎn)品級(jí)的質(zhì)量。
例如,對(duì)于DNN這個(gè)模塊,OpenCV 3.1開始出現(xiàn)在opencv_contrib中,到了3.3版本才移到了OpenCV核心庫。
opencv_contrib需要和OpenCV核心庫一同編譯。下載好opencv_contrib的源代碼并在CMake執(zhí)行時(shí)傳入?yún)?shù):-DOPENCV_EXTRA_MODULES_PATH=<opencv_contrib源碼路徑>/modules。
如果編譯時(shí)遇到問題,則可以在OpenCV核心庫和opencv_contrib庫的問題匯報(bào)頁面,查看一下是否有現(xiàn)成的解決方案,如果沒有,則讀者可新建一個(gè)問題。OpenCV是一個(gè)活躍的社區(qū),只要問題描述清晰、完整,一般會(huì)很快得到反饋。
3. opencv_extra
opencv_extra倉庫存放了運(yùn)行測試和示例程序時(shí)需要使用的一些測試數(shù)據(jù)和腳本。例如,運(yùn)行DNN模塊測試程序或者示例程序時(shí)需要用到預(yù)訓(xùn)練模型,這些模型可以通過opencv_extra中的腳本來自動(dòng)下載。近些年添加的opencv/open_model_zoo倉庫也增加了很多預(yù)訓(xùn)練好的深度學(xué)習(xí)模型,這些模型大多做過性能和速度上的調(diào)優(yōu)。
02 OpenCV深度學(xué)習(xí)應(yīng)用的典型流程
OpenCV是一個(gè)自包含庫,可以不依賴于任何第三方庫而運(yùn)行,這個(gè)特性給開發(fā)調(diào)試帶來了很大的便利。另外,OpenCV還提供了硬件加速功能,使得算法能夠在各種平臺(tái)高效地執(zhí)行。
下面以一個(gè)識(shí)別性別和年齡的深度學(xué)習(xí)應(yīng)用為例,展現(xiàn)OpenCV深度學(xué)習(xí)應(yīng)用的典型流程。該應(yīng)用使用C++語言,總共只需要百來行代碼便可實(shí)現(xiàn)人臉檢測、性別和年齡的識(shí)別功能,還可以方便地使用硬件的加速能力,提高程序的運(yùn)行效率。此處展示核心流程,故以偽代碼為例,完整的源代碼由本書的參考代碼庫提供。
該應(yīng)用的核心流程如下:首先讀取兩個(gè)網(wǎng)絡(luò)模型參數(shù)(分別是性別和年齡),然后檢測人臉,轉(zhuǎn)換輸入圖像,最后運(yùn)行網(wǎng)絡(luò)前向預(yù)測。偽代碼如下:
//?引入OpenCV?DNN模塊的命名空間 using?namespace?cv::dnn; //?創(chuàng)建人臉檢測器 CascadeClassifier cascade;//?導(dǎo)入性別和年齡深度神經(jīng)網(wǎng)絡(luò)模型 Net gender_net=dnn::readNetFromCaffe(gender_modelTxt, gender_modelBin); Net age_net=dnn::readNetFromCaffe(age_modelTxt, age_modelBin); //?人臉檢測 cascade.load(cascadeName); cascade.detectMultiScale(input_gray_file, output_faces_data);//?準(zhǔn)備深度神經(jīng)網(wǎng)絡(luò)的輸入數(shù)據(jù) Mat inputBlob=blobFromImage(input.getMat(ACCESS_READ)); gender_net.setInput(inputBlob,?"data"); age_net.setInput(inputBlob,?"data");//?執(zhí)行模型的前向運(yùn)算,即模型推理 Mat?gender_prob=gender_net.forward("prob"); Mat?age_prob=age_net.forward("prob");應(yīng)用識(shí)別效果如圖1-1所示。
▲圖1-1 應(yīng)用識(shí)別效果圖
以上偽代碼很好地展示了OpenCV深度學(xué)習(xí)應(yīng)用的典型流程,如圖1-2所示。
▲圖1-2?OpenCV深度學(xué)習(xí)應(yīng)用的典型流程
03 OpenCV深度學(xué)習(xí)模塊
深度學(xué)習(xí)模塊是OpenCV為支持基于深度學(xué)習(xí)的計(jì)算機(jī)視覺應(yīng)用所加入的新特性。OpenCV DNN模塊于OpenCV 3.1版本開始出現(xiàn)在opencv_contrib庫中,從3.3版本開始被納入OpenCV核心庫。
本節(jié)主要講解OpenCV深度學(xué)習(xí)模塊的實(shí)現(xiàn)原理和主要特性,通過這些內(nèi)容,讀者可以對(duì)OpenCV DNN有一個(gè)總體了解,并對(duì)OpenCV深度學(xué)習(xí)模塊的應(yīng)用代碼有一個(gè)初步的印象。
作為計(jì)算機(jī)視覺領(lǐng)域的“標(biāo)準(zhǔn)庫”,OpenCV為用戶提供深度學(xué)習(xí)的支持是題中應(yīng)有之義。OpenCV選擇重新實(shí)現(xiàn)一個(gè)深度學(xué)習(xí)框架而不是直接調(diào)用現(xiàn)有的各種框架(如TensorFlow、Caffe等),有如下幾點(diǎn)原因。
輕量:OpenCV的深度學(xué)習(xí)模塊只實(shí)現(xiàn)了模型推理功能,這使得相關(guān)代碼非常精簡,加速了安裝和編譯過程。
最少的外部依賴:重新實(shí)現(xiàn)一遍深度學(xué)習(xí)框架使得對(duì)外部依賴減到最小,大大方便了深度學(xué)習(xí)應(yīng)用的部署。
方便集成:①如果原來的應(yīng)用是基于OpenCV開發(fā)的,通過深度學(xué)習(xí)模塊可以非常方便地加入對(duì)神經(jīng)網(wǎng)絡(luò)推理的支持;②如果網(wǎng)絡(luò)模型來自多個(gè)框架,如一個(gè)來自TensorFlow,一個(gè)來自Caffe,則深度學(xué)習(xí)模塊可以方便整合網(wǎng)絡(luò)運(yùn)算結(jié)果。
通用性:①提供統(tǒng)一的接口來操作網(wǎng)絡(luò)模型;②內(nèi)部所做的優(yōu)化和加速對(duì)所有網(wǎng)絡(luò)模型格式都適用;③支持多種設(shè)備和操作系統(tǒng)。
1. 主要特性
OpenCV深度學(xué)習(xí)模塊只提供網(wǎng)絡(luò)推理功能,不支持網(wǎng)絡(luò)訓(xùn)練。像所有的推理框架一樣,加載和運(yùn)行網(wǎng)絡(luò)模型是基本的功能。深度學(xué)習(xí)模塊支持TensorFlow、Caffe、Torch、DarkNet、ONNX和OpenVINO格式的網(wǎng)絡(luò)模型,用戶無須考慮原格式的差異。在加載過程中,各種格式的模型被轉(zhuǎn)換成統(tǒng)一的內(nèi)部網(wǎng)絡(luò)結(jié)構(gòu)。
深度學(xué)習(xí)模塊支持所有的基本網(wǎng)絡(luò)層類型和子結(jié)構(gòu),包括AbsVal、AveragePooling、BatchNormalization、Concatenation、Convolution (with DILATION)、Crop、DetectionOutput、Dropout、Eltwise、Flatten、FullConvolution、FullyConnected、LRN、LSTM、MaxPooling、MaxUnpooling、MVN、NormalizeBBox、Padding、Permute、Power、PReLU、PriorBox、Relu、RNN、Scale、Shift、Sigmoid、Slice、Softmax、Split和Tanh。
如果需要的層類型不在這個(gè)支持列表之內(nèi),則可以通過腳注中的申請(qǐng)鏈接來請(qǐng)求新的層類型的支持,OpenCV的開發(fā)者們有可能會(huì)在將來加入對(duì)該層類型的支持。讀者也可以自己動(dòng)手實(shí)現(xiàn)新的層類型,并把代碼反饋回社區(qū),參與到深度學(xué)習(xí)模塊的開發(fā)中來。
除了實(shí)現(xiàn)基本的層類型,支持常見的網(wǎng)絡(luò)架構(gòu)也很重要,經(jīng)過嚴(yán)格測試,深度學(xué)習(xí)模塊支持的網(wǎng)絡(luò)架構(gòu)如下所示。
圖像分類網(wǎng)絡(luò)
Caffe:AlexNet、GoogLeNet、VGG、ResNet、SqueezeNet、DenseNet、ShuffleNet
TensorFlow:Inception、MobileNet
Darknet:darknet-imagenet
ONNX:AlexNet、GoogleNet、CaffeNet、RCNN_ILSVRC13、ZFNet512、VGG16、VGG16_bn、ResNet-18v1、ResNet-50v1、CNN Mnist、MobileNetv2、LResNet100E-IR、Emotion FERPlus、Squeezenet、DenseNet121、Inception-v1/v2、ShuffleNet
對(duì)象檢測網(wǎng)絡(luò)
Caffe:SSD、VGG、MobileNet-SSD、Faster-RCNN、R-FCN、OpenCV face detector
TensorFlow:SSD、Faster-RCNN、Mask-RCNN、EAST
Darknet:YOLOv2、Tiny YOLO、YOLOv3
ONNX:TinyYOLOv2
語義分割網(wǎng)絡(luò):FCN(Caffe)、ENet(Torch)、ResNet101_DUC_HDC(ONNX)
姿勢估計(jì)網(wǎng)絡(luò):openpose(Caffe)
圖像處理網(wǎng)絡(luò):Colorization(Caffe)、Fast-Neural-Style(Torch)
人臉識(shí)別網(wǎng)絡(luò):openface(Torch)
2. OpenCV DNN圖像分類舉例(Python)
C++和Python是OpenCV應(yīng)用開發(fā)的主要語言,1.1.2節(jié)介紹了一個(gè)基于C++語言的深度學(xué)習(xí)應(yīng)用,本節(jié)繼續(xù)介紹一個(gè)基于Python的圖像分類示例。
首先引入必要的Python庫:
import?numpy?as?np?#?引入numpy庫 import?cv2?as?cv?#?引入OpenCV庫,深度學(xué)習(xí)模塊包含在其中讀入類別文件:
with?open('synset_words.txt')?as?f:classes=[x[x.find('?')?+?1:]?for?x?in?f]讀入待分類的圖片:
image=cv.imread('space_shuttle.jpg')調(diào)用深度學(xué)習(xí)模塊的blobFromImage方法將圖片對(duì)象轉(zhuǎn)換成網(wǎng)絡(luò)模型的輸入張量(tensor)。該張量的大小是224×224,參數(shù)中的(104,117,123)表示需要從輸入張量減掉的均值,它是從訓(xùn)練網(wǎng)絡(luò)模型時(shí)用到的數(shù)據(jù)集計(jì)算出來的,這里直接使用即可。第二個(gè)參數(shù)“1”表示將OpenCV的默認(rèn)通道順序BGR轉(zhuǎn)換成網(wǎng)絡(luò)模型要求的RGB通道順序。
input=cv.dnn.blobFromImage(image,?1,?(224,?224),?(104,?117,?123))下面來加載Caffe網(wǎng)絡(luò)模型。注意,相關(guān)的模型參數(shù)和配置文件可在這里下載:
http://dl.caffe.berkeleyvision.org/bvlc_googlenet.caffemodel
https://github.com/opencv/opencv_extra/blob/4.1.0/testdata/dnn/bvlc_googlenet.prototxt
net=cv.dnn.readNetFromCaffe('bvlc_googlenet.prototxt','bvlc_googlenet.caffemodel')設(shè)置網(wǎng)絡(luò)模型輸入:
net.setInput(input)執(zhí)行網(wǎng)絡(luò)推理并得到輸出結(jié)果:
out=net.forward()從網(wǎng)絡(luò)輸出中獲取最大的5個(gè)可能種類的索引值并輸出類別名稱和概率值:
indexes=np.argsort(out[0])[-5:] for?i?in?reversed(indexes):print?('class:',?classes[i],?'?probability:',?out[0][i])通過這個(gè)例子,我們可以看到一個(gè)基于深度學(xué)習(xí)模型的分類應(yīng)用并不復(fù)雜,主要分3部分:模型導(dǎo)入、網(wǎng)絡(luò)執(zhí)行和結(jié)果解析。
小結(jié)
通過本章的學(xué)習(xí),讀者可以了解到OpenCV的主要組成部分,尤其是OpenCV深度學(xué)習(xí)模塊的基本情況。基于C++和Python的例子為讀者展示了OpenCV深度學(xué)習(xí)應(yīng)用的主要流程。
關(guān)于作者:吳至文,Intel亞太研發(fā)有限公司資深圖形圖像工程師,擁有多年算法開發(fā)優(yōu)化經(jīng)驗(yàn),技術(shù)領(lǐng)域涵蓋顯示系統(tǒng)、視覺處理、深度學(xué)習(xí)框架加速,尤其擅長基于OpenCL和Vulkan的算法設(shè)計(jì)及優(yōu)化,是OpenCV DNN模塊Vulkan后端的作者、OpenCL后端主要貢獻(xiàn)者之一。
郭葉軍,Intel資深圖形圖像工程師。多年圖形芯片驅(qū)動(dòng)開發(fā)經(jīng)驗(yàn),主要包括OpenGL驅(qū)動(dòng)和OpenCL驅(qū)動(dòng)。目前關(guān)注視頻分析中的深度學(xué)習(xí),是FFmpeg深度學(xué)習(xí)模塊的代碼維護(hù)者。
宗煒,Intel資深圖形圖像工程師,長期從事計(jì)算機(jī)視覺算法與應(yīng)用、數(shù)字圖像處理、Camera成像算法開發(fā),在CPU/GPU/ISP異構(gòu)計(jì)算算法設(shè)計(jì)與優(yōu)化上經(jīng)驗(yàn)頗豐,是圖像處理與計(jì)算機(jī)視覺算法開源項(xiàng)目libXCam的維護(hù)者和主要貢獻(xiàn)者。
李鵬,阿里巴巴高級(jí)技術(shù)專家,原Intel亞太研發(fā)有限公司資深圖形圖像工程師。涉及領(lǐng)域包括顯示系統(tǒng)、圖形圖像處理、深度學(xué)習(xí)框架加速。是OpenCV DNN模塊OpenCL后端主要貢獻(xiàn)者之一。
趙娟,Intel高級(jí)研發(fā)經(jīng)理,鉆研圖形圖像、視頻編解碼和視頻處理十幾年,帶領(lǐng)團(tuán)隊(duì)深耕視頻編解碼和處理軟硬件加速、深度學(xué)習(xí)算法分析與設(shè)計(jì),致力于讓開源軟件在圖形圖像視頻市場落地,并組織團(tuán)隊(duì)把多年的“干貨”整理成書,與視頻行業(yè)的朋友們一起探討與成長。
本文摘編自《OpenCV深度學(xué)習(xí)應(yīng)用與性能優(yōu)化實(shí)踐》,經(jīng)出版方授權(quán)發(fā)布。
延伸閱讀《OpenCV深度學(xué)習(xí)應(yīng)用與性能優(yōu)化實(shí)踐》
點(diǎn)擊上圖了解及購買
轉(zhuǎn)載請(qǐng)聯(lián)系微信:DoctorData
推薦語:Intel音視頻團(tuán)隊(duì)與阿里巴巴圖像處理專家聯(lián)合撰寫,知名專家聯(lián)袂推薦,深入解析OpenCV DNN 模塊、基于GPU/CPU的加速實(shí)現(xiàn)、性能優(yōu)化技巧與可視化工具,以及人臉活體檢測(完整案例)與主流識(shí)別項(xiàng)目解析。
劃重點(diǎn)????
干貨直達(dá)????
大數(shù)據(jù)、人工智能帶來的危機(jī):科技巨頭會(huì)毀掉我們的生活嗎?
56秒看完131年英格蘭頂級(jí)聯(lián)賽冠軍排行:利物浦時(shí)隔30年再奪冠
一文看懂Python的控制結(jié)構(gòu):for、while、if…都有了
12306驗(yàn)證碼為什么那么變態(tài)?都是這項(xiàng)深度學(xué)習(xí)應(yīng)用給逼的
更多精彩????
在公眾號(hào)對(duì)話框輸入以下關(guān)鍵詞
查看更多優(yōu)質(zhì)內(nèi)容!
PPT?|?讀書?|?書單?|?硬核?|?干貨?|?講明白
大數(shù)據(jù)?|?云計(jì)算?|?數(shù)據(jù)庫?|?Python?|?可視化?|?神操作
AI?|?人工智能?|?機(jī)器學(xué)習(xí)?|?深度學(xué)習(xí)?|?神經(jīng)網(wǎng)絡(luò)
5G?|?中臺(tái)?|?用戶畫像?|?1024?|?大神?|?數(shù)學(xué)?|?揭秘
據(jù)統(tǒng)計(jì),99%的大咖都完成了這個(gè)神操作
????
總結(jié)
以上是生活随笔為你收集整理的OpenCV入门及应用案例:手把手教你做DNN图像分类的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 以5个数据库为例,用Python实现数据
- 下一篇: 阿里动物园新成员来了,10本书带你读懂这