【机器学习】 - 使用dlib进行人脸定位,人脸检测,给人脸图片戴口罩

detector = dlib.get_frontal_face_detector()


功能:人脸检测画框
参数:无
返回值:默认的人脸检测器

faces = detector(img_gray, 0)


功能:对图像画人脸框
参数:img_gray:输入的图片
返回值:人脸检测矩形框4点坐标。坐标为[(x1, y1) (x2, y2)]。可以通过函数的left,right,top,bottom方法分别获取对应的x1, x2, y1, y2值。(cv里的矩阵和C++的那种一样,左上角是(0,0)点,水平为x方向,竖直为y方向,类似笛卡尔系(区别是y轴正方向不同),所以top的y坐标 < bottom的y坐标。matplotlib是相反的。)

后面那个参数代表将原始图像是否进行放大,1表示放大1倍再检查,提高小人脸的检测效果。

                       

左图是参数为0的检测情况,右图是参数为1的检测情况。

上述例子参考自链接:http://blog.sina.com.cn/s/blog_49b3ba190102yvl9.html

 

 

注意dlib只能对灰度图进行检测:

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

注意更改当前文件运行目录 为 程序执行文件路径 的方法:

https://www.jb51.net/article/138980.htm

 

下面进行代码实战:

原图地址

代码实战1:人脸检测

import numpy
import dlib
import cv2
import sys
import os

# 修改执行目录为该.py文件所在目录
#dirname, filename = os.path.split(os.path.abspath(sys.argv[0]))
dirname, filename = os.path.split(sys.argv[0])
# print(dirname,filename)
# path = os.getcwd()
os.chdir(dirname)
print(os.getcwd())

# 人脸检测
detector = dlib.get_frontal_face_detector()

# 人脸关键点标注。
predictor = dlib.shape_predictor(
    'shape_predictor_68_face_landmarks.dat'
)
img = cv2.imread('sdtw2.jpg')

gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#这样也可以灰度图但是不建议用:im2 = cv2.imread('tfboys.jpg',flags = 0)

faces = detector(gray,0)# 第二个参数越大,代表讲原图放大多少倍在进行检测,提高小人脸的检测效果。

for face in faces:
    #左上角(x1,y1),右下角(x2,y2)
    x1, y1, x2, y2 = face.left(), face.top(), face.right(), face.bottom()
    print(x1,y1,x2,y2)
    cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2)
cv2.imshow("image", img)
cv2.waitKey(0)

运行结果:

 

代码实战2:人脸关键点标注


 

import numpy
import dlib
import cv2
import sys
import os

#dirname, filename = os.path.split(os.path.abspath(sys.argv[0]))
dirname, filename = os.path.split(sys.argv[0])
# print(dirname,filename)
# path = os.getcwd()
os.chdir(dirname)
print(os.getcwd())

# 人脸检测
detector = dlib.get_frontal_face_detector()

# 人脸关键点标注。
predictor = dlib.shape_predictor(
    'shape_predictor_68_face_landmarks.dat'
)
img = cv2.imread('sdtw2.jpg')

gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#这样也可以灰度图但是不建议用:im2 = cv2.imread('tfboys.jpg',flags = 0)

dets = detector(gray,0)# 第二个参数越大,代表讲原图放大多少倍在进行检测,提高小人脸的检测效果。

for d in dets:
 # 使用predictor进行人脸关键点检测 shape为返回的结果
    shape = predictor(gray, d)
    for index, pt in enumerate(shape.parts()):
        print('Part {}: {}'.format(index, pt))
        pt_pos = (pt.x, pt.y)
        cv2.circle(img, pt_pos, 1, (255, 0, 0), 2)                          
        #利用cv2.putText标注序号
        font = cv2.FONT_HERSHEY_SIMPLEX
        cv2.putText(img, str(index+1),pt_pos,font, 0.3, (0, 0, 255), 1, cv2.LINE_AA)
cv2.imshow("image", img)
cv2.waitKey(0)
cv2.destroyAllWindows()

 

实验结果:

人脸关键点:

附标号:

 

代码实战3:佩戴口罩

我们取2,8,14,28作为口罩关键点,即下图3,9,15,29,放入points_key中

对于待测图片的每一个人脸框,按照对应points_key来检测边界,将口罩图片进行缩放,填入对应区域。

注意对下载后的口罩要进行背景去除,这里可以用一些在线处理网站,或者ps等等。(本项目使用已去除背景的口罩已上传到github

 

注意实现的时候,有个问题就是透明度的问题,不然会出现下面这个问题:

为了方便讲解,我们将口罩区域分成口罩图像区域,和口罩真实区域。

在代码实现的时候,刚开始只是想着分摊像素值,比如对口罩图像区域,让他80%保留原图像素值,20%来自口罩图像,这样进行merge。但是效果并不是期待的那样。

发现其实口罩部分还是要口罩占主体,所以换成了20%保留原图像素值,80%来自口罩图像,如下图。

剩下的就是透明度的问题了,这里我采用的是二值化方法,把像素值较小的背景部分隐去,像素值较大的是口罩真实区域,采用口罩图80%和人脸图20%进行merge。

阈值设置为80,表现良好。

此项目代码对应代码和实验所用到的图像均放到了github:https://github.com/xuanweiace/put_a_mask_on_the_face/

欢迎下载和star。

 

项目中是用二值化的方法来实验背景透明的功能,cv2中也自带了一个功能可以实现透明化处理,感兴趣的同学可以搜一下:

透明度覆盖:

img_mix = cv2.addWeighted(img1, 1, img2,1, 0) #合并,其中参数1表示透明度,第一个1表示img1不透明,第二个1表示img1不透明,如果改成0.5表示合并的时候已多少透明度覆盖。

 

相关拓展链接:

识别戴口罩的人脸的四种方法:https://blog.csdn.net/qq_23670601/article/details/104344917

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值