目录
效果图
一. 接入腾讯AI平台
1.接口鉴权,构造请求参数
2.请求接口地址
3.处理返回的信息
返回图片给用户
保存图片
调用人脸分析接口
上传图片
返回给用户
首页 微信小程序 微信开发 来看看你的颜值多高吧!基于Python开发的公众号

来看看你的颜值多高吧!基于Python开发的公众号

Jul 25, 2018 pm 01:56 PM
python 人工智能 公众号 微信 微信公众平台

这是一个基于Python的微信公众号开发之颜值检测,今天我们把用户的图片通过腾讯的AI平台分析后再返回给用户。来一起体验下公众号的颜值检测吧

效果图

1691280-3107ca5c3aec2f5b.png

1691280-201fade473e79cc3.jpg

1691280-cc338ba77cc79eaf.jpg

一. 接入腾讯AI平台

我们先看一下官方人脸检测与分析接口的描述:

检测给定图片(Image)中的所有人脸(Face)的位置和相应的面部属性。位置包括(x, y, w, h),面部属性包括性别(gender), 年龄(age), 表情(expression), 魅力(beauty), 眼镜(glass)和姿态(pitch,roll,yaw)。

请求参数包括下面几个:

  • app_id 应用标识,我们在AI平台注册后就可以得到app_id

  • time_stamp 时间戳

  • nonce_str 随机字符串

  • sign 签名信息,需要我们自己去计算

  • image 需要检测的图片(上限1M)

  • mode 检测模式

1.接口鉴权,构造请求参数

官方给了我们接口鉴权的计算方法。

  1. 请求参数对按key进行字典升序排序,得到有序的参数对列表N

  2. 将列表N中的参数对按URL键值对的格式拼接成字符串,得到字符串T(如:key1=value1&key2=value2),URL键值拼接过程value部分需要URL编码,URL编码算法用大写字母,例如%E8,而不是小写%e8

  3. 将应用密钥以app_key为键名,组成URL键值拼接到字符串T末尾,得到字符串S(如:key1=value1&key2=value2&app_key=密钥)

  4. 对字符串S进行MD5运算,将得到的MD5值所有字符转换成大写,得到接口请求签名

2.请求接口地址

请求接口信息,我们用 requests 发送请求,会得到返回的 json 格式的图像信息pip install requests安装requests。

3.处理返回的信息

处理返回的信息,把信息展示在图片上,再把处理后的图片保存。这里我们用到 opencv ,和 pillow 两个库pip install pillowpip 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 <= obj[&#39;gender&#39;] < 70:
                gender = "娘"
            elif obj[&#39;gender&#39;] < 30:
                gender = &#39;女&#39;
            else:
                gender = &#39;女汉子&#39;
            if 90 < obj[&#39;expression&#39;] <= 100:  # 表情从0-100,表示笑的程度
                expression = &#39;一笑倾城&#39;
            elif 80 < obj[&#39;expression&#39;] <= 90:
                expression = &#39;心花怒放&#39;
            elif 70 < obj[&#39;expression&#39;] <= 80:
                expression = &#39;兴高采烈&#39;
            elif 60 < obj[&#39;expression&#39;] <= 70:
                expression = &#39;眉开眼笑&#39;
            elif 50 < obj[&#39;expression&#39;] <= 60:
                expression = &#39;喜上眉梢&#39;
            elif 40 < obj[&#39;expression&#39;] <= 50:
                expression = &#39;喜气洋洋&#39;
            elif 30 < obj[&#39;expression&#39;] <= 40:
                expression = &#39;笑逐颜开&#39;
            elif 20 < obj[&#39;expression&#39;] <= 30:
                expression = &#39;似笑非笑&#39;
            elif 10 < obj[&#39;expression&#39;] <= 20:
                expression = &#39;半嗔半喜&#39;
            elif 0 <= obj[&#39;expression&#39;] <= 10:
                expression = &#39;黯然伤神&#39;
            delt = h // 5  # 确定文字垂直距离
            # 写入图片
            if len(res[&#39;data&#39;][&#39;face_list&#39;]) > 1:  # 检测到多个人脸,就把信息写入人脸框内
                font = ImageFont.truetype(&#39;yahei.ttf&#39;, w // 8, encoding=&#39;utf-8&#39;)  # 提前把字体文件下载好
                draw.text((x + 10, y + 10), &#39;性别 :&#39; + gender, (76, 176, 80), font=font)
                draw.text((x + 10, y + 10 + delt * 1), &#39;年龄 :&#39; + str(obj[&#39;age&#39;]), (76, 176, 80), font=font)
                draw.text((x + 10, y + 10 + delt * 2), &#39;表情 :&#39; + expression, (76, 176, 80), font=font)
                draw.text((x + 10, y + 10 + delt * 3), &#39;魅力 :&#39; + str(obj[&#39;beauty&#39;]), (76, 176, 80), font=font)
                draw.text((x + 10, y + 10 + delt * 4), &#39;眼镜 :&#39; + glass, (76, 176, 80), font=font)
            elif img_width - x - w < 170:  # 避免图片太窄,导致文字显示不完全
                font = ImageFont.truetype(&#39;yahei.ttf&#39;, w // 8, encoding=&#39;utf-8&#39;)
                draw.text((x + 10, y + 10), &#39;性别 :&#39; + gender, (76, 176, 80), font=font)
                draw.text((x + 10, y + 10 + delt * 1), &#39;年龄 :&#39; + str(obj[&#39;age&#39;]), (76, 176, 80), font=font)
                draw.text((x + 10, y + 10 + delt * 2), &#39;表情 :&#39; + expression, (76, 176, 80), font=font)
                draw.text((x + 10, y + 10 + delt * 3), &#39;魅力 :&#39; + str(obj[&#39;beauty&#39;]), (76, 176, 80), font=font)
                draw.text((x + 10, y + 10 + delt * 4), &#39;眼镜 :&#39; + glass, (76, 176, 80), font=font)
            else:
                font = ImageFont.truetype(&#39;yahei.ttf&#39;, 20, encoding=&#39;utf-8&#39;)
                draw.text((x + w + 10, y + 10), &#39;性别 :&#39; + gender, (76, 176, 80), font=font)
                draw.text((x + w + 10, y + 10 + delt * 1), &#39;年龄 :&#39; + str(obj[&#39;age&#39;]), (76, 176, 80), font=font)
                draw.text((x + w + 10, y + 10 + delt * 2), &#39;表情 :&#39; + expression, (76, 176, 80), font=font)
                draw.text((x + w + 10, y + 10 + delt * 3), &#39;魅力 :&#39; + str(obj[&#39;beauty&#39;]), (76, 176, 80), font=font)
                draw.text((x + w + 10, y + 10 + delt * 4), &#39;眼镜 :&#39; + 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(&#39;faces/{}&#39;.format(os.path.basename(img)), cv2img)  # 保存图片到 face 文件夹下
            return &#39;检测成功&#39;
    else:
        return &#39;检测失败&#39;
登录后复制

到这里我们的人脸检测接口接入及图片处理就完成了。之后在收到用户发送的图片信息后,调用这个函数,把处理后的图片返回给用户就可以。

返回图片给用户

当收到用户图片时,需要以下几个步骤:

保存图片

当接收到用户图片后,我们要先把图片保存起来,之后才能去调用人脸分析接口,把图片信息传递过去,我们需要编写一个 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 = &#39;&#39;
app_id = &#39;wxfc6adcdd7593a712&#39;
secret = &#39;429d85da0244792be19e0deb29615128&#39;


def img_download(url, name):
    r = requests.get(url)
    with open(&#39;images/{}-{}.jpg&#39;.format(name, time.strftime("%Y_%m_%d%H_%M_%S", time.localtime())), &#39;wb&#39;) as fd:
        fd.write(r.content)
    if os.path.getsize(fd.name) >= 1048576:
        return &#39;large&#39;
    # print(&#39;namename&#39;, os.path.basename(fd.name))
    return os.path.basename(fd.name)


def get_access_token(appid, secret):
    &#39;&#39;&#39;获取access_token,100分钟刷新一次&#39;&#39;&#39;

    url = &#39;https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={}&secret={}&#39;.format(appid, secret)
    r = requests.get(url)
    parse_json = json.loads(r.text)
    global token
    token = parse_json[&#39;access_token&#39;]
    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 = {&#39;media&#39;: open(&#39;{}&#39;.format(name), &#39;rb&#39;)}
    r = requests.post(url, files=files)
    parse_json = json.loads(r.text)
    return parse_json[&#39;media_id&#39;]

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(&#39;&&#39;)
        b = {}
        for i in query_list:
            b[i.split(&#39;=&#39;)[0]] = i.split(&#39;=&#39;)[1]

        try:
            check_signature(token=&#39;lengxiao&#39;, signature=b[&#39;signature&#39;], timestamp=b[&#39;timestamp&#39;], nonce=b[&#39;nonce&#39;])
            resp.body = (b[&#39;echostr&#39;])
        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 == &#39;text&#39;:
            reply = TextReply(content=msg.content, message=msg)
            xml = reply.render()
            resp.body = (xml)
            resp.status = falcon.HTTP_200
        elif msg.type == &#39;image&#39;:
            name = img_download(msg.image, msg.source)  # 下载图片
            r = access_api(&#39;images/&#39; + name)
            if r == &#39;检测成功&#39;:
                media_id = img_upload(&#39;image&#39;, &#39;faces/&#39; + name)  # 上传图片,得到 media_id
                reply = ImageReply(media_id=media_id, message=msg)
            else:
                reply = TextReply(content=&#39;人脸检测失败,请上传1M以下人脸清晰的照片&#39;, message=msg)
            xml = reply.render()
            resp.body = (xml)
            resp.status = falcon.HTTP_200

app = falcon.API()
connect = Connect()
app.add_route(&#39;/connect&#39;, connect)
登录后复制

至此我们的工作就做完了,我们的公众号可以进行颜值检测了。本来我打算用在自己公众号上的,但是还存在下面几个问题,所以没有使用。

  1. 微信的机制,我们的程序必须在5s内给出响应。不然就会报'公众号提供的服务出现故障'。然而处理图片有时会比较慢,经常会超过5s。所以正确的处理方式应该是拿到用户的请求后立即返回一个空字符串表示我们收到了,之后单独创建一个线程去处理图片,当图片处理完后通过客服接口发送给用户。可惜的是未认证的公众号没有客服接口,所以没办法,超过5s就会报错。

  2. 无法自定义菜单,一旦启用了自定义开发,菜单也需要自定义配置,但是未认证的公众号没有权限通过程序来配置菜单,只能在微信后台配置。

所以,我并没有在我的公众号上启用这个程序,但是如果有认证的公众号,可以尝试开发各种好玩的功能。

相关推荐:

微信公众平台开发一键关注微信公众平台账号

微信公众平台开发尝试,微信公众平台

视频:传智、黑马微信公众平台开发视频教程

以上是来看看你的颜值多高吧!基于Python开发的公众号的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
2 周前 By 尊渡假赌尊渡假赌尊渡假赌
仓库:如何复兴队友
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒险:如何获得巨型种子
4 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

xml格式怎么打开 xml格式怎么打开 Apr 02, 2025 pm 09:00 PM

用大多数文本编辑器即可打开XML文件;若需更直观的树状展示,可使用 XML 编辑器,如 Oxygen XML Editor 或 XMLSpy;在程序中处理 XML 数据则需使用编程语言(如 Python)与 XML 库(如 xml.etree.ElementTree)来解析。

有什么手机APP可以将XML转换成PDF? 有什么手机APP可以将XML转换成PDF? Apr 02, 2025 pm 08:54 PM

无法找到一款将 XML 直接转换为 PDF 的应用程序,因为它们是两种根本不同的格式。XML 用于存储数据,而 PDF 用于显示文档。要完成转换,可以使用编程语言和库,例如 Python 和 ReportLab,来解析 XML 数据并生成 PDF 文档。

手机XML转PDF,转换速度快吗? 手机XML转PDF,转换速度快吗? Apr 02, 2025 pm 10:09 PM

手机XML转PDF的速度取决于以下因素:XML结构的复杂性手机硬件配置转换方法(库、算法)代码质量优化手段(选择高效库、优化算法、缓存数据、利用多线程)总体而言,没有绝对的答案,需要根据具体情况进行优化。

xml格式化工具推荐 xml格式化工具推荐 Apr 02, 2025 pm 09:03 PM

XML格式化工具可以将代码按照规则排版,提高可读性和理解性。选择工具时,要注意自定义能力、对特殊情况的处理、性能和易用性。常用的工具类型包括在线工具、IDE插件和命令行工具。

有没有免费的手机XML转PDF工具? 有没有免费的手机XML转PDF工具? Apr 02, 2025 pm 09:12 PM

没有简单、直接的免费手机端XML转PDF工具。需要的数据可视化过程涉及复杂的数据理解和渲染,市面上所谓的“免费”工具大多体验较差。推荐使用电脑端的工具或借助云服务,或自行开发App以获得更靠谱的转换效果。

如何在手机上高质量地将XML转换成PDF? 如何在手机上高质量地将XML转换成PDF? Apr 02, 2025 pm 09:48 PM

在手机上高质量地将XML转换成PDF需要:使用无服务器计算平台在云端解析XML并生成PDF。选择高效的XML解析器和PDF生成库。正确处理错误。充分利用云端计算能力,避免在手机上进行繁重任务。根据需求调整复杂度,包括处理复杂的XML结构、生成多页PDF和添加图片。打印日志信息以帮助调试。优化性能,选择高效的解析器和PDF库,并可能使用异步编程或预处理XML数据。确保良好的代码质量和可维护性。

怎么在手机上把XML文件转换为PDF? 怎么在手机上把XML文件转换为PDF? Apr 02, 2025 pm 10:12 PM

不可能直接在手机上用单一应用完成 XML 到 PDF 的转换。需要使用云端服务,通过两步走的方式实现:1. 在云端转换 XML 为 PDF,2. 在手机端访问或下载转换后的 PDF 文件。

手机上如何将XML转换成PDF? 手机上如何将XML转换成PDF? Apr 02, 2025 pm 10:18 PM

直接在手机上将XML转换为PDF并不容易,但可以借助云端服务实现。推荐使用轻量级手机App上传XML文件并接收生成的PDF,配合云端API进行转换。云端API使用无服务器计算服务,选择合适的平台至关重要。处理XML解析和PDF生成时需要考虑复杂性、错误处理、安全性和优化策略。整个过程需要前端App与后端API协同工作,需要对多种技术有所了解。

See all articles