0. 百度AI开放平台使用步骤

https://www.cnblogs.com/ghgxj/p/14219117.html

1 建立连接与对象

# https://ai.baidu.com/ai-doc/IMAGERECOGNITION/Xk3bcxjho
from aip import AipImageClassify""" 你的 APPID AK SK """
APP_ID = '你的 App ID'  #用自己注册的APP替换
API_KEY = '你的 Api Key'
SECRET_KEY = '你的 Secret Key'client = AipImageClassify(APP_ID, API_KEY, SECRET_KEY)

2. 读取图片函数

# https://ai.baidu.com/ai-doc/IMAGERECOGNITION/4k3bcxj1m""" 读取图片 """
def get_file_content(filePath):with open(filePath, 'rb') as fp:return fp.read()

3. 使用实例

3.1 通用物体识别

3.1.1 SDK方式

# https://ai.baidu.com/ai-doc/IMAGERECOGNITION/4k3bcxj1m
image = get_file_content('yuanlongping.png')# """ 调用通用物体识别 """
# client.advancedGeneral(image);""" 如果有可选参数 """
options = {}
options["baike_num"] = 4""" 带参数调用通用物体识别 """
client.advancedGeneral(image, options)
{'result_num': 5,'result': [{'keyword': '轿车','score': 0.832354,'root': '交通工具-汽车','baike_info': {'baike_url': 'http://baike.baidu.com/item/%E8%BD%BF%E8%BD%A6/568373','image_url': 'https://bkimg.cdn.bcebos.com/pic/ac6eddc451da81cb39db49bf932ec7160924ab189b22','description': '轿车(saloon car)是指用于载送人员及其随身物品,且座位布置在两轴之间的汽车。包括驾驶者在内,座位数最多不超过九个。一般轿车强调的是舒适性,以乘员为中心。而且是从经济性考虑出发,选择马力适中、排量小、耗油量小的发动机。在中国内地的行驶证管理方面,轿车特指区别于货车、皮卡、SUV、大巴、中巴的小型汽车,俗称为“小轿车”。在香港,轿车又称私家车。'}},{'keyword': '汽车','score': 0.557051,'root': '交通工具-汽车','baike_info': {'baike_url': 'http://baike.baidu.com/item/%E6%B1%BD%E8%BD%A6/152503','image_url': 'https://bkimg.cdn.bcebos.com/pic/f3d3572c11dfa9ec8a13cbb20a9ae003918fa0ec6b49','description': '我国国家最新标准《汽车和挂车类型的术语和定义》(GB/T 3730.1—2001)中对汽车有如下定义:由动力驱动,具有4个或4个以上车轮的非轨道承载的车辆,主要用于:载运人员和(或)货物;牵引载运人员和(或)货物的车辆;特殊用途。国产汽车品牌有:红旗、长安、长城、奇瑞、吉利、荣威等。国外汽车品牌有:丰田、大众、现代、起亚、标致等。'}},{'keyword': 'SUV','score': 0.37136,'root': '交通工具-汽车','baike_info': {'baike_url': 'http://baike.baidu.com/item/SUV/29834','image_url': 'https://bkimg.cdn.bcebos.com/pic/d0c8a786c9177f3ec059cf7e7fcf3bc79f3d5657','description': 'SUV是指运动型多用途汽车,不同于可在崎岖地面使用的ORV越野车(Off-Road Vehicle的缩写);SUV全称是sport utility vehicle,或suburban utility vehicle,即运动性多用途汽车或城郊多用途汽车,是一种拥有旅行车般的空间机能,配以货卡车的越野能力的车型。'}},{'keyword': '跑车','score': 0.183879,'root': '交通工具-汽车','baike_info': {'baike_url': 'http://baike.baidu.com/item/%E8%B7%91%E8%BD%A6/303835','image_url': 'https://bkimg.cdn.bcebos.com/pic/5882b2b7d0a20cf431ad6481df425c36acaf2edd3313','description': '跑车的英文名是SportsCar或SportyCar。概念是车身线条流畅、车身高度低、操控性优良、动力强悍的汽车。其最大特点是不断追求速度极限。跑车的分类有很多种,按车身结构可分为轿跑、敞篷跑车、双门跑车,按价值可分为平民跑车、超级跑车。'}},{'keyword': '汽车中网', 'score': 0.007603, 'root': '交通工具-汽车'}],'log_id': 1648830542004231696}

3.1.2 API方式

# https://ai.baidu.com/ai-doc/IMAGERECOGNITION/7k3bcxdn8  # encoding:utf-8
import requests
import base64
from pprint import pprint""" 你的 APPID AK SK """
APP_ID = '你的 App ID'  #用自己注册的APP替换
API_KEY = '你的 Api Key'
SECRET_KEY = '你的 Secret Key''''
通用物体和场景识别
'''request_url = "https://aip.baidubce.com/rest/2.0/image-classify/v2/advanced_general"
# 二进制方式打开图片文件
f = open('yuanlongping.png', 'rb')
img = base64.b64encode(f.read())params = {"image":img,'baike_num':3}# 1,准备好申请的人脸识别api,API Key, Secret Key
# · grant_type: 必须参数,固定为client_credentials;
# · client_id: 必须参数,应用的API Key;
# · client_secret: 必须参数,应用的Secret Key;
access_token = 'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id='+API_KEY+'&client_secret='+SECRET_KEY# 2,获取token值,拼接API
response=requests.get(access_token)
access_token=eval(response.text)['access_token']
request_url="https://aip.baidubce.com/rest/2.0/image-classify/v2/advanced_general"+"?access_token="+access_tokenheaders = {'content-type': 'application/x-www-form-urlencoded'}
response = requests.post(request_url, data=params, headers=headers)
if response:pprint (response.json())

3.2 菜品识别

3.2.1 SDK方式

  • 建立连接与对象
# https://ai.baidu.com/ai-doc/IMAGERECOGNITION/Xk3bcxjho
from aip import AipImageClassify""" 你的 APPID AK SK """
APP_ID = '你的 App ID'  #用自己注册的APP替换
API_KEY = '你的 Api Key'
SECRET_KEY = '你的 Secret Key'client = AipImageClassify(APP_ID, API_KEY, SECRET_KEY)
  • 读取图片函数
# https://ai.baidu.com/ai-doc/IMAGERECOGNITION/4k3bcxj1m""" 读取图片 """
def get_file_content(filePath):with open(filePath, 'rb') as fp:return fp.read()
  • 调用接口函数
# https://ai.baidu.com/ai-doc/IMAGERECOGNITION/4k3bcxj1m  image = get_file_content('hongshaorou.jpg')# """ 调用菜品识别 """
# client.dishDetect(image);""" 如果有可选参数 """
options = {}
options["top_num"] = 5
options["filter_threshold"] = "0.7"
options["baike_num"] = 2
options['top_num'] = 4""" 带参数调用菜品识别 """
result = client.dishDetect(image, options)
pprint(result)
{'log_id': 1643928572215157516,'result': [{'baike_info': {'baike_url': 'http://baike.baidu.com/item/%E7%BA%A2%E7%83%A7%E8%82%89/571767','description': '红烧肉(拼音: hóng shāo ''ròu),一道著名的大众菜肴,各大菜系都有自己特色的红烧肉。其以五花肉为制作主料,也可用猪后腿代替,最好选用肥瘦相间的三层肉来做,锅具以砂锅为主,做出来的肉肥瘦相间,香甜松软,营养丰富,入口即化。红烧肉在我国各地流传甚广,做法多达二三十种,具有一定的营养价值。','image_url': 'https://bkimg.cdn.bcebos.com/pic/a5c27d1ed21b0ef41bd57f1c348d46da81cb39db9015'},'calorie': '227','has_calorie': True,'name': '红烧肉','probability': '0.994802'},{'baike_info': {'baike_url': 'http://baike.baidu.com/item/%E9%BB%91%E7%8C%AA%E8%82%89/9675905','description': '黑猪肉肉质细腻且营养价值丰富。肌肉中的不饱和脂肪酸的含量为8.87%,特别是亚麻酸能保护肝脏,能提高人体免疫能力,同时还可以改善人体内SOD的活性,抑制MDA的生成,延缓机体衰老,细胞老化。含量显著高于其他猪种,对人体有极高的营养价值及保健作用,如长期食用可延年益寿,并有着汤汁浓郁,绕齿留香。黑猪肌肉内的肉品鲜味主要特征氨基酸天门冬氨酸、谷氨酸、甘氨酸、丙氨酸,肌苷酸的总含量明显高于洋猪,烹饪调出的汤汁浓郁,口留余香,对人体有着较大的辅助功能。','image_url': 'https://bkimg.cdn.bcebos.com/pic/b812c8fcc3cec3fd7e22ad95dc88d43f87942735'},'has_calorie': False,'name': '黑猪肉','probability': '0.00109681'},{'calorie': '470','has_calorie': True,'name': '红烧肉饭','probability': '0.000587202'},{'has_calorie': False, 'name': '非菜', 'probability': '0.000448507'}],'result_num': 4}

3.2.2 API方式

# https://ai.baidu.com/ai-doc/IMAGERECOGNITION/tk3bcxbb0  import requests
import json
import base64
import urllib
from pprint import pprint
from aip import AipImageClassifydef get_access_token():""" 你的 APPID AK SK """APP_ID = '你的 App ID'  #用自己注册的APP替换API_KEY = '你的 Api Key'SECRET_KEY = '你的 Secret Keyurl = 'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=%s&client_secret=%s' % (API_KEY, SECRET_KEY)response = requests.post(url)access_token = response.content.decode('utf-8')access_token = json.loads(access_token)access_token = str(access_token['access_token'])return access_tokendef get_file_content(filePath):with open(filePath,'rb') as fp:return fp.read()def get_recognization(access_token):host = 'https://aip.baidubce.com/rest/2.0/image-classify/v2/dish?access_token=' + access_tokenheader = {'Content-Type' : 'appliapplication/x-www-form-urlencodedcation/x'}#这里改成自己的文件路径image = get_file_content('yuxiangrousi.jpg')image = base64.b64encode(image)body = {'image' : image, 'top_num' : 3}body = urllib.parse.urlencode(body)response = requests.post(host,data=body,headers=header)response = json.loads(response.text)pprint(response)name = response['result'][0]['name']return namedef main():access_token = get_access_token()recognization = get_recognization(access_token)print(recognization)if __name__ == '__main__':main()
{'log_id': 1643928700482877206,'result': [{'calorie': '154','has_calorie': True,'name': '鱼香肉丝','probability': '0.9769'},{'calorie': '268','has_calorie': True,'name': '肉丝饭','probability': '0.0106227'},{'calorie': '99','has_calorie': True,'name': '青椒肉丝','probability': '0.00476454'}],'result_num': 3}
鱼香肉丝

3.3 人脸检测

3.3.0 基础知识练习

3.3.0.1 查看百度AI开放平台返回结果形式

result= {'cached': 0,'error_code': 0,'error_msg': 'SUCCESS','log_id': 1764157945,'result': {'face_list': [{'age': 31,'angle': {'pitch': 3.39, 'roll': 1.81, 'yaw': -11.1},'beauty': 38.31,'face_probability': 1,'face_token': '9aca8a4f5c92b0c508d9bb9be3c5f3dd','liveness': {'livemapscore': 0.9921809435},'location': {'height': 88,'left': 266.36,'rotation': 5,'top': 460.79,'width': 109}},{'age': 43,'angle': {'pitch': 2.29, 'roll': -1.95, 'yaw': 0.89},'beauty': 50,'face_probability': 1,'face_token': 'ed5061925266fca0d8ed60c6d41fcbf6','liveness': {'livemapscore': 0.3553299606},'location': {'height': 96,'left': 1146.55,'rotation': 0,'top': 598.84,'width': 99}},{'age': 26,'angle': {'pitch': 1.51,'roll': -3.03,'yaw': -2.52},'beauty': 33.59,'face_probability': 1,'face_token': '87cbe88e63aec3bcbc054759750b9f90','liveness': {'livemapscore': 0.6609219313},'location': {'height': 94,'left': 1001.44,'rotation': 0,'top': 386.45,'width': 96}},{'age': 27,'angle': {'pitch': -3.43,'roll': -3.26,'yaw': 2.09},'beauty': 47.41,'face_probability': 1,'face_token': '68745f9db2a97960062c2eaf52442821','liveness': {'livemapscore': 0.3761869073},'location': {'height': 93,'left': 1260.73,'rotation': 0,'top': 323.98,'width': 97}},{'age': 24,'angle': {'pitch': -1.75,'roll': -5.74,'yaw': -6.5},'beauty': 51.75,'face_probability': 1,'face_token': '900f20c8a44214ec79a959b90c12b85c','liveness': {'livemapscore': 0.4826832116},'location': {'height': 92,'left': 1515.71,'rotation': -3,'top': 622.62,'width': 97}},{'age': 32,'angle': {'pitch': -1.12,'roll': -7.19,'yaw': 19.12},'beauty': 42.25,'face_probability': 1,'face_token': '197a5dea47764947d62298dd7c3064f5','liveness': {'livemapscore': 0.9917771816},'location': {'height': 89,'left': 2042.32,'rotation': -7,'top': 432.1,'width': 100}},{'age': 29,'angle': {'pitch': 5.98, 'roll': 2.6, 'yaw': -0.31},'beauty': 48.38,'face_probability': 1,'face_token': 'ee76b675ae9b527ed272bc0871a1475b','liveness': {'livemapscore': 0.8710184097},'location': {'height': 91,'left': 831.63,'rotation': 3,'top': 597.42,'width': 95}},{'age': 44,'angle': {'pitch': 0.35,'roll': -4.29,'yaw': -7.73},'beauty': 44.19,'face_probability': 1,'face_token': '8df0dc7a5e44beddf15e5ad0a3eb5f53','liveness': {'livemapscore': 0.8760032058},'location': {'height': 87,'left': 482.05,'rotation': -1,'top': 433.92,'width': 98}},{'age': 37,'angle': {'pitch': -2.24,'roll': -0.81,'yaw': -1.41},'beauty': 30.48,'face_probability': 1,'face_token': '77fd8183f918fde5f37b762558a27728','liveness': {'livemapscore': 0.4300559759},'location': {'height': 89,'left': 703.91,'rotation': 1,'top': 390.34,'width': 93}},{'age': 28,'angle': {'pitch': 2.29,'roll': -11.59,'yaw': 9.55},'beauty': 62.31,'face_probability': 1,'face_token': 'a0a417e4fadaf95aa8170c77ffc6cd3f','liveness': {'livemapscore': 0.05391738191},'location': {'height': 89,'left': 1848.9,'rotation': -8,'top': 383.45,'width': 89}},{'age': 23,'angle': {'pitch': -4.61,'roll': -6.71,'yaw': 0.68},'beauty': 53,'face_probability': 1,'face_token': 'e56d7bb1e5ccaea17fb77ba834ebe0c2','liveness': {'livemapscore': 0.05685265362},'location': {'height': 86,'left': 1571.27,'rotation': -4,'top': 360.19,'width': 89}}],'face_num': 11},'timestamp': 1681950564}

3.3.0.2 解析结果,获取相关信息

  • 获取是否检测成功
result['error_msg']
'SUCCESS'
  • 获取检测出的人脸数目
result['result']['face_num']
11
  • 获取检测出的所有人脸的相关信息
result['result']['face_list']
[{'age': 31,'angle': {'pitch': 3.39, 'roll': 1.81, 'yaw': -11.1},'beauty': 38.31,'face_probability': 1,'face_token': '9aca8a4f5c92b0c508d9bb9be3c5f3dd','liveness': {'livemapscore': 0.9921809435},'location': {'height': 88,'left': 266.36,'rotation': 5,'top': 460.79,'width': 109}},{'age': 43,'angle': {'pitch': 2.29, 'roll': -1.95, 'yaw': 0.89},'beauty': 50,'face_probability': 1,'face_token': 'ed5061925266fca0d8ed60c6d41fcbf6','liveness': {'livemapscore': 0.3553299606},'location': {'height': 96,'left': 1146.55,'rotation': 0,'top': 598.84,'width': 99}},{'age': 26,'angle': {'pitch': 1.51, 'roll': -3.03, 'yaw': -2.52},'beauty': 33.59,'face_probability': 1,'face_token': '87cbe88e63aec3bcbc054759750b9f90','liveness': {'livemapscore': 0.6609219313},'location': {'height': 94,'left': 1001.44,'rotation': 0,'top': 386.45,'width': 96}},{'age': 27,'angle': {'pitch': -3.43, 'roll': -3.26, 'yaw': 2.09},'beauty': 47.41,'face_probability': 1,'face_token': '68745f9db2a97960062c2eaf52442821','liveness': {'livemapscore': 0.3761869073},'location': {'height': 93,'left': 1260.73,'rotation': 0,'top': 323.98,'width': 97}},{'age': 24,'angle': {'pitch': -1.75, 'roll': -5.74, 'yaw': -6.5},'beauty': 51.75,'face_probability': 1,'face_token': '900f20c8a44214ec79a959b90c12b85c','liveness': {'livemapscore': 0.4826832116},'location': {'height': 92,'left': 1515.71,'rotation': -3,'top': 622.62,'width': 97}},{'age': 32,'angle': {'pitch': -1.12, 'roll': -7.19, 'yaw': 19.12},'beauty': 42.25,'face_probability': 1,'face_token': '197a5dea47764947d62298dd7c3064f5','liveness': {'livemapscore': 0.9917771816},'location': {'height': 89,'left': 2042.32,'rotation': -7,'top': 432.1,'width': 100}},{'age': 29,'angle': {'pitch': 5.98, 'roll': 2.6, 'yaw': -0.31},'beauty': 48.38,'face_probability': 1,'face_token': 'ee76b675ae9b527ed272bc0871a1475b','liveness': {'livemapscore': 0.8710184097},'location': {'height': 91,'left': 831.63,'rotation': 3,'top': 597.42,'width': 95}},{'age': 44,'angle': {'pitch': 0.35, 'roll': -4.29, 'yaw': -7.73},'beauty': 44.19,'face_probability': 1,'face_token': '8df0dc7a5e44beddf15e5ad0a3eb5f53','liveness': {'livemapscore': 0.8760032058},'location': {'height': 87,'left': 482.05,'rotation': -1,'top': 433.92,'width': 98}},{'age': 37,'angle': {'pitch': -2.24, 'roll': -0.81, 'yaw': -1.41},'beauty': 30.48,'face_probability': 1,'face_token': '77fd8183f918fde5f37b762558a27728','liveness': {'livemapscore': 0.4300559759},'location': {'height': 89,'left': 703.91,'rotation': 1,'top': 390.34,'width': 93}},{'age': 28,'angle': {'pitch': 2.29, 'roll': -11.59, 'yaw': 9.55},'beauty': 62.31,'face_probability': 1,'face_token': 'a0a417e4fadaf95aa8170c77ffc6cd3f','liveness': {'livemapscore': 0.05391738191},'location': {'height': 89,'left': 1848.9,'rotation': -8,'top': 383.45,'width': 89}},{'age': 23,'angle': {'pitch': -4.61, 'roll': -6.71, 'yaw': 0.68},'beauty': 53,'face_probability': 1,'face_token': 'e56d7bb1e5ccaea17fb77ba834ebe0c2','liveness': {'livemapscore': 0.05685265362},'location': {'height': 86,'left': 1571.27,'rotation': -4,'top': 360.19,'width': 89}}]
  • 获取检测出的第一张人脸的相关信息
result['result']['face_list'][0]
{'age': 31,'angle': {'pitch': 3.39, 'roll': 1.81, 'yaw': -11.1},'beauty': 38.31,'face_probability': 1,'face_token': '9aca8a4f5c92b0c508d9bb9be3c5f3dd','liveness': {'livemapscore': 0.9921809435},'location': {'height': 88,'left': 266.36,'rotation': 5,'top': 460.79,'width': 109}}
  • 获取检测出的第一张人脸的年龄
result['result']['face_list'][0]['age']
31
  • 获取检测出的第一张人脸的颜值
result['result']['face_list'][0]['beauty']
38.31
  • 获取检测处的第一张人脸的位置
result['result']['face_list'][0]['location']
{'height': 88, 'left': 266.36, 'rotation': 5, 'top': 460.79, 'width': 109}
  • 获取检测处的第一张人脸的左上角点x坐标
result['result']['face_list'][0]['location']['left']
266.36
  • 获取检测处的第一张人脸的左上角点y坐标
result['result']['face_list'][0]['location']['top']
460.79
  • 获取检测处的第一张人脸的宽度
result['result']['face_list'][0]['location']['width']
109
  • 获取检测处的第一张人脸的高度
result['result']['face_list'][0]['location']['height']
88
  • 循环获取检测出的所有人脸的年龄、颜值、位置,打印输出
no = 1
face_list = result['result']['face_list']
for face in face_list:age = face['age']beauty = face['beauty']location = face['location']print(f"第{no}张人脸信息:")print(f"年龄:{age},颜值:{beauty}")print(f"位置:")print(location)print("="*75)no += 1
第1张人脸信息:
年龄:31,颜值:38.31
位置:
{'height': 88, 'left': 266.36, 'rotation': 5, 'top': 460.79, 'width': 109}
===========================================================================
第2张人脸信息:
年龄:43,颜值:50
位置:
{'height': 96, 'left': 1146.55, 'rotation': 0, 'top': 598.84, 'width': 99}
===========================================================================
第3张人脸信息:
年龄:26,颜值:33.59
位置:
{'height': 94, 'left': 1001.44, 'rotation': 0, 'top': 386.45, 'width': 96}
===========================================================================
第4张人脸信息:
年龄:27,颜值:47.41
位置:
{'height': 93, 'left': 1260.73, 'rotation': 0, 'top': 323.98, 'width': 97}
===========================================================================
第5张人脸信息:
年龄:24,颜值:51.75
位置:
{'height': 92, 'left': 1515.71, 'rotation': -3, 'top': 622.62, 'width': 97}
===========================================================================
第6张人脸信息:
年龄:32,颜值:42.25
位置:
{'height': 89, 'left': 2042.32, 'rotation': -7, 'top': 432.1, 'width': 100}
===========================================================================
第7张人脸信息:
年龄:29,颜值:48.38
位置:
{'height': 91, 'left': 831.63, 'rotation': 3, 'top': 597.42, 'width': 95}
===========================================================================
第8张人脸信息:
年龄:44,颜值:44.19
位置:
{'height': 87, 'left': 482.05, 'rotation': -1, 'top': 433.92, 'width': 98}
===========================================================================
第9张人脸信息:
年龄:37,颜值:30.48
位置:
{'height': 89, 'left': 703.91, 'rotation': 1, 'top': 390.34, 'width': 93}
===========================================================================
第10张人脸信息:
年龄:28,颜值:62.31
位置:
{'height': 89, 'left': 1848.9, 'rotation': -8, 'top': 383.45, 'width': 89}
===========================================================================
第11张人脸信息:
年龄:23,颜值:53
位置:
{'height': 86, 'left': 1571.27, 'rotation': -4, 'top': 360.19, 'width': 89}
===========================================================================

3.3.1 SDK方式

3.3.1.1 建立连接与对象

# https://ai.baidu.com/ai-doc/FACE/ek37c1qizfrom aip import AipImageClassify""" 你的 APPID AK SK """
APP_ID = '你的 App ID'  #用自己注册的APP替换
API_KEY = '你的 Api Key'
SECRET_KEY = '你的 Secret Key'client2 = AipFace(APP_ID, API_KEY, SECRET_KEY)

3.3.1.2 读取图像

# -*- coding: utf-8 -*-
import base64#image = str(base64.b64encode(open("shengzhou.jpeg", 'rb').read()), 'utf-8')
#image = str(base64.b64encode(open("bisai.jpg", 'rb').read()), 'utf-8')
image = str(base64.b64encode(open("jys.jpg", 'rb').read()), 'utf-8')
import base64image=str(base64.b64encode(get_file_content("jys.jpg")),'utf-8')

3.3.1.3 SDK方式人脸检测

# https://ai.baidu.com/ai-doc/FACE/ek37c1qizimageType = "BASE64"# """ 无参数调用人脸检测 """
# result1 = client2.detect(image, imageType);
# pprint(result1)""" 如果有可选参数 """
options = {}
options["face_field"] = "age,beauty"
options["max_face_num"] = 11
options["face_type"] = "LIVE"
options["liveness_control"] = "LOW"""" 带参数调用人脸检测 """
result2 = client2.detect(image, imageType, options)
pprint(result2)
{'cached': 0,'error_code': 0,'error_msg': 'SUCCESS','log_id': 369368289,'result': {'face_list': [{'age': 31,'angle': {'pitch': 3.38, 'roll': 1.81, 'yaw': -11.1},'beauty': 38.16,'face_probability': 1,'face_token': '9aca8a4f5c92b0c508d9bb9be3c5f3dd','liveness': {'livemapscore': 0.9924196601},'location': {'height': 88,'left': 266.36,'rotation': 5,'top': 460.79,'width': 109}},{'age': 43,'angle': {'pitch': 2.29, 'roll': -1.95, 'yaw': 0.89},'beauty': 49.97,'face_probability': 1,'face_token': 'ed5061925266fca0d8ed60c6d41fcbf6','liveness': {'livemapscore': 0.3547513187},'location': {'height': 96,'left': 1146.55,'rotation': 0,'top': 598.84,'width': 99}},{'age': 26,'angle': {'pitch': 1.5, 'roll': -3.03, 'yaw': -2.52},'beauty': 33.53,'face_probability': 1,'face_token': '87cbe88e63aec3bcbc054759750b9f90','liveness': {'livemapscore': 0.6561560631},'location': {'height': 94,'left': 1001.44,'rotation': 0,'top': 386.45,'width': 96}},{'age': 27,'angle': {'pitch': -3.43,'roll': -3.27,'yaw': 2.11},'beauty': 47.41,'face_probability': 1,'face_token': '68745f9db2a97960062c2eaf52442821','liveness': {'livemapscore': 0.3778412342},'location': {'height': 93,'left': 1260.74,'rotation': 0,'top': 323.98,'width': 97}},{'age': 24,'angle': {'pitch': -1.75,'roll': -5.74,'yaw': -6.5},'beauty': 51.59,'face_probability': 1,'face_token': '900f20c8a44214ec79a959b90c12b85c','liveness': {'livemapscore': 0.481325388},'location': {'height': 92,'left': 1515.71,'rotation': -3,'top': 622.62,'width': 97}},{'age': 32,'angle': {'pitch': -1.12,'roll': -7.19,'yaw': 19.11},'beauty': 42.22,'face_probability': 1,'face_token': '197a5dea47764947d62298dd7c3064f5','liveness': {'livemapscore': 0.9915152788},'location': {'height': 89,'left': 2042.32,'rotation': -7,'top': 432.1,'width': 100}},{'age': 29,'angle': {'pitch': 5.98, 'roll': 2.6, 'yaw': -0.31},'beauty': 48.47,'face_probability': 1,'face_token': 'ee76b675ae9b527ed272bc0871a1475b','liveness': {'livemapscore': 0.875774622},'location': {'height': 91,'left': 831.63,'rotation': 3,'top': 597.42,'width': 95}},{'age': 44,'angle': {'pitch': 0.35,'roll': -4.29,'yaw': -7.73},'beauty': 44.22,'face_probability': 1,'face_token': '8df0dc7a5e44beddf15e5ad0a3eb5f53','liveness': {'livemapscore': 0.8748047948},'location': {'height': 87,'left': 482.05,'rotation': -1,'top': 433.92,'width': 98}},{'age': 37,'angle': {'pitch': -2.25, 'roll': -0.8, 'yaw': -1.4},'beauty': 30.52,'face_probability': 1,'face_token': '77fd8183f918fde5f37b762558a27728','liveness': {'livemapscore': 0.4344541728},'location': {'height': 89,'left': 703.91,'rotation': 1,'top': 390.34,'width': 93}},{'age': 28,'angle': {'pitch': 2.3, 'roll': -11.58, 'yaw': 9.55},'beauty': 62.34,'face_probability': 1,'face_token': 'a0a417e4fadaf95aa8170c77ffc6cd3f','liveness': {'livemapscore': 0.05372356251},'location': {'height': 89,'left': 1848.9,'rotation': -8,'top': 383.45,'width': 89}},{'age': 23,'angle': {'pitch': -4.61,'roll': -6.72,'yaw': 0.66},'beauty': 53.09,'face_probability': 1,'face_token': 'e56d7bb1e5ccaea17fb77ba834ebe0c2','liveness': {'livemapscore': 0.05662947521},'location': {'height': 86,'left': 1571.27,'rotation': -4,'top': 360.19,'width': 89}}],'face_num': 11},'timestamp': 1681952769}
import cv2 as cv
result2['result']['face_list']
[{'face_token': '9aca8a4f5c92b0c508d9bb9be3c5f3dd','location': {'left': 266.36,'top': 460.79,'width': 109,'height': 88,'rotation': 5},'face_probability': 1,'angle': {'yaw': -11.1, 'pitch': 3.38, 'roll': 1.81},'liveness': {'livemapscore': 0.9923582673},'age': 31},{'face_token': 'ed5061925266fca0d8ed60c6d41fcbf6','location': {'left': 1146.54,'top': 598.84,'width': 99,'height': 96,'rotation': 0},'face_probability': 1,'angle': {'yaw': 0.9, 'pitch': 2.29, 'roll': -1.95},'liveness': {'livemapscore': 0.3534035981},'age': 43},{'face_token': '87cbe88e63aec3bcbc054759750b9f90','location': {'left': 1001.44,'top': 386.45,'width': 96,'height': 94,'rotation': 0},'face_probability': 1,'angle': {'yaw': -2.52, 'pitch': 1.51, 'roll': -3.03},'liveness': {'livemapscore': 0.6603813767},'age': 26},{'face_token': '68745f9db2a97960062c2eaf52442821','location': {'left': 1260.74,'top': 323.98,'width': 97,'height': 93,'rotation': 0},'face_probability': 1,'angle': {'yaw': 2.11, 'pitch': -3.43, 'roll': -3.27},'liveness': {'livemapscore': 0.3773717582},'age': 27},{'face_token': '900f20c8a44214ec79a959b90c12b85c','location': {'left': 1515.71,'top': 622.62,'width': 97,'height': 92,'rotation': -3},'face_probability': 1,'angle': {'yaw': -6.5, 'pitch': -1.75, 'roll': -5.74},'liveness': {'livemapscore': 0.4817254543},'age': 24},{'face_token': '197a5dea47764947d62298dd7c3064f5','location': {'left': 2042.32,'top': 432.1,'width': 100,'height': 89,'rotation': -7},'face_probability': 1,'angle': {'yaw': 19.12, 'pitch': -1.12, 'roll': -7.19},'liveness': {'livemapscore': 0.9916789532},'age': 32},{'face_token': 'ee76b675ae9b527ed272bc0871a1475b','location': {'left': 831.63,'top': 597.42,'width': 95,'height': 91,'rotation': 3},'face_probability': 1,'angle': {'yaw': -0.31, 'pitch': 5.98, 'roll': 2.6},'liveness': {'livemapscore': 0.8773424029},'age': 29},{'face_token': '8df0dc7a5e44beddf15e5ad0a3eb5f53','location': {'left': 482.05,'top': 433.93,'width': 98,'height': 87,'rotation': -1},'face_probability': 1,'angle': {'yaw': -7.72, 'pitch': 0.35, 'roll': -4.28},'liveness': {'livemapscore': 0.8753650784},'age': 44},{'face_token': '77fd8183f918fde5f37b762558a27728','location': {'left': 703.91,'top': 390.34,'width': 93,'height': 89,'rotation': 1},'face_probability': 1,'angle': {'yaw': -1.4, 'pitch': -2.25, 'roll': -0.8},'liveness': {'livemapscore': 0.4357280731},'age': 37},{'face_token': 'a0a417e4fadaf95aa8170c77ffc6cd3f','location': {'left': 1848.9,'top': 383.45,'width': 89,'height': 89,'rotation': -8},'face_probability': 1,'angle': {'yaw': 9.55, 'pitch': 2.29, 'roll': -11.59},'liveness': {'livemapscore': 0.05388861522},'age': 28},{'face_token': 'e56d7bb1e5ccaea17fb77ba834ebe0c2','location': {'left': 1571.27,'top': 360.19,'width': 89,'height': 86,'rotation': -4},'face_probability': 1,'angle': {'yaw': 0.66, 'pitch': -4.61, 'roll': -6.72},'liveness': {'livemapscore': 0.05674218014},'age': 23}]

3.3.1.4 在图像上将识别出的人脸画上框 并贴上颜值与年龄

要在图像上画框及写字,可以使用opencv库,需要先安装opencv包,建议从国内源安装(譬如选用清华的源),指令如下:

pip install opencv-python  -i https://pypi.tuna.tsinghua.edu.cn/simple
faceItem = result2['result']['face_list'][0]
faceItem['location']
{'left': 266.36, 'top': 460.79, 'width': 109, 'height': 88, 'rotation': 5}
# cv2的imshow()不显示的解决办法
import matplotlib.pyplot as plt
import cv2 as cv
import numpy as np
import time
%matplotlib inline
def aidemy_imshow(name,img):b,g,r=cv.split(img)img=cv.merge([r,g,b])plt.imshow(img)plt.show
cv.imshow=aidemy_imshow
img = cv.imread("jys.jpg")
face_num = result2['result']['face_num']
for i in range(face_num):faceItem = result2['result']['face_list'][i]x = int(faceItem['location']['left'])y = int(faceItem['location']['top'])w = int(faceItem['location']['width'])h = int(faceItem['location']['height'])cv.rectangle(img,(x,y+3),(x+w,y+h),(0,255,0),2,4,0)  # 加人脸框age = faceItem['age']beauty = faceItem['beauty']cv.putText(img, str(age), (x,y),cv.FONT_HERSHEY_SIMPLEX,1,(0,255,0)) #加年龄文本cv.putText(img, str(beauty), (x,y-28),cv.FONT_HERSHEY_SIMPLEX,1,(0,255,0)) #加颜值文本cv.imwrite("jys2.jpeg",img)
cv.imshow("image", img)

3.3.2 API方式

3.3.2.1 设置ID与KEY等

""" 你的 APPID AK SK """
APP_ID = '你的 App ID'  #用自己注册的APP替换
API_KEY = '你的 Api Key'
SECRET_KEY = '你的 Secret Key'

3.3.2.2 API方式获取人脸检测结果

# -*- coding: utf-8 -*-import base64
import requests
from pprint import pprint'''
人脸检测与属性分析
'''image = str(base64.b64encode(open("shengzhou.jpeg", 'rb').read()), 'utf-8')url = 'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=%s&client_secret=%s' % (API_KEY, SECRET_KEY)
response = requests.post(url)access_token = response.content.decode('utf-8')
access_token = json.loads(access_token)
access_token = str(access_token['access_token'])params = {'image': image,'image_type':"BASE64",'max_face_num':5,'face_field': 'faceshape,facetype'}request_url = "https://aip.baidubce.com/rest/2.0/face/v3/detect"request_url = request_url + "?access_token=" + access_token
headers = {'content-type': 'application/json'}
response = requests.post(request_url, data=params, headers=headers)
if response:resJson = response.json()  # response对象的json方法,将结果反序列化,得到的也是字典print(f"resJson的类型是:{type(resJson)}\n")pprint (resJson)
resJson的类型是:<class 'dict'>{'cached': 0,'error_code': 0,'error_msg': 'SUCCESS','log_id': 2237172790,'result': {'face_list': [{'angle': {'pitch': -0.89,'roll': -2.86,'yaw': -1.44},'face_probability': 1,'face_shape': {'probability': 0.48,'type': 'square'},'face_token': '69f7f897ea6e0b7aae8b9e58b43bb084','face_type': {'probability': 1, 'type': 'human'},'location': {'height': 44,'left': 134.71,'rotation': -1,'top': 129.88,'width': 44}},{'angle': {'pitch': 1.4, 'roll': -7.39, 'yaw': 4.74},'face_probability': 1,'face_shape': {'probability': 0.54,'type': 'square'},'face_token': '6314669fe6e133c562402c119985d21a','face_type': {'probability': 0.99, 'type': 'human'},'location': {'height': 44,'left': 455.58,'rotation': -4,'top': 129.59,'width': 43}},{'angle': {'pitch': 3.92, 'roll': -1.34, 'yaw': 2.11},'face_probability': 1,'face_shape': {'probability': 0.34, 'type': 'round'},'face_token': '4fd11ea03d13b88f2bcf80fa78043a4c','face_type': {'probability': 1, 'type': 'human'},'location': {'height': 41,'left': 298.23,'rotation': 0,'top': 135.2,'width': 41}}],'face_num': 3},'timestamp': 1681868237}
resText = response.text  # response的文本
pprint(resText)
'{"error_code":0,"error_msg":"SUCCESS","log_id":2237172790,"timestamp":1681868237,"cached":0,"result":{"face_num":3,"face_list":[{"face_token":"69f7f897ea6e0b7aae8b9e58b43bb084","location":{"left":134.71,"top":129.88,"width":44,"height":44,"rotation":-1},"face_probability":1,"angle":{"yaw":-1.44,"pitch":-0.89,"roll":-2.86},"face_shape":{"type":"square","probability":0.48},"face_type":{"type":"human","probability":1}},{"face_token":"6314669fe6e133c562402c119985d21a","location":{"left":455.58,"top":129.59,"width":43,"height":44,"rotation":-4},"face_probability":1,"angle":{"yaw":4.74,"pitch":1.4,"roll":-7.39},"face_shape":{"type":"square","probability":0.54},"face_type":{"type":"human","probability":0.99}},{"face_token":"4fd11ea03d13b88f2bcf80fa78043a4c","location":{"left":298.23,"top":135.2,"width":41,"height":41,"rotation":0},"face_probability":1,"angle":{"yaw":2.11,"pitch":3.92,"roll":-1.34},"face_shape":{"type":"round","probability":0.34},"face_type":{"type":"human","probability":1}}]}}'

3.3.2.3 JSON转换成字典

https://www.runoob.com/python/python-json.html

函数 描述
json.dumps 将 Python 对象编码成 JSON 字符串
json.loads 将已编码的 JSON 字符串解码为 Python 对象
import json
resDict = json.loads(resText)
print(f"resText类型:{type(resText)}, resDict类型:{type(resDict)}\n")
print("resDict:")
pprint(resDict)
resText类型:<class 'str'>, resDict类型:<class 'dict'>resDict:
{'cached': 0,'error_code': 0,'error_msg': 'SUCCESS','log_id': 2237172790,'result': {'face_list': [{'angle': {'pitch': -0.89,'roll': -2.86,'yaw': -1.44},'face_probability': 1,'face_shape': {'probability': 0.48,'type': 'square'},'face_token': '69f7f897ea6e0b7aae8b9e58b43bb084','face_type': {'probability': 1, 'type': 'human'},'location': {'height': 44,'left': 134.71,'rotation': -1,'top': 129.88,'width': 44}},{'angle': {'pitch': 1.4, 'roll': -7.39, 'yaw': 4.74},'face_probability': 1,'face_shape': {'probability': 0.54,'type': 'square'},'face_token': '6314669fe6e133c562402c119985d21a','face_type': {'probability': 0.99, 'type': 'human'},'location': {'height': 44,'left': 455.58,'rotation': -4,'top': 129.59,'width': 43}},{'angle': {'pitch': 3.92, 'roll': -1.34, 'yaw': 2.11},'face_probability': 1,'face_shape': {'probability': 0.34, 'type': 'round'},'face_token': '4fd11ea03d13b88f2bcf80fa78043a4c','face_type': {'probability': 1, 'type': 'human'},'location': {'height': 41,'left': 298.23,'rotation': 0,'top': 135.2,'width': 41}}],'face_num': 3},'timestamp': 1681868237}

3.4 人脸比对-API方式


""" 你的 APPID AK SK """
APP_ID = '你的 App ID'  #用自己注册的APP替换
API_KEY = '你的 Api Key'
SECRET_KEY = '你的 Secret Key'
import requests
import base64
import json
# 1,准备好申请的人脸识别api,API Key, Secret Key
# · grant_type: 必须参数,固定为client_credentials;
# · client_id: 必须参数,应用的API Key;
# · client_secret: 必须参数,应用的Secret Key;
api1="https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id="+API_KEY+"&client_secret="+SECRET_KEY# 2,获取token值,拼接API
def get_token():response=requests.get(api1)access_token=eval(response.text)['access_token']api2="https://aip.baidubce.com/rest/2.0/face/v3/match"+"?access_token="+access_tokenreturn api2# 3,读取图片数据
def read_img(img1,img2):    #  两个图片参数with open(img1,'rb') as f:  # 读取图片数据pic1=base64.b64encode(f.read())  # 图片数据编码为base64格式数据with open(img2,'rb') as f:pic2=base64.b64encode(f.read())params=json.dumps([              # 将字典数据转化为字符串 {"image":str(pic1,"utf-8"),"image_type":'BASE64',"face_type":"LIVE"},{"image":str(pic2,"utf-8"),"image_type":'BASE64',"face_type":"IDCARD"}])return params# 4,发起请求拿到对比结果
def analyse_img(file1,file2):params=read_img(file1,file2)    # 调用第一个函数的结果apiapi=get_token()                  # 调用第二个函数的图片数据content=requests.post(api,params).text     # 获取对比详细结果# print(content)score=eval(content)['result']['score']if score>80:print('图片识别相似度度为'+str(score)+',比对结果是同一人')else:print('图片识别相似度度为'+str(score)+',比对结果不是同一人')#analyse_img("liehaisheng1.jpg","liehaisheng2.jpg")
analyse_img("RJG1.jpg","RJG2.jpg")
图片识别相似度度为80.58705902,比对结果是同一人

比对的两张图片

4. 图象增强–采用的API方式

油画与动漫化

python-使用百度AI开放平台实现人像动漫化、黑白图片上色、图像风格转化


""" 你的 APPID AK SK """
APP_ID = '你的 App ID'  #用自己注册的APP替换
API_KEY = '你的 Api Key'
SECRET_KEY = '你的 Secret Key'
import requests,base64# 百度AI开放平台鉴权函数
def get_access_token():url='https://aip.baidubce.com/oauth/2.0/token'data={'grant_type':'client_credentials',  # 固定值'client_id':"cRyx2WrmbSwgLPw2QmGGPcOq", # 在开放平台注册后所建应用的API Key'client_secret':"skX9N8OcoSfSb8eEAlFILKitQTtfDtYO"  # 所建应用的Secret Key}res=requests.post(url,data=data)res=res.json()access_token=res['access_token']return access_tokendef image_process(img_before,img_after,how_to_deal):
# 函数的三个参数,一个是转化前的文件名,一个是转化后的文件名,均在同一目录下,第三个是图像处理能力选择request_url='https://aip.baidubce.com/rest/2.0/image-process/v1/'+how_to_dealif how_to_deal=='style_trans': # 判断如果是 图像风格化,需要额外添加一个风格配置others='pencil'     # 风格化参数,具体可设置范围参见下面注释'''cartoon:卡通画风格pencil:铅笔风格color_pencil:彩色铅笔画风格warm:彩色糖块油画风格wave:神奈川冲浪里油画风格lavender:薰衣草油画风格mononoke:奇异油画风格scream:呐喊油画风格gothic:哥特油画风格'''else:others=''file=open(img_before,'rb') # 二进制读取图片origin_img=base64.b64encode(file.read())    # 将图片进行base64编码headers={'Content-Type':'application/x-www-form-urlencoded'}data={'access_token':get_access_token(),'image':origin_img,'option':others}res=requests.post(request_url,data=data,headers=headers)res=res.json()if res:f = open(img_after,'wb')after_img=res['image']after_img=base64.b64decode(after_img)f.write(after_img)f.close()
  • 图象上色
if __name__=='__main__':img_before='cqblack2.jpg'  # 当前目录下的图片img_after=img_before.split('.')     # 将原文件名分成列表img_after=img_after[0]+'_1.'+img_after[1]   #新生成的文件名为原文件名上加 _1image_process(img_before,img_after,'colourize')  # 第三个参数: selfie_anime 为人像动漫化,colourize 图像上色,style_trans 为图像风格化print('done!')
done!

图象上色前

图象上色后

  • 风格转换,转换为铅笔画
if __name__=='__main__':img_before='cqblack2.jpg'  # 当前目录下的图片img_after=img_before.split('.')     # 将原文件名分成列表img_after=img_after[0]+'_2.'+img_after[1]   #新生成的文件名为原文件名上加 _1image_process(img_before,img_after,'style_trans')  # 第三个参数: selfie_anime 为人像动漫化,colourize 图像上色,style_trans 为图像风格化print('done!')
done!

转换为铅笔画风格


AI导论-调用百度AI开放平台进行图象识别相关推荐

  1. Java调用百度AI开放平台API

    百度AI开放平台 百度AI开放平台是全球领先的人工智能服务平台,面向开发者及企业开放120多项全球领先的AI能力和软硬一体组件,并提供 EasyDL定制化训练平台.对话系统开发平台UNIT.自定义模板 ...

  2. python调用百度AI接口识别营业执照

    上一篇文章介绍了应用python中的pytesseract库和OCR识别软件进行文字识别.本文介绍应用百度AI的文字识别功能对营业执照进行识别,感兴趣的朋友一起来看看效果吧.    一.安装baidu ...

  3. C++ POST请求调用百度AI OCR

    阅读本文前先看这篇文章,有curl,openssl,jsoncpp的编译:c++调用百度AI OCR SDK ,本来百度是封装好了c++ SDK调用方法的,所以本文主要研究本质POST的用法. 一.鉴 ...

  4. Python——调用百度AI实现图片上文字识别

    Python--调用百度AI实现图片上文字识别 简介 步骤 安装百度AI库 注册百度AI开放平台 调用glob库 调用AipOcr库识别文字 可能会遇到的问题 批量操作 简介 Python免费调用百度 ...

  5. Python3 图片文字识别翻译——调用百度AI、百度翻译和有道翻译的API

    文章目录 Python3 图片文字识别翻译--调用百度AI.百度翻译和有道翻译的API 一.演示 二. API准备 三. 图片文字识别--调用百度AI文字识别API 四. 文字翻译 1. 百度翻译 请 ...

  6. 【应用】Python调用百度AI实现图片上表格识别

    [应用]Python调用百度AI实现图片上表格识别 简介 步骤 安装百度AI库 注册百度AI开放平台 调用AipOcr库识别表格文字 可能遇到的问题 批量操作 简介 Python免费调用百度AI实现图 ...

  7. 调用百度AI接口实现图片文字识别

    一.准备阶段 进入百度AI网址点击这里跳转 ,点击导航栏的开放能力 ---- 文字识别 ---- 通用文字识别,进入文字识别OCR界面. 在文字识别ORC界面点击 技术文档 进入帮助文档. 在左侧可以 ...

  8. ai图像识别python的项目_Python3调用百度AI识别图片中的文字功能示例【测试可用】...

    本文实例讲述了Python3调用百度AI识别图片中的文字功能.分享给大家供大家参考,具体如下: 首先pip install命令安装baidu-aip模块,如下图所示(这里使用pip3 install ...

  9. python调用百度AI自动识别并提取图片上指定位置的文字信息

    这是一个三个月前的项目需求,需要识别多张图片上固定位置的信息并提取.说到python 上文字识别,可能有些人想用 pytesseract 来做,怎么说呢,识别精准度相对较低,而且对于数量较大的图片来说 ...

最新文章

  1. cytoscape---插件clueGO的使用
  2. 如何加强网络安全 这7种建议你不可不知!
  3. 【10】青龙面板之JD ck 获取的1种办法
  4. 特征工程的宝典-《Feature Engineering for Machine Learning》翻译及代码实现
  5. 装车机器人_智造春天脚步近 青岛这家机器人公司着手打造模块化、标准化技术平台...
  6. mysql自定义函数应用_mysql functions实例:在自定义函数中应用字符串函数
  7. Meteor创建示例项目 Simple-todos
  8. 小议同步IO :fsync与fdatasync
  9. 关于IIS 7.5 限制连接数与流量限制模块
  10. window10怎么卸载php,window_win10怎么卸载程序?win10卸载程序教程,当win10正式版发布以后,不少 - phpStudy...
  11. php.ini详细介绍与设置,配置
  12. 线程安全的HashMap,TreeMap,ArrayList,TreeSet,Set
  13. [ROS]1 小乌龟
  14. 基于JAVA的私人牙科诊所管理系统
  15. Python实现最小二乘法曲线拟合
  16. 黑马程序员-微信小程序-原生框架——购物平台-首页
  17. Linux下测试SSD硬盘读写速率
  18. 右键文件或文件夹或空白处弹出菜单包含自己软件快捷方式
  19. Mac电脑的自动切换输入法
  20. 《在细雨中呼喊》---余华 (书摘)

热门文章

  1. Tanzu Mission Controle 图文并茂
  2. [iOS微博项目 - 3.2] - 发送微博
  3. 【基】医学CT图像-‘.dcm‘图像读取/处理/窗位窗宽修改/保存
  4. sql server 删除重复数据保留一条!
  5. 【小程序】组件化开发的基本使用(一)
  6. 有趣的css—简单的下雨效果
  7. 深度学习中FLOPS和FLOPs的区别与计算
  8. Docker容器启动时运行 sh 脚本
  9. viewport视口的概念
  10. redis aof重写