python用dlib关键点将人脸背景区域去除

在上一篇的工作基础上,检测到人脸的关键点,并利用这些关键点组成一个区域,对区域外的背景置0;

话不多说,先上代码:

if __name__=='__main__':
    path = 'res/00014206.jpg'
    img = io.imread(path)
    region = get_landmarks(img)
    print img.shape
    shape = list(img.shape) + [3]  # 将图像转化为列表,便于访问
    img1 = img.copy()
    for i in xrange(shape[0]):
        for j in xrange(shape[1]):
            if not inside(j, i, region): 
                img1[i, j] = (0, 0, 0)
    win.set_image(img1)

用imread读取图片后,调用get_landmarks(img)获取我们所要的人脸区域,代码如下:

def get_landmarks(img):
    dets = detector(img, 1)
    landmarks = np.zeros((19,2))
    for k, d in enumerate(dets):
        shape = predictor(img, d)
        for i in range(17):
            landmarks[i] = (shape.part(i).x, shape.part(i).y)
        landmarks[17] = (shape.part(24).x, shape.part(24).y - 20)
        landmarks[18] = (shape.part(19).x, shape.part(19).y - 20)
    return landmarks

这里不需要之前dlib所有的68个关键点,重新构建了一个landmarks矩阵,存储脸颊17个点和眉毛2个中间点,总共19个关键点; 注意这里landmarks 要用 np.zeros((19,2))来创建;
为了后面访问landmarks的边,这里需要将19,24两个眉毛的位置调一下位置,放入landmarks中17,18两个位置。
获取完关键点后,复制图片img1 = img.copy(),img1用于获取我们所需的目标图片。遍历图片img1,用inside(j, i, region)判断不在关键点区域内的点(注意这里由于shape[0]和shape[1]的问题,调用inside()函数时需要将i,j顺序变换一下),将这些点的像素置0(img1[i, j] = (0, 0, 0));
inside(j, i, region)函数如下:

def inside(X,Y,Region): 
    j=len(Region)-1
    flag=False
    for i in range(len(Region)):
        if (Region[i][1]<Y and Region[j][1]>=Y or Region[j][1]<Y and Region[i][1]>=Y):  
            if (Region[i][0] + (Y - Region[i][1]) / (Region[j][1] - Region[i][1]) * (Region[j][0] - Region[i][0]) < X):
                flag =not flag
        j=i
    return flag

这个函数网上有很多解释,边的遍历顺序为(18->0->1->2->3->4->5->6->7->8->9->10->11->12->13->14->15->16->17->18)。
下面是背景区域去除后的效果:
这里写图片描述
这里写图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值