目錄
一、準(zhǔn)備階段
?二、圖片處理
?三、生成描述文件
?四、生成.vec文件
? 五、生成.xml自定義分類器文件
?六、識別檢測
一、準(zhǔn)備階段
正樣本集:正樣本集為包含“識別物體”的灰度圖,一般大于等于2000張,尺寸不能太大,尺寸太大會導(dǎo)致訓(xùn)練時間過長。
負(fù)樣本集:負(fù)樣本集為不含“識別物體”的任何圖片,一般大于等于5000張,尺寸比正樣本集稍大。一般為正樣品集的3倍。
在當(dāng)前文件夾下新建五個文件夾,pos和neg放處理后的圖片,ini_pos和ini_neg放原來的圖像,xml放以后自定義生成的分類器
將下載的正負(fù)樣本集分別放入ini_pos和ini_neg文件夾。
我百度圖片上下載了船的圖片到ini_pos,魚的圖片到ini_neg
注意:好的正訓(xùn)練集最好還是圖片中只有你需要的物體,而沒有其他物體和背景干擾,百度圖片里面有動圖gif格式圖片,不能通過opencv讀取,下載完后看好圖片后綴。
下面是初始的倆個樣品集
?二、圖片處理
樣品集需要統(tǒng)一大小和統(tǒng)一改為灰度圖
代碼:
import cv2 as cv
import matplotlib.pyplot as plt
import os
#解決中文顯示問題,固定格式,直接復(fù)制下面?zhèn)z行代碼就行
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus']=False
pospath = "./ini_pos"#正樣本集文件夾路徑
pos = os.listdir(pospath)#讀取路徑下的所有文件
negpath = "./ini_neg"
neg = os.listdir(negpath)
#圖片處理,注意圖片不能有g(shù)if格式
def picdif():
global pos,neg;
i=1;
for picname in pos:#遍歷pos文件數(shù)組所有的文件名
#讀取灰度圖
pic=cv.imread(pospath+"\\"+picname)
pic=cv.cvtColor(pic,cv.COLOR_BGR2GRAY)
#修改尺寸
pic=cv.resize(pic,(40,40))
#保存圖片
cv.imwrite("./pos/"+str("%03d"%i)+".jpg",pic)
i+=1
#同理對負(fù)樣本集進(jìn)行處理
j = 1;
for picname in neg: # 遍歷neg文件數(shù)組所有的文件名
#讀取灰度圖
pic=cv.imread(negpath+"\\"+picname)
pic=cv.cvtColor(pic,cv.COLOR_BGR2GRAY)
#修改尺寸
pic=cv.resize(pic,(50,50))
#重命名,并保存圖片
cv.imwrite("./neg/"+str("%03d"%j)+".jpg",pic)
j+=1
if __name__ == '__main__':
# 1.導(dǎo)入文件夾,對圖像統(tǒng)一處理,統(tǒng)一尺寸大小,統(tǒng)一灰度圖
picdif()
處理后的正負(fù)樣本集和圖片:
三、生成描述文件
正樣本描述文件如下:
其中"1"為圖片數(shù)量(0,0)坐標(biāo),(40,40)是正樣本集的長寬
負(fù)樣本描述文件如下:
代碼更新:
a_main.py
import cv2 as cv import os #解決中文顯示問題,固定格式,直接復(fù)制下面?zhèn)z行代碼就行 plt.rcParams['font.sans-serif']=['SimHei'] plt.rcParams['axes.unicode_minus']=False pospath = "./ini_pos"#正樣本集文件夾路徑 pos = os.listdir(pospath)#讀取路徑下的所有文件 negpath = "./ini_neg" neg = os.listdir(negpath) #圖片處理,注意圖片不能有g(shù)if格式 def picdif(): global pos,neg; i=1; for picname in pos:#遍歷pos文件數(shù)組所有的文件名 #讀取灰度圖 pic=cv.imread(pospath+"\\"+picname) pic=cv.cvtColor(pic,cv.COLOR_BGR2GRAY) #修改尺寸 pic=cv.resize(pic,(40,40)) #保存圖片 cv.imwrite("./pos/"+str("%03d"%i)+".jpg",pic) i+=1 #同理對負(fù)樣本集進(jìn)行處理 j = 1; for picname in neg: # 遍歷neg文件數(shù)組所有的文件名 #讀取灰度圖 pic=cv.imread(negpath+"\\"+picname) pic=cv.cvtColor(pic,cv.COLOR_BGR2GRAY) #修改尺寸 pic=cv.resize(pic,(50,50)) #重命名,并保存圖片 cv.imwrite("./neg/"+str("%03d"%j)+".jpg",pic) j+=1 # 描述文件生成 def createtxt(): global pos, neg #正樣本描述文件: for picname in pos: line ="pos/"+picname+" 1 0 0 40 40"+"\n"#"1"為圖片數(shù)量(0,0)是坐標(biāo),(40,40)是正樣本集的w,h with open('pos.txt', 'a') as f: f.write(line) #負(fù)樣本描述文件: for picname in neg: line ="neg/"+picname+"\n"#(0,0)是坐標(biāo),(40,40)是正樣本集的w,h with open('neg.txt', 'a') as f: f.write(line) if __name__ == '__main__': # 1.導(dǎo)入文件夾,對圖像統(tǒng)一處理,統(tǒng)一尺寸大小,統(tǒng)一灰度圖 picdif() #pos和neg改成處理后的圖片文件夾; pospath = "./pos"#正樣本集文件夾路徑 pos = os.listdir(pospath)#讀取路徑下的所有文件 negpath = "./neg" neg = os.listdir(negpath) #2.正負(fù)樣本描述文件的生成 createtxt()
?四、生成.vec文件
獲取opencv_createsamples.exe和opencv_traincascade.exe
這兩個軟件在opencv安裝包里是沒有的,只有下載opencv以及opencv_contrib源碼自己編譯才會生成這兩個可執(zhí)行程序
我是直接下載別人的程序,下面是網(wǎng)址
opencv341_bin: 編譯opencv以及opencv_contrib以后的bin文件夾,里面包含一些可執(zhí)行程序https://gitee.com/lizaozao/opencv341_bin注意下載依賴項解壓到opencv_createsamples.exe和opencv_traincascade.exe同一目錄下
在該主目錄文件下打開終端窗口,win11可直接通過右鍵“在終端打開”
輸入
.\opencv_createsamples.exe -info pos.txt -vec detect_number.vec -bg neg.txt -num 19 -w 40 -h 40
-info 正樣本txt
-vec 是你生成vec文件的位置和名稱
-bg 負(fù)樣本txt
-num 正樣本數(shù)量
-w 正樣本寬度
-h 正樣本高度
? 五、生成.xml自定義分類器文件
當(dāng)前主目錄文件夾終端下輸入
./opencv_traincascade.exe -data xml -vec detect_number.vec -bg neg.txt -numPos 19 -numNeg 25 -numStages 20 -featureType HAAR -w 40 -h 40
-data 前面創(chuàng)建好的xml文件夾
-vec 是你之前生成vec文件
-bg 負(fù)樣本集txt
-numPos 正樣本的數(shù)量
-numNeg 負(fù)樣本的數(shù)量
-numStages 訓(xùn)練步數(shù)
-featureType 特征類型?訓(xùn)練時,提取圖像特征的類型,目前只支持LBP、HOG、Haar三種特征。但是HAAR訓(xùn)練非常非常的慢,而LBP則相對快很多,因為HAAR需要浮點運算,精度自然比LBP更高
-w -h 正樣本的寬高
結(jié)果:
由于樣本較少,訓(xùn)練十秒就完成了
?六、識別檢測
上一節(jié)課已經(jīng)說了,直接上代碼
[圖像識別]12.Opencv案例 超簡單人臉檢測識別_ζ?? ??霧 ??狼 ???的博客-CSDN博客1.原理:我們使用機(jī)器學(xué)習(xí)的方法完成人臉檢測,首先需要大量的正樣本圖像(面部圖像)和負(fù)樣本圖像(不含面部的圖像)來訓(xùn)練分類器。我們需要從其中提取特征。Haar特征(這個值等于黑色矩形中的像素值之后減去白色矩形中的像素值和。)會被使用,就像我們的卷積核,每一個特征是一個值。Haar特征值反映了圖像的灰度變化情況。Haar特征可用于于圖像任意位置,大小也可以任意改變,所以矩形特征值是矩形模版類別、矩形位置和矩形大小這三個因素的函數(shù)。故類別、大小和位置的變化,使得很小的檢測窗口含有非常多的矩形特征。https://blog.csdn.net/qq_54263076/article/details/127155374?spm=1001.2014.3001.5501
main.py文件
import cv2 as cv import matplotlib.pyplot as plt #解決中文顯示問題,固定格式,直接復(fù)制下面?zhèn)z行代碼就行 plt.rcParams['font.sans-serif']=['SimHei'] plt.rcParams['axes.unicode_minus']=False # 加載分類器 cascade = cv.CascadeClassifier("./xml/cascade.xml") cascade.load("./xml/cascade.xml") # 讀取灰度圖片 pic1 = cv.imread("boat.jpg") pic2= cv.imread("./ini_neg/0b46f21fbe096b639ef96b67fc926942eaf8ac49.jpeg") pic1=cv.resize(pic1,(100,100)) pic2=cv.resize(pic2,(400,400)) pic2[200:300,100:200]=pic1 gray = cv.cvtColor(pic2,cv.COLOR_BGR2GRAY) # 探測圖片中的船只 faces = cascade.detectMultiScale( gray, scaleFactor = 1.1, minNeighbors = 150, minSize = (50,50), ) #繪制矩形 pic3=pic2.copy() for (x,y,w,h) in faces: cv.rectangle(pic3,(x,y),(x+h,y+w),(0,0,255),5) #繪圖 fig,axes=plt.subplots(nrows=1,ncols=2) axes[0].imshow(pic2[:,:,::-1]) axes[0].set_title("原圖") axes[1].imshow(pic3[:,:,::-1]) axes[1].set_title("識別") plt.show() cv.waitKey()
由于所選樣本太太太太少,且有些正樣本不純不好,導(dǎo)致結(jié)果偏差比較大
根據(jù)以上教程,可以不斷像文件夾添加樣本圖片達(dá)到上千,生成.vec和.xml文件,完成自己的物品識別,完整代碼放在下面,可以自己下載修改文章來源:http://www.zghlxwxcb.cn/news/detail-456398.html
https://download.csdn.net/download/qq_54263076/86736208https://download.csdn.net/download/qq_54263076/86736208文章來源地址http://www.zghlxwxcb.cn/news/detail-456398.html
到了這里,關(guān)于(終章)[圖像識別]13.OpenCV案例 自定義訓(xùn)練集分類器物體檢測的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!