Bilineární interpolace / škálování obrazu – příklad výpočtu

Rád bych vás odkázal na tuto velmi výstižnou grafiku z Wikipedie, která znázorňuje, jak provést bilineární interpolaci pro jeden bod:

Zdroj: Jak vidíte, čtyři červené body jsou to, co je známo. Tyto body znáte předem a P je bod, který chceme interpolovat. Jako takoví musíme provést dva kroky (jak jste uvedl ve svém příspěvku). Pro zpracování souřadnice x (vodorovné) musíme vypočítat, jaká je interpolovaná hodnota po řádcích pro horní řadu červených bodů a dolní řadu červených bodů. Výsledkem jsou dva modré body R1 a R2. Pro zpracování souřadnice y (vertikální) použijeme dva modré body a interpolujeme je vertikálně, abychom získali konečný bod P.

Při změně velikosti obrázku sice vizuálně nevidíme, co se chystám říct, ale představme si, že tento obrázek je 3D signál f. Každý bod v matici je ve skutečnosti 3D souřadnice, kde umístění ve sloupci je hodnota x, umístění v řádku je hodnota y a hodnota z je množství / hodnota odstínů šedi samotné matice. Proto dělá z = f(x,y) je hodnota matice v umístění (x,y) v matici. V našem případě, protože máte co do činění s obrázky, jsou jednotlivé hodnoty (x,y) celá čísla, která jdou od 1 až po tolik řádků/sloupců, kolik máme v závislosti na tom, na jaký rozměr se díváte.

Tedy vzhledem k souřadnici, kterou chcete interpolovat v místě (x,y), a vzhledem k červeným souřadnicím na obrázku výše, které jim říkáme x1,y1,x2,y2 podle diagramu – konkrétně jdeme s konvencí diagramu a odkazem na to, jak se přistupuje k obrázkům: x1 = 1, x2 = 2, y1 = 2, y2 = 1, modré souřadnice R1 a R2 se vypočítají pomocí 1D interpolace po sloupcích s použitím stejného řádku, na kterém se oba body shodují:

R1 = f(x1,y1) + (x - x1)/(x2 - x1)*(f(x2,y1) - f(x1,y1))R2 = f(x1,y2) + (x - x1)/(x2 - x1)*(f(x2,y2) - f(x1,y2))

Důležité je poznamenat, že (x - x1) / (x2 - x1) je váha / podíl toho, jak moc se výstup skládá ze směsi mezi dvěma hodnotami viděnými na f(x1,y1) a f(x2,y1) pro R1 nebo f(x1,y2) a f(x2,y2) pro R2. Konkrétně x1 je výchozí bod a (x2 - x1) je rozdíl hodnot x. Můžete si ověřit, že dosazením x1 za x získáme 0, zatímco dosazením x2 za x získáme 1. Tato váha se pohybuje mezi , což je nutné pro fungování výpočtu.

Je třeba si uvědomit, že počátek obrázku je v levém horním rohu, a proto je (1,1) v levém horním rohu. Jakmile zjistíme R1 a R2, můžeme zjistit P interpolací po řádcích:

P = R2 + (y - y2)/(y2 - y1)*(R1 - R2)

Znovu platí, že (y - y2) / (y2 - y1) značí poměr/směs toho, jak moc se R1 a R2 podílejí na konečném výsledku P. Jako takový jste f5 vypočítali správně, protože jste použili čtyři známé body: Vlevo nahoře je 100, vpravo nahoře je 50, vlevo dole je 70 a vpravo dole je 20. Konkrétně, pokud chcete vypočítat f5, znamená to, že (x,y) = (1.5,1.5), protože jsme v polovině mezi 100 a 50 kvůli tomu, že obrázek škálujete o dva. Pokud tyto hodnoty dosadíte do výše uvedeného výpočtu, dostanete hodnotu 60, jak jste očekávali. Výsledkem vah pro oba výpočty bude také 0.5, což je hodnota, kterou jste dostali ve svých výpočtech a kterou očekáváme.

Pokud vypočtete f1, odpovídá to hodnotě (x,y) = (1.5,1), a pokud ji dosadíte do výše uvedené rovnice, zjistíte, že (y - y2)/(y2 - y1) vám dává 0 neboli váha je 0, a tak to, co se vypočítá, je právě R2, což odpovídá lineární interpolaci pouze podél horního řádku. Podobně, pokud jsme vypočítali f7, znamená to, že chceme interpolovat na (x,y) = (1.5,2). V tomto případě uvidíte, že (y - y2) / (y2 - y1) je 1 neboli váha je 1 a tedy P = R2 + (R1 - R2), což zjednodušeně znamená R1 a odpovídá lineární interpolaci pouze podél spodního řádku.

Nyní je tu případ f3 a f5. Ty obě odpovídají (x,y) = (1,1.5), respektive (x,y) = (2,1.5). Dosazením těchto hodnot za R1 a R2 a P pro oba případy dostaneme:

f3

R1 = f(1,2) + (1 - 1)/(2 - 1)*(f(2,2) - f(1,2)) = f(1,2)R2 = f(1,1) + (1 - 1)/(2 - 1)*(f(1,2) - f(1,1)) = f(1,1)P = R1 + (1.5 - 1)*(R1 - R2) = f(1,2) + 0.5*(f(1,2) - f(1,1))P = 70 + 0.5*(100 - 70) = 85

f5

R1 = f(1,2) + (2 - 1)/(2 - 1)*(f(2,2) - f(1,2)) = f(2,2)R2 = f(1,1) + (2 - 1)/(2 - 1)*(f(1,2) - f(1,1)) = f(1,2)P = R1 + (1.5 - 1)*(R1 - R2) = f(2,2) + 0.5*(f(2,2) - f(1,2))P = 20 + 0.5*(50 - 20) = 35

Co nám to tedy říká? Znamená to, že interpolujete pouze podél směru y. To je zřejmé, když se podíváme na P. Při důkladnějším prozkoumání výpočtu P pro každý z řádků f3 a f5 vidíte, že uvažujeme hodnoty pouze podél svislého směru.

Pokud tedy chcete definitivní odpověď, f1 a f7 naleznete interpolací podél směru x / sloupce pouze podél stejného řádku. f3 a f5 jsou nalezeny interpolací y / směr řádku podél stejného sloupce. f4 používá k výpočtu výsledné hodnoty směs f1 a f7, jak jste již viděli.

Pro odpověď na vaši poslední otázku jsou f2, f6 a f8 vyplněny na základě osobních preferencí. Tyto hodnoty jsou považovány za neomezené, přičemž hodnoty x a y jsou obě 2.5 a to je mimo naši mřížku pro (x,y). V MATLABu je výchozí implementací tohoto postupu vyplnit všechny hodnoty mimo definované hranice tak, aby nebyly číslem (NaN), ale někdy lidé extrapolují pomocí lineární interpolace, kopírují hraniční hodnoty nebo provádějí nějaké složité vyplňování, například symetrické nebo kruhové vyplňování. Záleží na tom, v jaké situaci se nacházíte, ale neexistuje žádná správná a jednoznačná odpověď na to, jak vyplnit f2, f6 a f8 – vše záleží na vaší aplikaci a na tom, co vám dává největší smysl.

Jako bonus si můžeme ověřit, že mé výpočty jsou správné v MATLABu. Nejprve definujeme mřížku (x,y) bodů v rozsahu , pak změníme velikost obrázku tak, aby byl dvakrát větší, kde zadáme rozlišení 0,5 na bod, nikoli 1. V tomto případě je třeba zadat rozlišení 0,5 na bod. Vámi definovanou matici nazvu A:

A = ; %// Define original matrix = meshgrid(1:2,1:2); %// Define original grid of points = meshgrid(1:0.5:2.5,1:0.5:2.5) %// Define expanded grid of pointsB = interp2(X,Y,A,X2,Y2,'linear'); %// Perform bilinear interpolation

Původní mřížka (x,y) bodů vypadá takto:

>> XX = 1 2 1 2>> YY = 1 1 2 2

Rozšířená mřížka pro zvětšení velikosti matice o dvojnásobek vypadá takto:

>> X2X2 = 1.0000 1.5000 2.0000 2.5000 1.0000 1.5000 2.0000 2.5000 1.0000 1.5000 2.0000 2.5000 1.0000 1.5000 2.0000 2.5000>> Y2Y2 = 1.0000 1.0000 1.0000 1.0000 1.5000 1.5000 1.5000 1.5000 2.0000 2.0000 2.0000 2.0000 2.5000 2.5000 2.5000 2.5000

B je výstup s použitím X a Y jako původní mřížky bodů a X2 a Y2 jsou body, které chceme interpolovat.

Dostaneme:

>> BB = 100 75 50 NaN 85 60 35 NaN 70 45 20 NaN NaN NaN NaN NaN

Napsat komentář