python 作物识别_Python-OpenCV —— 物体识别(TrainCascadeClassification)
在上次教程Python-OpenCV —— Machine Learning講述了如何建立模型,進(jìn)行訓(xùn)練,然后利用模型對(duì)新獲得的照片進(jìn)行預(yù)測(cè)并給出預(yù)測(cè)值,本期教程針對(duì)某個(gè)特定的物體進(jìn)行檢測(cè),將其標(biāo)記出來,分為3個(gè)步驟,第一:訓(xùn)練特定物體,第二:
訓(xùn)練模型
級(jí)聯(lián)分類器
前幾天看到一個(gè)笑話,很有意思,說的是
理論就是你什么都知道但是什么都干不了
實(shí)踐就是你什么都能干但是不知道為什么
我就不一樣了,我可以理論與實(shí)踐相結(jié)合——什么都干不了而且不知道為什么
開個(gè)玩笑,目前有很大一部分的東西都是人們實(shí)踐得來的經(jīng)驗(yàn),有些東西也許很好用,但未必是好理論,比如現(xiàn)在的深度學(xué)習(xí),扯遠(yuǎn)了,繼續(xù)今天的話題,到底什么是級(jí)聯(lián)分類器,其實(shí)就是把分類器按照一定的順序聯(lián)合到一起。一個(gè)分類器也許不好用,沒關(guān)系,我給你多加幾個(gè),俗話說得好,三個(gè)臭皮匠,頂個(gè)諸葛亮呢。
具體來說,OpenCV實(shí)現(xiàn)的Cascade(級(jí)聯(lián))分類器就是基于多個(gè)弱分類器對(duì)不同的特征進(jìn)行依次處理(分類)來完成對(duì)目標(biāo)的檢測(cè),簡(jiǎn)單的說有多個(gè)弱分類器串起來,然后提取每個(gè)平滑窗上的不同特征,把這些特征依次放進(jìn)不同的弱分類器里判斷,如果所有的弱分類器都判斷正標(biāo)簽,則表示該該平滑窗內(nèi)檢測(cè)到目標(biāo)。這樣做的好處是不但通過多個(gè)弱分類器來形成一個(gè)強(qiáng)的級(jí)聯(lián)分類器,而且可以減少運(yùn)算量,比如當(dāng)一個(gè)平滑窗第一個(gè)特征沒有通過第一個(gè)分類器,那么就沒有必要繼續(xù)運(yùn)算下去,直接拒絕掉當(dāng)前平滑窗,轉(zhuǎn)而處理下一個(gè)平滑窗,事實(shí)上作者的目的就是為了快速拋棄沒有目標(biāo)的平滑窗,從而達(dá)到快速檢測(cè)目標(biāo)。
本次用到了OpenCV的兩個(gè)程序,分別是opencv_createsamples.exe和opencv_traincascade.exe,分別用來創(chuàng)建樣本文件和訓(xùn)練級(jí)聯(lián)分類器。
準(zhǔn)備訓(xùn)練數(shù)據(jù)
正樣本
正樣本就是你要檢測(cè)的東西,比如說香蕉、車牌、酒瓶、紅綠燈等等,你可以找相關(guān)的數(shù)據(jù)集,或者自己手動(dòng)截圖,只取你想要識(shí)別的那部分,下面我給了一個(gè)小程序用來將你截取的圖片都變成統(tǒng)一大小。
#改變圖片尺寸為統(tǒng)一大小,在當(dāng)前目錄創(chuàng)建一個(gè)名為pos的文件夾
#把需要統(tǒng)一尺寸的正樣本放到里面,寫上尺寸,運(yùn)行程序就可以了,一般來說建議長(zhǎng)寬在100像素一下,不然訓(xùn)練會(huì)很慢
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('暫停一下')
修改完圖片尺寸之后,需要生成圖片的路徑,我也寫了一個(gè)代碼,運(yùn)行后,會(huì)在當(dāng)前目錄生成一個(gè)如圖所示的文件
pos.txt
每一行分別代表文件路徑 1代表里面有幾個(gè)目標(biāo),咱們用的截取好的,所以只有一個(gè),然后 0 0 60 120 分別代表著圖片的起始像素和終止像素的長(zhǎng)寬
#會(huì)在當(dāng)前目錄生成一個(gè)如圖所示的文件,記得修改 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生成正樣本文件了,寫了一個(gè)批處理文件,新建crate_samples.bat,打開編輯
"在此處寫上你的opencv_createsamples.exe路徑" -info "pos.txt" -vec pos.vec -num 200 -w 60 -h 120
一些參數(shù)解釋:
info 輸入正樣本描述文件
img 輸入圖像文件名,默認(rèn)NULL
bg 負(fù)樣本描述文件,文件中包含一系列的被隨機(jī)選作物體背景的圖像文件名,默認(rèn)NULL
num 生成正樣本的數(shù)目,默認(rèn)1000
bgcolor 背景顏色,表示透明顏色,默認(rèn)0
bgthresh 顏色容差,所有處于bgcolor- bgthresh和bgcolor+bgthresh之間的像素被置為透明像素,也就是將白噪聲加到前景圖像上,默認(rèn)80
inv 前景圖像顏色翻轉(zhuǎn)標(biāo)志,如果指定顏色翻轉(zhuǎn),默認(rèn)0(不翻轉(zhuǎn))
randinv 如果指定顏色將隨機(jī)翻轉(zhuǎn),默認(rèn)0
maxidev 前景圖像中像素的亮度梯度最大值,默認(rèn)40
maxxangle X軸最大旋轉(zhuǎn)角度,以弧度為單位,默認(rèn)1.1
maxyangle Y軸最大旋轉(zhuǎn)角度,以弧度為單位,默認(rèn)1.1
maxzangle Z軸最大旋轉(zhuǎn)角度,以弧度為單位,默認(rèn)0.5
輸入圖像沿著三個(gè)軸進(jìn)行旋轉(zhuǎn),旋轉(zhuǎn)角度由上述3個(gè)值限定。
show 如果指定,每個(gè)樣本都將被顯示,按下Esc鍵,程序?qū)⒗^續(xù)創(chuàng)建樣本而不在顯示,默認(rèn)為0(不顯示)
scale 顯示圖像的縮放比例,默認(rèn)4.0
w 輸出樣本寬度,默認(rèn)24
h 輸出樣本高度,默認(rèn)24
vec 輸出用于訓(xùn)練的.vec文件
負(fù)樣本
負(fù)樣本只需要生成路徑文件,不需要生成vec文件,具體步驟跟上面類似,要注意的是負(fù)樣本要盡可能比正樣本多,大概十倍的樣子吧。
開始訓(xùn)練
新建一個(gè)文件夾TrainCascadeClassification,一會(huì)訓(xùn)練好的文件就在這里
新建一個(gè)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 訓(xùn)練的分類器的存儲(chǔ)目錄
vec 正樣本文件,由open_createsamples.exe生成,正樣本文件后綴名為.vec
bg 負(fù)樣本說明文件,主要包含負(fù)樣本文件所在的目錄及負(fù)樣本文件名
numPos 每級(jí)分類器訓(xùn)練時(shí)所用到的正樣本數(shù)目,應(yīng)小于vec文件中正樣本的數(shù)目,具體數(shù)目限制條件為:numPos+(numStages- 1)numPos(1- minHitRate)<=vec文件中正樣本的數(shù)目。根據(jù)我的經(jīng)驗(yàn),一般為正樣本文件的80%
numNeg 每級(jí)分類器訓(xùn)練時(shí)所用到的負(fù)樣本數(shù)目,可以大于- bg指定的圖片數(shù)目。根據(jù)我的經(jīng)驗(yàn),一般為numPos的2-3倍
numStages 訓(xùn)練分類器的級(jí)數(shù),強(qiáng)分類器的個(gè)數(shù)。根據(jù)我的經(jīng)驗(yàn),一般為12-20
precalcValBufSize 緩存大小,用于存儲(chǔ)預(yù)先計(jì)算的特征值,單位MB,根據(jù)自己內(nèi)存大小分配
precalcIdxBufSize 緩存大小,用于存儲(chǔ)預(yù)先計(jì)算的特征索引,單位MB,根據(jù)自己內(nèi)存大小分配
featureType 訓(xùn)練使用的特征類型,目前支持的特征有Haar,LBP和HOG
w 訓(xùn)練的正樣本的寬度
h 訓(xùn)練的正樣本的高
進(jìn)階參數(shù)
minHitRate 影響每個(gè)強(qiáng)分類器閾值,每一級(jí)分類器最小命中率,表示每一級(jí)強(qiáng)分類器對(duì)正樣本的的分類準(zhǔn)確率
maxFalseAlarm 最大虛警率,影響弱分類器的閾值,表示每個(gè)弱分類器將負(fù)樣本誤分為正樣本的比例,一般默認(rèn)值為0.5
weightTrimRate 0- 1之間的閾值,影響參與訓(xùn)練的樣本,樣本權(quán)重更新排序后(從小到大),從前面累計(jì)權(quán)重小于(1- weightTrimRate)的樣本將不參與下一次訓(xùn)練,一般默認(rèn)值為0.95
maxDepth 每一個(gè)弱分類器決策樹的深度,默認(rèn)是1,是二叉樹(stumps),只使用一個(gè)特征。
maxWeakCount 每級(jí)強(qiáng)分類器中弱分類器的最大個(gè)數(shù),當(dāng)FA降不到指定的maxFalseAlarm時(shí)可以通過指定最大弱分類器個(gè)數(shù)停止單個(gè)強(qiáng)分類器
這個(gè)時(shí)候先看一下我們的工作目錄下都有那些東西,沒有的話,記得補(bǔ)全它。
工作目錄
然后打開train.bat,等著就可以了,訓(xùn)練結(jié)束后,會(huì)得到自己的xml文件,就可以調(diào)用了。
總結(jié)
以上是生活随笔為你收集整理的python 作物识别_Python-OpenCV —— 物体识别(TrainCascadeClassification)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: lisp读写cass属性_130507A
- 下一篇: websocket python爬虫_p