给wulikunkun换脸,但是在换之后不能正常显示换之后的图片,思路就是把动图每一帧保存,然后调用face++人脸识别的api识别出人脸的位置,将要换的图片用Image.paste()方法在人脸的位置进行粘贴,最后再用imageio库对已经修改好的图片制作GIF图片。
原图:
要换的图片:
代码里的api key和secret要自己去face++官网申请
代码:
import requests
import base64
import json
import os
from PIL import Image, ImageDraw
import imageio
def devide():
im = Image.open('ikun.gif')
try:
while True:
# C:\Users\是景航啊\Desktop\kun
# 保存当前帧
# C:\Users\hpuzjh\Desktop\人工智能
im.save('/Users/hpuzjh/Desktop/人工智能/kun/%s.png' % (im.tell())) # 使用jpg就不对?
# 跳到下一帧
im.seek(im.tell() + 1)
except:
print('动图已按帧分割结束')
# 转64位编码
def change2base64(file_path):
f = open(file_path,'rb')
base64_data = base64.b64encode(f.read())
s = base64_data.decode()
ss = 'data:image/jpeg;base64,%s' %(s)
return ss
def req(file_path):
http_url = 'https://api-cn.faceplusplus.com/facepp/v3/detect'
key = 'XXX'
secret = 'XXX'
# 设置参数
data = {}
data['api_key'] = key
data['api_secret'] = secret
data['image_base64'] = change2base64(file_path)
data['return_attributes'] = 'gender,ethnicity' #性别与人种
# post方式进行请求 200
response = requests.post(url = http_url,data = data)
return_content = response.text #str
# 转成字典格式 dict
return_content = json.loads(return_content)
# 可能出现没有检测出人脸的情况
if return_content['face_num'] == 0:
return False
else:
width, y, x, height = return_content['faces'][0]['face_rectangle'].values()
return width, y, x, height
def draw(file_path,img):
if req(file_path):
width, y, x, height = req(file_path)
# print(width,height)
image = Image.open(file_path)
# image.show()
markImg = Image.open('k.jpg')
# markImg.show()
# draw = ImageDraw.Draw(image)
# # draw.rectangle((x, y, x+width, y+height),None,'red')
# draw.polygon([(x,y), (x+width, y),(x+width, y+height),(x, y+height)])
# # image.show()
image.paste(markImg, (x,y))
# image.show()
print('%s图片中检测出人脸正在更换保存' % (img))
image.save('./kunkun/'+img)
else:
image = Image.open(file_path)
image.save('./kunkun/' + img)
print('%s图片中没有检测出人脸正在保存' %(img))
def read_folder(file_dir):
# 直接读出的文件名是按照字符串排序的
filenames = os.listdir(file_dir)
# 倒着数第四位'.'为分界线,按照'.'左边的数字从小到大排序
filenames.sort(key=lambda x: int(x[:-4]))
return filenames
def make_gif():
image_list = read_folder('./kunkun/')
image_list = ['./kunkun/'+i for i in image_list ]
# print(image_list)
gif_name = 'kunkun.gif'
frames = []
for image_name in image_list:
frames.append(imageio.imread(image_name))
imageio.mimsave(gif_name, frames, 'GIF', duration=0.01)
return
if __name__ == '__main__':
devide()
file_dir = './kun/'
# 图片名字列表
imgname_list = read_folder(file_dir)
for img in imgname_list:
file_path = './kun/'+img
draw(file_path,img)
make_gif()
完成的作品:
直接做好的动图太大了,三十多兆,这个是压缩过的