Raspberry Pi-da bulutli ob'ekt detektori videosi

Prologiya

Hozir internetda Tesla avtopiloti yo'lni qanday ko'rishini ko'rsatadigan video tarqalmoqda.

Men detektor bilan boyitilgan videoni va real vaqtda efirga uzatish uchun uzoq vaqt qichimadim.

Raspberry Pi-da bulutli ob'ekt detektori videosi

Muammo shundaki, men Raspberry-dan videoni efirga uzatmoqchiman va undagi neyron tarmoq detektorining ishlashi ko'p narsani orzu qiladi.

Intel neyron kompyuter tayoqchasi

Men turli xil echimlarni ko'rib chiqdim.

Π’ oxirgi maqola Intel Neural Computer Stick bilan tajriba o'tkazdi. Uskuna kuchli, lekin o'zining tarmoq formatini talab qiladi.

Intel asosiy ramkalar uchun konvertorlarni taqdim etsa ham, bir qator tuzoqlar mavjud.

Masalan, kerakli tarmoq formati mos kelmasligi mumkin va agar u mos kelsa, qurilmada ba'zi qatlamlar qo'llab-quvvatlanmasligi mumkin va agar ular qo'llab-quvvatlansa, konvertatsiya jarayonida xatolar yuzaga kelishi mumkin, buning natijasida biz chiqishda g'alati narsalarni olamiz.

Umuman olganda, agar siz biron bir ixtiyoriy neyron tarmoqni xohlasangiz, u NCS bilan ishlamasligi mumkin. Shuning uchun men muammoni eng keng tarqalgan va mavjud vositalar yordamida hal qilishga qaror qildim.

Bulut

Mahalliy apparat yechimiga aniq alternativ bulutga o'tishdir.

Tayyor variantlar - ko'zlaringiz yovvoyi yuguradi.

Barcha rahbarlar:

... Va o'nlab kamroq ma'lum bo'lganlar.

Bu xilma-xillikni tanlash unchalik oson emas.

Va men tanlashga emas, balki Docker-dagi OpenCV-da eski yaxshi ish sxemasini o'rashga va uni bulutda ishga tushirishga qaror qildim.

Ushbu yondashuvning afzalligi moslashuvchanlik va nazoratdir - siz neyron tarmoqni, xostingni, serverni - umuman, har qanday injiqlikni o'zgartirishingiz mumkin.

Server

Keling, mahalliy prototipdan boshlaylik.

An'anaviy ravishda men REST API, OpenCV va MobileSSD tarmoqlari uchun Flask-dan foydalanaman.

Docker-ga joriy versiyalarni o'rnatganimdan so'ng, men OpenCV 4.1.2 Mobile SSD v1_coco_2018_01_28 bilan ishlamasligini aniqladim va men tasdiqlangan 11/06_2017 yilga qaytishga majbur bo'ldim.

Xizmat boshlanishida biz sinf nomlari va tarmoqni yuklaymiz:

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

Mahalliy dokerda (juda yosh bo'lmagan noutbukda) bu 0.3 soniyani oladi, Raspberry'da - 3.5.

Hisoblashni boshlaylik:

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 egzozini o'qiladigan jsonga aylantirish:

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

Bundan tashqari bu operatsiyani Flask orqali eksport qiling(kirish - rasm, chiqish - json-dagi detektorning natijalari).

Muqobil variant, unda ko'proq ish serverga o'tkaziladi: uning o'zi topilgan ob'ektlarni aylantiradi va tayyor tasvirni qaytaradi.

Opencv ni serverga sudrab borishni istamaganimizda bu variant yaxshi.

Docker

Biz rasmni yig'amiz.

Kod taralgan va joylashtirilgan Github, docker uni to'g'ridan-to'g'ri u erdan oladi.

Platforma sifatida biz Raspberry-dagi kabi Debian Stretch-ni olamiz - biz tasdiqlangan texnologik stekdan chetga chiqmaymiz.

Siz flask, protobuf, so'rovlar, opencv_python o'rnatishingiz, Mobil SSD-ni, Github-dan server kodini yuklab olishingiz va serverni ishga tushirishingiz kerak.

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

Oddiy detektor mijozi so'rovlar asosida.

Docker Hub-da nashr qilish

Docker registrlari bulut detektorlaridan kam bo'lmagan tezlikda ko'paymoqda.

Bezovta qilmaslik uchun biz konservativ tarzda o'tamiz DockerHub.

  1. RoΚ»yxatdan oΚ»tish
  2. Tizimga kirish:
    docker login
  3. Keling, ma'noli ismni topaylik:
    docker tegi opencv-detect tprlab/opencv-detect-ssd
  4. Rasmni serverga yuklang:
    docker push tprlab/opencv-detect-ssd

Biz bulutda ishga tushamiz

Konteynerni qaerga ishga tushirishni tanlash ham ancha keng.

Barcha yirik o'yinchilar (Google, Microsoft, Amazon) birinchi yil uchun mikro-naslni bepul taklif qilishadi.
Microsoft Azure va Google Cloud bilan tajriba o'tkazganimdan so'ng, men ikkinchisiga qaror qildim, chunki u tezroq uchib ketdi.

Men bu erda ko'rsatmalar yozmadim, chunki bu qism tanlangan provayderga juda xosdir.

Men turli xil apparat variantlarini sinab ko'rdim,
Past darajalar (birgalikda va ajratilgan) - 0.4 - 0.5 soniya.
Yana kuchli mashinalar - 0.25 - 0.3.
Xo'sh, hatto eng yomon stsenariyda ham, yutuq uch marta, siz sinab ko'rishingiz mumkin.

Π’ΠΈΠ΄Π΅ΠΎ

Biz Raspberry-da Google Cloud orqali aniqlaydigan oddiy OpenCV video strimini ishga tushiramiz.
Tajriba uchun bir marta tasodifiy chorrahada suratga olingan videofayl ishlatilgan.


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

Detektor bilan biz soniyada uch kvadratdan ko'p bo'lmagan kadrlarni olamiz, hamma narsa juda sekin ketadi.
Agar siz GCloud-ga kuchli mashinani olsangiz, soniyada 4-5 kvadratni aniqlay olasiz, ammo farq deyarli ko'zga ko'rinmaydi, u hali ham sekin.

Raspberry Pi-da bulutli ob'ekt detektori videosi

Bulutli va transport xarajatlari bunga hech qanday aloqasi yo'q, detektor oddiy uskunada ishlaydi va shunday tezlikda ishlaydi.

Neyron kompyuter tayoqchasi

Men qarshilik ko'rsata olmadim va NCSda benchmarkni o'tkazdim.

Detektorning tezligi 0.1 soniyadan biroz sekinroq, har holda zaif mashinadagi bulutdan 2-3 baravar tezroq, ya'ni soniyada 8-9 kvadrat.

Raspberry Pi-da bulutli ob'ekt detektori videosi

Natijalardagi farq NCS mobil SSD versiyasi 2018_01_28 ishlayotganligi bilan izohlanadi.

P.S. Bundan tashqari, tajribalar shuni ko'rsatdiki, I7 protsessorli juda kuchli ish stoli mashinasi biroz yaxshiroq natijalarni ko'rsatadi va soniyada 10 kadrni siqib chiqarish mumkin bo'ldi.

Klaster

Tajriba davom etdi va men detektorni Google Kubernetes-dagi beshta tugunga o'rnatdim.
Podlarning o'zi zaif edi va ularning har biri soniyasiga 2 kvadratdan ko'proq ishlov bera olmadi.
Ammo agar siz N tugunli klasterni ishga tushirsangiz va N ta ipda ramkalarni tahlil qilsangiz, unda etarli miqdordagi tugunlar (5) bilan siz sekundiga 10 kvadratga erishishingiz mumkin.

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

Mana nima bo'ldi:

Raspberry Pi-da bulutli ob'ekt detektori videosi

NCSga qaraganda bir oz tezroq, lekin bitta oqimga qaraganda kuchliroq.

Daromad, albatta, chiziqli emas - sinxronizatsiya va opencv tasvirlarini chuqur nusxalash uchun qoplamalar mavjud.

xulosa

Umuman olganda, tajriba, agar siz harakat qilsangiz, oddiy bulutdan qutulishingiz mumkin degan xulosaga kelishimizga imkon beradi.

Ammo kuchli ish stoli yoki mahalliy apparat sizga hech qanday hiyla-nayranglarsiz yaxshi natijalarga erishishga imkon beradi.

Manbalar

Manba: www.habr.com

a Izoh qo'shish