從你的物聯網設備計數庫存 - 虛擬物聯網硬體和樹莓派
可以使用預測結果及其邊界框的組合來計數圖像中的庫存
顯示邊界框
作為一個有用的調試步驟,你不僅可以打印出邊界框,還可以將它們繪製在捕獲圖像時寫入磁盤的圖像上。
任務 - 打印邊界框
-
確保在 VS Code 中打開
stock-counter
專案,如果你使用的是虛擬物聯網設備,請激活虛擬環境。 -
將
for
迴圈中的print
語句更改為以下內容,以將邊界框打印到控制台:print(f'{prediction.tag_name}:\t{prediction.probability * 100:.2f}%\t{prediction.bounding_box}')
-
將相機對準架子上的一些庫存運行應用程式。邊界框將打印到控制台,左、上、寬和高值範圍為 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}
任務 - 在圖像上繪製邊界框
-
Pip 套件 Pillow 可用於在圖像上繪製。使用以下命令安裝它:
pip3 install pillow
如果你使用的是虛擬物聯網設備,請確保在激活的虛擬環境內運行此命令。
-
在
app.py
文件的頂部添加以下導入語句:from PIL import Image, ImageDraw, ImageColor
這將導入編輯圖像所需的代碼。
-
在
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)。
每個邊界框都使用紅線繪製在圖像上。最後,編輯後的圖像被保存,覆蓋原始圖像。
-
將相機對準架子上的一些庫存運行應用程式。你將在 VS Code 資源管理器中看到
image.jpg
文件,並且可以選擇它以查看邊界框。
計數庫存
在上圖中,邊界框有小的重疊。如果這種重疊更大,那麼邊界框可能表示同一個物體。為了正確計數物體,你需要忽略具有顯著重疊的框。
任務 - 忽略重疊計數庫存
-
Pip 套件 Shapely 可用於計算交集。如果你使用的是樹莓派,則需要先安裝庫依賴項:
sudo apt install libgeos-dev
-
安裝 Shapely Pip 套件:
pip3 install shapely
如果你使用的是虛擬物聯網設備,請確保在激活的虛擬環境內運行此命令。
-
在
app.py
文件的頂部添加以下導入語句:from shapely.geometry import Polygon
這將導入創建多邊形以計算重疊所需的代碼。
-
在繪製邊界框的代碼上方添加以下代碼:
overlap_threshold = 0.20
這定義了在邊界框被認為是同一個物體之前允許的重疊百分比。0.20 定義了 20% 的重疊。
-
要使用 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)])這使用預測的邊界框創建一個多邊形。
-
刪除重疊物體的邏輯涉及比較所有邊界框,如果任何一對預測的邊界框重疊超過閾值,則刪除其中一個預測。要比較所有預測,你需要將預測 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')重疊是使用 Shapely 的
Polygon.intersection
方法計算的,該方法返回具有重疊的多邊形。然後從這個多邊形計算面積。這個重疊閾值不是一個絕對值,而是需要是邊界框的百分比,因此找到最小的邊界框,並使用重疊閾值計算重疊面積不能超過最小邊界框的百分比重疊閾值。如果重疊超過此值,則標記預測以刪除。一旦預測被標記為刪除,就不需要再次檢查,因此內部迴圈中斷以檢查下一個預測。你不能在遍歷列表時刪除列表中的項目,因此重疊超過閾值的邊界框被添加到
to_delete
列表中,然後在最後刪除。最後,庫存計數打印到控制台。然後可以將其發送到物聯網服務以在庫存水平低時發出警報。所有這些代碼都在繪製邊界框之前,因此你將在生成的圖像上看到沒有重疊的庫存預測。
💁 這是一種非常簡單的方法來刪除重疊,只刪除重疊對中的第一個。在生產代碼中,你可能需要在這裡添加更多邏輯,例如考慮多個物體之間的重疊,或者如果一個邊界框包含在另一個邊界框中。
-
將相機對準架子上的一些庫存運行應用程式。輸出將顯示沒有超過閾值的重疊邊界框的數量。嘗試調整
overlap_threshold
值以查看被忽略的預測。
💁 你可以在 code-count/pi 或 code-count/virtual-iot-device 文件夾中找到此代碼。
😀 你的庫存計數程式成功了!