Ceva despre estomparea unei imagini folosind shadere

Ceva despre estomparea unei imagini folosind shadere

De fapt, pentru a estompa imaginea trebuie să fie valori ale fiecărui pixel de culoare cu culorile vecinilor săi în medie într-un fel într-un anumit interval. Această gamă va fi numită raza de estompare. Soluția evidentă ar fi următoarele: a stabili valorile de culoare pentru fiecare pixel, care este situat nu mai departe decât raza estompare a curentului, în coordonatele X și Y și apoi împărțiți-le cu pătratul razelor două neclaritate plus unu (din moment ce suntem la stânga, dreapta, sus și jos selectați pixeli la o distanță care să nu depășească raza pixelilor de centru +). Cu toate acestea, să numărăm cât de mulți pixeli trebuie să obținem din imagine. Rezultatul acestui cod:








va fi o valoare egală cu (1 + 2 • r) • (1 + 2 • r), unde r este raza de neclaritate. Pentru raza de neclaritate = 10, aceasta produce 441 de probe! Aceasta este o complexitate imensă care nu poate fi folosită peste tot. A fost de a simplifica această complexitate și a venit cu algoritmi de blocare a două treceri. Esența acestor algoritmi este că imaginea este neclară în primul rând pe orizontală (sau verticală) și stocate în imagine temporar, după care imaginea rezultată este neclară în cealaltă direcție. În acest caz, obținem complexitatea (1 + 2 • R) + (1 + 2 • R). Pentru raza de neclaritate = 10, obținem 42 de probe pe pixel, care sunt aproape de R ori mai mici.

De asemenea, atunci când se estompează imaginea, trebuie luată în considerare greutatea pixelilor. Cu variația lor, puteți obține un rezultat diferit. Deci, dacă toți pixelii au aceeași greutate, obținem o imagine medie. Dacă dai pixelilor centrali mai multă greutate decât cea extremă, atunci imaginea va fi mai "concentrată". Pentru a modifica ponderile, putem folosi diferite legi de distribuție cunoscute din statisticile matematice.

Deci, haideți să ne uităm la algoritmii principali de blocare a două treceri. De exemplu, luați această imagine originală:

Ceva despre estomparea unei imagini folosind shadere

Apreciați pixelii adiacenți

Acesta este cel mai simplu algoritm. Folosim legea uniformă de distribuție. În acest caz, toți pixelii vor avea aceeași greutate. Să setăm raza de neclaritate la zece:

Ceva despre estomparea unei imagini folosind shadere

numărul magic 21 este suma tuturor greutăților pixelilor vecini (desigur, pentru o rază de neclaritate egală cu 10). Pentru acest număr trebuie să împărțim suma culorilor pixelilor vecini. După cum puteți vedea, suma pixelilor centrali și vecini (din fiecare parte) este exact 2 * R + 1. Astfel, nu este nevoie să calculați această sumă.

Luați în considerare implementarea acestui algoritm în limbajul shader GLSL

Parametrii de intrare sunt un sampler pentru imaginea originală și un vector cu trei componente care conține etapa de estompare și raza. Pasul neclaritate în acest caz va fi (1.0 / (lățime de imagine); 0,0) pentru estomparea orizontală și (0,0; 1,0 / (înălțimea imaginii)) vertical. În implementările ulterioare, vom folosi aceeași terminologie. După două treceri, imaginea neclară va arăta astfel:







Ceva despre estomparea unei imagini folosind shadere

Dreptul triunghiular de distribuție

Algoritmul următor cel mai complicat este un algoritm care utilizează legea distribuției Simpson. În această lege, distribuția greutății punctelor vecine pe textură, cu distanța tot mai mare către punctul central, scade liniar. Ca și înainte, am stabilit raza de neclaritate la zece. Ca și înainte, va trebui să găsim suma tuturor greutăților pixelilor vecini ai texturii și să împărțim rezultatul final în ea. Pentru a face acest lucru, puneți greutatea băncii centrale egale cu (r + 1). În acest caz, greutatea pixelilor vecini se va schimba în funcție de funcția f (x) (în imaginea de mai jos). Ponderile punctelor extreme în acest caz vor fi egale cu unitatea.

Ceva despre estomparea unei imagini folosind shadere

Suma ponderilor tuturor pixelilor în acest caz va fi exprimată prin formula (R + 1) 2.

Implementarea acestui algoritm pe GLSL este prezentată mai jos:

Rezultatul prelucrării imaginilor de către acest algoritm va arăta astfel:

Ceva despre estomparea unei imagini folosind shadere

Legea distribuției normale

Următorul algoritm de estompare, pe care îl vom lua în considerare, va fi așa numitul blur gaussian. Este folosit în Photoshop. Esența sa constă în utilizarea legii normale de distribuție. De obicei, legea normală de distribuție include doi parametri: așteptarea matematică și varianța. Pentru cazul nostru, presupunem că așteptarea matematică este zero. În acest caz, legea distribuției include doar un singur parametru, variația. O astfel de lege simplificată de distribuție este prezentată în figura de mai jos (funcția f (x)). Deoarece legea de dispersie este utilizată în această lege, și nu în rază, vom folosi regula de trei sigma. Se spune că în intervalul -3 # 963; + 3 # 963; 99,73% din toate valorile rezultate din scăderea distribuției. Setați raza la zece, în acest caz # 963; va fi 10/3 = 3 (partea fracționată nu este luată în considerare, deoarece facem un pas pe un număr întreg de pixeli distanță de cel central).

Trebuie notat că în acest algoritm suma greutăților tuturor pixelilor vecini va fi aproape de unitate. Adică nu trebuie să divizăm sau să multiplicăm rezultatul cu niciun număr. Dar, de asemenea, nu trebuie să uităm că nu 100% din valori se încadrează în limita aleasă, dar numai 99,73%. Aceasta înseamnă că suma va fi mai mică decât una și imaginea finală va fi estompată. Pentru a elimina acest neajuns va crește modificarea greutății punctului central de la (1,0 - [suma ponderilor vecine]) și în cele din urmă se obține o sumă de greutăți de toți pixelii egal cu unitatea.

Ceva despre estomparea unei imagini folosind shadere

Luați în considerare codul acestui algoritm pe GLSL:

După cum puteți vedea, există multe instrucțiuni inutile. Constantele sunt recalculate de fiecare dată, etc. Să optimizăm puțin acest cod:
1) luați sigma din rădăcină și calculați constanta 1.0 / sqrt (2.0 * PI),
2) deoarece sigma nu am modificat, astfel încât nu se schimba întreaga expresie înainte de exponent, precum și coeficientul lui x în expresia în exponent, prin urmare, toate acestea pot fi numărate o dată și să facă „bracketing“
3) scapă de operația superfluă de împărțire cu trei, înlocuind tripletul cu expresii.

După operațiile terminate, ajungem aici într-un asemenea shader

Cu această optimizare am redus nu numai dimensiunea shader-ului, ci și creșterea vitezei cu aproximativ 1,15 ori (testat cu o rază de estompare = 50). Acest lucru, veți fi de acord, este un pic, dar util :)

Rezultatul blurului Gaussian va arăta astfel:

Ceva despre estomparea unei imagini folosind shadere

Setați raza de estompare la 30 și comparați rezultatul cu neclaritatea din Photoshop:

Ceva despre estomparea unei imagini folosind shadere
Ceva despre estomparea unei imagini folosind shadere

Prima imagine, neclară cu o rază de 30 de pixeli, a doua - diferența dintre algoritmul de mai sus și filtrul photoshop







Trimiteți-le prietenilor: