You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
IoT-For-Beginners/translations/sr/5-retail/lessons/2-check-stock-device/single-board-computer-count...

177 lines
13 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "9c4320311c0f2c1884a6a21265d98a51",
"translation_date": "2025-08-28T14:28:46+00:00",
"source_file": "5-retail/lessons/2-check-stock-device/single-board-computer-count-stock.md",
"language_code": "sr"
}
-->
# Бројање залиха са вашег IoT уређаја - Виртуелни IoT хардвер и Raspberry Pi
Комбинација предвиђања и њихових оквира може се користити за бројање залиха на слици.
## Приказивање оквира
Као користан корак за отклањање грешака, можете не само исписати оквире, већ их и нацртати на слици која је сачувана на диску када је слика снимљена.
### Задатак - исписивање оквира
1. Уверите се да је пројекат `stock-counter` отворен у VS Code-у и да је виртуелно окружење активирано ако користите виртуелни IoT уређај.
1. Промените `print` изјаву у `for` петљи у следеће како бисте исписали оквире у конзолу:
```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. Покрените апликацију са камером усмереном на неке залихе на полици. Видећете фајл `image.jpg` у VS Code прегледачу и моћи ћете да га изаберете како бисте видели оквире.
![4 конзерве парадајз пасте са оквирима око сваке конзерве](../../../../../translated_images/rpi-stock-with-bounding-boxes.b5540e2ecb7cd49f1271828d3be412671d950e87625c5597ea97c90f11e01097.sr.jpg)
## Бројање залиха
На приказаној слици, оквири се благо преклапају. Ако би ово преклапање било много веће, оквири би могли указивати на исти објекат. Да бисте правилно избројали објекте, потребно је игнорисати оквире са значајним преклапањем.
### Задатак - бројање залиха игноришући преклапање
1. Pip пакет [Shapely](https://pypi.org/project/Shapely/) може се користити за израчунавање пресека. Ако користите Raspberry Pi, прво ћете морати да инсталирате библиотеку зависности:
```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).
😀 Ваш програм за бројање залиха је био успешан!
---
**Одрицање од одговорности**:
Овај документ је преведен коришћењем услуге за превођење помоћу вештачке интелигенције [Co-op Translator](https://github.com/Azure/co-op-translator). Иако се трудимо да обезбедимо тачност, молимо вас да имате у виду да аутоматски преводи могу садржати грешке или нетачности. Оригинални документ на његовом изворном језику треба сматрати ауторитативним извором. За критичне информације препоручује се професионални превод од стране људи. Не сносимо одговорност за било каква погрешна тумачења или неспоразуме који могу настати услед коришћења овог превода.