来自数组的图像显示为灰色图像
Image fromarray is showing a greyed out image
我正在从相机中获取一个数组,对值进行阈值处理并想保存新图像。我正在使用 PIL.Image.fromarry()
将数组转换为图像,但我只看到灰色图像。图像在那里,因为当我导入另一个程序时,我可以看到我想要的东西。当我用 plt.show(data)
显示图像时,这就是我希望看到的图像。如何更改颜色值?
from flirpy.camera.lepton import Lepton
import matplotlib.pyplot as plt
import numpy as np
import cv2
from PIL import Image as im
camera = Lepton()
for i in range(5):
image = camera.grab()
cimage = np.around(image/100 - 273.15, 2)
cimage = np.where(cimage < 20, 20, cimage)
cimage = np.where(cimage > 30, 30, cimage)
data = im.fromarray(cimage.astype(np.uint8),'L')
data.save(f'test_{i:04}.png')
plt.imshow(data)
plt.show()
camera.close()
Matplotlib:
PIL:
Matplotlib 将颜色图应用于您的图像,并且在某些情况下还会将值缩放到完整的颜色范围。 PIL 不会那样做,所以如果你给它一个灰度图像(单通道),所有值都在 20..30 范围内,它会变成黑色,因为它真的期望值在 0..255 范围内,它也不会为您着色灰色。
以下是如何将 Matplotlib cmap
转换为调色板并将其推入 PIL Image
:
#!/usr/bin/env python3
import matplotlib.pyplot as plt
from PIL import Image, ImageMath
def cmap2palette(cmapName='viridis'):
"""Convert a Matplotlib colormap to a PIL Palette"""
cmap = plt.get_cmap(cmapName)
palette = [int(x*255) for entry in cmap.colors for x in entry]
return palette
# Generate a linear ramp
im = Image.linear_gradient('L')
im.save('DEBUG-ramp.png') # just debug, not required
# Generate the viridis Matplotlib colourmap push into our PIL Image
pal = cmap2palette('viridis')
im.putpalette(pal)
im.save('DEBUG-viridis.png')
# Just for fun...
# Generate the inferno Matplotlib colourmap push into our PIL Image
pal = cmap2palette('inferno')
im.putpalette(pal)
im.save('DEBUG-inferno.png')
# Now with your image
im = Image.open('w9jUR.png')
# Contrast-stretch to full range
gMin, gMax = im.getextrema()
print(F'Greyscale min: {gMin}, greyscale max: {gMax}')
im = ImageMath.eval('int(255*(g-gMin)/(gMax-gMin))', g=im, gMin=gMin, gMax=gMax).convert('L')
# Generate the viridis Matplotlib colourmap push into our PIL Image
pal = cmap2palette('viridis')
im.putpalette(pal)
im.save('DEBUG-result.png')
将此作为输入灰度图像:
这是 viridis
和 inferno
颜色图的结果:
另请注意,您不需要像这样将图像裁剪到 20..30 范围内 2 遍:
cimage = np.where(cimage < 20, 20, cimage)
cimage = np.where(cimage > 30, 30, cimage)
您应该可以使用 np.clip()
:
np.clip(cimage, 20, 30, out=cimage)
如果我们将上面的代码应用到您的图片:
我正在从相机中获取一个数组,对值进行阈值处理并想保存新图像。我正在使用 PIL.Image.fromarry()
将数组转换为图像,但我只看到灰色图像。图像在那里,因为当我导入另一个程序时,我可以看到我想要的东西。当我用 plt.show(data)
显示图像时,这就是我希望看到的图像。如何更改颜色值?
from flirpy.camera.lepton import Lepton
import matplotlib.pyplot as plt
import numpy as np
import cv2
from PIL import Image as im
camera = Lepton()
for i in range(5):
image = camera.grab()
cimage = np.around(image/100 - 273.15, 2)
cimage = np.where(cimage < 20, 20, cimage)
cimage = np.where(cimage > 30, 30, cimage)
data = im.fromarray(cimage.astype(np.uint8),'L')
data.save(f'test_{i:04}.png')
plt.imshow(data)
plt.show()
camera.close()
Matplotlib:
PIL:
Matplotlib 将颜色图应用于您的图像,并且在某些情况下还会将值缩放到完整的颜色范围。 PIL 不会那样做,所以如果你给它一个灰度图像(单通道),所有值都在 20..30 范围内,它会变成黑色,因为它真的期望值在 0..255 范围内,它也不会为您着色灰色。
以下是如何将 Matplotlib cmap
转换为调色板并将其推入 PIL Image
:
#!/usr/bin/env python3
import matplotlib.pyplot as plt
from PIL import Image, ImageMath
def cmap2palette(cmapName='viridis'):
"""Convert a Matplotlib colormap to a PIL Palette"""
cmap = plt.get_cmap(cmapName)
palette = [int(x*255) for entry in cmap.colors for x in entry]
return palette
# Generate a linear ramp
im = Image.linear_gradient('L')
im.save('DEBUG-ramp.png') # just debug, not required
# Generate the viridis Matplotlib colourmap push into our PIL Image
pal = cmap2palette('viridis')
im.putpalette(pal)
im.save('DEBUG-viridis.png')
# Just for fun...
# Generate the inferno Matplotlib colourmap push into our PIL Image
pal = cmap2palette('inferno')
im.putpalette(pal)
im.save('DEBUG-inferno.png')
# Now with your image
im = Image.open('w9jUR.png')
# Contrast-stretch to full range
gMin, gMax = im.getextrema()
print(F'Greyscale min: {gMin}, greyscale max: {gMax}')
im = ImageMath.eval('int(255*(g-gMin)/(gMax-gMin))', g=im, gMin=gMin, gMax=gMax).convert('L')
# Generate the viridis Matplotlib colourmap push into our PIL Image
pal = cmap2palette('viridis')
im.putpalette(pal)
im.save('DEBUG-result.png')
将此作为输入灰度图像:
这是 viridis
和 inferno
颜色图的结果:
另请注意,您不需要像这样将图像裁剪到 20..30 范围内 2 遍:
cimage = np.where(cimage < 20, 20, cimage)
cimage = np.where(cimage > 30, 30, cimage)
您应该可以使用 np.clip()
:
np.clip(cimage, 20, 30, out=cimage)
如果我们将上面的代码应用到您的图片: