首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >带你用 Python + 人脸识别自动裁剪头像

带你用 Python + 人脸识别自动裁剪头像

作者头像
不二小段
发布2019-05-13 18:56:34
3.8K0
发布2019-05-13 18:56:34
举报
文章被收录于专栏:不二小段不二小段

之前我们写了一篇制作人物关系图的文章,如果你还没有看可以点击下面的图片跳转查看:

在这篇文章的最后,我们留下了一个需求:将剧照中的人物裁剪为圆形头像,美化关系图。

也就是把这种干巴巴的图变的图文并茂一点:

对于这个需求,大家的第一反应可能是 PS,但 PS 用来干这件事情我觉得太“重”了,有没有更轻便的办法来实现呢?

今天来介绍两个办法:一是 PPT 的图片编辑功能处理单张图片;二是利用 Python 实现人脸识别+图像处理批量裁剪。

PPT 的图片操作功能在很多时候是简单有效的,而且很多电脑上没有装 PS,PPT 则是都有的。如果想要裁剪圆形头像只需要三步:

1、插入图片

2、裁剪图片,根据需要裁剪头像范围,并设置横纵比例为1:1,

3、裁剪完成后再次选择裁剪图片-裁剪为形状-椭圆,即可完成圆形头像制作,最后另存为图片即可。

两步裁剪其实可以合成一步,大家实践一下就明白

用 PPT 来处理单张图片是可以的,但是假如我们这次要一次性处理十几个甚至上百个人物图片,那么每次都要人工确定一下头像的位置,然后进行裁剪,如此低效的重复劳动对程序员来说绝对不能忍的。接下来我们使用 Python 实现自动化人脸识别和图片裁剪功能。

利用 Python 实现裁剪圆形头像分为以下步骤:

1、利用人脸识别接口确定人脸在图片中的位置

2、计算出需要裁剪的区域

3、利用 PIL 库进行裁剪

人脸识别的提供功能很丰富,像我们之前使用到的颜值打分、年龄等。我们这次用到的其实是最基础的功能——人脸检测,即通过人工智能检测图片中是否有人脸,并标出其区域位置。

人脸检测的功能几乎所有的人脸识别接口都会提供,所以我们随便用一个就好。这次我们用微软的 API 来做测试,当然你也可以使用百度、Face ++等公司的 API,只需要替换掉请求接口的部分就可以了。

你可以下面的网址申请微软 API 试用:

https://azure.microsoft.com/zh-cn/services/cognitive-services/face/

接口的使用各家不同,一般来讲会提供一个 key ,在通过网络请求时作为身份鉴别的依据。官方文档一般都会给出详细介绍和示例,这里就不再赘述了,直接上代码。

import requests
import json

headers = {
    'Content-Type': 'application/json',
    'Ocp-Apim-Subscription-Key': '修改为自己的 key',
}

params = {
    'returnFaceId': 'true',
    'returnFaceLandmarks': 'false',
    # 'returnFaceAttributes': '{string}',
    'recognitionModel': 'recognition_01',
    'returnRecognitionModel': 'false',
}

API_url = 'https://westcentralus.api.cognitive.microsoft.com/face/v1.0/detect'
data = {
    'url': '修改为图片 URL'
}
response = requests.post(API_url, data=data, headers=headers, params=params)
face = json.loads(response.text)

微软的图片接口支持网络图片地址和字节流两种方法,上面的代码是网络图片的地址的写法,使用时需要填入自己的 key 并修改图片 URL。

如果要使用本地图片,则需要修改为下面的代码。

import requests
import json

headers = {
    'Content-Type': 'application/octet-stream',
    'Ocp-Apim-Subscription-Key': '修改为自己的 key',
}

params = {
    'returnFaceId': 'true',
    'returnFaceLandmarks': 'false',
    # 'returnFaceAttributes': '{string}',
    'recognitionModel': 'recognition_01',
    'returnRecognitionModel': 'false',
}
img_path = '修改为本地图片路径'
API_url = 'https://westcentralus.api.cognitive.microsoft.com/face/v1.0/detect'
data = open(img_path, 'rb').read()
response = requests.post(API_url, data=data, headers=headers, params=params)
face = json.loads(response.text)

这段代码会返回一个 JSON 格式的数据:

[
    {
        "faceId": "c5c24a82-6845-4031-9d5d-978df9175426",
        "recognitionModel": "recognition_02",
        "faceRectangle": {
            "width": 78,
            "height": 78,
            "left": 394,
            "top": 54
        }}
]

如果检测到图片中有多个人脸,则会返回多组坐标数据。需要注意的一个问题是,微软的接口 URL 要请求 HTTPS,如果请求 HTTP 网址,则会返回 404 错误代码。

接下来我们需要计算出需要裁剪的区域,由于人脸检测主要是以五官为特征点,返回的坐标主要以脸部为主,不包含头发,人脸检测的区域大概如下图所示。

我这边估算后简单地将人脸检测的区域扩大一倍作为裁剪区域,可以满足需求,当然大家可以根据实际情况进行调整。

接下来我们使用 Python 中的 PIL 库进行裁剪。PIL只支持到 Python 2.7,之后版本应该选择安装 Pillow 库。如果安装的是 Anaconda,已经内置了 pillow,无需安装,否则需要 pip 安装。(假定我们已经通过上面的 API 获取到了人脸上下左右的坐标)

from PIL import Image, ImageDraw
import numpy as np

faceRectangle = {
    "width": 78,
    "height": 78,
    "left": 394,
    "top": 54
}
# 计算需要裁剪的区域
crop_left = faceRectangle['left'] - faceRectangle['width']
crop_right = faceRectangle['left'] + faceRectangle['width'] * 2
crop_top = faceRectangle['top'] - faceRectangle['height']
crop_bottom = faceRectangle['top'] + faceRectangle['height'] * 2

img_path = '本地图片路径'
img = Image.open(img_path).convert("RGB")
cropped = img.crop((crop_left, crop_top, crop_right, crop_bottom))
npImage = np.array(cropped)
h, w = cropped.size

# 新建圆形遮罩图层
alpha = Image.new('L', cropped.size, 0)
draw = ImageDraw.Draw(alpha)
draw.pieslice([0, 0, h, w], 0, 360, fill=255)
npAlpha = np.array(alpha)
npImage = np.dstack((npImage, npAlpha))

# 保存图片结果
Image.fromarray(npImage).save('cut.png')

经过以上三个步骤,我们已经实现了使用 Python 自动裁剪圆形头像的功能,我们可以把上面的代码封装为一个函数,留下图片路径作为参数,就可以进行批量处理了。

import os
from PIL import Image, ImageDraw
import requests
import json
import numpy as np


def cut_circle(path):
    headers = {
        'Content-Type': 'application/octet-stream',
        'Ocp-Apim-Subscription-Key': 'your key',
    }
    params = {
        'returnFaceId': 'true',
        'returnFaceLandmarks': 'false',
        # 'returnFaceAttributes': '{string}',
        'recognitionModel': 'recognition_01',
        'returnRecognitionModel': 'false',
    }
    API_url = 'https://westcentralus.api.cognitive.microsoft.com/face/v1.0/detect'
    data = open(path, 'rb').read()
    response = requests.post(API_url, data=data, headers=headers, params=params)
    faceRectangle = json.loads(response.text)[0]['faceRectangle']
    print(faceRectangle)
    crop_left = faceRectangle['left'] - faceRectangle['width']
    crop_right = faceRectangle['left'] + faceRectangle['width'] * 2
    crop_top = faceRectangle['top'] - faceRectangle['height']
    crop_bottom = faceRectangle['top'] + faceRectangle['height'] * 2

    img = Image.open(path).convert("RGB")

    cropped = img.crop((crop_left, crop_top, crop_right, crop_bottom))

    npImage = np.array(cropped)
    h, w = cropped.size

    # 新建圆形遮罩图层
    alpha = Image.new('L', cropped.size, 0)
    draw = ImageDraw.Draw(alpha)
    draw.pieslice([0, 0, h, w], 0, 360, fill=255)
    npAlpha = np.array(alpha)
    npImage = np.dstack((npImage, npAlpha))

    # 保存图片结果
    Image.fromarray(npImage).save(os.path.splitext(path)[0] + '_circle.png')


if __name__ == '__main__':
    files = os.listdir(r'存放图片的路径')
    for file in files:
        file_path = os.path.join(r'存放图片的路径', file)
        cut_circle(file_path)

小结:

在这篇文章中,我们介绍了使用 PPT 裁剪圆形头像的方法,并学习了如何通过 Python 自动化批量裁剪圆形头像。主要用到的知识点有:

1、微软人脸识别接口的调用

2、PIL 库实现裁剪功能

遗留问题:

1、裁剪区域的合理性:如果人脸在图片中的位置过于靠近边缘,就会导致我们计算的裁剪区域超出图片区域,裁剪结果中就会出现黑色部分,比如下面这张:

2、一张图片中如果有多个人脸,微软 API 就会返回多组值,可以遍历处理每个人脸。这次我为了方便,用的都是单人的图片。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-04-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 不二小段 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
人脸识别
腾讯云神图·人脸识别(Face Recognition)基于腾讯优图强大的面部分析技术,提供包括人脸检测与分析、比对、搜索、验证、五官定位、活体检测等多种功能,为开发者和企业提供高性能高可用的人脸识别服务。 可应用于在线娱乐、在线身份认证等多种应用场景,充分满足各行业客户的人脸属性识别及用户身份确认等需求。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档