LoginSignup
9
4

More than 5 years have passed since last update.

CPU単体で無理やり RealTime Semantic Segmentaion 【その1】 [1 FPS / CPU only]

Last updated at Posted at 2018-12-01

OpenVINO-ADAS GitHub stars3
OpenVINO-DeeplabV3 GitHub stars3

◆ 前回記事

LattePanda Alpha 864 (OS付属無し) にUbuntu16.04+OpenVINOを導入してNeural Compute Stick(NCS1) と Neural Compute Stick 2(NCS2) で爆速Semantic Segmentationを楽しむ

◆ はじめに

あけおめ。。。あ、間違えた。まだ12月1日だ。
今回は超絶ラフにいく。
1分で読み終える記事を目指す。

前回、OpenVINOの導入と各種モデルのコンバートと静止画ベースのデモプログラムの実装を行った。
Neural Compute Stick 2 のゴミクズ加減に打ちひしがれている。
さて、今回は USB Camera あるいは 動画ファイル によるリアルタイムセグメンテーションを実装する。
OpenVINOの概要や各種キッティングの手順、性能評価の結果(国外エンジニアとの協力調査) は 前回記事 に記載しているため、そちらを参照願う。

この記事の実装を行うと、シングルボードコンピュータのCPU単体 で、下図のようなスピードでリアルタイムにセグメンテーションできる。
Intel Neural Compute Stick も GPU のどちらも使用せずに CPU単体 でセグメンテーションする男気実装
↓ 画像をクリックすると Youtube で再生できる。
sample.gif
個人的な感覚では、今までの常識を覆すスピードと精度。 mp4の動画ファイルで試行した。

◆ 環境

  • LattePanda Alpha (Intel 7th Core m3-7y30)
  • Ubuntu 16.04 x86_64
  • OpenVINO toolkit 2018 R4 (2018.4.420)
  • Python 3.5
  • OpenCV 3.4.3
  • PIL

◆ 実装

コメント部を切り替えることで、 推論デバイスを CPU GPU NCS1/NCS2 から選択可能。
Github - OpenVINO-ADAS - PINTO0309 で、OpenVINO本体以外のリソース一式を調達可能な状態にしておいた。
CPU用カーネル拡張ライブラリを取り込まないと正常に動作しない、が、 ".so"ファイル の取り込み動作そのものはロジック中に実装してあるため、気にする必要は無い。

CPU単体のリアルタイムセグメンテーションの実装
#!/usr/bin/env python

import sys
import cv2
import numpy as np
from PIL import Image
import time
from openvino.inference_engine import IENetwork, IEPlugin

model_xml='lrmodels/FP32/semantic-segmentation-adas-0001.xml'
model_bin='lrmodels/FP32/semantic-segmentation-adas-0001.bin'
net = IENetwork.from_ir(model=model_xml, weights=model_bin)
seg_image = Image.open("data/input/009649.png")
palette = seg_image.getpalette() # Get a color palette
camera_width = 320
camera_height = 240
fps = ""
framepos = 0
frame_count = 0
vidfps = 0
elapsedTime = 0

#plugin = IEPlugin(device="HETERO:MYRIAD,CPU")
#plugin.set_config({"TARGET_FALLBACK": "HETERO:MYRIAD,CPU"})
#plugin.set_initial_affinity(net)

#plugin = IEPlugin(device="MYRIAD")
#plugin = IEPlugin(device="GPU")
plugin = IEPlugin(device="CPU")

plugin.add_cpu_extension("lib/libcpu_extension.so")
exec_net = plugin.load(network=net)

input_blob = next(iter(net.inputs))  #input_blob = "data"
out_blob   = next(iter(net.outputs)) #out_blob   = "argmax"
print("input_blob =", input_blob)
print("out_blob =", out_blob)
n, c, h, w = net.inputs[input_blob].shape  #n, c, h, w = 1, 3, 1024, 2048

del net

#cap = cv2.VideoCapture(0)
#cap.set(cv2.CAP_PROP_FPS, 10)
#cap.set(cv2.CAP_PROP_FRAME_WIDTH, camera_width)
#cap.set(cv2.CAP_PROP_FRAME_HEIGHT, camera_height)

cap = cv2.VideoCapture("data/input/testvideo.mp4")
camera_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
camera_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
frame_count = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
vidfps = int(cap.get(cv2.CAP_PROP_FPS))
print("videosFrameCount =", str(frame_count))
print("videosFPS =", str(vidfps))

time.sleep(1)

while cap.isOpened():
    t1 = time.time()
    cap.set(cv2.CAP_PROP_POS_FRAMES, framepos)
    ret, frame = cap.read()
    if not ret:
        break
    #frame = cv2.imread('data/input/000003.jpg')
    prepimg = frame[:, :, ::-1].copy()
    prepimg = Image.fromarray(prepimg)
    prepimg = prepimg.resize((2048, 1024), Image.ANTIALIAS)
    prepimg = np.asarray(prepimg)
    prepimg = prepimg.transpose((2, 0, 1)).reshape((1, c, h, w))

    t2 = time.perf_counter()
    exec_net.start_async(request_id=0, inputs={input_blob: prepimg})

    if exec_net.requests[0].wait(-1) == 0:
        outputs = exec_net.requests[0].outputs[out_blob] # (1, 1, 1024, 2048)
        print("SegmentationTime = {:.7f}".format(time.perf_counter() - t2))
        outputs = outputs[0][0]
        print(outputs.shape)
        outputs = cv2.resize(outputs, (camera_width, camera_height))

        # View
        image = Image.fromarray(np.uint8(outputs), mode="P")
        image.putpalette(palette)
        image = image.convert("RGB")

        image = np.asarray(image)
        image = cv2.addWeighted(frame, 1, image, 0.9, 0)

    cv2.putText(image, fps, (camera_width-180,15), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (38,0,255), 1, cv2.LINE_AA)
    cv2.imshow("Result", image)

    if cv2.waitKey(1)&0xFF == ord('q'):
        break
    elapsedTime = time.time() - t1
    fps = "(Playback) {:.1f} FPS".format(1/elapsedTime)
    framepos += vidfps

cv2.destroyAllWindows()
del exec_net
del plugin

たったのこれだけ。
え? 雑過ぎる?
いいんですよ。 見る人いないから。
しょーもないネタなので、日本人技術者全体の 0.01% ぐらいの心に刺さればいいかな。
しかし。。。モデルの入力解像度、本当は縦横共に4分の1にしたい。
ということで、モデルの改造ができないか、を引き続き検証する。

◆ 次回記事

CPU単体で無理やり RealTime Semantic Segmentaion 【その2】 [4-5 FPS / CPU only] DeeplabV3+MobilenetV2

9
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
4