15 KiB
Бройте наличности от вашето IoT устройство - Виртуален IoT хардуер и Raspberry Pi
Комбинацията от предсказанията и техните ограничителни кутии може да се използва за преброяване на наличности в изображение.
Показване на ограничителни кутии
Като полезна стъпка за отстраняване на грешки, можете не само да отпечатате ограничителните кутии, но и да ги нарисувате върху изображението, което е записано на диска, когато е заснето изображение.
Задача - отпечатайте ограничителните кутии
-
Уверете се, че проектът
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 може да се използва за изчисляване на пресечната точка. Ако използвате Raspberry Pi, първо ще трябва да инсталирате библиотечна зависимост:
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.
😀 Вашата програма за броене на наличности беше успешна!
Отказ от отговорност:
Този документ е преведен с помощта на AI услуга за превод Co-op Translator. Въпреки че се стремим към точност, моля, имайте предвид, че автоматизираните преводи може да съдържат грешки или неточности. Оригиналният документ на неговия роден език трябва да се счита за авторитетен източник. За критична информация се препоръчва професионален човешки превод. Ние не носим отговорност за недоразумения или погрешни интерпретации, произтичащи от използването на този превод.