Video vum Cloud Object Detector op Raspberry Pi

Prolog

E Video zirkuléiert elo um Internet, deen weist wéi den Autopilot vum Tesla d'Strooss gesäit.

Ech hu scho laang gejaut fir Video beräichert mat engem Detektor ze iwwerdroen, an Echtzäit.

Video vum Cloud Object Detector op Raspberry Pi

De Problem ass datt ech Video vu Raspberry wëlle verbreeden, an d'Performance vum neurale Netzwierkdetektor op et léisst vill ze wënschen.

Intel Neural Computer Stick

Ech hu verschidde Léisungen ugesinn.

В leschten Artikel experimentéiert mam Intel Neural Computer Stick. D'Hardware ass mächteg, awer erfuerdert säin eegent Netzwierkformat.

Och wann Intel Konverter fir grouss Kaderen ubitt, ginn et eng Zuel vu Fallen.

Zum Beispill kann de Format vum erfuerderlechen Netzwierk inkompatibel sinn, a wann et kompatibel ass, da kënnen e puer Schichten net um Apparat ënnerstëtzt ginn, a wa se ënnerstëtzt ginn, da kënne Feeler während dem Konversiounsprozess optrieden, als Resultat vun deem mir kréien e puer komesch Saachen um Output.

Am Allgemengen, wann Dir eng Zort arbiträr neural Netzwierk wëllt, da funktionnéiert et vläicht net mat NCS. Dofir hunn ech beschloss ze probéieren de Problem mat de verbreetsten an zougänglechsten Tools ze léisen.

Wolleken

Déi offensichtlech Alternativ zu enger lokaler Hardwareléisung ass an d'Wollek ze goen.

Fäerdeg Optiounen - meng Ae lafen wild.

All Leader:

... An Dosende vu manner bekannten.

Wiel vun dëser Varietéit ass guer net einfach.

An ech hu beschloss net ze wielen, mee de gudden alen Aarbechtsschema op OpenCV am Docker ze wéckelen an an der Wollek ze lafen.

De Virdeel vun dëser Approche ass Flexibilitéit a Kontroll - Dir kënnt den neuralen Netzwierk, Hosting, Server änneren - am Allgemengen, all Geck.

Server

Loosst eis mat engem lokale Prototyp ufänken.

Traditionell benotzen ech Flask fir REST API, OpenCV a MobileSSD Netzwierk.

Nodeems ech déi aktuell Versiounen op Docker installéiert hunn, hunn ech entdeckt datt OpenCV 4.1.2 net mat Mobile SSD v1_coco_2018_01_28 funktionnéiert, an ech hu missen zréck op de bewährte 11/06_2017.

Um Ufank vum Service luede mir d'Klassennimm an d'Netz:

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

Op engem lokalen Docker (op engem net ganz jonke Laptop) dauert et 0.3 Sekonnen, op Raspberry - 3.5.

Loosst eis d'Berechnung ufänken:

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

Tensor Auspuff an liesbar json ëmsetzen:

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

Weider exportéiert dës Operatioun iwwer Flask(Input ass e Bild, Ausgang ass d'Resultater vum Detektor am json).

Eng alternativ Optioun, an där méi Aarbecht op de Server verréckelt gëtt: et selwer kreéiert déi fonnt Objeten a bréngt dat fäerdegt Bild zréck.

Dës Optioun ass gutt wou mir net wëllen opencv op de Server zéien.

Docker

Mir sammelen d'Bild.

De Code gëtt gekämmt a gepost op Github, Docker wäert et direkt vun do huelen.

Als Plattform wäerte mir déiselwecht Debian Stretch huelen wéi op Raspberry - mir wäerten net vum bewährten Tech Stack ofwäichen.

Dir musst Flask, Protobuf, Ufroen, opencv_python installéieren, Mobile SSD eroflueden, Servercode vu Github an de Server starten.

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

Einfach Detektor Client baséiert op Ufroen.

Verëffentlechung op Docker Hub

Docker Registries multiplizéieren mat enger Geschwindegkeet net manner wéi Cloud Detektoren.

Fir net ze stéieren, wäerte mir konservativ duerchgoen DockerHub.

  1. Registréiert
  2. Login:
    docker Login
  3. Komme mer mat engem sënnvollen Numm:
    docker tag opencv-detect tprlab/opencv-detect-ssd
  4. Eroplueden d'Bild op de Server:
    docker push tprlab/opencv-detect-ssd

Mir starten an der Wollek

D'Wiel vu wou de Container ze lafen ass och zimlech breet.

All déi grouss Spiller (Google, Microsoft, Amazon) bidden fir dat éischt Joer eng Mikro-Instanz gratis un.
Nodeems ech mat Microsoft Azure a Google Cloud experimentéiert hunn, hunn ech mech op déi lescht niddergelooss, well et méi séier fortgaang ass.

Ech hunn hei keng Instruktioune geschriwwen, well dësen Deel ass ganz spezifesch fir de gewielte Provider.

Ech probéiert verschidden Hardware Optiounen,
Niddereg Niveauen (gedeelt an engagéiert) - 0.4 - 0.5 Sekonnen.
Méi mächteg Autoen - 0.25 - 0.3.
Ee, och am schlëmmste Fall Szenario, de Gewënn sinn dräimol, Dir kënnt probéieren.

Видео

Mir starten en einfachen OpenCV Video Streamer op Raspberry, detektéieren duerch Google Cloud.
Fir den Experiment gouf eng Videodatei benotzt déi eemol op enger zoufälleger Kräizung gefilmt gouf.


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

Mam Detektor kréie mir net méi wéi dräi Frames pro Sekonn, alles geet ganz lues.
Wann Dir eng mächteg Maschinn an GCloud hëlt, kënnt Dir 4-5 Frames pro Sekonn entdecken, awer den Ënnerscheed ass bal onsichtbar fir d'Aen, et ass ëmmer nach lues.

Video vum Cloud Object Detector op Raspberry Pi

D'Wollek an d'Transportkäschte hunn näischt domat ze dinn; den Detektor leeft op regelméisseg Hardware a funktionnéiert mat där Geschwindegkeet.

Neural Computer Stick

Ech konnt net widderstoen an de Benchmark op NCS lafen.

D'Vitesse vum Detektor war liicht méi lues wéi 0.1 Sekonnen, op alle Fall 2-3 Mol méi séier wéi d'Wollek op enger schwaacher Maschinn, also 8-9 Frames pro Sekonn.

Video vum Cloud Object Detector op Raspberry Pi

Den Ënnerscheed an de Resultater gëtt erkläert duerch d'Tatsaach datt NCS Mobile SSD Versioun 2018_01_28 leeft.

P.S. Zousätzlech hunn Experimenter gewisen datt eng zimlech mächteg Desktop-Maschinn mat engem I7-Prozessor liicht besser Resultater weist an et huet sech erausgestallt datt et méiglech ass 10 Frames pro Sekonn auszedrécken.

Koup

D'Experiment ass weider gaang an ech hunn den Detektor op fënnef Knäppercher am Google Kubernetes installéiert.
D'Pods selwer ware schwaach a jidderee vun hinnen konnt net méi wéi 2 Frames pro Sekonn veraarbechten.
Awer wann Dir e Stärekoup mat N Wirbelen leeft a Frames an N Threads parséiert, da kënnt Dir mat enger genuch Zuel vu Wirbelen (5) déi gewënscht 10 Frames pro Sekonn erreechen.

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

Hei ass wat geschitt ass:

Video vum Cloud Object Detector op Raspberry Pi

E bësse manner séier wéi mat NCS, awer méi kräfteg wéi an enger Baach.

De Gewënn ass natierlech net linear - et gi Overlays fir Synchroniséierung an déif Kopie vun opencv Biller.

Konklusioun

Am Allgemengen erlaabt d'Experiment eis ze schléissen datt wann Dir probéiert, Dir kënnt mat enger einfacher Wollek fortkommen.

Awer e mächtege Desktop oder lokal Hardware erlaabt Iech besser Resultater z'erreechen, an ouni Tricken.

Referenze

Source: will.com

Setzt e Commentaire