5.20. Regressio ja samankaltaisuus

Kaksi muuta Image-luokan mittausta tekee kuvasta yhteenvedon jonain muuna kuin pikseliarvojen jakaumana. Kynnystettyjen pikselien lineaarinen regressio antaa sovellukselle viivan, jonka perusteella se voi toimia – klassinen syöte viivaa seuraavalle robotille. Samankaltaisuusmittaus antaa sovellukselle yksittäisen luvun, joka kuvaa, kuinka samankaltaisia kaksi kuvaa ovat – luonnollinen syöte kultakuvaregressiotestille tai karkeiden muutosten tunnistimelle.

5.20.1. Lineaarinen regressio

Kun kuvan etualan pikselit sattuvat muodostamaan viivan kehyksen poikki – teippi radalla, jota robotti seuraa, horisontin viiva, tien tai käytävän reuna – sovellus ei yleensä halua jokaista yksittäistä etualan pikseliä. Se haluaa parhaiten sopivan viivan niiden kaikkien läpi, parametrisoituna niin, että se voi päättää, kuinka viiva on suunnattu ja missä se ylittää kehyksen.

get_regression() tekee tämän sovituksen. Se ottaa saman kynnysarvotuplemuodon, jota binary() ja find_blobs() käyttävät, tunnistaa jokaisen kynnysarvoa vastaavan pikselin ja palauttaa yksittäisen line-tuloksen, joka kuvaa parhaiten sopivan viivan näiden pikselien läpi:

line = img.get_regression([(0, 60)])
if line:
    img.draw_line((line.x1(), line.y1(),
                   line.x2(), line.y2()),
                  color=(255, 0, 0))

Sovitus on Theil-Sen-lineaarinen regressio – robusti menetelmä, joka sietää poikkeavia arvoja paremmin kuin tutumpi pienimmän neliösumman sovitus. Pieni kourallinen pikseleitä kaukana todellisesta viivasta ei vinouta tulosta samalla tavalla kuin pienimmän neliösumman menetelmässä, mikä vastaa todellisen kynnysarvotulosteen kohisevaa etuala-todellisuutta.

line-tulos kantaa kuvan suorakulmioon leikatut päätepisteet (x1, y1, x2, y2), viivan pituuden ja suuruuden (length, magnitude) sekä viivan geometrisen kuvauksen polaarimuodossa (theta, rho) – viivan kulman vaakasuunnasta ja sen kohtisuoran etäisyyden origosta. Polaarimuoto on se, mitä säätösilmukka yleensä haluaa: theta kertoo robotille, mihin suuntaan viiva kallistuu, rho kertoo, missä viiva ylittää kuvan, ja näiden kahden takaisinkytkentäsilmukka pitää robotin keskitettynä viivalle.

Kourallinen avainsana-argumentteja säätää robustisuutta ja kustannusta. x_stride ja y_stride ohittavat pikseleitä sovituksen aikana – suuremmat askelvälit tekevät regressiosta edullisemman sovitettujen pikselien vähenemisen kustannuksella. area_threshold ja pixels_threshold hylkäävät viivat, joiden takana ei ole riittävästi vastaavia pikseleitä. target_size skaalaa syötteen pienempään kokoon ennen sovitusta – regressio toimii nopeammin kuvan 80x60-korvikkeella ilman suurta tarkkuuden menetystä viivan suunnassa.

Jos hyväksyttävää viivaa ei voitu sovittaa – jos kynnysarvo ei vastannut yhtäkään pikseliä tai vastasi kaavaa, joka ei näytä viivalta – menetelmä palauttaa None. Todellinen viivaa seuraava koodi suojaa jokaisen get_regression()-kutsun None-tarkistuksella ennen kuin se hakee viivan attribuutteja.

5.20.2. Kuvien samankaltaisuus

Erilainen mittaus: sen sijaan, että kysyttäisiin ”mitä kuva sisältää?”, kysytään ”kuinka samankaltaisia nämä kaksi kuvaa ovat?”. Tähän tarkoitukseen sopiva operaatio on get_similarity(), joka laskee rakenteellisen samankaltaisuusindeksin (SSIM) lähdekuvan ja vertailukuvan välillä.

s = img.get_similarity(reference)
print(s.mean, s.stdev)

SSIM on vakiomittari kuvien samankaltaisuudelle, jota käytetään kautta kuvankäsittelyn, koska se käyttäytyy tavalla, jolla ihmisen intuitio samankaltaisuudesta käyttäytyy – pieni siirtymä tai pieni kirkkausmuutos laskee pistemäärää hieman, kun taas suuri rakenteellinen muutos (puuttuva kohde, eri näkymä) laskee sitä dramaattisesti. Pistemäärä vaihtelee välillä -1+1: +1 tarkoittaa, että kaksi kuvaa ovat identtisiä, 0 tarkoittaa, että ne ovat toisiinsa liittymättömiä, ja -1 tarkoittaa, että ne ovat rakenteellisesti vastakkaisia. Palautettu similarity-objekti tarjoaa keskimääräisen SSIM:n koko kuvalle sekä ruutukohtaisten pistemäärien keskihajonnan, minimin ja maksimin.

Sellaiseen vertailuun, jossa pieni luku on parempi kuin suuri – regressiotesti, jonka pitäisi raportoida nolla, kun ”mikään ei muuttunut”, ja nousta muutosten kertyessä – dssim=True-lippu palauttaa rakenteellisen erilaisuuden: keskimääräisen SSIM:n vähennettynä luvusta 1, jolloin paluuarvo on 0.0 identtisille kuville ja nousee, kun ne eroavat toisistaan.

5.20.3. SSIM:n käyttötapaukset

Kaksi yleistä sovellusta:

Kultakuvaregressiotestaus. Testikehys kaappaa vertailukehyksen tunnetusti hyvissä olosuhteissa ja tallentaa sen kultakuvana. Myöhemmät testiajot kaapataan samoissa olosuhteissa ja niitä verrataan kultakuvaan SSIM:llä. Tietyn kynnysarvon yläpuolella oleva pistemäärä (0.95 tai 0.98 toleranssista riippuen) on läpäisy; sen alapuolella on hylkäys. Testikehyksen ei tarvitse tietää, mikä muuttui – SSIM-pistemäärä on signaali.

Karkeiden muutosten tunnistus. Sovellus, joka haluaa karkeamman version kehyserotuksesta – sellaisen, joka jättää huomiotta pienet kirkkausmuutokset mutta reagoi suuriin rakenteellisiin muutoksiin – voi käyttää SSIM:ää vertailukehystä vastaan pikselikohtaisen difference()-toiminnon ja sitä seuraavan kynnysarvon sijaan. SSIM on vähemmän herkkä valaistuksen ajelehtimiselle kuin pikselikohtainen erotus, mikä tekee siitä paremman valinnan, kun tavoitteena on havaita ”näkymä näyttää olennaisesti erilaiselta” eikä ”mikä tahansa yksittäinen pikseli muuttui”.

Molemmat sovellukset käyttävät samaa kutsua – img.get_similarity(reference) – ja laukeavat palautetun pistemäärän kynnysarvosta. Ero on vain siinä, onko kynnysarvo korkea (regressiotesti, joka etsii lähes identtistä vastaavuutta) vai matala (muutostunnistus, joka etsii mitä tahansa suurta rakenteellista muutosta).

5.20.4. Muunna-ja-vertaa-muoto

Hyödyllinen hienous: get_similarity() hyväksyy samat x-, y-, x_scale-, y_scale-, roi-, rgb_channel-, alpha-, color_palette-, alpha_palette-, hint- ja transform-parametrit kuin draw_image(). Vertailukuva sijoitetaan, skaalataan ja muunnetaan näillä parametreilla ennen SSIM-vertailun suorittamista.

Tämä tarkoittaa, että sovellus voi kysyä ”kuinka samankaltainen tämä näkymä on vertailukehyksen kanssa jälkeen tunnetun siirtymän / kierron / skaalauksen” valmistelematta esimuunnettua vertailukuvaa. Tämä on edullinen tapa rakentaa seurain, joka etsii parametriavaruutta ja raportoi, mikä vertailukuvan muunnos vastaa parhaiten nykyistä kehystä.