LoginSignup
1
1

More than 5 years have passed since last update.

TensorFlowを使ってDir en greyの顔分類器を作ってみた - ⑪Web公開準備編

Last updated at Posted at 2017-05-31

はじめに

ここからは周りに自慢するためだけのものなので、自慢したい人だけ使ってください。

準備

ディレクトリ構成

ドキュメントルート
├ template
│ ├ index.html
│ └ layout.html
├ static
│ └ images
├ eval.py
├ main.py
├ style.css
└ web.py

プログラム

web.py
#!/usr/local/bin/python
#! -*- coding: utf-8 -*-

import tensorflow as tf
import multiprocessing as mp
from flask import Flask, render_template, request, redirect, url_for
import numpy as np
from werkzeug import secure_filename
import os
import eval

# 自身の名称を app という名前でインスタンス化する
app = Flask(__name__)
app.config['DEBUG'] = True

# 投稿画像の保存先
UPLOAD_FOLDER = '{ドキュメントルートパス}/static/images/'

# ルーティング。/にアクセス時
@app.route('/')
def index():
  return render_template('index.html')

# 画像投稿時のアクション
@app.route('/post', methods=['GET','POST'])
def post():
  if request.method == 'POST':
    if not request.files['file'].filename == u'':
      # アップロードされたファイルを保存
      f = request.files['file']
      img_path = os.path.join(UPLOAD_FOLDER, secure_filename(f.filename))
      f.save(img_path)

      # eval.pyへアップロードされた画像を渡す
      result = eval.evaluation(img_path, '{main.py実行ディレクトリ}パス/model2.ckpt')
    else:
      result = []
    return render_template('index.html', result=result)
  else:
    # エラーなどでリダイレクトしたい場合
    return redirect(url_for('index'))

if __name__ == '__main__':
  app.debug = True
  app.run(host='127.0.0.1')
index.html
{% extends "layout.html" %}
{% block content %}
<div class="form">
  <div class="container">
    <div class="row">
      <div class="col-md-12">
        <p style="margin-left:15px;">
          AIが顔写真からDir en greyの顔を検出します。(京、薫、Shinyaに対応)
        </p>
        {% if result %}
          {% if result[0][0]['rate'] > 90 %}
            {% if result[0][0]['label'] == 0 %}
              <h2 style="margin-left:10px;"><span class="red">{{result[0][0]['name']}}</span>の確率<span class="red">{{result[0][0]['rate']}}</span>%です。」</h2>
              <div class="col-md-7">
                <img src="./static/images/{{result[1]}}" class="detect_img">
              </div>
              <div class="col-md-5">
                <p class="logo_container">
                  <img src='./static/images/kyo.jpg' class="logo">
                </p>
                <p><img src="./static/images/{{result[2]}}" class="cut_image"></p>
                <p class="detail_container">
                  <解析詳細><br>
                  {{result[0][0]['name']}}:{{result[0][0]['rate']}}%<br>
                  {{result[0][1]['name']}}:{{result[0][1]['rate']}}%<br>
                  {{result[0][2]['name']}}:{{result[0][2]['rate']}}%<br>
                </p>
              </div>
            {% elif result[0][0]['label'] == 1 %}
              <h2 style="margin-left:10px;"><span class="red">{{result[0][0]['name']}}</span>の確率<span class="red">{{result[0][0]['rate']}}</span>%です。」</h2>
              <div class="col-md-7">
                <img src="./static/images/{{result[1]}}" class="detect_img">
              </div>
              <div class="col-md-5">
                <p class="logo_container">
                  <img src='./static/images/kaoru.jpg' class="logo">
                </p>
                <p><img src="./static/images/{{result[2]}}" class="cut_image"></p>
                <p class="detail_container">
                  <解析詳細><br>
                  {{result[0][0]['name']}}:{{result[0][0]['rate']}}%<br>
                  {{result[0][1]['name']}}:{{result[0][1]['rate']}}%<br>
                  {{result[0][2]['name']}}:{{result[0][2]['rate']}}%<br>
                </p>
              </div>
            {% elif result[0][0]['label'] == 2 %}
              <h2 style="margin-left:10px;"><span class="red">{{result[0][0]['name']}}</span>の確率<span class="red">{{result[0][0]['rate']}}</span>%です。」</h2>
              <div class="col-md-7">
                <img src="./static/images/{{result[1]}}" class="detect_img">
              </div>
              <div class="col-md-5">
                <div>
                  <p class="logo_container"><img src='./static/images/shinya.jpg' class="logo"></p>
                  <p><img src="./static/images/{{result[2]}}" class="cut_image"></p>
                  <p class="detail_container">
                    <解析詳細><br>
                    {{result[0][0]['name']}}:{{result[0][0]['rate']}}%<br>
                    {{result[0][1]['name']}}:{{result[0][1]['rate']}}%<br>
                    {{result[0][2]['name']}}:{{result[0][2]['rate']}}%<br>
                  </p>
                </div>
              </div>
            {% endif %}
          {% else %}
            <h2 style="margin-left:10px;">「どうやら<span class="red">Dir en greyではなさそう</span>です。」</h2>
            <div class="col-md-7">
              <img src="./static/images/{{result[1]}}" class="detect_img">
            </div>
            <div class="col-md-5">
              <p style="margin-top:70px;">
                   Who I am?<br>
                <img src="./static/images/{{result[2]}}" class="cut_image"></p>
              <p class="detail_container">
                <解析詳細><br>
                {{result[0][0]['name']}}:{{result[0][0]['rate']}}%<br>
                {{result[0][1]['name']}}:{{result[0][1]['rate']}}%<br>
                {{result[0][2]['name']}}:{{result[0][2]['rate']}}%<br>
              </p>
            </div>
          {% endif %}
        {% else %}
          <div class="col-md-12">
            <h3>顔写真をアップロードしてください!</h3>
          </div>
        {% endif %}
        <div class="col-md-12" style="margin-top:10px; margin-bottom:20px;">
          <form action="/post" method="post" class="form-inline" enctype = "multipart/form-data">
            <input type = "file" name = "file" />
            <button type="submit" class="btn btn-primary" style="margin-top:5px;">Dir en greyの顔をチェック!</button>
          </form>
        </div>
      </div>
    </div>
  </div>
</div>
{% endblock %}
layout.html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Dir en grey顔チェッカー</title>
    <link rel=stylesheet type=text/css href="{{ url_for('static', filename='style.css') }}">
    <!-- Bootstrap -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" integrity="sha512-dTfge/zgoMYpP7QbHy4gWMEGsbsdZeCXz7irItjcC3sPUFtf0kuFbDz/ixG7ArTxmDjLXDmezHubeNikyKGVyQ==" crossorigin="anonymous">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css" integrity="sha384-aUGj/X2zp5rLCbBxumKTCw2Z50WgIr1vs/PFN4praOTvYXWlVyh2UtNUU0KAUhAX" crossorigin="anonymous">
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js" integrity="sha512-K1qjQ+NcF2TYO/eI3M6v8EiNYZfA95pQumfvcVrTHtwQVDG+aHRqLi/ETn2uB+1JqwYqVG3LIvdm9lj6imS/pQ==" crossorigin="anonymous"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular-animate.min.js"></script>
    <script src="https://use.fontawesome.com/83341aec39.js"></script>
    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>
      <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
      <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
  </head>
  <body>
    <nav class="navbar navbar-inverse">
      <div class="container-fluid">
        <div class="navbar-header" style="padding-left:120px;">
          <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbarEexample7">
          <span class="sr-only">Toggle navigation</span>
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
          </button>
          <a class="navbar-brand" href="/">
          Dir en grey顔チェッカー
          </a>
        </div>
        <div class="collapse navbar-collapse" id="navbarEexample7">
          <ul class="nav navbar-nav">
          <!-- <li><a href="#">メニューA</a></li>
          <li class="active"><a href="#">メニューB</a></li>
          <li><a href="#">メニューC</a></li> -->
          </ul>
          <p class="navbar-text navbar-right">ようこそ <a href="#" class="navbar-link">ゲスト</a> さん。</p>
        </div>
      </div>
    </nav>
    {% block content %}{% endblock %}
  </body>
</html>
style.css
.red {
  color: red;
}
.detect_img {
  width: 100%;
  height:400px;
  border: 1px solid #808080;
}
.cut_image {
  width: 150px;
  height: 150px;
}
.logo {
  width:150px;
  height:35px;
}
.logo_container {
  margin-top:50px;
}
.detail_container {
  background-color:#dcdcdc;
  padding:5px; width:200px;
  border:1px solid #a9a9a9;
}

Apacheの設定

python.conf
LoadModule wsgi_module /usr/local/lib/python2.7/site-packages/mod_wsgi/server/mod_wsgi-py27.so

<VirtualHost *:80>
    ServerName localhost:80
    WSGIScriptAlias /dir {ドキュメントルート}/web.py

    <Directory "{ドキュメントルート}">
      Options Indexes FollowSymLinks ExecCGI
      SetHandler wsgi-script
      AddHandler wsgi-script .wsgi
      AddHandler wsgi-script .py
      Require all granted
      AllowOverride all
    </Directory>
</VirtualHost>

補足と言い訳

  • なかなか上手く起動できず試行錯誤しました。
  • 起動後の画像が正しくとれず、staticディレクトリ以下の画像しか見れませんでした。(理由は探っておりません)

全ページリンク

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1