5.2. Coordonate și regiuni

Procesarea imaginilor acționează asupra pixelilor, iar pentru a acționa asupra unui pixel un algoritm trebuie să îl adreseze prin coordonată. Pentru a acționa asupra unui dreptunghi de pixeli, este la fel – dreptunghiul trebuie descris într-un mod asupra căruia algoritmul și codul aplicației sunt de acord. Convenția pe care modulul image o folosește pentru coordonate și dreptunghiuri este simplă, cu un detaliu care îi surprinde pe cititorii obișnuiți cu convenția matematică mai degrabă decât cu cea din grafica pe calculator, și acela merită menționat explicit de la bun început.

5.2.1. Grila de pixeli

Pixelul (0, 0) este colțul din stânga-sus al unei imagini. Axa x se desfășoară spre dreapta, deci un x mai mare înseamnă mai la dreapta. Axa y se desfășoară în jos, deci un y mai mare înseamnă mai jos în imagine. O imagine de lățime pe înălțime conține pixeli la coordonate întregi de la (0, 0) până la (width - 1, height - 1); nu există niciun pixel la (width, 0) sau (0, height) – acele poziții sunt muchiile din dreapta și de jos, la un pas dincolo de ultimul pixel real în fiecare direcție.

Axa y orientată în jos este detaliul menționat mai sus. Un cititor obișnuit cu geometria pe hârtie milimetrică se așteaptă ca un y mai mare să însemne mai sus; aici această intuiție este exact inversată. Motivul inversării este că senzorii digitali și afișajele digitale lucrează amândouă pornind din stânga-sus și parcurg fiecare rând spre dreapta, de sus în jos, iar dispunerea pixelilor în memorie în aceeași ordine face ca relația dintre „poziția i în tampon” și „rândul r, coloana c ale imaginii” să fie cel mai simplu calcul aritmetic posibil – poziția i a pixelului (x, y) este pur și simplu y * width + x. Fiecare bibliotecă de imagini a căzut de acord asupra acestei dispuneri cu decenii în urmă din același motiv, iar costul este o mică ajustare mentală atunci când lucrezi pentru prima dată cu imagini.

Un dreptunghi care reprezintă o imagine. Un marcaj în colțul său din stânga-sus este etichetat (0, 0). O săgeată de-a lungul muchiei superioare arată spre dreapta, etichetată x; o săgeată de-a lungul muchiei din stânga arată în jos, etichetată y. Un dreptunghi mai mic desenat în interior este etichetat ROI, cu colțul său din stânga-sus la (x, y) și dimensiunile w și h marcate de-a lungul muchiilor.

Sistemul de coordonate al imaginii: originea în stânga-sus, x se desfășoară spre dreapta, y se desfășoară în jos. O regiune dreptunghiulară din interiorul imaginii este denumită prin colțul ei din stânga-sus (x, y) și dimensiunile ei (w, h).

5.2.2. Dreptunghiuri

Majoritatea operațiilor asupra unei imagini sunt mai puțin interesate de un singur pixel cât de un dreptunghi de pixeli – o zonă în care se caută, o regiune de copiat, un cadru în interiorul unui cadru asupra căruia se calculează statistici. Forma pentru denumirea unui dreptunghi alege cea mai simplă extindere posibilă a convenției pentru un singur pixel: dă coordonata colțului din stânga-sus, urmată de dimensiunile dreptunghiului, împachetate într-un cvadruplu (x, y, w, h). Pixelii din interiorul dreptunghiului se află la coloanele de la x până la x + w - 1 și rândurile de la y până la y + h - 1.

Detaliul care merită menționat explicit aici este că w și h sunt dimensiuni, nu coordonate ale colțului din dreapta-jos. Dreptunghiul (10, 20, 4, 3) acoperă coloanele 10, 11, 12, 13 și rândurile 20, 21, 22 – douăsprezece pixeli în total – nu o regiune care merge de la (10, 20) la (4, 3). Convenția este uniformă în întregul modul, așa că odată ce este interiorizată, scăpările încetează, dar îi prinde pe oameni prima dată.

Forma (x, y, w, h) apare în trei locuri care par distincte, dar împărtășesc aceeași convenție. Primul este atunci când o imagine își descrie propria amprentă: dreptunghiul care acoperă întreaga imagine este (0, 0, width, height). Al doilea este atunci când o metodă de detectare returnează un rezultat cu o casetă de încadrare – un blob, un rect, un apriltag – iar caseta este raportată ca (x, y, w, h). Al treilea este atunci când unei metode trebuie să i se spună să lucreze pe o sub-regiune a imaginii mai degrabă decât pe întregul cadru; argumentul de tip cuvânt-cheie roi care delimitează operația preia același cvadruplu.

Preluarea unei casete de încadrare de la o metodă și transmiterea ei în argumentul roi al metodei următoare este unul dintre cele mai frecvente tipare în procesarea imaginilor. Caseta de încadrare a unei prime detectări grosiere îngustează zona de căutare pentru o a doua detectare mai fină, iar vocabularul uniform între rezultatele detectării și argumentele metodelor este ceea ce face ca acest tipar să fie atât de simplu – o singură formă de tuplu, folosită în același mod de ambele părți ale predării.

5.2.3. Adrese întregi, centroizi fracționari

Adresele pixelilor în sine sunt numere întregi. Un pixel fie se află, fie nu se află la o anumită coloană și rând întreg, iar întrebarea ce se află la coordonata (40.5, 30.7) nu este o întrebare bine formulată – nu există niciun pixel situat exact în acea poziție. Câteva mărimi pe care modulul image le derivă din pozițiile pixelilor sunt totuși fracționare, și merită să înțelegem de ce, astfel încât distincția să nu surprindă aplicația mai târziu.

Cel mai frecvent caz este centroidul – centrul de masă al unei regiuni. Pentru o regiune conectată de pixeli, centroidul în formă cu virgulă mobilă este media pozițiilor pixelilor membri, ponderată după densitatea lor. O regiune ai cărei pixeli se întind pe două coloane va avea un centroid x de, să zicem, 41.6 – o poziție reală pe care ochiul ar descrie-o ca „mijlocul acelei regiuni”, deși niciun pixel real nu se află exact la acel x. Obiectele rezultat ale detectării poartă ambele forme ca proprietăți doar-în-citire: o pereche de întregi (cx / cy, utilă când poziția este transmisă înapoi către ceva care dorește coordonate de pixeli întregi) și o pereche cu virgulă mobilă (cxf / cyf, utilă când poziția intră într-o buclă de control care beneficiază de rezoluție sub-pixel).

Celălalt caz este deplasarea dintre două cadre măsurată în domeniul frecvenței. Tehnicile care analizează conținutul spectral al unei imagini mai degrabă decât direct pixelii ei pot rezolva deplasări mai fine decât un pixel, iar acestea raportează acele deplasări ca valori (dx, dy) cu virgulă mobilă.

Regula de bază: adresele pixelilor sunt numere întregi; pozițiile și deplasările care ies dintr-un algoritm pot fi numere cu virgulă mobilă. Metodele de desenare acceptă oricare formă și rotunjesc numerele cu virgulă mobilă în jos la cel mai apropiat pixel întreg atunci când rezultatul trebuie să nimerească pe grilă.

5.2.4. Cartezian și polar

Sistemul descris până acum este cartezian: fiecare pixel este denumit prin deplasarea sa orizontală și verticală față de origine. Acela este sistemul în care octeții sunt stocați – pixelul i din tampon corespunde pixelului de la coloana i % width și rândul i // width, parcurgând rândurile de sus în jos – și este sistemul în care fiecare metodă operează în mod implicit.

O a doua reprezentare merită cunoscută deoarece unii algoritmi funcționează mult mai bine cu ea. Coordonatele polare denumesc fiecare pixel prin distanța sa față de un punct central ales și unghiul dintre el și o direcție de referință. Pixelii imaginii nu s-au mișcat – octeții sunt în continuare în același tampon ordonat pe rânduri – dar schema de adresare a trecut de la „cât de la dreapta și cât de jos” la „cât de departe de centru și la ce unghi în jurul lui.”

Două dreptunghiuri unul lângă altul, fiecare reprezentând aceeași imagine. Cel din stânga arată coordonate carteziene -- origine în stânga-sus, axele x și y, un punct exemplu P la coordonatele (x, y). Cel din dreapta arată coordonate polare -- un marcaj de centru C în interiorul dreptunghiului, cu o linie de la C la același punct P etichetată r (distanță), și un arc etichetat theta (unghi).

Același punct P, denumit în două moduri: cartezian (x, y) față de originea din stânga-sus, polar (r, theta) față de un centru ales.

De ce să ne deranjăm să schimbăm sistemul? Din cauza a două identități care transformă căutările dificile în unele ușoare.

În coordonate polare, rotirea imaginii în jurul centrului ales este aceeași operație cu translatarea pixelilor ei de-a lungul axei unghiului – direcția x în imaginea re-proiectată. O copie rotită este originalul deplasat la stânga sau la dreapta în formă polară.

În varianta log-polară – axa distanței folosește o scară logaritmică, axa unghiului rămâne liniară – scalarea imaginii în jurul centrului ales este aceeași operație cu translatarea pixelilor ei de-a lungul axei distanței – direcția y. O copie scalată este originalul deplasat în sus sau în jos în formă log-polară.

Astfel, un algoritm care trebuie să recunoască un tipar cunoscut sub rotație sau scalare își poate face căutarea în spațiul polar, unde ambele transformări devin translatări obișnuite. Translatările sunt mult mai ieftine de căutat decât rotațiile și scalările, iar re-proiecția polară este cea care face posibilă această substituire.

Coordonatele polare nu înlocuiesc cartezienele pentru stocarea pixelilor; octeții trăiesc întotdeauna pe grila carteziană. Modulul oferă o pereche de metode care re-proiectează o imagine din formă carteziană în formă polară la cerere, algoritmul care are nevoie de coordonate polare își face treaba, iar fie rezultatul se proiectează înapoi, fie măsurătoarea din spațiul polar este folosită direct. Acel mecanism este singurul motiv pentru care coordonatele polare apar undeva pe suprafața modulului.

Cu coordonatele carteziene pentru denumirea pixelilor individuali, cvadruplul (x, y, w, h) pentru denumirea dreptunghiurilor de pixeli, și coordonatele polare disponibile atunci când un algoritm beneficiază de ele, o aplicație are un vocabular complet pentru a denumi unde în imagine se află ceva. Ceea ce este stocat efectiv la oricare dintre aceste poziții este următorul strat al fundației.