2x upsample with bicubic interpolation

345 Views Asked by At

I would like to understand how bicubic interpolation works and for that I choose the most easy example, 2x upsample.

So I know that I start with an image array, let say it is:

1 5 6 8 7
3 4 8 9 7
9 8 7 5 4
3 2 5 4 7

As I want to 2x upsample I will add 0s between column and rows:

1 0 5 0 6 0 8 0 7
0 0 0 0 0 0 0 0 0
3 0 4 0 8 0 9 0 7
0 0 0 0 0 0 0 0 0
9 0 8 0 7 0 5 0 4
0 0 0 0 0 0 0 0 0
3 0 2 0 5 0 4 0 7

I know how to get the pixel at 4,4 on the new image. First I need to make a cubic interpolation using 1 5 6 8 and get P1, then P2 with 2 4 8 9, then P3 with 9 8 7 5 and P4 with 3 2 5 4. Finally I need to cubic interpolate the pixel intensity with P1 P2 P3 P4. My main concern is about getting the pixel at 4,5 or 5,4

Right now I write this code in Python:

        # Creo una nueva imagen vacia con el doble de las dimensiones anteriores
        res_h = height *2
        res_w = width  *2
        img = np.zeros((res_h, res_w, 1), np.uint8)
        # Map original image into new, 2x resolution image
        img[::2,::2,0] = self.imageA

        # Recorro las filas de la imagen nueva
        for i in range(3,res_h-4,2):
            # Recorro las columnas de la imagen nueva
            for j in range(3,res_w-4,2):
                # Suponiendo a=-0.5 en la interpolacion cubica tengo estos valores para distancia 0.5 y 1.5
                h1 = 0.5625     # distancia 0.5
                h2 = -0.0625    # distancia 1.5
                # Almaceno los 16 puntos de soporte usados para la interpolacion
                Q11 = self.imageA[(i - 2)/2, (j - 2)/2]
                Q12 = self.imageA[(i - 2)/2, (j - 1)/2]
                Q13 = self.imageA[(i - 2)/2, (j + 1)/2]
                Q14 = self.imageA[(i - 2)/2, (j + 2)/2]

                Q21 = self.imageA[(i - 1)/2, (j - 2)/2]
                Q22 = self.imageA[(i - 1)/2, (j - 1)/2]
                Q23 = self.imageA[(i - 1)/2, (j + 1)/2]
                Q24 = self.imageA[(i - 1)/2, (j + 2)/2]

                Q31 = self.imageA[(i + 1)/2, (j - 2)/2]
                Q32 = self.imageA[(i + 1)/2, (j - 1)/2]
                Q33 = self.imageA[(i + 1)/2, (j + 1)/2]
                Q34 = self.imageA[(i + 1)/2, (j + 2)/2]

                Q41 = self.imageA[(i + 2)/2, (j - 2)/2]
                Q42 = self.imageA[(i + 2)/2, (j - 1)/2]
                Q43 = self.imageA[(i + 2)/2, (j + 1)/2]
                Q44 = self.imageA[(i + 2)/2, (j + 2)/2]

                # Interpolo cubicamente por filas y obtengo 4 puntos
                P1 = Q11 * h2 + Q12 * h1 + Q13 * h1 + Q14 * h2
                P2 = Q21 * h2 + Q22 * h1 + Q23 * h1 + Q24 * h2
                P3 = Q31 * h2 + Q32 * h1 + Q31 * h1 + Q34 * h2
                P4 = Q41 * h2 + Q42 * h1 + Q43 * h1 + Q44 * h2

                # Interpolo cubicamente esos 4 puntos para obtener el pixel actual
                pix = P1 * h2 + P2 * h1 + P3 * h1 + P4 * h2

                img[i, j] = pix

Thank!

0

There are 0 best solutions below