简体   繁体   English

PIL Image 如何保存具有非整数和非正值的 NumPy 数组?

[英]How does PIL Image save NumPy arrays with non-integer and non-positive values?

I have a NumPy array of size 28 x 280, which contains real number values (both positive and negative values).我有一个大小为 28 x 280 的 NumPy 数组,其中包含实数值(正值和负值)。 I am using the following code to save this array to file through a PIL Image -我正在使用以下代码通过 PIL 图像将此数组保存到文件中-

img = Image.fromarray(img)
img.save(save_path, "PNG")

Now, when I load this saved image using PIL using the following code -现在,当我使用以下代码使用 PIL 加载此保存的图像时 -

img = Image.open(save_path)
img = np.array(img)
print(img[:,:,0]) # since the image is saved in RGB by default, and the channels are simply all the same, I am printing out only one of the channels
print(img.shape) # printing shape of loaded image for sanity check

The above gives me the following output -以上给了我以下输出 -

array([[ 0,  0,  0],
       [ 0,  0,  0],
       [ 0,  0,  0],
       [14, 14, 14],
       [ 0,  0,  0],
       [14, 14, 14],
       [ 0,  0,  0],
       [ 2,  2,  2],
       [10, 10, 10],
       [ 0,  0,  0],
       [ 0,  0,  0],
       [ 0,  0,  0],
       [ 6,  6,  6],
       [ 0,  0,  0],
       [19, 19, 19],
       [16, 16, 16],
       [ 0,  0,  0],
       [ 9,  9,  9],
       [14, 14, 14],
       [ 5,  5,  5],
-- omitting the remaining matrix for spatial reasons

The original matrix looks something like the following if that helps -如果有帮助,原始矩阵如下所示 -

   1.54009545e+00  1.14122391e-01 -5.44282794e-01 -1.66106954e-01]
 [-2.70073628e+00 -6.25280142e+00  1.77814519e+00 -8.72797012e+00
   9.91206944e-01  6.63580036e+00  6.84081888e+00 -1.18705761e+00
  -4.54479456e+00 -5.26672935e+00  4.91975927e+00 -5.48409176e+00
  -3.93164325e+00  5.19110155e+00  1.26516495e+01  9.93665600e+00
  -5.70824432e+00  5.72582603e-01 -4.31831169e+00 -9.31297874e+00
   2.13714447e-02 -9.82507896e+00 -2.47176766e+00 -1.94778728e+00
  -1.85507727e+00 -8.01630592e+00 -4.42644596e+00  5.74180269e+00]
 [ 3.32923412e+00  1.50732050e+01 -1.01800518e+01  1.85193479e-01
  -1.77801073e+00 -4.91134501e+00 -4.94232035e+00  5.52533197e+00
  -3.84771490e+00 -5.61370182e+00 -2.91945863e+00 -9.53506768e-01
   7.03971624e-01  1.26758552e+00 -1.29794350e+01 -1.08105397e+00
  -5.57984650e-01 -1.50801647e+00 -3.45247960e+00 -6.14299655e-01
  -4.83907032e+00  5.44770575e+00  2.50088573e+00 -2.45785332e+00
  -3.94766003e-01  7.80810177e-01 -1.66951954e+00 -5.23118067e+00]
 [ 1.24226892e+00 -4.30912447e+00  1.14384556e+00 -5.38896322e+00
  -5.95073175e+00  5.03882837e+00  4.15563917e+00 -7.99412632e+00
  -1.68129158e+00 -2.23124218e+00  2.24080634e+00 -5.57195246e-01
  -2.29391623e+00 -2.70431495e+00  9.87635612e+00 -2.90223390e-01
   3.25407982e+00  3.67051101e+00 -2.86848998e+00 -4.53229618e+00
  -3.80941963e+00  3.66697168e+00  3.98574305e+00 -1.50027335e-01
  -8.77485275e+00  2.20300531e+00  4.97666216e+00  2.27730870e+00]]

-- again, omitting large chunks for spatial reasons

Question -问题 -

  1. Here, from what I understand, PIL is implicitly converting the reals to uint8 format (0 to 255 pixel values), but I want to know how exactly conversion of reals to uint8 takes place?在这里,据我了解,PIL 隐式将实数转换为uint8格式(0 到 255 像素值),但我想知道实数到uint8的转换究竟是如何发生的? Are the real pixel values rounded off or truncated to the closest integer, if so, what happens to the negative pixel values?实际像素值是否四舍五入或截断为最接近的整数,如果是,负像素值会发生什么?
  2. Also, when I try to visualize the PIL image by simply opening it, it just shows me a black screen, like so -此外,当我尝试通过简单地打开 PIL 图像来可视化它时,它只会显示一个黑屏,就像这样 - 在此处输入图像描述

But, the weird thing is that, when I multiply the np array by 255, like so - img = img * 255 , and then save it, it shows some values, like so -但是,奇怪的是,当我将 np 数组乘以 255 时,就像这样 - img = img * 255 ,然后保存它,它会显示一些值,就像这样 -

在此处输入图像描述

Is it just that the pixel values initially are too light to be perceived by my eyes?只是最初的像素值太轻而无法被我的眼睛感知吗? I think so, but I just want to confirm.我想是的,但我只是想确认一下。

If you want to save negative and floating point data as an image, you should probably use TIFF format.如果要将负数和浮点数据保存为图像,您可能应该使用TIFF格式。

PNG is only able to store unsigned integer data at up to 16-bit/channel, ie in range 0..65535. PNG最多只能存储 16 位/通道的无符号整数数据,即范围 0..65535。


Here is a demonstration of saving positive and negative floating point numbers in a TIFF and then retrieving them:这是在 TIFF 中保存正负浮点数然后检索它们的演示:

import numpy as np
from PIL import Image

# Set height and width
h, w = 5, 4

# Create image from Numpy array of float32 and save as TIFF
naA = np.linspace(-1000, 1000, h*w, dtype=np.float32).reshape((h,w))
Image.fromarray(naA).save('floats.tif')

# Read back image and compare
imB = Image.open('floats.tif')
naB = np.array(imB)

Now print both and check same:现在打印两者并检查相同:

In [101]: naA
Out[101]: 
array([[-1000.     ,  -894.7368 ,  -789.4737 ,  -684.2105 ],
       [ -578.9474 ,  -473.6842 ,  -368.42105,  -263.1579 ],
       [ -157.89473,   -52.63158,    52.63158,   157.89473],
       [  263.1579 ,   368.42105,   473.6842 ,   578.9474 ],
       [  684.2105 ,   789.4737 ,   894.7368 ,  1000.     ]],
      dtype=float32)

In [102]: naB
Out[102]: 
array([[-1000.     ,  -894.7368 ,  -789.4737 ,  -684.2105 ],
       [ -578.9474 ,  -473.6842 ,  -368.42105,  -263.1579 ],
       [ -157.89473,   -52.63158,    52.63158,   157.89473],
       [  263.1579 ,   368.42105,   473.6842 ,   578.9474 ],
       [  684.2105 ,   789.4737 ,   894.7368 ,  1000.     ]],
      dtype=float32)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM