opencv-python 人脸人眼检测
人脸检测:在一张图像中判断是否存在人脸并找出人脸所在的位置。
人脸识别:在人脸检测的基础上收集人脸数据集合进行处理保存信息,将输入人脸与保存的信息进行比对校验,得到是否为其中某个人脸。
特征值:以某种特定规则对输入源进行处理得到具有唯一性质量化的值,在人脸识别中特征值的提取有:HOG--方向梯度直方图;HAAR--like特征;LBP--局部二进制模式。
分类器:根据特征值界定输入事物是否属于已知某种类别的过滤条件组合,未知类别的是聚类器。弱分类器:分类器的正确率高于50%,强分类器:能满足预期分类并且正确率很高的分类器。
Adaboost:迭代算法,同一个训练集合下训练多个弱分类器,把弱分类器迭代组合成一个强分类器。
级联分类器:将多个同类型的分类器联合起来进行推算整合以得到符合目标的最终分类器的方法。
分类器生成及使用
一个高准确率的级联分类器的主要生成步骤如下:
1.大量样本集合,特征值的提取。
2.通过adaboost训练多个弱分类器并迭代为强分类器。
3.多层级联强分类器,得到最终的级联分类器。
这些训练流程完成之后结果以xml的方式保存起来,opencv中包含了以上的实现,并且已经存放了很多训练好的不同类型的级联分类器。
opencv中可以通过API直接加载这些分类器文件。
CascadeClassifier(级联分类器)
检测人脸或人眼的函数:detectMultiScale()
参数1:image--待检测图片,一般为灰度图片加快检测速度。
参数2:objects--被检测物体的矩形框向量组。
参数3:scaleFactor--前后两次相继的扫描中,图像被缩放的比例,1.1即每次被缩放10%用于检测。
参数4:minNeighbors--表示构成检测目标的相邻矩形的最小个数(默认3个)
参数5:flags--要么使用默认值,要么使用CV_HAAR_DO_CANNY_PRUNING,设置成后面这个函数会使用canny边缘检测来排除边缘过多或过少的区域。
参数6/7:minsize和mzxsize用来限制得到的目标区域的范围。
opencv的各种级联分类器保存在data目录下:
直接调用cv的级联分类器进行人脸和人眼的检测如下(图片来源于百度):
import cv2 import numpy as np img = cv2.imread('./mans.jpg') gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) equalize = cv2.equalizeHist(gray) #创建人脸级联分类器 face = cv2.CascadeClassifier('./haarcascade_frontalface_alt2.xml') #创建眼睛级联分类器 eye = cv2.CascadeClassifier('./haarcascade_eye.xml') #开始检测 faces = face.detectMultiScale(gray,scaleFactor=1.1,minNeighbors=4) #存放每个人脸框的位置,ndarray eyes = eye.detectMultiScale(gray,scaleFactor=1.2,minNeighbors=3) print(type(faces)) print(faces) for face in faces: (x,y,w,h) = face cv2.rectangle(img,(x,y),(x+w,y+h),[0,0,255],2) for eye in eyes: (x,y,w,h) = eye cv2.rectangle(img,(x,y),(x+w,y+h),[0,255,0],2) cv2.imshow('img',img) # cv2.imshow('gray',gray) # cv2.imshow('equalize',equalize) cv2.waitKey(0) cv2.destroyAllWindows()
相比于检测人脸,人眼的检测更容易出错,有误检的可能,所有可以在人脸框里面进行人眼检测:
import cv2 import numpy as np #只在人脸框内进行眼睛检测 img = cv2.imread('./mans.jpg') gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) equalize = cv2.equalizeHist(gray) #创建人脸级联分类器 face = cv2.CascadeClassifier('./haarcascade_frontalface_alt2.xml') # eye = cv2.CascadeClassifier('./haarcascade_eye.xml') faces = face.detectMultiScale(gray,scaleFactor=1.1,minNeighbors=4) #存放每个人脸框的位置,ndarray # eyes = eye.detectMultiScale(gray,scaleFactor=1.2,minNeighbors=3) for face in faces: (x,y,w,h) = face cv2.rectangle(img,(x,y),(x+w,y+h),[0,0,255],2) face_img = img[y:y+h,x:x+w] #把检测处理的人脸框切片出来 eye = cv2.CascadeClassifier('./haarcascade_eye.xml') #创建眼睛级联分类器 eyes = eye.detectMultiScale(face_img) #在人脸切片图片上检测眼睛 for eye in eyes: (ex,ey,ew,eh) = eye cv2.rectangle(face_img,(ex,ey),(ex+ew,ey+eh),[0,255,0],2) ##在人脸切片图片上框出眼睛,face_img已经修改 img[y:y+h,x:x+w] = face_img #把框出眼睛的人脸切片图片贴到img上去 cv2.imshow('img',img) # cv2.imshow('gray',gray) # cv2.imshow('equalize',equalize) cv2.waitKey(0) cv2.destroyAllWindows()