如何替换图像数据的 NaN 值?

数据挖掘 机器学习 Python 熊猫 麻木的 图像预处理
2021-09-21 08:16:23

我的数据集共有 200 列,其中每一列对应于我所有图像中的相同像素。我总共有 48,500 行。数据的标签范围为 0-9。

数据看起来像这样:

raw_0   raw_1   raw_2   raw_3   raw_4
0   120.0   133.0   96.0    155.0   66.0
1   159.0   167.0   163.0   185.0   160.0
2   45.0    239.0   66.0    252.0   NaN
3   126.0   239.0   137.0   NaN 120.0
4   226.0   222.0   153.0   235.0   171.0
5   169.0   81.0    100.0   44.0    104.0
6   154.0   145.0   76.0    134.0   175.0
7   77.0    35.0    105.0   108.0   112.0
8   104.0   55.0    113.0   90.0    107.0
9   97.0    253.0   255.0   251.0   141.0
10  224.0   227.0   84.0    214.0   57.0
11  NaN 13.0    51.0    50.0    NaN
12  82.0    213.0   61.0    98.0    59.0
13  NaN 40.0    84.0    7.0 39.0
14  129.0   103.0   65.0    159.0   NaN
15  123.0   128.0   116.0   198.0   111.0

每列有大约 5% 的缺失值,我想用有意义的东西填充这些 NaN 值。但是,我不知道该怎么做。欢迎大家提出意见。

谢谢!

4个回答

假设您将图像拉伸为大约 48,500 行的表格中的列,我假设您拥有尺寸为 220x220 的原始图像。

您可以使用通过 OpenCV 提供的名为 的函数inpaint,该函数将恢复丢失的像素值(例如退化照片的黑色像素)。

这是一个图像示例。左上角显示缺失值的图像(黑色)。右上角仅显示缺失值(掩码)。左下和右下是最终输出,比较了两种不同的填充图像算法。

恢复图像

我建议在你的图像上尝试这两种方法,看看什么看起来最好。

有关算法本身更多详细信息,请查看文档。这是实际功能的文档

至于代码,它看起来像这样:

import opencv as cv    # you will need to install OpenCV

dst = cv.inpaint(img, mask, 3, cv.INPAINT_TELEA)
  • 第一个参数是缺少值的图像
  • 第二个是掩码,其中包含丢失像素的位置,即应该填充/插值哪些像素。
  • 第三是要填充的缺失像素周围的半径
  • 第四个是要使用的算法的标志(请参阅上面的链接以获取两种选择)

对于每个图像,您可以使用以下内容生成掩码:

mask = image[np.isnan(image)]

注意:'==' 不适用于 np.nan

在此之后有多种方法可以解决。您可以进行均值插补、中值插补、众数插补或最常见的值插补。根据数据的结构方式,为行或列计算上述值之一。填充 Nan 的最简单方法之一是df.fillna使用 pandas

对于任何 (x,y) 如果 NAN,您可以将周围像素的平均值估算为:

if((x==0  & y==0):
 return (x+1)+(y+1))/2 

else if(x==x_max & y==y_max):
 return (x-1)+(y-1))/2

else if(x==0 & y==y_max):
 return (x+1)+(y-1))/2

else if(x==x_max & y==0):
 return (x-1)+(y+1))/2

else if(x==0):
 return ((x+1)+(y-1)+(y+1))/3

else if(x==x_max):
 return ((x-1)+(y-1)+(y+1))/3

else if(y==0):
 return ((x+1)+(x-1)+(y+1))/3

else if(y==y_max):
 return ((x-1)+(x+1)+(y-1))/3

else :
  return  ((x-1)+(x+1)+(y-1)+(y+1))/4 

如果相邻行是相邻像素,我将使用相邻像素的平均值。这对于图像来说似乎是有意义的,而且人眼肯定很难看到。