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

15 KiB

Бройте наличности от вашето IoT устройство - Виртуален IoT хардуер и Raspberry Pi

Комбинацията от предсказанията и техните ограничителни кутии може да се използва за преброяване на наличности в изображение.

Показване на ограничителни кутии

Като полезна стъпка за отстраняване на грешки, можете не само да отпечатате ограничителните кутии, но и да ги нарисувате върху изображението, което е записано на диска, когато е заснето изображение.

Задача - отпечатайте ограничителните кутии

  1. Уверете се, че проектът stock-counter е отворен в VS Code и виртуалната среда е активирана, ако използвате виртуално IoT устройство.

  2. Променете израза print в цикъла for на следното, за да отпечатате ограничителните кутии в конзолата:

    print(f'{prediction.tag_name}:\t{prediction.probability * 100:.2f}%\t{prediction.bounding_box}')
    
  3. Стартирайте приложението с камерата, насочена към някакви наличности на рафт. Ограничителните кутии ще бъдат отпечатани в конзолата с леви, горни, широчинни и височинни стойности от 0 до 1.

    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 може да се използва за рисуване върху изображения. Инсталирайте го със следната команда:

    pip3 install pillow
    

    Ако използвате виртуално IoT устройство, уверете се, че сте изпълнили тази команда в активираната виртуална среда.

  2. Добавете следния израз за импортиране в началото на файла app.py:

    from PIL import Image, ImageDraw, ImageColor
    

    Това импортира код, необходим за редактиране на изображението.

  3. Добавете следния код в края на файла app.py:

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

    Всяка ограничителна кутия се рисува върху изображението с червена линия. Накрая редактираното изображение се записва, като се презаписва оригиналното изображение.

  4. Стартирайте приложението с камерата, насочена към някакви наличности на рафт. Ще видите файла image.jpg в изследователя на VS Code и ще можете да го изберете, за да видите ограничителните кутии.

    4 консерви доматено пюре с ограничителни кутии около всяка консерва

Бройте наличности

На показаното по-горе изображение ограничителните кутии имат малко припокриване. Ако това припокриване беше много по-голямо, тогава ограничителните кутии може да показват един и същ обект. За да преброите обектите правилно, трябва да игнорирате кутиите със значително припокриване.

Задача - бройте наличности, игнорирайки припокриването

  1. Пакетът Pip Shapely може да се използва за изчисляване на пресечната точка. Ако използвате Raspberry Pi, първо ще трябва да инсталирате библиотечна зависимост:

    sudo apt install libgeos-dev
    
  2. Инсталирайте пакета Shapely:

    pip3 install shapely
    

    Ако използвате виртуално IoT устройство, уверете се, че сте изпълнили тази команда в активираната виртуална среда.

  3. Добавете следния израз за импортиране в началото на файла app.py:

    from shapely.geometry import Polygon
    

    Това импортира код, необходим за създаване на полигони за изчисляване на припокриването.

  4. Над кода, който рисува ограничителните кутии, добавете следния код:

    overlap_threshold = 0.20
    

    Това определя процента на припокриване, който е допустим, преди ограничителните кутии да се считат за един и същ обект. 0.20 определя 20% припокриване.

  5. За да изчислите припокриването с помощта на Shapely, ограничителните кутии трябва да бъдат преобразувани в полигони на Shapely. Добавете следната функция, за да направите това:

    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)])
    

    Това създава полигон, използвайки ограничителната кутия на предсказание.

  6. Логиката за премахване на припокриващи се обекти включва сравняване на всички ограничителни кутии и ако някои двойки предсказания имат ограничителни кутии, които се припокриват повече от прага, изтриване на едно от предсказанията. За да сравните всички предсказания, сравнявате предсказание 1 с 2, 3, 4 и т.н., след това 2 с 3, 4 и т.н. Следният код прави това:

    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')
    

    Припокриването се изчислява с помощта на метода Polygon.intersection на Shapely, който връща полигон с припокриването. Площта след това се изчислява от този полигон. Този праг на припокриване не е абсолютна стойност, а трябва да бъде процент от ограничителната кутия, така че се намира най-малката ограничителна кутия и прагът на припокриване се използва за изчисляване на площта, която припокриването може да има, за да не надвишава прага на процентното припокриване на най-малката ограничителна кутия. Ако припокриването надвишава това, предсказанието се маркира за изтриване.

    След като предсказанието е маркирано за изтриване, то не е необходимо да се проверява отново, така че вътрешният цикъл прекъсва, за да провери следващото предсказание. Не можете да изтривате елементи от списък, докато го обхождате, така че ограничителните кутии, които се припокриват повече от прага, се добавят към списъка to_delete, след което се изтриват накрая.

    Накрая броят на наличностите се отпечатва в конзолата. Това след това може да бъде изпратено към IoT услуга, за да се сигнализира, ако нивата на наличностите са ниски. Целият този код е преди ограничителните кутии да бъдат нарисувани, така че ще видите предсказанията за наличности без припокривания върху генерираните изображения.

    💁 Това е много опростен начин за премахване на припокривания, като просто се премахва първото в припокриваща се двойка. За производствен код бихте искали да добавите повече логика тук, като например разглеждане на припокриванията между множество обекти или ако една ограничителна кутия е съдържана в друга.

  7. Стартирайте приложението с камерата, насочена към някакви наличности на рафт. Резултатът ще покаже броя на ограничителните кутии без припокривания, които надвишават прага. Опитайте да промените стойността на overlap_threshold, за да видите как предсказанията се игнорират.

💁 Можете да намерите този код в папката code-count/pi или code-count/virtual-iot-device.

😀 Вашата програма за броене на наличности беше успешна!


Отказ от отговорност:
Този документ е преведен с помощта на AI услуга за превод Co-op Translator. Въпреки че се стремим към точност, моля, имайте предвид, че автоматизираните преводи може да съдържат грешки или неточности. Оригиналният документ на неговия роден език трябва да се счита за авторитетен източник. За критична информация се препоръчва професионален човешки превод. Ние не носим отговорност за недоразумения или погрешни интерпретации, произтичащи от използването на този превод.