Video di Cloud Object Detector in Raspberry Pi

Prologu

Un video hè in circulazione in Internet chì mostra cumu l'autopilotu di Tesla vede a strada.

Aghju prucedimentu per un bellu pezzu per trasmette video arricchitu cù un detector, è in tempu reale.

Video di Cloud Object Detector in Raspberry Pi

U prublema hè chì vogliu trasmette u video da Raspberry, è a prestazione di u detector di a rete neurale lascia assai per esse desideratu.

Intel Neural Computer Stick

Aghju cunsideratu diverse suluzioni.

В ultimu articulu sperimentatu cù Intel Neural Computer Stick. U hardware hè putente, ma esige u so propiu formatu di rete.

Ancu s'è Intel furnisce cunvertitori per i frameworki maiò, ci sò una quantità di trappule.

Per esempiu, u formatu di a reta dumandata pò esse incompatibile, è s'ellu hè cumpatibile, allura certi strati ùn ponu esse supportati in u dispusitivu, è s'ellu sò supportati, allura l'errore pò accade durante u prucessu di cunversione, per via di quale. avemu alcune cose strane à l'output.

In generale, sè vo vulete un tipu di rete neurale arbitraria, allora ùn pò micca travaglià cù NCS. Dunque, aghju decisu di pruvà à risolve u prublema cù l'arnesi più diffusi è accessibili.

Cloud

L'alternativa ovvia à una suluzione hardware locale hè di andà in u nuvulu.

Opzioni prontu - i vostri ochji sò salvatichi.

Tutti i capi:

... È decine di menu cunnisciuti.

Sceglie trà sta varietà ùn hè micca faciule.

E aghju decisu di ùn sceglie micca, ma di imballà u bonu schema di travagliu anticu in OpenCV in Docker è eseguisce in u nuvulu.

U vantaghju di questu approcciu hè a flessibilità è u cuntrollu - pudete cambià a rete neurale, hosting, servitore - in generale, ogni capriccio.

Servidor

Cuminciamu cù un prototipu lucale.

Tradizionalmente, aghju utilizatu Flask per a rete REST API, OpenCV è MobileSSD.

Dopu avè installatu e versioni attuali nantu à Docker, aghju scupertu chì OpenCV 4.1.2 ùn funziona micca cù Mobile SSD v1_coco_2018_01_28, è aghju avutu à rinvià à a pruvata 11/06_2017.

À u principiu di u serviziu, carchemu i nomi di classi è a rete:

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

In un docker locale (in un laptop micca assai ghjovanu) ci vole 0.3 seconde, in Raspberry - 3.5.

Cuminciamu u calculu:

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 sec, Raspberry - 1.7.

Trasfurmà l'exhaust tensor in json leggibile:

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

Poi Esporta sta operazione via Flask(l'input hè una stampa, l'output hè i risultati di u detector in json).

Una opzione alternativa, in quale più travagliu hè spustatu à u servitore: ellu stessu circunda l'uggetti truvati è torna l'imagine finita.

Questa opzione hè bona induve ùn vulemu micca arrastà opencv à u servitore.

Docker

Cullemu l'imaghjini.

U codice hè pettinatu è publicatu Github, Docker u piglierà direttamente da quì.

Cum'è una piattaforma, piglieremu u listessu Debian Stretch cum'è in Raspberry - ùn deviaremu micca da a pila di tecnulugia pruvata.

Avete bisognu di stallà flask, protobuf, richieste, opencv_python, scaricate Mobile SSD, codice di u servitore da Github è inizià u servitore.

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

Простой cliente detector basatu nantu à e dumande.

Publicazione à Docker Hub

I registri Docker si multiplicanu à una velocità micca menu di i detectori di nuvola.

Per ùn disturbà, andemu cunservatoriamente DockerHub.

  1. Registrate
  2. Entra in:
    login docker
  3. Venitemu cun un nome significativu:
    tag docker opencv-detect tprlab/opencv-detect-ssd
  4. Caricate l'imaghjini à u servitore:
    docker push tprlab/opencv-detect-ssd

Lanciamu in u nuvulu

L'scelta di induve corre u cuntinuu hè ancu abbastanza larga.

Tutti i grandi attori (Google, Microsoft, Amazon) offrenu una microistanza gratuitamente per u primu annu.
Dopu avè spirimintatu cù Microsoft Azure è Google Cloud, aghju stabilitu nantu à l'ultime perchè s'hè alluntanatu più veloce.

Ùn aghju micca scrittu struzzioni quì, postu chì sta parte hè assai specifica per u fornitore sceltu.

Aghju pruvatu diverse opzioni di hardware,
Livelli bassi (spartitu è ​​dedicatu) - 0.4 - 0.5 seconde.
Cars più putenti - 0.25 - 0.3.
Ebbè, ancu in u peghju scenariu, i vincitori sò trè volte, pudete pruvà.

Видео

Lancemu un streamer di video OpenCV simplice nantu à Raspberry, detectendu attraversu Google Cloud.
Per l'esperimentu, hè stata utilizata un schedariu di video chì una volta era filmatu in una intersezzione aleatoria.


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

Cù u detector ùn avemu micca più di trè frames per seconda, tuttu passa assai pianu.
Se pigliate una macchina putente in GCloud, pudete detectà 4-5 frames per seconda, ma a diferenza hè quasi invisibule à l'ochju, hè sempre lenta.

Video di Cloud Object Detector in Raspberry Pi

U nuvulu è i costi di trasportu ùn anu nunda di fà cù questu; u detector funziona nantu à hardware regulare è travaglia à quella velocità.

Stick Neural Computer

Ùn pudia micca resiste è curria u benchmark in NCS.

A vitezza di u detector era ligeramente più lenta di 0.1 seconde, in ogni casu 2-3 volte più veloce di u nuvulu nantu à una macchina debule, vale à dì 8-9 frames per seconda.

Video di Cloud Object Detector in Raspberry Pi

A sfarenza di i risultati hè spiegata da u fattu chì NCS eseguiva Mobile SSD versione 2018_01_28.

P.S. Inoltre, l'esperimenti anu dimustratu chì una macchina di scrivania abbastanza putente cù un processore I7 mostra risultati ligeramente megliu è hè statu pussibule di strincà 10 frames per seconda.

Cluster

L'esperimentu andò più in là è aghju installatu u detector in cinque nodi in Google Kubernetes.
I baccelli stessi eranu debuli è ognunu ùn pudia micca processà più di 2 frames per seconda.
Ma se eseguite un cluster cù N nodes è parse frames in N threads, allora cun un numeru suffirenziu di nodi (5) pudete ottene i 10 frames per seconda.

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

Eccu ciò chì succideva:

Video di Cloud Object Detector in Raspberry Pi

Un pocu menu veloce chì cù NCS, ma più vigoru chì in un flussu.

U guadagnu, sicuru, ùn hè micca lineare - ci sò overlays per a sincronizazione è a copia profonda di l'imagine opencv.

cunchiusioni

In generale, l'esperimentu ci permette di cuncludi chì, se pruvate, pudete scappà cù un nuvulu simplice.

Ma un putente desktop o hardware locale permette di ottene risultati megliu, è senza trucchi.

referenze

Source: www.habr.com

Add a comment