简体   繁体   English

如何使用PIL将灰度转换为假色?

[英]How to turn grayscale into false color using PIL?

I can't seem to figure out how to take my grayscale function and change it to give me false color.我似乎无法弄清楚如何使用我的灰度函数并将其更改为给我假颜色。 I know I need to break each color (R,G,B) into ranges and then assign colors based on the range for each color.我知道我需要将每种颜色(R、G、B)分成多个范围,然后根据每种颜色的范围分配颜色。 Does anyone have any idea how this can work?有谁知道这是如何工作的?

def grayscale(pic):
    (width,height) = pic.size
    for y in range (height):
        for x in range(width):
            pix = cp.getpixel((x,y))
            (r, g, b) = pix
            avg = (r + g + b)//3
            newPix = (avg, avg, avg)
            cp.putpixel((x,y),newPix)
    return cp

Since you never answered my final follow-on question in the comments, I've made a few guesses and implemented something to illustrate how it might be done using only the PIL (or pillow ) module.由于您从未在评论中回答我的最后一个后续问题,因此我做了一些猜测并实现了一些东西来说明如何仅使用PIL (或pillow )模块来完成它。

In a nutshell, the code converts the image a grayscale, divides up the resulting 0% to 100% luminosity (intensity) pixel range into equally sized sub-ranges, and then assigns a color from a palette to each of them.简而言之,代码将图像转换为灰度,将产生的 0% 到 100% 亮度(强度)像素范围划分为大小相等的子范围,然后从调色板中为每个子范围分配一种颜色。

from PIL import Image
from PIL.ImageColor import getcolor, getrgb
from PIL.ImageOps import grayscale

try:
    xrange
except NameError:  # Python 3.
    xrange = range

def falsecolor(src, colors):
    if Image.isStringType(src):  # File path?
        src = Image.open(src)
    if src.mode not in ['L', 'RGB', 'RGBA']:
        raise TypeError('Unsupported source image mode: {}'.format(src.mode))
    src.load()

    # Create look-up-tables (luts) to map luminosity ranges to components
    # of the colors given in the color palette.
    num_colors = len(colors)
    palette = [colors[int(i/256.*num_colors)] for i in xrange(256)]
    luts = (tuple(c[0] for c in palette) +
            tuple(c[1] for c in palette) +
            tuple(c[2] for c in palette))

    # Create grayscale version of image of necessary.
    l = src if Image.getmodebands(src.mode) == 1 else grayscale(src)

    # Convert grayscale to an equivalent RGB mode image.
    if Image.getmodebands(src.mode) < 4:  # Non-alpha image?
        merge_args = ('RGB', (l, l, l))  # RGB version of grayscale.

    else:  # Include copy of src image's alpha layer.
        a = Image.new('L', src.size)
        a.putdata(src.getdata(3))
        luts += tuple(xrange(256))  # Add a 1:1 mapping for alpha values.
        merge_args = ('RGBA', (l, l, l, a))  # RGBA version of grayscale.

    # Merge all the grayscale bands back together and apply the luts to it.
    return Image.merge(*merge_args).point(luts)

if __name__ == '__main__':
    R, G, B = (255,   0,   0), (  0, 255,   0), (  0,   0, 255)
    C, M, Y = (  0, 255, 255), (255,   0, 255), (255, 255,   0)
    filename = 'test_image.png'

    # Convert image into falsecolor one with 4 colors and display it.
    falsecolor(filename, [B, R, G, Y]).show()

Below is a composite showing an RGB test image, the intermediate internal 256-level grayscale image, and the final result of changing that into a false color one comprised of only four colors (each representing a range of 64 levels of intensity):下面是一张合成图,显示了 RGB 测试图像、中间的内部 256 级灰度图像,以及将其更改为仅包含四种颜色(每种颜色代表 64 级强度范围)的假彩色的最终结果:

之前、中间和之后的图像

Here's another composite, only this time showing the conversion of an image that's already grayscale into the same palette of 4 false colors.这是另一个合成图,只是这次显示了将已经灰度化的图像转换为 4 种假色的相同调色板。

灰度到假彩色图像转换的例子

Is something like this what you're wanting to do?你想做这样的事情吗?

It looks like that all you want to do is to determine the average brightness per pixel, and make each pixel grey.看起来您要做的就是确定每个像素的平均亮度,并使每个像素变灰。 I would use either native Image functionality for that, or if you want to manipulate individual pixels, at least use numpy for that instead of a nested for loop.我会为此使用本机 Image 功能,或者如果您想操作单个像素,至少使用numpy而不是嵌套的for循环。 Example:例子:

from PIL import Image, ImageDraw
import numpy as np

def makeGrey():
    W = 800
    H = 600
    img = Image.new('RGB', (W, H))
    draw = ImageDraw.Draw(img)

    draw.rectangle((0, H * 0 / 3, W, H * 1 / 3), fill=(174, 28, 40), outline=None)
    draw.rectangle((0, H * 1 / 3, W, H * 2 / 3), fill=(255, 255, 255), outline=None)
    draw.rectangle((0, H * 2 / 3, W, H * 3 / 3), fill=(33, 70, 139), outline=None)

    img.show()

    pixels = np.array(img.getdata())
    avg_pixels = np.sum(pixels, axis=1) / 3
    grey_img = avg_pixels.reshape([H, W])

    img2 = Image.fromarray(grey_img)
    img2.show()

if __name__ == '__main__':
    makeGrey()

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

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