【火爐煉AI】機器學習052-OpenCV構建人臉鼻子眼睛檢測器
(本文所使用的Python庫和版本號: Python 3.6, Numpy 1.14, scikit-learn 0.19, matplotlib 2.2,opencv-python 3.4.2)
有兩個重要的概念需要澄清一下:人臉檢測:是指檢測影象或視訊中是否存在人臉,以及定位人臉的具體位置,人臉識別:確定影象或視訊中的人臉是張三還是李四還是其他某人。故而人臉檢測是人臉識別的基礎和前提條件。
在這一章我們來學習如何用OpenCV構建人臉檢測器,鼻子檢測器和眼睛檢測器。
1. 構建人臉檢測器
前面提到過,人臉檢測器是確定影象中人臉位置的過程,我們將用Haar級聯來構建人臉檢測器。Haar級聯通過在多個尺度上從影象中提取大量的簡單特徵來實現,這些簡單特徵包括有邊,角,線,矩形特徵等,然後通過建立一系列簡單的分類器來做訓練。
Haar級聯是一個基於Haar特徵的級聯分類器,所謂級聯分類器,是把多個弱分類器串聯成一個強分類器的過程,弱分類器是指效能受限,預測準確度不太高的分類器,所以此處的串聯實際上就是機器學習中的Boost方法,即整合方法。所以Haar分類器 = Haar-like特徵 + 積分圖方法 + AdaBoost + 級聯。關於Haar-like特徵和積分圖的概念,可以參考博文: ofollow,noindex">淺析人臉檢測之Haar分類器方法 .
1.1 對單張圖片進行人臉檢測
# 構建單張圖片的人臉檢測器 def img_face_detector(img_path,face_cascade_file): image=cv2.imread(img_path) face_cascade=cv2.CascadeClassifier(face_cascade_file) if face_cascade.empty(): raise IOError('Unable to load the face cascade classifier xml file!') gray=cv2.cvtColor(image,cv2.COLOR_BGR2GRAY) face_rects=face_cascade.detectMultiScale(gray,1.3,5) # 在檢測到的臉部周圍畫矩形框 for (x,y,w,h) in face_rects: cv2.rectangle(image,(x,y),(x+w,y+h),(0,0,255),3) return image 複製程式碼
# 測試一下這個人臉檢測器: image1=img_face_detector('E:\PyProjects\DataSet\FireAI/face1.jpg', 'E:\PyProjects\DataSet\FireAI\cascade_files/haarcascade_frontalface_alt.xml') image1=cv2.cvtColor(image1,cv2.COLOR_BGR2RGB) plt.imshow(image1) 複製程式碼
通過對下面幾張圖片進行人臉檢測,得到的結果分別為:



1.2 對視訊流進行人臉檢測
視訊流的本質其實就是圖片,將圖片按照一定的每秒幀率fps播放出來即可。故而我們在對視訊進行分析時,需要從視訊流中捕獲圖片,對圖片進行分析。
# 對視訊流進行人臉檢測 def video_face_detector(face_cascade_file): face_cascade=cv2.CascadeClassifier(face_cascade_file) if face_cascade.empty(): raise IOError('Unable to load the face cascade classifier xml file!') capture=cv2.VideoCapture(0) while True: _,frame=capture.read() # 捕獲當前幀 gray=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY) face_rects=face_cascade.detectMultiScale(gray,1.3,5) # 在檢測到的臉部周圍畫矩形框 for (x,y,w,h) in face_rects: cv2.rectangle(frame,(x,y),(x+w,y+h),(0,0,255),3) cv2.imshow('Video Face Detector', frame) key=cv2.waitKey(1) # 按ESC退出檢測 if key==27: break capture.release() cv2.destroyAllWindows() 複製程式碼
2. 構建鼻子檢測器
2.1 對單張圖片進行鼻子檢測
# 構建單張圖片的鼻子檢測器 def img_nose_detector(img_path,face_cascade_file,nose_cascade_file,show_face=True): image=cv2.imread(img_path) face_cascade=cv2.CascadeClassifier(face_cascade_file) if face_cascade.empty(): raise IOError('Unable to load the face cascade classifier xml file!') nose_cascade=cv2.CascadeClassifier(nose_cascade_file) if nose_cascade.empty(): raise IOError('Unable to load the nose cascade classifier xml file!') gray=cv2.cvtColor(image,cv2.COLOR_BGR2GRAY) face_rects=face_cascade.detectMultiScale(gray,1.3,5) # 在檢測到的臉部周圍畫矩形框 for (x,y,w,h) in face_rects: if show_face: cv2.rectangle(image,(x,y),(x+w,y+h),(0,0,255),3) roi=gray[y:y+h,x:x+w] nose_rects=nose_cascade.detectMultiScale(roi,1.3,5) for (x_nose,y_nose,w_nose,h_nose) in nose_rects: cv2.rectangle(image,(x+x_nose,y+y_nose),(x+x_nose+w_nose,y+y_nose+h_nose), (0,255,0),3) break # 一張臉上只能有一個鼻子,故而此處break return image 複製程式碼

2.2 對視訊流進行鼻子檢測
同樣的,對視訊流進行鼻子檢測的程式碼為:
# 對視訊流進行鼻子檢測 def video_nose_detector(face_cascade_file,nose_cascade_file): face_cascade=cv2.CascadeClassifier(face_cascade_file) if face_cascade.empty(): raise IOError('Unable to load the face cascade classifier xml file!') nose_cascade=cv2.CascadeClassifier(nose_cascade_file) if nose_cascade.empty(): raise IOError('Unable to load the nose cascade classifier xml file!') capture=cv2.VideoCapture(0) while True: _,frame=capture.read() # 捕獲當前幀 gray=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY) face_rects=face_cascade.detectMultiScale(gray) # 在檢測到的臉部周圍畫矩形框 for (x,y,w,h) in face_rects: cv2.rectangle(frame,(x,y),(x+w,y+h),(0,0,255),3) roi=gray[y:y+h,x:x+w] nose_rects=nose_cascade.detectMultiScale(roi,1.3,5) for (x_nose,y_nose,w_nose,h_nose) in nose_rects: cv2.rectangle(frame,(x+x_nose,y+y_nose),(x+x_nose+w_nose,y+y_nose+h_nose), (0,255,0),3) break # 一張臉上只能有一個鼻子,故而此處break cv2.imshow('Video Face Detector', frame) key=cv2.waitKey(1) # 按ESC退出檢測 if key==27: break capture.release() cv2.destroyAllWindows() 複製程式碼
同樣的,可以構建對單張圖片和視訊流的眼睛檢測器,具體程式碼可以看( 我的github )

當然,還可以建立函式同時對鼻子和眼睛進行檢測,只需要對原來的鼻子檢測函式做少許修改即可。
########################小**********結###############################
1,此處使用Haar級聯構建了人臉,鼻子,眼睛檢測器,能夠很好的檢測到圖片,視訊流中的各個結構資訊。
2,從結果上可以看出,雖然能夠有效檢測,但是還有些人臉或鼻子,眼睛等難以被檢測到,此時可能要調整檢測函式detectMultiScale()的引數,如果調整引數仍然不理想,就需要修改特徵檢測級聯檔案cascade_file這個xml了。
#################################################################
注:本部分程式碼已經全部上傳到( 我的github )上,歡迎下載。
參考資料:
1, Python機器學習經典例項,Prateek Joshi著,陶俊傑,陳小莉譯