


Voyons à quel point tu es belle ! Compte public développé sur la base de Python
Il s'agit d'un développement de compte public WeChat basé sur Python pour la détection d'apparence. Aujourd'hui, nous analysons les photos de l'utilisateur via la plate-forme d'IA de Tencent, puis les renvoyons à l'utilisateur. Vivons ensemble le test beauté des comptes publics
Rendu
1 . Accès à la plateforme Tencent AI
Jetons d'abord un coup d'œil à la description de l'interface officielle de détection et d'analyse des visages :
Détecter tous les visages (Face) dans un emplacement d'image (Image) donné et attributs du visage correspondants. La position comprend (x, y, w, h) et les attributs du visage incluent le sexe, l'âge, l'expression, la beauté, les lunettes et la posture (tangage, roulis, lacet).
Les paramètres de la demande incluent les éléments suivants :
identification de l'application app_id, nous pouvons obtenir l'app_id après l'inscription sur la plateforme AI
time_stamp timestamp
nonce_str chaîne aléatoire
signer les informations de signature, nous devons les calculer nous-mêmes
-
image Image à détecter (limite supérieure 1M)
mode de détection
1.
Le responsable nous a donné la méthode de calcul de l'authentification de l'interface.
Triez les paires de paramètres de requête
dans l'ordre croissant du dictionnaire par clé pour obtenir une liste ordonnée de paires de paramètres N Les paires de paramètres de la liste N sont fusionnées en chaînes au format de paires clé-valeur d'URL pour obtenir la chaîne T (par exemple : clé1=valeur1&clé2=valeur2). La partie valeur du processus d'épissage clé-valeur d'URL nécessite un codage d'URL. . L'algorithme de codage d'URL utilise des lettres majuscules. Par exemple, %E8, au lieu de %e8 minuscule
, utilisez app_key comme nom de clé pour former la valeur de clé d'URL et l'associer à la clé. fin de la chaîne T pour obtenir la chaîne S (comme : key1 =value1&key2=value2&app_key=Key)
Effectuer l'opération MD5 sur la chaîne S, convertir tous les caractères de la valeur MD5 obtenue en majuscules et obtenez la signature de la demande d'interface
2. Demander l'adresse de l'interface
Demander les informations de l'interface Nous utilisons des requêtes pour envoyer la demande, et nous obtiendrons. les informations d'image renvoyées au format json pip install requests
Demandes d'installation.
3. Traitez les informations renvoyées
Traitez les informations renvoyées, affichez les informations sur l'image, puis enregistrez l'image traitée. Ici, nous utilisons les bibliothèques opencv et Pillow pip install pillow
et pip install opencv-python
pour installer.
Commençons à écrire du code. Nous créons un nouveau fichier face_id.py pour nous connecter à la plateforme AI et renvoyer les données d'image détectées.
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['gender'] < 70: gender = "娘" elif obj['gender'] < 30: gender = '女' else: gender = '女汉子' if 90 < obj['expression'] <= 100: # 表情从0-100,表示笑的程度 expression = '一笑倾城' elif 80 < obj['expression'] <= 90: expression = '心花怒放' elif 70 < obj['expression'] <= 80: expression = '兴高采烈' elif 60 < obj['expression'] <= 70: expression = '眉开眼笑' elif 50 < obj['expression'] <= 60: expression = '喜上眉梢' elif 40 < obj['expression'] <= 50: expression = '喜气洋洋' elif 30 < obj['expression'] <= 40: expression = '笑逐颜开' elif 20 < obj['expression'] <= 30: expression = '似笑非笑' elif 10 < obj['expression'] <= 20: expression = '半嗔半喜' elif 0 <= obj['expression'] <= 10: 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 < 170: # 避免图片太窄,导致文字显示不完全 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) 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 '检测失败'
À ce stade, l'accès à notre interface de détection de visage et le traitement des images sont terminés. Après avoir reçu les informations d'image envoyées par l'utilisateur, appelez cette fonction et renvoyez l'image traitée à l'utilisateur.
Renvoyer la photo à l'utilisateur
Lors de la réception de la photo de l'utilisateur, les étapes suivantes sont requises :
Enregistrer la photo
Après avoir reçu la photo de l'utilisateur , Nous devons d'abord enregistrer l'image, puis nous pouvons appeler l'interface d'analyse du visage et transmettre les informations sur l'image. Nous devons écrire une fonction img_download pour télécharger l'image. Voir le code ci-dessous pour plus de détails
Appel de l'interface d'analyse du visage
Après avoir téléchargé l'image, appelez la fonction d'interface dans le fichier face_id.py pour obtenir l'image traitée.
Télécharger l'image
Le résultat de la détection est une nouvelle image. Pour envoyer l'image à l'utilisateur, nous avons besoin d'un Media_ID. Pour obtenir le Media_ID, nous devons d'abord télécharger l'image en tant que matériau temporaire. , donc ici nous avons besoin d'une fonction img_upload qui est utilisée pour télécharger des images, et un access_token est requis lors du téléchargement. Nous l'obtenons via une fonction Pour obtenir le access_token, nous devons ajouter notre propre adresse IP à la liste blanche, sinon elle. ne sera pas obtenu. Veuillez vous connecter à « WeChat Public Platform-Development-Basic Configuration » pour ajouter l'adresse IP du serveur à la liste blanche IP à l'avance. Vous pouvez afficher l'adresse IP de cette machine sur http://ip.qq.com/...<. 🎜>
Commençons à écrire du code, nous créons un nouveau utils.py pour télécharger et télécharger des imagesimport 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)
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)
Mécanisme de WeChat, notre programme doit répondre dans les 5 secondes. Sinon, il signalera « Le service fourni par le compte officiel est défectueux ». Cependant, le traitement des images est parfois lent, dépassant souvent les 5 secondes. Par conséquent, la bonne façon de le gérer devrait être de renvoyer immédiatement une chaîne vide après avoir reçu la demande de l'utilisateur pour indiquer que nous l'avons reçue, puis de créer un thread séparé pour traiter l'image. Lorsque l'image est traitée, elle est envoyée. l'utilisateur via l'interface du service client. Malheureusement, les comptes publics non certifiés n'ont pas d'interface de service client, vous ne pouvez donc rien faire. Si cela prend plus de 5 secondes, une erreur sera signalée.
Le menu ne peut pas être personnalisé. Une fois le développement personnalisé activé, le menu doit également être personnalisé. Cependant, les comptes publics non certifiés n'ont pas l'autorisation de configurer le menu via le programme et peuvent le faire. configurez-le uniquement dans la configuration du backend WeChat.
Donc, je n'ai pas activé ce programme sur mon compte officiel, mais si vous avez un compte officiel certifié, vous pouvez essayer de développer diverses fonctions amusantes.
Recommandations associées :
Tentative de développement de la plateforme publique WeChat , Plateforme publique WeChat
Vidéo : Tutoriel vidéo de développement de la plateforme publique Chuanzhi et Dark Horse WeChat
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

AI Hentai Generator
Générez AI Hentai gratuitement.

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

La page H5 doit être maintenue en continu, en raison de facteurs tels que les vulnérabilités du code, la compatibilité des navigateurs, l'optimisation des performances, les mises à jour de sécurité et les améliorations de l'expérience utilisateur. Des méthodes de maintenance efficaces comprennent l'établissement d'un système de test complet, à l'aide d'outils de contrôle de version, de surveiller régulièrement les performances de la page, de collecter les commentaires des utilisateurs et de formuler des plans de maintenance.

Comment obtenir des données dynamiques de la page de travail 58.com tout en rampant? Lorsque vous rampez une page de travail de 58.com en utilisant des outils de chenilles, vous pouvez rencontrer cela ...

Explication détaillée des compétences de rédaction de code JavaScript Lors de l'écriture de code JavaScript, nous rencontrons souvent une ligne de code trop longue, ce qui affecte non seulement la lisibilité du code ...

Les problèmes de «chargement» PS sont causés par des problèmes d'accès aux ressources ou de traitement: la vitesse de lecture du disque dur est lente ou mauvaise: utilisez Crystaldiskinfo pour vérifier la santé du disque dur et remplacer le disque dur problématique. Mémoire insuffisante: améliorez la mémoire pour répondre aux besoins de PS pour les images à haute résolution et le traitement complexe de couche. Les pilotes de la carte graphique sont obsolètes ou corrompues: mettez à jour les pilotes pour optimiser la communication entre le PS et la carte graphique. Les chemins de fichier sont trop longs ou les noms de fichiers ont des caractères spéciaux: utilisez des chemins courts et évitez les caractères spéciaux. Problème du PS: réinstaller ou réparer le programme d'installation PS.

La résolution du problème du démarrage lent Photoshop nécessite une approche à plusieurs volets, notamment: la mise à niveau du matériel (mémoire, lecteur à semi-conducteurs, CPU); des plug-ins désinstallés ou incompatibles; nettoyer régulièrement les déchets du système et des programmes de fond excessifs; clôture des programmes non pertinents avec prudence; Éviter d'ouvrir un grand nombre de fichiers pendant le démarrage.

Un PS est coincé sur le "chargement" lors du démarrage peut être causé par diverses raisons: désactiver les plugins corrompus ou conflictuels. Supprimer ou renommer un fichier de configuration corrompu. Fermez des programmes inutiles ou améliorez la mémoire pour éviter une mémoire insuffisante. Passez à un entraînement à semi-conducteurs pour accélérer la lecture du disque dur. Réinstaller PS pour réparer les fichiers système corrompus ou les problèmes de package d'installation. Afficher les informations d'erreur pendant le processus de démarrage de l'analyse du journal d'erreur.

La raison du chargement lent PS est l'impact combiné du matériel (CPU, mémoire, disque dur, carte graphique) et logiciel (système, programme d'arrière-plan). Les solutions incluent: la mise à niveau du matériel (en particulier le remplacement des disques à semi-conducteurs), l'optimisation des logiciels (nettoyage des ordures système, mise à jour des pilotes, vérification des paramètres PS) et traitement des fichiers PS. La maintenance ordinaire de l'ordinateur peut également aider à améliorer la vitesse d'exécution du PS.

H5. La principale différence entre les mini programmes et l'application est: Architecture technique: H5 est basé sur la technologie Web, et les mini-programmes et l'application sont des applications indépendantes. Expérience et fonctions: H5 est légère et facile à utiliser, avec des fonctions limitées; Les mini-programmes sont légers et ont une bonne interactivité; Les applications sont puissantes et ont une expérience fluide. Compatibilité: H5 est compatible multiplateforme, les applets et les applications sont limités par la plate-forme. Coût de développement: H5 a un faible coût de développement, des mini-programmes moyens et une application la plus élevée. Scénarios applicables: H5 convient à l'affichage d'informations, les applets conviennent aux applications légères et les applications conviennent aux fonctions complexes.
