7.9 KiB
Loenda varusid oma IoT-seadmest - Wio Terminal
Ennustuste ja nende piirdekastide kombinatsiooni saab kasutada varude loendamiseks pildil.
Varude loendamine
Ülaltoodud pildil on piirdekastid veidi kattuvad. Kui see kattumine oleks palju suurem, siis võivad piirdekastid viidata samale objektile. Objektide korrektseks loendamiseks tuleb ignoreerida kaste, mille kattumine on märkimisväärne.
Ülesanne - loenda varusid ignoreerides kattumist
-
Ava oma
stock-counterprojekt, kui see pole juba avatud. -
Lisa
processPredictionsfunktsiooni kohale järgmine kood:const float overlap_threshold = 0.20f;See määratleb protsentuaalse kattumise, mille korral piirdekastid loetakse samaks objektiks. 0.20 määratleb 20% kattumise.
-
Selle alla ja
processPredictionsfunktsiooni kohale lisa järgmine kood, et arvutada kahe ristküliku kattuvus:struct Point { float x, y; }; struct Rect { Point topLeft, bottomRight; }; float area(Rect rect) { return abs(rect.bottomRight.x - rect.topLeft.x) * abs(rect.bottomRight.y - rect.topLeft.y); } float overlappingArea(Rect rect1, Rect rect2) { float left = max(rect1.topLeft.x, rect2.topLeft.x); float right = min(rect1.bottomRight.x, rect2.bottomRight.x); float top = max(rect1.topLeft.y, rect2.topLeft.y); float bottom = min(rect1.bottomRight.y, rect2.bottomRight.y); if ( right > left && bottom > top ) { return (right-left)*(bottom-top); } return 0.0f; }See kood määratleb
Pointstruktuuri, et salvestada punkte pildil, jaRectstruktuuri, et määratleda ristkülik, kasutades ülemist vasakut ja alumist paremat koordinaati. Seejärel määratleb seeareafunktsiooni, mis arvutab ristküliku pindala ülemise vasaku ja alumise parema koordinaadi põhjal.Järgmisena määratleb see
overlappingAreafunktsiooni, mis arvutab kahe ristküliku kattuva ala. Kui need ei kattu, tagastab see 0. -
Lisa
overlappingAreafunktsiooni alla funktsioon, mis teisendab piirdekastiRect-iks:Rect rectFromBoundingBox(JsonVariant prediction) { JsonObject bounding_box = prediction["boundingBox"].as<JsonObject>(); float left = bounding_box["left"].as<float>(); float top = bounding_box["top"].as<float>(); float width = bounding_box["width"].as<float>(); float height = bounding_box["height"].as<float>(); Point topLeft = {left, top}; Point bottomRight = {left + width, top + height}; return {topLeft, bottomRight}; }See võtab objekti detektori ennustuse, eraldab piirdekasti ja kasutab piirdekasti väärtusi ristküliku määratlemiseks. Parempoolne külg arvutatakse vasakust küljest pluss laius. Alumine külg arvutatakse ülemisest küljest pluss kõrgus.
-
Ennustusi tuleb omavahel võrrelda, ja kui kahel ennustusel on kattumine, mis ületab läve, tuleb üks neist kustutada. Kattumise lävi on protsent, seega tuleb see korrutada väikseima piirdekasti suurusega, et kontrollida, kas kattumine ületab antud protsendi piirdekastist, mitte kogu pildist. Alusta
processPredictionsfunktsiooni sisu kustutamisega. -
Lisa tühja
processPredictionsfunktsiooni järgmine kood:std::vector<JsonVariant> passed_predictions; for (int i = 0; i < predictions.size(); ++i) { Rect prediction_1_rect = rectFromBoundingBox(predictions[i]); float prediction_1_area = area(prediction_1_rect); bool passed = true; for (int j = i + 1; j < predictions.size(); ++j) { Rect prediction_2_rect = rectFromBoundingBox(predictions[j]); float prediction_2_area = area(prediction_2_rect); float overlap = overlappingArea(prediction_1_rect, prediction_2_rect); float smallest_area = min(prediction_1_area, prediction_2_area); if (overlap > (overlap_threshold * smallest_area)) { passed = false; break; } } if (passed) { passed_predictions.push_back(predictions[i]); } }See kood määratleb vektori, kuhu salvestatakse ennustused, mis ei kattu. Seejärel tsüklitakse läbi kõik ennustused, luues piirdekastist
Rect.Järgmisena tsüklitakse läbi ülejäänud ennustused, alustades praeguse ennustuse järgmisest. See väldib ennustuste korduvat võrdlemist - kui 1 ja 2 on võrreldud, pole vaja võrrelda 2 ja 1, ainult 3, 4 jne.
Iga ennustuste paari puhul arvutatakse kattuv ala. Seda võrreldakse väikseima piirdekasti pindalaga - kui kattumine ületab väikseima piirdekasti antud protsendi, märgitakse ennustus mitte läbituks. Kui pärast kõigi kattumiste võrdlemist ennustus läbib kontrollid, lisatakse see
passed_predictionskogusse.💁 See on väga lihtsustatud viis kattumiste eemaldamiseks, lihtsalt eemaldades esimese kattuva paari. Tootmiskoodis tuleks siia lisada rohkem loogikat, näiteks arvestada mitme objekti kattumisi või kui üks piirdekast sisaldub teises.
-
Pärast seda lisa järgmine kood, et saata läbitud ennustuste üksikasjad seeriamonitorile:
for(JsonVariant prediction : passed_predictions) { String boundingBox = prediction["boundingBox"].as<String>(); String tag = prediction["tagName"].as<String>(); float probability = prediction["probability"].as<float>(); char buff[32]; sprintf(buff, "%s:\t%.2f%%\t%s", tag.c_str(), probability * 100.0, boundingBox.c_str()); Serial.println(buff); }See kood tsüklitab läbi läbitud ennustused ja prindib nende üksikasjad seeriamonitorile.
-
Selle alla lisa kood, et prindida loendatud esemete arv seeriamonitorile:
Serial.print("Counted "); Serial.print(passed_predictions.size()); Serial.println(" stock items.");See võiks seejärel saata IoT-teenusele teate, kui varude tase on madal.
-
Laadi üles ja käivita oma kood. Suuna kaamera riiulil olevatele objektidele ja vajuta C-nuppu. Proovi muuta
overlap_thresholdväärtust, et näha, kuidas ennustusi ignoreeritakse.Connecting to WiFi.. Connected! Image captured Image read to buffer with length 17416 tomato paste: 35.84% {"left":0.395631,"top":0.215897,"width":0.180768,"height":0.359364} tomato paste: 35.87% {"left":0.378554,"top":0.583012,"width":0.14824,"height":0.359382} tomato paste: 34.11% {"left":0.699024,"top":0.592617,"width":0.124411,"height":0.350456} tomato paste: 35.16% {"left":0.513006,"top":0.647853,"width":0.187472,"height":0.325817} Counted 4 stock items.
💁 Selle koodi leiad kaustast code-count/wio-terminal.
😀 Sinu varude loendamise programm oli edukas!
Lahtiütlus:
See dokument on tõlgitud AI tõlketeenuse Co-op Translator abil. Kuigi püüame tagada täpsust, palume arvestada, et automaatsed tõlked võivad sisaldada vigu või ebatäpsusi. Algne dokument selle algses keeles tuleks pidada autoriteetseks allikaks. Olulise teabe puhul soovitame kasutada professionaalset inimtõlget. Me ei vastuta arusaamatuste või valesti tõlgenduste eest, mis võivad tekkida selle tõlke kasutamise tõttu.
