0

I wanted two interpolate pixels of an picture by the surrounding pixels due to the fact that I have some pixels which do not contain the correct values. For this, I found this answer.

I put it in this function:

from typing import List, Tuple

import numpy as np
from scipy import interpolate


def bilinear_interpolation_and_insert(indices_list: List[Tuple[int, int]],
                                      array: np.ndarray) -> np.ndarray:
    """
    Perform bilinear interpolation using scipy.interpolate.griddata and insert the interpolated values into the 2D array
    at the given indices.

    Parameters:
        indices_list (list of tuples): A list of tuples, each containing the row and column indices (both integers) for interpolation.
        array (list of lists): A 2D array with numerical values.

    Returns:
        list of lists: The updated 2D array with the interpolated values inserted at the given indices.
    """

    def interpolate_missing_pixels(image: np.ndarray,
                                   mask: np.ndarray,
                                   method: str = 'cubic',
                                   fill_value: int = 0) -> np.ndarray:
        h, w = image.shape[:2]
        xx, yy = np.meshgrid(np.arange(w), np.arange(h))

        known_x = xx[~mask]
        known_y = yy[~mask]
        known_v = image[~mask]
        missing_x = xx[mask]
        missing_y = yy[mask]

        interp_values = interpolate.griddata((known_x, known_y),
                                             known_v, (missing_x, missing_y),
                                             method=method,
                                             fill_value=fill_value)

        interp_image = image.copy()
        interp_image[missing_y, missing_x] = interp_values

        return interp_image

    mask = np.zeros(array.shape, dtype=bool)
    for row, col in indices_list:
        mask[row, col] = True

    interpolated_array = interpolate_missing_pixels(array, mask)

    return interpolated_array


# Example usage:
array_2d = np.array([
    [100, 2, 100],
    [40, 5, 40],
    [100, 2, 100],
])

indices_to_interpolate = [(1, 1)]  # Use integers for indices

updated_array = bilinear_interpolation_and_insert(indices_to_interpolate,
                                                  array_2d)
print("Updated 2D array:")
for row in updated_array:
    print(row)

I would expect it to yield a number in the middle of 2 and 40 e.g. 21 however the results for the central value of the array is 14. With the linear mode it seems only to interpolate along one axis. What I would like to have is the mean of the surrounding values. Any idea of how I can achieve this?

David Zanger
  • 333
  • 1
  • 3
  • 8
  • `griddata` assumes the input samples are arbitrary, not on a regular grid. It uses Delaunay triangulation to divide up the domain into triangles, each vertex is a sample position. The area of the triangle can then be interpolated using those three samples. It will never use the four neighboring samples. – Cris Luengo Jul 27 '23 at 16:24
  • Try this instead: https://docs.opencv.org/3.4/df/d3d/tutorial_py_inpainting.html – Cris Luengo Jul 27 '23 at 16:27

0 Answers0