Dies ist eine Python-basierte Entwicklung eines öffentlichen WeChat-Kontos zur Erkennung des Erscheinungsbilds. Heute analysieren wir die Bilder des Benutzers über die KI-Plattform von Tencent und geben sie dann an den Benutzer zurück. Lassen Sie uns gemeinsam den Schönheitstest öffentlicher Konten erleben
Schauen wir uns zunächst die Beschreibung der offiziellen Gesichtserkennungs- und Analyseschnittstelle an:
Erkennen Sie alle Gesichter (Gesicht) an einem bestimmten Bildort (Bild) und entsprechend Gesichtsattribute. Die Position umfasst (x, y, w, h) und die Gesichtsattribute umfassen Geschlecht, Alter, Ausdruck, Schönheit, Brille und Körperhaltung (Nicken, Rollen, Gieren).
Die Anforderungsparameter umfassen Folgendes:
app_id Anwendungsidentifikation, wir können die app_id nach der Registrierung auf der KI-Plattform erhalten
Zeitstempel Zeitstempel
nonce_str Zufallszeichenfolge
Signaturinformationen, wir müssen sie selbst berechnen
Bild Zu erkennendes Bild (Obergrenze 1M)
Modus Erkennungsmodus
Der Beamte gab uns die Berechnungsmethode für die Schnittstellenauthentifizierung.
Sortieren Sie die
Die Parameterpaare in Liste N werden in Zeichenfolgen im Format von URL-Schlüssel-Wert-Paaren gespleißt, um die Zeichenfolge T zu erhalten (zum Beispiel: Schlüssel1=Wert1&Schlüssel2=Wert2). Der Wertteil des URL-Schlüssel-Wert-Spleißprozesses erfordert eine URL-Codierung . Der URL-Kodierungsalgorithmus verwendet Großbuchstaben anstelle von Kleinbuchstaben %e8
, verwenden Sie app_key als Schlüsselnamen, um den URL-Schlüsselwert zu bilden und ihn mit dem zu verbinden Ende der Zeichenfolge T, um die Zeichenfolge S zu erhalten (z. B.: key1 =value1&key2=value2&app_key=Key)
Führen Sie eine MD5-Operation für die Zeichenfolge S aus und konvertieren Sie alle Zeichen des erhaltenen MD5-Werts in Großbuchstaben umwandeln und die Schnittstellenanforderungssignatur abrufen
Anfragen verwenden, um die Anfrage zu senden die zurückgegebenen Bildinformationen im JSON-Format pip install requests
Installationsanfragen.
Verarbeiten Sie die zurückgegebenen Informationen, zeigen Sie die Informationen auf dem Bild an und speichern Sie dann das verarbeitete Bild. Hier verwenden wir zur Installation die OpenCV- und Pillow-Bibliotheken pip install pillow
und pip install opencv-python
.
Beginnen Sie mit dem Schreiben von Code. Wir erstellen eine neue face_id.py-Datei, um eine Verbindung zur KI-Plattform herzustellen und die erkannten Bilddaten zurückzugeben.
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 '检测失败'
An diesem Punkt sind unser Zugriff auf die Gesichtserkennungsschnittstelle und die Bildverarbeitung abgeschlossen. Rufen Sie nach Erhalt der vom Benutzer gesendeten Bildinformationen diese Funktion auf und geben Sie das verarbeitete Bild an den Benutzer zurück.
Beim Empfang des Benutzerbildes sind folgende Schritte erforderlich:
Nach Erhalt des Benutzerbildes , Wir müssen das Bild zuerst speichern, dann können wir die Gesichtsanalyseschnittstelle aufrufen und die Bildinformationen übergeben. Wir müssen eine img_download-Funktion schreiben, um das Bild herunterzuladen. Einzelheiten finden Sie im folgenden Code.
Rufen Sie nach dem Herunterladen des Bildes die Schnittstellenfunktion in der Datei face_id.py auf, um das verarbeitete Bild zu erhalten.
Um das Bild an den Benutzer zu senden, benötigen wir eine Media_ID. Um die Media_ID zu erhalten, müssen wir das Bild zunächst als temporäres Material hochladen , also brauchen wir hier eine img_upload-Funktion zum Hochladen von Bildern, und beim Hochladen ist ein access_token erforderlich. Wir erhalten es über eine Funktion. Um das access_token zu erhalten, müssen wir unsere eigene IP-Adresse zur Whitelist hinzufügen wird nicht erhalten. Bitte melden Sie sich bei „WeChat Public Platform-Development-Basic Configuration“ an, um die Server-IP-Adresse vorab zur IP-Whitelist hinzuzufügen. Sie können die IP dieses Geräts unter http://ip.qq.com/...< einsehen 🎜>
Beginnen Sie mit dem Schreiben des Codes, wir erstellen eine neue utils.py zum Herunterladen und Hochladen von Bildernimport 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)
Mit dem WeChat-Mechanismus muss unser Programm innerhalb von 5 Sekunden reagieren. Andernfalls wird die Meldung „Der vom offiziellen Konto bereitgestellte Dienst ist fehlerhaft“ angezeigt. Allerdings ist die Bildverarbeitung manchmal langsam und dauert oft länger als 5 Sekunden. Daher sollte die richtige Vorgehensweise darin bestehen, nach Erhalt der Benutzeranforderung sofort eine leere Zeichenfolge zurückzugeben, um anzugeben, dass wir sie erhalten haben, und dann einen separaten Thread zum Verarbeiten des Bildes zu erstellen der Benutzer über die Kundendienstschnittstelle. Leider verfügen nicht zertifizierte öffentliche Konten nicht über eine Kundendienstschnittstelle, daher können Sie nichts dagegen tun. Wenn der Vorgang länger als 5 Sekunden dauert, wird ein Fehler gemeldet.
Das Menü kann nicht angepasst werden. Sobald die benutzerdefinierte Entwicklung aktiviert ist, muss auch das Menü angepasst werden. Nicht zertifizierte offizielle Konten haben jedoch keine Berechtigung, das Menü über das Programm zu konfigurieren Konfigurieren Sie es nur in der WeChat-Backend-Konfiguration.
Ich habe dieses Programm also nicht auf meinem offiziellen Konto aktiviert, aber wenn Sie ein zertifiziertes offizielles Konto haben, können Sie versuchen, verschiedene unterhaltsame Funktionen zu entwickeln.
Verwandte Empfehlungen:
Versuch der Entwicklung einer öffentlichen WeChat-Plattform , Öffentliche WeChat-Plattform
Video: Video-Tutorial zur Entwicklung der öffentlichen WeChat-Plattform von Chuanzhi und Dark Horse
Das obige ist der detaillierte Inhalt vonMal sehen, wie gut du aussiehst! Auf Python basierendes öffentliches Konto. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!