Video af Cloud Object Detector på Raspberry Pi

prolog

En video cirkulerer nu på internettet, der viser, hvordan Teslas autopilot ser vejen.

Jeg har længe kløet efter at udsende video beriget med en detektor og i realtid.

Video af Cloud Object Detector på Raspberry Pi

Problemet er, at jeg vil udsende video fra Raspberry, og ydeevnen af ​​den neurale netværksdetektor på den lader meget tilbage at ønske.

Intel Neural Computer Stick

Jeg overvejede forskellige løsninger.

В sidste artikel eksperimenteret med Intel Neural Computer Stick. Hardwaren er kraftfuld, men kræver sit eget netværksformat.

Selvom Intel leverer konvertere til større frameworks, er der en række faldgruber.

For eksempel kan formatet på det påkrævede netværk være inkompatibelt, og hvis det er kompatibelt, understøttes nogle lag muligvis ikke på enheden, og hvis de understøttes, kan der opstå fejl under konverteringsprocessen, som et resultat af vi får nogle mærkelige ting ved udgangen.

Generelt, hvis du ønsker en form for vilkårligt neuralt netværk, så virker det muligvis ikke med NCS. Derfor besluttede jeg at forsøge at løse problemet ved hjælp af de mest udbredte og tilgængelige værktøjer.

sky

Det oplagte alternativ til en lokal hardwareløsning er at gå til skyen.

Færdiglavede muligheder - mine øjne løber løbsk.

Alle ledere:

... Og snesevis af mindre kendte.

At vælge blandt denne sort er slet ikke let.

Og jeg besluttede ikke at vælge, men at pakke det gode gamle arbejdsskema på OpenCV i Docker og køre det i skyen.

Fordelen ved denne tilgang er fleksibilitet og kontrol - du kan ændre det neurale netværk, hosting, server - generelt ethvert indfald.

Server

Lad os starte med en lokal prototype.

Traditionelt bruger jeg Flask til REST API, OpenCV og MobileSSD netværk.

Efter at have installeret de nuværende versioner på Docker, opdagede jeg, at OpenCV 4.1.2 ikke virker med Mobile SSD v1_coco_2018_01_28, og jeg var nødt til at rulle tilbage til den gennemprøvede 11/06_2017.

Ved starten af ​​tjenesten indlæser vi klassenavne og netværk:

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 docker (på en ikke særlig ung bærbar computer) tager det 0.3 sekunder, på Raspberry - 3.5.

Lad os starte udregningen:

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

Forvandler tensorudstødning til 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

yderligere eksporter denne operation via Flask(input er et billede, output er resultaterne af detektoren i json).

En alternativ mulighed, hvor mere arbejde flyttes til serveren: den selv cirkler de fundne objekter og returnerer det færdige billede.

Denne mulighed er god, hvor vi ikke ønsker at trække opencv til serveren.

Docker

Vi samler billedet.

Koden kæmmes og lægges på Github, vil docker tage det direkte derfra.

Som platform tager vi den samme Debian Stretch som på Raspberry - vi vil ikke afvige fra den gennemprøvede teknologistak.

Du skal installere flask, protobuf, requests, opencv_python, downloade Mobile SSD, serverkode fra Github og starte serveren.

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

Simple detektorklient baseret på anmodninger.

Udgivelse til Docker Hub

Docker-registre formerer sig med en hastighed, der ikke er mindre end skydetektorer.

For ikke at genere, vil vi konservativt gå igennem DockerHub.

  1. Tilmeld
  2. Log på:
    docker-login
  3. Lad os finde på et meningsfuldt navn:
    docker tag opencv-detect tprlab/opencv-detect-ssd
  4. Upload billedet til serveren:
    docker push tprlab/opencv-detect-ssd

Vi starter i skyen

Valget af, hvor containeren skal køres, er også ret bredt.

Alle de store spillere (Google, Microsoft, Amazon) tilbyder en mikroinstans gratis det første år.
Efter at have eksperimenteret med Microsoft Azure og Google Cloud valgte jeg sidstnævnte, fordi det tog fart hurtigere.

Jeg har ikke skrevet instruktioner her, da denne del er meget specifik for den valgte udbyder.

Jeg prøvede forskellige hardwareindstillinger,
Lave niveauer (delt og dedikeret) - 0.4 - 0.5 sekunder.
Kraftigere biler - 0.25 - 0.3.
Nå, selv i det værste tilfælde er gevinsten tre gange, du kan prøve.

Video

Vi lancerer en simpel OpenCV-videostreamer på Raspberry, der registrerer via Google Cloud.
Til forsøget blev der brugt en videofil, der engang blev filmet i et tilfældigt kryds.


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 detektoren får vi ikke mere end tre billeder i sekundet, alt går meget langsomt.
Hvis du tager en kraftfuld maskine ind i GCloud, kan du registrere 4-5 billeder i sekundet, men forskellen er næsten usynlig for øjet, den er stadig langsom.

Video af Cloud Object Detector på Raspberry Pi

Sky- og transportomkostningerne har intet med det at gøre; detektoren kører på almindelig hardware og arbejder med sådan en hastighed.

Neural Computer Stick

Jeg kunne ikke modstå og kørte benchmark på NCS.

Detektorens hastighed var lidt langsommere end 0.1 sekunder, i hvert fald 2-3 gange hurtigere end skyen på en svag maskine, altså 8-9 billeder i sekundet.

Video af Cloud Object Detector på Raspberry Pi

Forskellen i resultater forklares af, at NCS kørte Mobile SSD version 2018_01_28.

P.S. Derudover har eksperimenter vist, at en ret kraftig desktop-maskine med en I7-processor viser lidt bedre resultater og det viste sig at være muligt at presse 10 billeder ud i sekundet.

klynge

Eksperimentet gik videre, og jeg installerede detektoren på fem noder i Google Kubernetes.
Selve bælgerne var svage, og hver af dem kunne ikke behandle mere end 2 billeder i sekundet.
Men hvis du kører en klynge med N noder og parser frames i N tråde, så kan du med et tilstrækkeligt antal noder (5) opnå de ønskede 10 frames i sekundet.

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

Her er hvad der skete:

Video af Cloud Object Detector på Raspberry Pi

Lidt mindre hurtigt end med NCS, men kraftigere end i én vandløb.

Forstærkningen er selvfølgelig ikke lineær - der er overlays til synkronisering og dyb kopiering af opencv-billeder.

Konklusion

Samlet set giver eksperimentet os mulighed for at konkludere, at hvis du prøver, kan du slippe afsted med en simpel sky.

Men en kraftfuld desktop eller lokal hardware giver dig mulighed for at opnå bedre resultater og uden nogen tricks.

RЎSЃS <P "RєRё

Kilde: www.habr.com

Tilføj en kommentar