5.27. Daireleri ve dikdörtgenleri bulma

Çizgiler ve segmentler, yakalanan çerçevedeki düz kenarları kapsar; ancak kameranın aradığı gerçek dünya özniteliklerinin çoğu düz değildir. Bir masanın üzerinde duran bozuk para bir dairedir. Basılı bir etiket, bir yapışkan not veya eksen dışından görülen bir kutunun üst yüzeyi bir dörtgendir. image modülü her biri için ayrı bir tespit ediciye sahiptir: daireler için Hough tarzı bir arama ve dört kenarlı şekiller için AprilTag türevli bir arama.

Her iki yöntem de çizgi tespit edicilerinin izlediği aynı şablonu izler – threshold bir tespitin kaç oya ihtiyaç duyduğunu denetler, roi aramayı daraltır ve döndürülen nesneler hem bir konum hem de bir güven büyüklüğü taşır – ancak parametre alanları ve doğru varsayılanlar, açıkça ele alınmayı hak edecek kadar farklılaşır.

5.27.1. Hough daireleri

find_circles(), Hough dönüşümünün dairesel varyantını çalıştırır. Sobel ön geçişinden gelen her kenar pikseli, içinden geçebilecek her daire için oy verir; yeterli oyu toplayan daireler döndürülür.

circles = img.find_circles(threshold=3500,
                            x_margin=10, y_margin=10, r_margin=10,
                            r_min=10, r_max=80, r_step=2)

for c in circles:
    img.draw_circle((c.x, c.y, c.r), color=(255, 0, 0))

threshold, aday daire boyunca Sobel kenar büyüklüklerinin minimum toplamıdır. Daha büyük daireler daha fazla piksel izler ve bu nedenle geçmek için daha yüksek eşiklere ihtiyaç duyar; 20 piksel yarıçaplı bir bozuk parayı bulan bir değer, 100 piksellik bir kenarın çevresindeki gürültüde de tetiklenir, oysa büyük bozuk para için ayarlanmış bir değer küçük olanı kaçırır. Hedef yarıçap aralığı bilindiğinde, doğru eşik çevre uzunluğuyla ölçeklenir – kabaca threshold = 50 * 2 * pi * r makul bir başlangıç noktası verir ve doğru değer kısa bir ayar geçişinin ardından gelir.

r_min, r_max ve r_step, yarıçap aramasını belirler. Sınırlar olmadan, tespit edici birkaç pikselden görüntünün yarı genişliğine kadar her yarıçapı arardı; bu hem yavaştır hem de yanlış pozitiflere davetiyedir. r_min ve r_max değerlerini beklenen hedef boyutunu cömert bir payla kuşatacak şekilde ayarlamak (örneğin yaklaşık 20 piksel olduğu bilinen bir bozuk para için r_min=15, r_max=25) işi büyük ölçüde azaltır ve oyların sinyal-gürültü oranını iyileştirir. r_step aramanın ayrıntı düzeyini denetler; daha büyük adımlar daha hızlı çalışır ve gerçek yarıçapı örneklenen iki değer arasında kalan bir daireyi kaçırabilir. Varsayılan r_step=2 makul bir uzlaşmadır.

x_margin, y_margin ve r_margin, theta_margin ve rho_margin değerlerinin çizgi tespiti için yaptığı gibi, yakındaki tespitlerin birleştirilmesini denetler. Görüntüdeki tek bir fiziksel daire, merkezleri ve yarıçapları birkaç piksel içinde uyuşan bir aday daire kümesi için oy verir; bu paylar, sonuç listesi oluşturulmadan önce her kümeyi tepe noktasına indirir. Daha büyük paylar daha az ve daha güvenilir tespitler döndürür; daha küçük paylar olası neredeyse-yinelenenlerle birlikte daha fazla tespit döndürür.

x_stride ve y_stride, diğer tespit edicilerde yaptıkları gibi oylama taramasını adımlar. 2 ve 1 varsayılanı çoğu görüntü için uygundur; her ikisini de 4 değerine yükseltmek, büyük daireler içerdiği bilinen bir görüntü için standart hız ödünleşmesidir.

Döndürülen her Circle, x, y, r (merkez ve yarıçap) ve magnitude (oy toplamı; sıralama veya filtreleme için bir güven puanı olarak kullanışlıdır) taşır. Tespiti çerçeveye geri çizmek tek bir çağrıdır – draw_circle(), sonuçtan doğrudan (c.x, c.y, c.r) olarak erişilebilen (x, y, r) 3’lü demetini alır.

5.27.2. Dikdörtgenler

find_rects(), dörtgen tespit edicisini AprilTag işlem hattından ödünç alır – bir etiketin etrafındaki siyah kareyi bulan aynı rutin, genel amaçlı bir dikdörtgen bulucu olarak kendi başına sunulur.

rects = img.find_rects(threshold=12000)

for r in rects:
    img.draw_rectangle(r.rect, color=(0, 255, 0))
    for corner in r.corners:
        img.draw_circle((corner[0], corner[1], 4),
                        color=(0, 255, 0))

threshold, dikdörtgenin çevresi boyunca kenar büyüklüklerinin minimum toplamıdır. İyi aydınlatılmış bir çerçevedeki beyaz üzerine basılı siyah bir dikdörtgen 10000 değerini kolayca geçer; dokulu bir arka plandaki soluk bir dikdörtgenin 2000 değerine düşmesi gerekebilir – yanlış pozitifleri duyarlılık karşılığında takas eder. Daire tespit edicisi gibi, doğru değer de hedeflenen nesneler görüntüdeyken yapılan hızlı bir ayar geçişinin ardından gelir.

Tespit edici projektiftir – kenarları düz ancak ille de paralel veya eksen hizalı olmayan dörtgenleri bulur. Eksen dışından görülen bir etiket görüntüde bir yamuk gibi görünür ve dikdörtgen tespit edicisi onu doğru bir şekilde bulur; eksen hizalı bir dikdörtgen, dört köşenin tesadüfen dik açılı bir kutu oluşturduğu dejenere durumdan ibarettir. roi aramayı kısıtlar; anahtar sözcük argümanlarının geri kalanı varsayılan değerlerini AprilTag işlem hattından alır ve nadiren ayar gerektirir.

Döndürülen her Rect, eksen hizalı sınırlayıcı kutuyu – x, y, w, h ile birlikte draw_rectangle() yönteminin beklediği rect 4’lü demetini – ve corners olarak dört tespit edilen köşeyi taşır. Sınırlayıcı kutu, uygulamanın kaba konum ve boyut için kullandığı şeydir; köşeler projektif dörtgenin kendisini tanımlar. Kamera düz bir hedefi bir açıdan görüntülediğinde ve uygulamanın anahtar taşı bozulmasını geri almaya ihtiyacı olduğunda – bir etiketteki metni okumak, düz bir yamadan renk örneklemek – köşeler corners= anahtar sözcüğüyle doğrudan rotation_corr() yöntemine beslenir (bkz. lens and perspective correction) ve çıktı, sonraki analiz için hazır düzeltilmiş dikdörtgendir.

Uyarı

Tespit edici, AprilTag işlem hattının ihtiyaç duyduğu şey için ayarlandığından – beyaz kağıt üzerindeki siyah bir etiket ana hattı gibi güçlü, yüksek kontrastlı kenarlara sahip dörtgenler – her dikdörtgeni bulan bir geçiş değildir. Yumuşak kontrastlı, dokulu kenarlı veya yoğun çevreli dikdörtgenler tamamen tespit edilemeyebilir. Ne kadar iyi çalıştığı duruma bağlıdır: etrafında bir işlem hattı kurmadan önce, erken bir aşamada gerçek hedeflere karşı test edin.

5.27.3. Tespit edici yanlış tetiklendiğinde

Özellikle daireler, girişe uygulanan bir ön filtreden yararlanır. Gürültülü bir çerçeve, hepsi oy veren çok sayıda başıboş kenar pikseli üretir ve ortaya çıkan Hough uzayı, birleştiricinin ayırmakta zorlandığı geniş ve bulanık tepelere sahip olur. find_circles() öncesinde bir gaussian() veya mean() geçişi, gürültüyü düzleştirerek giderir ve gerçek kenarları sağlam bırakır; tespit edici daha kısa sürede daha temiz tepeler döndürür.

Dikdörtgenler için yaygın hata türü tam tersidir: dikdörtgen ile arka planı arasındaki düşük kontrast, kenar büyüklüğü toplamının threshold değerini hiç geçmediği anlamına gelir. Parlaklık aralığını tam 0 ile 255 arasındaki yayılıma yeniden dağıtan bir histeq() geçişi, tespit edicinin ihtiyaç duyduğu kontrastı geri kazandırır. (Kontrastın görüntüde bir yerde var olması gerekir; histogram eşitlemesi yalnızca zaten orada olanı yükseltebilir.)