from aip import AipFace
import base64
from PIL import Image


# 人脸比对函数(client:人脸识别客户，img_src_path:参考的原图路径，img_det_path：比对人脸路径）
def face_match(client, img_src_path, img_det_path):
    # 将两张照片的数据分别转换为base64格式编码的字符串
    img_scr64 = str(base64.b64encode(open(img_src_path, 'rb').read()), 'utf-8')
    img_det64 = str(base64.b64encode(open(img_det_path, 'rb').read()), 'utf-8')
    # 调用百度AI人脸比对函数
    result = client.match(
        [{'image': img_scr64, 'image_type': 'BASE64'},
         {'image': img_det64, 'image_type': 'BASE64'}])
    result = result['result']  # 从接口返回值中取出result项
    if result is None:  # 若result值为空，说明人脸比对失败，返回False
        return False
    elif result['score'] >= 80:  # 若result中的score值大于80，返回True,否则返回False
        return True
    else:
        return False


# 定义人脸位置检测函数
def face_detect(client, img_det_path):
    # 功能：对一张照片进行检测，返回各张人脸位置
    # 参数client:百度AI人脸识别客户端，img_det_path：待检测图片路径
    # 返回值：人脸区域的位置列表，人脸区域的位置包括左端、顶端、右端、底端
    img_det64 = str(base64.b64encode(open(img_det_path, 'rb').read()), 'utf-8')
    # 调用人脸检测接口
    result = client.detect(img_det64, 'BASE64', {"max_face_num": 10})
    result = result['result']
    face_list = []
    if result is not None:
        for face in result['face_list']:
            left = face['location']['left']
            top = face['location']['top']
            right = left + face['location']['width']
            bottom = top + face['location']['height']
            face_list.append([left, top, right, bottom])
    return face_list


# 填写你的文字识别应用的App ID、API Key、Secret Key
APP_ID = ''
API_Key = ''
Secret_Key = ''
client = AipFace(APP_ID, API_Key, Secret_Key)
img_src_path = './imgs/org-1.jpg'  # 参考原图的文件路径
while True:
    det_fName = input('识别的合照文件名（若直接按回车，程序结束）：')
    if det_fName == '':
        break
    img_det_path = './imgs/' + det_fName  # 多人合照的文件路径
    face_list = face_detect(client, img_det_path)  # 人脸位置检测
    img_det = Image.open(img_det_path)
    for face in face_list:
        # 根据face的人脸区域位置剪裁人脸，并保存成图片
        img_crop = img_det.crop(face)
        img_crop.save('img_crop.jpg')
        # 将剪裁的人脸图片与参考原图比对
        is_same = face_match(client, img_src_path, 'img_crop.jpg')
        if is_same:  # 若比对是同一人，输出合照有此人并退出循环
            print('合照有此人')
            break
    else:  # 合照的所有人和参考原图比对都不是同一人，输出合照无此人
        print('合照无此人')
