8.6 KiB
IoT Cihazınızla Stok Sayımı - Wio Terminal
Tahminler ve bunlara ait sınırlayıcı kutuların kombinasyonu, bir görüntüdeki stokları saymak için kullanılabilir.
Stok Sayımı
Yukarıdaki görüntüde, sınırlayıcı kutuların küçük bir örtüşmesi var. Eğer bu örtüşme çok daha büyük olsaydı, sınırlayıcı kutular aynı nesneyi gösterebilirdi. Nesneleri doğru bir şekilde saymak için, önemli ölçüde örtüşen kutuları görmezden gelmeniz gerekir.
Görev - Örtüşmeyi göz ardı ederek stok sayımı
-
stock-counter
projenizi henüz açmadıysanız açın. -
processPredictions
fonksiyonunun üstüne aşağıdaki kodu ekleyin:const float overlap_threshold = 0.20f;
Bu, sınırlayıcı kutuların aynı nesne olarak kabul edilmeden önce izin verilen örtüşme yüzdesini tanımlar. 0.20, %20'lik bir örtüşmeyi ifade eder.
-
Bunun altına ve
processPredictions
fonksiyonunun üstüne, iki dikdörtgen arasındaki örtüşmeyi hesaplamak için aşağıdaki kodu ekleyin: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; }
Bu kod, görüntüdeki noktaları saklamak için bir
Point
yapısı ve bir dikdörtgeni sol üst ve sağ alt koordinatlarla tanımlamak için birRect
yapısı tanımlar. Daha sonra, bir dikdörtgenin alanını sol üst ve sağ alt koordinatlarından hesaplayan birarea
fonksiyonu tanımlar.Ardından, iki dikdörtgenin örtüşen alanını hesaplayan bir
overlappingArea
fonksiyonu tanımlar. Eğer örtüşme yoksa, 0 döner. -
overlappingArea
fonksiyonunun altına, bir sınırlayıcı kutuyuRect
e dönüştürmek için bir fonksiyon tanımlayın: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}; }
Bu, nesne algılayıcıdan bir tahmin alır, sınırlayıcı kutuyu çıkarır ve sınırlayıcı kutudaki değerleri kullanarak bir dikdörtgen tanımlar. Sağ taraf, sol taraf artı genişlikten hesaplanır. Alt taraf ise üst taraf artı yükseklikten hesaplanır.
-
Tahminlerin birbirleriyle karşılaştırılması gerekir ve eğer iki tahmin, eşik değerinden daha fazla örtüşüyorsa, bunlardan biri silinmelidir. Örtüşme eşiği bir yüzdedir, bu yüzden en küçük sınırlayıcı kutunun boyutuyla çarpılması gerekir. Böylece örtüşmenin, sınırlayıcı kutunun belirli bir yüzdesini aşıp aşmadığı kontrol edilir, tüm görüntünün yüzdesini değil.
processPredictions
fonksiyonunun içeriğini silerek başlayın. -
Boş
processPredictions
fonksiyonuna aşağıdakileri ekleyin: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]); } }
Bu kod, örtüşmeyen tahminleri saklamak için bir vektör tanımlar. Daha sonra tüm tahminler arasında döngü yapar ve sınırlayıcı kutudan bir
Rect
oluşturur.Ardından, kalan tahminler arasında döngü yapar ve mevcut tahminden sonrakilerle başlar. Bu, tahminlerin birden fazla kez karşılaştırılmasını önler - bir kez 1 ve 2 karşılaştırıldıktan sonra, 2'nin 1 ile tekrar karşılaştırılmasına gerek yoktur, yalnızca 3, 4, vb. ile karşılaştırılır.
Her tahmin çifti için örtüşen alan hesaplanır. Bu, en küçük sınırlayıcı kutunun alanıyla karşılaştırılır - eğer örtüşme, en küçük sınırlayıcı kutunun eşik yüzdesini aşarsa, tahmin geçerli olarak işaretlenmez. Tüm örtüşmeler karşılaştırıldıktan sonra, tahmin kontrolleri geçerse
passed_predictions
koleksiyonuna eklenir.💁 Bu, örtüşmeleri kaldırmanın oldukça basit bir yoludur, sadece örtüşen çiftteki ilkini kaldırır. Üretim kodu için, birden fazla nesne arasındaki örtüşmeleri dikkate almak veya bir sınırlayıcı kutunun başka bir kutunun içinde olup olmadığını kontrol etmek gibi daha fazla mantık eklemek isteyebilirsiniz.
-
Bundan sonra, geçen tahminlerin detaylarını seri monitöre göndermek için aşağıdaki kodu ekleyin:
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); }
Bu kod, geçen tahminler arasında döngü yapar ve detaylarını seri monitöre yazdırır.
-
Bunun altına, sayılan öğelerin sayısını seri monitöre yazdırmak için kod ekleyin:
Serial.print("Counted "); Serial.print(passed_predictions.size()); Serial.println(" stock items.");
Bu, stok seviyelerinin düşük olduğunu bildirmek için bir IoT hizmetine gönderilebilir.
-
Kodunuzu yükleyin ve çalıştırın. Kamerayı bir raftaki nesnelere doğrultun ve C düğmesine basın. Tahminlerin göz ardı edildiğini görmek için
overlap_threshold
değerini ayarlamayı deneyin.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.
💁 Bu kodu code-count/wio-terminal klasöründe bulabilirsiniz.
😀 Stok sayacı programınız başarılı oldu!
Feragatname:
Bu belge, AI çeviri hizmeti Co-op Translator kullanılarak çevrilmiştir. Doğruluk için çaba göstersek de, otomatik çevirilerin hata veya yanlışlıklar içerebileceğini lütfen unutmayın. Belgenin orijinal dili, yetkili kaynak olarak kabul edilmelidir. Kritik bilgiler için profesyonel insan çevirisi önerilir. Bu çevirinin kullanımından kaynaklanan yanlış anlamalar veya yanlış yorumlamalardan sorumlu değiliz.