Během posledního roku jsme společně pracovali na IoT projektu, který využívá síly Arduina v kombinaci s Azure Cloud Services. Našim cílem bylo vytvořit spojení mezi Arduino deskou a službami Azure, aby bylo možné pomocí hardware vyfotit fotografii, odeslat ji do Azure IoT Hub a pomocí Azure Functions s využitím umělé inteligence zjistit, kolik lidí se na fotografii nachází. Takovéto zařízení by pak mohlo být jednoduše využitelné v obchodech a službách. Sledoval by se tím počet aktuálních návštěvníků v budově, čímž by se zjednodušilo dodržování COVID opatření.
Obsah
Problém
Když vláda oznámila omezení lidí uvnitř budov, majitelé těchto nemovitostí museli vymyslet, jak toto opatření dodržet – zejména v obchodech. Obvyklým řešením bylo omezení počtu nákupních košíků a přimění každého zákazníka, aby si při vstupu do obchodu jeden vzal.
Pomocí moderních technologií (Azure Services a Arduina) chceme tuto situaci majitelům usnadnit a zpříjemnit.
Hardware a software
Jako naši vývojovou desku používáme Arduino AI-Thinker ESP32-CAM s 2 Mpx kamerovým modulem OV2640. Tyto komponenty jsme zvolili kvůli malým rozměrům, poměrně velkému rozlišení fotoaparátu a vestavěné Wi-Fi konektivitě – to vše na jedné desce.
C++ kód pro Arduino jsme psali v IDE CLion od JetBrains s použitím frameworku PlatformIO.
Azure Services nám posloužily jako back-end pro náš projekt – Azure IoT Hub pro komunikaci a Azure Functions pro zpracování.
Řešení
Záměrem bylo v definovaném intervalu pořizovat fotografie pomocí Arduina, oříznout je a odeslat pomocí protokolu MQTT do end-pointu v Azure IoT Hubu. Odtud roli přebírají Azure Functions, kde je fotografie zpracována naším ML modelem, jejíž výsledkem bude počet lidí.
Členové našeho týmu a jejich role
- Petr Kučera – vedoucí
- Václav Kuboň – vývojář v Azure
- Jakub Ferenčík – vývojář pro Arduino
Postup práce
Arduino
Arduino je open-source hardware, který je vhodný pro malé, ale i komplexní projekty, a sice díky své jednoduchosti a možnostem za relativně nízkou cenu.
Prvním krokem správné propojení desky a připojení k počítači. Pomohl nám k tomu tento článek, kde je popsán kompletní pin-out. Po překonání problémů způsobených poničením hardware při přepravě a vadným kabelem se nám podařilo navázat komunikaci.
Jelikož jsem vždy pracoval pouze ve vyšších programovacích jazycích (Java, Kotlin, Python) a jazyk C++ pro mě byl úplně nový, měl jsem zpočátku problém syntaxi a využívání pointerů pochopit a následně si na to zvyknout. Po několika týdnech jsem se již částečně orientoval a začal shánět potřebné knihovny, kterými se nakonec staly tyto:
- ESP32 Camera Driver
- Arduino JSON
- Azure IoT Hub
- Azure IoT Protocol – MQTT
- Azure IoT Utility
- Azure IoT Socket – WiFi
Vytvořil jsem také naše vlastní „helpery“, jejichž úkolem je manipulovat s výše uvedenými knihovnami:
- AzureHelper – obsahuje metody používané pro přípravu zpráv MQTT a komunikaci s Azure
- CameraHelper – obsahuje metody používané pro fotografování (pomocí knihovny esp32cam) a manipulaci s nimi.
Nakonec jedna třída, která rozšiřuje možnosti logování v Arduinu.
- Logger – obsahuje metody používané pro vylepšené logování
Základ kódu
Jako základ kódu jsem použil příklady uvedené na stránce se seznamem knihoven PlatformIO, které mi poskytly počáteční inspiraci, jak komunikovat s Azure a přijímat odpovědi.
Pokus o použití BLOB jako úložiště pro naše obrázky
Chtěli jsme pomocí knihovny Azure IoT Hub použít BLOB úložiště jako místo pro nahrávání fotek, ale už při kompilaci kódu se vyskytl problém, který byl způsoben třídou ‚upload_to_blob‘ a bylo potřeba ji deaktivovat pomocí „build parametru“.
Kódování zpráv
Jako alternativu k BLOB úložišti jsme zvolili přenos prostřednictvím JSON formátovaných zpráv. Prodiskutovali jsme, jakým způsobem by bylo nejvýhodnější fotografii zakódovat do JSON formátu, aby ji bylo pak možné odeslat přes protokol MQTT. Omezení Azure IoT Hub je 256 kB na zprávu, což nám teoreticky dává možnost poslat fotku ve stupních šedi v rozlišení až 500×500 px, ale jakmile jsme odeslali první zprávu, zjistili jsme, že tato cesta také nebude bezproblémová – IoT Hub nebyl schopen zprávu dekódovat, či v některých případech ji ani neobdržel. Fotografie je nejprve převedena na pole bajtů, které je poté zakódováno pomocí Base64 a vloženo do zprávy.
Odstraňování problémů
Jakmile se nám podařilo rozchodit komunikaci přes MQTT alespoň s nižším rozlišením (97×97 px), objevil se další problém kvůli omezené velikosti RAM paměti na Arduinu. Rychle jsme však našli řešení – uložit některé objekty do tzv. PSRAM.
V Azure IoT Hub došlo k další komplikaci při pokusu o zvýšení rozlišení. Po několika týdnech jsme zjistili, že pravděpodobně existuje nějaký nezmíněný limit délky zprávy – konkrétně že zpráva nesmí být delší než přibližně 5000 znaků. Rozhodli jsme se poslat fotografii rozdělenou do více zpráv, tento přístup však také nefungoval.
Jelikož se nám nedařilo vyřešit problém s odesíláním větších fotek, rozhodli jsme se mírně pozměnit cíl projektu z počítání lidí na fotografii, na ověřování, zda má vyfocená osoba nasazenou ochranu úst. To nám umožnilo použít nižší rozlišení a tedy i kratší zprávy. Bohužel se nám však nepodařilo zprovoznit ani tuto verzi projektu.
Azure
Služba Azure Cloud Service nabízí nástroje pro sběr dat ze zařízení IoT a pro hladkou integraci s dalšími službami Azure. Pro sběr dat jsme zvolili IoT Hub, jehož prostřednictvím se připojíme k našemu IoT zařízení a přesměrujeme data na místo určení. Tato část popisuje nejslibnější verzi webové aplikace, která by měla shromažďovat data z IoT Hub, rekonstruovat původní obraz a použít model počítačového vidění pro klasifikaci osoby na obrázku, zda má nebo nemá roušku nebo respirátor.
Přenos z ESP32 do webové aplikace
Na počátku jsme zamýšleli použít pro aplikační část projektu Azure function spouštěnou z event-hub. Data odeslaná do IoT Hub, buď prostřednictvím protokolů HTTP, nebo MQTT mohou pohodlně spustit vestavěný event hub zabudovaný do služby. Funkce Azure napsaná v jazyce Python se spustí, jakmile dorazí nová data. Tato metoda však nebyla nikdy dokončena, díky tomu, že funkce se neosvědčily jako ideální pro průběžné zobrazování příchozích dat v reálném čase.
Vyzkoušeli jsme ještě jeden přístup, jehož kód jsme přiložili. Existuje možnost odesílat data ze zařízení IoT do úložiště Azure blob storage – služby určené pro nestrukturovaná data jako například obrázky. Jak bylo popsáno v předchozích částech, tato metoda nakonec na straně zařízení IoT selhala. Následující odstavec nabízí popis technologií použitých v aplikaci, které mohou sloužit alespoň jako inspirace pro podobné snahy.
Webová aplikace
Backend aplikace využívá Python framework Flask. Skript application.py se stará o stahování z úložiště Blob Storage a volá vlastní ML model.
Po vytvoření úložiště blobů na portálu Azure potřebujeme k připojení pouze připojovací řetězec a název blobu. V pravidelných intervalech se volá trasa aktualizačních zpráv a kontroluje, zda dorazily nějaké nové bloby. Pokud ano, blob se stáhne a uloží. Protože limity MQTT znemožňují odeslání celého obrazu, aplikace je navržena tak, aby před dokončením obrazu počkala na příchod všech modelu částí. Obrázek je převeden do správného formátu a prostřednictvím Custom Vision API je zavolán model, který předpovídá pravděpodobnosti nošení masky.
Povaha problému vyžadovala použití asynchronní komunikace. Proto jsme v šabloně frontendu použili Ajax pro periodické volání výše zmíněné funkce. Výsledek je potom zobrazen.
Model počítačového vidění
Model byl vycvičen ve službě Azure Custom Vision s použitím této datové sady z Kaggle. Díky použití Custom Vision bylo trénování modelu snadné a nezabralo mnoho času. Model dosáhl podle performance záložky průměrné přesnosti 98,4 %.
Stav
Nedokončeno.
Projekt jsme nedokončili kvůli komplikacím s odesíláním větších zpráv do Azure, proto jsme tento projekt označili jako nedokončený a soustředíme se na nějakou jinou práci, která nám v tuto chvíli dává větší smysl.
Zdrojový kód
Kompletní repositář se zdrojovým kódem pro Arduino i Azure naleznete na našem GitHubu. Ačkoli nás naše úsilí nedovedlo k naplánovanému cíli, věříme, že kód, který jsme napsali, stejně jako poznatky, které jsme zde shrnuli, poslouží ostatním při práci na podobných projektech.
Přečtěte si i další články na našem blogu studuj.digital.