Raspberry Pi'deki Bulut Nesne Dedektörünün Videosu

prolog

Şu anda internette Tesla'nın otopilotunun yolu nasıl gördüğünü gösteren bir video dolaşıyor.

Uzun zamandır bir dedektörle zenginleştirilmiş videoyu gerçek zamanlı olarak yayınlamak için can atıyordum.

Raspberry Pi'deki Bulut Nesne Dedektörünün Videosu

Sorun şu ki, Raspberry'den video yayınlamak istiyorum ve üzerindeki sinir ağı dedektörünün performansı arzu edilenden çok uzak.

Intel Sinir Bilgisayar Çubuğu

Farklı çözümler düşündüm.

В son makale Intel Neural Computer Stick ile deneyler yapıldı. Donanım güçlüdür ancak kendi ağ formatını gerektirir.

Her ne kadar Intel büyük çerçeveler için dönüştürücüler sağlasa da bir takım tuzaklar var.

Örneğin gerekli ağın formatı uyumsuz olabilir ve uyumluysa cihazda bazı katmanlar desteklenmeyebilir, destekleniyorsa dönüştürme işlemi sırasında hatalar meydana gelebilir ve bunun sonucunda çıktıda bazı tuhaf şeyler elde ediyoruz.

Genel olarak, bir tür rastgele sinir ağı istiyorsanız, NCS ile çalışmayabilir. Bu nedenle sorunu en yaygın ve erişilebilir araçları kullanarak çözmeye karar verdim.

Облако

Yerel donanım çözümünün bariz alternatifi buluta geçmektir.

Hazır seçenekler - gözlerim çıldırıyor.

Tüm liderler:

... Ve daha az bilinen onlarcası.

Bu çeşitlilik arasında seçim yapmak hiç de kolay değil.

Ve seçim yapmamaya, eski güzel çalışma planını Docker'daki OpenCV'ye sarmaya ve bulutta çalıştırmaya karar verdim.

Bu yaklaşımın avantajı esneklik ve kontroldür - sinir ağını, barındırmayı, sunucuyu - genel olarak herhangi bir hevesle değiştirebilirsiniz.

Sunucu

Yerel bir prototiple başlayalım.

Geleneksel olarak REST API, OpenCV ve MobileSSD ağı için Flask'ı kullanıyorum.

Güncel sürümleri Docker'a yükledikten sonra OpenCV 4.1.2'nin Mobile SSD v1_coco_2018_01_28 ile çalışmadığını keşfettim ve kanıtlanmış 11/06_2017 sürümüne geri dönmek zorunda kaldım.

Hizmetin başlangıcında sınıf adlarını ve ağı yüklüyoruz:

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

Yerel bir liman işçisinde (çok genç olmayan bir dizüstü bilgisayarda) Raspberry'de 0.3 saniye sürer - 3.5.

Hesaplamaya başlayalım:

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 saniye, Ahududu - 1.7.

Tensör egzozunu okunabilir json'a dönüştürmek:

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

ayrıca bu işlemi Flask aracılığıyla dışa aktar(giriş bir resimdir, çıkış ise dedektörün json cinsinden sonuçlarıdır).

Daha fazla işin sunucuya kaydırıldığı alternatif bir seçenek: kendisi bulunan nesneleri daire içine alır ve bitmiş görüntüyü döndürür.

Bu seçenek, opencv'yi sunucuya sürüklemek istemediğimiz durumlarda iyidir.

Liman işçisi

Görüntüyü topluyoruz.

Kod tarandı ve yayınlandı Github, docker onu doğrudan oradan alacaktır.

Platform olarak Raspberry'dekiyle aynı Debian Stretch'i kullanacağız; kanıtlanmış teknoloji yığınından sapmayacağız.

Github'dan flask, protobuf, request, opencv_python kurmanız, Mobile SSD, sunucu kodunu indirmeniz ve sunucuyu başlatmanız gerekiyor.

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

basit dedektör istemcisi isteklere dayanmaktadır.

Docker Hub'da Yayınlama

Docker kayıtları, bulut dedektörlerinden daha az olmayan bir hızla çoğalıyor.

Rahatsız etmemek için muhafazakar bir şekilde geçeceğiz DockerHub.

  1. Kayıt olmak
  2. Giriş yapmak:
    liman işçisi girişi
  3. Anlamlı bir isim bulalım:
    docker etiketi opencv-detect tprlab/opencv-detect-ssd
  4. Resmi sunucuya yükleyin:
    docker push tprlab/opencv-detect-ssd

Bulutta başlatıyoruz

Konteynerin nerede çalıştırılacağı seçimi de oldukça geniştir.

Tüm büyük oyuncular (Google, Microsoft, Amazon) ilk yıl için ücretsiz bir mikro örnek sunuyor.
Microsoft Azure ve Google Cloud ile denemeler yaptıktan sonra daha hızlı sonuç verdiği için ikincisinde karar kıldım.

Bu bölüm seçilen sağlayıcıya çok özel olduğundan talimatları buraya yazmadım.

Farklı donanım seçeneklerini denedim,
Düşük seviyeler (paylaşılan ve ayrılmış) - 0.4 - 0.5 saniye.
Daha güçlü arabalar - 0.25 - 0.3.
En kötü senaryoda bile kazançlar üç katına çıkar, deneyebilirsiniz.

Video

Raspberry'de Google Cloud aracılığıyla tespit yapan basit bir OpenCV video aktarıcısını başlatıyoruz.
Deney için, bir zamanlar rastgele bir kavşakta çekilmiş bir video dosyası kullanıldı.


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

Dedektörle saniyede üç kareden fazlasını alamıyoruz, her şey çok yavaş ilerliyor.
Güçlü bir makineyi GCloud'a alırsanız saniyede 4-5 kare tespit edebilirsiniz ancak fark neredeyse gözle görülemez, yine de yavaştır.

Raspberry Pi'deki Bulut Nesne Dedektörünün Videosu

Bulut ve ulaşım maliyetlerinin bununla hiçbir alakası yok, dedektör sıradan bir donanım üzerinde çalışıyor ve o kadar hızlı çalışıyor.

Nöral Bilgisayar Çubuğu

Dayanamadım ve kıyaslamayı NCS'de çalıştırdım.

Dedektörün hızı 0.1 saniyeden biraz daha yavaştı, her halükarda zayıf bir makinedeki buluttan 2-3 kat daha hızlıydı, yani saniyede 8-9 kare.

Raspberry Pi'deki Bulut Nesne Dedektörünün Videosu

Sonuçlardaki fark, NCS'nin Mobil SSD 2018_01_28 sürümünü çalıştırmasıyla açıklanmaktadır.

PS Ayrıca deneyler, I7 işlemcili oldukça güçlü bir masaüstü makinenin biraz daha iyi sonuçlar verdiğini ve üzerinde saniyede 10 kare sıkıştırmanın mümkün olduğunu gösterdi.

Küme

Deney daha da ileri gitti ve dedektörü Google Kubernetes'teki beş düğüme kurdum.
Bölmelerin kendisi zayıftı ve her biri saniyede 2 kareden fazlasını işleyemiyordu.
Ancak N düğümlü bir küme çalıştırırsanız ve N iş parçacığında çerçeveleri ayrıştırırsanız, yeterli sayıda düğümle (5) saniyede istenen 10 kareyi elde edebilirsiniz.

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

İşte olanlar:

Raspberry Pi'deki Bulut Nesne Dedektörünün Videosu

NCS'den biraz daha yavaş, ancak tek akıştan daha güçlü.

Kazanç elbette doğrusal değil - opencv görüntülerin senkronizasyonu ve derin kopyalanması için katmanlar var.

Sonuç

Genel olarak deney, eğer denerseniz basit bir buluttan kurtulabileceğiniz sonucuna varmamızı sağlıyor.

Ancak güçlü bir masaüstü veya yerel donanım, herhangi bir hileye gerek kalmadan daha iyi sonuçlar elde etmenizi sağlar.

referanslar

Kaynak: habr.com

Yorum ekle