魏老师学生——Cecil:学习OpenCV-机器视觉之旅
Aim:学习以Haar特征分类器为基础的面部检测技术;
将面部检测扩展到眼部检测。
基础
- 对象检测技术:基于机器学习,通过使用大量的正负样本图像训练得到一个cascade_function,最后用它做对象检测。
- 面部检测:算法先通过大量的正样本图像(面部图像)和负样本图像(不带面部的图像)训练分类器从中提取特征。
- Haar特征类似卷积核,每个特征是一个值,等于黑色矩形中的像素值之和减去白色矩形中的像素值之和。使用所有可能的核心计算足够多的特征。(计算量:一个24×24的窗口有160000个特征)
- 如何计算白色和黑色矩形内的像素和?算法使用积分图像大大简化求和运算。对于任何一个区域的像素和只需要对积分图像中的四个像素操作。
- 如何从数十万个特征中选出最好特征?使用Adaboost。将每个特征应用于所有的训练图像。找出每个特征能够区分出正样本和负样本的最佳阈值。
- 必须选取错误率最低的特征,说明它们是检测面部和非面部图像最好的特征。最终的分类器是所有弱分类器的加权和。弱分类器不足以对图像进行分类,但是与其他分类器联合以后就变成很强的分类器。最后从160000个特征减少到6000个特征。
- 如何继续降低特征数?只需要证明不是面部区域的部分,直接抛弃此部分,从而降低时间复杂度。
- 级联分类器:将特征分成不同组,在不同的分类阶段逐个使用。对每个窗口进行不同级别的检测,只有通过当前级别才能进入下级检测。只有通过所有级别的检测才被认为是面部区域。
- 算法将6000个特征分为38阶段,前五个阶段特征数分别是1、10、25、25、50.
OpenCV中的Haar级联检测
OpenCV自带训练器和检测器。也可以使用OpenCV自己构建,训练一个分类器检测物体(飞机坦克等等)
OpenCV包含很多已经训练好的分类器:面部、眼睛、微笑等。
创建一个面部和眼部检测器
- 加载需要的XML分类器,以灰度格式加载输入图像或视频。
- 在图像中检测面部,一旦检测到面部就返回面部所在的矩形区域Rect(x,y,w,h),然后对此矩形区域创建一个ROI在其中进行眼部检测。
#coding=utf-8
import cv2
import numpy as np
face_cascade=cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
eye_cascade=cv2.CascadeClassifier('haarcascade_eye.xml')
img=cv2.imread('./image2/123.jpg')
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#cv2.CascadeClassifier.detectMultiScale(image,scaleFactor,minNeighbors,flags,minSize,maxSize)
faces=face_cascade.detectMultiScale(gray,1,15)
for (x,y,w,h) in faces:
img=cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
roi_gray=gray[y:y+h,x:x+w]
roi_color = img[y:y + h, x:x + w]
eyes=eye_cascade.detectMultiScale(roi_gray)
for (ex,ey,ew,eh) in eyes:
cv2.rectangle(roi_color,(ex,ey),(ex+ew,ey+eh),(0,255,0),2)
cv2.imshow('img',img)
cv2.waitKey(0)
cv2.destroyAllWindows()