Přeskočit na obsah
coden

Obraz jako signál: pixely, barvy, konvoluce a hrany

Obraz jako matice čísel, barvy a jas, 2D konvoluce (rozmazání a zostření), Sobelův detektor hran v šumu, aliasing a moaré při zmenšování a cesta od ručně navržených jader ke konvolučním sítím.

12 minut Matěj Žalmánek 2026-10-16

Série Základy AI Díl 60 z 83
  1. Mapa umělé inteligence: co je co a jak to do sebe zapadá
  2. Stručná historie umělé inteligence: od Turinga po jazykové modely
  3. Data, model, trénink, inference: základní pojmy na jednom příkladu
  4. Jak číst matematický zápis: symboly, indexy, sumy a kvantifikátory
  5. Množiny a relace: stavebnice, ze které se skládají definice v AI
  6. Funkce a zobrazení: proč je každý model v AI funkce
  7. Logika a důkazy: pravidla, podle kterých se v AI uvažuje
  8. Grafy a stromy: struktura, na které stojí hledání i neuronové sítě
  9. Lineární algebra pro strojové učení: vektory, matice a proč AI hlavně násobí
  10. Derivace, gradient a řetízkové pravidlo: jak model zjistí, kterým směrem se učit
  11. Gradientní sestup: jak se model učí
  12. Co je pravděpodobnost: od hodu kostkou ke Kolmogorovovým axiomům
  13. Podmíněná pravděpodobnost a Bayesova věta: jak změnit odhad, když se dozvíte něco nového
  14. Náhodná veličina a distribuční funkce: jedna funkce, která o rozdělení řekne všechno
  15. Funkce hustoty a pravděpodobnostní funkce: proč má spojitá veličina v bodě pravděpodobnost nula
  16. Střední hodnota, rozptyl a kovariance: kde rozdělení leží, jak je široké a co s čím souvisí
  17. Přehled pravděpodobnostních rozdělení: Bernoulli, binomické, Poisson, rovnoměrné, normální a exponenciální
  18. Zákon velkých čísel a centrální limitní věta: proč se průměry chovají tak předvídatelně
  19. Statistika a odhady parametrů: maximální věrohodnost, MAP a intervaly spolehlivosti
  20. Teorie informace: entropie, křížová entropie a KL divergence — odkud se berou ztrátové funkce
  21. Prohledávání stavového prostoru: BFS, DFS, UCS a A* s animacemi
  22. Hry a protivník: minimax, alfa-beta ořezávání a Monte Carlo tree search
  23. Splňování omezujících podmínek: backtracking, propagace omezení a AC-3 na sudoku a mapě krajů
  24. Logika a znalostní systémy: dopředné a zpětné řetězení, rezoluce a expertní systémy
  25. Plánování: STRIPS, svět kostek, heuristiky z relaxace a plánování v AI agentech
  26. Lokální hledání a simulované žíhání: obchodní cestující přes krajská města
  27. Genetické algoritmy: populace, křížení, mutace a výběr na batohu na výlet
  28. Evoluční strategie a genetické programování: od pravidla jedné pětiny po Keplerův zákon
  29. Optimalizace mravenčí kolonií: jak feromonová stopa najde krátkou cestu
  30. Optimalizace hejnem částic: setrvačnost, vlastní zkušenost a zkušenost hejna
  31. Neuroevoluce: evoluce vah i tvaru neuronových sítí a algoritmus NEAT
  32. Fuzzy množiny a funkce příslušnosti: jak zapsat „trochu teplo“
  33. Fuzzy logika a pravděpodobnost: proč „trochu teplo“ neznamená „pravděpodobně teplo“
  34. Fuzzy logika: t-normy, implikace a pravidla KDYŽ–PAK
  35. Fuzzy řízení: Mamdani a Sugeno od ventilátoru po kyvadlo na vozíku
  36. Fuzzy shlukování: algoritmus fuzzy c-means a body mezi shluky
  37. Neuro-fuzzy systémy (ANFIS): fuzzy pravidla, která se učí z dat
  38. Markovovy řetězce: přechodová matice, stacionární rozdělení a PageRank
  39. Skryté Markovovy modely: Viterbiho algoritmus a nepoctivé kasino
  40. Bayesovské sítě: proč je tráva mokrá a co z toho plyne pro postřikovač
  41. Kalmanův filtr: jak z nepřesných měření odhadnout, kde auto je a jak rychle jede
  42. Druhy strojového učení: s učitelem, bez učitele, s částečným učitelem a další
  43. Přeučení a regularizace: proč model, který zná data nazpaměť, selže
  44. Vyhodnocení modelu: křížová validace, F1 a křivka ROC
  45. Shlukování a snížení dimenze: k-means, PCA a t-SNE
  46. Klasifikace a regrese: dvě úlohy učení s učitelem
  47. Lineární regrese: nejmenší čtverce geometricky i maticově
  48. Polynomiální a nelineární regrese: jak přímku ohnout
  49. Logistická regrese: sigmoida, šance a křížová entropie
  50. Vícetřídní klasifikace a softmax: od dvou tříd k mnoha
  51. Naivní Bayesův klasifikátor: spamový filtr, který funguje lépe, než by měl
  52. Ztrátové funkce: co přesně model minimalizuje
  53. Rozhodovací stromy a k nejbližších sousedů: modely bez vzorců
  54. Ansámbly: náhodný les a gradient boosting
  55. SVM a jádrový trik: nejširší hranice a jak ji ohnout
  56. Signál a vzorkování: proč platí Nyquistův teorém
  57. Fourierova transformace: rozklad signálu na frekvence
  58. Filtry a konvoluce: vyhlazení, hrany a odstranění šumu
  59. Zvuk a řeč: spektrogram, melová škála a MFCC
  60. Obraz jako signál: pixely, barvy, konvoluce a hrany
  61. Perceptron a umělý neuron: nejjednodušší neuronová síť a co neumí
  62. Neuronová síť od nuly: zpětné šíření chyby krok za krokem
  63. Aktivace, inicializace a normalizace: drobnosti, na kterých hluboká síť stojí
  64. Konvoluční sítě: jak síť poznává obrázky
  65. Rekurentní sítě: paměť pro posloupnosti a mizející gradient
  66. LSTM a GRU: brány, které rozhodují, co si síť zapamatuje
  67. Autoenkodéry: síť, která se učí data stlačit a zase rozbalit
  68. Embeddingy a word2vec: jak se slovo stane vektorem
  69. Mechanismus pozornosti: jak se model naučí, kam se dívat
  70. Transformery a velké jazykové modely: architektura krok za krokem
  71. Tokenizace: jak se text rozseká na kousky pro model
  72. Předtrénování a škálování: proč větší model a víc dat funguje
  73. Doladění a RLHF: jak se z doplňovače textu stane asistent
  74. Prompty, kontext a RAG: jak modelu dát správné informace
  75. Variační autoenkodéry (VAE): nové obrázky ze spojitého latentního prostoru
  76. Generativní adversariální sítě (GAN): padělatel proti detektivovi
  77. Difúzní modely: jak se z čistého šumu stane obrázek
  78. Markovovy rozhodovací procesy: stavy, akce, odměny a Bellmanovy rovnice
  79. Q-learning a DQN: učení hodnoty akcí od tabulky po neuronovou síť
  80. Policy gradient a PPO: učení přímo strategie
  81. Jak funguje AI agent: jazykový model ve smyčce s nástroji
  82. Programování s AI agenty: zadání, testy a kontrola
  83. Vyhodnocení a bezpečnost AI systémů: jak měřit a jak hlídat

Celá osnova série 83 z 83 témat hotovo

Co si odnesete
  • Jak počítač ukládá obraz a barvy a kolik čísel to je.
  • Co dělá 2D konvoluce a jak se jí hledají hrany.
  • Proč zmenšování obrázku vyrábí moaré a proč se konvoluční sítě učí jádra samy.

Co se hodí znát předem: Signál a vzorkování: proč platí Nyquistův teorém, Filtry a konvoluce: vyhlazení, hrany a odstranění šumu

Pro počítač je fotka tabulka čísel. Kočka, západ slunce i rentgenový snímek jsou jen matice hodnot jasu — a všechno, co jsme se v posledních dílech naučili o signálech, platí i pro ně. Vzorkování, aliasing, konvoluce a hrany mají v obraze dva rozměry místo jednoho, ale princip je stejný. A právě na obrazech se ukázalo, jak silná konvoluce je: konvoluční neuronové sítě, které se ji učí samy, v roce 2012 překvapivě vyhrály soutěž v rozpoznávání obrázků a odstartovaly dnešní vlnu umělé inteligence.

Navazuje na díly Signál a vzorkování a Filtry a konvoluce.

1. Obraz jako matice čísel

Definice — digitální obraz a pixel

Nechť H, W ∈ ℕ (výška a šířka) a V je množina možných hodnot jasu — pro 8bitový obraz V = {0, 1, …, 255}, ve výpočtech V = ℝ. Digitální šedotónový obraz je funkce

I : {0, …, H − 1} × {0, …, W − 1} → V,

tedy matice I[y, x] s H řádky a W sloupci. Každá dvojice (y, x) je pixel a I[y, x] je jeho jas (řádek y shora, sloupec x zleva). Barevný obraz má v každém pixelu tři hodnoty, I : {0, …, H − 1} × {0, …, W − 1} → V3. Obraz je tak dvourozměrný signál, vzorkovaný (hodnoty jen v bodech mřížky) a kvantovaný (konečně mnoho úrovní jasu).

Laicky řečeno

Mozaika z dlaždiček, každá jednobarevná. Z dálky obraz, zblízka čísla. Fotka z telefonu s 12 megapixely (4 000 × 3 000) má po třech barvách 36 milionů čísel. Neuronové sítě na rozpoznávání obrázků proto obvykle dostávají obrázek zmenšený na 224 × 224 pixelů — i tak je to 150 528 čísel.

bez šumu šum σ = 0,12
Syntetická scéna 48 × 48 pixelů: bez šumu a se šumem
22925518421393114160752032552551971251351521022452142142271808214992233255217229176170103132255255241255255144821552552052432331981599690196245167255126100118118157228246253114127107128
Výřez 8 × 8 pixelů na okraji kruhu: odstín a hodnota 0–255

Naše scéna má 48 × 48 pixelů: pozadí plynule světlající zleva doprava, světlý kruh a tmavý čtverec. Výřez ukazuje, co z toho „vidí“ počítač: hranice kruhu není čára, ale místo, kde čísla skočí ze zhruba 230 na zhruba 120 — a šum do čísel přimíchá náhodné výkyvy.

Definice — kvantování jasu

Výpočty v tomhle dílu pracují s jasem v ∈ ℝ jako s reálným číslem (0 = černá, 1 = bílá). Nechť round(t) značí celé číslo nejbližší k t ∈ ℝ (poloviny nahoru). Kvantování na 8 bitů je funkce q : ℝ → {0, 1, …, 255},

q(v) = round(255 · min(1, max(0, v))).

Hodnoty mimo [0, 1] se tedy nejdřív ořežou a pak se výsledek zaokrouhlí na nejbližší z 256 úrovní.

kruh: v = 0,9  ⇒  255 · 0,9 = 229,5  ⇒  230

pozadí ve sloupci x = 26: v = 0,3 + 0,3 · 26/47 = 0,4660  ⇒  255 · 0,4660 = 118,8  ⇒  119

fotka 4 000 × 3 000 se třemi kanály po 8 bitech: 36 000 000 bajtů = 36 MB bez komprese

Definice — aditivní gaussovský šum

Nechť I : {0, …, H − 1} × {0, …, W − 1} → ℝ je obraz, σ > 0 a εy,x (pro všechny pixely (y, x)) jsou nezávislé náhodné veličiny s normovaným normálním rozdělením 𝒩(0, 1) (střední hodnota 0, rozptyl 1). Obraz s aditivním gaussovským šumem je

Ĩ[y, x] = I[y, x] + σ · εy,x   pro všechny pixely (y, x).

K jasu každého pixelu se tedy přičte vlastní náhodný výkyv se směrodatnou odchylkou σ, nezávisle na ostatních pixelech. U nás σ = 0,12 — na stupnici 0–255 typický výkyv kolem 31 úrovní. Je to nejjednodušší a nejběžnější model šumu snímače (skutečný šum je navíc závislý na jasu).

2. Barvy

Definice — model RGB a jas

V modelu RGB je barva trojice (R, G, B) ∈ [0, 255]3 intenzit červené, zelené a modré složky, které se sčítají (aditivní míchání světla): (0, 0, 0) je černá, (255, 255, 255) bílá. Jas barvy (R, G, B) podle normy ITU-R BT.601 je číslo

Y = 0,299 R + 0,587 G + 0,114 B ∈ [0, 255].

Jas je tedy vážený součet složek; je to nejčastěji používaná volba vah.

Laicky řečeno

Displej má v každém pixelu tři maličké lampičky. Oko má na barvy tři druhy čípků a nejcitlivější je na zelenou — proto má zelená ve vzorci pro jas největší váhu. Plně svítící zelená má jas 150 z 255, červená 76, modrá jen 29. Žlutá (červená + zelená) 226. Proto modrý text na černém pozadí čte oko tak špatně.

Y = 0,299 R + 0,587 G + 0,114 B

Y
jas — jak světlý pixel připadá oku; tohle číslo zbude po převodu na šedou
0,299 R
příspěvek červené: oko ji vnímá zhruba poloviční silou než zelenou
0,587 G
příspěvek zelené — největší váha, protože na zelenou je oko nejcitlivější
0,114 B
příspěvek modré — nejmenší, modrou vnímá oko jako nejtmavší
Váhy dávají dohromady 0,299 + 0,587 + 0,114 = 1, takže bílá (255, 255, 255) má jas přesně 255 a šedá zůstane šedou.
Příklad — jas základních barev

Barvy podle vzorce výše:

zelená (0, 255, 0): 0,587 · 255 = 149,685 ≈ 150

červená (255, 0, 0): 0,299 · 255 = 76,245 ≈ 76;   modrá (0, 0, 255): 0,114 · 255 = 29,07 ≈ 29

žlutá (255, 255, 0): 76,245 + 149,685 = 225,93 ≈ 226

Pro neuronovou síť je barevný obrázek tři matice nad sebou — tři kanály. Většina operací v tomhle dílu se dělá na každém kanálu zvlášť, a tak budeme pracovat jen se šedotónovými obrázky.

3. 2D konvoluce

Definice — dvourozměrná konvoluce

Nechť I : ℤ2 → ℝ je obraz (mimo svůj rozsah doplněný podle definice okrajů níže), m ∈ {0, 1, 2, …} a K : {−m, …, m}2 → ℝ je jádro — matice vah velikosti (2m + 1) × (2m + 1), např. 3 × 3 pro m = 1. 2D konvoluce obrazu I s jádrem K je obraz I * K daný pro každý pixel (y, x) předpisem

(I * K)[y, x] = ∑i=−mm ∑j=−mm K[i, j] · I[y − i, x − j].

Jádro se tedy posouvá po obraze a v každé poloze se spočte vážený součet pixelů pod ním.

Laicky řečeno

Stejné jako v jednom rozměru, jen šablona je čtvereček a jezdí po řádcích i sloupcích. Každý pixel výsledku je směs jeho sousedů podle vah v šabloně. Různé šablony dělají různé věci:

(I * K)[y, x] = ∑i=−mm ∑j=−mm K[i, j] · I[y − i, x − j]

(I * K)[y, x]
pixel výsledku v řádku y a sloupci x — každý pixel výstupu se počítá zvlášť, stejným předpisem
∑i ∑j
přes všechna políčka jádra velikosti (2m + 1) × (2m + 1); m = 1 pro 3 × 3 — výsledek závisí jen na blízkém okolí
K[i, j]
váha jádra: určuje, co konvoluce dělá (rozmazává, zostřuje, hledá hrany); v konvoluční síti jsou to učené parametry
I[y − i, x − j]
soused pixelu [y, x] posunutý o (i, j); mínus znamená, že se jádro „otočí“ o 180° — díky tomu má konvoluce pěkné vlastnosti (je záměnná a asociativní)
U souměrných jader (průměr, gaussovka, zostření) otočení nic nemění. Neuronové sítě i náš kód jádro neotáčejí a počítají ∑ K[i, j] · I[y + i, x + j] (vzájemná korelace) — u učených vah je to jedno.
Příklad — jeden pixel z výřezu

Pixel ve 4. řádku a 4. sloupci výřezu výše (v obraze řádek 17, sloupec 25; bez šumu by měl 230) a jeho sousedé, hodnoty 0–255:

214227180
217229176
241255255

Barvy podle vzorce výše:

průměr 3 × 3 (všech 9 vah 1/9): 1/9 · (214 + 227 + 180 + 217 + 229 + 176 + 241 + 255 + 255) = 1 994/9 ≈ 221,6

zostření: 5 · 229 + (−1) · (227 + 217 + 176 + 255) = 1 145 − 875 = 270  ⇒  víc než bílá, po ořezání 255

Pixel leží těsně u okraje kruhu a vpravo od něj je tmavší pozadí. Průměr do něj přimíchá kus pozadí, zostření ho naopak od pozadí „odtlačí“ — a přetáhne až za bílou.

Definice — okraje obrazu

Na okraji chybí jádru sousedé. Nechť obraz I má H řádků a W sloupců (u nás H = W = 48) a pro N ∈ ℕ a t ∈ ℤ označme omezN(t) = min(N − 1, max(0, t)). Doplnění opakováním okraje rozšíří obraz na celé ℤ2 předpisem

I[y, x] = I[omezH(y), omezW(x)]   pro všechna (y, x) ∈ ℤ2,

tj. pixel mimo obraz nahradí nejbližším pixelem uvnitř (index se ořízne do rozsahu 0 … 47); to dělá náš kód. Jiné možnosti jsou doplnění nulami, I[y, x] = 0 mimo obraz (běžné v neuronových sítích), nebo zrcadlení. Výsledek konvoluce pak počítáme jen v pixelech původního obrazu, takže má stejnou velikost jako vstup.

Jádrováhyco děláodchylka od scény bez šumu
žádné—zašuměný obrázek0,121
průměr 3 × 3všech 9 vah 1/9rozmaže, potlačí šum0,066
gaussovka 5 × 5(1 4 6 4 1)ᵀ(1 4 6 4 1)/256rozmaže hladčeji0,061
zostřenístřed 5, čtyři sousedé −1zvýrazní rozdíly0,678
průměr 3 × 3 gaussovka 5 × 5 zostření
Zašuměná scéna po třech konvolucích

Rozmazání sníží šum na polovinu, ale rozmaže i hrany. Zostření dělá opak: k pixelu přičte jeho rozdíl od sousedů, takže hrany vyniknou — a šum s nimi, odchylka vzroste víc než pětkrát. Zostřovat se vyplatí jen obrázek, který šum nemá. Gaussovka 5 × 5 je zajímavá i jinak: jde napsat jako součin sloupce a řádku, takže se dá spočítat jako dvě 1D konvoluce — místo 25 násobení na pixel jen 10.

Věta — co udělá konvoluce se šumem

Nechť Ĩ = I + σε je obraz s aditivním šumem, kde σ ≥ 0 a εy,x jsou nezávislé náhodné veličiny se střední hodnotou 0 a rozptylem 1, a nechť K : {−m, …, m}2 → ℝ je jádro. Pak v každém pixelu (y, x), který je od okraje obrazu vzdálen aspoň m (takže se žádný pixel nepoužije dvakrát), má šumová složka výsledku (σε) * K směrodatnou odchylku

σpo = σ · √∑i,j K[i, j]2.

Důkaz. Konvoluce je lineární, takže Ĩ * K = I * K + (σε) * K a šumová složka výsledku je ∑i,j K[i, j] · σεy−i, x−j. Rozptyl součtu nezávislých veličin je součet rozptylů a konstanta před veličinou se do rozptylu dostane na druhou: Var = ∑ K[i, j]2 σ2. Odmocnina dá tvrzení. ∎

Příklad — proč tabulka vyšla tak, jak vyšla

průměr 3 × 3: √9 · (1/9)2 = √1/9 = 1/3  ⇒  0,12/3 = 0,040

gaussovka 5 × 5: 1 + 16 + 36 + 16 + 1/256 = 70/256 = 0,2734  ⇒  0,12 · 0,2734 = 0,033

zostření: √52 + 4 · 12 = √29 = 5,385  ⇒  0,12 · 5,385 = 0,646

U gaussovky jsme využili, že její váhy jsou součiny K[i, j] = gigj/256 s (gi) = (1, 4, 6, 4, 1), takže ∑ K2 = (∑ gi2)2/2562 a √∑ K2 = ∑ gi2/256. Zbylý šum v naší scéně opravdu vyjde 0,041, 0,034 a 0,644. Celková odchylka v tabulce je větší, protože rozmazání poškodí i hrany scény: u průměru 3 × 3 tak vznikne další chyba 0,052 a zhruba √0,0412 + 0,0522 ≈ 0,066 (zjednodušeně — obě chyby bereme jako nezávislé). Lepšího filtru proti šumu tedy nedosáhneme jen menším ∑ K2; větší jádro šum potlačí víc, ale hrany rozmaže víc.

def konvoluce(I, K):                  # K má velikost (2m+1) × (2m+1)
    for y in 0 … výška−1:
        for x in 0 … šířka−1:
            s = 0
            for i in −m … m:
                for j in −m … m:
                    s += K[i][j] · I[omez(y+i)][omez(x+j)]   # omez = opakování okraje
            V[y][x] = s
    return V

def gauss5(I):                        # oddělitelné jádro: dva průchody po 5 násobeních
    g = [1, 4, 6, 4, 1] / 16
    return konvoluce_sloupcu(konvoluce_radku(I, g), g)

4. Detekce hran

Definice — gradient obrazu a Sobelův operátor

Nechť f : ℝ2 → ℝ, (x, y) ↦ f(x, y), je diferencovatelná funkce jasu spojitého obrazu. Její gradient v bodě (x, y) je vektor

∇f(x, y) = (∂f/∂x(x, y), ∂f/∂y(x, y));

ukazuje směr, ve kterém jas nejrychleji roste, a jeho velikost |∇f| je strmost tohoto růstu.

Nechť I : ℤ2 → ℝ je digitální obraz (doplněný za okraji). Sobelův operátor odhaduje gradient dvěma jádry 3 × 3, indexovanými i, j ∈ {−1, 0, 1} (řádek, sloupec):

Sx s řádky (−1, 0, 1), (−2, 0, 2), (−1, 0, 1),   Sy = SxT s řádky (−1, −2, −1), (0, 0, 0), (1, 2, 1),

a pro každý pixel (y, x) klade

Gx[y, x] = ∑i,j=−11 Sx[i, j] · I[y + i, x + j],   Gy[y, x] = ∑i,j=−11 Sy[i, j] · I[y + i, x + j]

(vzájemná korelace; konvoluce s týmiž jádry by dala jen opačné znaménko). Velikost hrany v pixelu je

|∇I|[y, x] = √Gx[y, x]2 + Gy[y, x]2.

Gx je tedy (až na kladný násobek) odhad ∂I/∂x a Gy odhad ∂I/∂y, kde y roste směrem dolů.

Laicky řečeno

Jádro Gx odečte levé sousedy od pravých: kde je obraz rovný, dá nulu, kde jas vodorovně skočí, dá velké číslo. Prostřední řádek má dvojnásobnou váhu — malé rozmazání ve svislém směru je v jádře rovnou zabudované. Gy totéž svisle a dohromady najdou hrany v libovolném směru.

Rozepsané do jednotlivých pixelů je Gx rozdíl sloupců vážený přes tři řádky:

Gx[y, x] = ∑i=−11 wi · ( I[y + i, x + 1] − I[y + i, x − 1] ),   (w−1, w0, w1) = (1, 2, 1)

Gx[y, x]
odhad vodorovné derivace jasu (bez dělení vzdáleností — na měřítku pro hledání hran nezáleží)
wi = (1, 2, 1)
vyhlazení ve svislém směru: rozdíl se změří ve třech řádcích a prostřední řádek váží nejvíc — jeden zašuměný řádek tak výsledek nepokazí
I[·, x + 1] − I[·, x − 1]
rozdíl pravého a levého souseda (centrální diference) — na rovné ploše 0, na svislé hraně velké číslo; znaménko říká, kterým směrem jas roste
Sobelovo jádro je součin sloupce (1, 2, 1)ᵀ a řádku (−1, 0, 1): vyhladit napříč, derivovat podél. Gy je totéž otočené o 90°; velikost hrany |∇I| ≈ √Gx2 + Gy2 a směr gradientu atan2(Gy, Gx).
Příklad — Sobel na hraně a mimo ni (scéna bez šumu)

levá hrana tmavého čtverce, pixel [30, 27]: vlevo pozadí 0,4660, vpravo čtverec 0,1 ve všech třech řádcích

Gx = (1 + 2 + 1) · (0,1 − 0,4660) = −1,464,   Gy = 0  ⇒  |∇I| = 1,464, směr 180° (jas roste doleva)

pozadí, pixel [40, 10]: Gx = (1 + 2 + 1) · (0,3 · 11/47 − 0,3 · 9/47) = 4 · 0,6/47 ≈ 0,051,   Gy = 0

(barvy podle vzorce výše)

Plynulý přechod pozadí dá skoro nulu, skutečná hrana skoro třicetkrát víc. Nejlepší práh na čisté scéně vyjde zhruba 1,0 — a všechno nad ním se prohlásí za hranu.

bez šumu se šumem rozmazáno, pak Sobel
Velikost gradientu (Sobel): scéna bez šumu, se šumem a se šumem po rozmazání

Ve scéně je 240 skutečných hranových pixelů. Detektor porovnáme s nimi jako klasifikátor z dílu o vyhodnocení modelu: při nejlepším prahu má Sobel na čisté scéně F1 0,994. Na zašuměné jen 0,859 — práh musí být vysoko, aby nebral šum, a tak najde jen 80 % hran. Když obrázek nejdřív rozmažeme gaussovkou, F1 stoupne na 0,880 a najde se 90 % hran. Stejný recept jako v 1D: nejdřív vyhladit, pak derivovat.

F1 = 2 · P · R/P + R,   P = TP/TP + FP,   R = TP/TP + FN

F1
jedno číslo pro porovnání detektorů; harmonický průměr je vysoký jen tehdy, když jsou vysoké oba členy — detektor, který označí všechno, nebo skoro nic, dostane málo
P (preciznost)
z pixelů, které detektor označil, podíl skutečných hran (TP); trestá falešné poplachy FP — tady zrnka šumu
R (úplnost)
ze všech 240 skutečných hran podíl nalezených; trestá přehlédnuté hrany FN — práh příliš vysoko
Pro každý práh se spočte F1 a vybere se práh s nejlepší hodnotou.
Příklad — F1 se šumem, bez rozmazání a s ním

Barvy podle vzorce výše:

bez rozmazání: označeno 207, z toho TP = 192, FP = 15, FN = 48  ⇒  P = 192/207 = 0,928, R = 192/240 = 0,800, F1 = 0,859

s rozmazáním: označeno 253, z toho TP = 217, FP = 36, FN = 23  ⇒  P = 217/253 = 0,858, R = 217/240 = 0,904, F1 = 0,880

Rozmazání si koupí 25 nalezených hran navíc za 21 falešných poplachů — preciznost klesne, úplnost stoupne víc, a F1 tak vzroste.

def hrany(I, prah):
    J  = konvoluce(I, gauss5)          # 1. vyhladit (bez toho najdeme šum)
    Gx = konvoluce(J, sobelX)          # 2. derivovat vodorovně
    Gy = konvoluce(J, sobelY)          #    a svisle
    G  = sqrt(Gx² + Gy²)               # 3. velikost gradientu v každém pixelu
    return G > prah                    # 4. hrana = silná změna jasu

5. Aliasing při zmenšování

Zmenšit obrázek čtyřikrát nejjednodušeji jde tak, že se vezme každý čtvrtý pixel. To je převzorkování — a víme, co hrozí. Vyzkoušíme to na zónové desce: soustředných kroužcích, které se od středu zahušťují.

Z[y, x] = 1/2 + 1/2 cos(π r2/96),   r2 = (x − 48)2 + (y − 48)2,   x, y ∈ {0, …, 95}

Z[y, x]
jas pixelu zónové desky 96 × 96
1/2
střední šeď — kolem ní jas kmitá
1/2 cos
kmit s amplitudou 1/2, takže jas běhá přesně mezi 0 (černý kroužek) a 1 (bílý)
πr2/96
fáze roste s druhou mocninou vzdálenosti od středu, ne lineárně — proto se kroužky směrem ven zahušťují a deska obsahuje všechny frekvence od 0 do 0,5 cyklu na pixel najednou
Místní frekvence ve vzdálenosti r je derivace fáze dělená 2π: f(r) = 1/2π · d/dr(πr2/96) = 1/2π · 2πr/96 = r/96 cyklu na pixel. Uprostřed stran (r = 48) je to 0,5 — nejvyšší frekvence, jakou mřížka pixelů vůbec unese; v rozích je deska podvzorkovaná už sama.
originál 96 × 96 každý 4. pixel průměr bloků 4 × 4
Zónová deska 96 × 96 a její čtyřnásobné zmenšení

Po zmenšení na 24 × 24 je Nyquistova frekvence 0,125 cyklu na původní pixel. Kroužky ve vzdálenosti přes 12 pixelů od středu jsou hustší, a tak se výběrem každého čtvrtého pixelu převléknou za falešné kroužky — moaré. Ve vnějším prstenci mají kontrast 0,35, ačkoli tam žádné kroužky, které by se daly zachytit, nejsou. Když se před zmenšením každý blok 4 × 4 zprůměruje (rozmazání = antialiasingový filtr), vnější prstenec splyne v šeď s kontrastem 0,04 — informace je ztracená, ale nic falešného nepřibylo. Stejně proto fungují kvalitní zmenšovací algoritmy a stejně tak se chová fotoaparát s antialiasingovým filtrem před snímačem.

Věta — kam se frekvence při zmenšení přesune

Nechť k ∈ ℕ, k ≥ 2, f ≥ 0, φ ∈ ℝ a s[x] = cos(2πfx + φ), x ∈ ℤ, je kmit s frekvencí f cyklu na pixel. Zmenšení výběrem každého k-tého pixelu ponechá jen hodnoty s[kt], t ∈ ℤ; nová vzorkovací frekvence je 1/k cyklu na původní pixel a Nyquistova frekvence 1/2k. Pak:

  1. pro každé n ∈ ℤ má kmit s frekvencí f − n/k (a toutéž fází φ) v bodech x = kt tytéž hodnoty jako s, protože se jeho fáze liší o 2πnt, celý násobek 2π;
  2. zvolíme-li n jako celé číslo nejbližší k · f, je

fa = |f − n/k| ∈ [0, 1/2k]

a zmenšený obraz kmitu se nedá odlišit od kmitu s frekvencí fa mezi 0 a Nyquistovou frekvencí (absolutní hodnota jen obrátí znaménko fáze, cos je sudá funkce). Tomuto kmitu říkáme alias.

Příklad — falešné kroužky na zónové desce (k = 4)

Na vodorovné ose desky (řádek 48) ve vzdálenosti r od středu:

r = 12: f = 12/96 = 0,125 = Nyquistova frekvence — hranice, kam až zmenšení věrně funguje

r = 24: f = 0,25, n = 1  ⇒  fa = |0,25 − 1/4| = 0 — kmit se tváří jako konstanta: falešný „střed“

r = 36: f = 0,375, kf = 1,5  ⇒  fa = |0,375 − 2/4| = 0,125 (nebo stejně tak s n = 1)

r = 48: f = 0,5, n = 2  ⇒  fa = 0 — další falešný střed, uprostřed strany

Mimo osy je místní frekvence vektor (x − 48/96, y − 48/96) a každá složka se „přeloží“ zvlášť. Falešný střed vznikne tam, kde jsou obě složky násobky 1/4, tedy kde jsou x − 48 i y − 48 násobky 24 — to je pravidelná mřížka falešných středů v prostředním obrázku.

|H(f)| = |sin(πkf)/k · sin(πf)|,   0 < f < 1

|H(f)|
kolikrát průměr k sousedních pixelů zmenší amplitudu kmitu s frekvencí f (1 = projde celý, 0 = zmizí)
sin(πkf)
je nulový, když se do bloku k pixelů vejde celý počet period (f = 1/k, 2/k, …) — kladné a záporné půlvlny se v průměru přesně vyruší
k · sin(πf)
normalizace: pro f → 0 je poměr 1, takže rovnoměrná plocha projde beze změny
Útlum průměru bloku k pixelů v jednom směru, tj. filtru s jádrem h[j] = 1/k pro j = 0, …, k − 1 (součet geometrické řady, viz díl Filtry a konvoluce; frekvence f v cyklech na pixel).
Příklad — průměr bloků 4 × 4 jako antialiasingový filtr

k = 4, barvy podle vzorce výše:

f = 0,125: sin π/2/4 sin π/8 = 1/4 · 0,3827 ≈ 0,65

f = 0,25: sin π/4 sin π/4 = 0 — právě frekvence, která by vyrobila falešný střed, zmizí úplně

f = 0,375: |sin(1,5π)|/4 sin(0,375π) = 1/4 · 0,9239 ≈ 0,27

Ve vnějším prstenci propustí průměr v jednom směru nejvýš asi čtvrtinu amplitudy; šikmé kroužky tlumí ve dvou směrech zároveň, a tak naměřený kontrast spadne z 0,35 až na 0,04. Pod Nyquistovou frekvencí ale ubírá i to, co by zmenšení zvládlo (0,65 na hranici) — proto zmenšený obrázek působí měkce. Lepší zmenšovací filtry (např. Lanczos) mají ostřejší přechod mezi „propustit“ a „utlumit“.

6. Od ručních jader k učeným

  • Jádra jako příznaky. Desítky let se do systémů pro počítačové vidění ručně navrhovala jádra: Sobel, gaussovky, Gaborovy filtry. Z jejich odezev se skládaly příznaky pro klasifikátor.
  • Konvoluční síť. Konvoluční vrstva obsahuje desítky jader, jejichž váhy se učí gradientním sestupem. Vrstva s 64 jádry 3 × 3 nad barevným obrázkem 224 × 224 provede asi 87 milionů násobení.
  • Co se síť naučí. Jádra první vrstvy natrénované sítě vypadají jako detektory hran v různých směrech a barevné skvrny — síť sama znovu objeví Sobela. Hlubší vrstvy skládají hrany do textur, tvarů a částí objektů.
  • Proč konvoluce. Kočka je kočka, ať je vlevo nahoře, nebo vpravo dole. Konvoluce použije stejné váhy na každém místě, takže stačí naučit jedno „oko na kočičí ucho“, ne zvláštní pro každou pozici.

násobení = Hout · Wout · k2 · Cin · Cout

Hout · Wout
počet poloh jádra = počet pixelů výstupu; v každé se počítá znovu
k2
políčka jádra k × k — jedno násobení na každé
Cin
vstupní kanály: jádro v síti není čtvereček, ale kvádr k × k × Cin, který sčítá přes všechny kanály naráz (u fotky R, G, B)
Cout
počet jader ve vrstvě — každé vyrobí jeden výstupní kanál (jednu „mapu příznaků“)
224 · 224 · 32 · 3 · 64 = 86 704 128 ≈ 87 milionů násobení pro jedinou vrstvu a jediný obrázek.
Definice — velikost výstupu, okraj a krok

Nechť vstup má šířku W ∈ ℕ, jádro velikost k × k (k ∈ ℕ), okraj p ∈ {0, 1, 2, …} je počet pixelů doplněných na každé straně a krok s ∈ ℕ je počet pixelů, o který se jádro posouvá, přičemž k ≤ W + 2p. Jádro se přiloží v polohách, kde jeho levý okraj leží na sloupci 0, s, 2s, … doplněného vstupu a celé jádro se do doplněné šířky W + 2p vejde. Počet těchto poloh, tedy šířka výstupu, je

Wout = ⌊W − k + 2p/s⌋ + 1

(pro výšku totéž; ⌊t⌋ je dolní celá část). Příklad pro W = 224 a k = 3: s p = 1, s = 1 vyjde ⌊223/1⌋ + 1 = 224 — velikost se zachová; s p = 1, s = 2 vyjde ⌊223/2⌋ + 1 = 112 — obraz se zmenší na polovinu; bez okraje (p = 0, s = 1) 222.

Příklad — kolik vah ušetří sdílení jádra

konvoluční vrstva: 64 jader · (3 · 3 · 3 vah + 1 posun) = 64 · 28 = 1 792 parametrů

plně propojená vrstva se stejným vstupem a výstupem: 150 528 vstupů · (224 · 224 · 64 = 3 211 264) výstupů ≈ 4,8 · 1011 vah

Rozdíl je přes dvě stě milionů krát. Konvoluce si to může dovolit, protože předpokládá dvě věci, které pro obrazy platí: pixel souvisí hlavně se svým okolím (malé jádro) a co je užitečné hledat na jednom místě, je užitečné i jinde (stejné váhy všude).

7. Shrnutí

  • Obraz je matice vzorků jasu; fotka 12 Mpx má 36 milionů čísel, vstup sítě 224 × 224 × 3 = 150 528.
  • Barva jsou tři kanály RGB; jas váží zelenou nejvíc (plná zelená 150, červená 76, modrá 29 z 255).
  • 2D konvoluce posouvá malé jádro po obraze: rozmazání snížilo šum z 0,121 na 0,061, zostření ho zvětšilo na 0,678.
  • Sobelův operátor najde hrany; na zašuměném obrázku pomůže nejdřív rozmazat (F1 0,859 → 0,880).
  • Zmenšení výběrem pixelů vyrobí moaré (kontrast 0,35), průměr bloků předem ho odstraní (0,04).

Chcete si to osahat? Nechte AI agenta načíst vaši fotku, převést ji na šedou, pustit na ni Sobelův operátor a uložit výsledek — a pak to zkuste znovu na fotce zmenšené výběrem každého čtvrtého pixelu.

Máte na to jiný názor? Napište na support@coden-app.com.

Agent na vašem počítači, ovládaný z telefonu