13 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 Pip пакет:
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')
Преклапање се израчунава користећи Shapely метод
Polygon.intersection
који враћа полигон који представља преклапање. Површина се затим израчунава из овог полигона. Овај праг преклапања није апсолутна вредност, већ мора бити проценат оквира, па се проналази најмањи оквир, а праг преклапања се користи за израчунавање колика површина преклапања може бити да не би премашила дозвољени проценат преклапања најмањег оквира. Ако преклапање премаши ово, предвиђање се означава за брисање.Када је предвиђање означено за брисање, не мора се поново проверавати, па се унутрашња петља прекида како би се проверило следеће предвиђање. Не можете брисати ставке из листе док пролазите кроз њу, па се оквири који се преклапају више од прага додају у листу
to_delete
, а затим се бришу на крају.На крају, број залиха се исписује у конзолу. Ово би се затим могло послати IoT услузи како би се упозорило ако су нивои залиха ниски. Све ово се извршава пре него што се оквири нацртају, тако да ћете видети предвиђања залиха без преклапања на генерисаним сликама.
💁 Ово је веома једноставан начин уклањања преклапања, само уклањањем првог у пару који се преклапа. За продукцијски код, желели бисте да додате више логике овде, као што је разматрање преклапања између више објеката или ако је један оквир садржан у другом.
-
Покрените апликацију са камером усмереном на неке залихе на полици. Излаз ће показати број оквира без преклапања који премашују праг. Покушајте да подесите вредност
overlap_threshold
да бисте видели како се предвиђања игноришу.
💁 Овај код можете пронаћи у фасцикли code-count/pi или code-count/virtual-iot-device.
😀 Ваш програм за бројање залиха је био успешан!
Одрицање од одговорности:
Овај документ је преведен коришћењем услуге за превођење помоћу вештачке интелигенције Co-op Translator. Иако се трудимо да обезбедимо тачност, молимо вас да имате у виду да аутоматски преводи могу садржати грешке или нетачности. Оригинални документ на његовом изворном језику треба сматрати ауторитативним извором. За критичне информације препоручује се професионални превод од стране људи. Не сносимо одговорност за било каква погрешна тумачења или неспоразуме који могу настати услед коришћења овог превода.