简体   繁体   English

灰度热图到颜色梯度热图

[英]Grayscale Heatmap to Color Gradient Heatmap

I am trying to take a set of 256x256px 8-bit grayscale .pngs (with transparency) and convert the grayscale .png to a color .png of the same size, still retaining transparency.我正在尝试采用一组 256x256px 8 位灰度 .png(具有透明度)并将灰度 .png 转换为相同大小的颜色 .png,但仍保持透明度。 The palette I want to use is Zissou1 from the R wesanderson package, which I have gotten into a Python dictionary where each key corresponds to a greyscale value and each value a HEX color.我想使用的调色板是来自 R wesanderson包的 Zissou1,我已经进入了 Python 字典,其中每个键对应一个灰度值,每个值对应一个 HEX 颜色。

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()

I am getting the error:我收到错误消息:

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

The first parameter to PIL's PixelAccess.putpixel method expects the pixel's coordinates to be passed as a (x,y) tuple: PIL 的PixelAccess.putpixel方法的第一个参数期望像素的坐标作为 (x,y) 元组传递:

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

Alternatively, consider using the Image.point method which takes a look up table similar to the one you already created to map an image based on pixel values.或者,考虑使用Image.point方法,该方法采用类似于您已经创建的查找表的查找表,以根据像素值映射图像。 See the answer at Using the Image.point() method in PIL to manipulate pixel data for more details有关更多详细信息,请参阅使用 PIL 中的 Image.point() 方法操作像素数据中的答案

To extend on Jason's answer :扩展杰森的回答

The lookup as given by PIL PIL 给出的查找

With Image.point(lookup_table, mode = 'L') you can lookup and transpose the colors of your image.使用Image.point(lookup_table, mode = 'L')您可以查找和转置图像的颜色。

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

To see an example for using the Image.point method with the lookup_table :要查看将Image.point方法与lookup_table一起使用的示例:

Your own implementation (fixed with improved naming)您自己的实现(通过改进命名修复)

or implement the lookup against your_dic yourself:或自己实现对your_dic的查找:

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

with this alternative function (you almost did):使用这个替代功能(你几乎做到了):

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

Preserving the alpha-channel (transparency)保留 Alpha 通道(透明度)

See the source-code of ImageColor.getColor() at the begin and end of its method body:请参阅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

(comments mine) (评论我的)

So you could simply set the fourth element of the returned color-tuple to the previous value of the original gray-scale image:因此,您可以简单地将返回的颜色元组的第四个元素设置为原始灰度图像的前一个值:

            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)

Note: because the A(lpha-channel) is provided from original image, I removed the A from the getColor invocation's last argument.注意:因为 A(lpha-channel) 是从原始图像提供的,所以我从getColor调用的最后一个参数中删除了A Technically, you can also remove the slicing from mapped_color[:2] to result in mapped_color + (greyscale[3],) .从技术上讲,您还可以从mapped_color[:2]中删除切片以mapped_color + (greyscale[3],)

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

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