Vaizdo įrašas apie debesies objektų detektorių Raspberry Pi

Prologas

По сети сейчас гуляет видео — как автопилот Теслы видит дорогу.

У меня давно чесались руки транслировать видео, обогащенное детектором, да и в реальном времени.

Vaizdo įrašas apie debesies objektų detektorių Raspberry Pi

Проблема в том, что транслировать видео я хочу с Raspberry, а производительность нейросетевого детектора на ней оставляет желать лучшего.

„Intel Neural Computer Stick“.

Svarsčiau įvairius sprendimus.

В paskutinis straipsnis eksperimentavo su Intel Neural Computer Stick. Techninė įranga yra galinga, tačiau jai reikalingas atskiras tinklo formatas.

Nors „Intel“ teikia keitiklius pagrindinėms sistemoms, yra keletas spąstų.

Pavyzdžiui, reikiamo tinklo formatas gali būti nesuderinamas, o jei jis suderinamas, kai kurie sluoksniai gali būti nepalaikomi įrenginyje, o jei jie palaikomi, konversijos proceso metu gali atsirasti klaidų, dėl kurių išvestyje gauname keistų dalykų.

В общем, если хочется какую-то произвольную нейросеть, то с NCS может не получиться. Поэтому, я решил попробовать решить проблему через самые массовые и доступные инструменты.

Debesis

Akivaizdi alternatyva vietiniam aparatūros sprendimui yra pereiti prie debesies.

Готовых вариантов — глаза разбегаются.

Visi lyderiai:

… И десятки менее известных.

Išsirinkti iš šios veislės nėra lengva.

Ir nusprendžiau ne rinktis, o suvynioti seną gerą OpenCV darbo schemą į Docker ir paleisti ją debesyje.

Šio požiūrio privalumas yra lankstumas ir valdymas – galite keisti neuroninį tinklą, prieglobą, serverį – apskritai, bet kokią užgaidą.

Serveris

Pradėkime nuo vietinio prototipo.

Tradiciškai naudoju Flask REST API, OpenCV ir MobileSSD tinklui.

Įdiegęs dabartines „Docker“ versijas, sužinojau, kad „OpenCV 4.1.2“ neveikia su „Mobile SSD v1_coco_2018_01_28“, todėl turėjau grįžti į patikrintą 11-06-2017.

Paslaugos pradžioje įkeliame klasių pavadinimus ir tinklą:

def init():
    tf_labels.initLabels(dnn_conf.DNN_LABELS_PATH)
    return cv.dnn.readNetFromTensorflow(dnn_conf.DNN_PATH, dnn_conf.DNN_TXT_PATH)

На локальном докере (на не самом молодом лаптопе) это занимает 0.3 секунды, на Raspberry — 3.5.

Pradėkime skaičiavimą:

def inference(img):
    net.setInput(cv.dnn.blobFromImage(img, 1.0/127.5, (300, 300), (127.5, 127.5, 127.5), swapRB=True, crop=False))
    return net.forward()

Dokeris – 0.2 sek., Avietė – 1.7.

Tenzoriaus išmetimo pavertimas skaitomu JSON:

def build_detection(data, thr, rows, cols):
    ret = []
    for detection in data[0,0,:,:]:
        score = float(detection[2])
        if score > thr:
            cls = int(detection[1])
            a = {"class" : cls, "name" : tf_labels.getLabel(cls),  "score" : score}
            a["x"] = int(detection[3] * cols)
            a["y"] = int(detection[4] * rows)
            a["w"] = int(detection[5] * cols ) - a["x"]
            a["h"] = int(detection[6] * rows) - a["y"]
            ret.append(a)
    return ret

Toliau eksportuoti šią operaciją per Kolbą(įvestis yra paveikslėlis, išvestis yra detektoriaus rezultatai JSON).

Alternatyvus variantas, kai daugiau darbo perkeliama į serverį: jis pats apkelia rastus objektus ir grąžina baigtą vaizdą.

Ši parinktis yra gera, kai nenorime vilkti opencv į serverį.

Dokeris

Mes renkame vaizdą.

Kodas sušukuojamas ir paskelbiamas Github, dokeris paims jį tiesiai iš ten.

Kaip platformą naudosime tą pačią Debian Stretch kaip ir Raspberry – nenukrypsime nuo patikrintų technologijų paketo.

Turite įdiegti kolbą, protobufą, užklausas, opencv_python, atsisiųsti Mobile SSD, serverio kodą iš Github ir paleisti serverį.

FROM python:3.7-stretch

RUN pip3 install flask
RUN pip3 install protobuf
RUN pip3 install requests
RUN pip3 install opencv_python

ADD http://download.tensorflow.org/models/object_detection/ssd_mobilenet_v1_coco_11_06_2017.tar.gz /
RUN tar -xvf /ssd_mobilenet_v1_coco_11_06_2017.tar.gz

ADD https://github.com/tprlab/docker-detect/archive/master.zip /
RUN unzip /master.zip

EXPOSE 80

CMD ["python3", "/docker-detect-master/detect-app/app.py"]

Paprastas detektoriaus klientas remiantis prašymais.

Publikuojama Docker Hub

Docker registrai dauginasi ne mažesniu greičiu nei debesų detektoriai.

Kad nesivargintume, pereisime konservatyviai DockerHub.

  1. Registruotis
  2. Prisijungti:
    dokerio prisijungimas
  3. Sugalvokime prasmingą pavadinimą:
    docker tag opencv-detect tprlab/opencv-detect-ssd
  4. Įkelkite paveikslėlį į serverį:
    docker push tprlab/opencv-detect-ssd

Запускаем в облаке

Pasirinkimas, kur paleisti konteinerį, taip pat gana platus.

Visi didieji žaidėjai (Google, Microsoft, Amazon) pirmus metus siūlo mikro egzempliorių nemokamai.
Поэксперементировав с Microsoft Azure и Google Cloud, остановился на последнем — потому, что быстрее взлетело.

Instrukcijų čia nerašiau, nes ši dalis yra labai specifinė pasirinktam teikėjui.

Išbandžiau įvairias aparatūros parinktis,
Низкие уровни (shared и выделенные) — 0.4 — 0.5 секунды.
Galingesni automobiliai – 0.25 – 0.3.
Na, net ir blogiausiu atveju laimėjimas yra tris kartus, galite pabandyti.

video

„Raspberry“ paleidžiame paprastą „OpenCV“ vaizdo transliuotoją, aptinkamą per „Google Cloud“.
Eksperimentui buvo naudojamas vaizdo failas, kuris kadaise buvo nufilmuotas atsitiktinėje sankryžoje.


def handle_frame(frame):
    return detect.detect_draw_img(frame)
       
def generate():
    while True:
        rc, frame = vs.read()
        outFrame = handle_frame(frame)
        if outFrame is None:
            (rc, outFrame) = cv.imencode(".jpg", frame)
        yield(b'--framern' b'Content-Type: image/jpegrnrn' + bytearray(outFrame) + b'rn')

@app.route("/stream")
def video_feed():
    return Response(generate(), mimetype = "multipart/x-mixed-replace; boundary=frame")

Su detektoriumi gauname ne daugiau kaip tris kadrus per sekundę, viskas vyksta labai lėtai.
Jei paimsite galingą mašiną į GCloud, galite aptikti 4-5 kadrus per sekundę, tačiau skirtumas beveik nepastebimas akiai, jis vis tiek lėtas.

Vaizdo įrašas apie debesies objektų detektorių Raspberry Pi

Debesis ir transportavimo išlaidos neturi nieko bendra su tuo, detektorius veikia su įprasta technine įranga ir veikia tokiu greičiu.

Neuroninė kompiuterio lazda

Negalėjau atsispirti ir atlikau etaloną NCS.

Detektoriaus greitis buvo šiek tiek lėtesnis nei 0.1 sekundės, bet kokiu atveju 2-3 kartus greitesnis nei debesis silpnoje mašinoje, t.y. 8-9 kadrai per sekundę.

Vaizdo įrašas apie debesies objektų detektorių Raspberry Pi

Разница в результатах объясняется тем, что на NCS запускался Mobile SSD версии 2018_01_28.

PS Be to, eksperimentai parodė, kad gana galingas stalinis kompiuteris su I7 procesoriumi rodo kiek geresnius rezultatus ir pasirodė, kad jame galima išspausti 10 kadrų per sekundę.

Klasteris

Eksperimentas buvo tęsiamas ir aš įdiegiau detektorių penkiuose „Google Kubernetes“ mazguose.
Patys ankštys buvo silpnos ir kiekviena iš jų negalėjo apdoroti daugiau nei 2 kadrų per sekundę.
Bet jei paleidžiate klasterį su N mazgų ir analizuojate kadrus N gijomis, tada su pakankamu mazgų skaičiumi (5) galite pasiekti norimus 10 kadrų per sekundę.

def generate():
    while True:
        rc, frame = vs.read()
        if frame is not None:
            future = executor.submit(handle_frame, (frame.copy()))
            Q.append(future)

        keep_polling = len(Q) > 0
        while(keep_polling):            
            top = Q[0]
            if top.done():
                outFrame = top.result()
                Q.popleft()
                if outFrame:
                    yield(b'--framern' b'Content-Type: image/jpegrnrn' + bytearray(outFrame) + b'rn')
                keep_polling = len(Q) > 0
            else:
                keep_polling = len(Q) >= M

Štai kas nutiko:

Vaizdo įrašas apie debesies objektų detektorių Raspberry Pi

Šiek tiek lėčiau nei su NCS, bet energingesnis nei viename sraute.

Padidėjimas, žinoma, nėra tiesinis – yra perdangos, skirtos sinchronizuoti ir giliai kopijuoti opencv vaizdus.

išvada

В целом, эксперимент позволяет сделать вывод, что, если постараться, можно выкрутиться с простым облаком.

Tačiau galingas darbalaukis arba vietinė aparatinė įranga leidžia pasiekti geresnių rezultatų ir be jokių gudrybių.

Nuorodos

Šaltinis: www.habr.com

Добавить комментарий