Video de Nuba Objekta Detektilo sur Raspberry Pi

Antaŭparolo

Vidbendo nun cirkulas en la Interreto montrante kiel la aŭtomata piloto de Tesla vidas la vojon.

Mi delonge jukas elsendi videon riĉigitan per detektilo, kaj en reala tempo.

Video de Nuba Objekta Detektilo sur Raspberry Pi

La problemo estas, ke mi volas elsendi filmeton de Raspberry, kaj la agado de la neŭrala reto-detektilo lasas multe por deziri.

Intel Neŭrala Komputila Stilo

Mi pripensis malsamajn solvojn.

В lasta artikolo eksperimentis kun Intel Neural Computer Stick. La aparataro estas potenca, sed postulas sian propran retan formaton.

Kvankam Intel provizas konvertilojn por gravaj kadroj, ekzistas kelkaj malfacilaĵoj.

Ekzemple, la formato de la bezonata reto povas esti malkongrua, kaj se ĝi estas kongrua, tiam iuj tavoloj eble ne estas subtenataj sur la aparato, kaj se ili estas subtenataj, tiam eraroj povas okazi dum la konverta procezo, kiel rezulto de kio. ni ricevas kelkajn strangajn aferojn ĉe la eligo.

Ĝenerale, se vi volas ian arbitran neŭralan reton, tiam ĝi eble ne funkcias kun NCS. Tial mi decidis provi solvi la problemon per la plej disvastigitaj kaj alireblaj iloj.

Nubo

La evidenta alternativo al loka aparatara solvo estas iri al la nubo.

Pretaj opcioj - miaj okuloj sovaĝiĝas.

Ĉiuj gvidantoj:

... Kaj dekoj da malpli konataj.

Elekti inter ĉi tiu vario tute ne estas facila.

Kaj mi decidis ne elekti, sed envolvi la bonan malnovan laborskemon sur OpenCV en Docker kaj ruli ĝin en la nubo.

La avantaĝo de ĉi tiu aliro estas fleksebleco kaj kontrolo - vi povas ŝanĝi la neŭralan reton, gastigadon, servilon - ĝenerale, ajna kaprico.

Servilo

Ni komencu per loka prototipo.

Tradicie mi uzas Flask por REST API, OpenCV kaj MobileSSD-reto.

Instalinte la nunajn versiojn sur Docker, mi malkovris, ke OpenCV 4.1.2 ne funkcias kun Mobile SSD v1_coco_2018_01_28, kaj mi devis reveni al la pruvita 11/06_2017.

Komence de la servo, ni ŝarĝas la klasnomojn kaj reton:

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

Sur loka dokero (sur ne tre juna tekkomputilo) necesas 0.3 sekundoj, ĉe Raspberry - 3.5.

Ni komencu la kalkulon:

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 sek, Frambo - 1.7.

Turnante tensora ellasilo en legeblan 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

Plue eksportu ĉi tiun operacion per Flask(enigo estas bildo, eligo estas la rezultoj de la detektilo en json).

Alternativa opcio, en kiu pli da laboro estas movita al la servilo: ĝi mem rondiras la trovitajn objektojn kaj resendas la finitan bildon.

Ĉi tiu opcio estas bona kie ni ne volas treni opencv al la servilo.

Docker

Ni kolektas la bildon.

La kodo estas kombita kaj afiŝita Github, Docker prenos ĝin rekte de tie.

Kiel platformo, ni prenos la saman Debian Stretch kiel sur Raspberry - ni ne devios de la provita teknika stako.

Vi devas instali flaskon, protobuf, petojn, opencv_python, elŝuti Poŝtelefonan SSD, servilan kodon de Github kaj komenci la servilon.

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

Simpla detektilo kliento surbaze de petoj.

Eldonado al Docker Hub

Docker-registroj multiĝas je rapideco ne malpli ol nubaj detektiloj.

Por ne ĝeni, ni konserveme trairos DockerHub.

  1. Registru
  2. Ensaluti:
    docker ensaluto
  3. Ni elpensu signifoplenan nomon:
    docker-etikedo opencv-detect tprlab/opencv-detect-ssd
  4. Alŝutu la bildon al la servilo:
    docker push tprlab/opencv-detect-ssd

Ni lanĉas en la nubo

La elekto de kie ruli la ujon ankaŭ estas sufiĉe larĝa.

Ĉiuj grandaj ludantoj (Google, Microsoft, Amazon) ofertas mikro-instancon senpage dum la unua jaro.
Post eksperimentado kun Microsoft Azure kaj Google Cloud, mi decidis pri ĉi-lasta ĉar ĝi ekflugis pli rapide.

Mi ne skribis instrukciojn ĉi tie, ĉar ĉi tiu parto estas tre specifa por la elektita provizanto.

Mi provis malsamajn aparatajn opciojn,
Malaltaj niveloj (dividitaj kaj dediĉitaj) - 0.4 - 0.5 sekundoj.
Pli potencaj aŭtoj - 0.25 - 0.3.
Nu, eĉ en la plej malbona kazo, la gajno estas trioble, vi povas provi.

Video

Ni lanĉas simplan OpenCV-videofluilon sur Raspberry, detektante per Google Cloud.
Por la eksperimento oni uzis videodosieron, kiu iam estis filmita ĉe hazarda intersekciĝo.


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

Kun la detektilo ni ricevas ne pli ol tri kadrojn por sekundo, ĉio iras tre malrapide.
Se vi prenas potencan maŝinon en GCloud, vi povas detekti 4-5 kadrojn sekundo, sed la diferenco estas preskaŭ nevidebla por la okulo, ĝi ankoraŭ malrapidas.

Video de Nuba Objekta Detektilo sur Raspberry Pi

La nubo kaj transportkostoj havas nenion por fari kun ĝi; la detektilo funkcias per ordinara aparataro kaj funkcias kun tia rapideco.

Neŭrala Komputila Bastono

Mi ne povis rezisti kaj kuris la komparnormon sur NCS.

La rapido de la detektilo estis iomete pli malrapida ol 0.1 sekundoj, ĉiukaze 2-3 fojojn pli rapida ol la nubo sur malforta maŝino, t.e. 8-9 kadroj sekundo.

Video de Nuba Objekta Detektilo sur Raspberry Pi

La diferenco en rezultoj estas klarigita per la fakto, ke NCS rulis Mobile SSD version 2018_01_28.

PS Krome, eksperimentoj montris, ke sufiĉe potenca labortabla maŝino kun I7-procesoro montras iomete pli bonajn rezultojn kaj montriĝis eble premi 10 kadrojn por sekundo sur ĝi.

Areto

La eksperimento iris plu kaj mi instalis la detektilon sur kvin nodoj en Guglo Kubernetes.
La guŝoj mem estis malfortaj kaj ĉiu el ili ne povis prilabori pli ol 2 kadrojn por sekundo.
Sed se vi kuras areton kun N nodoj kaj analizas kadrojn en N fadenoj, tiam kun sufiĉa nombro da nodoj (5) vi povas atingi la deziratajn 10 kadrojn sekundo.

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

Jen kio okazis:

Video de Nuba Objekta Detektilo sur Raspberry Pi

Iom malpli rapide ol kun NCS, sed pli vigla ol en unu rivereto.

La gajno, kompreneble, ne estas linia - estas supermetaĵoj por sinkronigado kaj profunda kopiado de opencv-bildoj.

konkludo

Ĝenerale, la eksperimento permesas al ni konkludi, ke se vi provas, vi povas eliri per simpla nubo.

Sed potenca labortablo aŭ loka aparataro permesas vin atingi pli bonajn rezultojn, kaj sen ajnaj lertaĵoj.

referencoj

fonto: www.habr.com

Aldoni komenton