這兩天學習了人臉識別,看了學長寫的代碼,邊看邊碼邊理解搞完了一邊,再又是本身靠着理解和記憶硬碼了一邊,感受仍是很生疏,就只能來寫個隨筆加深一下印象了。html
關於人臉識別,首先須要瞭解的是級聯分類器CascadeClassifier,它能夠它既能夠是Haar特徵,也能夠是LBP特徵的分類器,能夠加載OpenCV所提供的庫當中的.xml文件,文件存放在anaconda\pkgs\libopencv-3.4.1-h875b8b8_3\Library\etc的haarcascades文件夾中,包含了許多個.xml文件,分別有不一樣的用途。而在使用級聯分類器進行人臉檢測時,須要調用 .detectMultiScale 方法,其中的參數爲ide
img:傳入圖像
object:被檢測的物體的矩形框向量組
scaleFactor:表示先後兩次相繼的掃描中,搜索窗口的比例係數。默認爲1.1,即每次搜索窗口擴大10%
minNegihbors,表示構成檢測目標的相鄰矩形的最小個數(默認爲3個)
flags:要麼使用默認值,要麼使用CV_HAAR_DO_CANNY_PRUNING,若是設置爲CV_HAAR_DO_CANNY_PRUNING,那麼函數會使用Canny邊緣檢測來排除邊緣過多或者過少的區域,這些一般不會是人臉所在區域
minSize和maxSize:用來限制獲得的目標區域的範圍函數
其輸出爲一個vector矩陣,保存人臉的座標和大小,須要注意的是,傳入的圖像必須爲灰度圖像,由於級聯分類器檢測須要接收灰度圖像。學習
1.首先是靜態圖片中的人臉檢測spa
這部分並不算難,看着註釋應該也能夠看懂,就很少作解釋。code
def StaticDetect(filename): ''' 靜態圖像的人臉檢測 ''' #建立一個級聯分類器,加載一個 .xml文件,它既能夠是Haar特徵,也能夠是LBP特徵的分類器 face_casecade=cv2.CascadeClassifier('./haarcascades/haarcascade_frontalface_default.xml') #加載圖像 img=cv2.imread(filename,cv2.IMREAD_COLOR) #轉換爲灰度圖像 gray_img=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) ''' detectMultiScale進行人臉檢測 傳入參數爲args: img:傳入圖像 object:被檢測的物體的矩形框向量組 scaleFactor:表示先後兩次相繼的掃描中,搜索窗口的比例係數。默認爲1.1,即每次搜索窗口擴大10% minNegihbors,表示構成檢測目標的相鄰矩形的最小個數(默認爲3個) flags:要麼使用默認值,要麼使用CV_HAAR_DO_CANNY_PRUNING,若是設置爲CV_HAAR_DO_CANNY_PRUNING,那麼函數會使用Canny邊緣檢測來排除邊緣過多或者過少的區域,這些一般不會是人臉所在區域 minSize和maxSize:用來限制獲得的目標區域的範圍 輸出爲:vector保存各我的臉的座標、大小(用矩形表示) ''' faces=face_casecade.detectMultiScale(gray_img,1.2,5) for (x,y,w,h) in faces: #在原圖上繪製矩形 img=cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2) cv2.namedWindow('Face_Detected') cv2.imshow('Face_Detected',img) cv2.waitKey(0) cv2.destroyAllWindows()
檢測的結果以下圖,圖片是我從網上隨便找的一張圖,若是有任何侵犯的地方,請及時聯繫我,會即刻刪除。咱們能夠發現結果並非太好,有許多漏檢,因爲是初學則不作過多改正嘗試,能夠嘗試修改級聯分類器中的文件以及搜索窗口比例係數來改變檢測準確度。視頻
2.動態人臉檢測xml
這一部分採用了兩個級聯分類器,一個檢測面部,一個檢測眼睛,須要注意的是,眼睛的檢測是在人臉檢測後再進行檢測,即先從大的人臉開始畫出矩形再到眼睛畫出的矩形。檢測眼睛時能夠把眼鏡摘下,會準確不少。htm
def Video_detected(): ''' 從視頻中進行人臉檢測 ''' #建立一個級聯分類器,家在一個 .xml文件它既能夠是Haar特徵,也能夠是LBP特徵的分類器 face_cascade=cv2.CascadeClassifier('./haarcascades/haarcascade_frontalface_default.xml') eye_cascade=cv2.CascadeClassifier('./haarcascades/haarcascade_eye.xml') #打開攝像頭 camera=cv2.VideoCapture(0) cv2.namedWindow('Dynamic') while(True): #讀取一幀圖像 ret ret,frame=camera.read() #判斷圖片讀取是否成功 if ret: gray_img=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY) #人臉檢測 faces=face_cascade.detectMultiScale(gray_img,1.3,5) for (x,y,w,h) in faces: #在原圖上繪製矩形 cv2.rectangle(frame,(x,y),(x+w,y+h),(255,0,0),2) #藍色 roi_gray=gray_img[y:y+h,x:x+w] #眼睛檢測 eyes=eye_cascade.detectMultiScale(roi_gray,1.1,5,0,(40,40)) for (ex,ey,ew,eh) in eyes: cv2.rectangle(frame,(ex+x,ey+y),(ex+x+ew,ey+y+eh),(0,255,0),2) #綠色 cv2.imshow('Dynamic',frame) #若是按下q鍵則退出 if cv2.waitKey(10) & 0xff==ord('q'): break camera.release() cv2.destroyAllWindows()
檢測結果以下圖,能夠發現對象很少的時候,人臉檢測仍是挺準確的,嘗試事後,動態狀況下多我的臉也是能夠檢測出來的。咱們能夠發現,在眼睛的檢測中多了幾個參數,這些參數是因爲眼睛比較小,而且有鼻子等形成的陰影可能會產生假陽性,所以經過限制檢測的眼睛大小爲40*40能夠去除假陽性的影響。後續能夠嘗試不一樣的參數的檢測精度,這裏就很少作描述。 對象
這裏附上原博客的鏈接:https://www.cnblogs.com/zyly/p/9410563.html
2018.10.28