Fideo fan Cloud Object Detector op Raspberry Pi

Proloog

In fideo sirkulearret no op it ynternet dat sjen lit hoe't de autopilot fan Tesla de dyk sjocht.

Ik haw al in lange tiid jeuk om fideo ferrike mei in detektor út te stjoeren, en yn echte tiid.

Fideo fan Cloud Object Detector op Raspberry Pi

It probleem is dat ik fideo wolle útstjoere fan Raspberry, en de prestaasjes fan 'e neurale netwurkdetektor derop litte in protte te winskjen oer.

Intel Neural Computer Stick

Ik haw ferskate oplossingen beskôge.

В lêste artikel eksperimintearre mei Intel Neural Computer Stick. De hardware is krêftich, mar fereasket in eigen netwurkformaat.

Sels hoewol Intel converters leveret foar grutte kaders, binne d'r in oantal falkûlen.

Bygelyks, it formaat fan it fereaske netwurk kin ynkompatibel wêze, en as it kompatibel is, dan kinne guon lagen miskien net wurde stipe op it apparaat, en as se wurde stipe, kinne flaters foarkomme tidens it konverzjeproses, as gefolch dêrfan wy krije wat nuvere dingen by de útgong.

Yn 't algemien, as jo in soarte fan willekeurige neurale netwurk wolle, dan kin it miskien net wurkje mei NCS. Dêrom besleat ik om te besykjen it probleem op te lossen mei de meast wiidferspraat en tagonklike ark.

Wolke

It foar de hân lizzende alternatyf foar in lokale hardware-oplossing is om nei de wolk te gean.

Ready-made opsjes - myn eagen rinne wyld.

Alle lieders:

... En tsientallen minder bekende.

Kieze tusken dizze ferskaat is net hielendal maklik.

En ik besleat net te kiezen, mar it goede âlde wurkskema op OpenCV yn Docker te wikkeljen en it yn 'e wolk út te fieren.

It foardiel fan dizze oanpak is fleksibiliteit en kontrôle - jo kinne it neurale netwurk, hosting, server feroarje - yn 't algemien, elke wille.

Tsjinner

Litte wy begjinne mei in lokaal prototype.

Tradysjoneel brûk ik Flask foar REST API, OpenCV en MobileSSD netwurk.

Nei't ik de hjoeddeistige ferzjes op Docker ynstalleare, ûntduts ik dat OpenCV 4.1.2 net wurket mei Mobile SSD v1_coco_2018_01_28, en ik moast weromdraaie nei de bewezen 11/06_2017.

Oan it begjin fan 'e tsjinst laden wy de klassenammen en netwurk:

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

Op in lokale docker (op in net hiel jonge laptop) duorret it 0.3 sekonden, op Raspberry - 3.5.

Litte wy begjinne mei de berekkening:

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.

Tensor-útlaat omsette yn lêsbere 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

Fierder eksportearje dizze operaasje fia Flask(ynfier is in ôfbylding, útfier is de resultaten fan 'e detektor yn json).

In alternative opsje, wêrby't mear wurk wurdt ferpleatst nei de tsjinner: it sels sirkelt de fûn objekten en jout de ôfmakke ôfbylding werom.

Dizze opsje is goed wêr't wy opencv net wolle slepe nei de tsjinner.

Docker

Wy sammelje de ôfbylding.

De koade wurdt gekamd en pleatst op Github, sil docker it dêr direkt fanôf nimme.

As platfoarm sille wy deselde Debian Stretch nimme as op Raspberry - wy sille net ôfwike fan 'e bewezen tech-stapel.

Jo moatte ynstallearje flask, protobuf, fersiken, opencv_python, download Mobile SSD, tsjinner koade fan Github en start de tsjinner.

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 detector client basearre op fersiken.

Publisearje nei Docker Hub

Docker-registraasjes fermannichfâldigje mei in snelheid net minder dan wolkdetektors.

Om net te lestich falle, sille wy konservatyf trochgean DockerHub.

  1. Register
  2. Oanmelde:
    docker login
  3. Litte wy mei in betsjuttingsfolle namme komme:
    docker tag opencv-detect tprlab/opencv-detect-ssd
  4. Upload de ôfbylding nei de tsjinner:
    docker push tprlab/opencv-detect-ssd

Wy lansearje yn 'e wolk

De kar fan wêr't de kontener rinne moat is ek frij breed.

Alle grutte spilers (Google, Microsoft, Amazon) biede yn it earste jier in mikro-eksimplaar fergees.
Nei it eksperimintearjen mei Microsoft Azure en Google Cloud, haw ik it lêste fêststeld, om't it rapper naam.

Ik haw hjir gjin ynstruksjes skreaun, om't dit diel heul spesifyk is foar de selektearre provider.

Ik besocht ferskate hardware-opsjes,
Lege nivo's (dield en tawijd) - 0.4 - 0.5 sekonden.
Krêftiger auto's - 0.25 - 0.3.
No, sels yn it slimste gefal, de winst binne trije kear, kinne jo besykje.

Видео

Wy lansearje in ienfâldige OpenCV-fideostreamer op Raspberry, detecting fia Google Cloud.
Foar it eksperimint waard in fideobestân brûkt dat eartiids op in willekeurige krusing ferfilme waard.


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

Mei de detektor krije wy net mear as trije frames per sekonde, alles giet hiel stadich.
As jo ​​nimme in krêftige masine yn GCloud, kinne jo detect 4-5 frames per sekonde, mar it ferskil is hast ûnsichtber foar it each, it is noch stadich.

Fideo fan Cloud Object Detector op Raspberry Pi

De wolk- en ferfierkosten hawwe der neat mei te krijen, de detektor draait op gewoane hardware en wurket op sa'n snelheid.

Neural Computer Stick

Ik koe net wjerstean en rûn de benchmark op NCS.

De snelheid fan de detektor wie wat stadiger as 0.1 sekonden, yn alle gefallen 2-3 kear flugger as de wolk op in swakke masine, dus 8-9 frames per sekonde.

Fideo fan Cloud Object Detector op Raspberry Pi

It ferskil yn resultaten wurdt ferklearre troch it feit dat NCS Mobile SSD ferzje 2018_01_28 draaide.

PS Derneist hawwe eksperiminten sjen litten dat in frij krêftige buroblêdmasine mei in I7-prosessor wat bettere resultaten toant en it die bliken dat it mooglik wie om der 10 frames per sekonde op te squeeze.

Cluster

It eksperimint gie fierder en ik ynstalleare de detektor op fiif knopen yn Google Kubernetes.
De pods sels wiene swak en elk fan harren koe net ferwurkje mear as 2 frames per sekonde.
Mar as jo in kluster útfiere mei N knopen en frames yn N triedden parse, dan kinne jo mei in foldwaande oantal knopen (5) de winske 10 frames per sekonde berikke.

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

Hjir is wat barde:

Fideo fan Cloud Object Detector op Raspberry Pi

In bytsje minder fluch as mei NCS, mar mear enerzjyk as yn ien stream.

De winst is fansels net lineêr - d'r binne overlays foar syngronisaasje en djippe kopiearjen fan opencv-ôfbyldings.

konklúzje

Oer it algemien lit it eksperimint ús konkludearje dat as jo besykje, kinne jo fuortkomme mei in ienfâldige wolk.

Mar in krêftich buroblêd as lokale hardware kinne jo bettere resultaten berikke, en sûnder trúkjes.

referinsjes

Boarne: www.habr.com

Add a comment