रास्पबेरी पाई पर क्लाउड ऑब्जेक्ट डिटेक्टर का वीडियो

प्रस्तावना

एक वीडियो अब इंटरनेट पर प्रसारित हो रहा है जिसमें दिखाया गया है कि टेस्ला का ऑटोपायलट सड़क को कैसे देखता है।

मैं लंबे समय से डिटेक्टर से समृद्ध वीडियो को वास्तविक समय में प्रसारित करने के लिए इच्छुक हूं।

रास्पबेरी पाई पर क्लाउड ऑब्जेक्ट डिटेक्टर का वीडियो

समस्या यह है कि मैं रास्पबेरी से वीडियो प्रसारित करना चाहता हूं, और उस पर तंत्रिका नेटवर्क डिटेक्टर का प्रदर्शन वांछित होने के लिए बहुत कुछ छोड़ देता है।

इंटेल न्यूरल कंप्यूटर स्टिक

मैंने विभिन्न समाधानों पर विचार किया।

В अंतिम लेख इंटेल न्यूरल कंप्यूटर स्टिक के साथ प्रयोग किया गया। हार्डवेयर शक्तिशाली है, लेकिन इसके लिए अपने स्वयं के नेटवर्क प्रारूप की आवश्यकता होती है।

हालाँकि इंटेल प्रमुख ढाँचों के लिए कन्वर्टर्स प्रदान करता है, फिर भी इसमें कई खामियाँ हैं।

उदाहरण के लिए, आवश्यक नेटवर्क का प्रारूप असंगत हो सकता है, और यदि यह संगत है, तो डिवाइस पर कुछ परतें समर्थित नहीं हो सकती हैं, और यदि वे समर्थित हैं, तो रूपांतरण प्रक्रिया के दौरान त्रुटियां हो सकती हैं, जिसके परिणामस्वरूप हमें आउटपुट पर कुछ अजीब चीजें मिलती हैं।

सामान्य तौर पर, यदि आप किसी प्रकार का मनमाना तंत्रिका नेटवर्क चाहते हैं, तो यह एनसीएस के साथ काम नहीं कर सकता है। इसलिए, मैंने सबसे व्यापक और सुलभ उपकरणों का उपयोग करके समस्या को हल करने का प्रयास करने का निर्णय लिया।

बादल

स्थानीय हार्डवेयर समाधान का स्पष्ट विकल्प क्लाउड पर जाना है।

तैयार विकल्प - मेरी आँखें घूम जाती हैं।

सभी नेता:

...और दर्जनों कम ज्ञात।

इस किस्म में से चयन करना बिल्कुल भी आसान नहीं है।

और मैंने चुनने का नहीं, बल्कि Docker में OpenCV पर अच्छी पुरानी कार्यशील योजना को लपेटने और इसे क्लाउड में चलाने का निर्णय लिया।

इस दृष्टिकोण का लाभ लचीलापन और नियंत्रण है - आप तंत्रिका नेटवर्क, होस्टिंग, सर्वर - सामान्य तौर पर, किसी भी समय बदल सकते हैं।

सेवक

आइए एक स्थानीय प्रोटोटाइप से शुरुआत करें।

परंपरागत रूप से मैं REST API, OpenCV और MobileSSD नेटवर्क के लिए फ्लास्क का उपयोग करता हूं।

डॉकर पर वर्तमान संस्करण स्थापित करने के बाद, मुझे पता चला कि OpenCV 4.1.2 मोबाइल 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 सेकंड लगते हैं, रास्पबेरी पर - 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।

टेंसर एग्जॉस्ट को पठनीय जेसन में बदलना:

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

आगे इस ऑपरेशन को फ्लास्क के माध्यम से निर्यात करें(इनपुट एक चित्र है, आउटपुट json में डिटेक्टर के परिणाम है)।

एक वैकल्पिक विकल्प, जिसमें अधिक काम सर्वर पर स्थानांतरित कर दिया जाता है: यह स्वयं पाए गए ऑब्जेक्ट को घेरता है और तैयार छवि लौटाता है।

यह विकल्प अच्छा है जहां हम opencv को सर्वर पर नहीं खींचना चाहते।

डाक में काम करनेवाला मज़दूर

हम छवि एकत्र करते हैं.

कोड को खंगाला जाता है और पोस्ट किया जाता है 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"]

सरल डिटेक्टर क्लाइंट अनुरोधों के आधार पर।

डॉकर हब पर प्रकाशन

डॉकर रजिस्ट्रियां क्लाउड डिटेक्टरों से कम गति से नहीं बढ़ रही हैं।

परेशान न होने के लिए, हम रूढ़िवादी तरीके से आगे बढ़ेंगे डॉकरहब.

  1. पंजीकरण करवाना
  2. लॉग इन करें:
    डोकर लॉगिन
  3. आइए एक सार्थक नाम लेकर आएं:
    डॉकर टैग ओपनसीवी-डिटेक्ट टीपीआरलैब/ओपनसीवी-डिटेक्ट-एसएसडी
  4. छवि को सर्वर पर अपलोड करें:
    डॉकर पुश टीपीआरलैब/ओपनसीवी-डिटेक्ट-एसएसडी

हम क्लाउड में लॉन्च करते हैं

कंटेनर को कहां चलाना है इसका विकल्प भी काफी विस्तृत है।

सभी बड़े खिलाड़ी (Google, Microsoft, Amazon) पहले वर्ष के लिए एक माइक्रो-इंस्टेंस निःशुल्क प्रदान करते हैं।
Microsoft Azure और Google Cloud के साथ प्रयोग करने के बाद, मैंने बाद वाले पर निर्णय लिया क्योंकि यह तेजी से आगे बढ़ा।

मैंने यहां निर्देश नहीं लिखे, क्योंकि यह भाग चयनित प्रदाता के लिए बहुत विशिष्ट है।

मैंने विभिन्न हार्डवेयर विकल्प आज़माए,
निम्न स्तर (साझा और समर्पित) - 0.4 - 0.5 सेकंड।
अधिक शक्तिशाली कारें - 0.25 - 0.3।
खैर, सबसे खराब स्थिति में भी, जीत तीन गुना है, आप कोशिश कर सकते हैं।

वीडियो

हमने Google क्लाउड के माध्यम से पता लगाकर रास्पबेरी पर एक सरल ओपनसीवी वीडियो स्ट्रीमर लॉन्च किया है।
प्रयोग के लिए, एक वीडियो फ़ाइल का उपयोग किया गया था जिसे एक बार यादृच्छिक चौराहे पर फिल्माया गया था।


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 फ्रेम का पता लगा सकते हैं, लेकिन अंतर आंखों के लिए लगभग अदृश्य है, यह अभी भी धीमा है।

रास्पबेरी पाई पर क्लाउड ऑब्जेक्ट डिटेक्टर का वीडियो

क्लाउड और परिवहन लागत का इससे कोई लेना-देना नहीं है; डिटेक्टर नियमित हार्डवेयर पर चलता है और उसी गति से काम करता है।

न्यूरल कंप्यूटर स्टिक

मैं विरोध नहीं कर सका और एनसीएस पर बेंचमार्क चलाया।

डिटेक्टर की गति 0.1 सेकंड से थोड़ी धीमी थी, किसी भी स्थिति में कमजोर मशीन पर बादल की तुलना में 2-3 गुना तेज, यानी 8-9 फ्रेम प्रति सेकंड।

रास्पबेरी पाई पर क्लाउड ऑब्जेक्ट डिटेक्टर का वीडियो

परिणामों में अंतर इस तथ्य से समझाया गया है कि एनसीएस मोबाइल एसएसडी संस्करण 2018_01_28 चला रहा था।

पी.एस. इसके अलावा, प्रयोगों से पता चला है कि I7 प्रोसेसर के साथ एक काफी शक्तिशाली डेस्कटॉप मशीन थोड़ा बेहतर परिणाम दिखाती है और प्रति सेकंड 10 फ्रेम निचोड़ना संभव हो गया है।

समूह

प्रयोग आगे बढ़ा और मैंने डिटेक्टर को Google Kubernetes में पाँच नोड्स पर स्थापित किया।
पॉड्स स्वयं कमजोर थे और उनमें से प्रत्येक प्रति सेकंड 2 फ्रेम से अधिक प्रोसेस नहीं कर सका।
लेकिन यदि आप एन नोड्स के साथ एक क्लस्टर चलाते हैं और एन थ्रेड्स में फ्रेम पार्स करते हैं, तो पर्याप्त संख्या में नोड्स (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

यहाँ क्या हुआ है:

रास्पबेरी पाई पर क्लाउड ऑब्जेक्ट डिटेक्टर का वीडियो

एनसीएस की तुलना में थोड़ा कम तेज़, लेकिन एक स्ट्रीम की तुलना में अधिक जोरदार।

बेशक, लाभ रैखिक नहीं है - ओपनसीवी छवियों के सिंक्रनाइज़ेशन और गहरी प्रतिलिपि के लिए ओवरले हैं।

निष्कर्ष

कुल मिलाकर, प्रयोग हमें यह निष्कर्ष निकालने की अनुमति देता है कि यदि आप कोशिश करते हैं, तो आप एक साधारण बादल से बच सकते हैं।

लेकिन एक शक्तिशाली डेस्कटॉप या स्थानीय हार्डवेयर आपको बिना किसी चाल के बेहतर परिणाम प्राप्त करने की अनुमति देता है।

संदर्भों

स्रोत: www.habr.com

एक टिप्पणी जोड़ें