# अपने IoT डिवाइस से स्टॉक गिनें - वर्चुअल IoT हार्डवेयर और रास्पबेरी पाई पूर्वानुमानों और उनके बाउंडिंग बॉक्स का संयोजन छवि में स्टॉक गिनने के लिए उपयोग किया जा सकता है। ## बाउंडिंग बॉक्स दिखाएं डिबगिंग के लिए एक सहायक कदम के रूप में, आप न केवल बाउंडिंग बॉक्स को प्रिंट कर सकते हैं, बल्कि उन्हें उस छवि पर भी खींच सकते हैं जो छवि कैप्चर होने पर डिस्क पर लिखी गई थी। ### कार्य - बाउंडिंग बॉक्स प्रिंट करें 1. सुनिश्चित करें कि `stock-counter` प्रोजेक्ट VS Code में खुला है, और यदि आप वर्चुअल IoT डिवाइस का उपयोग कर रहे हैं तो वर्चुअल एनवायरनमेंट सक्रिय है। 1. `for` लूप में `print` स्टेटमेंट को निम्नलिखित में बदलें ताकि बाउंडिंग बॉक्स को कंसोल में प्रिंट किया जा सके: ```python print(f'{prediction.tag_name}:\t{prediction.probability * 100:.2f}%\t{prediction.bounding_box}') ``` 1. ऐप को चलाएं और कैमरे को शेल्फ पर रखे स्टॉक की ओर इंगित करें। बाउंडिंग बॉक्स कंसोल में प्रिंट होंगे, जिनमें 0-1 के बीच के लेफ्ट, टॉप, चौड़ाई और ऊंचाई के मान होंगे। ```output pi@raspberrypi:~/stock-counter $ python3 app.py tomato paste: 33.42% {'additional_properties': {}, 'left': 0.3455171, 'top': 0.09916268, 'width': 0.14175442, 'height': 0.29405564} tomato paste: 34.41% {'additional_properties': {}, 'left': 0.48283678, 'top': 0.10242918, 'width': 0.11782813, 'height': 0.27467814} tomato paste: 31.25% {'additional_properties': {}, 'left': 0.4923783, 'top': 0.35007596, 'width': 0.13668466, 'height': 0.28304994} tomato paste: 31.05% {'additional_properties': {}, 'left': 0.36416405, 'top': 0.37494493, 'width': 0.14024884, 'height': 0.26880276} ``` ### कार्य - छवि पर बाउंडिंग बॉक्स खींचें 1. [Pillow](https://pypi.org/project/Pillow/) नामक Pip पैकेज का उपयोग छवियों पर खींचने के लिए किया जा सकता है। इसे निम्नलिखित कमांड से इंस्टॉल करें: ```sh pip3 install pillow ``` यदि आप वर्चुअल IoT डिवाइस का उपयोग कर रहे हैं, तो सुनिश्चित करें कि इसे सक्रिय वर्चुअल एनवायरनमेंट के अंदर से चलाएं। 1. `app.py` फ़ाइल के शीर्ष पर निम्नलिखित इम्पोर्ट स्टेटमेंट जोड़ें: ```python from PIL import Image, ImageDraw, ImageColor ``` यह कोड इम्पोर्ट करता है जो छवि को संपादित करने के लिए आवश्यक है। 1. `app.py` फ़ाइल के अंत में निम्नलिखित कोड जोड़ें: ```python with Image.open('image.jpg') as im: draw = ImageDraw.Draw(im) for prediction in predictions: scale_left = prediction.bounding_box.left scale_top = prediction.bounding_box.top scale_right = prediction.bounding_box.left + prediction.bounding_box.width scale_bottom = prediction.bounding_box.top + prediction.bounding_box.height left = scale_left * im.width top = scale_top * im.height right = scale_right * im.width bottom = scale_bottom * im.height draw.rectangle([left, top, right, bottom], outline=ImageColor.getrgb('red'), width=2) im.save('image.jpg') ``` यह कोड पहले से सहेजी गई छवि को संपादन के लिए खोलता है। फिर यह पूर्वानुमानों के माध्यम से लूप करता है, बाउंडिंग बॉक्स प्राप्त करता है, और बाउंडिंग बॉक्स मानों का उपयोग करके नीचे दाएं कोने का निर्देशांक गणना करता है। इन मानों को छवि के आयामों से गुणा करके छवि निर्देशांक में परिवर्तित किया जाता है। उदाहरण के लिए, यदि लेफ्ट मान 0.5 है और छवि 600 पिक्सल चौड़ी है, तो यह 300 में परिवर्तित होगा (0.5 x 600 = 300)। प्रत्येक बाउंडिंग बॉक्स को छवि पर एक लाल रेखा का उपयोग करके खींचा जाता है। अंत में, संपादित छवि को सहेजा जाता है और मूल छवि को ओवरराइट कर दिया जाता है। 1. ऐप को चलाएं और कैमरे को शेल्फ पर रखे स्टॉक की ओर इंगित करें। आप VS Code एक्सप्लोरर में `image.jpg` फ़ाइल देखेंगे और इसे चुनकर बाउंडिंग बॉक्स देख सकेंगे। ![4 टमाटर पेस्ट के डिब्बे, जिनके चारों ओर बाउंडिंग बॉक्स हैं](../../../../../translated_images/rpi-stock-with-bounding-boxes.b5540e2ecb7cd49f1271828d3be412671d950e87625c5597ea97c90f11e01097.hi.jpg) ## स्टॉक गिनें ऊपर दिखाई गई छवि में, बाउंडिंग बॉक्स में थोड़ा ओवरलैप है। यदि यह ओवरलैप बहुत बड़ा होता, तो बाउंडिंग बॉक्स एक ही वस्तु को इंगित कर सकते थे। वस्तुओं को सही ढंग से गिनने के लिए, आपको उन बॉक्स को अनदेखा करना होगा जिनमें महत्वपूर्ण ओवरलैप है। ### कार्य - ओवरलैप को अनदेखा करते हुए स्टॉक गिनें 1. [Shapely](https://pypi.org/project/Shapely/) नामक Pip पैकेज का उपयोग इंटरसेक्शन की गणना के लिए किया जा सकता है। यदि आप रास्पबेरी पाई का उपयोग कर रहे हैं, तो पहले एक लाइब्रेरी डिपेंडेंसी इंस्टॉल करें: ```sh sudo apt install libgeos-dev ``` 1. Shapely Pip पैकेज इंस्टॉल करें: ```sh pip3 install shapely ``` यदि आप वर्चुअल IoT डिवाइस का उपयोग कर रहे हैं, तो सुनिश्चित करें कि इसे सक्रिय वर्चुअल एनवायरनमेंट के अंदर से चलाएं। 1. `app.py` फ़ाइल के शीर्ष पर निम्नलिखित इम्पोर्ट स्टेटमेंट जोड़ें: ```python from shapely.geometry import Polygon ``` यह कोड इम्पोर्ट करता है जो ओवरलैप की गणना के लिए पॉलीगॉन बनाने के लिए आवश्यक है। 1. बाउंडिंग बॉक्स खींचने वाले कोड के ऊपर निम्नलिखित कोड जोड़ें: ```python overlap_threshold = 0.20 ``` यह परिभाषित करता है कि बाउंडिंग बॉक्स को एक ही वस्तु मानने से पहले कितना प्रतिशत ओवरलैप की अनुमति है। 0.20 का अर्थ है 20% ओवरलैप। 1. Shapely का उपयोग करके ओवरलैप की गणना करने के लिए, बाउंडिंग बॉक्स को Shapely पॉलीगॉन में परिवर्तित करना होगा। ऐसा करने के लिए निम्नलिखित फ़ंक्शन जोड़ें: ```python def create_polygon(prediction): scale_left = prediction.bounding_box.left scale_top = prediction.bounding_box.top scale_right = prediction.bounding_box.left + prediction.bounding_box.width scale_bottom = prediction.bounding_box.top + prediction.bounding_box.height return Polygon([(scale_left, scale_top), (scale_right, scale_top), (scale_right, scale_bottom), (scale_left, scale_bottom)]) ``` यह एक पॉलीगॉन बनाता है जो पूर्वानुमान के बाउंडिंग बॉक्स का उपयोग करता है। 1. ओवरलैपिंग वस्तुओं को हटाने के लिए लॉजिक में सभी बाउंडिंग बॉक्स की तुलना करना शामिल है। यदि किसी भी पूर्वानुमान जोड़े के बाउंडिंग बॉक्स ओवरलैप थ्रेशोल्ड से अधिक ओवरलैप करते हैं, तो उनमें से एक को हटा दिया जाता है। सभी पूर्वानुमानों की तुलना करने के लिए, आप पूर्वानुमान 1 की तुलना 2, 3, 4 आदि से करते हैं, फिर 2 की तुलना 3, 4 आदि से करते हैं। निम्नलिखित कोड यह करता है: ```python to_delete = [] for i in range(0, len(predictions)): polygon_1 = create_polygon(predictions[i]) for j in range(i+1, len(predictions)): polygon_2 = create_polygon(predictions[j]) overlap = polygon_1.intersection(polygon_2).area smallest_area = min(polygon_1.area, polygon_2.area) if overlap > (overlap_threshold * smallest_area): to_delete.append(predictions[i]) break for d in to_delete: predictions.remove(d) print(f'Counted {len(predictions)} stock items') ``` ओवरलैप की गणना Shapely के `Polygon.intersection` मेथड का उपयोग करके की जाती है, जो ओवरलैप का पॉलीगॉन लौटाता है। इस पॉलीगॉन से क्षेत्रफल की गणना की जाती है। यह ओवरलैप थ्रेशोल्ड एक पूर्ण मान नहीं है, बल्कि यह बाउंडिंग बॉक्स का प्रतिशत होना चाहिए। इसलिए सबसे छोटा बाउंडिंग बॉक्स पाया जाता है, और ओवरलैप थ्रेशोल्ड का उपयोग यह गणना करने के लिए किया जाता है कि ओवरलैप का क्षेत्र कितना हो सकता है ताकि यह सबसे छोटे बाउंडिंग बॉक्स के प्रतिशत ओवरलैप थ्रेशोल्ड से अधिक न हो। यदि ओवरलैप इसे पार कर जाता है, तो पूर्वानुमान को हटाने के लिए चिह्नित किया जाता है। एक बार जब किसी पूर्वानुमान को हटाने के लिए चिह्नित कर दिया जाता है, तो उसे फिर से जांचने की आवश्यकता नहीं होती है, इसलिए आंतरिक लूप अगले पूर्वानुमान की जांच करने के लिए ब्रेक कर देता है। आप सूची से आइटम को हटाते समय उसके माध्यम से इटरेट नहीं कर सकते, इसलिए जो बाउंडिंग बॉक्स थ्रेशोल्ड से अधिक ओवरलैप करते हैं, उन्हें `to_delete` सूची में जोड़ा जाता है और फिर अंत में हटा दिया जाता है। अंत में, स्टॉक काउंट कंसोल में प्रिंट किया जाता है। इसे IoT सेवा को भेजा जा सकता है ताकि स्टॉक स्तर कम होने पर अलर्ट किया जा सके। यह सारा कोड बाउंडिंग बॉक्स खींचने से पहले है, इसलिए आप उत्पन्न छवियों पर ओवरलैप के बिना स्टॉक पूर्वानुमान देखेंगे। > 💁 यह ओवरलैप को हटाने का एक बहुत ही सरल तरीका है, जिसमें केवल ओवरलैपिंग जोड़े में से पहले वाले को हटा दिया जाता है। प्रोडक्शन कोड के लिए, आप यहां अधिक लॉजिक जोड़ना चाहेंगे, जैसे कि कई वस्तुओं के बीच ओवरलैप पर विचार करना, या यदि एक बाउंडिंग बॉक्स दूसरे के अंदर है। 1. ऐप को चलाएं और कैमरे को शेल्फ पर रखे स्टॉक की ओर इंगित करें। आउटपुट यह दिखाएगा कि थ्रेशोल्ड से अधिक ओवरलैप के बिना कितने बाउंडिंग बॉक्स हैं। `overlap_threshold` मान को समायोजित करके देखें कि पूर्वानुमान कैसे अनदेखा किए जाते हैं। > 💁 आप इस कोड को [code-count/pi](../../../../../5-retail/lessons/2-check-stock-device/code-count/pi) या [code-count/virtual-iot-device](../../../../../5-retail/lessons/2-check-stock-device/code-count/virtual-iot-device) फ़ोल्डर में पा सकते हैं। 😀 आपका स्टॉक काउंटर प्रोग्राम सफल रहा! **अस्वीकरण**: यह दस्तावेज़ AI अनुवाद सेवा [Co-op Translator](https://github.com/Azure/co-op-translator) का उपयोग करके अनुवादित किया गया है। जबकि हम सटीकता सुनिश्चित करने का प्रयास करते हैं, कृपया ध्यान दें कि स्वचालित अनुवाद में त्रुटियां या अशुद्धियां हो सकती हैं। मूल भाषा में उपलब्ध मूल दस्तावेज़ को आधिकारिक स्रोत माना जाना चाहिए। महत्वपूर्ण जानकारी के लिए, पेशेवर मानव अनुवाद की सिफारिश की जाती है। इस अनुवाद के उपयोग से उत्पन्न किसी भी गलतफहमी या गलत व्याख्या के लिए हम जिम्मेदार नहीं हैं।