Video detektora cloudových objektov na Raspberry Pi

prológ

Na internete teraz koluje video, ktoré ukazuje, ako autopilot Tesly vidí cestu.

Už dlho ma núti vysielať video obohatené o detektor a v reálnom čase.

Video detektora cloudových objektov na Raspberry Pi

Problém je v tom, že chcem vysielať video z Raspberry a výkon detektora neurónovej siete na ňom ponecháva veľa želaní.

Intel Neural Computer Stick

Zvažoval som rôzne riešenia.

В posledný článok experimentoval s Intel Neural Computer Stick. Hardvér je výkonný, ale vyžaduje si vlastný sieťový formát.

Aj keď spoločnosť Intel poskytuje konvertory pre hlavné rámce, existuje niekoľko úskalí.

Napríklad formát požadovanej siete môže byť nekompatibilný, a ak je kompatibilný, niektoré vrstvy nemusia byť na zariadení podporované, a ak sú podporované, môžu sa počas procesu konverzie vyskytnúť chyby, v dôsledku ktorých na výstupe dostaneme nejaké zvláštne veci.

Vo všeobecnosti, ak chcete nejaký druh ľubovoľnej neurónovej siete, potom nemusí fungovať s NCS. Preto som sa rozhodol pokúsiť sa problém vyriešiť pomocou najrozšírenejších a najdostupnejších nástrojov.

mrak

Zjavnou alternatívou k lokálnemu hardvérovému riešeniu je prejsť do cloudu.

Hotové možnosti - oči mi bežia.

Všetci vedúci:

... A desiatky menej známych.

Vybrať si z tejto odrody nie je vôbec jednoduché.

A rozhodol som sa nevybrať, ale zabaliť starú dobrú fungujúcu schému na OpenCV v Dockeri a spustiť ju v cloude.

Výhodou tohto prístupu je flexibilita a kontrola - môžete zmeniť neurónovú sieť, hosting, server - vo všeobecnosti akýkoľvek rozmar.

Server

Začnime s lokálnym prototypom.

Tradične používam Flask pre REST API, OpenCV a MobileSSD sieť.

Po nainštalovaní aktuálnych verzií na Docker som zistil, že OpenCV 4.1.2 nefunguje s Mobile SSD v1_coco_2018_01_28 a musel som sa vrátiť k osvedčenému 11.

Na začiatku služby načítame názvy tried a sieť:

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

Na miestnom doku (na nie príliš mladom notebooku) to trvá 0.3 sekundy, na Raspberry - 3.5.

Začnime s výpočtom:

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()

Docker - 0.2 sekundy, Raspberry - 1.7.

Premena výfuku tenzora na čitateľný 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

ďalej exportovať túto operáciu cez Flask(vstup je obrázok, výstup sú výsledky detektora v json).

Alternatívna možnosť, pri ktorej sa viac práce presúva na server: sám zakrúžkuje nájdené objekty a vráti hotový obrázok.

Táto možnosť je dobrá tam, kde nechceme preťahovať opencv na server.

Docker

Zhromažďujeme obrázok.

Kód je vyčesaný a vyvesený Github, docker to vezme priamo odtiaľ.

Ako platformu použijeme rovnaký Debian Stretch ako na Raspberry – nevybočíme z osvedčeného tech stacku.

Musíte nainštalovať flask, protobuf, requesty, opencv_python, stiahnuť Mobile SSD, kód servera z Github a spustiť 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"]

prostý klient detektora na základe žiadostí.

Publikovanie na Docker Hub

Registre Docker sa množia rýchlosťou nie menšou ako cloudové detektory.

Aby sme sa neobťažovali, konzervatívne prejdeme DockerHub.

  1. Registrovať
  2. Prihlásiť sa:
    prihlásenie do docker
  3. Poďme vymyslieť zmysluplný názov:
    docker tag opencv-detect tprlab/opencv-detect-ssd
  4. Nahrajte obrázok na server:
    docker push tprlab/opencv-detect-ssd

Spúšťame v cloude

Pomerne široký je aj výber, kam nádobu spustiť.

Všetci veľkí hráči (Google, Microsoft, Amazon) ponúkajú na prvý rok mikroinštanciu zadarmo.
Po experimentovaní s Microsoft Azure a Google Cloud som sa rozhodol pre druhý, pretože sa to rozbehlo rýchlejšie.

Návod som tu nenapísal, keďže táto časť je veľmi špecifická pre vybraného poskytovateľa.

Skúšal som rôzne možnosti hardvéru,
Nízke úrovne (zdieľané a vyhradené) - 0.4 - 0.5 sekundy.
Silnejšie autá - 0.25 - 0.3.
No aj v najhoršom prípade sú výhry trojnásobné, môžete skúsiť.

video

Na Raspberry spúšťame jednoduchý streamer videa OpenCV, ktorý zisťujeme prostredníctvom Google Cloud.
Na experiment bol použitý video súbor, ktorý bol raz natočený na náhodnej križovatke.


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")

S detektorom nedostávame viac ako tri snímky za sekundu, všetko ide veľmi pomaly.
Ak do GCloud vezmete výkonný stroj, môžete rozpoznať 4-5 snímok za sekundu, ale rozdiel je takmer neviditeľný pre oči, stále je pomalý.

Video detektora cloudových objektov na Raspberry Pi

Cloud a náklady na dopravu s tým nemajú nič spoločné, detektor beží na bežnom hardvéri a pracuje takou rýchlosťou.

Neurónová počítačová tyčinka

Nemohol som odolať a spustil som benchmark na NCS.

Rýchlosť detektora bola o niečo nižšia ako 0.1 sekundy, v každom prípade 2-3 krát rýchlejšia ako cloud na slabom stroji, t.j. 8-9 snímok za sekundu.

Video detektora cloudových objektov na Raspberry Pi

Rozdiel vo výsledkoch je vysvetlený skutočnosťou, že NCS používalo verziu Mobile SSD 2018_01_28.

P.S. Okrem toho experimenty ukázali, že pomerne výkonný stolný stroj s procesorom I7 vykazuje o niečo lepšie výsledky a ukázalo sa, že je možné vytlačiť 10 snímok za sekundu.

zhluk

Experiment išiel ďalej a detektor som nainštaloval na päť uzlov v Google Kubernetes.
Samotné moduly boli slabé a každý z nich nedokázal spracovať viac ako 2 snímky za sekundu.
Ale ak spustíte klaster s N uzlami a analyzujete snímky v N vláknach, potom s dostatočným počtom uzlov (5) môžete dosiahnuť požadovaných 10 snímok za sekundu.

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

Tu sa stalo:

Video detektora cloudových objektov na Raspberry Pi

Trochu menej rýchle ako s NCS, ale razantnejšie ako v jednom prúde.

Zisk, samozrejme, nie je lineárny - existujú prekrytia pre synchronizáciu a hlboké kopírovanie obrázkov opencv.

Záver

Celkovo nám experiment umožňuje dospieť k záveru, že ak sa pokúsite, môžete sa dostať preč s jednoduchým cloudom.

Ale výkonný desktop alebo lokálny hardvér vám umožní dosiahnuť lepšie výsledky a to bez akýchkoľvek trikov.

referencie

Zdroj: hab.com

Pridať komentár