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/et/5-retail/lessons/2-check-stock-device/wio-terminal-count-stock.md

7.9 KiB

Loenda varusid oma IoT-seadmest - Wio Terminal

Ennustuste ja nende piirdekastide kombinatsiooni saab kasutada varude loendamiseks pildil.

Varude loendamine

4 tomatipasta purki, mille ümber on piirdekastid

Ü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

  1. Ava oma stock-counter projekt, kui see pole juba avatud.

  2. Lisa processPredictions funktsiooni 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.

  3. Selle alla ja processPredictions funktsiooni 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 Point struktuuri, et salvestada punkte pildil, ja Rect struktuuri, et määratleda ristkülik, kasutades ülemist vasakut ja alumist paremat koordinaati. Seejärel määratleb see area funktsiooni, mis arvutab ristküliku pindala ülemise vasaku ja alumise parema koordinaadi põhjal.

    Järgmisena määratleb see overlappingArea funktsiooni, mis arvutab kahe ristküliku kattuva ala. Kui need ei kattu, tagastab see 0.

  4. Lisa overlappingArea funktsiooni alla funktsioon, mis teisendab piirdekasti Rect-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.

  5. 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 processPredictions funktsiooni sisu kustutamisega.

  6. Lisa tühja processPredictions funktsiooni 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_predictions kogusse.

    💁 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.

  7. 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.

  8. 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.

  9. Laadi üles ja käivita oma kood. Suuna kaamera riiulil olevatele objektidele ja vajuta C-nuppu. Proovi muuta overlap_threshold vää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.