前回からの続きになります。
今回は前回作成したオウム返のLinebotに顔面偏差値を測るアプリを組み込んで、作成していきます。
コンテンツ
ゴール


流行の芸人さんを載せてみましたが、最大5人まで測定してくれます。
実際のLINEアカウントがこちらです。


環境
- Mac:カトリーナ10.15
- Python 3.7
- Lineアカウント
- heroku
全体像

手順
まずはFace++と言うアプリを入れますのでこちらからAPI keyとsecretを取得します。

右上のSign upから登録を進めましょう

登録できるとすぐに、Get API Keyと出てきますのでそのままクリックします。
そうするとすぐにAPI Keyを取得できます。
またこれとは別途、登録したメールにも届いているので確認できます。
それではPythonを作成していきます。
まずは新たに下記ファイルを作成します。ファイル名は、face_detect.pyとします。
import requestdef face_detect(image):
# api_keyとapi_secretを持ってアクセスしに行きます
url = "https://api-us.faceplusplus.com/facepp/v3/detect"
payload = {'api_key': 'face++のAPIキー', 'api_secret': 'face++のsecretキー',\
'image_base64': image, 'return_attributes': 'gender,age,ethnicity,beauty'}
# base64…全てのパラメータを英数字で表す
try:
r = requests.post(url, data=payload)
r = r.json()
face_list = []
for face in r["faces"]:
faces = {}
if "attributes" in face:
faces["gender"] = face["attributes"]["gender"]["value"]
faces["age"] = face["attributes"]["age"]["value"]
# 人種を取得したい場合は以下の記述を追加する
# faces["ethnicity"] = face["attributes"]["ethnicity"]["value"]
# faces["ethnicity"] = faces["ethnicity"].replace("ASIAN", "アジア人").replace("WHITE", "白人").replace("BLACK", "黒人")
if faces["gender"] == "Male":
faces["beauty"] = face["attributes"]["beauty"]["male_score"]
faces["gender"] = "男性"
else:
faces["beauty"] = face["attributes"]["beauty"]["female_score"]
faces["gender"] = "女性"
faces["x_axis"] = face["face_rectangle"]["left"] # 並び替え用に画像上の顔のX座標の位置を代入
face_list.append(faces)
face_list = sorted(face_list, key=lambda x:x["x_axis"])
# 左から順に並び変える
msg = ""
for i, f in enumerate(face_list, 1):
if len(face_list) == 1:
# 写真が一人の時
msg += ""
else:
# 写真が2-5人の時
msg += "左から{}人目の情報\n".format(i)
# msg += "X軸の位置:{} \n".format(face["x_axis"]) デバッグ用
msg += "性別: {}\n".format(f["gender"])
msg += "年齢: {}歳\n".format(f["age"])
print(f["age"])
print(format(f["age"]))
# 人種を取得したい場合は以下の記述を追加する
# msg += "人種: {}\n".format(f["ethnicity"])
msg += "偏差値: {}\n".format(int(f["beauty"]))
msg += "評価: "
if f["beauty"] >= 90:
msg += "神レベル。出会った人が卒倒するレベル。\n\n"
elif 90 > f["beauty"] >= 80:
msg += "準神レベル。多くの人からチヤホヤされるレベル。\n\n"
elif 80 > f["beauty"] >= 70:
msg += "アイドル。顔だけで生きていける。\n\n"
elif 70 > f["beauty"] >= 60:
msg += "準アイドル。周りの人が振り向くレベル。\n\n"
elif 60 > f["beauty"] >= 55:
msg += "そこそこ。これ以上言うと図に乗るだろう?\n\n"
elif 55 > f["beauty"] >= 45:
msg += "一般人。人生苦もありゃ楽もある。\n\n"
else:
msg += "ドンマイ。\n\n"
msg = msg.rstrip()
if not msg:
msg = "画像から顔データを検出できませんでした。"
return msg
except:
return "サーバーの接続に失敗したか画像を正しく認識できませんでした。"
mian.pyも修正します。
from flask import Flask, request, abort
import face_detect as f # face_detext.py
import base64
from linebot import (
LineBotApi, WebhookHandler
)
from linebot.exceptions import (
InvalidSignatureError
)
from linebot.models import (
MessageEvent, TextMessage, TextSendMessage, ImageMessage
)
import os
app = Flask(name)
# 環境変数取得
# LINE Developersで設定されているアクセストークンとChannel Secretを取得し設定します。
YOUR_CHANNEL_ACCESS_TOKEN = os.environ["YOUR_CHANNEL_ACCESS_TOKEN"]
YOUR_CHANNEL_SECRET = os.environ["YOUR_CHANNEL_SECRET"]
line_bot_api = LineBotApi(YOUR_CHANNEL_ACCESS_TOKEN)
handler = WebhookHandler(YOUR_CHANNEL_SECRET)
# webhookからのリクエストチェック
@app.route("/callback", methods=['POST'])
def callback():
# get X-Line-Signature header value
# ⇨リクエストヘッダーからの署名検証の為の値を取得。
signature = request.headers['X-Line-Signature']
# get request body as text
# ⇨リクエストボディの取得
body = request.get_data(as_text=True)
app.logger.info("Request body: " + body)
# handle webhook body
# ⇨ 署名を検証後、問題なければhandleに定義されている関数を呼び出す
try:
handler.handle(body, signature)
# 署名検証で失敗した場合、例外を出す
except InvalidSignatureError:
abort(400) # handleの処理を終えればOK
return 'OK'
#LINEのメッセージの取得と返信内容の設定(オウム返し)
#LINEでMessageEvent(普通のメッセージを送信された場合)が起こった場合に、
def以下の関数を実行します。
#reply_messageの第一引数のevent.reply_tokenは、イベントの応答に用いるトークンです。
#第二引数には、linebot.modelsに定義されている返信用のTextSendMessageオブジェクトを渡しています。
@handler.add(MessageEvent, message=TextMessage)
テキストの場合はオウム返し:62行目
def handle_message(event):
# line_bot_api.reply_message(event.reply_token, TextSendMessage(text=event.message.text))
line_bot_api.reply_message(event.reply_token, TextSendMessage(text="測定したい写真を送ってね!!"))
print(event.message.text)
# コンソール上に表示させる
# imgがPOSTされた時の応答
@handler.add(MessageEvent, message=ImageMessage)
def handle_image_message(event):
push_img_id = event.message.id # 投稿された画像IDを取得
message_content = line_bot_api.get_message_content(push_img_id)
# LINEサーバー上に自動保存された画像を取得
push_img = b""
for chunk in message_content.iter_content():
push_img += chunk #画像をiter_contentでpush_imgに順次代入
push_img = base64.b64encode(push_img) # APIに通すためbase64エンコード
msg = f.face_detect(push_img)
line_bot_api.reply_message(event.reply_token, TextSendMessage(text=msg))
# ポート番号の設定
# おまじない
if name == "main":
# app.run()
port = int(os.getenv("PORT", 5000))
# Heroku console access
app.run(host="0.0.0.0", port=port)
準備OKですね。それでは最後にherokuにデータをpushします。
nit $ git add face_detect.py $ git add main.py $ git commit -m "second commit" $ git push heroku master
それではLINEから確認してみましょう。


OKですね!
スクールを利用して本格的に学ぶ
10人中9人が挫折すると言われるプログラミングを、半年間もの間頑張れ、結果、今はPythonエンジニアとして働く事ができているヒロヤンは、プログラミングスクールを利用して自ら目標を設定して講師の言う通りにひたすら打ち込んだまでです。
挫折率が高いプログラミングこそお金を払ってメンターを付けて、道を見失わないように環境を構築する必要があるのではないでしょうか。
結局一人だとどうしてもだらけてしまいます。
これはダイエットで自分一人では痩せられないけど、トレーナーを付けて否が応でもせざるを得ない環境を作ると一緒ですね。
ヒロヤンもプログラミング勉強開始直後はあれこれ悩みましたが、悩むよりも手っ取り早くスクールに登録した方が最短ルートで勉強できるのではないかと考えました。
無料カウンセリングで、あなたの悩みを相談してみてはいかがでしょうか?
Youtubeでおなじみのまこなり社長が運営するプログラミングスクールになります。
上記リンク先から無料相談ができます。




コメントを残す