1:人脸检测的介绍以及综述:
现在人脸检测已经成为我们生活必不可少的一个部分,比如西电进宿舍刷脸(我从来没有成功过),现在基于深度学习的人脸检测算法大致分为以下三类:
- 基于级联的人脸检测算法。
- 基于两阶段的人脸基于级联的人脸检测算法。检测算法。
- 基于单阶段的人脸检测算法。
- 第一类基于级联的人脸检测方法(如Cascade CNN、MTCNN)运行速度较快、检测性能适中,适用于算力有限、背景简单且人脸数量较少的场景。
- 第二类两阶段人脸检测方法一般基于Faster-RCNN框架,在第一阶段生成候选区域,然后在第二阶段对候选区域进行分类和回归,其检测准确率较高,缺点是检测速度较慢,代表方法有Face R-CNN 、ScaleFace、FDNet。
- 第三类单阶段的人脸检测方法主要基于Anchor的分类和回归,通常会在经典框架(如SSD、RetinaNet)的基础上进行优化,其检测速度较两阶段法快,检测性能较级联法优,是一种检测性能和速度平衡的算法,也是当前人脸检测算法优化的主流方向。
2:利用OpenCv对照片进行处理:
先说一下opencv的工作原理,虽然我使用了OpenCV来进行人脸识别,但OpenCV本身并不负责识别人脸。归功于叫一个'xml'的文件,这是通过很多数据一段训练得到的一个分类器,如果想识别汽车,或者各种东西,只需要训练就完事来了。说到这,我就已经透露了这次我即将用上文我提到的第一个方法:基于级联的人脸检测算法。
好,先上代码:
import cv2 as cv
import numpy as np
def face_detect_demo(image):
gray = cv.cvtColor(image,cv.COLOR_BGR2GRAY) #在灰度图像基础上实现的
face_detector = cv.CascadeClassifier("./haarcascade_frontalcatface.xml") #级联检测器获取文件
faces = face_detector.detectMultiScale(gray,1.01,1) #在多个尺度空间上进行人脸检测
#第一个参数是灰度图像
#第二个参数是尺度变换,就是向上或者向下每次是原来的多少倍,这里是1.02倍
#第三个参数是人脸检测次数,设置越高,误检率越低,但是对于迷糊图片,我们设置越高,越不易检测出来,要试单降低
for x,y,w,h in faces:
cv.rectangle(image,(x,y),(x+w,y+h),(255,0,0),2)
cv.namedWindow("xdy",0)
cv.imshow("xdy",image)
cv.imwrite("xdy.jpg", image,[int(cv.IMWRITE_PNG_COMPRESSION), 0])
#
#
#
src = cv.imread("./1.jpg") #读取图片
cv.namedWindow("input image",0)
cv.imshow("input image",src)
# p=cv.Canny(src,200,200)
face_detect_demo(src)
# cv.imshow("p image",p)
cv.waitKey(0) #等待用户操作,里面等待参数是毫秒,我们填写0,代表是永远,等待用户操作
cv.destroyAllWindows() #销毁所有窗口
我写了一个函数,对于大工程更加的方便,其中第五行是最重要的,他就是通过不断的训练得到的。其中imread读取的图片是当代大学生都喜欢的IU,图片从网上随便找的。
哈哈哈最后的结果是这个样子:
啊,对不起,我的检测不是很准!因为我训练的数据不是很大。
在这里我顺便说一下我对图像处理的理解,如果要对人脸进行识别,第一步那就是要得到人脸的位置,然后再根据你的一个个像素比较,从而得到最后的结果。写的有点简单了。。。
为了提取轮廓,我采用了opencv里面的Cancy,最后得到的结果如下:
其中这里采用的是AdaBoost框架,boost算法是基于PAC学习理论(probably approximately correct)而建立的一套集成学习算法(ensemble learning)。其根本思想在于通过多个简单的弱分类器,构建出准确率很高的强分类器,PAC学习理论证实了这一方法的可行性。
2:利用opencv进行实时人脸检测:
上面我们所提到的都是对于单一的照片进行操作,下面我们来看一下对视频进行操作,其中操作和上面差不多,只是用了videocapture,附上代码:
import cv2
# cap = cv2.VideoCapture(0,cv2.CAP_DSHOW)
#cv2.namedWindow('v',0)
cap=cv2.VideoCapture('./good plmm.flv')
cap.set(10,200)
face_cascade=cv2.CascadeClassifier("./haarcascade_frontalface_default.xml")
eye_cascade=cv2.CascadeClassifier("./haarcascade_eye.xml")
smile_cascade=cv2.CascadeClassifier("./haarcascade_smile.xml")
while True:
ret,xdy = cap.read()
if not ret:
cv2.waitKey(30)
gray = cv2.cvtColor(xdy,cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray,1.3,5)
for (x,y,w,h) in faces:
xdy = cv2.rectangle(xdy,(x,y),(x+w,y+h),(255,0,0),4)
face_eye =xdy[y:y+h, x:x+w]
eyes=eye_cascade.detectMultiScale(face_eye,1.3,3)
for (ex,ey,ew,eh) in eyes:
cv2.rectangle(face_eye,(ex,ey),(ex+ew,ey+eh),(0,0,255),3)
smiles=smile_cascade.detectMultiScale(face_eye,1.3,20)
for ex,ey,ew,eh in smiles:
cv2.rectangle(face_eye,(ex,ey),(ex+ew,ey+eh),(0,255,0),2)
cv2.putText(face_eye,'smile',(x,y-8),3,1.2,(0,255,0),2,cv2.LINE_AA)
cv2.imshow("xdy",xdy)
cv2.waitKey(30)
# cv2.destroyAllWindows()
当videocapture中的值是0时,就会默认打开你的摄像头,这里我就不表演那个了哈哈哈,我就导入了一个视频,看效果:
可以看出来结果还是可以的。不是很准确。
当把videocapture改成0的时候,视频如下,结果还是不错的勒,毕竟我调了快一小时,此视频不允许转发:
3:通过这个工程的总结
- 写到这里,相信大家都看过上面的照片了,这个时候问题就来了,我拿一张照片他也可以识别出来,,无法识别是真人还是照片。如果这样的话,那么刷脸支付谁还敢操作呢哈哈哈。
- 能区分真人和照片的技术,这个硏究领域叫做 Liveness detection。因为现在社交网络、电子成像产品这么发达,人们可以很方便获取他人的人脸照片,进而来欺骗人脸识别系统,所以区分系统前的人脸是真的人脸,还是照片/视频/三维面具,就变得非常重要。对于照片欺骗,主要是根据分辨率拍的照片分辨率比直接从真人上采集的照片在质量、分辨率上有差别)、三维信息、眼动等来区分。对于视频欺骗,根据三维信息、光线等来区分。对于三维面具欺骗,这方面的硏究还很少。
- 就我看来,计算机算法是可以区分照片和真人的。但是人脸活体取证在实际应用中,还有很大局限性。现在的算法基本还是基于实验室数据,离实用还有一段距离。