2013-12-24 6 views
9

Изображение (test.tif) прилагается. Значения np.nan являются наиболее белой областью. Как заполнить эту самую белую область, используя алгоритмы заполнения пробелов, которые используют значения от соседей?заполнение пробелов на изображении с помощью numpy и scipy

enter image description here

import scipy.ndimage 

data = ndimage.imread('test.tif') 
+0

Посмотрите на библиотеку scipy interolate, чтобы найти функцию, соответствующую вашим потребностям. http://docs.scipy.org/doc/scipy/reference/interpolate.html – M4rtini

ответ

5

0 думаю, viena's вопрос больше связан с проблемой inpainting.

Вот некоторые идеи:

  • Для того, чтобы заполнить пробелы в B/W изображения, которые вы можете использовать некоторые заполнения алгоритм как scipy.ndimage.morphology.binary_fill_holes. Но у вас есть изображение на уровне серого, поэтому вы не можете его использовать.

  • Я полагаю, что вы не хотите использовать комплексный алгоритм inpainting. Мое первое предложение: не пытайтесь использовать значение Nearest grey (вы не знаете реального значения NaN-пикселей). Использование значения NEarest создаст грязный алгоритм. Вместо этого я предлагаю вам заполнить пробелы некоторым другим значением (например, среднее из строки). Вы можете сделать это без кодирования с использованием scikit-learn:

Source:

>>> from sklearn.preprocessing import Imputer 
>>> imp = Imputer(strategy="mean") 
>>> a = np.random.random((5,5)) 
>>> a[(1,4,0,3),(2,4,2,0)] = np.nan 
>>> a 
array([[ 0.77473361, 0.62987193,   nan, 0.11367791, 0.17633671], 
    [ 0.68555944, 0.54680378,   nan, 0.64186838, 0.15563309], 
    [ 0.37784422, 0.59678177, 0.08103329, 0.60760487, 0.65288022], 
    [  nan, 0.54097945, 0.30680838, 0.82303869, 0.22784574], 
    [ 0.21223024, 0.06426663, 0.34254093, 0.22115931,   nan]]) 
>>> a = imp.fit_transform(a) 
>>> a 
array([[ 0.77473361, 0.62987193, 0.24346087, 0.11367791, 0.17633671], 
    [ 0.68555944, 0.54680378, 0.24346087, 0.64186838, 0.15563309], 
    [ 0.37784422, 0.59678177, 0.08103329, 0.60760487, 0.65288022], 
    [ 0.51259188, 0.54097945, 0.30680838, 0.82303869, 0.22784574], 
    [ 0.21223024, 0.06426663, 0.34254093, 0.22115931, 0.30317394]]) 
  • грязный раствор, который использует Ближайшие значения может быть таким: 1) Найти точки периметра NaN 2) Вычислить все расстояния между точками NaN и периметром 3) Заменить NaN на th e ближайшая точка значение серого
7

Если вы хотите значения от ближайших соседей, вы можете использовать NearestNDInterpolator из scipy.interpolate. Есть также other interpolators, а также вы можете рассмотреть.

Вы можете найти X, значения Y индекса для NaN значения с:

import numpy as np 

nan_locs = np.where(np.isnan(data)) 

Есть некоторые другие опции для интерполяции, а также. Один из вариантов заключается в замене значений NaN на результаты median filter (но ваши области для этого являются большими). Другим вариантом может быть grayscale dilation. Правильная интерполяция зависит от вашего конечного домена.

Если вы раньше не использовали интерполятор SciPy ND, вам необходимо предоставить данные X, Y и value, чтобы они соответствовали интерполятору, а затем X и Y для значений для интерполяции. Вы можете сделать это, используя пример, приведенный выше, в качестве шаблона.

19

Как и другие, предлагается использовать scipy.interpolate. Однако для этого требуется довольно обширная манипуляция индексами.

Полный пример:

from pylab import * 
import numpy 
import scipy.ndimage 
import scipy.interpolate 
import pdb 

data = scipy.ndimage.imread('data.png') 

# a boolean array of (width, height) which False where there are missing values and True where there are valid (non-missing) values 
mask = ~((data[:,:,0] == 255) & (data[:,:,1] == 255) & (data[:,:,2] == 255)) 

# array of (number of points, 2) containing the x,y coordinates of the valid values only 
xx, yy = numpy.meshgrid(numpy.arange(data.shape[1]), numpy.arange(data.shape[0])) 
xym = numpy.vstack((numpy.ravel(xx[mask]), numpy.ravel(yy[mask]))).T 

# the valid values in the first, second, third color channel, as 1D arrays (in the same order as their coordinates in xym) 
data0 = numpy.ravel(data[:,:,0][mask]) 
data1 = numpy.ravel(data[:,:,1][mask]) 
data2 = numpy.ravel(data[:,:,2][mask]) 

# three separate interpolators for the separate color channels 
interp0 = scipy.interpolate.NearestNDInterpolator(xym, data0) 
interp1 = scipy.interpolate.NearestNDInterpolator(xym, data1) 
interp2 = scipy.interpolate.NearestNDInterpolator(xym, data2) 

# interpolate the whole image, one color channel at a time  
result0 = interp0(numpy.ravel(xx), numpy.ravel(yy)).reshape(xx.shape) 
result1 = interp1(numpy.ravel(xx), numpy.ravel(yy)).reshape(xx.shape) 
result2 = interp2(numpy.ravel(xx), numpy.ravel(yy)).reshape(xx.shape) 

# combine them into an output image 
result = numpy.dstack((result0, result1, result2)) 

imshow(result) 
show() 

Выход:

enter image description here

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

Смежные вопросы