本次将借助于 dlib 程序包实现人脸区域检测、特征点提取等功能,
dlib 封装了许多优秀的机器学习算法, 可实现人脸识别、检测、识别,视频目标追逐等功能,是由由 C++开发的一个开源程序库,目前也提供了 Python 接口,可供我们直接调用。
1,dilb 安装
dlib 程序包的安装方式也是用 pip 来进行安装的,但不同于其它程序包的是,在输入
pip install dlib
之前,需要安装 Cmake 程序包,该工具主要是对 dlib 进行编译,安装命令与其他包类似
pip install Cmake
2,实现人脸识别
利用 dlib 实现人脸识别功能时,先定义一个检测器和一个 图片预览窗口:
detector = dlib.get_frontal_face_detector() win = win = dlib.image_window()
之后利用 load_rgb_image() 函数读取图像:
img = dlib.load_rgb_image(f)
接下来进行核心功能人脸检测的实现,这里需要借助于上面定义得到的检测器
dets,score,idx = detector.run(img,1,-1)
img 就是我们读取后的图像,第二个参数 1 代表的是图片上采样倍数,值越大,最终识别得到的结果越好,-1 代表的是调整分割阈值,负值表示将返回更多检测结果
返回的 dets 返回的是一个人脸区域矩形,分别表示左,上、右、下边界,是 tuple 形式,如果检测出一个人脸,则为一个 tuple, 如果是多个人脸,将会把多个 tuple 放置在一个列表中;有个这个矩形坐标就可以做以下事情:
- 人脸区域裁剪,进行区域提取;
- 人脸区域线条标记
score 表示的是人脸识结果检测概率,越大代表识别出来的结果越好;如果一幅图有多个人脸,则返回多个检测概率以列表形式储存;idx 是用于在一副图检测出多个人脸是用的索引,可以对其进行索引
win.clear_overlay() win.set_image(img) win.add_overlay(dets) dlib.hit_enter_to_continue
最后我们利用 前面定义的 win 窗口,进行图像预览,结果如下,
Snipaste_2020-06-01_23-43-59.png
当然也可以用 OpenCV 进行轮廓勾勒,OpenCV 勾勒结果如下( 有色差的原因是OpenCV 读取的是 BGR 通道顺序 );
Snipaste_2020-06-01_23-46-03.png
3,dlib 提取人脸68个特征点
OpenCV 也可以用于人脸识别,但效果不如 dlib ,除了上面提到的线框检测之外,dlib 还可以直接提取人脸上的 68 个特征点,作为坐标形式来返回;
有了这 68 个特征点的坐标,可以很方便地帮助我们实现人脸对齐、融合等应用,先看一下用 dlib 勾勒出来的效果
Snipaste_2020-06-02_14-48-24.png
与人脸识别不一样的是,这里需要加上一个形状检测器,形状检测器这里需要官网提供的文件、里面放置已经训练好的权重信息,可以直接使用,上面功能实现代码如下:
import dlib import os import cv2 predictor_path = "E:/shape_predictor_68_face_landmarks.dat"#权重文件路径 png_path = "E:/ceshi.png" detector = dlib.get_frontal_face_detector() #相撞 predicator = dlib.shape_predictor(predictor_path) win = dlib.image_window() img = dlib.load_rgb_image(png_path) win.clear_overlay() win.set_image(img1) for k,d in enumerate(dets): print("Detection {} left:{} Top: {} Right {} Bottom {}".format( k,d.left(),d.top(),d.right(),d.bottom() shape = predicator(img,d) #Get the landmarks/parts for face in box d print("Part 0:{},Part 1 :{}".format(shape.part(0),shape.part(1))) win.add_overlay(shape) win.add_overlay(dets) dlib.hit_enter_to_continue()
坐标点的获取可以通过 part(index) 函数获取
上面的坐标点,也可以通过 OpenCV 在原图上勾勒出来,并注释上文字,效果如下:
Snipaste_2020-06-02_15-02-38.png
附上完整代码:
import dlib import os import cv2 predictor_path = "E:/shape_predictor_68_face_landmarks.dat" png_path = "E:/ceshi.png" detector = dlib.get_frontal_face_detector() #相撞 predicator = dlib.shape_predictor(predictor_path) win = dlib.image_window() img1 = cv2.imread(png_path) dets = detector(img1,1) print("Number of faces detected : {}".format(len(dets))) for k,d in enumerate(dets): print("Detection {} left:{} Top: {} Right {} Bottom {}".format( k,d.left(),d.top(),d.right(),d.bottom() )) lanmarks = [[p.x,p.y] for p in predicator(img1,d).parts()] for idx,point in enumerate(lanmarks): point = (point[0],point[1]) cv2.circle(img1,point,5,color=(0,0,255)) font = cv2.FONT_HERSHEY_COMPLEX_SMALL cv2.putText(img1,str(idx),point,font,0.5,(0,255,0),1,cv2.LINE_AA) #对标记点进行递归; cv2.namedWindow("img",cv2.WINDOW_NORMAL) cv2.imshow("img",img1) cv2.waitKey(0)
4,小总结
以上就是对 dlib 程序包的简单介绍,在人脸识别应用方面上 dlib 的表现相当不错的,有兴趣的同学可以去官网看关于 dlib 的详细介绍,自己闲余时间动手跟着敲一下。