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/uk/5-retail/lessons/2-check-stock-device/single-board-computer-count...

177 lines
14 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-28T17:37:20+00:00",
"source_file": "5-retail/lessons/2-check-stock-device/single-board-computer-count-stock.md",
"language_code": "uk"
}
-->
# Підрахунок запасів за допомогою вашого 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. Запустіть додаток, направивши камеру на запаси на полиці. Рамки будуть виведені на консоль із значеннями left, top, width і height у діапазоні від 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. Ці значення перетворюються в координати зображення шляхом множення на відповідний розмір зображення. Наприклад, якщо значення left дорівнює 0.5 на зображенні шириною 600 пікселів, це перетвориться на 300 (0.5 x 600 = 300).
Кожна рамка малюється на зображенні червоною лінією. Нарешті, відредаговане зображення зберігається, замінюючи оригінальне зображення.
1. Запустіть додаток, направивши камеру на запаси на полиці. Ви побачите файл `image.jpg` у провіднику VS Code і зможете вибрати його, щоб побачити рамки.
![4 банки томатної пасти з рамками навколо кожної банки](../../../../../translated_images/rpi-stock-with-bounding-boxes.b5540e2ecb7cd49f1271828d3be412671d950e87625c5597ea97c90f11e01097.uk.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). Хоча ми прагнемо до точності, будь ласка, майте на увазі, що автоматичні переклади можуть містити помилки або неточності. Оригінальний документ на його рідній мові слід вважати авторитетним джерелом. Для критичної інформації рекомендується професійний людський переклад. Ми не несемо відповідальності за будь-які непорозуміння або неправильні тлумачення, що виникають внаслідок використання цього перекладу.