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