Я хотел бы указать вам на этот очень проницательный рисунок из Википедии, который иллюстрирует, как выполнять билинейную интерполяцию для одной точки:
![](https://upload.wikimedia.org/wikipedia/commons/e/e7/Bilinear_interpolation.png)
Источник: Википедия
Как видите, четыре красных точки - это то, что известно. Эти точки вы знаете заранее, и P
- это точка, которую мы хотим интерполировать. Таким образом, мы должны сделать два шага (как вы указали в своем сообщении). Чтобы обработать координату x
(по горизонтали), мы должны вычислить, какое интерполированное значение является построчным для верхнего ряда красных точек и нижнего ряда красных точек. В результате появляются две синие точки R1
и R2
. Чтобы обработать y
координату (по вертикали), мы используем две синие точки и интерполируем по вертикали, чтобы получить окончательную P
точку.
Когда вы изменяете размер изображения, даже если мы не видим визуально то, что я собираюсь сказать, но представьте, что это изображение является 3D-сигналом f
. Каждая точка в матрице фактически является трехмерной координатой, где положение столбца - это значение x
, положение строки - это значение y
, а значение z
- это количество / значение в градациях серого самой матрицы. Следовательно, выполнение z = f(x,y)
- это значение матрицы в позиции (x,y)
в матрице. В нашем случае, поскольку вы имеете дело с изображениями, каждое значение (x,y)
является целым числом от 1 до такого количества строк / столбцов, которое есть у нас, в зависимости от того, на какое измерение вы смотрите.
Следовательно, с учетом координаты, которую вы хотите интерполировать в (x,y)
, и с учетом красных координат на изображении выше, которые мы называем их x1,y1,x2,y2
в соответствии с диаграммой - в частности, следуя соглашению диаграммы и ссылаясь на то, как осуществляется доступ к изображениям: x1 = 1, x2 = 2, y1 = 2, y2 = 1
, синие координаты R1
и R2
вычисляются с помощью столбца одномерной интерполяции, используя одну и ту же строку, в которой совпадают обе точки:
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))
Важно отметить, что (x - x1) / (x2 - x1)
- это вес / пропорция того, из какой смеси состоит вывод между двумя значениями, указанными в f(x1,y1)
и f(x2,y1)
для R1
или f(x1,y2)
и f(x2,y2)
для R2
. В частности, x1
- это начальная точка, а (x2 - x1)
- разница в x
значениях. Вы можете убедиться, что замена x1
на x
дает нам 0, а x2
как x
дает нам 1. Этот вес колеблется между [0,1]
, который требуется для работы вычислений.
Следует отметить, что источник изображения находится в верхнем левом углу, поэтому (1,1)
находится в верхнем левом углу. Как только вы найдете R1
и R2
, мы сможем найти P
путем интерполяции по строкам:
P = R2 + (y - y2)/(y2 - y1)*(R1 - R2)
Опять же, (y - y2) / (y2 - y1)
обозначает пропорцию / сочетание того, сколько R1
и R2
вносят вклад в окончательный результат P
. Таким образом, вы вычислили f5
правильно, потому что вы использовали четыре известных точки: верхний левый - 100, верхний правый - 50, нижний левый - 70 и нижний правый - 20. В частности, если вы хотите вычислить f5
, это означает, что (x,y) = (1.5,1.5)
, потому что мы находятся на полпути между 100 и 50 из-за того, что вы масштабируете изображение вдвое. Если вы подставите эти значения в вышеприведенное вычисление, вы получите значение 60, как вы и ожидали. Веса для обоих расчетов также приведут к 0.5
, что вы и получили в своих расчетах, и это то, что мы ожидаем.
Если вы вычислите f1
, это соответствует (x,y) = (1.5,1)
, и если вы подставите это в приведенное выше уравнение, вы увидите, что (y - y2)/(y2 - y1)
дает вам 0 или вес равен 0, и поэтому вычисляется просто R2
, что соответствует линейной интерполяции по верхнему краю. только ряд. Точно так же, если мы вычислили f7
, это означает, что мы хотим интерполировать на (x,y) = (1.5,2)
. В этом случае вы увидите, что (y - y2) / (y2 - y1)
= 1 или вес равен 1, и поэтому P = R2 + (R1 - R2)
, что упрощается до R1
и представляет собой линейную интерполяцию только по нижней строке.
Теперь это случай с f3
и f5
. Оба соответствуют (x,y) = (1,1.5)
и (x,y) = (2,1.5)
соответственно. Подстановка этих значений на R1
, R2
и P
для обоих случаев дает:
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
Так что это нам говорит? Это означает, что вы интерполируете только по оси Y. Это становится очевидным, если мы посмотрим на P
. Более тщательно изучив вычисления P
для каждого из f3
и f5
, вы увидите, что мы рассматриваем значения только в вертикальном направлении.
Таким образом, если вы хотите получить окончательный ответ, f1
и f7
будут найдены путем интерполяции в направлении x
/ столбца только по одной и той же строке. f3
и f5
находятся путем интерполяции направления y
/ строка вдоль одного и того же столбца. f4
использует смесь f1
и f7
для вычисления окончательного значения, как вы уже видели.
Чтобы ответить на ваш последний вопрос, заполните f2
, f6
и f8
на основе личных предпочтений. Эти значения считаются выходящими за границы, причем значения x
и y
равны 2.5
и находятся за пределами нашей [1,2]
сетки для (x,y)
. В MATLAB реализация этого по умолчанию состоит в том, чтобы заполнить любые значения за пределами определенных границ, чтобы они не были числами (NaN
), но иногда люди экстраполируют с использованием линейной интерполяции, копируют значения границ или выполняют некоторые сложные дополнения, такие как симметричные или круглая набивка. Это зависит от того, в какой ситуации вы находитесь, но нет правильного и окончательного ответа о том, как заполнить f2
, f6
и f8
- все зависит от вашего приложения и того, что для вас наиболее разумно.
В качестве бонуса мы можем проверить правильность моих расчетов в MATLAB. Сначала мы определяем сетку из (x,y)
точек в диапазоне [1,2]
, затем изменяем размер изображения так, чтобы оно было вдвое больше, где мы указываем разрешение 0,5 на точку, а не 1. Я собираюсь называть вашу заданную матрицу A
:
A = [100 50; 70 20]; %// Define original matrix
[X,Y] = meshgrid(1:2,1:2); %// Define original grid of points
[X2,Y2] = meshgrid(1:0.5:2.5,1:0.5:2.5) %// Define expanded grid of points
B = interp2(X,Y,A,X2,Y2,'linear'); %// Perform bilinear interpolation
Исходная (x,y)
сетка точек выглядит так:
>> X
X =
1 2
1 2
>> Y
Y =
1 1
2 2
Расширенная сетка для увеличения размера матрицы вдвое выглядит так:
>> X2
X2 =
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
>> Y2
Y2 =
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
- это результат с использованием X
и Y
в качестве исходной сетки точек, а X2
и Y2
- это точки, в которых мы хотим интерполировать.
Мы получаем:
>> B
B =
100 75 50 NaN
85 60 35 NaN
70 45 20 NaN
NaN NaN NaN NaN
person
rayryeng
schedule
20.08.2015