5.20. Regresie și similaritate¶
Încă două măsurători din clasa Image rezumă imaginea ca altceva decât o distribuție de valori de pixeli. Regresia liniară a pixelilor cu prag aplicat oferă unei aplicații o linie pe baza căreia poate acționa – intrarea clasică pentru un robot care urmărește o linie. Măsurarea similarității oferă unei aplicații un singur număr care descrie cât de asemănătoare sunt două imagini – intrarea naturală pentru un test de regresie cu imagine de referință (golden image) sau pentru un detector de schimbări majore.
5.20.1. Regresie liniară¶
Atunci când pixelii din prim-planul unei imagini formează întâmplător o linie peste cadru – banda de pe o pistă pe care o urmărește un robot, linia unui orizont, marginea unui drum sau a unui coridor – aplicația de obicei nu dorește fiecare pixel individual din prim-plan. Ea dorește linia de cea mai bună potrivire prin toți aceștia, parametrizată astfel încât să poată decide cum este orientată linia și unde traversează cadrul.
get_regression() realizează acea potrivire. Ea preia aceeași formă de tuplu de prag pe care o folosesc binary() și find_blobs(), identifică fiecare pixel care se potrivește pragului și returnează un singur rezultat line care descrie linia de cea mai bună potrivire prin acei pixeli:
line = img.get_regression([(0, 60)])
if line:
img.draw_line((line.x1(), line.y1(),
line.x2(), line.y2()),
color=(255, 0, 0))
Potrivirea este regresia liniară Theil-Sen – o metodă robustă care tolerează valorile aberante mai bine decât mai cunoscuta potrivire prin cele mai mici pătrate. O mână mică de pixeli aflați departe de linia adevărată nu distorsionează rezultatul așa cum ar face-o cu metoda celor mai mici pătrate, ceea ce se potrivește cu realitatea zgomotoasă a unui prim-plan rezultat dintr-un prag real.
Rezultatul line poartă punctele finale decupate la dreptunghiul imaginii (x1, y1, x2, y2), lungimea și magnitudinea liniei (length, magnitude) și descrierea geometrică a liniei în formă polară (theta, rho) – unghiul liniei față de orizontală și distanța sa perpendiculară față de origine. Forma polară este cea pe care o dorește de obicei o buclă de control: theta îi spune robotului în ce direcție înclină linia, rho îi spune unde traversează linia imaginea, iar o buclă de reacție pe cele două menține robotul centrat pe linie.
O mână de argumente de tip cuvânt-cheie reglează robustețea și costul. x_stride și y_stride sar peste pixeli în timpul potrivirii – pași mai mari fac regresia mai ieftină cu prețul potrivirii a mai puțini pixeli. area_threshold și pixels_threshold resping liniile care nu au suficienți pixeli care se potrivesc în spate. target_size redimensionează intrarea la o dimensiune mai mică înainte de potrivire – regresia rulează mai repede pe un surogat de 80 pe 60 al imaginii fără prea multă pierdere în acuratețea direcției liniei.
Dacă nu s-a putut potrivi nicio linie acceptabilă – dacă pragul nu s-a potrivit cu niciun pixel, sau s-a potrivit cu un tipar care nu seamănă cu o linie – metoda returnează None. Codul real de urmărire a liniei protejează fiecare apel get_regression() cu o verificare None înainte de a accesa atributele liniei.
5.20.2. Similaritatea imaginilor¶
Un alt tip de măsurătoare: în loc de a întreba „ce conține imaginea?”, se întreabă „cât de asemănătoare sunt aceste două imagini?”. Operația la care se recurge este get_similarity(), care calculează Indicele de Similaritate Structurală (SSIM) între imaginea sursă și o imagine de referință.
s = img.get_similarity(reference)
print(s.mean, s.stdev)
SSIM este metrica standard de similaritate a imaginilor folosită în procesarea imaginilor deoarece se comportă așa cum se comportă intuiția umană despre similaritate – o deplasare mică sau o mică schimbare de luminozitate reduce scorul ușor, în timp ce o schimbare structurală mare (un obiect lipsă, o scenă diferită) îl reduce dramatic. Scorul variază de la -1 la +1: +1 înseamnă că cele două imagini sunt identice, 0 înseamnă că nu au legătură, iar -1 înseamnă că sunt structural opuse. Un obiect similarity returnat expune SSIM-ul mediu pe întreaga imagine, plus abaterea standard, minimul și maximul scorurilor per dală.
Pentru tipul de comparație în care un număr mic este mai bun decât unul mare – un test de regresie care ar trebui să raporteze zero la „nimic schimbat” și să crească pe măsură ce se acumulează schimbările – indicatorul dssim=True returnează disimilaritatea structurală: SSIM-ul mediu scăzut din 1, astfel încât valoarea returnată este 0.0 pentru imagini identice și crește pe măsură ce ele diferă.
5.20.3. Cazuri de utilizare pentru SSIM¶
Cele două aplicații frecvente:
Testarea de regresie cu imagine de referință (golden image). Un cadru de testare captează un cadru de referință în condiții cunoscute ca fiind bune și îl stochează ca imagine de referință (golden image). Rulările ulterioare de test captează în aceleași condiții și compară cu imaginea de referință folosind SSIM. Un scor peste un anumit prag (0.95 sau 0.98, în funcție de toleranță) este o trecere; sub acesta este un eșec. Cadrul de testare nu trebuie să știe ce s-a schimbat – scorul SSIM este semnalul.
Detectarea schimbărilor majore. O aplicație care dorește o versiune mai grosieră a diferențierii cadrelor – una care ignoră schimbările mici de luminozitate dar reacționează la schimbările structurale mari – poate folosi SSIM față de un cadru de referință în loc de difference() per pixel urmat de un prag. SSIM este mai puțin sensibil la deriva iluminării decât diferențierea per pixel, ceea ce îl face alegerea mai bună atunci când scopul este de a detecta „scena arată semnificativ diferit” mai degrabă decât „vreun pixel individual s-a schimbat.”
Ambele aplicații folosesc același apel – img.get_similarity(reference) – și se declanșează pe baza unui prag al scorului returnat. Diferența este doar dacă pragul este înalt (test de regresie, care caută o potrivire aproape identică) sau scăzut (detectare a schimbărilor, care caută orice schimbare structurală mare).
5.20.4. Forma transformă-și-compară¶
O subtilitate utilă: get_similarity() acceptă aceiași parametri x, y, x_scale, y_scale, roi, rgb_channel, alpha, color_palette, alpha_palette, hint și transform ca draw_image(). Imaginea de referință este poziționată, scalată și transformată de acei parametri înainte de rularea comparației SSIM.
Aceasta înseamnă că o aplicație poate întreba „cât de similară este această scenă cu un cadru de referință după o deplasare / rotație / scalare cunoscută” fără a pregăti o imagine de referință pre-transformată. Este modalitatea ieftină de a construi un dispozitiv de urmărire care caută într-un spațiu de parametri și raportează care transformare a referinței se potrivește cel mai bine cu cadrul curent.