灰度热图到颜色梯度热图

Grayscale Heatmap to Color Gradient Heatmap

我正在尝试获取一组 256x256px 8 位灰度 .png(具有透明度)并将灰度 .png 转换为相同大小的彩色 .png,但仍保持透明度。我想使用的调色板是 R wesanderson 包中的 Zissou1,我已经将其放入 Python 字典中,其中每个键对应一个灰度值,每个值对应一个十六进制颜色。

import os
from PIL import Image, ImageColor

### dic = the dictionary containing the palette in format {grayscale pixel value: "HEX COLOR"},
###       created earlier in the script

with Image.open("3.png") as im:
    fin = Image.new("RGBA", im.size)
    px = im.load()
    px1 = fin.load()
    for x in range(0,256):
        for y in range(0,256):
            px1.putpixel(x,y,ImageColor.getcolor(dic[px.getpixel(x,y)[1]],"RGBA"))
    fin.show()

我遇到错误:

px1.putpixel(x,y,ImageColor.getcolor(dic[px.getpixel(x,y)[1]],"RGBA"))
AttributeError: 'PixelAccess' object has no attribute 'putpixel'

PIL 的 PixelAccess.putpixel 方法的第一个参数期望像素的坐标作为 (x,y) 元组传递:

px1.putpixel((x,y),ImageColor.getcolor(dic[px.getpixel(x,y)[1]],"RGBA"))

或者,考虑使用 Image.point method which takes a look up table similar to the one you already created to map an image based on pixel values. See the answer at Using the Image.point() method in PIL to manipulate pixel data 了解更多详情

延期 :

PIL 给出的查找

使用 Image.point(lookup_table, mode = 'L'),您可以查找和转置图像的颜色。

lookup_table = ...
with Image.open("3.png") as orig:
    image = orig.point(lookup_table, mode = 'L')
    image.show()

要查看将 Image.point 方法与 lookup_table 结合使用的示例:

  • Using the Image.point() method in PIL to manipulate pixel data

您自己的实现(通过改进的命名进行修复)

或自己实施针对 your_dic 的查找:

your_dic = ...
with Image.open("3.png") as orig:
    image = colored_from_map(orig, your_dic)
    image.show()

使用这个替代函数(你几乎做到了):

def colored_from_map(orig, map_to_color):
    image_in = orig.load()
    image = Image.new("RGBA", im.size)
    image_out = image.load()

    for x in range(0,256):
        for y in range(0,256):
            coords = (x,y)
            greyscale = image_in.getpixel(x,y)[1]
            color_name = map_to_color[greyscale]
            image_out.putpixel(coords, ImageColor.getcolor(color_name,"RGBA"))

    return image

保留 alpha-channel(透明度)

查看 source-code of ImageColor.getColor() 在其方法体的开头和结尾:

    color, alpha = getrgb(color), 255  # default to no-transparency
    if len(color) == 4:  # if your mapped color has 4th part as alpha-channel
        color, alpha = color[0:3], color[3]  # then use it

    # omitted lines
    else:
        if mode[-1] == "A":  # if the last char of `RGBA` is `A`
            return color + (alpha,)  # then return with added alpha-channel
    return color

(评论我的)

因此您可以简单地将返回的 color-tuple 的第四个元素设置为原始 gray-scale 图像的先前值:

            greyscale = image_in.getpixel(x,y)[1]  # containing original alpha-channel
            color_name = map_to_color[greyscale]  # name or hex
            mapped_color = ImageColor.getcolor(color_name,"RGB")  # removed the A
            transposed_color = mapped_color[:2] + (greyscale[3],)  # first 3 for RGB + original 4th for alpha-channel (transparency)
            image_out.putpixel(coords, transposed_color)

注意:因为 A(lpha-channel) 是从原始图像提供的,所以我从 getColor 调用的最后一个参数中删除了 A。从技术上讲,您还可以从 mapped_color[:2] 中删除切片以生成 mapped_color + (greyscale[3],).