使用numpy和scipy填充图像上的空白

时间:2022-10-16 14:15:12

The image (test.tif) is attached. The np.nan values are the whitest region. How to fill those whitest region using some gap filling algorithms that uses values from the neighbours?

图像(test.tif)附呈。np。nan值是最白的区域。如何使用一些使用邻域值的间隙填充算法来填充最白的区域?

使用numpy和scipy填充图像上的空白

import scipy.ndimage

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

3 个解决方案

#1


5  

I think viena's question is more related to an inpainting problem.

我认为viena的问题更多的是与inpainting的问题有关。

Here are some ideas:

这里有一些建议:

  • In order to fill the gaps in B/W images you can use some filling algorithm like scipy.ndimage.morphology.binary_fill_holes. But you have a gray level image, so you can't use it.

    为了填补B/W图像中的空白,您可以使用一些填充算法,如scipy.ndimage.morphology.binary_fill_holes。但是你有一个灰度图像,所以你不能使用它。

  • I suppose that you don't want to use a complex inpainting algorithm. My first suggestion is: Don't try to use Nearest gray value (you don't know the real value of the NaN pixels). Using the NEarest value will generate a dirty algorithm. Instead, I would suggest you to fill the gaps with some other value (e.g. the mean of the row). You can do it without coding by using scikit-learn:

    我想你不希望使用复杂的内画算法。我的第一个建议是:不要尝试使用最接近的灰色值(您不知道NaN像素的真实值)。使用最接近的值将生成脏算法。相反,我建议您用其他值(例如行的平均值)来填补空白。你可以不通过使用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]])
  • The dirty solution that uses the Nearest values can be this: 1) Find the perimeter points of the NaN regions 2) Compute all the distances between the NaN points and the perimeter 3) Replace the NaNs with the nearest's point gray value
  • 使用最接近值的脏兮兮的解决方案可以是:1)找到NaN区域的周长点2)计算所有NaN点和周长之间的距离3)用最近的点灰度值替换NaNs

#2


19  

As others have suggested, scipy.interpolate can be used. However, it requires fairly extensive index manipulation to get this to work.

正如其他人所建议的,可以使用scipy.内插。然而,它需要相当广泛的索引操作才能使其工作。

Complete example:

完整的例子:

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()

Output:

输出:

使用numpy和scipy填充图像上的空白

This passes to the interpolator all values we have, not just the ones next to the missing values (which may be somewhat inefficient). It also interpolates every point in the output, not just the missing values (which is extremely inefficient). A better way is to interpolate just the missing values, and then patch them into the original image. This is just a quick working example to get started :)

这将传递给我们拥有的所有值,而不仅仅是缺失值旁边的值(这可能有些低效)。它还会插入输出中的每个点,而不仅仅是缺失的值(这是非常低效的)。更好的方法是插入缺失值,然后将它们贴到原始图像中。这只是一个开始的快速工作示例:)

#3


7  

If you want values from the nearest neighbors, you could use the NearestNDInterpolator from scipy.interpolate. There are also other interpolators as well you can consider.

如果您想要来自最近邻居的值,您可以使用来自scipy.插补的最近邻插值器。你也可以考虑其他的插值器。

You can locate the X,Y index values for the NaN values with:

可以用以下方法找到NaN值的X、Y索引值:

import numpy as np

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

There are some other options for the interpolation as well. One option is to replace NaN values with the results of a median filter (but your areas are kind of large for this). Another option might be grayscale dilation. The correct interpolation depends on your end domain.

还有一些其他的插值选项。一种选择是用中值过滤器的结果替换NaN值(但是您的区域在这方面比较大)。另一种选择可能是灰度扩张。正确的插值取决于你的端域。

If you haven't used a SciPy ND interpolator before, you'll need to provide X, Y, and value data to fit the interpolator to then X and Y data for values to interpolate at. You can do this using the where example above as a template.

如果您以前没有使用过SciPy ND插值器,则需要提供X、Y和值数据,以便将插值器的值与X和Y数据相匹配。您可以使用上面的where示例作为模板来实现这一点。

#1


5  

I think viena's question is more related to an inpainting problem.

我认为viena的问题更多的是与inpainting的问题有关。

Here are some ideas:

这里有一些建议:

  • In order to fill the gaps in B/W images you can use some filling algorithm like scipy.ndimage.morphology.binary_fill_holes. But you have a gray level image, so you can't use it.

    为了填补B/W图像中的空白,您可以使用一些填充算法,如scipy.ndimage.morphology.binary_fill_holes。但是你有一个灰度图像,所以你不能使用它。

  • I suppose that you don't want to use a complex inpainting algorithm. My first suggestion is: Don't try to use Nearest gray value (you don't know the real value of the NaN pixels). Using the NEarest value will generate a dirty algorithm. Instead, I would suggest you to fill the gaps with some other value (e.g. the mean of the row). You can do it without coding by using scikit-learn:

    我想你不希望使用复杂的内画算法。我的第一个建议是:不要尝试使用最接近的灰色值(您不知道NaN像素的真实值)。使用最接近的值将生成脏算法。相反,我建议您用其他值(例如行的平均值)来填补空白。你可以不通过使用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]])
  • The dirty solution that uses the Nearest values can be this: 1) Find the perimeter points of the NaN regions 2) Compute all the distances between the NaN points and the perimeter 3) Replace the NaNs with the nearest's point gray value
  • 使用最接近值的脏兮兮的解决方案可以是:1)找到NaN区域的周长点2)计算所有NaN点和周长之间的距离3)用最近的点灰度值替换NaNs

#2


19  

As others have suggested, scipy.interpolate can be used. However, it requires fairly extensive index manipulation to get this to work.

正如其他人所建议的,可以使用scipy.内插。然而,它需要相当广泛的索引操作才能使其工作。

Complete example:

完整的例子:

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()

Output:

输出:

使用numpy和scipy填充图像上的空白

This passes to the interpolator all values we have, not just the ones next to the missing values (which may be somewhat inefficient). It also interpolates every point in the output, not just the missing values (which is extremely inefficient). A better way is to interpolate just the missing values, and then patch them into the original image. This is just a quick working example to get started :)

这将传递给我们拥有的所有值,而不仅仅是缺失值旁边的值(这可能有些低效)。它还会插入输出中的每个点,而不仅仅是缺失的值(这是非常低效的)。更好的方法是插入缺失值,然后将它们贴到原始图像中。这只是一个开始的快速工作示例:)

#3


7  

If you want values from the nearest neighbors, you could use the NearestNDInterpolator from scipy.interpolate. There are also other interpolators as well you can consider.

如果您想要来自最近邻居的值,您可以使用来自scipy.插补的最近邻插值器。你也可以考虑其他的插值器。

You can locate the X,Y index values for the NaN values with:

可以用以下方法找到NaN值的X、Y索引值:

import numpy as np

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

There are some other options for the interpolation as well. One option is to replace NaN values with the results of a median filter (but your areas are kind of large for this). Another option might be grayscale dilation. The correct interpolation depends on your end domain.

还有一些其他的插值选项。一种选择是用中值过滤器的结果替换NaN值(但是您的区域在这方面比较大)。另一种选择可能是灰度扩张。正确的插值取决于你的端域。

If you haven't used a SciPy ND interpolator before, you'll need to provide X, Y, and value data to fit the interpolator to then X and Y data for values to interpolate at. You can do this using the where example above as a template.

如果您以前没有使用过SciPy ND插值器,则需要提供X、Y和值数据,以便将插值器的值与X和Y数据相匹配。您可以使用上面的where示例作为模板来实现这一点。