Myndband af Cloud Object Detector á Raspberry Pi

Prologue

Myndband er nú í dreifingu á netinu sem sýnir hvernig sjálfstýring Tesla sér veginn.

Mig hefur lengi klæjað að senda út myndband auðgað með skynjara, og það í rauntíma.

Myndband af Cloud Object Detector á Raspberry Pi

Vandamálið er að ég vil senda út myndband frá Raspberry og frammistaða tauganetskynjarans á honum skilur eftir sig miklu.

Intel taugatölvustafur

Ég velti fyrir mér mismunandi lausnum.

В síðasta greinin gerði tilraunir með Intel Neural Computer Stick. Vélbúnaðurinn er öflugur, en þarfnast eigin netsniðs.

Jafnvel þó að Intel veiti breytum fyrir helstu ramma, þá eru ýmsar gildrur.

Til dæmis gæti snið tilskilins netkerfis verið ósamrýmanlegt og ef það er samhæft, þá gæti verið að sum lög séu ekki studd á tækinu og ef þau eru studd geta villur komið upp í umbreytingarferlinu, sem leiðir af sér við fáum skrítna hluti við úttakið.

Almennt séð, ef þú vilt einhvers konar handahófskennt tauganet, þá gæti það ekki virka með NCS. Þess vegna ákvað ég að reyna að leysa vandamálið með því að nota útbreiddustu og aðgengilegustu tækin.

Ský

Augljósi valkosturinn við staðbundna vélbúnaðarlausn er að fara í skýið.

Tilbúnir valkostir - augu mín hlaupa villt.

Allir leiðtogar:

... Og tugir minna þekktra.

Það er alls ekki auðvelt að velja á milli þessarar fjölbreytni.

Og ég ákvað að velja ekki, heldur að vefja gamla góða vinnukerfið á OpenCV í Docker og keyra það í skýinu.

Kosturinn við þessa nálgun er sveigjanleiki og stjórn - þú getur breytt taugakerfi, hýsingu, netþjóni - almennt, hvaða duttlunga sem er.

Server

Byrjum á staðbundinni frumgerð.

Hefðbundið nota ég Flask fyrir REST API, OpenCV og MobileSSD net.

Eftir að hafa sett upp núverandi útgáfur á Docker, uppgötvaði ég að OpenCV 4.1.2 virkar ekki með Mobile SSD v1_coco_2018_01_28, og ég varð að snúa aftur til sannaðs 11/06_2017.

Við upphaf þjónustunnar hleðum við flokksnöfnum og netkerfi:

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

Á staðbundnum tengikví (á ekki mjög ungri fartölvu) tekur það 0.3 sekúndur, á Raspberry - 3.5.

Byrjum á útreikningnum:

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

Breytir tensor útblástur í læsilegt 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

Nánari flytja þessa aðgerð út í gegnum Flask(inntak er mynd, úttak er niðurstöður skynjarans í json).

Annar valkostur, þar sem meiri vinna er færð yfir á netþjóninn: hann sjálft hringir um fundna hluti og skilar fulluninni mynd.

Þessi valkostur er góður þar sem við viljum ekki draga opencv á netþjóninn.

Hafnarmaður

Við söfnum myndinni.

Kóðinn er greiddur og settur á Github, Docker mun taka það beint þaðan.

Sem vettvangur tökum við sömu Debian Stretch og á Raspberry - við munum ekki víkja frá hinum sannaða tæknistafla.

Þú þarft að setja upp flösku, protobuf, beiðnir, opencv_python, hlaða niður Mobile SSD, miðlarakóða frá Github og ræsa netþjóninn.

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

Einfalt skynjari viðskiptavinur byggt á beiðnum.

Birtir á Docker Hub

Docker skrár eru að fjölga sér á ekki minni hraða en skýskynjarar.

Til þess að trufla okkur ekki munum við fara íhaldssamt í gegn DockerHub.

  1. Skráðu þig
  2. Skrá inn:
    docker innskráningu
  3. Við skulum finna merkingarbært nafn:
    docker tag opencv-detect tprlab/opencv-detect-ssd
  4. Hladdu upp myndinni á netþjóninn:
    docker ýta á tprlab/opencv-detect-ssd

Við ræsum í skýinu

Valið um hvar á að keyra gáminn er líka nokkuð breitt.

Allir stóru leikmennirnir (Google, Microsoft, Amazon) bjóða upp á örtilvik ókeypis fyrsta árið.
Eftir tilraunir með Microsoft Azure og Google Cloud, settist ég á hið síðarnefnda vegna þess að það tók hraðar á loft.

Ég skrifaði ekki leiðbeiningar hér, þar sem þessi hluti er mjög sérstakur fyrir valinn þjónustuaðila.

Ég prófaði mismunandi vélbúnaðarvalkosti,
Lág gildi (samnýtt og hollt) - 0.4 - 0.5 sekúndur.
Öflugri bílar - 0.25 - 0.3.
Jæja, jafnvel í versta falli, eru vinningarnir þrisvar sinnum, þú getur reynt.

video

Við kynnum einfaldan OpenCV vídeóstraumspilara á Raspberry, uppgötvum í gegnum Google Cloud.
Fyrir tilraunina var notuð myndbandsskrá sem var einu sinni tekin upp á handahófskenndum gatnamótum.


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

Með skynjaranum fáum við ekki meira en þrjá ramma á sekúndu, allt gengur mjög hægt.
Ef þú tekur öfluga vél inn í GCloud geturðu greint 4-5 ramma á sekúndu, en munurinn er næstum ósýnilegur fyrir augað, hann er samt hægur.

Myndband af Cloud Object Detector á Raspberry Pi

Skýið og flutningskostnaður hefur ekkert með það að gera; skynjarinn keyrir á venjulegum vélbúnaði og vinnur á þeim hraða.

Tauga tölvustafur

Ég gat ekki staðist og rak viðmiðið á NCS.

Hraði skynjarans var aðeins hægari en 0.1 sekúnda, alla vega 2-3 sinnum meiri en skýið á veikri vél, þ.e.a.s. 8-9 rammar á sekúndu.

Myndband af Cloud Object Detector á Raspberry Pi

Munurinn á niðurstöðum skýrist af því að NCS var að keyra Mobile SSD útgáfu 2018_01_28.

PS Auk þess hafa tilraunir sýnt að nokkuð öflug borðvél með I7 örgjörva sýnir aðeins betri árangur og það reyndist hægt að kreista 10 ramma á sekúndu á hana.

Klasa

Tilraunin gekk lengra og ég setti skynjarann ​​á fimm hnúta í Google Kubernetes.
Belgirnir sjálfir voru veikir og hver þeirra gat ekki unnið meira en 2 ramma á sekúndu.
En ef þú keyrir þyrping með N hnútum og greinir ramma í N þræði, þá geturðu náð 5 römmum á sekúndu með nægilegum fjölda hnúta (10).

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 er það sem gerðist:

Myndband af Cloud Object Detector á Raspberry Pi

Örlítið hraðari en með NCS, en öflugri en í einum straumi.

Hagnaðurinn er auðvitað ekki línulegur - það eru yfirlög fyrir samstillingu og djúpa afritun á opencv myndum.

Ályktun

Á heildina litið gerir tilraunin okkur kleift að álykta að ef þú reynir geturðu komist upp með einfalt ský.

En öflugur skjáborðs- eða staðbundinn vélbúnaður gerir þér kleift að ná betri árangri og án allra brellna.

tilvísanir

Heimild: www.habr.com

Bæta við athugasemd