5.21. Skaliranje, zrcaljenje i obrezivanje

Sve prethodne podsekcije radile su na pikselima na istim položajima na kojima su počele. Obitelj transformacija to mijenja. Skaliranje šalje svaki ulazni piksel na drugačiji izlazni položaj, moguće na nekoliko izlaznih položaja odjednom (pri uvećavanju) ili na položaj dijeljen s nekoliko drugih ulaznih piksela (pri umanjivanju). Zrcaljenje i rotiranje rade isto kroz drugačije preslikavanje. Obrezivanje zadržava pravokutni podskup ulaznih piksela, a ostatak odbacuje.

Modul image izlaže tu obitelj kroz tri metode koje dijele većinu svojih argumenata i većinu svog ponašanja:

  • copy() – proizvodi kopiju slike, moguće skaliranu, obrezanu ili preorijentiranu.

  • crop() – ista operacija kao copy, ali s očekivanjem da će aplikacija izabrati podpravokutnik iz izvora.

  • scale() – isto ponovno, s očekivanjem da će aplikacija promijeniti veličinu rezultata.

Sve tri dijele iste argumente i istu mehaniku transformacije; razlika je gdje rezultat pretpostavljeno završava. copy() proizvodi novu sliku, dok crop() i scale() mijenjaju izvor na mjestu.

5.21.1. Zajednički argumenti

Jedan poziv kombinira bilo koju kombinaciju skaliranja, obrezivanja, orijentacije i izdvajanja kanala koju aplikacija zatraži:

x_scale i y_scale skaliraju ulaz duž vodoravne i okomite osi neovisno. Oba pretpostavljeno iznose 1.0 (bez skaliranja). Različite vrijednosti za svaku proizvode neuniformno skaliranje – na primjer, sličicu rastegnutu dvostruko šire nego što je visoka.

roi ograničava ulaz na pravokutnik izvorne slike, uzimajući samo te piksele kroz ostatak transformacije. Ovo je dio operacije „obrezivanja”: proslijedite roi za izdvajanje podpodručja.

hint je bitno polje zastavica koje odabire metodu interpolacije i bilo kakve orijentacijske zaokrete. Više zastavica kombinira se bitovnim ILI (hint=image.BILINEAR | image.HMIRROR). Zastavice se dijele u dvije skupine – obitelj interpolacije i obitelj orijentacije – koje nemaju nikakve veze jedna s drugom, ali dijele isto bitno polje.

rgb_channel odabire jedan kanal RGB565 izvora. 0 znači crveni, 1 znači zeleni, 2 znači plavi; rezultat izlazi kao slika u sivim tonovima koja sadrži samo taj kanal. Korisno za određivanje praga samo na crvenom kanalu, na primjer.

color_palette i alpha_palette preslikavaju vrijednosti piksela kroz tablicu pretraživanja prilikom izlaza, na isti način kao što to čine metode konverzije to_rainbow() i to_ironbow().

copy=True i copy_to_fb=True slijede istu konvenciju koju koristi svaka druga metoda koja proizvodi rezultat – na mjestu pretpostavljeno, copy=True dodjeljuje zaseban rezultat, copy_to_fb=True smješta rezultat u međuspremnik slike za pregled u IDE-u.

5.21.2. Interpolacija: AREA, BILINEAR, BICUBIC

Kada skaliranje šalje svaki izlazni piksel na položaj koji se ne poravnava ni s jednim pojedinačnim ulaznim pikselom, metoda mora izabrati koju vrijednost zapisati. Tri zastavice upravljaju time kako:

image.BILINEAR interpolira između četiri najbliža ulazna piksela ponderirana njihovom udaljenošću od izlaznog položaja. Rezultat je glađi od najbližeg susjeda, bez vidljivih nazubljenosti na dijagonalnim crtama, ali dodatna aritmetika košta otprilike četiri puta više od prolaza najbližeg susjeda. Pravi izbor za većinu poslova uvećavanja i za bilo koji necjelobrojni faktor mjerila.

image.BICUBIC interpolira između šesnaest najbližih ulaznih piksela koristeći kubičnu krivulju, što proizvodi još glađe rezultate uz cijenu još više aritmetike. Najbolja kvaliteta za aplikacije osjetljive na cijenu kojima je potrebna; rijetko vrijedna dodatnog izračuna za sličice uživo koje će IDE samo prikazivati.

image.AREA usrednjava svaki ulazni piksel koji pada unutar otiska izlaznog piksela – pravi algoritam za umanjivanje. Bilinearna i bikubična su interpolatori: procjenjuju vrijednost između izvornih piksela, što je ono što uvećavanje treba, ali pri umanjivanju svaki izlazni piksel pokriva mnogo izvornih piksela, a interpolator čita samo onih nekoliko najbližih – detalj koji preskoči vraća se kao aliasing. image.AREA umjesto toga uračunava svaki pokriveni piksel u prosjek.

Pretpostavljeni algoritam skaliranja bez ikakvog hinta je najbliži susjed, koji je najjeftiniji i pravi odgovor kada je izvor već na pikselskoj razlučivosti odredišta.

5.21.3. Orijentacija: zrcaljenja i rotacije

Orijentacijske zastavice su mali skup logičkih transformacija koje se slobodno slažu jedna s drugom i s interpolacijskim zastavicama:

  • image.VFLIP zrcali sliku okomito (vrh postaje dno).

  • image.HMIRROR zrcali je vodoravno (lijevo postaje desno).

  • image.TRANSPOSE zamjenjuje x i y osi (retci postaju stupci).

Većina rotacija proizlazi iz slaganja te tri. Modul također izlaže imenovane prečace:

  • image.ROTATE_90 (= VFLIP | TRANSPOSE)

  • image.ROTATE_180 (= HMIRROR | VFLIP)

  • image.ROTATE_270 (= HMIRROR | TRANSPOSE)

U kodu:

img.copy(hint=image.ROTATE_90, copy_to_fb=True)

5.21.4. Postupanje s omjerom

Kada se omjer širine i visine izvora ne podudara s pravokutnikom u koji se crta, tri zastavice odlučuju što učiniti s nepodudaranjem:

image.SCALE_ASPECT_KEEP zadržava omjer širine i visine izvora i letterboxa rezultat – izvor se skalira dok ne stane unutar odredišta, pri čemu prazni (nulti) pikseli popunjavaju ostatak odredišta. Pravi izbor kada je očuvanje neiskrivljenog izvora važnije od popunjavanja cijelog izlaza.

image.SCALE_ASPECT_EXPAND zadržava omjer širine i visine izvora i obrezuje ga – izvor se skalira dok ne ispuni odredište, pri čemu se dijelovi koji prelaze izvan odredišta odsijecaju. Pravi izbor kada je popunjavanje cijelog izlaza važnije od vidljivosti svakog dijela izvora.

image.SCALE_ASPECT_IGNORE zanemaruje omjer širine i visine i rasteže izvor da ispuni odredište, prihvaćajući bilo kakvo iskrivljenje koje to uvodi. Pravi izbor kada je aplikacija već uzela u obzir iskrivljenje – kada dimenzije odredišta zapravo nisu pravokutnik iste scene, na primjer.

Pretpostavljeno (bez postavljene zastavice omjera) jednako je kao SCALE_ASPECT_IGNORE: rastegni da ispuni. Aplikacije koje vode računa o omjeru širine i visine eksplicitno navode jednu od tri.

5.21.5. Kada posegnuti za kojom

Većina promjena veličine koristi scale() s parom x_scale / y_scale i interpolacijskim hintom:

img.scale(x_scale=0.5, y_scale=0.5, hint=image.AREA)

Većina rotacija koristi isti poziv s hint=image.ROTATE_90 ili sličnim.

Obrezivanje koristi crop() s nepretpostavljenim roi:

img.crop(roi=(40, 30, 200, 150))

Kada izvor mora preživjeti operaciju – snimanje referentne sličice, izrada sličice umanjenog prikaza sličice koja će biti destruktivno obrađena – copy() proizvodi rezultat kao novu sliku i ostavlja izvor netaknutim:

thumbnail = img.copy(x_scale=0.25, y_scale=0.25, hint=image.AREA)

Ta pretpostavljena vrijednost je prava razlika iza tri imena: scale i crop transformiraju na mjestu, copy dodjeljuje. Ključne riječi za smještaj rezultata premošćuju jaz: copy=True na scale ili crop dodjeljuje rezultat kao zaseban međuspremnik na gomili umjesto prepisivanja izvora, a copy_to_fb=True na bilo kojoj od tri smješta ga u međuspremnik slike za pregled u IDE-u.