14 KiB
شمارش موجودی با دستگاه IoT - سختافزار مجازی IoT و رزبری پای
ترکیبی از پیشبینیها و جعبههای محدودکننده میتواند برای شمارش موجودی در یک تصویر استفاده شود.
نمایش جعبههای محدودکننده
به عنوان یک مرحله مفید برای اشکالزدایی، میتوانید نه تنها جعبههای محدودکننده را چاپ کنید، بلکه میتوانید آنها را روی تصویری که هنگام ثبت تصویر در دیسک ذخیره شده است، رسم کنید.
وظیفه - چاپ جعبههای محدودکننده
-
اطمینان حاصل کنید که پروژه
stock-counter
در VS Code باز است و اگر از یک دستگاه مجازی IoT استفاده میکنید، محیط مجازی فعال شده باشد. -
دستور
print
در حلقهfor
را به صورت زیر تغییر دهید تا جعبههای محدودکننده را در کنسول چاپ کنید:print(f'{prediction.tag_name}:\t{prediction.probability * 100:.2f}%\t{prediction.bounding_box}')
-
برنامه را اجرا کنید و دوربین را به سمت مقداری موجودی روی یک قفسه بگیرید. جعبههای محدودکننده در کنسول چاپ خواهند شد، با مقادیر چپ، بالا، عرض و ارتفاع از 0 تا 1.
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}
وظیفه - رسم جعبههای محدودکننده روی تصویر
-
بسته Pip به نام Pillow میتواند برای رسم روی تصاویر استفاده شود. این بسته را با دستور زیر نصب کنید:
pip3 install pillow
اگر از یک دستگاه مجازی IoT استفاده میکنید، مطمئن شوید که این دستور را در محیط مجازی فعال اجرا کنید.
-
دستور وارد کردن زیر را به ابتدای فایل
app.py
اضافه کنید:from PIL import Image, ImageDraw, ImageColor
این کد لازم برای ویرایش تصویر را وارد میکند.
-
کد زیر را به انتهای فایل
app.py
اضافه کنید: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).
هر جعبه محدودکننده با یک خط قرمز روی تصویر رسم میشود. در نهایت، تصویر ویرایششده ذخیره شده و تصویر اصلی بازنویسی میشود.
-
برنامه را اجرا کنید و دوربین را به سمت مقداری موجودی روی یک قفسه بگیرید. فایل
image.jpg
را در کاوشگر VS Code خواهید دید و میتوانید آن را انتخاب کنید تا جعبههای محدودکننده را مشاهده کنید.
شمارش موجودی
در تصویر بالا، جعبههای محدودکننده کمی همپوشانی دارند. اگر این همپوشانی بسیار بیشتر بود، ممکن بود جعبههای محدودکننده نشاندهنده یک شیء یکسان باشند. برای شمارش صحیح اشیاء، باید جعبههایی که همپوشانی قابلتوجهی دارند را نادیده بگیرید.
وظیفه - شمارش موجودی با نادیده گرفتن همپوشانی
-
بسته Pip به نام Shapely میتواند برای محاسبه تقاطع استفاده شود. اگر از یک رزبری پای استفاده میکنید، ابتدا باید یک وابستگی کتابخانهای را نصب کنید:
sudo apt install libgeos-dev
-
بسته Shapely را نصب کنید:
pip3 install shapely
اگر از یک دستگاه مجازی IoT استفاده میکنید، مطمئن شوید که این دستور را در محیط مجازی فعال اجرا کنید.
-
دستور وارد کردن زیر را به ابتدای فایل
app.py
اضافه کنید:from shapely.geometry import Polygon
این کد لازم برای ایجاد چندضلعیها برای محاسبه همپوشانی را وارد میکند.
-
کد زیر را بالای کدی که جعبههای محدودکننده را رسم میکند اضافه کنید:
overlap_threshold = 0.20
این کد درصد همپوشانی مجاز را قبل از اینکه جعبههای محدودکننده به عنوان یک شیء یکسان در نظر گرفته شوند، تعریف میکند. مقدار 0.20 نشاندهنده 20% همپوشانی است.
-
برای محاسبه همپوشانی با استفاده از Shapely، جعبههای محدودکننده باید به چندضلعیهای Shapely تبدیل شوند. تابع زیر را برای انجام این کار اضافه کنید:
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 با 2، 3، 4 و غیره مقایسه میشود، سپس 2 با 3، 4 و غیره. کد زیر این کار را انجام میدهد:
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')
همپوشانی با استفاده از متد
Polygon.intersection
در Shapely محاسبه میشود که یک چندضلعی با همپوشانی را برمیگرداند. مساحت این چندضلعی سپس محاسبه میشود. این آستانه همپوشانی یک مقدار مطلق نیست، بلکه باید درصدی از جعبه محدودکننده باشد، بنابراین کوچکترین جعبه محدودکننده پیدا میشود و آستانه همپوشانی برای محاسبه مساحتی که همپوشانی میتواند داشته باشد تا از درصد آستانه همپوشانی کوچکترین جعبه محدودکننده تجاوز نکند، استفاده میشود. اگر همپوشانی از این مقدار بیشتر شود، پیشبینی برای حذف علامتگذاری میشود.وقتی یک پیشبینی برای حذف علامتگذاری شد، دیگر نیازی به بررسی مجدد آن نیست، بنابراین حلقه داخلی متوقف میشود تا پیشبینی بعدی بررسی شود. نمیتوانید هنگام پیمایش در یک لیست، آیتمها را از آن حذف کنید، بنابراین جعبههای محدودکنندهای که بیش از آستانه همپوشانی دارند به لیست
to_delete
اضافه میشوند و سپس در انتها حذف میشوند.در نهایت، تعداد موجودی در کنسول چاپ میشود. این مقدار سپس میتواند به یک سرویس IoT ارسال شود تا در صورت کم بودن سطح موجودی هشدار دهد. تمام این کد قبل از رسم جعبههای محدودکننده است، بنابراین پیشبینیهای موجودی بدون همپوشانی در تصاویر تولیدشده مشاهده میشوند.
💁 این یک روش بسیار ساده برای حذف همپوشانیها است که فقط اولین مورد در یک جفت همپوشانی را حذف میکند. برای کد تولیدی، ممکن است بخواهید منطق بیشتری در اینجا قرار دهید، مانند در نظر گرفتن همپوشانی بین چندین شیء یا اگر یک جعبه محدودکننده در دیگری قرار دارد.
-
برنامه را اجرا کنید و دوربین را به سمت مقداری موجودی روی یک قفسه بگیرید. خروجی تعداد جعبههای محدودکننده بدون همپوشانی که از آستانه تجاوز میکنند را نشان میدهد. سعی کنید مقدار
overlap_threshold
را تنظیم کنید تا پیشبینیهایی که نادیده گرفته میشوند را مشاهده کنید.
💁 میتوانید این کد را در پوشه code-count/pi یا code-count/virtual-iot-device پیدا کنید.
😀 برنامه شمارش موجودی شما موفقیتآمیز بود!
سلب مسئولیت:
این سند با استفاده از سرویس ترجمه هوش مصنوعی Co-op Translator ترجمه شده است. در حالی که ما تلاش میکنیم دقت را حفظ کنیم، لطفاً توجه داشته باشید که ترجمههای خودکار ممکن است شامل خطاها یا نادرستیها باشند. سند اصلی به زبان اصلی آن باید به عنوان منبع معتبر در نظر گرفته شود. برای اطلاعات حساس، ترجمه حرفهای انسانی توصیه میشود. ما مسئولیتی در قبال سوء تفاهمها یا تفسیرهای نادرست ناشی از استفاده از این ترجمه نداریم.