本文將使用opencv-python識別自定義物體,能夠區(qū)分識別到的物體,如果用作人臉識別,則能夠區(qū)分出不同的人臉id,也就是能夠分得清張三,李四,王二麻子
?
本文提供的所有資源僅供學(xué)習(xí)使用,不可商用
?
文末有完整工程鏈接
?
效果:
?
識別出局座,大緊,大眾和沃爾沃
?
vs2017+python+opencv配置請參考https://blog.csdn.net/qq_43440703/article/details/88375609
本文中文亂碼問題參考博客https://blog.csdn.net/qq_39622065/article/details/84859629
?
為什么能讓程序識別出我們想要讓它識別的物體,程序怎么能認(rèn)得哪個是我們想要識別的物體
此時我們需要事先訓(xùn)練程序,我們需要事先告訴它,哪個人是局座,哪個人是大緊,哪個車是沃爾沃,哪個車是大眾
如何訓(xùn)練程序去認(rèn)識這些人和物,我們在本文最后去講
?
本教程中出現(xiàn)的所有的訓(xùn)練數(shù)據(jù)文件都包含在文末的工程文件中,下載后可直接運行
?
注意:
本教程只使用了少量的樣本訓(xùn)練,精度一般,主要是了解思想
本教程中對應(yīng)物體的訓(xùn)練數(shù)據(jù)僅對本視頻文件有較好的識別概率,其他場景效果不行
如果需要在任何場景中都能識別局座或者其他人和物,需要重新使用大量到的樣本數(shù)據(jù)去訓(xùn)練,需要成千上萬個樣本,本程序只是一個示例教程
掌握了思想,就可以自己去準(zhǔn)備樣本去訓(xùn)練
?
?
程序?qū)崿F(xiàn):
新建一個Python應(yīng)用程序
安裝opencv-python
?
from PIL import Image, ImageDraw, ImageFont
import cv2
import numpy as np
import time
#由于直接用opencv顯示中文會亂碼,所以先將圖片格式轉(zhuǎn)化為PIL庫的格式,用PIL的方法寫入中文,然后在轉(zhuǎn)化為CV的格式
def change_cv2_draw(image,strs,local,sizes,colour):
cv2img = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
pilimg = Image.fromarray(cv2img)
draw = ImageDraw.Draw(pilimg)
font = ImageFont.truetype("SIMYOU.TTF",sizes, encoding="utf-8") #SIMYOU.TTF為字體文件
draw.text(local, strs, colour, font=font)
image = cv2.cvtColor(np.array(pilimg), cv2.COLOR_RGB2BGR)
return image
#src為輸入的圖像
#classifier為對應(yīng)識別物體的分類器
#strs為識別出的物體的中文說明
#colors表示框的顏色
#minSize為識別物體的最小尺寸,當(dāng)識別的物體尺寸低于這個尺寸,則不檢測,就當(dāng)沒識別到
#minSize為識別物體的最大尺寸,當(dāng)大于該尺寸時不識別
def myClassifier(src,classifier,strs,colors,minSize,maxSize):
gray=cv2.cvtColor(src,cv2.COLOR_BGR2GRAY)
#detectMultiScale()方法里面的參數(shù)在另一篇博客中有詳解:https://blog.csdn.net/GottaYiWanLiu/article/details/90442274
obj = classifier.detectMultiScale(gray,scaleFactor = 1.15, minNeighbors = 5,minSize=minSize,maxSize=maxSize)
for (x,y,w,h) in obj:
cv2.rectangle(src,(x,y),(x+w,y+w),colors,2) #畫框,(x,y)為識別物體的左上角頂點,(w,h)為寬和高
src=change_cv2_draw(src,strs,(x,y-20),20,colors)#顯示中文
return src
#讀取視頻文件 若 cap=cv2.VideoCapture(0),則為獲取攝像頭畫面
cap=cv2.VideoCapture("001.mp4")
#讀取對應(yīng)物體的訓(xùn)練數(shù)據(jù), 注意,以下這些訓(xùn)練數(shù)據(jù)僅對本視頻文件有較好的識別概率,其他場景不行
#其他場景中,需要重新使用大量到的樣本數(shù)據(jù)去訓(xùn)練,本程序只是一個示例教程
juzuo=cv2.CascadeClassifier("juzuo.xml") #局座人臉的訓(xùn)練數(shù)據(jù)
dajin=cv2.CascadeClassifier("dajin.xml") #大緊人類的訓(xùn)練數(shù)據(jù)
volvo=cv2.CascadeClassifier("volvo.xml") #沃爾沃汽車的訓(xùn)練數(shù)據(jù)
volkswagen=cv2.CascadeClassifier("volkswagen.xml") #大眾汽車的訓(xùn)練數(shù)據(jù)
while True:
_,frame=cap.read()
frame=myClassifier(frame,juzuo,"局座",(0,0,255),(40,40),(60,60))
frame=myClassifier(frame,dajin,"大緊",(0,255,0),(40,40),(70,70))
frame=myClassifier(frame,volvo,"沃爾沃",(255,0,0),(35,35),(70,70))
frame=myClassifier(frame,volkswagen,"大眾",(0,255,255),(40,40),(70,70))
cv2.imshow("frame",frame)
cv2.waitKey(30)
如果想按Esc鍵退出程序
將最后一行改為:
c=cv2.waitKey(30)
if c==27:
? ?cv2.destroyAllWindows()
? ?break
?
所有參數(shù)說明看注釋
?
?
如何訓(xùn)練我們想要識別的物體?
?
參考博客:
https://blog.csdn.net/qq_32502511/article/details/79010509
?
?
首先我們需要安裝3.0以上4.0以下的opencv
本人使用的opencv3.4.0
官網(wǎng)下載:https://opencv.org/releases/page/2/
安裝完以后
在路徑opencv\build\x64\vc14\bin\下有我們需要的訓(xùn)練程序
opencv_createsamples.exe和opencv_traincascade.exe
?
以本文為例:
首先新建一個文件夾取名 JuZuo
然后將opencv\build\x64\vc14\bin\下的所有文件復(fù)制到該文件夾下
然后在此文件夾下再新建一個pos文件夾,一個neg文件夾,一個xml文件夾
如下圖所示:
?
?
其中neg文件夾保存我們的負(fù)樣本
pos文件夾保存我們的正樣本,
正負(fù)樣本都是圖片文件
正樣本就是我們需要識別的物體的圖片,而負(fù)樣本中不能出現(xiàn)正樣本
?
負(fù)樣本下載(本人花積分從csdn上下載的):
我推薦自己去網(wǎng)上搜,尊重別人勞動成果,我本來想把我下載的博主的鏈接粘貼過來,結(jié)果找了半天沒找到
先用這個吧
鏈接:https://pan.baidu.com/s/1ahJA6BsY4oVL20oY3GSQjg?
提取碼:2o95?
?
負(fù)樣本的尺寸沒有具體要求,只要比正樣本大就行
而正樣本,尺寸需要統(tǒng)一,為了保準(zhǔn)訓(xùn)練的速度,本文正樣本圖片尺寸統(tǒng)一20x20
需要使用ps或者其他軟件裁剪一下
?
局座正樣本下載(本人一點一點的裁的):
鏈接:https://pan.baidu.com/s/1Erwm59tzfdDHL3HTnu4QpA?
提取碼:gi7p?
?
然后將負(fù)樣本所有圖片放到neg文件夾下
將局座的所有正樣本圖片放到pos文件夾下
?
然后win+r? ?輸入cmd,打開cmd
比如本人的JuZuo文件夾在D盤
則輸入?d:? ?然后回車
然后來到我們的負(fù)樣本文件夾
輸入:cd?D:\JuZuo\neg? 回車
此時我們已經(jīng)進(jìn)入neg文件夾
輸入:dir /b/s/p/w *.jpg > neg.txt? 回車
此時會在neg文件末尾生成一個neg.txt文件
然后我們進(jìn)入pos文件夾
輸入 cd?D:\JuZuo\pos? 回車
此時我們輸入:dir /b/s/p/w *.jpg > pos.txt? 回車
此時會在pos文件末尾生成一個pos.txt文件
如下圖:
?
此時我們將neg.txt和pos.txt文件都移動到D:\JuZuo\路徑下
即移動到上一層目錄
此時我們需要修改一下pos.txt
此時我們借助Notepad++程序,百度Notepad++下載
右鍵pos.txt,使用Notepad++打開
然后 按?Ctrl+H
將所有的jpg替換成jpg 1 0 0 20 20
替換完后:
一定要記得保存
?
?
修改完后,
在回到D:\JuZuo\文件夾下
在cmd 命令提示符里輸入: cd?D:\JuZuo 回車
然后輸入:opencv_createsamples.exe -vec pos.vec -info pos.txt -num 200 -w 20 -h 20 回車
其中-num 后面的200,是正樣本的數(shù)量,比如有300個正樣本,不一定要用滿,比如我用200個,后面兩個20 就是正樣本的尺寸
如下圖:
?
此時會在JiuZuo文件夾下創(chuàng)建一個pos.vec文件
此時我們新建一個文本文檔
命名任意,但是需要將后綴名改為bat,比如start.bat
如下圖:
?
此時右鍵start.bat,編輯
opencv_traincascade.exe -data xml -vec pos.vec -bg neg.txt -numPos 200 -numNeg 400 -numStages 15 -w 20 -h 20 -maxFalseAlarmRate 0.4 -precalcValBufSize 2048 -precalcIdxBufSize 2048 -mode ALL
pause
將這一段話復(fù)制進(jìn)去保存
numPos為正樣本數(shù)量,numNeg為負(fù)樣本數(shù)量,numStages為分類器的級數(shù),w和h為正樣本的寬和高,maxFalseAlarmRate為最大誤報率,precalcValBufSize為緩存大小,用于存儲預(yù)先計算的特征值單位為MB,precalcIdxBufSize為緩存大小,用于存儲預(yù)先計算的特征索引(feature indices),單位為MB。內(nèi)存越大,訓(xùn)練時間越短。
具體參數(shù)說明請參考官方文檔:
https://www.baidu.com/link?url=qZmbQOIgAdjLrWTy0-JAZW5UvMbHYuPDA0sDtGEPvJTLh2hPc56dccEq_9q6yYtSvBBciUE9cQrUYN8iTlec7a3lAPAlaBQd3X60WHvPm7qJcMPTNcwSuVcfQHdrJRoF&wd=&eqid=8cd1a75100010c7b000000055ce60780
然后雙擊start.bat啟動
?
然后會在xml中生成cascade.xml文件,此文件就是訓(xùn)練后的文件
我們只需在代碼中讀取此文件即可
?
?
工程鏈接:
鏈接:https://pan.baidu.com/s/1cK19bZkNFwnQDBxAo9UDfg?
提取碼:fosm?
?
?
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
