Video av Cloud Object Detector på Raspberry Pi

prolog

En video cirkulerar nu på internet som visar hur Teslas autopilot ser vägen.

Jag har länge längtat efter att sända video berikad med en detektor, och i realtid.

Video av Cloud Object Detector på Raspberry Pi

Problemet är att jag vill sända video från Raspberry, och prestandan för den neurala nätverksdetektorn på den lämnar mycket övrigt att önska.

Intel Neural Computer Stick

Jag funderade på olika lösningar.

В senaste artikeln experimenterade med Intel Neural Computer Stick. Hårdvaran är kraftfull, men kräver ett eget nätverksformat.

Även om Intel tillhandahåller omvandlare för stora ramverk finns det ett antal fallgropar.

Till exempel kan formatet på det erforderliga nätverket vara inkompatibelt, och om det är kompatibelt kan det hända att vissa lager inte stöds på enheten, och om de stöds kan det uppstå fel under konverteringsprocessen, som ett resultat av vilket vi får några konstiga saker vid utgången.

I allmänhet, om du vill ha något slags godtyckligt neuralt nätverk, kanske det inte fungerar med NCS. Därför bestämde jag mig för att försöka lösa problemet med de mest utbredda och tillgängliga verktygen.

moln

Det självklara alternativet till en lokal hårdvarulösning är att gå till molnet.

Färdiga alternativ - mina ögon rinner vilt.

Alla ledare:

... Och dussintals mindre kända.

Att välja bland denna sort är inte alls lätt.

Och jag bestämde mig för att inte välja, utan att slå in det gamla goda arbetsschemat på OpenCV i Docker och köra det i molnet.

Fördelen med detta tillvägagångssätt är flexibilitet och kontroll - du kan ändra det neurala nätverket, hosting, server - i allmänhet, vilket infall som helst.

Server

Låt oss börja med en lokal prototyp.

Traditionellt använder jag Flask för REST API, OpenCV och MobileSSD-nätverk.

Efter att ha installerat de nuvarande versionerna på Docker upptäckte jag att OpenCV 4.1.2 inte fungerar med Mobile SSD v1_coco_2018_01_28, och jag var tvungen att rulla tillbaka till den beprövade 11/06_2017.

I början av tjänsten laddar vi klassnamnen och nätverket:

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

På en lokal dockare (på en inte särskilt ung bärbar dator) tar det 0.3 sekunder, på Raspberry - 3.5.

Låt oss börja beräkningen:

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, Hallon - 1.7.

Förvandlar tensoravgas till läsbar 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

ytterligare exportera denna operation via Flask(ingången är en bild, utgången är resultatet av detektorn i json).

Ett alternativt alternativ, där mer arbete flyttas till servern: den själv cirklar de hittade objekten och returnerar den färdiga bilden.

Det här alternativet är bra där vi inte vill dra opencv till servern.

Hamnarbetare

Vi samlar in bilden.

Koden kammas och läggs på Github, kommer docker att ta det direkt därifrån.

Som plattform kommer vi att ta samma Debian Stretch som på Raspberry - vi kommer inte att avvika från den beprövade teknikstacken.

Du måste installera flask, protobuf, requests, opencv_python, ladda ner Mobile SSD, serverkod från Github och starta servern.

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

enkel detektorklient baserat på förfrågningar.

Publicerar till Docker Hub

Docker-register förökar sig med en hastighet som inte är mindre än molndetektorer.

För att inte bry oss kommer vi konservativt att gå igenom DockerHub.

  1. Registrera
  2. Logga in:
    docker-inloggning
  3. Låt oss komma på ett meningsfullt namn:
    docker-tagg opencv-detect tprlab/opencv-detect-ssd
  4. Ladda upp bilden till servern:
    docker push tprlab/opencv-detect-ssd

Vi lanserar i molnet

Valet av var containern ska köras är också ganska brett.

Alla de stora aktörerna (Google, Microsoft, Amazon) erbjuder en mikroinstans gratis under det första året.
Efter att ha experimenterat med Microsoft Azure och Google Cloud bestämde jag mig för det senare eftersom det tog fart snabbare.

Jag skrev inga instruktioner här, eftersom den här delen är mycket specifik för den valda leverantören.

Jag provade olika hårdvarualternativ,
Låga nivåer (delade och dedikerade) - 0.4 - 0.5 sekunder.
Kraftfullare bilar - 0.25 - 0.3.
Tja, även i värsta fall är vinsterna tre gånger, du kan prova.

Video

Vi lanserar en enkel OpenCV-videostreamer på Raspberry, som upptäcker via Google Cloud.
För experimentet användes en videofil som en gång filmades i en slumpmässig korsning.


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

Med detektorn får vi inte mer än tre bilder per sekund, allt går väldigt långsamt.
Om du tar in en kraftfull maskin i GCloud kan du upptäcka 4-5 bilder per sekund, men skillnaden är nästan osynlig för ögat, den är fortfarande långsam.

Video av Cloud Object Detector på Raspberry Pi

Molnet och transportkostnaderna har inget med det att göra, detektorn körs på vanlig hårdvara och arbetar med den hastigheten.

Neural datorpinne

Jag kunde inte motstå och körde benchmark på NCS.

Detektorns hastighet var något lägre än 0.1 sekunder, i alla fall 2-3 gånger snabbare än molnet på en svag maskin, dvs 8-9 bilder per sekund.

Video av Cloud Object Detector på Raspberry Pi

Skillnaden i resultat förklaras av att NCS körde Mobile SSD version 2018_01_28.

PS Dessutom har experiment visat att en ganska kraftfull stationär dator med en I7-processor visar något bättre resultat och det visade sig vara möjligt att klämma in 10 bilder per sekund på den.

Klunga

Experimentet gick längre och jag installerade detektorn på fem noder i Google Kubernetes.
Poddarna själva var svaga och var och en av dem kunde inte bearbeta mer än 2 bilder per sekund.
Men om du kör ett kluster med N noder och analyserar ramar i N trådar, kan du med ett tillräckligt antal noder (5) uppnå önskade 10 bildrutor 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

Här är vad som hände:

Video av Cloud Object Detector på Raspberry Pi

Lite mindre snabb än med NCS, men kraftigare än i en bäck.

Förstärkningen är naturligtvis inte linjär - det finns överlägg för synkronisering och djupkopiering av opencv-bilder.

Slutsats

Sammantaget låter experimentet oss dra slutsatsen att om du försöker kan du komma undan med ett enkelt moln.

Men en kraftfull stationär eller lokal hårdvara låter dig uppnå bättre resultat, och utan några knep.

referenser

Källa: will.com

Lägg en kommentar