【问题标题】:Is there any good color map to convert gray-scale image to colorful ones using python's PIL? [duplicate]是否有任何好的颜色图可以使用 python 的 PIL 将灰度图像转换为彩色图像? [复制]
【发布时间】:2017-04-17 18:31:06
【问题描述】:

Matplotlib 有很多好的颜色图,但是性能很差。我正在编写一些代码来使灰度图像变得丰富多彩,其中使用颜色图进行插值是一个好主意。我想知道是否有可用的开源颜色图或演示代码使用 Pillow 通过颜色图将灰度图像转换为彩色图像?


澄清:

  1. Matplotlib 非常适合演示使用,但对于成千上万的图像性能不佳。
  2. Matplotlib colormaps
  3. 您可以将灰度图像映射到颜色图以获得彩色图像。

演示:

第一张图片是灰度图,第二张是在 'jet' cmap 中映射的,第三张是'hot'。

问题是我对颜色不太了解,我想在 PIL 中实现这样的效果以获得更好的性能。

【问题讨论】:

  • 请澄清您的问题..“但性能不好”,为什么性能不好? “在哪里用彩色图插值是个好主意”,你是什么意思? “将灰度图像转换为彩色图像”,以什么方式?哪些颜色应该映射到哪些灰色调?你有输入图像的例子,结果应该是什么?

标签: python matplotlib colors python-imaging-library


【解决方案1】:

我发现@ImportanceOfBeingErnest (How to convert Numpy array to PIL image applying matplotlib colormap) 提到的重复答案

import matplotlib as mpl
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import numpy as np

import timeit

from PIL import Image

def pil_test():
    cm_hot = mpl.cm.get_cmap('hot')
    img_src = Image.open('test.jpg').convert('L')
    img_src.thumbnail((512,512))
    im = np.array(img_src)
    im = cm_hot(im)
    im = np.uint8(im * 255)
    im = Image.fromarray(im)
    im.save('test_hot.jpg')

def rgb2gray(rgb):
    return np.dot(rgb[:,:,:3], [0.299, 0.587, 0.114])

def plt_test():
    img_src = mpimg.imread('test.jpg')
    im = rgb2gray(img_src)
    f = plt.figure(figsize=(4, 4), dpi=128)
    plt.axis('off')
    plt.imshow(im, cmap='hot')
    plt.savefig('test2_hot.jpg', dpi=f.dpi)
    plt.close()

t = timeit.timeit(pil_test, number=30)
print('PIL: %s' % t)
t = timeit.timeit(plt_test, number=30)
print('PLT: %s' % t)

性能结果是:

PIL: 1.7473899199976586
PLT: 10.632971412000188

他们都给了我与hot颜色图相似的结果。

【讨论】:

  • 虽然它不能完全缓解时间差异,但您当然应该将 matplotlib 后端切换为非交互式后端。你想要PNG,所以使用mpl.use("agg")。用你的代码测试,它看起来快两倍。
【解决方案2】:

您可以使用 matplotlib 中的颜色图并应用它们没有任何 matplotlib 图形等。 这将使事情变得更快:

import matplotlib.pyplot as plt

# Get the color map by name:
cm = plt.get_cmap('gist_rainbow')

# Apply the colormap like a function to any array:
colored_image = cm(image)

# Obtain a 4-channel image (R,G,B,A) in float [0, 1]
# But we want to convert to RGB in uint8 and save it:
Image.fromarray((colored_image[:, :, :3] * 255).astype(np.uint8)).save('test.png')

注意:

  • 如果您的输入图像是浮点数,则值应在区间 [0.0, 1.0] 内。
  • 如果您的输入图像是整数,则整数应在[0, N) 范围内,其中N 是地图中的颜色数。但是您可以根据需要将地图重新​​采样为任意数量的值:

    # If you need 8 color steps for an integer image with values from 0 to 7:
    cm = plt.get_cmap('gist_rainbow', lut=8)
    

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-12-28
    • 1970-01-01
    • 1970-01-01
    • 2019-10-24
    • 1970-01-01
    • 2016-01-11
    • 2015-10-07
    相关资源
    最近更新 更多