python自动给头像添加圣诞帽

通知:今年的圣诞节推迟到2021年1月8日,因为圣诞老人到了之后还要被隔离14天。

在这里插入图片描述
马上就要圣诞节了,大家想好送什么礼物给自己对象了吗?
因为疫情原因,圣诞老人不能来中国给我们送礼物了,所以今年由我来给大家圣诞礼物——用python给你的头像戴圣诞帽!
我知道网上已经有很多关于这个的代码了,他们一般都是调用cv或者dlib的人脸识别库来实现,但今天我想通过调用百度AI的人脸识别接口来实现。

实现步骤

首先我们需要申请百度AI的密钥,之后就可以通过开发文档来进行人脸识别了。(我之前的一篇文章已经讲的十分清楚了python颜值分析,这里就不再描述。)
其次我们需要一个背景透明的圣诞帽。可以通过ps等软件把圣诞帽抠出来,也可以通过python代码。

python使图片白色背景变透明代码:

这是一个单独的python file,你可以命名为transparent.py

from PIL import Image
def transparent():
    img = Image.open('hat.jpg')
    # 图片转换为四通道。第四个通道就是我们要修改的透明度。
    #RGBA是代表Red(红色)Green(绿色)Blue(蓝色)和Alpha的色彩空间。
    #如果一个像素的alpha通道数值为0%,那它就是完全透明的(也就是看不见的),而数值为100%则意味着一个完全不透明的像素(传统的数字图像)。
    img = img.convert('RGBA')
    # 获取图片像素尺寸
    width, height = img.size
    pix = img.load()
    #方法load()返回一个用于读取和修改像素的像素访问对象
    #print(pixel_data[0,0])
    for i in range(height):
        for j in range(width):
            pixel = pix[j, i]
            r = pixel[0]
            g = pixel[1]
            b = pixel[2]
            a = pixel[3]
            # 四通道色彩值大于250(白色且不透明),则将像素点变为透明块
            if r > 245 and g > 245 and b > 245 and a > 250:
                pix[j, i] = (255, 255, 255, 0)
    img.save('newhat.png')  # 保存新图片
transparent()

原图:
在这里插入图片描述
透明化后:
在这里插入图片描述

然后我们需要通过百度AI人脸识别接口得到人脸位置、大小等信息。

获取人脸信息核心代码:

    def face_identification(self):
        # 人脸检测与属性分析
        img = self.img_to_base64(self.img_src)
        request_url = "https://aip.baidubce.com/rest/2.0/face/v3/detect"
        post_data = {
    
    
            "image": img,
            "image_type": "BASE64",
            "max_face_num":10,
            "face_field": "face_num,face_list",#包括age,beauty,expression,face_shape,gender,glasses,landmark,emotion,face_type,mask,spoofing信息
            "face_type": "LIVE"#人脸的类型。LIVE表示生活照,IDCARD表示身份证芯片照,WATERMARK表示带水印证件照,CERT表示证件照片,默认LIVE。
        }
        access_token = self.get_AccessToken()
        request_url = request_url + "?access_token=" + access_token
        response = requests.post(url=request_url, data=post_data, headers=self.headers)
        json_result = json.loads(response.text)
        print(json_result)
        if json_result['error_code'] == 0:
            a = 1
            print('检测到的图片中的人脸数量:',json_result['result']['face_num'])
            for i in json_result['result']['face_list']:
                face_info = []
                print('第{}张人脸信息:'.format(a))
                a=a+1
                left=i['location']['left']
                face_info.append(left)
                top=i['location']['top']
                face_info.append(top)
                width=i['location']['width']
                face_info.append(width)
                height=i['location']['height']
                face_info.append(height)
                print('人脸区域离左边界的距离:',left)
                print('人脸区域离上边界的距离:', top)
                print("人脸区域的宽度:",width )
                print("人物区域的高度:", height)
                faces.append(face_info)
            #print("人物特征点位置:", json_result['result']['face_list'][0]['landmark72'])
        else:
            print(json_result['error_code'])
            print(json_result['error_msg'])

最后我们需要根据人脸信息确定圣诞帽的位置。

确定圣诞帽位置代码:

def addhat(faces,face_image,hat_image):
    for face in faces:
        hat = cv2.imread(hat_image, -1)  # 读入完整图片,包括alpha通道。
        scale = face[3] / hat.shape[0] * 1.4
        hat = cv2.resize(hat, (0, 0), fx=scale, fy=scale)  # 改变帽子大小
        x_offset = int(face[0] -10+face[2] / 2 - hat.shape[1] / 2)
        y_offset = int(face[1] - hat.shape[0]/1)  # 根据人脸坐标调整帽子位置
        x1, x2 = max(x_offset, 0), min(x_offset + hat.shape[1], face_image.shape[1])
        y1, y2 = max(y_offset, 0), min(y_offset + hat.shape[0], face_image.shape[0])
        hat_x1 = max(0, -x_offset)
        hat_x2 = hat_x1 + x2 - x1
        hat_y1 = max(0, -y_offset)
        hat_y2 = hat_y1 + y2 - y1  # 计算贴图位置
        alpha_h = hat[hat_y1:hat_y2, hat_x1:hat_x2, 3] / 255  # 透明部分的处理
        alpha = 1 - alpha_h
        for c in range(0, 3):
            face_image[y1:y2, x1:x2, c] = (alpha_h * hat[hat_y1:hat_y2, hat_x1:hat_x2, c] + alpha * face_image[y1:y2, x1:x2,c])  # 按3个通道合并图片
    return face_image

上面代码参考于网上。

给头像添加圣诞帽完整代码:

这是另一个独立的python file,你可以命名为add_hat.py

# encoding:utf-8
import base64
import json
import requests
import cv2

class BaiduAI:
    def __init__(self, img):
        self.AK = ""#你的应用API Key
        self.SK = ""#你的应用Secret Key
        self.img_src = img
        self.headers = {
    
    
            "Content-Type": "application/json; charset=UTF-8"
        }

    def get_AccessToken(self):
        #获取Access Token
        host = 'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=' + self.AK + '&client_secret=' + self.SK
        response = requests.get(host, headers=self.headers)
        json_result = json.loads(response.text)
        if response:
            return json_result['access_token']
        else:
            print(json_result)
            return 0

    def img_to_base64(slef, path):
        #图片转化为base64
        with open(path, 'rb') as f:
            image = f.read()
            image_base64 = str(base64.b64encode(image), encoding='utf-8')
        return image_base64

    def face_identification(self):
        # 人脸检测与属性分析
        img = self.img_to_base64(self.img_src)
        request_url = "https://aip.baidubce.com/rest/2.0/face/v3/detect"
        post_data = {
    
    
            "image": img,
            "image_type": "BASE64",
            "max_face_num":10,
            "face_field": "face_num,face_list",#包括age,beauty,expression,face_shape,gender,glasses,landmark,emotion,face_type,mask,spoofing信息
            "face_type": "LIVE"#人脸的类型。LIVE表示生活照,IDCARD表示身份证芯片照,WATERMARK表示带水印证件照,CERT表示证件照片,默认LIVE。
        }
        access_token = self.get_AccessToken()
        request_url = request_url + "?access_token=" + access_token
        response = requests.post(url=request_url, data=post_data, headers=self.headers)
        json_result = json.loads(response.text)
        print(json_result)
        if json_result['error_code'] == 0:
            a = 1
            print('检测到的图片中的人脸数量:',json_result['result']['face_num'])
            for i in json_result['result']['face_list']:
                face_info = []
                print('第{}张人脸信息:'.format(a))
                a=a+1
                left=i['location']['left']
                face_info.append(left)
                top=i['location']['top']
                face_info.append(top)
                width=i['location']['width']
                face_info.append(width)
                height=i['location']['height']
                face_info.append(height)
                print('人脸区域离左边界的距离:',left)
                print('人脸区域离上边界的距离:', top)
                print("人脸区域的宽度:",width )
                print("人物区域的高度:", height)
                faces.append(face_info)
            #print("人物特征点位置:", json_result['result']['face_list'][0]['landmark72'])
        else:
            print(json_result['error_code'])
            print(json_result['error_msg'])
def addhat(faces,face_image,hat_image):
    for face in faces:
        hat = cv2.imread(hat_image, -1)  # 读入完整图片,包括alpha通道。
        scale = face[3] / hat.shape[0] * 1.5
        hat = cv2.resize(hat, (0, 0), fx=scale, fy=scale)  # 改变帽子大小
        x_offset = int(face[0] +face[2] / 2 - hat.shape[1] / 2)
        y_offset = int(face[1] - hat.shape[0]/1.2)  # 根据人脸坐标调整帽子位置
        x1, x2 = max(x_offset, 0), min(x_offset + hat.shape[1], face_image.shape[1])
        y1, y2 = max(y_offset, 0), min(y_offset + hat.shape[0], face_image.shape[0])
        hat_x1 = max(0, -x_offset)
        hat_x2 = hat_x1 + x2 - x1
        hat_y1 = max(0, -y_offset)
        hat_y2 = hat_y1 + y2 - y1  # 计算贴图位置
        alpha_h = hat[hat_y1:hat_y2, hat_x1:hat_x2, 3] / 255  # 透明部分的处理
        alpha = 1 - alpha_h
        for c in range(0, 3):
            face_image[y1:y2, x1:x2, c] = (alpha_h * hat[hat_y1:hat_y2, hat_x1:hat_x2, c] + alpha * face_image[y1:y2, x1:x2,c])  # 按3个通道合并图片
    return face_image
if __name__ == '__main__':
    img_file = ''
    hat_file=''
    faces=[]
    demo = BaiduAI(img_file)
    if(demo.get_AccessToken()):
        demo.face_identification()
    print(faces)
    face_image = cv2.imread(img_file)
    face_image=addhat(faces,face_image,hat_file)
    cv2.imwrite('addhat_' + img_file, face_image)

说明:self.AK用你的应用API Key,self.SK用你的应用Secret Key。img_file用你的照片路径,hat_file用你的圣诞帽图片路径。

最终效果

原图:
在这里插入图片描述
戴上圣诞帽:
在这里插入图片描述
原图:
在这里插入图片描述
戴上圣诞帽:
在这里插入图片描述
这次的分享到此结束。
圣诞节要到了,送大家三千万。千万要开心,千万要快乐,千万要幸福!!!
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_44809707/article/details/111568429
今日推荐