5.27. Pronalaženje kružnica i pravokutnika

Linije i segmenti pokrivaju ravne rubove u snimljenoj sličici, no mnoge stvarne značajke koje kamera traži nisu ravne. Novčić koji leži na stolu je kružnica. Tiskana oznaka, samoljepljiva poruka ili vrh kutije gledan ukoso jest četverokut. Modul image nudi namjenski detektor za svaki od njih: Hough-pretragu za kružnice i pretragu izvedenu iz AprilTag-a za četverostrane oblike.

Obje metode slijede isti obrazac kao i detektori linija – threshold upravlja brojem glasova koji detekcija treba, roi sužava pretragu, a vraćeni objekti nose i položaj i veličinu pouzdanosti – ali se prostori parametara i ispravne zadane vrijednosti razlikuju dovoljno da zaslužuju izričito obrađivanje.

5.27.1. Houghove kružnice

find_circles() pokreće kružnu varijantu Houghove transformacije. Svaki rubni piksel iz Sobelovog predprolaza glasa za svaku kružnicu koja bi mogla proći kroz njega; kružnice koje skupe dovoljno glasova bivaju vraćene.

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 je najmanji zbroj veličina Sobelovih rubova duž kandidatske kružnice. Veće kružnice ocrtavaju više piksela pa zahtijevaju više pragove da bi prošle; vrijednost koja pronađe novčić polumjera 20 piksela također će se aktivirati na šumu oko ruba od 100 piksela, dok će vrijednost podešena za veliki novčić promašiti mali. Kada je poznat raspon ciljnog polumjera, ispravan prag skalira se s opsegom – otprilike threshold = 50 * 2 * pi * r daje razumnu polaznu točku, a ispravna vrijednost slijedi iz kratkog prolaza podešavanja.

r_min, r_max i r_step postavljaju pretragu polumjera. Bez granica detektor bi pretraživao svaki polumjer od nekoliko piksela do polovice širine slike, što je i sporo i recept za lažne pozitive. Postavljanje r_min i r_max tako da velikodušnom marginom obuhvate očekivanu veličinu cilja (npr. r_min=15, r_max=25 za novčić za koji se zna da je oko 20 piksela) bitno smanjuje posao i poboljšava omjer signala i šuma glasova. r_step upravlja granularnošću pretrage; veći koraci rade brže i mogu promašiti kružnicu čiji pravi polumjer pada između dvije uzorkovane vrijednosti. Zadana vrijednost r_step=2 razuman je kompromis.

x_margin, y_margin i r_margin upravljaju spajanjem obližnjih detekcija, na isti način kao što to theta_margin i rho_margin rade za detekciju linija. Jedna fizička kružnica na slici glasa za skupinu kandidatskih kružnica čija se središta i polumjeri podudaraju unutar nekoliko piksela; margine svaku skupinu sažimaju na njezin vrhunac prije nego što se izgradi popis rezultata. Veće margine vraćaju manje, pouzdanijih detekcija; manje margine vraćaju više detekcija s mogućim bliskim duplikatima.

x_stride i y_stride koračaju kroz skeniranje glasovanja, na isti način kao u drugim detektorima. Zadane vrijednosti 2 i 1 prikladne su za većinu slika; podizanje obiju na 4 standardni je kompromis brzine za sliku za koju se zna da sadrži velike kružnice.

Svaka vraćena Circle nosi x, y, r (središte i polumjer) i magnitude (ukupni broj glasova, korisno kao ocjena pouzdanosti za sortiranje ili filtriranje). Crtanje detekcije natrag u sličicu jedan je poziv – draw_circle() prima 3-torku (x, y, r), dostupnu kao (c.x, c.y, c.r) izravno iz rezultata.

5.27.2. Pravokutnici

find_rects() posuđuje detektor četverokuta iz AprilTag protoka – istu rutinu koja locira crni kvadrat oko oznake izloženu zasebno kao pretraživač pravokutnika opće namjene.

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 je najmanji zbroj veličina rubova oko opsega pravokutnika. Tiskani crni pravokutnik na bijeloj podlozi u dobro osvijetljenoj sličici lako prelazi 10000; slabašan pravokutnik na teksturiranoj podlozi može trebati spustiti na 2000 – žrtvujući lažne pozitive za osjetljivost. Kao i kod detektora kružnica, ispravna vrijednost slijedi iz brzog prolaza podešavanja s namijenjenim ciljevima u kadru.

Detektor je projektivan – pronalazi četverokute čije su stranice ravne, ali ne nužno paralelne ili poravnate s osima. Oznaka gledana ukoso na slici izgleda kao trapez, a detektor pravokutnika ispravno je pronalazi; pravokutnik poravnat s osima samo je degenerirani slučaj u kojem se četiri kuta slučajno sastaju u pravokutnu kutiju. roi ograničava pretragu; ostali ključni argumenti uzimaju svoje zadane vrijednosti iz AprilTag protoka i rijetko trebaju podešavanje.

Svaki vraćeni Rect nosi granični okvir poravnat s osima – x, y, w, h, uz 4-torku rect koju draw_rectangle() očekuje – i četiri otkrivena kuta kao corners. Granični okvir je ono što aplikacija koristi za grubi položaj i veličinu; kutovi opisuju sam projektivni četverokut. Kada kamera gleda ravni cilj pod kutom i aplikacija treba poništiti trapezno izobličenje – čitanje teksta na oznaci, uzorkovanje boje s ravne mrlje – kutovi se izravno predaju metodi rotation_corr() s ključnom riječi corners= (vidi korekcija leće i perspektive), a izlaz je ispravljeni pravokutnik spreman za kakvu god analizu slijedi.

Upozorenje

Budući da je detektor podešen za ono što AprilTag protok treba – četverokute sa snažnim, visokokontrastnim obrubima, poput crnog obrisa oznake na bijelom papiru – on nije prolaz koji pronalazi svaki pravokutnik. Pravokutnici s mekim kontrastom, teksturiranim rubovima ili užurbanom okolinom mogu u potpunosti ostati nezamijećeni. Koliko dobro radi ovisi o situaciji: testirajte ga rano na stvarnim ciljevima, prije nego što oko njega izgradite protok.

5.27.3. Kada detektor pogriješi

Kružnice posebno imaju koristi od predfiltra na ulazu. Šumovita sličica daje mnogo zalutalih rubnih piksela koji svi glasaju, a rezultirajući Houghov prostor ima široke razmrljane vrhove koje spajač teško razdvaja. Prolaz gaussian() ili mean() prije find_circles() izglađuje šum i ostavlja prave rubove netaknutima; detektor vraća čišće vrhove u kraćem vremenu.

Kod pravokutnika čest način otkazivanja je suprotan: nizak kontrast između pravokutnika i njegove podloge znači da zbroj veličina rubova nikada ne prelazi threshold. Prolaz histeq() koji preraspodjeljuje raspon svjetline preko cijelog raspona od 0 do 255 vraća kontrast koji detektor treba. (Kontrast mora postojati negdje na slici; izjednačavanje histograma može samo pojačati ono što je već prisutno.)