วิดีโอของ Cloud Object Detector บน Raspberry Pi

อารัมภบท

ขณะนี้วิดีโอกำลังเผยแพร่บนอินเทอร์เน็ตเพื่อแสดงให้เห็นว่าระบบขับเคลื่อนอัตโนมัติของ Tesla มองเห็นถนนได้อย่างไร

ฉันอยากออกอากาศวิดีโอที่มีเครื่องตรวจจับและแบบเรียลไทม์มาเป็นเวลานาน

วิดีโอของ Cloud Object Detector บน Raspberry Pi

ปัญหาคือฉันต้องการออกอากาศวิดีโอจาก Raspberry และประสิทธิภาพของเครื่องตรวจจับโครงข่ายประสาทเทียมบนนั้นยังเป็นที่ต้องการอย่างมาก

Intel Neural คอมพิวเตอร์สติ๊ก

ฉันพิจารณาวิธีแก้ปัญหาที่แตกต่างกัน

В บทความล่าสุด ทดลองใช้ Intel Neural Computer Stick ฮาร์ดแวร์มีประสิทธิภาพ แต่ต้องมีรูปแบบเครือข่ายของตัวเอง

แม้ว่า Intel จะจัดเตรียมคอนเวอร์เตอร์สำหรับเฟรมเวิร์กหลักๆ แต่ก็มีข้อผิดพลาดอยู่หลายประการ

ตัวอย่างเช่น รูปแบบของเครือข่ายที่ต้องการอาจเข้ากันไม่ได้ และหากเข้ากันได้ อุปกรณ์บางเลเยอร์อาจไม่รองรับ และหากได้รับการรองรับ ข้อผิดพลาดอาจเกิดขึ้นในระหว่างกระบวนการแปลง ซึ่งเป็นผลให้ เราได้รับสิ่งแปลก ๆ ที่เอาต์พุต

โดยทั่วไป หากคุณต้องการโครงข่ายประสาทเทียมตามอำเภอใจ เครือข่ายนั้นอาจไม่ทำงานกับ NCS ดังนั้นฉันจึงตัดสินใจพยายามแก้ไขปัญหาโดยใช้เครื่องมือที่แพร่หลายและเข้าถึงได้มากที่สุด

เมฆ

ทางเลือกที่ชัดเจนสำหรับโซลูชันฮาร์ดแวร์ในเครื่องคือการไปที่ระบบคลาวด์

ตัวเลือกที่เตรียมไว้ - ดวงตาของฉันดุร้าย

ผู้นำทั้งหมด:

... และอีกหลายคนที่ไม่ค่อยมีใครรู้จัก

การเลือกความหลากหลายนี้ไม่ใช่เรื่องง่ายเลย

และฉันตัดสินใจที่จะไม่เลือก แต่ต้องรวมรูปแบบการทำงานเก่าที่ดีบน OpenCV ใน Docker และรันในระบบคลาวด์

ข้อดีของแนวทางนี้คือความยืดหยุ่นและการควบคุม - คุณสามารถเปลี่ยนโครงข่ายประสาทเทียม, โฮสติ้ง, เซิร์ฟเวอร์ - โดยทั่วไปได้ตามต้องการ

เซิร์ฟเวอร์

เริ่มจากต้นแบบท้องถิ่นกันก่อน

ตามเนื้อผ้าฉันใช้ Flask สำหรับเครือข่าย REST API, OpenCV และ MobileSSD

หลังจากติดตั้งเวอร์ชันปัจจุบันบน Docker ฉันพบว่า OpenCV 4.1.2 ไม่ทำงานกับ Mobile SSD v1_coco_2018_01_28 และฉันต้องย้อนกลับไปเป็น 11/06_2017 ที่ได้รับการพิสูจน์แล้ว

เมื่อเริ่มต้นบริการ เราจะโหลดชื่อคลาสและเครือข่าย:

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

บนนักเทียบท่าในพื้นที่ (บนแล็ปท็อปที่อายุไม่มาก) ใช้เวลา 0.3 วินาทีบน Raspberry - 3.5

มาเริ่มการคำนวณกันดีกว่า:

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

นักเทียบท่า - 0.2 วินาที, ราสเบอร์รี่ - 1.7

เปลี่ยนไอเสียเทนเซอร์ให้เป็น 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

ต่อไป ส่งออกการดำเนินการนี้ผ่าน Flask(อินพุตคือรูปภาพ เอาต์พุตคือผลลัพธ์ของตัวตรวจจับใน json)

ตัวเลือกอื่นซึ่งมีการเลื่อนงานไปที่เซิร์ฟเวอร์มากขึ้น: ตัวมันเองจะวนวัตถุที่พบและส่งกลับภาพที่เสร็จสมบูรณ์

ตัวเลือกนี้ดีเมื่อเราไม่ต้องการลาก opencv ไปยังเซิร์ฟเวอร์

นักเทียบท่า

เรารวบรวมภาพ

รหัสถูกหวีและโพสต์ไว้ Githubนักเทียบท่าจะนำมันโดยตรงจากที่นั่น

ในฐานะแพลตฟอร์ม เราจะใช้ Debian Stretch เช่นเดียวกับ Raspberry - เราจะไม่เบี่ยงเบนไปจากกลุ่มเทคโนโลยีที่ได้รับการพิสูจน์แล้ว

คุณต้องติดตั้ง flask, protobuf, คำขอ, opencv_python, ดาวน์โหลด Mobile SSD, รหัสเซิร์ฟเวอร์จาก Github และเริ่มต้นเซิร์ฟเวอร์

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

ง่าย ลูกค้าเครื่องตรวจจับ ตามคำขอ

การเผยแพร่ไปยัง Docker Hub

การลงทะเบียนนักเทียบท่ากำลังทวีคูณด้วยความเร็วไม่น้อยไปกว่าตัวตรวจจับคลาวด์

เพื่อไม่ให้เป็นการรบกวนเราจะดำเนินการอย่างระมัดระวัง นักเทียบท่าฮับ.

  1. ลงทะเบียน
  2. เข้าสู่ระบบ:
    นักเทียบท่าเข้าสู่ระบบ
  3. เรามาตั้งชื่อที่มีความหมายกันดีกว่า:
    แท็กนักเทียบท่า opencv-detect tprlab/opencv-detect-ssd
  4. อัปโหลดภาพไปยังเซิร์ฟเวอร์:
    นักเทียบท่ากด tprlab/opencv-detect-ssd

เราเปิดตัวในระบบคลาวด์

ทางเลือกของตำแหน่งที่จะเรียกใช้คอนเทนเนอร์ก็ค่อนข้างกว้างเช่นกัน

ผู้เล่นรายใหญ่ทั้งหมด (Google, Microsoft, Amazon) เสนออินสแตนซ์ขนาดเล็กฟรีในปีแรก
หลังจากทดลองใช้ Microsoft Azure และ Google Cloud ฉันตัดสินใจเลือกอย่างหลังเพราะมันเริ่มเร็วขึ้น

ฉันไม่ได้เขียนคำแนะนำที่นี่ เนื่องจากส่วนนี้มีความเฉพาะเจาะจงมากสำหรับผู้ให้บริการที่เลือก

ฉันลองใช้ตัวเลือกฮาร์ดแวร์ที่แตกต่างกัน
ระดับต่ำ (แชร์และทุ่มเท) - 0.4 - 0.5 วินาที
รถยนต์ที่ทรงพลังยิ่งขึ้น - 0.25 - 0.3
แม้ว่าในกรณีที่เลวร้ายที่สุด การชนะจะเป็นสามครั้ง คุณสามารถลองได้

วีดีโอ

เราเปิดตัวสตรีมเมอร์วิดีโอ OpenCV อย่างง่ายบน Raspberry โดยตรวจจับผ่าน Google Cloud
สำหรับการทดลองนี้ ใช้ไฟล์วิดีโอที่เคยถ่ายที่สี่แยกสุ่ม


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

ด้วยเครื่องตรวจจับเราจะได้ไม่เกินสามเฟรมต่อวินาทีทุกอย่างดำเนินไปช้ามาก
หากคุณนำเครื่องจักรอันทรงพลังเข้าสู่ GCloud คุณสามารถตรวจจับได้ 4-5 เฟรมต่อวินาที แต่ความแตกต่างนั้นแทบจะมองไม่เห็นด้วยตาเปล่า แต่ก็ยังช้าอยู่

วิดีโอของ Cloud Object Detector บน Raspberry Pi

ต้นทุนคลาวด์และการขนส่งไม่เกี่ยวข้องเลย ตัวตรวจจับทำงานบนฮาร์ดแวร์ธรรมดาและทำงานด้วยความเร็วขนาดนั้น

สติ๊กคอมพิวเตอร์ประสาท

ฉันอดใจไม่ไหวและรันการวัดประสิทธิภาพบน NCS

ความเร็วของเครื่องตรวจจับช้ากว่า 0.1 วินาทีเล็กน้อย ไม่ว่าในกรณีใดเร็วกว่าคลาวด์บนเครื่องที่อ่อนแอ 2-3 เท่าเช่น 8-9 เฟรมต่อวินาที

วิดีโอของ Cloud Object Detector บน Raspberry Pi

ความแตกต่างในผลลัพธ์อธิบายได้จากข้อเท็จจริงที่ว่า NCS ใช้ Mobile SSD เวอร์ชัน 2018_01_28

ป.ล. นอกจากนี้การทดลองแสดงให้เห็นว่าเครื่องเดสก์ท็อปที่ทรงพลังพอสมควรซึ่งมีโปรเซสเซอร์ I7 แสดงผลลัพธ์ที่ดีกว่าเล็กน้อยและปรากฏว่าเป็นไปได้ที่จะบีบ 10 เฟรมต่อวินาที

กลุ่ม

การทดลองดำเนินต่อไปอีกขั้น และฉันได้ติดตั้งตัวตรวจจับบนโหนดห้าโหนดใน Google Kubernetes
ตัวพ็อดเองนั้นอ่อนแอและแต่ละตัวไม่สามารถประมวลผลได้มากกว่า 2 เฟรมต่อวินาที
แต่ถ้าคุณรันคลัสเตอร์ที่มี N โหนดและแยกเฟรมใน N เธรด ด้วยจำนวนโหนดที่เพียงพอ (5) คุณสามารถบรรลุ 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

นี่คือสิ่งที่เกิดขึ้น:

วิดีโอของ Cloud Object Detector บน Raspberry Pi

เร็วกว่า NCS เล็กน้อย แต่แข็งแกร่งกว่าในสตรีมเดียว

แน่นอนว่าการได้รับนั้นไม่เป็นเชิงเส้น - มีการซ้อนทับสำหรับการซิงโครไนซ์และการคัดลอกรูปภาพ opencv แบบลึก

ข้อสรุป

โดยรวมแล้ว การทดลองช่วยให้เราสรุปได้ว่าหากคุณลอง คุณจะรอดจากระบบคลาวด์ธรรมดาๆ ได้

แต่เดสก์ท็อปหรือฮาร์ดแวร์ภายในเครื่องที่มีประสิทธิภาพช่วยให้คุณได้ผลลัพธ์ที่ดีขึ้น และไม่มีลูกเล่นใดๆ

การอ้างอิง

ที่มา: will.com

เพิ่มความคิดเห็น