Python 画像認識のwebでの利用

構成

Flaskを使用し、画像をアップロードしたらその結果が出るようにする。

web.pyにFlaskのコードを書き、templates内にindex.htmlとresult.htmlを用意する。

web.pyと同一フォルダ内にlabel_image.py、label.txt、model.tfliteを用意する。

準備

  1. label_image.py を汎用的に使えるように修正しておく
  2. label.txt を日本語に変更しておく

label_image.pyの改造

現状はコマンドラインでファイル名などを指定し結果を表示している。これを他のプログラムから呼び出せるように改造する。

まず、以下の部分はコマンドラインでオプションを指定されたものを取り出す部分であり、ここを最初から指定したファイル、オプションで行えるように変更する。

if __name__ == '__main__':
	# 省略
	args = parser.parse_args()

関数 detect_image にするようにし、画像ファイル名を引数 imageでもらうように変更する。オプションは関数の先頭で全て固定で指定する。

def detect_image(image):
  model_file = 'model.tflite'
  label_file = 'labels.txt'
  input_mean = 0
  input_std = 255
  num_threads = None

そして、以降のプログラムの args. の部分は全て削除する。

また、最後にある以下の部分は結果をコンソールの画面に表示している。

  for i in top_k:
    if floating_model:
      print('{:08.6f}: {}'.format(float(results[i]), labels[i]))
    else:
      print('{:08.6f}: {}'.format(float(results[i] / 255.0), labels[i]))

  print('time: {:.3f}ms'.format((stop_time - start_time) * 1000))

これを汎用的に利用できるようにするため、画面に表示するのでは無く、辞書に入れて返すように変更する。

  detects = {}
  for i in top_k:
    if floating_model:
      detect = {labels[i]:'{:8.2f}'.format(float(results[i]*100))}
    else:
      detect = {labels[i]:'{:8.2f}'.format(float(results[i]*100 / 255.0))}
    detects.update(detect)
  return detects  

これを利用するには以下のようにする。

from label_image import detect_image

filename = 'test.jpg'

detects = detect_image(filename)

print(detects)

Flaskでの画像アップロード

web.py の作成

from flask import Flask, render_template,request,redirect
import tempfile
import os

from label_image import detect_image

app = Flask(__name__)

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/imgup',methods=["POST"])
def imageUpload():
    if 'upfile' not in request.files:
        return redirect('/')
    
    file = request.files['upfile']
    orgname = file.filename
    
    if orgname=='':
        return redirect('/')

    temp = tempfile.TemporaryDirectory()
    fname = os.path.join(temp.name, orgname)
    file.save(fname)

    detects = detect_image(fname)
    
    return render_template('result.html',detects=detects)

app.run(debug=True)

index.html(body内のみ)

<h1>画像判定</h1>

<form action="/imgup" method="post" enctype="multipart/form-data">
<input type="file" name="upfile">
<input type="submit" value="判定">
</form>

result.html(body内のみ)

<h1>画像判定結果</h1>

<table>
{% for key in detects.keys() %}
<tr>
	<td>{{key}}</td>
	<td>{{detects[key]}}%</td>
</tr>
{% endfor %}
</table>
<a href="/">戻る</a>