在上次教程Python-OpenCV —— Machine Learning講述了如何建立模型,進行訓練哩陕,然后利用模型對新獲得的照片進行預測并給出預測值,本期教程針對某個特定的物體進行檢測,將其標記出來腻菇,分為3個步驟园细,第一:訓練特定物體惦积,第二:
訓練模型
級聯(lián)分類器
前幾天看到一個笑話,很有意思猛频,說的是
- 理論就是你什么都知道但是什么都干不了
- 實踐就是你什么都能干但是不知道為什么
- 我就不一樣了狮崩,我可以理論與實踐相結(jié)合——什么都干不了而且不知道為什么
開個玩笑,目前有很大一部分的東西都是人們實踐得來的經(jīng)驗鹿寻,有些東西也許很好用睦柴,但未必是好理論,比如現(xiàn)在的深度學習毡熏,扯遠了坦敌,繼續(xù)今天的話題,到底什么是級聯(lián)分類器痢法,其實就是把分類器按照一定的順序聯(lián)合到一起恬试。一個分類器也許不好用,沒關系疯暑,我給你多加幾個训柴,俗話說得好,三個臭皮匠妇拯,頂個諸葛亮呢幻馁。
具體來說,OpenCV實現(xiàn)的Cascade(級聯(lián))分類器就是基于多個弱分類器對不同的特征進行依次處理(分類)來完成對目標的檢測越锈,簡單的說有多個弱分類器串起來仗嗦,然后提取每個平滑窗上的不同特征,把這些特征依次放進不同的弱分類器里判斷甘凭,如果所有的弱分類器都判斷正標簽稀拐,則表示該該平滑窗內(nèi)檢測到目標。這樣做的好處是不但通過多個弱分類器來形成一個強的級聯(lián)分類器丹弱,而且可以減少運算量德撬,比如當一個平滑窗第一個特征沒有通過第一個分類器铲咨,那么就沒有必要繼續(xù)運算下去,直接拒絕掉當前平滑窗蜓洪,轉(zhuǎn)而處理下一個平滑窗纤勒,事實上作者的目的就是為了快速拋棄沒有目標的平滑窗,從而達到快速檢測目標隆檀。
本次用到了OpenCV的兩個程序摇天,分別是opencv_createsamples.exe
和opencv_traincascade.exe
,分別用來創(chuàng)建樣本文件和訓練級聯(lián)分類器恐仑。
準備訓練數(shù)據(jù)
正樣本
正樣本就是你要檢測的東西泉坐,比如說香蕉、車牌裳仆、酒瓶坚冀、紅綠燈等等,你可以找相關的數(shù)據(jù)集鉴逞,或者自己手動截圖记某,只取你想要識別的那部分,下面我給了一個小程序用來將你截取的圖片都變成統(tǒng)一大小构捡。
#改變圖片尺寸為統(tǒng)一大小,在當前目錄創(chuàng)建一個名為pos的文件夾
#把需要統(tǒng)一尺寸的正樣本放到里面液南,寫上尺寸,運行程序就可以了勾徽,一般來說建議長寬在100像素一下滑凉,不然訓練會很慢
import cv2
import os
w = **
h = **
def getimage(file_dir):
images = {}
for root, dirs, files in os.walk(file_dir):
for name in files:
images[name] = os.path.join(root,name)
return images
if __name__ == '__main__':
n=-1
aa = os.getcwd()
dirpath = os.path.join(aa, 'pos')
imagedic = getimage(dirpath)
try :
for key,value in imagedic.items():
img = cv2.imread(value)
img1 = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img2 = cv2.resize(img1,(w,h))
cv2.imwrite('pos'+str(n+1).rjust(3,'0')+'.jpg',img2)
n+=1
except KeyboardInterrupt:
print('暫停一下')
修改完圖片尺寸之后,需要生成圖片的路徑喘帚,我也寫了一個代碼畅姊,運行后,會在當前目錄生成一個如圖所示的文件
每一行分別代表文件路徑 1代表里面有幾個目標吹由,咱們用的截取好的若未,所以只有一個,然后 0 0 60 120 分別代表著圖片的起始像素和終止像素的長寬
#會在當前目錄生成一個如圖所示的文件倾鲫,記得修改 w h 為上面修改后的尺寸值
import os
def getimage(file_dir):
images = {}
for root, dirs, files in os.walk(file_dir):
for name in files:
images[name] = os.path.join(root,name)
return images
if __name__ == '__main__':
n=0
aa = os.getcwd()
dirpath = os.path.join(aa, 'pos')
imagedic = getimage(dirpath)
#print (imagedic)
try :
for key,value in imagedic.items():
with open ('pos.txt','a') as f:
f.write('pos/'+str(key).rjust(3,'0')+' 1 0 0 w h''\n')
except KeyboardInterrupt:
print('暫停一下')
接下來就要用opencv_createsamples.exe
生成正樣本文件了粗合,寫了一個批處理文件,新建crate_samples.bat乌昔,打開編輯
"在此處寫上你的opencv_createsamples.exe路徑" -info "pos.txt" -vec pos.vec -num 200 -w 60 -h 120
一些參數(shù)解釋:
info 輸入正樣本描述文件
img 輸入圖像文件名隙疚,默認NULL
bg 負樣本描述文件,文件中包含一系列的被隨機選作物體背景的圖像文件名磕道,默認NULL
num 生成正樣本的數(shù)目供屉,默認1000
bgcolor 背景顏色,表示透明顏色,默認0
bgthresh 顏色容差伶丐,所有處于bgcolor- bgthresh和bgcolor+bgthresh之間的像素被置為透明像素悼做,也就是將白噪聲加到前景圖像上,默認80
inv 前景圖像顏色翻轉(zhuǎn)標志撵割,如果指定顏色翻轉(zhuǎn)贿堰,默認0(不翻轉(zhuǎn))
randinv 如果指定顏色將隨機翻轉(zhuǎn)辙芍,默認0
maxidev 前景圖像中像素的亮度梯度最大值啡彬,默認40
maxxangle X軸最大旋轉(zhuǎn)角度,以弧度為單位故硅,默認1.1
maxyangle Y軸最大旋轉(zhuǎn)角度庶灿,以弧度為單位秸抚,默認1.1
maxzangle Z軸最大旋轉(zhuǎn)角度毁兆,以弧度為單位,默認0.5
輸入圖像沿著三個軸進行旋轉(zhuǎn)椭盏,旋轉(zhuǎn)角度由上述3個值限定徘层。
show 如果指定峻呕,每個樣本都將被顯示,按下Esc鍵趣效,程序?qū)⒗^續(xù)創(chuàng)建樣本而不在顯示瘦癌,默認為0(不顯示)
scale 顯示圖像的縮放比例,默認4.0
w 輸出樣本寬度跷敬,默認24
h 輸出樣本高度讯私,默認24
vec 輸出用于訓練的.vec文件
負樣本
負樣本只需要生成路徑文件,不需要生成vec文件西傀,具體步驟跟上面類似斤寇,要注意的是負樣本要盡可能比正樣本多,大概十倍的樣子吧拥褂。
開始訓練
新建一個文件夾TrainCascadeClassification娘锁,一會訓練好的文件就在這里
新建一個train.bat,編輯
"你的opencv_traincascade.exe目錄" -data "你的TrainCascadeClassification目錄" -vec pos.vec -bg neg.txt -numPos 160 -numNeg 500 -numStages 15 -precalcValBufSize 3000 -precalcIdxBufSize 3000 -featureType LBP -w 60 -h 120
Pause
一些參數(shù)解釋
- data 訓練的分類器的存儲目錄
- vec 正樣本文件饺鹃,由open_createsamples.exe生成致盟,正樣本文件后綴名為.vec
- bg 負樣本說明文件,主要包含負樣本文件所在的目錄及負樣本文件名
- numPos 每級分類器訓練時所用到的正樣本數(shù)目尤慰,應小于vec文件中正樣本的數(shù)目馏锡,具體數(shù)目限制條件為:numPos+(numStages- 1)numPos(1- minHitRate)<=vec文件中正樣本的數(shù)目。根據(jù)我的經(jīng)驗伟端,一般為正樣本文件的80%
- numNeg 每級分類器訓練時所用到的負樣本數(shù)目杯道,可以大于- bg指定的圖片數(shù)目。根據(jù)我的經(jīng)驗,一般為numPos的2-3倍
- numStages 訓練分類器的級數(shù)党巾,強分類器的個數(shù)萎庭。根據(jù)我的經(jīng)驗,一般為12-20
- precalcValBufSize 緩存大小齿拂,用于存儲預先計算的特征值驳规,單位MB,根據(jù)自己內(nèi)存大小分配
- precalcIdxBufSize 緩存大小署海,用于存儲預先計算的特征索引吗购,單位MB,根據(jù)自己內(nèi)存大小分配
- featureType 訓練使用的特征類型砸狞,目前支持的特征有Haar捻勉,LBP和HOG
- w 訓練的正樣本的寬度
- h 訓練的正樣本的高
進階參數(shù)
- minHitRate 影響每個強分類器閾值,每一級分類器最小命中率刀森,表示每一級強分類器對正樣本的的分類準確率
- maxFalseAlarm 最大虛警率踱启,影響弱分類器的閾值,表示每個弱分類器將負樣本誤分為正樣本的比例研底,一般默認值為0.5
- weightTrimRate 0- 1之間的閾值埠偿,影響參與訓練的樣本,樣本權重更新排序后(從小到大)榜晦,從前面累計權重小于(1- weightTrimRate)的樣本將不參與下一次訓練冠蒋,一般默認值為0.95
- maxDepth 每一個弱分類器決策樹的深度,默認是1芽隆,是二叉樹(stumps)浊服,只使用一個特征。
- maxWeakCount 每級強分類器中弱分類器的最大個數(shù)胚吁,當FA降不到指定的maxFalseAlarm時可以通過指定最大弱分類器個數(shù)停止單個強分類器
這個時候先看一下我們的工作目錄下都有那些東西牙躺,沒有的話,記得補全它腕扶。
然后打開train.bat,等著就可以了孽拷,訓練結(jié)束后,會得到自己的xml文件半抱,就可以調(diào)用了脓恕。