2019-08-09 YOLO算法

**一、用到的工具**

pycharm

postman

flask框架

yaml文件

gunicorn

**二、过程**

1.最开始的时候准备好文件,拷贝到自己的电脑里。

decu文件,下面有一个huojia和一个didui。

在huojia和didui中分别还有五个小文件,

格式是decu_anchors.txt,decu_classes.txt,,cfg , .h5, .weight。

2.分析得到的yolo.py里面的程序,解析每一个变量的数据是什么。

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返回数据,并且取数据中的“data”,也就是图片网址。

4.修改yolo。

主要是后面for循环,取出坐标值。

注意,prob这个值小数点后数值太多,如果不进行修改,那么会报错。

所以写成这个格式

```

"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,在数值部分就修改差不多了。

5.文件的调用。

我们这次在flask框架,调用yolo.py中的YOLO这个类。

所以我们在xuehua_flask.py中,就写

```

from keras_yolo.yolo import YOLO

```

刚开始将yolo_huojia = YOLO()写在了def函数里面,会发现运行的很慢。

所以,我们将这个写在外边。

也就是

```

app = Flask(__name__)

yolo_huojia = YOLO()

yolo_didui = YOLO_DIDUI()

@app.route('/', methods=["GET", "POST"])

def predict():

```

这样。

6.gunicorn的使用。

我们先运用了一个虚拟环境tensorflow,然后在terminal中调用虚拟环境。

```

source activate tensorflow  # 启动虚拟环境

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)

```

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容