# আপনার 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. Pip প্যাকেজ [Pillow](https://pypi.org/project/Pillow/) ব্যবহার করে ছবিতে আঁকা সম্ভব। এটি ইনস্টল করতে নিম্নলিখিত কমান্ডটি ব্যবহার করুন: ```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-1 এর মান থেকে নিচের ডানদিকের কোঅর্ডিনেট গণনা করে। এগুলো ছবির কোঅর্ডিনেটে রূপান্তরিত হয় ছবির প্রাসঙ্গিক মাত্রার সাথে গুণ করে। উদাহরণস্বরূপ, যদি বাম মানটি 0.5 হয় এবং ছবিটি 600 পিক্সেল চওড়া হয়, এটি 300-এ রূপান্তরিত হবে (0.5 x 600 = 300)। প্রতিটি বাউন্ডিং বক্স ছবিতে একটি লাল রেখা ব্যবহার করে আঁকা হয়। শেষে সম্পাদিত ছবিটি সংরক্ষণ করা হয়, মূল ছবির উপর লিখে। 1. অ্যাপটি চালান এবং ক্যামেরা তাক করুন শেলফে থাকা কিছু স্টকের দিকে। আপনি VS Code এক্সপ্লোরারে `image.jpg` ফাইলটি দেখতে পাবেন এবং এটি নির্বাচন করে বাউন্ডিং বক্সগুলো দেখতে পারবেন। ![4টি টমেটো পেস্টের ক্যান, প্রতিটির চারপাশে বাউন্ডিং বক্স](../../../../../translated_images/rpi-stock-with-bounding-boxes.b5540e2ecb7cd49f1271828d3be412671d950e87625c5597ea97c90f11e01097.bn.jpg) ## স্টক গণনা করুন উপরের ছবিতে, বাউন্ডিং বক্সগুলো সামান্য ওভারল্যাপ করেছে। যদি এই ওভারল্যাপ অনেক বেশি হয়, তাহলে বাউন্ডিং বক্সগুলো একই বস্তু নির্দেশ করতে পারে। সঠিকভাবে বস্তুগুলো গণনা করতে, আপনাকে উল্লেখযোগ্য ওভারল্যাপযুক্ত বক্সগুলো উপেক্ষা করতে হবে। ### কাজ - ওভারল্যাপ উপেক্ষা করে স্টক গণনা করুন 1. Pip প্যাকেজ [Shapely](https://pypi.org/project/Shapely/) ব্যবহার করে ইন্টারসেকশন গণনা করা সম্ভব। আপনি যদি রাস্পবেরি পাই ব্যবহার করেন, তবে প্রথমে একটি লাইব্রেরি ডিপেনডেন্সি ইনস্টল করতে হবে: ```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. ওভারল্যাপযুক্ত বস্তুগুলো সরানোর লজিকটি সমস্ত বাউন্ডিং বক্স তুলনা করে। যদি কোনো জোড়া ভবিষ্যদ্বাণীর বাউন্ডিং বক্সগুলো ওভারল্যাপ থ্রেশহোল্ডের চেয়ে বেশি হয়, তাহলে একটি ভবিষ্যদ্বাণী মুছে ফেলা হয়। তুলনা করার জন্য, প্রথম ভবিষ্যদ্বাণীটি দ্বিতীয়, তৃতীয়, চতুর্থ ইত্যাদির সাথে তুলনা করা হয়, তারপর দ্বিতীয়টি তৃতীয়, চতুর্থ ইত্যাদির সাথে। নিম্নলিখিত কোড এটি করে: ```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) ব্যবহার করে অনুবাদ করা হয়েছে। আমরা যথাসাধ্য সঠিকতার জন্য চেষ্টা করি, তবে অনুগ্রহ করে মনে রাখবেন যে স্বয়ংক্রিয় অনুবাদে ত্রুটি বা অসঙ্গতি থাকতে পারে। মূল ভাষায় থাকা নথিটিকে প্রামাণিক উৎস হিসেবে বিবেচনা করা উচিত। গুরুত্বপূর্ণ তথ্যের জন্য, পেশাদার মানব অনুবাদ সুপারিশ করা হয়। এই অনুবাদ ব্যবহারের ফলে কোনো ভুল বোঝাবুঝি বা ভুল ব্যাখ্যা হলে আমরা দায়বদ্ধ থাকব না।