AIコラムー第7回 (OpenVINO第2回)
OpenVINO上でのアプリケーション開発の方法を学ぶ

OpenVINOのコラム、第2回は実際にアプリケーション開発を行い、自作のアプリケーション開発を行うところまで行いたいと思います。

今回作成するアプリケーションは、Open Model Zoo から学習済みの物体検知モデルを使って、人を検知した時は赤色の枠、車を検知したときは黄色の枠で囲うアプリを作成します。
本コラムを読めば、OpenVINOで使用可能な任意の学習済み物体検知モデルを使用したアプリケーションの作成ができるようになります。

※ アプリケーション開発の手順は以下を参考にしました。
https://github.com/yas-sim/openvino-workshop-jp/blob/master/object-detection-ssd.ipynb

事前準備

開発を行う環境は、前回コラムで環境構築を行ったマシンを使用します。
環境構築を行っていない場合は、前回コラムの「OpenVINOのインストール」の章を参照ください。

■開発を行うマシンの構成
OS : Ubuntu 18.04.1 LTS 64bit
CPU : AVX2搭載のIntel® Core™ Processor
※ 前回コラムで「OpenVINOのインストール」の章の手順を実施していることが前提になります。

アプリケーションの開発は Jupyter Notebook 上で行います。以下のコマンドで必要なパッケージをインストールしてください。

> sudo apt install jupyter-notebook
> pip3 install matplotlib

また、開発を行う前にOpenVINOの環境変数の設定を行う必要があります。以下のコマンドで設定を行ってください。

> source /opt/intel/openvino/bin/setupvars.sh

最後に、今回の作業ディレクトリを作成します。ホームフォルダの直下にwork ディレクトリを作成します。

> mkdir ~/work
> cd ~/work

自作アプリケーションの開発 (モデルの用意)

まずは今回使用するモデルをダウンロードします。
Open Model Zooと呼ばれる学習済みモデルファイルのアーカイブから、簡単にモデルをダウンロードして使用する機能が備わっています。
では実際に、モデルをダウンロードしてみましょう。以下のコマンドを使用して、mobilenet-ssd をダウンロードしてください。

> python3 $INTEL_OPENVINO_DIR/deployment_tools/tools/model_downloader/downloader.py –name mobilenet-ssd

※ INTEL_OPENVINO_DIR変数は「事前準備」でOpenVINOの環境変数設定を行った際に設定されるものです。
この変数にはOpenVINOがインストールされているディレクトリパスが格納されています。

ダウンロードされたモデルは、./public/mobilenet-ssd/ ディレクトリ配下に格納されます。

> ls ./public/mobilenet-ssd/*
mobilenet-ssd.caffemodel mobilenet-ssd.prototxt

続いて、ダウンロードしたモデルをOpenVINOの推論エンジンで使用する IRフォーマットに変換します。

> python3 $INTEL_OPENVINO_DIR/deployment_tools/tools/model_downloader/converter.py –name mobilenet-ssd –precisions FP32

引数に指定した –precisions FP32 は、変換するモデルの精度を指定しています。(–precisions を付けなかった場合は、生成可能な精度で全て変換します)

IRフォーマットに変換されたモデルは、./public/mobilenet-ssd/FP32/ ディレクトリ配下に格納されます。

> ls ./public/mobilenet-ssd/FP32/*
mobilenet-ssd.bin mobilenet-ssd.mapping mobilenet-ssd.xml

補足:
OpenVINO に付属の Model Downloader を使用して、Open Model Zoo から好きなモデルをダウンロードすることができます。ダウンロード可能なモデル一覧は以下のコマンドを実行することで確認できます。

> python3 $INTEL_OPENVINO_DIR/deployment_tools/tools/model_downloader/downloader.py –print_all

また、各モデルの詳細情報は、以下のURLから参照することもできます。
https://github.com/opencv/open_model_zoo/tree/master/models

例) 今回のアプリケーション開発で使用する mobilenet-ssd モデル
https://github.com/opencv/open_model_zoo/blob/master/models/public/mobilenet-ssd/mobilenet-ssd.md

最後にモデルが学習しているラベルファイルを用意します。mobilenet-ssdの出力は、オブジェクトの矩形情報と、そのオブジェクトが何のクラスなのかを示すインデックスになります。モデルの出力結果を人間が分かるクラス名と紐づけるために、ラベルファイルを用意します。
今回使用するmobilenet-ssd は VOC データセットで学習された物体検知のモデルになります。バックグラウンド(1クラス) + VOCのクラス(20クラス)の合計21クラスで学習されていますが、今回は、OpenVINOにあらかじめインストールされており、そのまま使えるラベルファイルをコピーして使用します。

> cp $INTEL_OPENVINO_DIR/deployment_tools/open_model_zoo/demos/python_demos/voc_labels.txt .

※ voc_labels.txtは、以下のようにインデックス順にクラス名を列挙したテキストファイルになります。
例) voc_labels.txt の内容

> ubuntu@ubuntu-X299-UD4:~/work$ cat voc_labels.txt
background
aeroplane
bicycle
bird
boat
bottle
bus
car
cat
chair
cow
diningtable
dog
horse
motorbike
person
pottedplant
sheep
sofa
train

※ mobilenet-ssd以外のモデルを利用する場合、インデックスとクラス名の対応は、前述のモデルのURLのページに書かれているものや、URLのページから飛べるリンク先に情報が書かれています。

ここまでの手順をまとめると、
① downloader.pyを使用して、Open Model Zoo からモデルをダウンロード
② converter.pyを使用して、モデルをIRフォーマットに変換
③ ラベルファイルを用意する

以上の3ステップで、モデルの用意は完了です。とても簡単にモデルの用意が完了します。

次は、用意したモデルを使って推論を行うコードを書いていきましょう

自作アプリケーション開発 (ソースコード)

ソースコードはJupyter-notebookを使用して書いていきます。以下のコマンドを使用して、Jupyter-notebookを起動させてください。

> jupyter-notebook .
>

以下の画面のように、ブラウザが起動します。

次に新規ファイルを作成します。以下の画面のように右側の「New」ボタンから「Python3」を選択してください。

ソースコードは以下のようになります。
最初に必要なパッケージを読み込みます。

%matplotlib inline
import cv2
import matplotlib.pyplot as plt
import numpy as np      
from openvino.inference_engine import IECore

今回使用するモデルのラベルファイルを読み込みます。

label = open('voc_labels.txt').readlines()
print(label)

次に、OpenVINOの推論エンジンのオブジェクトを生成します。

※ 該当のAPIドキュメントは以下になります。
https://docs.openvinotoolkit.org/latest/ie_python_api/classie__api_1_1IECore.html

OpenVINOによって最適化されたモデルを読み込むために、Inference Engineコアオブジェクトの read_network() を利用して、.xmlファイルと.binファイルを読み込みます。
第一引数のmodelに指定したxmlファイルは、モデル定義のファイルで、第二引数のweightsに指定した bin ファイルは、モデルの重みファイルになります。これらは、converter.pyを使用し変換したIRフォーマット変換済みのファイルになります。

# Inference Engineコアオブジェクトの生成
ie = IECore()

# IRモデルファイルの読み込み
model = './public/mobilenet-ssd/FP32/mobilenet-ssd'
net = ie.read_network(model=model+'.xml', weights=model+'.bin')

# 入出力blobの名前の取得、入力blobのシェイプの取得
input_blob_name  = list(net.inputs.keys())[0]
output_blob_name = list(net.outputs.keys())[0]
batch,channel,height,width = net.inputs[input_blob_name].shape

次に、各デバイスに最適化された推論用のインスタンスを作成するためにload_network() を呼び出します。
このとき、第二引数のdevice_nameにはターゲットデバイス(※ OpenVINO第1回コラムのサポートするデバイスの表を参照ください) を指定します。今回は CPU が実行環境なので、device_name には CPU を指定しています。

exec_net = ie.load_network(network=net, device_name='CPU', num_requests=1)

推論用のインスタンスが生成できたら、これを使用して推論を行います。推論用のインスタンスに入力する際は、入力をモデルのサイズに合わせる必要がありますので、今回は300×300にリサイズしなければなりません。モデルのサイズは、前述のコードで取得したwidth、heightのサイズにリサイズし、以下コードの7行目でリサイズした画像を推論用のインスタンスの引数としています。

def infer(path):
    print('input blob: name="{}", N={}, C={}, H={}, W={}'.format(input_blob_name, batch, channel, height, width))
    img    = cv2.imread(path)
    in_img = cv2.resize(img, (width,height))
    in_img = in_img.transpose((2, 0, 1))
    in_img = in_img.reshape((1, channel, height, width))
    return img, exec_net.infer(inputs={input_blob_name: in_img})

最後に、推論した結果を表示させるコードです。
推論結果によって枠線の色を変えるために、以下コードの14行目では、推論結果のクラス(clsid)が、”car” または “person” で条件分岐させています。“car” の場合は黄色の枠、”person” の場合は赤色の枠を表示させます。

def show(img, res):
    print('output blob: name="{}", shape={}'.format(output_blob_name, net.outputs[output_blob_name].shape))
    result = res[output_blob_name][0][0]
    img_h, img_w, _ = img.shape
    for obj in result:
        imgid, clsid, confidence, x1, y1, x2, y2 = obj
        if confidence>0.6:
            x1 = int(x1 * img_w)
            y1 = int(y1 * img_h)
            x2 = int(x2 * img_w)
            y2 = int(y2 * img_h)

            color = (0,255,0)
            if label[int(clsid)][:-1] == 'car':
                color = (0,255,255)
            elif label[int(clsid)][:-1] == 'person':
                color = (0,0,255)
        
            cv2.rectangle(img, (x1, y1), (x2, y2), color, thickness=4 )
            cv2.putText(img, label[int(clsid)][:-1], (x1, y1), cv2.FONT_HERSHEY_PLAIN, fontScale=4, color=color, thickness=4)

    %matplotlib inline
    import matplotlib.pyplot as plt
    img=cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    plt.imshow(img)
    plt.show()

最後に、上記のコードを実行した結果を載せます。

img, res = infer('car.PNG')
show(img, res)

input blob: name=”data”, N=1, C=3, H=300, W=300
output blob: name=”detection_out”, shape=[1, 1, 100, 7]

img, res = infer('person.JPG')
show(img, res)

input blob: name=”data”, N=1, C=3, H=300, W=300
output blob: name=”detection_out”, shape=[1, 1, 100, 7]

以上のように、OpenVINOでは、Open Model Zooと呼ばれるモデルファイルのアーカイブの中から、モデルファイルをダウンロードし、簡単に利用できるようになっています(※ Open Model Zoo 以外の学習済みモデルを使用する選択肢もあります)。

また、OpenVINOのモデルの読み込みや推論の処理も簡単に書くことができるため、効率的なアプリケーション開発を行うことができます。

次回は、クラウドサービス「Intel DevCloud for the Edge」について、ご紹介したいと思います。

カテゴリ一覧

お問い合わせ

名古屋本社

東京本社

【受付時間】9:00~18:00

pagetop