Bilineaire interpolatie / schaling van afbeeldingen – Een rekenvoorbeeld

Ik wil u graag wijzen op deze zeer inzichtelijke grafiek van Wikipedia die illustreert hoe je bilineaire interpolatie voor één punt kunt doen:

Bron: Wikipedia

Zoals je kunt zien, zijn de vier rode punten wat bekend is. Deze punten ken je van tevoren en P is het punt dat we willen interpoleren. Als zodanig moeten we twee stappen doen (zoals je hebt aangegeven in je post). Om het coördinaat x (horizontaal) te behandelen, moeten we berekenen wat de geïnterpoleerde waarde rijgewijs is voor de bovenste rij rode punten en de onderste rij rode punten. Dit resulteert in de twee blauwe punten R1 en R2. Om het coördinaat y (verticaal) te behandelen, gebruiken we de twee blauwe punten en interpoleren verticaal om het uiteindelijke punt P te krijgen.

Wanneer u het formaat van een afbeelding wijzigt, ook al zien we visueel niet wat ik ga zeggen, maar stel u voor dat deze afbeelding een 3D signaal f is. Elk punt in de matrix is in feite een 3D coördinaat waar de kolom locatie de x waarde is, de rij locatie is de y waarde en de z waarde is de hoeveelheid / grijsschaal waarde van de matrix zelf. Daarom doet z = f(x,y) de waarde van de matrix op locatie (x,y) in de matrix. In ons geval, omdat je te maken hebt met afbeeldingen, zijn alle waarden van (x,y) gehele getallen die gaan van 1 tot zoveel rijen/kolommen als we hebben, afhankelijk van welke dimensie je bekijkt.

Daarom, gegeven de coördinaat die je wilt interpoleren op (x,y), en gegeven de rode coördinaten in de afbeelding hierboven, die we x1,y1,x2,y2 noemen volgens het diagram – specifiek volgens de conventie van het diagram en verwijzend naar hoe afbeeldingen worden benaderd: x1 = 1, x2 = 2, y1 = 2, y2 = 1, de blauwe coördinaten R1 en R2 worden berekend via 1D interpolatie kolomgewijs met behulp van dezelfde rij waarop beide punten samenvallen:

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))

Het is belangrijk op te merken dat (x - x1) / (x2 - x1) een gewicht / aandeel is van hoeveel van een mix de uitvoer bestaat uit tussen de twee waarden te zien op f(x1,y1) en f(x2,y1) voor R1 of f(x1,y2) en f(x2,y2) voor R2. Concreet is x1 het startpunt en (x2 - x1) het verschil in x waarden. U kunt nagaan dat substitutie van x1 als x ons 0 oplevert, terwijl x2 als x ons 1 oplevert. Dit gewicht schommelt tussen , wat nodig is om de berekeningen te laten werken.

Opgemerkt moet worden dat de oorsprong van het beeld in de linkerbovenhoek ligt, en dus (1,1) in de linkerbovenhoek ligt. Zodra u R1 en R2 hebt gevonden, kunnen we P vinden door rijgewijs te interpoleren:

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

Nogmaals, (y - y2) / (y2 - y1) geeft de verhouding / mix aan van hoeveel R1 en R2 bijdragen aan de uiteindelijke output P. Als zodanig hebt u f5 correct berekend omdat u vier bekende punten hebt gebruikt: Linksboven is 100, rechtsboven is 50, linksonder is 70 en rechtsonder is 20. Om precies te zijn, als je f5 wilt berekenen, betekent dit dat (x,y) = (1.5,1.5) omdat we halverwege tussen de 100 en 50 zitten, omdat je het beeld met twee schaalt. Als u deze waarden in de bovenstaande berekening invoegt, krijgt u de waarde 60, zoals u verwachtte. De gewichten voor beide berekeningen zullen ook resulteren in 0.5, dat is wat u kreeg in uw berekeningen en dat is wat we verwachten.

Als u f1 berekent, komt dit overeen met (x,y) = (1.5,1) en als u dit in de bovenstaande vergelijking substitueert, zult u zien dat (y - y2)/(y2 - y1) u 0 oplevert, ofwel het gewicht is 0, en wat dus wordt berekend is slechts R2, hetgeen overeenkomt met de lineaire interpolatie langs alleen de bovenste rij. Evenzo, als we f7 hebben berekend, betekent dit dat we willen interpoleren op (x,y) = (1.5,2). In dit geval ziet u dat (y - y2) / (y2 - y1) 1 is of het gewicht is 1 en dus P = R2 + (R1 - R2), dat vereenvoudigd wordt tot R1 en overeenkomt met de lineaire interpolatie alleen langs de onderste rij.

Nu is er het geval van f3 en f5. Deze komen overeen met respectievelijk (x,y) = (1,1.5) en (x,y) = (2,1.5). Invullen van deze waarden voor R1 en R2 en P voor beide gevallen geeft:

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

Wat zegt dit ons? Dit betekent dat je alleen interpoleert in de y-richting. Dit wordt duidelijk als we naar P kijken. Als u de berekeningen van P voor elk van f3 en f5 nauwkeuriger bekijkt, ziet u dat we alleen waarden langs de verticale richting beschouwen.

Als zodanig, als u een definitief antwoord wilt, worden f1 en f7 gevonden door te interpoleren langs de x / kolomrichting alleen langs dezelfde rij. f3 en f5 worden gevonden door y / rijrichting te interpoleren langs dezelfde kolom. f4 gebruikt een mengsel van f1 en f7 om de uiteindelijke waarde te berekenen, zoals u al hebt gezien.

Om uw laatste vraag te beantwoorden: f2, f6 en f8 zijn ingevuld op basis van persoonlijke voorkeur. Deze waarden worden beschouwd als buiten de grenzen, waarbij de x en y waarden beide 2.5 zijn en dat is buiten ons raster voor (x,y). In MATLAB is de standaard implementatie hiervan om alle waarden buiten de gedefinieerde grenzen op te vullen als niet-een-getal (NaN), maar soms extrapoleren mensen met behulp van lineaire interpolatie, kopiëren ze de grenswaarden, of voeren ze een of andere uitgebreide opvulling uit, zoals symmetrische of circulaire opvulling. Het hangt er van af in welke situatie je zit, maar er is geen juist en definitief antwoord op de vraag hoe je f2, f6 en f8 invult – het hangt allemaal af van je toepassing en wat voor jou het meest zinvol is.

Als bonus kunnen we in MATLAB verifiëren dat mijn berekeningen correct zijn. We definiëren eerst een raster van (x,y) punten in het bereik, dan herschalen we de afbeelding zodat hij twee keer zo groot is, waarbij we een resolutie van 0,5 per punt opgeven in plaats van 1. Ik noem uw gedefinieerde matrix 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

Het oorspronkelijke (x,y) puntenraster ziet er zo uit:

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

Het uitgebreide raster om de matrix twee keer zo groot te maken ziet er zo uit:

>> 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 is de uitvoer met X en Y als het oorspronkelijke puntenraster en X2 en Y2 zijn de punten waarnaar we willen interpoleren.

We krijgen:

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

Plaats een reactie