みらいテックラボ

音声・画像認識や機械学習など, 週末プログラマである管理人が興味のある技術の紹介や実際にトライしてみた様子などメモしていく.

YOLOv3で金魚検出サーバ...

CODE for YAMATOKORIYAMAの取組みの一環として, 「Kingyo AI Navi」[1]なる金魚の種類識別を活用したアプリのプロト開発を行っている.
現在は, Cloud AutoML Visionを使って種類識別を行っているのだが, 水槽の中の泳いでいる金魚1匹に注目して, その1匹だけが写った写真を撮るのは結構難しい.
そこで, 前回[2]複数の金魚が写った写真でもいけるようにするために, Cloud AutoML Vision Object Detectionを少し試してみた.
しかし, 運用するには結構費用がかかりそうだったので, 今回はYOLOv3を使って金魚の検出サーバを作ってみることに...


1. サーバ側
サーバ側は, Python + Flask + YOLOv3で作成することにした.
PythonからのYOLOv3読み出しについては, こちらの記事[3]を参照.
ちなみに, YOLOv3の金魚検出モデルは, 前回と同じ学習データを用いて学習したものを用いた.

[コード]

import numpy as np
import io
from PIL import Image
from flask import Flask, request, jsonify

import darknet as dn

app = Flask(__name__)

def load_model():
    global net, meta
    net = dn.load_net(b'./cfg/yolov3-tiny-goldfish.cfg', b'./weights/yolov3-tiny-goldfish_500000.weights', 0)
    meta = dn.load_meta(b'./cfg/goldfish.data')
    print('Model loading completed.')

def set_results(res, shape):
    data = []
    for r in res:
        x, y, w, h = r[2]
        left = max(0, round(x - w/2))
        top = max(0, round(y - h/2))
        right = min(shape[1], round(x + w/2))
        bottom = min(shape[0], round(y + h/2))
        bbox = {'left' : left, 'top' : top, 'right' : right, 'bottom': bottom}
        data.append({'label': r[0], 'score': r[1], 'bbox': bbox})

    print(data)
    return data

@app.route('/predict', methods=['POST'])
def predict():
    data = {'Success': False}
    print(request.files)
    if request.method == 'POST' and request.files.get('image'):
        # 画像データ読み込み
        image = request.files['image'].read()
        image = Image.open(io.BytesIO(image))
        image = np.asarray(image)
        # YOLOv3処理
        res = dn.detect_cvimage(net, meta, image)
        data['predictions'] = set_results(res, image.shape)
        data['Success'] = True
        print(data)
    else:
        print("param error")
    return jsonify(data)

if __name__ == '__main__':
    load_model()
    app.run(use_reloader=False, debug=True, port=5000)


2. 動作検証
クライアント側のテストコードを作成し, 金魚の検出をやってみる.

(1) 東錦
検出位置は少しずれているが, 一応東錦を検出.
f:id:moonlight-aska:20191012085234p:plain

(2) 水泡眼と頂点眼
まったく検出できず.
(Cloud AutoML Vision Object Detectionでは, 頂点眼は検出&識別OKだったのだが...)
f:id:moonlight-aska:20191012085417p:plain

他の画像もいろいろ試してみたが, 学習データ以外のデータについては正しく検出&識別できるものが少なかった.
学習データが増えてくるとある程度使えるかもしれないが, 現状は学習データ不足の感はいなめない.
そう考えると, 前回Cloud AutoML Vision Object Detectionでは同じ程度の学習データで, もっと検出&識別できていたのだから, やっぱりCloud AutoML Vision Object Detectionの学習ってすごいって感じですね.

----
参照URL:
[1] 「Kingyo AI Navi」のアプリ化を考える (1)~(4)
[2] Cloud AutoML Vision Object Detectionを試してみる
[3] Jetson NanoでIntel RealSenseを試してみる(3)