Video Pengesan Objek Awan pada Raspberry Pi

Prolog

Video kini beredar di Internet yang menunjukkan cara juruterbang auto Tesla melihat jalan.

Saya telah lama gatal untuk menyiarkan video yang diperkaya dengan pengesan, dan dalam masa nyata.

Video Pengesan Objek Awan pada Raspberry Pi

Masalahnya ialah saya ingin menyiarkan video dari Raspberry, dan prestasi pengesan rangkaian saraf di atasnya meninggalkan banyak yang diinginkan.

Stick Komputer Intel Neural

Saya mempertimbangkan penyelesaian yang berbeza.

Π’ artikel terakhir bereksperimen dengan Intel Neural Computer Stick. Perkakasan itu berkuasa, tetapi memerlukan format rangkaiannya sendiri.

Walaupun Intel menyediakan penukar untuk rangka kerja utama, terdapat beberapa perangkap.

Sebagai contoh, format rangkaian yang diperlukan mungkin tidak serasi, dan jika ia serasi, maka beberapa lapisan mungkin tidak disokong pada peranti, dan jika ia disokong, maka ralat mungkin berlaku semasa proses penukaran, akibatnya kita mendapat beberapa perkara pelik pada output.

Secara umum, jika anda mahukan beberapa jenis rangkaian saraf arbitrari, maka ia mungkin tidak berfungsi dengan NCS. Oleh itu, saya memutuskan untuk cuba menyelesaikan masalah menggunakan alat yang paling meluas dan boleh diakses.

Awan

Alternatif yang jelas kepada penyelesaian perkakasan tempatan ialah pergi ke awan.

Pilihan yang sedia dibuat - mata saya meliar.

Semua pemimpin:

... Dan berpuluh-puluh yang kurang dikenali.

Memilih antara varieti ini sama sekali tidak mudah.

Dan saya memutuskan untuk tidak memilih, tetapi untuk membungkus skema kerja lama yang baik pada OpenCV di Docker dan menjalankannya di awan.

Kelebihan pendekatan ini ialah fleksibiliti dan kawalan - anda boleh menukar rangkaian saraf, pengehosan, pelayan - secara umum, apa-apa kehendak.

pelayan

Mari kita mulakan dengan prototaip tempatan.

Secara tradisinya saya menggunakan Flask untuk REST API, OpenCV dan rangkaian MobileSSD.

Setelah memasang versi semasa pada Docker, saya mendapati OpenCV 4.1.2 tidak berfungsi dengan SSD Mudah Alih v1_coco_2018_01_28, dan saya terpaksa kembali ke 11/06_2017 yang telah terbukti.

Pada permulaan perkhidmatan, kami memuatkan nama kelas dan rangkaian:

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

Pada docker tempatan (pada komputer riba yang tidak terlalu muda) ia mengambil masa 0.3 saat, pada Raspberry - 3.5.

Mari kita mulakan pengiraan:

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 saat, Raspberry - 1.7.

Mengubah ekzos tensor menjadi json yang boleh dibaca:

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

lagi eksport operasi ini melalui Flask(input adalah gambar, output adalah hasil pengesan dalam json).

Pilihan alternatif, di mana lebih banyak kerja dialihkan ke pelayan: ia sendiri mengelilingi objek yang ditemui dan mengembalikan imej yang telah siap.

Pilihan ini bagus di mana kita tidak mahu menyeret opencv ke pelayan.

Docker

Kami mengumpul imej.

Kod disikat dan disiarkan pada Github, docker akan mengambilnya terus dari sana.

Sebagai platform, kami akan menggunakan Debian Stretch yang sama seperti pada Raspberry - kami tidak akan menyimpang daripada susunan teknologi yang terbukti.

Anda perlu memasang kelalang, protobuf, permintaan, opencv_python, muat turun SSD Mudah Alih, kod pelayan daripada Github dan mulakan pelayan.

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

ΠŸΡ€ΠΎΡΡ‚ΠΎΠΉ pelanggan pengesan berdasarkan permintaan.

Menerbitkan ke Docker Hub

Pendaftaran Docker membiak pada kelajuan tidak kurang daripada pengesan awan.

Untuk tidak mengganggu, kami akan secara konservatif melalui DockerHub.

  1. Daftar
  2. Log masuk:
    log masuk buruh pelabuhan
  3. Mari kita dapatkan nama yang bermakna:
    tag docker opencv-detect tprlab/opencv-detect-ssd
  4. Muat naik imej ke pelayan:
    docker push tprlab/opencv-detect-ssd

Kami melancarkan dalam awan

Pilihan tempat untuk menjalankan kontena juga agak luas.

Semua pemain besar (Google, Microsoft, Amazon) menawarkan contoh mikro secara percuma untuk tahun pertama.
Selepas bereksperimen dengan Microsoft Azure dan Google Cloud, saya memilih yang kedua kerana ia berlepas lebih cepat.

Saya tidak menulis arahan di sini, kerana bahagian ini sangat khusus untuk pembekal yang dipilih.

Saya mencuba pilihan perkakasan yang berbeza,
Tahap rendah (berkongsi dan berdedikasi) - 0.4 - 0.5 saat.
Kereta yang lebih berkuasa - 0.25 - 0.3.
Nah, walaupun dalam senario terburuk, kemenangan adalah tiga kali ganda, anda boleh mencuba.

Video

Kami melancarkan penstrim video OpenCV ringkas pada Raspberry, mengesan melalui Google Cloud.
Untuk percubaan, fail video telah digunakan yang pernah dirakam di persimpangan rawak.


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

Dengan pengesan kami mendapat tidak lebih daripada tiga bingkai sesaat, semuanya berjalan dengan perlahan.
Jika anda membawa mesin berkuasa ke dalam GCloud, anda boleh mengesan 4-5 bingkai sesaat, tetapi perbezaannya hampir tidak dapat dilihat oleh mata, ia masih perlahan.

Video Pengesan Objek Awan pada Raspberry Pi

Kos awan dan pengangkutan tidak ada kaitan dengannya; pengesan berjalan pada perkakasan biasa dan berfungsi pada kelajuan sedemikian.

Batang Komputer Neural

Saya tidak dapat menahan dan menjalankan penanda aras pada NCS.

Kelajuan pengesan adalah lebih perlahan sedikit daripada 0.1 saat, dalam apa jua keadaan 2-3 kali lebih cepat daripada awan pada mesin yang lemah, iaitu 8-9 bingkai sesaat.

Video Pengesan Objek Awan pada Raspberry Pi

Perbezaan dalam keputusan dijelaskan oleh fakta bahawa NCS menjalankan SSD Mudah Alih versi 2018_01_28.

P.S. Di samping itu, eksperimen telah menunjukkan bahawa mesin desktop yang cukup berkuasa dengan pemproses I7 menunjukkan hasil yang lebih baik sedikit dan ternyata mungkin untuk memerah 10 bingkai sesaat.

Kluster

Percubaan pergi lebih jauh dan saya memasang pengesan pada lima nod dalam Google Kubernetes.
Pod itu sendiri lemah dan setiap daripadanya tidak dapat memproses lebih daripada 2 bingkai sesaat.
Tetapi jika anda menjalankan gugusan dengan N nod dan menghuraikan bingkai dalam N benang, maka dengan bilangan nod yang mencukupi (5) anda boleh mencapai 10 bingkai sesaat yang dikehendaki.

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

Berikut adalah apa yang berlaku:

Video Pengesan Objek Awan pada Raspberry Pi

Sedikit kurang pantas berbanding dengan NCS, tetapi lebih bertenaga daripada dalam satu aliran.

Keuntungan, sudah tentu, tidak linear - terdapat tindanan untuk penyegerakan dan penyalinan dalam imej opencv.

Kesimpulan

Secara keseluruhan, percubaan membolehkan kami membuat kesimpulan bahawa jika anda mencuba, anda boleh melarikan diri dengan awan yang mudah.

Tetapi desktop yang berkuasa atau perkakasan tempatan membolehkan anda mencapai hasil yang lebih baik, dan tanpa sebarang helah.

rujukan

Sumber: www.habr.com

Tambah komen