**一邓夕、用到的工具**
pycharm
postman
flask框架
yaml文件
gunicorn
**二岸啡、過程**
1.最開始的時候準備好文件罢艾,拷貝到自己的電腦里臀玄。
decu文件渊额,下面有一個huojia和一個didui况木。
在huojia和didui中分別還有五個小文件垒拢,
格式是decu_anchors.txt,decu_classes.txt火惊,,cfg , .h5, .weight求类。
2.分析得到的yolo.py里面的程序,解析每一個變量的數(shù)據(jù)是什么屹耐。
3.編寫最基本的flask框架尸疆。
```
from flask import Flask, request, Response
app = Flask(__name__)
@app.route('/', methods=["GET", "POST"])
def predict():
params = json.loads(request.get_data())
paths = params['data']
return paths
if __name__ == '__main__':
app.run(processes=1, threaded=True)
```
這樣簡單的框架就出來了,params返回數(shù)據(jù)惶岭,并且取數(shù)據(jù)中的“data”寿弱,也就是圖片網(wǎng)址。
4.修改yolo按灶。
主要是后面for循環(huán)症革,取出坐標值。
注意兆衅,prob這個值小數(shù)點后數(shù)值太多地沮,如果不進行修改,那么會報錯羡亩。
所以寫成這個格式
```
"prob": float('%.7f' % score)
```
最后返回的整理一下摩疑,就變成
```
result = {"status": {"code": 200,"msg": "OK"},"head": {"method": "/predict","service": "xuehua_service","time": str(end_run - start_run)},"body": {"predictions": predictions_list}}
return result
```
這樣最后的yolo.py,在數(shù)值部分就修改差不多了畏铆。
5.文件的調(diào)用雷袋。
我們這次在flask框架,調(diào)用yolo.py中的YOLO這個類辞居。
所以我們在xuehua_flask.py中楷怒,就寫
```
from keras_yolo.yolo import YOLO
```
剛開始將yolo_huojia = YOLO()寫在了def函數(shù)里面,會發(fā)現(xiàn)運行的很慢瓦灶。
所以鸠删,我們將這個寫在外邊。
也就是
```
app = Flask(__name__)
yolo_huojia = YOLO()
yolo_didui = YOLO_DIDUI()
@app.route('/', methods=["GET", "POST"])
def predict():
```
這樣贼陶。
6.gunicorn的使用刃泡。
我們先運用了一個虛擬環(huán)境tensorflow,然后在terminal中調(diào)用虛擬環(huán)境碉怔。
```
source activate tensorflow? # 啟動虛擬環(huán)境
gunicorn -c conf/gunicorn.py xuehua_flask:app # 運行程序
```
7.yolo代碼
```
# -*- coding: utf-8 -*-
"""
Class definition of YOLO_v3 style detection model on image and video
"""
import colorsys
from timeit import default_timer as timer
import numpy as np
from keras import backend as K
from keras.models import load_model
from keras.layers import Input
from PIL import Image, ImageFont, ImageDraw
from keras_yolo.yolo3.model import yolo_eval, yolo_body, tiny_yolo_body
from keras_yolo.yolo3.utils import letterbox_image
import os
from keras.utils import multi_gpu_model
from io import BytesIO
import requests
import time
import yaml
class YOLO(object):
? ? curPath = os.path.dirname(os.path.realpath(__file__))
? ? yamlpath = os.path.join(curPath, "../conf/params.yaml")
? ? f = open(yamlpath, 'r', encoding='utf-8')
? ? cfg = f.read()
? ? # print(cfg)
? ? d = yaml.load(cfg, Loader=yaml.FullLoader)
? ? _defaults = {
? ? ? ? "model_path": d.get("model_path"),
? ? ? ? "anchors_path": d.get("anchors_path"),
? ? ? ? "classes_path": d.get("classes_path"),
? ? ? ? "score" : int(d.get("score")),
? ? ? ? "iou" : float(d.get("iou")),
? ? ? ? "model_image_size" : eval(d.get("model_image_size")),
? ? ? ? "gpu_num" : int(d.get("gpu_num"))
? ? }
? ? @classmethod
? ? def get_defaults(cls, n):
? ? ? ? if n in cls._defaults:
? ? ? ? ? ? return cls._defaults[n]
? ? ? ? else:
? ? ? ? ? ? return "Unrecognized attribute name '" + n + "'"
? ? def __init__(self, **kwargs):
? ? ? ? self.__dict__.update(self._defaults) # set up default values
? ? ? ? self.__dict__.update(kwargs) # and update with user overrides
? ? ? ? self.class_names = self._get_class()
? ? ? ? self.anchors = self._get_anchors()
? ? ? ? self.sess = K.get_session()
? ? ? ? self.boxes, self.scores, self.classes = self.generate()
? ? def _get_class(self):
? ? ? ? classes_path = os.path.expanduser(self.classes_path)
? ? ? ? with open(classes_path) as f:
? ? ? ? ? ? class_names = f.readlines()
? ? ? ? class_names = [c.strip() for c in class_names]
? ? ? ? return class_names
? ? def _get_anchors(self):
? ? ? ? anchors_path = os.path.expanduser(self.anchors_path)
? ? ? ? with open(anchors_path) as f:
? ? ? ? ? ? anchors = f.readline()
? ? ? ? anchors = [float(x) for x in anchors.split(',')]
? ? ? ? return np.array(anchors).reshape(-1, 2)
? ? def generate(self):
? ? ? ? model_path = os.path.expanduser(self.model_path)
? ? ? ? assert model_path.endswith('.h5'), 'Keras model or weights must be a .h5 file.'
? ? ? ? # Load model, or construct model and load weights.
? ? ? ? num_anchors = len(self.anchors)
? ? ? ? num_classes = len(self.class_names)
? ? ? ? is_tiny_version = num_anchors==6 # default setting
? ? ? ? try:
? ? ? ? ? ? self.yolo_model = load_model(model_path, compile=False)
? ? ? ? except:
? ? ? ? ? ? self.yolo_model = tiny_yolo_body(Input(shape=(None,None,3)), num_anchors//2, num_classes) \
? ? ? ? ? ? ? ? if is_tiny_version else yolo_body(Input(shape=(None,None,3)), num_anchors//3, num_classes)
? ? ? ? ? ? self.yolo_model.load_weights(self.model_path) # make sure model, anchors and classes match
? ? ? ? else:
? ? ? ? ? ? assert self.yolo_model.layers[-1].output_shape[-1] == \
? ? ? ? ? ? ? ? num_anchors/len(self.yolo_model.output) * (num_classes + 5), \
? ? ? ? ? ? ? ? 'Mismatch between model and given anchor and class sizes'
? ? ? ? print('{} model, anchors, and classes loaded.'.format(model_path))
? ? ? ? # Generate colors for drawing bounding boxes.
? ? ? ? hsv_tuples = [(x / len(self.class_names), 1., 1.)
? ? ? ? ? ? ? ? ? ? ? for x in range(len(self.class_names))]
? ? ? ? self.colors = list(map(lambda x: colorsys.hsv_to_rgb(*x), hsv_tuples))
? ? ? ? self.colors = list(
? ? ? ? ? ? map(lambda x: (int(x[0] * 255), int(x[1] * 255), int(x[2] * 255)),
? ? ? ? ? ? ? ? self.colors))
? ? ? ? np.random.seed(10101)? # Fixed seed for consistent colors across runs.
? ? ? ? np.random.shuffle(self.colors)? # Shuffle colors to decorrelate adjacent classes.
? ? ? ? np.random.seed(None)? # Reset seed to default.
? ? ? ? # Generate output tensor targets for filtered bounding boxes.
? ? ? ? self.input_image_shape = K.placeholder(shape=(2, ))
? ? ? ? if self.gpu_num>=2:
? ? ? ? ? ? self.yolo_model = multi_gpu_model(self.yolo_model, gpus=self.gpu_num)
? ? ? ? boxes, scores, classes = yolo_eval(self.yolo_model.output, self.anchors,
? ? ? ? ? ? ? ? len(self.class_names), self.input_image_shape,
? ? ? ? ? ? ? ? score_threshold=self.score, iou_threshold=self.iou)
? ? ? ? return boxes, scores, classes
? ? def detect_image(self, paths):
? ? ? ? predictions_list = []
? ? ? ? t = time.time()
? ? ? ? start_run = int(round(t*1000))
? ? ? ? classes = []
? ? ? ? for path in paths:
? ? ? ? ? ? bytes_io_obj = BytesIO()
? ? ? ? ? ? bytes_io_obj.write(requests.get(path).content)
? ? ? ? ? ? image = Image.open(bytes_io_obj)
? ? ? ? ? ? if self.model_image_size != (None, None):
? ? ? ? ? ? ? ? assert self.model_image_size[0]%32 == 0, 'Multiples of 32 required'
? ? ? ? ? ? ? ? assert self.model_image_size[1]%32 == 0, 'Multiples of 32 required'
? ? ? ? ? ? ? ? boxed_image = letterbox_image(image, tuple(reversed(self.model_image_size)))
? ? ? ? ? ? else:
? ? ? ? ? ? ? ? new_image_size = (image.width - (image.width % 32),
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? image.height - (image.height % 32))
? ? ? ? ? ? ? ? boxed_image = letterbox_image(image, new_image_size)
? ? ? ? ? ? image_data = np.array(boxed_image, dtype='float32')
? ? ? ? ? ? image_data /= 255.
? ? ? ? ? ? image_data = np.expand_dims(image_data, 0)? # Add batch dimension.
? ? ? ? ? ? out_boxes, out_scores, out_classes = self.sess.run(
? ? ? ? ? ? ? ? [self.boxes, self.scores, self.classes],
? ? ? ? ? ? ? ? feed_dict={
? ? ? ? ? ? ? ? ? ? self.yolo_model.input: image_data,
? ? ? ? ? ? ? ? ? ? self.input_image_shape: [image.size[1], image.size[0]],
? ? ? ? ? ? ? ? ? ? # K.learning_phase(): 0
? ? ? ? ? ? ? ? })
? ? ? ? ? ? for i, c in reversed(list(enumerate(out_classes))):
? ? ? ? ? ? ? ? box = out_boxes[i]
? ? ? ? ? ? ? ? score = out_scores[i]
? ? ? ? ? ? ? ? top, left, bottom, right = box
? ? ? ? ? ? ? ? top = max(0, np.floor(top + 0.5).astype('int32'))
? ? ? ? ? ? ? ? left = max(0, np.floor(left + 0.5).astype('int32'))
? ? ? ? ? ? ? ? bottom = min(image.size[1], np.floor(bottom + 0.5).astype('int32'))
? ? ? ? ? ? ? ? right = min(image.size[0], np.floor(right + 0.5).astype('int32'))
? ? ? ? ? ? ? ? classes.append({"prob": float('%.7f' % score), "cat": str(c), "bbox": {"ymax": int(bottom), "xmax": int(right), "ymin": int(top), "xmin":int(left) }})
? ? ? ? ? ? predict_dict = {"classes":classes, "uri":path}
? ? ? ? ? ? predictions_list.append(predict_dict)
? ? ? ? t = time.time()
? ? ? ? end_run = int(round(t * 1000))
? ? ? ? result = {"status": {"code": 200,"msg": "OK"},"head": {"method": "/predict","service": "xuehua_service","time": str(end_run - start_run)},"body": {"predictions": predictions_list}}
? ? ? ? return result
? ? def close_session(self):
? ? ? ? self.sess.close()
```
8.flask框架代碼
```
from flask import Flask, request, Response
from keras_yolo.yolo import YOLO
from keras_yolo.yolo_didui import YOLO_DIDUI
import json
app = Flask(__name__)
yolo_huojia = YOLO()
yolo_didui = YOLO_DIDUI()
@app.route('/', methods=["GET", "POST"])
def predict():
? ? b = ''
? ? global yolo_huojia, yolo_didui
? ? params = json.loads(request.get_data())
? ? paths = params['data']
? ? model_type = params['model_type']
? ? if 0 == model_type:
? ? ? ? b = yolo_huojia.detect_image(paths=paths)
? ? if 1 == model_type:
? ? ? ? b = yolo_didui.detect_image(paths=paths)
? ? return Response(json.dumps(b), mimetype='application/json')
if __name__ == '__main__':
? ? app.run(processes=1, threaded=True)
```