引言
在网上看到一篇基于python实现AI换脸的文章,觉得很好玩复现了一下。研究了几个小时后成功把迪丽热巴的脸换到关晓彤上,很好看;另外还把蔡徐坤的脸换到特朗普上,效果那是相当惊人(⊙ˍ⊙)
思路
思路比较简单,主要使用了旷视人工智能平台上的API实现。首先调用脸部识别API识别被换图和融合图,再调用脸部融合API换脸就完成了。整个过程中要用到request库调用API,json、simplejson和base64模块编码和解码,以及文件的读写操作
人脸识别API
脸部融合API
代码
import requests
import simplejson
import json
import base64
def detect_face(path, img): # 脸部识别
print("detecting %s..."%(img))
url_detect = "https://api-cn.faceplusplus.com/facepp/v3/detect" # 旷视Detect API
data = {"api_key": "UmeTHKmayj5KFi6SCTt3-0rwc8XSx9k9",
"api_secret": "KlpfpUnIK_0FllNu3JbREJM3WKppz1OJ", "image_file":img ,
"return_landmark": 2} # 构造表单数据,用于post请求(api_key和api_secret要注册旷视人工智能平台后才有)
files = {"image_file": open(path+img, "rb")}
response = requests.post(url_detect, data=data, files=files)
req_con = response.content.decode("utf-8") # 将已编码的json字符解码为python对象
req_dict = json.JSONDecoder().decode(req_con)
this_json = simplejson.dumps(req_dict) # 将python对象编码成json字符串
this_json2 = simplejson.loads(this_json) # 将已编码的json字符串解码为python对象
faces = this_json2["faces"]
# print(faces)
rectangle = list0["face_rectangle"]
return rectangle
def merge_face(path, img1, img2, img3, number): # 人脸融合
list0 = faces[0]
df1 = detect_face(path, img1)
df2 = detect_face(path, img2)
rectangle1 = str(df1["top"]) + "," + str(df1["left"]) + "," + str(df1["width"]) + "," + str(df1["height"])
rectangle2 = str(df2["top"]) + "," + str(df2["left"]) + "," + str(df2["width"]) + "," + str(df2["height"])
url_merge = "https://api-cn.faceplusplus.com/imagepp/v1/mergeface" # 旷视Merge_face API
f1 = open(path+img1, "rb")
f1_64 = base64.b64encode(f1.read())
f1.close()
f2 = open(path+img2, "rb")
f2_64 = base64.b64encode(f2.read())
f2.close()
data = {"api_key": "UmeTHKmayj5KFi6SCTt3-0rwc8XSx9k9",
"api_secret": "KlpfpUnIK_0FllNu3JbREJM3WKppz1OJ",
"template_base64": f1_64, "template_rectangle": rectangle1,
"merge_base64": f2_64, "merge_rectangle": rectangle2,
"merge_rate": number}
print("merging...")
response = requests.post(url_merge, data=data)
req_con = response.content.decode("utf-8")
req_dict = json.JSONDecoder().decode(req_con)
result = req_dict["result"]
imgdata = base64.b64decode(result)
file = open(path+img3, "wb")
file.write(imgdata)
file.close()
def main():
path = input("输入图片路径:")
image1 = input("输入被换图名称:")
image2 = input("输入融合图名称:")
image3 = input("输入换脸后的图片名称:")
try:
merge_face(path, image1, image2, image3, 100) # 融合率为100
print("converted successfully!")
except:
print("出现异常")
import traceback
traceback.print_exc()
main()
效果
经过测试发现:换脸效果和两张脸的朝向、脸型、大小、五官位置、是否闭眼有关(要得到不错的换脸图,条件还真有点苛刻),剔除了一些合成效果不好的图片后,保留了两组换脸效果还不错的图
还不错!
参考:
python实现AI换脸