Escalado de imágenes mediante interpolación bilineal | Image scaling applying bilinear interpolation

Repo: https://github.com/umarquez/100DaysOfC0D3/tree/master/24-bilinear-interpolation-scaling

La interpolación bilineal es una extensión de la interpolación lineal para interpolar funciones de dos variables (por ejemplo, x e y) en una malla regular de dos dimensiones. Wikipedia

En esta ocasión utilizaremos esta técnica para generar la información faltante en los píxeles vacíos cuando escalamos una imagen; la ocasión anterior hablamos de interpolación por vecinos cercanos, así que si no has leído la primera parte de este tema o quieres tener un poco más de información te recomiendo leer el capítulo [16100] antes de continuar.

Nuevamente tomaremos como referencia los píxeles originales que colocaremos en el píxel superior izquierdo de cada bloque de píxeles nuevos, esto hará que contemos con una matriz de n x n en la que habremos distribuido la información original de manera uniforme.

Lo primero que deberemos hacer será interpolar linealmente de manera vertical cada píxel de la imagen hasta el siguiente píxel disponible dentro de la misma columna, con esto generaremos columnas que recorren toda la imagen nueva, a continuación solo bastará con interpolar de manera horizontal cada fila de píxeles vacíos, a modo de conectar una columna con otra.

Vamos a aplicar estos pasos en un ejemplo.

Ejemplo

Vamos a escalar 3:1 los siguientes píxeles utilizando interpolación bilineal.

Paso 1

Generamos la nueva matriz y colocamos los valores originales en la nueva ubicación

Paso 2

A continuación deberemos conectar cada columna, interpolando entre los valores disponibles:

A continuación se muestra el procedimiento a detalle para cada par de valores

Hemos decidido rellenar las últimas filas duplicando el último valor disponible debido a la falta de información.

Paso 3

Una vez que contamos con las primeras columnas, procedemos a generar los valores para cada fila:

La fórmula será la misma que en el paso anterior: valor = (((origen - destino) / escala) * posición) + origen

Resultado

Una vez que realicemos todos los cálculos terminaremos con los siguientes valores aproximados:

Notas

  • Debemos mencionar que todos los valores son redondeados debido a que los colores de cada píxel solo aceptan colores con valores enteros positivos.
  • Deberemos definir un método para rellenar las orillas, en este caso se decidió duplicar los últimos valores.
  • Este método generará una especie de desenfoque que se intensifica entre mayor sea la proporción y es producto de la distorsión que genera la interpolación lineal.

Implementación en Go

Utilizaremos la interpolación por vecinos cercanos y la interpolación lineal para generar dos imágenes escaladas a partir de una imagen aleatoria de menor tamaño, de esta forma podremos comparar los resultados de que genera cada método.

original
original

bilineal
bilineal

vecino cercano
vecino cercano

original
original

bilineal
bilineal

vecino cercano
vecino cercano

original
original

bilineal
bilineal

vecino cercano
vecino cercano

original
original

bilineal
bilineal

vecino cercano
vecino cercano