Билинейная интерполяция для увеличения растровых изображений

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

изображение задается как 24-битное .формат BMP. У меня уже есть ридер .bmp и сохранили пиксели в массиве.

теперь мне нужно выполнить билинейную интерполяцию массива. Я не понимаю математику за ним (даже после прохождения статьи и другие результаты Google). Из-за этого я не могу придумать алгоритм.

есть ли кто-нибудь, кто может помочь мне со ссылкой на существующий алгоритм билинейной интерполяции на 1-D массиве? Или, возможно, ссылка на библиотеку обработки изображений с открытым исходным кодом, которая использует билинейную и бикубическую интерполяцию для масштабирования изображений?

3 ответов


самый простой способ понять билинейную интерполяцию-понять линейную интерполяцию в 1D.

эта первая цифра должна дать вам воспоминания о математике средней школы. Учитывая некоторое местоположение a на котором мы хотим знать f (a), мы берем соседние "известные" значения и помещаем линию между ними.

Linear interpolation in 1D.

поэтому мы просто использовали старые уравнения средней школы y=mx+b и y-y1=m(x-x1). Ничего маскарадный.

мы в основном переносим эту концепцию на 2-D, чтобы получить билинейную интерполяцию. Мы можем атаковать проблему поиска f (a,b) любой a, b выполнив три интерполяции. Внимательно изучите следующую фигуру. Не пугайтесь всех ярлыков. На самом деле это довольно просто.

Bilinear interpolation as three 1D interpolations.

для билинейной интерполяции мы снова используем соседние точки. Теперь их четыре, так как мы находимся в 2D. Фокус в том, чтобы атаковать проблему по одному измерению за раз.

мы проецируем наши (a, b) в стороны и сначала вычислить два (одномерный!) линии интерполяции.

  • f (a, yj) здесь yj проводится постоянный
  • f (a, yС J+1) здесь yС J+1 остается неизменным.

теперь есть только один последняя ступень. Вы берете два пункта, которые вы рассчитали,f (a, yj) и f (a, yС J+1), и установить границы между ними. Это синий, идущий слева направо на диаграмме, проходящий через f (a,b). Интерполяция по этой последней строке дает окончательный ответ.

Я оставлю математику для 2-D случая для вас. Это не сложно, если вы работаете по схеме. И пройдя через это, ты действительно научишься. что происходит.

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


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

смотрите фотографии в ПРИМЕР ИЗМЕНЕНИЯ РАЗМЕРА ИЗОБРАЖЕНИЯ.

на f(x,y)=... формула эта статья в Википедии дает метод для вычисления цвета f вставленного пикселя:

enter image description here

для каждого вставленного пикселя вы объединяете цвета 4 исходных пикселей (Q11, Q12, Q21, Q22), окружающих его. Комбинация зависит от расстояния между вставленным пикселем и окружающими оригинальными пикселями, чем ближе он к одному из них, тем ближе их цвета:

enter image description here

исходные пиксели отображаются красным цветом. Вставленный пиксель отображается зеленым цветом.

это идея.

Если вы масштабируете стороны неинтегрированным фактором, формулы по-прежнему сохраняются, но теперь вам нужно чтобы пересчитать все цвета пикселей, вы не можете просто взять исходные пиксели и просто вставить между ними дополнительные пиксели.


не зацикливайтесь на том, что 2D-массивы в C действительно являются 1D-массивами. Это деталь реализации. Математически вам все равно нужно будет думать в терминах 2D-массивов.

подумайте о линейной интерполяции на массиве 1D. Вы знаете значение 0, 1, 2, 3, ... теперь предположим, я попрошу у вас значение в 1.4. Вы бы дали мне взвешенное сочетание значений в 1 и 2: (1 - 0.4)*A[1] + 0.4*A[2]. Просто, да?

теперь вам нужно расширить до 2D. Нет проблем. 2Д интерполяция может быть разложена на две 1D интерполяции, по оси x, а затем по оси y. Скажите, что вы хотите (1.4, 2.8). Получить интерполянтами 1Д между (1, 2)<->(2,2) и (1,3)<->(2,3). Это твой шаг по оси Х. Теперь 1D интерполируют между ними с соответствующими весами для y = 2.8.

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