


Voyons à quel point tu es belle?! Compte public développé sur la base de Python
Jul 25, 2018 pm 01:56 PMIl 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'age, 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 # 一.計算接口鑒權(quán),構(gòu)造請求參數(shù) 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): '''組織接口請求的參數(shù)形式,并且計算sign接口鑒權(quán)信息, 最終返回接口請求所需要的參數(shù)字典''' 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,接口鑒權(quán) params['sign'] = md5text # 添加到請求參數(shù)列表中 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) # 圖片轉(zhuǎn)為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格式轉(zhuǎn)換為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'] # 人臉框?qū)挾? h = obj['height'] # 人臉框高度 # 根據(jù)返回的值,自定義一下顯示的文字內(nèi)容 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: # 檢測到多個人臉,就把信息寫入人臉框內(nèi) 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 格式轉(zhuǎn)換為 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)Retour à l'utilisateurNous modifions simplement la logique après réception l'image. Après détection du visage et téléchargement pour obtenir le Media_ID, il ne reste plus qu'à restituer l'image à l'utilisateur. Regardez directement le code de 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)à ce stade, notre travail est terminé et notre compte officiel peut être testé pour son apparence. J'avais initialement prévu de l'utiliser sur mon compte officiel, mais il y a encore plusieurs problèmes ci-dessous, donc je ne l'ai pas utilisé.
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

Undress AI Tool
Images de déshabillage gratuites

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.

Clothoff.io
Dissolvant de vêtements AI

Video Face Swap
échangez les visages dans n'importe quelle vidéo sans effort grace à notre outil d'échange de visage AI entièrement gratuit?!

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)

Installez PYODBC: utilisez la commande PiPInstallpyodbc pour installer la bibliothèque; 2. Connectez SQLServer: utilisez la cha?ne de connexion contenant le pilote, le serveur, la base de données, l'UID / PWD ou TrustEd_Connection via la méthode pyoDBC.Connect () et prendre en charge l'authentification SQL ou l'authentification Windows respectivement; 3. Vérifiez le pilote installé: exécutez pyodbc.Drivers () et filtrez le nom du pilote contenant ?SQLServer? pour vous assurer que le nom du pilote correct est utilisé tel que ?ODBCDriver17 pour SQLServer?; 4. Paramètres clés de la cha?ne de connexion

L'introduction à l'arbitrage statistique L'arbitrage statistique est une méthode commerciale qui capture l'inadéquation des prix sur le marché financier basé sur des modèles mathématiques. Sa philosophie principale découle de la régression moyenne, c'est-à-dire que les prix des actifs peuvent s'écarter des tendances à long terme à court terme, mais reviendront éventuellement à leur moyenne historique. Les traders utilisent des méthodes statistiques pour analyser la corrélation entre les actifs et rechercher des portefeuilles qui changent généralement de manière synchrone. Lorsque la relation de prix de ces actifs est anormalement déviée, des opportunités d'arbitrage se présentent. Sur le marché des crypto-monnaies, l'arbitrage statistique est particulièrement répandu, principalement en raison de l'inefficacité et des fluctuations drastiques du marché lui-même. Contrairement aux marchés financiers traditionnels, les crypto-monnaies fonctionnent 24h / 24 et leurs prix sont très susceptibles de briser les nouvelles, les sentiments des médias sociaux et les améliorations technologiques. Cette fluctuation des prix constante crée fréquemment un biais de prix et fournit aux arbitrageurs un

Actuellement, JD.com n'a émis aucune stablecoins, et les utilisateurs peuvent choisir les plates-formes suivantes pour acheter des stablescoins grand public: 1. Binance est la plate-forme avec le plus grand volume de transaction au monde, prend en charge plusieurs paiements de monnaie fiduciaire et a une solide liquidité; 2. OKX a des fonctions puissantes, fournissant un service client de 7x24 heures et plusieurs méthodes de paiement; 3. Huobi a une grande réputation dans la communauté chinoise et a un système complet de contr?le des risques; 4. Gate.io a de riches types de devises, adaptés à l'exploration des actifs de niche après avoir acheté des staboins; 5. Il existe de nombreux types de devises répertoriées sur Kucoin, qui est propice à la découverte des premiers projets; 6. Bitget est caractérisé par des transactions de commande, avec des transactions P2P pratiques, et convient aux amateurs de trading social. Les plates-formes ci-dessus fournissent toutes des services d'achat de stablecoin s?r et fiable.

Iter () est utilisé pour obtenir l'objet Iterator, et Next () est utilisé pour obtenir l'élément suivant; 1. Utilisez Iterator () pour convertir des objets itérables tels que les listes en itérateurs; 2. Appelez Next () pour obtenir des éléments un par un et déclenchez l'exception de l'arrêt lorsque les éléments sont épuisés; 3. Utilisez Suivant (iterator, par défaut) pour éviter les exceptions; 4. Les itérateurs personnalisés doivent implémenter les méthodes __iter __ () et __Next __ () pour contr?ler la logique d'itération; L'utilisation de valeurs par défaut est un moyen courant de parcourir la traversée et l'ensemble du mécanisme est concis et pratique.

ShutLil.rmtree () est une fonction de Python qui supprime récursivement l'intégralité de l'arborescence du répertoire. Il peut supprimer les dossiers spécifiés et tous les contenus. 1. Utilisation de base: utilisez ShutLil.rmtree (Path) pour supprimer le répertoire, et vous devez gérer FileLenotFoundError, PermissionError et autres exceptions. 2. Application pratique: vous pouvez effacer les dossiers contenant des sous-répertoires et des fichiers en un seul clic, tels que des données temporaires ou des répertoires mis en cache. 3. Remarques: L'opération de suppression n'est pas restaurée; FilenotFoundError est lancé lorsque le chemin n'existe pas; Il peut échouer en raison d'autorisations ou d'occupation des fichiers. 4. Paramètres facultatifs: les erreurs peuvent être ignorées par ignore_errors = true

Installer le pilote de base de données correspondant; 2. Utilisez Connect () pour se connecter à la base de données; 3. Créez un objet de curseur; 4. Utilisez EXECUTE () ou Execumany () pour exécuter SQL et utiliser une requête paramétrée pour empêcher l'injection; 5. Utilisez fetchall (), etc. pour obtenir des résultats; 6. commit () est requis après modification; 7. Enfin, fermez la connexion ou utilisez un gestionnaire de contexte pour le gérer automatiquement; Le processus complet garantit que les opérations SQL sont s?res et efficaces.

Threading.Timer exécute les fonctions de manière asynchrone après un délai spécifié sans bloquer le thread principal et convient à la gestion des retards légers ou des taches périodiques. ① utilisation basique: Créez un objet Timer et Call Start () pour retarder l'exécution de la fonction spécifiée; ② Annuler la tache: appeler la méthode annulée () avant l'exécution de la tache peut empêcher l'exécution; ③ Exécution de répétition: activer le fonctionnement périodique en encapsulant la classe Repetingtimer; ④ Remarque: chaque minuterie démarre un nouveau thread et les ressources doivent être gérées raisonnablement. Si nécessaire, appelez Annuler () pour éviter les déchets de mémoire. Lorsque le programme principal sort, vous devez prêter attention à l'influence des fils non prodigués. Il convient aux opérations retardées, au traitement du délai d'attente et à un sondage simple. C'est simple mais très pratique.

Novice pour entrer dans le cercle de la devise doit apprendre systématiquement, choisir des plates-formes fiables, assurer la sécurité, ma?triser les opérations de trading et continuer à apprendre. 1. Apprenez les connaissances de base, y compris les principes de la blockchain, les devises traditionnelles, l'utilisation du stockage et la gestion des risques; 2. Choisissez des échanges fiables tels que la binance et les ouyi; 3. Configurer un environnement sécurisé, activer la vérification en deux étapes et la sauvegarde des clés privées; 4. Dép?t via C2C ou Banque et effectuer le trading au comptant; 5. Continuez à prêter attention à la dynamique, à diversifier l'investissement et à arrêter strictement les pertes.
