温州黄华镇来看看你的颜值多高吧!基于Python开发的公众号
阅读 25080 · 发布日期 2020-08-24 17:26 · 温州优光网络科技有限公司|建站|APP小程序制作|做网站SEO推广优化
【摘要】
这是一个基于Python的微信公众号开发之颜值检测,今天我们把用户的图片通过腾讯的AI平台分析后再返回给用户。来一起体验下公众号的颜值检测吧效果图一. 接入腾讯AI平台我们先看一下官方人脸检测与分析接口的描述:检测给定图片(Image)中的所有人脸(Face)的位置和相应的面部属性。位置包括(x, y, w, h),面... 【温州小程序开发,温州微信公众号,平阳做网站,平阳网站建设公司,平阳小程序商城制作,昆阳万全做网站,鳌江水头小程序,萧江腾蛟微信公众号,山门顺溪南雁海西南麂凤卧麻步怀溪网络网店服务,政采云网店管理服务】...
这是一个基于Python的微信公众号开发之颜值检测,今天我们把用户的图片通过腾讯的AI平台分析后再返回给用户。
来一起体验下公众号的颜值检测吧效果图一. 接入腾讯AI平台我们先看一下官方人脸检测与分析接口的描述:
检测给定图片(Image)中的所有人脸(Face)的位置和相应的面部属性。
位置包括(x, y, w, h),面部属性包括性别(gender), 年龄(age), 表情(expression), 魅力(beauty), 眼镜(glass)和姿态(pitch,roll,yaw)。
请求参数包括下面几个:
app_id 应用标识,我们在AI平台注册后就可以得到app_idtime_stamp 时间戳nonce_str 随机字符串sign 签名信息,需要我们自己去计算image 需要检测的图片(上限1M)mode 检测模式1.接口鉴权,构造请求参数官方给了我们接口鉴权的计算方法。
将
key1=value1&key2=value2),URL键值拼接过程value部分需要URL编码,URL编码算法用大写字母,例如%E8,而不是小写%e8将应用密钥以app_key为键名,组成URL键值拼接到字符串T末尾,得到字符串S(如:
key1=value1&key2=value2&app_key=密钥)对字符串S进行MD5运算,将得到的MD5值所有字符转换成大写,得到接口请求签名2.请求接口地址请求接口信息,我们用 requests 发送请求,会得到返回的 json 格式的图像信息pip install requests安装requests。
3.处理返回的信息处理返回的信息,把信息展示在图片上,再把处理后的图片保存。
这里我们用到 opencv ,和 pillow 两个库pip install pillow和pip install opencv-python来安装。
开始编写代码,我们新建一个face_id.py 文件来对接AI平台,并且返回检测后的图像数据。
import time import random import base64 import hashlib import requests from urllib.parse import urlencode import cv2 import numpy as np from PIL import Image, ImageDraw, ImageFont import os # 一.计算接口鉴权,构造请求参数 def random_str(): '
'
'
得到随机字符串nonce_str'
'
'
str = '
abcdefghijklmnopqrstuvwxyz'
r = '
'
for i in range(15): index = random.randint(0,25) r += str[index] return r def image(name): with open(name, '
rb'
) as f: content = f.read() return base64.b64encode(content) def get_params(img): '
'
'
组织接口请求的参数形式,并且计算sign接口鉴权信息, 最终返回接口请求所需要的参数字典'
'
'
params = {
'
app_id'
: '
1106860829'
, '
time_stamp'
: str(int(time.time())), '
nonce_str'
: random_str(), '
image'
: img, '
mode'
: '
0'
}
sort_dict = sorted(params.items(), key=lambda item: item[0], reverse=False) # 排序 sort_dict.append(('
app_key'
, '
P8Gt8nxi6k8vLKbS'
)) # 添加app_key rawtext = urlencode(sort_dict).encode() # URL编码 sha = hashlib.md5() sha.update(rawtext) md5text = sha.hexdigest().upper() # 计算出sign,接口鉴权 params['
sign'
] = md5text # 添加到请求参数列表中 return params # 二.请求接口URL def access_api(img): frame = cv2.imread(img) nparry_encode = cv2.imencode('
.jpg'
, frame)[1] data_encode = np.array(nparry_encode) img_encode = base64.b64encode(data_encode) # 图片转为base64编码格式 url = '
https://api.ai.qq.com/fcgi-bin/face/face_detectface'
res = requests.post(url, get_params(img_encode)).json() # 请求URL,得到json信息 # 把信息显示到图片上 if res['
ret'
] == 0: # 0代表请求成功 pil_img = Image.fromarray(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)) # 把opencv格式转换为PIL格式,方便写汉字 draw = ImageDraw.Draw(pil_img) for obj in res['
data'
]['
face_list'
]: img_width = res['
data'
]['
image_width'
] # 图像宽度 img_height = res['
data'
]['
image_height'
] # 图像高度 # print(obj) x = obj['
x'
] # 人脸框左上角x坐标 y = obj['
y'
] # 人脸框左上角y坐标 w = obj['
width'
] # 人脸框宽度 h = obj['
height'
] # 人脸框高度 # 根据返回的值,自定义一下显示的文字内容 if obj['
glass'
] == 1: # 眼镜 glass = '
有'
else: glass = '
无'
if obj['
gender'
] >= 70: # 性别值从0-100表示从女性到男性 gender = '
男'
elif 50 gender'
] gender'
] 女'
else: gender = '
女汉子'
if 90 expression'
] 一笑倾城'
elif 80 expression'
] 心花怒放'
elif 70 expression'
] 兴高采烈'
elif 60 expression'
] 眉开眼笑'
elif 50 expression'
] 喜上眉梢'
elif 40 expression'
] 喜气洋洋'
elif 30 expression'
] 笑逐颜开'
elif 20 expression'
] 似笑非笑'
elif 10 expression'
] 半嗔半喜'
elif 0 expression'
] 黯然伤神'
delt = h // 5 # 确定文字垂直距离 # 写入图片 if len(res['
data'
]['
face_list'
]) > 1: # 检测到多个人脸,就把信息写入人脸框内 font = ImageFont.truetype('
yahei.ttf'
, w // 8, encoding='
utf-8'
) # 提前把字体文件下载好 draw.text((x + 10, y + 10), '
性别 :'
+ gender, (76, 176, 80), font=font) draw.text((x + 10, y + 10 + delt * 1), '
年龄 :'
+ str(obj['
age'
]), (76, 176, 80), font=font) draw.text((x + 10, y + 10 + delt * 2), '
表情 :'
+ expression, (76, 176, 80), font=font) draw.text((x + 10, y + 10 + delt * 3), '
魅力 :'
+ str(obj['
beauty'
]), (76, 176, 80), font=font) draw.text((x + 10, y + 10 + delt * 4), '
眼镜 :'
+ glass, (76, 176, 80), font=font) elif img_width - x - w yahei.ttf'
, w // 8, encoding='
utf-8'
) draw.text((x + 10, y + 10), '
性别 :'
+ gender, (76, 176, 80), font=font) draw.text((x + 10, y + 10 + delt * 1), '
年龄 :'
+ str(obj['
age'
]), (76, 176, 80), font=font) draw.text((x + 10, y + 10 + delt * 2), '
表情 :'
+ expression, (76, 176, 80), font=font) draw.text((x + 10, y + 10 + delt * 3), '
魅力 :'
+ str(obj['
beauty'
]), (76, 176, 80), font=font) draw.text((x + 10, y + 10 + delt * 4), '
眼镜 :'
+ glass, (76, 176, 80), font=font) else: font = ImageFont.truetype('
yahei.ttf'
, 20, encoding='
utf-8'
) draw.text((x + w + 10, y + 10), '
性别 :'
+ gender, (76, 176, 80), font=font) draw.text((x + w + 10, y + 10 + delt * 1), '
年龄 :'
+ str(obj['
age'
]), (76, 176, 80), font=font) draw.text((x + w + 10, y + 10 + delt * 2), '
表情 :'
+ expression, (76, 176, 80), font=font) draw.text((x + w + 10, y + 10 + delt * 3), '
魅力 :'
+ str(obj['
beauty'
]), (76, 176, 80), font=font) draw.text((x + w + 10, y + 10 + delt * 4), '
眼镜 :'
+ glass, (76, 176, 80), font=font) draw.rectangle((x, y, x + w, y + h), outline="#4CB050") # 画出人脸方框 cv2img = cv2.cvtColor(np.array(pil_img), cv2.COLOR_RGB2BGR) # 把 pil 格式转换为 cv cv2.imwrite('
faces/{
}
'
.format(os.path.basename(img)), cv2img) # 保存图片到 face 文件夹下 return '
检测成功'
else: return '
检测失败'
到这里我们的人脸检测接口接入及图片处理就完成了。
之后在收到用户发送的图片信息后,调用这个函数,把处理后的图片返回给用户就可以。
返回图片给用户当收到用户图片时,需要以下几个步骤:
保存图片当接收到用户图片后,我们要先把图片保存起来,之后才能去调用人脸分析接口,把图片信息传递过去,我们需要编写一个 img_download 函数来下载图片。
详见下方代码调用人脸分析接口图片下载后,调用 face_id.py 文件里的接口函数,得到处理后的图片。
上传图片检测结果是一张新的图片,要把图片发送给用户我们需要一个 Media_ID,要获取Media_ID必须先把图片上传为临时素材,所以这里我们需要一个img_upload函数来上传图片,并且在上传时需要用到一个access_token,我们通过一个函数来获取. 获取access_token必须要把我们自己的IP地址加入白名单,否则是获取不到的。
请登录“微信公众平台-开发-基本配置”提前将服务器IP地址添加到IP白名单中,可以在http://ip.qq.com/查看本机的IP...开始编写代码,我们新建一个 utils.py 来下载、上传图片import requests import json import threading import time import os token = '
'
app_id = '
wxfc6adcdd7593a712'
secret = '
429d85da0244792be19e0deb29615128'
def img_download(url, name): r = requests.get(url) with open('
images/{
}
-{
}
.jpg'
.format(name, time.strftime("%Y_%m_%d%H_%M_%S", time.localtime())), '
wb'
) as fd: fd.write(r.content) if os.path.getsize(fd.name) >= 1048576: return '
large'
# print('
namename'
, os.path.basename(fd.name)) return os.path.basename(fd.name) def get_access_token(appid, secret): '
'
'
获取access_token,100分钟刷新一次'
'
'
url = '
https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={
}
&secret={
}
'
.format(appid, secret) r = requests.get(url) parse_json = json.loads(r.text) global token token = parse_json['
access_token'
] global timer timer = threading.Timer(6000, get_access_token) timer.start() def img_upload(mediaType, name): global token url = "https://api.weixin.qq.com/cgi-bin/media/upload?access_token=%s&type=%s" % (token, mediaType) files = {
'
media'
: open('
{
}
'
.format(name), '
rb'
)}
r = requests.post(url, files=files) parse_json = json.loads(r.text) return parse_json['
media_id'
] get_access_token(app_id, secret)返回给用户我们简单修改下收到图片后的逻辑,收到图片后经过人脸检测,上传获得Media_ID,我们要做的就是把图片返回给用户即可。
直接看connect.py的代码import falcon from falcon import uri from wechatpy.utils import check_signature from wechatpy.exceptions import InvalidSignatureException from wechatpy import parse_message from wechatpy.replies import TextReply, ImageReply from utils import img_download, img_upload from face_id import access_api class Connect(object): def on_get(self, req, resp): query_string = req.query_string query_list = query_string.split('
&'
) b = {
}
for i in query_list: b[i.split('
='
)[0]] = i.split('
='
)[1] try: check_signature(token='
lengxiao'
, signature=b['
signature'
], timestamp=b['
timestamp'
], nonce=b['
nonce'
]) resp.body = (b['
echostr'
]) except InvalidSignatureException: pass resp.status = falcon.HTTP_200 def on_post(self, req, resp): xml = req.stream.read() msg = parse_message(xml) if msg.type == '
text'
: reply = TextReply(content=msg.content, message=msg) xml = reply.render() resp.body = (xml) resp.status = falcon.HTTP_200 elif msg.type == '
image'
: name = img_download(msg.image, msg.source) # 下载图片 r = access_api('
images/'
+ name) if r == '
检测成功'
: media_id = img_upload('
image'
, '
faces/'
+ name) # 上传图片,得到 media_id reply = ImageReply(media_id=media_id, message=msg) else: reply = TextReply(content='
人脸检测失败,请上传1M以下人脸清晰的照片'
, message=msg) xml = reply.render() resp.body = (xml) resp.status = falcon.HTTP_200 app = falcon.API() connect = Connect() app.add_route('
/connect'
, connect)至此我们的工作就做完了,我们的公众号可以进行颜值检测了。
本来我打算用在自己公众号上的,但是还存在下面几个问题,所以没有使用。
微信的机制,我们的程序必须在5s内给出响应。
不然就会报'
公众号提供的服务出现故障'
。
然而处理图片有时会比较慢,经常会超过5s。
所以正确的处理方式应该是拿到用户的请求后立即返回一个空字符串表示我们收到了,之后单独创建一个线程去处理图片,当图片处理完后通过客服接口发送给用户。
可惜的是未认证的公众号没有客服接口,所以没办法,超过5s就会报错。
无法自定义菜单,一旦启用了自定义开发,菜单也需要自定义配置,但是未认证的公众号没有权限通过程序来配置菜单,只能在微信后台配置。
所以,我并没有在我的公众号上启用这个程序,但是如果有认证的公众号,可以尝试开发各种好玩的功能。
相关推荐:
微信公众平台开发一键关注微信公众平台账号微信公众平台开发尝试,微信公众平台视频:
传智、黑马微信公众平台开发视频教程以上就是来看看你的颜值多高吧!基于Python开发的公众号的详细内容,更多请关注php中文网其它相关文章!
微信
分享相关标签:
人工智能 微信公众平台 微信 公众号 python本文原创发布php中文网,转载请注明出处,感谢您的尊重!
上一篇:
关于微信小程序上传word、txt、Excel、PPT等文件的详解
下一篇:
终于整理出来了,用微信第三方平台授权小程序业务相关文章相关视频修改微信号有什么影响吗?微信中共享实时位置什么意思数据库设计的基本原则是什么?微信小程序调用图片安全API来看看你的颜值多高吧!基于Python开发的公众号微信公众平台概述微信公众平台开发概述微信公众平台 接口域名说明微信公众平台 获取access_token注册属于自己的微信公众平台