【问题标题】:Pandas - image to DataFrame熊猫 - 图像到 DataFrame
【发布时间】:2018-04-04 10:55:32
【问题描述】:

我想将一个 RGB 图像转换成一个 DataFrame,这样我就有了每个像素的坐标和它们的 RGB 值。

         x   y   red  green  blue
0        0   0   154      0     0
1        1   0   149    111     0
2        2   0   153      0     5
3        0   1   154      0     9
4        1   1   154     10    10
5        2   1   154      0     0

我可以很容易地将 RGB 提取到 DataFrame 中

colourImg = Image.open("test.png")
colourPixels = colourImg.convert("RGB")
colourArray = np.array(colourPixels.getdata())

df = pd.DataFrame(colourArray, columns=["red","green","blue"])

但我不知道如何获取其中的 X 和 Y 坐标。我可以写一个循环,但是在一个需要很长时间的大图像上。

【问题讨论】:

  • 一张3通道的图片有3个维度……你怎么解释只有两个坐标?
  • 每个像素都有一个 X 和 Y 位置。每个像素还有一个 R、G、B 值。

标签: python image pandas


【解决方案1】:

尝试使用np.indices 不幸的是,它最终会得到一个坐标是第一个维度的数组,但您可以做一些np.moveaxis 来解决这个问题。

colourImg = Image.open("test.png")
colourPixels = colourImg.convert("RGB")
colourArray = np.array(colourPixels.getdata()).reshape(colourImg.size + (3,))
indicesArray = np.moveaxis(np.indices(colourImg.size), 0, 2)
allArray = np.dstack((indicesArray, colourArray)).reshape((-1, 5))


df = pd.DataFrame(allArray, columns=["y", "x", "red","green","blue"])

这不是最漂亮的,但它似乎工作(编辑:固定 x,y 是错误的方式)。

【讨论】:

  • 工作完美 - 比我的尝试快得多 - 非常感谢!
  • 我如何应用这个反向过程?我在数据框中有 X、Y 坐标和 R、G、B 值,看起来像 X、Y、R、G、B。如何通过保留坐标将数据框转换为图像。
【解决方案2】:

如果 x 坐标是指原始像素数组的列号或行号,我将坐标“col”和“row”命名为明确的,以避免混淆:

A = colourArray

# Create the multiindex we'll need for the series
index = pd.MultiIndex.from_product(
    (*map(range, A.shape[:2]), ('r', 'g', 'b')),
    names=('row', 'col', None)
)

# Can be chained but separated for use in explanation
df = pd.Series(A.flatten(), index=index)
df = df.unstack()
df = df.reset_index().reindex(columns=['col', 'row', 'r', 'g', 'b'])

说明:

pd.Series(A.flatten(), index=index) 将创建一个多索引系列,其中每个通道强度都可以通过df[row_n, col_n][channel_r_g_or_b] 访问。 df 变量(目前是一个系列)现在看起来像这样:

row  col   
0    0    r    116
          g     22
          b    220
     1    r     75
          g    134
          b     43
              ... 
255  246  r     79
          g      9
          b    218
     247  r    225
          g    172
          b    172

unstack() 将旋转第三个索引(通道索引),返回一个包含bgr 列的数据帧,其中每一行都由(row_n, col_n) 的多索引索引。 df 现在看起来像这样:

           b    g    r
row col               
0   0    220   22  116
    1     43  134   75
    2    187   97   33
... ...  ...  ...  ...
255 226  156  242  128
    227  221   63  212
    228   75  110  193

然后我们调用reset_index() 以摆脱(row_n, col_n) 多索引,只拥有一个平坦的0..⁠(n_pixels-1) 索引。 df 现在是:

       row  col    b    g    r
0        0    0  220   22  116
1        0    1   43  134   75
2        0    2  187   97   33
...    ...  ...  ...  ...  ...
65506  255  226  156  242  128
65507  255  227  221   63  212
65508  255  228   75  110  193

然后一个简单的reindex() 将列重新排列为colrowrgb 顺序。


时间安排:

现在至于运行速度有多快,嗯...对于 3 通道图像,时间如下:

Size       Time
  250x250  58.2 ms
  500x500   251 ms
1000x1000  1.03 s
2500x2500  8.14 s

诚然,图像 > 1 MP 的效果不佳。 unstack() 在 df 变得非常大后可能需要一段时间。

我试过@davidsheldon's solution,它的运行速度要快得多,对于 2500x2500 的图像,需要 244 毫秒,而对于 10000x10000 的图像,需要 9.04 秒。

【讨论】:

  • 我认为xyrowcol 更清楚,在谈论图片时... +1 ;-)
  • 感谢您非常详细的解释。
猜你喜欢
  • 2019-04-27
  • 1970-01-01
  • 2018-08-13
  • 1970-01-01
  • 2013-01-28
  • 2016-05-03
  • 2020-08-31
  • 2018-07-04
  • 1970-01-01
相关资源
最近更新 更多