<jupyter_start><jupyter_text>OpenVINOを使った物体検出プログラムの基礎を学ぶOpenVINOを使うと物体検出(object detection)プログラムも簡単に作ることができます。  ここではSSD(Single Shot multi-box Detection)モデルを使った物探検出プログラムの基礎を学びます。  必要なPythonモジュールをインストールするこのコースでは`matplotlib`を使って画像表示を行うので、モジュールをインストールしておきます。<jupyter_code># Linux
!pip3 install matplotlib
# Windows
!pip install matplotlib<jupyter_output><empty_output><jupyter_text>入力画像とラベルデータの準備まずは推論に使用する入力画像ファイルと、クラスラベルのテキストファイルをOpenVINOのdemoディレクトリからコピーしてきます。<jupyter_code># Linux
!cp $INTEL_OPENVINO_DIR/deployment_tools/demo/car_1.bmp .
!cp $INTEL_OPENVINO_DIR/deployment_tools/open_model_zoo/data/dataset_classes/voc_20cl_bkgr.txt .
# Windows 
!copy "%INTEL_OPENVINO_DIR%\deployment_tools\demo\car_1.bmp" .
!copy "%INTEL_OPENVINO_DIR%\deployment_tools\open_model_zoo\data\dataset_classes\voc_20cl_bkgr.txt" .<jupyter_output><empty_output><jupyter_text>コピーしてきた推論入力の絵を表示して確認します。  **Note:** `IPython.display.Image`ではBMPファイルの表示ができないので、ここでは`OpenCV`と`matplotlib`を使用しています。<jupyter_code>%matplotlib inline
import cv2
import matplotlib.pyplot as plt
img=cv2.imread('car_1.bmp')
img=cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
plt.imshow(img)
plt.show()<jupyter_output><empty_output><jupyter_text>推論に使用するIRモデルデータの準備推論に使用するモデルを`Model downloader`でダウンロードし、`Model converter`でIRモデルに変換します。  モデルは軽量な`mobilenet-ssd`モデルを使用します。<jupyter_code># Linux
!python3 $INTEL_OPENVINO_DIR/deployment_tools/open_model_zoo/tools/downloader/downloader.py --name mobilenet-ssd
!python3 $INTEL_OPENVINO_DIR/deployment_tools/open_model_zoo/tools/downloader/converter.py  --name mobilenet-ssd --precisions FP16
!ls public/mobilenet-ssd/FP16 -l
# Windows
!python "%INTEL_OPENVINO_DIR%\deployment_tools\open_model_zoo\tools\downloader\downloader.py" --name mobilenet-ssd
!python "%INTEL_OPENVINO_DIR%\deployment_tools\open_model_zoo\tools\downloader\converter.py"  --name mobilenet-ssd --precisions FP16
!dir public\mobilenet-ssd\FP16<jupyter_output><empty_output><jupyter_text>----ここからPythonプログラム本体となります。    プログラムで使用するモジュールをインポートする<jupyter_code>import cv2
import numpy as np
from openvino.inference_engine import IECore<jupyter_output><empty_output><jupyter_text>クラスラベルテキストデータを読み込む<jupyter_code>label = [ s.replace('\n', '') for s in open('voc_20cl_bkgr.txt').readlines() ]

print(len(label), 'labels read')   # 読み込んだラベルの個数を表示
print(label)                       # ラベルを表示<jupyter_output><empty_output><jupyter_text>Inference Engineオブジェクトを生成する- Inference Engineコアオブジェクトを生成- モデルデータの読み込み- 入出力ブロブ(バッファ)の情報取得<jupyter_code># Inference Engineコアオブジェクトの生成
ie = IECore()

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

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

# モデルの情報の表示
print(input_blob_name, batch, channel, height, width)
print(output_blob_name, net.outputs[output_blob_name].shape)<jupyter_output><empty_output><jupyter_text>モデルをIE coreオブジェクトにロードする読み込んだネットワークオブジェクトをInference engineプラグインにセットします。<jupyter_code>exec_net = ie.load_network(network=net, device_name='CPU', num_requests=1)<jupyter_output><empty_output><jupyter_text>推論入力データを準備する推論入力画像を読み込み、入力ブロブのシェイプに合わせて変形します。<jupyter_code>print('input blob: name="{}", N={}, C={}, H={}, W={}'.format(input_blob_name, batch, channel, height, width))
img    = cv2.imread('car_1.bmp')
in_img = cv2.resize(img, (width,height))
in_img = in_img.transpose((2, 0, 1))
in_img = in_img.reshape((1, channel, height, width))

print(in_img.shape)<jupyter_output><empty_output><jupyter_text>推論を実行する`infer()` APIはブロッキング関数です。推論が終了すると制御が戻り、次の行を実行します。  入力は`{入力blob名:入力データ}`の辞書の形で渡します。**ここまでのコードは画像分類(classification)の時と変わっていません(モデル、ラベル、入力画像ファイル名だけが違う)。OpenVINOでの推論プログラムはモデルに応じた結果の処理部分以外は共通で使える部分が多いのも特徴です**<jupyter_code>res = exec_net.infer(inputs={input_blob_name: in_img})

print(res[output_blob_name].shape)<jupyter_output><empty_output><jupyter_text>推論結果を表示する  今回使用しているmobilenet-ssdモデル100のオブジェクト候補を出力し、各オブジェクトごとに7つのデータを出力します(シェイプが[1,1,100,7])。  各オブジェクト毎のデータは[`id`, `class`, `confidence`, `xmin`, `ymin`, `xmax`, `ymax`]の７つのパラメータが出てきます。  classはクラス番号を、confidenceは「そのクラスらしさ」を0.0-1.0 (1.0=100%)で表します。(`xmin`,`ymin`)-(`xmax`,`ymax`)がオブジェクトを囲む箱(bounding box)の座標を示します。bounding boxの座標も0.0-1.0で出力され、画像の左上が(0.0, 0.0)、画像の右下が(1.0, 1.0)となるので画像のピクセル数を掛けて座標値に変換し、黄色の箱とラベル名を描画しています。  最後に`matplotlib`を使用して画像を表示させています。<jupyter_code>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)
        cv2.rectangle(img, (x1, y1), (x2, y2), (0,255,255), thickness=4 )
        cv2.putText(img, label[int(clsid)], (x1, y1), cv2.FONT_HERSHEY_PLAIN, fontScale=4, color=(0,255,255), thickness=4)

%matplotlib inline
import matplotlib.pyplot as plt
img=cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
plt.imshow(img)
plt.show()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.13379737045630316, 'fraction_numerical': 0.022235112142304718, 'mean_word_length': 8.834600760456274, 'pattern_counts': {'":': 0, '<': 45, '<?xml version=': 0, '>': 46, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 1}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 7, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '11', 'dir': 'jupyter-structured-clean-dedup', 'id': '127147', 'license': 'Apache-2.0', 'n_tokens_mistral': 2793, 'n_tokens_neox': 2692, 'n_words': 231, 'path': 'object-detection-ssd.ipynb', 'repo_name': 'yas-sim/openvino-workshop-jp', 'size': '5172'}