Ответ 1
Какое разумное решение во многом зависит от того, на какие вопросы вы пытаетесь ответить с помощью интерполированных пикселей - caveat emptor: экстраполяция по отсутствующим данным может привести к очень вводящим в заблуждение ответам!
Радиальная базовая функция Интерполяция/сглаживание ядра
С точки зрения практических решений, доступных в Python, одним из способов заполнения этих пикселей было бы использование Scipy реализации интерполяции Radial Basis Function (см. здесь), которая предназначенные для сглаживания/интерполяции рассеянных данных.
Учитывая вашу матрицу M
и лежащие в основе 1D координатные массивы r
и c
(такие, что M.shape == (r.size, c.size)
), где отсутствующие записи M установлены на nan
, это, похоже, работает довольно хорошо с линейной RBF следующим образом:
import numpy as np
import scipy.interpolate as interpolate
with open('measurement.txt') as fh:
M = np.vstack(map(float, r.split(' ')) for r in fh.read().splitlines())
r = np.linspace(0, 1, M.shape[0])
c = np.linspace(0, 1, M.shape[1])
rr, cc = np.meshgrid(r, c)
vals = ~np.isnan(M)
f = interpolate.Rbf(rr[vals], cc[vals], M[vals], function='linear')
interpolated = f(rr, cc)
Это дает следующую интерполяцию данных, которые вы связали выше, что, хотя и разумно выглядит, показывает, насколько неблагоприятным является отношение недостающих образцов к реальным данным:
Гауссовская регрессия процесса/кригинг
Интерпретация кригинга доступна с помощью регрессии Gaussian Process(), которая сама по себе основана на инструменте DACE Kriging для Matlab) в библиотеке scikit-learn. Это можно вызвать следующим образом:
from sklearn.gaussian_process import GaussianProcess
gp = GaussianProcess(theta0=0.1, thetaL=.001, thetaU=1., nugget=0.01)
gp.fit(X=np.column_stack([rr[vals],cc[vals]]), y=M[vals])
rr_cc_as_cols = np.column_stack([rr.flatten(), cc.flatten()])
interpolated = gp.predict(rr_cc_as_cols).reshape(M.shape)
Это дает очень похожую интерполяцию на приведенный выше пример радиальной основы. В обоих случаях есть много параметров для изучения - выбор в значительной степени зависит от предположений, которые вы можете сделать о данных. (Одно преимущество линейного ядра, используемого в приведенном выше примере RBF, состоит в том, что он не имеет свободных параметров)
Inpainting
В качестве окончательного в стороне, полностью визуально мотивированное решение будет использовать функциональность OpenCV inpainting, хотя это предполагает 8-битные массивы (0 - 255) и не имеет простой математической интерпретации.