Заполните границы матрицы с помощью бикубической интерполяции

У меня есть матрица размера 28x22. Первая строка, две последние строки, первый столбец и два последних столбца (отмечены красным и зеленым цветом) пусты. Предполагается, что эти столбцы и строки заполняются бикубической интерполяцией.

Я прочитал несколько сообщений в SO и Интернете о бикубической интерполяции, но, к сожалению, я не могу этого понять. Кроме того, я читал, что для бикубической интерполяции требуется знание сетки 4x4 вокруг пикселя, который необходимо интерполировать. Однако, поскольку строки и столбцы находятся на границе, вокруг них нет сетки 4 x 4.

изображение


person skm    schedule 31.03.2016    source источник
comment
вам нужно искать экстраполяцию вместо интерполяции (кстати, хороший аватар Lena Icon)   -  person Spektre    schedule 31.03.2016


Ответы (1)


Пролог

вам нужно экстраполировать неизвестные области. Вам нужно решить, из какой информации вы хотите экстраполировать данные. Например, вы хотите использовать точки рядом с неизвестной областью или использовать точки, разбросанные по всей известной области. Оба подхода верны, но дают разные результаты, соответствующие разным потребностям.

Я буду использовать близкие точки к неизвестной области. Начну с более простого случая:

  1. 1D линейная экстраполяция

    Линейная экстраполяция использует линию, образованную двумя известными точками. так, например, предположим, что этот вектор:

    1D линейная экстраполяция

    Ось x — это индекс вектора/массива, а ось y — значение ячейки. Итак, я взял 2 последние известные точки (синие) и построил из них линию (зеленую). Там, где он пересекает следующие позиции массива, находятся ваши экстраполированные значения (красные). Итак, на С++ это выглядит так:

    float a[8]={ 1.0,2.0,4.0,8.0,10.0,7.0,0.0,0.0 }; // your vector (last two numbers are unknown)
    a[6]=a[4]+((a[5]-a[4])*2.0); // =4.0
    a[7]=a[4]+((a[5]-a[4])*3.0); // =1.0
    
  2. 1D кубическая экстраполяция

    Это похоже на #1, но вместо линии вы используете кубическую кривую с 4 контрольными точками в параметрической полиномиальной форме. Большинство кубических кривых построены так, что если параметр t=0, вы получите вторую контрольную точку, а если t=1, то вы получите третью контрольную точку. Если вы используете t=<0,1>, вы будете плавно переключаться между ними. Однако нам нужно расширить диапазон после последней контрольной точки, поэтому t>=3 с шагом 1 для следующей точки. Так:

    1D кубическая экстраполяция

    float a[8]={ 1.0,2.0,4.0,8.0,10.0,7.0,0.0,0.0 }; // your vector (last two numbers are unknown)
    float a0,a1,a2,a3; // your cubic curve polynomial coefficients (computed from 4 control points a[2],a[3],a[4],a[5])
    float t; // curve parameter
    // here compute the a0,a1,a2,a3
    t=3.0; a[6]=a0+a1*t+a2*t*t+a3*t*t*t*t;
    t=4.0; a[7]=a0+a1*t+a2*t*t+a3*t*t*t*t;
    

    Теперь, как получить коэффициенты a0,a1,a2,a3? Вы можете использовать любой интерполяционный полином. Мне больше всего нравится это (маркер #3):

    Итак, вот он (надеюсь, я не сделал глупой ошибки при замене pi на a[2+i]):

    float  d1,d2;
    d1=0.5*(a[4]-a[2]);
    d2=0.5*(a[5]-a[3]);
    a0=a[3];
    a1=d1;
    a2=(3.0*(a[4]-a[3]))-(2.0*d1)-d2;
    a3=d1+d2+(2.0*(-a[4]+a[3]));
    
  3. Двухмерная бикубическая экстраполяция

    Это просто разделение проблемы на набор кубических экстраполяций 1D. Если вы посмотрите на графики из #2 сверху, вы увидите для бикубического режима следующее:

    2D бикубическая экстраполяция

    Поэтому сначала вы вычисляете неизвестные столбцы (которые вы можете), а затем из них вычисляете недостающие строки (или наоборот).

person Spektre    schedule 31.03.2016