Video detektora objekata u oblaku na Raspberry Pi

Prolog

Internetom sada kruži video koji prikazuje kako Teslin autopilot vidi cestu.

Dugo sam žudio da emitiram video obogaćen detektorom i to u stvarnom vremenu.

Video detektora objekata u oblaku na Raspberry Pi

Problem je u tome što želim emitirati video s Raspberryja, a izvedba detektora neuronske mreže na njemu ostavlja mnogo za poželjeti.

Intel Neural Computer Stick

Razmatrao sam različita rješenja.

В zadnji članak eksperimentirao s Intel Neural Computer Stick. Hardver je moćan, ali zahtijeva vlastiti mrežni format.

Iako Intel nudi pretvarače za glavne okvire, postoji niz zamki.

Na primjer, format tražene mreže može biti nekompatibilan, a ako je kompatibilan, neki slojevi možda neće biti podržani na uređaju, a ako su podržani, može doći do grešaka tijekom procesa konverzije, uslijed čega dobivamo neke čudne stvari na izlazu.

Općenito, ako želite neku vrstu proizvoljne neuronske mreže, ona možda neće raditi s NCS-om. Stoga sam odlučio pokušati riješiti problem koristeći najrasprostranjenije i najpristupačnije alate.

Oblak

Očigledna alternativa lokalnom hardverskom rješenju je odlazak u oblak.

Gotove opcije - oči mi divljaju.

Svi voditelji:

... I deseci manje poznatih.

Odabir među ovom raznolikošću nije nimalo lak.

I odlučio sam ne birati, već umotati staru dobru radnu shemu na OpenCV-u u Docker i pokrenuti je u oblaku.

Prednost ovog pristupa je fleksibilnost i kontrola - možete promijeniti neuronsku mrežu, hosting, poslužitelj - općenito, bilo koji hir.

Server

Počnimo s lokalnim prototipom.

Tradicionalno koristim Flask za REST API, OpenCV i MobileSSD mrežu.

Nakon što sam instalirao trenutne verzije na Docker, otkrio sam da OpenCV 4.1.2 ne radi s Mobile SSD v1_coco_2018_01_28 i morao sam se vratiti na provjerenu 11/06_2017.

Na početku usluge učitavamo nazive klasa i mrežu:

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

Na lokalnom dockeru (na ne baš mladom prijenosnom računalu) potrebno je 0.3 sekunde, na Raspberryju - 3.5.

Krenimo s izračunom:

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.

Pretvaranje tenzorskog ispuha u čitljiv 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

dalje eksportirajte ovu operaciju preko Flaska(ulaz je slika, izlaz rezultati detektora u jsonu).

Alternativna opcija, u kojoj se više posla prebacuje na poslužitelj: on sam kruži pronađene objekte i vraća gotovu sliku.

Ova opcija je dobra kada ne želimo povući opencv na poslužitelj.

Lučki radnik

Sakupljamo sliku.

Šifra je pročešljana i objavljena Github, docker će ga preuzeti izravno od tamo.

Kao platformu, uzet ćemo isti Debian Stretch kao i na Raspberryju - nećemo odstupiti od provjerene tehnologije.

Trebate instalirati flask, protobuf, requests, opencv_python, preuzeti Mobile SSD, kod poslužitelja s Githuba i pokrenuti poslužitelj.

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

Jednostavan klijent detektora na temelju zahtjeva.

Objavljivanje na Docker Hubu

Docker registri množe se brzinom ništa manjom od detektora oblaka.

Da ne bi smetali, proći ćemo konzervativno DockerHub.

  1. Registar
  2. Prijaviti se:
    docker prijava
  3. Smislimo smisleno ime:
    docker oznaka opencv-detect tprlab/opencv-detect-ssd
  4. Prenesi sliku na server:
    docker push tprlab/opencv-detect-ssd

Pokrećemo u oblaku

Izbor mjesta za pokretanje kontejnera također je prilično širok.

Svi veliki igrači (Google, Microsoft, Amazon) nude mikroinstancu besplatno tijekom prve godine.
Nakon eksperimentiranja s Microsoft Azureom i Google Cloudom, odlučio sam se za potonji jer se brže razvio.

Ovdje nisam pisao upute jer je ovaj dio vrlo specifičan za odabranog pružatelja usluga.

Isprobao sam različite opcije hardvera,
Niske razine (dijeljene i namjenske) - 0.4 - 0.5 sekundi.
Snažniji automobili - 0.25 - 0.3.
Pa i u najgorem slučaju dobitak je trostruki, možete pokušati.

video

Pokrećemo jednostavan OpenCV video streamer na Raspberryju, otkrivajući putem Google Clouda.
Za eksperiment je korištena video datoteka koja je jednom snimljena na nasumičnom raskrižju.


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

S detektorom ne dobivamo više od tri slike u sekundi, sve ide jako sporo.
Ako ubacite moćnu mašinu u GCloud, možete detektirati 4-5 sličica u sekundi, ali razlika je gotovo nevidljiva oku, i dalje je spor.

Video detektora objekata u oblaku na Raspberry Pi

Oblak i troškovi transporta nemaju veze s tim, detektor radi na običnom hardveru i radi takvom brzinom.

Neuralni računalni štap

Nisam mogao odoljeti i pokrenuo sam benchmark na NCS-u.

Brzina detektora bila je nešto sporija od 0.1 sekunde, u svakom slučaju 2-3 puta brža od oblaka na slabom stroju, tj. 8-9 sličica u sekundi.

Video detektora objekata u oblaku na Raspberry Pi

Razlika u rezultatima objašnjava se činjenicom da je NCS pokretao Mobile SSD verziju 2018_01_28.

PS Osim toga, eksperimenti su pokazali da prilično moćan stolni stroj s I7 procesorom pokazuje nešto bolje rezultate i pokazalo se da je na njemu moguće stisnuti 10 sličica u sekundi.

Klastera

Eksperiment je otišao dalje i instalirao sam detektor na pet čvorova u Google Kubernetesu.
Sami moduli bili su slabi i svaki od njih nije mogao obraditi više od 2 okvira u sekundi.
Ali ako pokrenete klaster s N čvorova i analizirate okvire u N niti, tada s dovoljnim brojem čvorova (5) možete postići željenih 10 okvira u sekundi.

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

Evo što se dogodilo:

Video detektora objekata u oblaku na Raspberry Pi

Malo manje brzo nego s NCS-om, ali snažnije nego u jednom streamu.

Dobitak, naravno, nije linearan - postoje slojevi za sinkronizaciju i duboko kopiranje opencv slika.

Zaključak

Sve u svemu, eksperiment nam omogućuje da zaključimo da ako pokušate, možete se izvući s jednostavnim oblakom.

Ali moćno stolno računalo ili lokalni hardver omogućuje postizanje boljih rezultata, i to bez ikakvih trikova.

reference

Izvor: www.habr.com

Dodajte komentar