OpenCV学习笔记(二十六)——小试SVM算法ml OpenCV学习笔记(二十七)——基于级联分类器的目标检测objdect OpenCV学习笔记(二十八)——光流法对运动目标跟踪Video Ope
OpenCV學習筆記(二十六)——小試SVM算法ml?
總感覺自己停留在碼農的初級階段,要想更上一層,就得靜下心來,好好研究一下算法的東西。OpenCV作為一個計算機視覺的開源庫,肯定不會只停留在數字圖像處理的初級階段,我也得加油,深入研究它的算法庫。就從ml入手吧,最近做東西遇到隨機森林,被搞的頭大,深深感覺自己肚子里貨太少,關鍵時刻調不出東西來。切勿浮躁,一點點研究吧。
這次就先介紹一下機器學習中的一個常用算法SVM算法,即支持向量機Support Vector Machine(SVM),是一種有監督學習方法,更多介紹請見維基百科http://zh.wikipedia.org/wiki/SVM。
OpenCV開發SVM算法是基于LibSVM軟件包開發的,LibSVM是臺灣大學林智仁(Lin Chih-Jen)等開發設計的一個簡單、易于使用和快速有效的SVM模式識別與回歸的軟件包。用OpenCV使用SVM算法的大概流程是
1)設置訓練樣本集
需要兩組數據,一組是數據的類別,一組是數據的向量信息。
2)設置SVM參數
利用CvSVMParams類實現類內的成員變量svm_type表示SVM類型:
CvSVM::C_SVC? C-SVC
CvSVM::NU_SVC v-SVC
CvSVM::ONE_CLASS 一類SVM
CvSVM::EPS_SVR e-SVR
CvSVM::NU_SVR v-SVR
成員變量kernel_type表示核函數的類型:
CvSVM::LINEAR 線性:u‘v
CvSVM::POLY 多項式:(r*u'v + coef0)^degree
CvSVM::RBF RBF函數:exp(-r|u-v|^2)
CvSVM::SIGMOID sigmoid函數:tanh(r*u'v + coef0)
成員變量degree針對多項式核函數degree的設置,gamma針對多項式/rbf/sigmoid核函數的設置,coef0針對多項式/sigmoid核函數的設置,Cvalue為損失函數,在C-SVC、e-SVR、v-SVR中有效,nu設置v-SVC、一類SVM和v-SVR參數,p為設置e-SVR中損失函數的值,class_weightsC_SVC的權重,term_crit為SVM訓練過程的終止條件。其中默認值degree = 0,gamma = 1,coef0 = 0,Cvalue = 1,nu = 0,p = 0,class_weights = 0
3)訓練SVM
調用CvSVM::train函數建立SVM模型,第一個參數為訓練數據,第二個參數為分類結果,最后一個參數即CvSVMParams
4)用這個SVM進行分類
調用函數CvSVM::predict實現分類
5)獲得支持向量
除了分類,也可以得到SVM的支持向量,調用函數CvSVM::get_support_vector_count獲得支持向量的個數,CvSVM::get_support_vector獲得對應的索引編號的支持向量。
實現代碼如下:
[cpp]?view plain?copy
OpenCV學習筆記(二十七)——基于級聯分類器的目標檢測objdect?
OpenCV支持的目標檢測的方法是利用樣本的Haar特征進行的分類器訓練,得到的級聯boosted分類器(Cascade Classification)。注意,新版本的C++接口除了Haar特征以外也可以使用LBP特征。
先介紹一下相關的結構,級聯分類器的計算特征值的基礎類FeatureEvaluator,功能包括讀操作read、復制clone、獲得特征類型getFeatureType,分配圖片分配窗口的操作setImage、setWindow,計算有序特征calcOrd,計算絕對特征calcCat,創建分類器特征的結構create函數。級聯分類器類CascadeClassifier。目標級聯矩形的分組函數groupRectangles。
接下來,我嘗試使用CascadeClassifier這個級聯分類器類檢測視頻流中的目標(haar支持的目標有人臉、人眼、嘴、鼻、身體。這里嘗試比較成熟的人臉和眼鏡)。用load函數加載XML分類器文件(目前提供的分類器包括Haar分類器和LBP分類器(LBP分類器數據較少))具體步驟如下:
這里再補充一點:后來我又進行了一些實驗,對正面人臉分類器進行了實驗,總共有4個,alt、alt2、alt_tree、default。對比下來發現alt和alt2的效果比較好,alt_tree耗時較長,default是一個輕量級的,經常出現誤檢測。所以還是推薦大家使用haarcascade_frontalface_atl.xml和haarcascade_frontalface_atl2.xml。
1)加載級聯分類器
調用CascadeClassifier類成員函數load實現,代碼為:
[cpp]?view plain?copy
2)讀取視頻流
這部分比較基礎啦~~從文件中讀取圖像序列,讀取視頻文件,讀取攝像頭視頻流看過我之前的文章,這3種方法應該了然于心。
3)對每一幀使用該分類器
這里先將圖像變成灰度圖,對它應用直方圖均衡化,做一些預處理的工作。接下來檢測人臉,調用detectMultiScale函數,該函數在輸入圖像的不同尺度中檢測物體,參數image為輸入的灰度圖像,objects為得到被檢測物體的矩形框向量組,scaleFactor為每一個圖像尺度中的尺度參數,默認值為1.1,minNeighbors參數為每一個級聯矩形應該保留的鄰近個數(沒能理解這個參數,-_-|||),默認為3,flags對于新的分類器沒有用(但目前的haar分類器都是舊版的,CV_HAAR_DO_CANNY_PRUNING利用Canny邊緣檢測器來排除一些邊緣很少或者很多的圖像區域,CV_HAAR_SCALE_IMAGE就是按比例正常檢測,CV_HAAR_FIND_BIGGEST_OBJECT只檢測最大的物體,CV_HAAR_DO_ROUGH_SEARCH只做初略檢測),默認為0.minSize和maxSize用來限制得到的目標區域的范圍。這里調用的代碼如下:
[cpp]?view plain?copy
4)顯示目標
這個也比較簡單,調用ellips函數將剛才得到的faces矩形框都顯示出來
更進一步,也可以在得到的每一幅人臉中得到人眼的位置,調用的分類器文件為haarcascade_eye_tree_eyeglasses.xml,先將臉部區域選為興趣區域ROI,重復上訴步驟即可,這里就不詳細介紹了。當然,感興趣的朋友也可以試試其他的xml文件作為分類器玩一下啊,感覺LBP特征雖然xml文件的大小很小,但效果還可以,不過我沒有做過多的測試。光說不練假把式,最后貼上效果圖和源代碼的下載地址
代碼下載地址:http://download.csdn.net/detail/yang_xian521/3800468
OpenCV學習筆記(二十八)——光流法對運動目標跟蹤Video?
OpenCV配套的教程Tutorials對于Video的部分,沒有實例進行說明,我只能摸石頭過河啦,之前試過一個camShift做目標檢測,這次試一試光流法做運動估計。這里使用的光流法是比較常用的?Lucas-Kanade方法。對于光流法的原理,我就不過多介紹了,主要講使用OpenCV如何實現。
首先利用goodFeaturesToTrack函數得到圖像中的強邊界作為跟蹤的特征點,接下來要調用calcOpticalFlowPyrLK函數,輸入兩幅連續的圖像,并在第一幅圖像里選擇一組特征點,輸出為這組點在下一幅圖像中的位置。再把得到的跟蹤結果過濾一下,去掉不好的特征點。再把特征點的跟蹤路徑標示出來。說著好簡單哦~~
程序的效果和代碼下載http://download.csdn.net/detail/yang_xian521/3811478
OpenCV學習筆記(二十九)——視頻前景的提取Video?
視頻捕捉的對象中,背景通常保持不變。一般分析中關注移動的前景物體,威力提取出前景物體,需要建立背景的模型,將模型和當前幀進行比對檢測前景物體。前景提取應用非常廣泛,特別是在智能監控領域中。
如果有不含前景物體的背景圖片,提取前景的工作相對容易,只需要比對當前幀和背景圖片的不同,調用函數absdiff實現。但是大多數情況,獲得背景圖片是不可能的,比如在復雜的場景下,或者有光線條件的變化。因此,就需要動態的變換背景。一種簡單的辦法是對所觀察到的圖片取平均,但這樣做也有很多弊端,首先,這種辦法在計算背景圖片的前需要輸入大量的圖片,其次我們進行取平均的過程中不能有前景物體進入。所以一種相對好的辦法是動態建立背景圖片并實時更新。
具體的實現過程主要分為兩部分:一部分是調用absdiff函數找出當前圖片和背景圖片的區別,這之中使用了threshold函數去除為前景,當前圖片像素與背景圖片像素變化超過一定閾值的時候才認定其為前景;另一個工作是更新背景圖片,調用函數accumulateWeighted,根據權重參數可以調整背景更新的速度,將當前圖片更新到背景中,這里巧妙利用得到的前景提取結果作為mask,在更新背景圖片的過程中避免了前景的干擾。
程序效果如圖,代碼下載地址為http://download.csdn.net/detail/yang_xian521/3814878
雖然可以調整閾值參數和權重更新速度調節前景提取的結果,但從測試視頻可以發現,樹葉的運動對結果的干擾還是不小的,特別對于第一幀出現前景的情況,由于后續更新背景都是對前景mask后對背景進行更新的,所以第一幀的前景部分對背景的影響因子很難被更新掉。這里提出一種改進的辦法——混合高斯模型??梢允挂粋€像素具有更多的信息,這樣可以有效的減少類似樹葉的不停飄動,水波的不停蕩漾這種對前景的干擾。這個精密的算法比之前我所介紹的簡單方法要復雜很多,不易實現。還好,OpenCV已經為我們做好了相關工作,將其封裝在類BackgroundSubtractorMOG,使用起來非常方便。實現代碼如下:
[cpp]?view plain?copy
新程序的效果圖如下,下載地址為 http://download.csdn.net/detail/yang_xian521/3815366
OpenCV學習筆記(三十)——解開VideoInput面紗highgui
最近做一個東西,攝像頭使用的高清攝像頭,采集出來的視頻是D1格式(720*480)。使用VideoCapture發現速度很忙,網上的朋友說VideoCapture提供的讀寫功能采用VFW,效率低下且有些格式支持不好。而 OpenCV 2.0 內置了videoInput Library,可以自動在VFW和DirectShow間切換。videoInput是老外寫的功能強大的開源視頻處理庫。是一個第三方庫,2.0~2.2的版本專門有一個3rdparty對該庫進行支持,而在最新的2.3版本中,已經講videoInput庫集成到highgui中了,想使用它的話,只需要在cmake中設置宏WITH_VIDEOiNPUT=OFF/ON即可。好像我使用的2.3.1自帶的那個build文件夾下面的庫就是在ON條件下編譯得到的,所以就不用cmake重新編譯了。2.3中使用手冊和教程對VideoInput類只字未提,我只好自己摸索了。還好有源代碼可以看,開源偉大。
網上見過其他朋友寫過2.2實現VideoInput的使用,我實驗發現2.3中的使用方法基本沒有變化。后面再把配套例程奉上,先把VideoInput類內的公有成員函數一一介紹一下,該類還有個相關的類是VideoDevice。包括控制是否在控制臺輸出信息開關setVerbose函數,打印出可用視頻設備信息的函數listDevices,之后可以得到設備名函數getDeviceName,視頻捕捉的回調函數設置函數setUseCallback,調整捕捉幀率的函數setIdealFramerate(默認30fps,可修改,但不能被保證準確,directshow會嘗試一個鄰近的幀率),防止設備休眠重新連接的函數setAutoReconnectOnFreeze,開啟設備函數setupDevice,在setpuDevice之前可以設置視頻制式,調用函數為setFormat,檢測是否有新的幀函數isFrameNew,檢測視頻是否開啟isDeviceSetup,獲得數據的函數getPixels(注意這里獲得的數據時uchar型的指針),顯示視頻設置窗口函數showSettingsWindow,控制視頻設置的相關函數有setVideoSettingFilter、setVideoSettingFilterPct、getVideoSettingFilter、setVideoSettingCamera、setVideoSettingCameraPct、getVideoSettingCamera,獲得視頻寬高信息的函數有getWidth、getHeight、getSize,停止設備函數stopDevice,重啟設備函數restartDevice。
講了這么多函數,還是直接上代碼說話吧,我這是找的VideoInput注釋中的一個例程。
[cpp]?view plain?copy
from: http://blog.csdn.net/yang_xian521/article/category/910716
總結
以上是生活随笔為你收集整理的OpenCV学习笔记(二十六)——小试SVM算法ml OpenCV学习笔记(二十七)——基于级联分类器的目标检测objdect OpenCV学习笔记(二十八)——光流法对运动目标跟踪Video Ope的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: OpenCV学习笔记(二十一)——绘图函
- 下一篇: OpenCV学习笔记(三十一)——让de