皮尔?提取给定 RGB 值的所有像素

Cal*_*eng 1 gdal python-imaging-library

给定一个图像(.tiff 或 geotiff 文件)正好有 22 种颜色(每种颜色都有一个不同的 RGB 值),有什么方法可以将它们分离(“过滤”)成 22 个单独的图像,每个图像只包含那些具有特定 RGB 的像素价值?

fra*_*xel 5

这是一种逐像素的方法,它可以用于图像中的任意数量的颜色(尽管对于许多颜色和大图像可能会变慢)。它也适用于调色板图像(它会转换它们)。

import Image

def color_separator(im):
    if im.getpalette():
        im = im.convert('RGB')

    colors = im.getcolors()
    width, height = im.size
    colors_dict = dict((val[1],Image.new('RGB', (width, height), (0,0,0))) 
                        for val in colors)
    pix = im.load()    
    for i in xrange(width):
        for j in xrange(height):
            colors_dict[pix[i,j]].putpixel((i,j), pix[i,j])
    return colors_dict

im = Image.open("colorwheel.tiff")
colors_dict = color_separator(im)
#show the images:
colors_dict.popitem()[1].show()
colors_dict.popitem()[1].show()
Run Code Online (Sandbox Code Playgroud)
  1. 调用im.getcolors()以元组形式返回图像中所有颜色的列表及其出现的次数,除非颜色数超过最大值(您可以指定,默认为 256)。
  2. 然后我们构建一个字典colors_dict,以图像中的颜色为键,并具有相应的空图像值。
  3. 然后我们遍历所有像素的图像,为每个像素更新适当的字典条目。这样做意味着我们只需要通读图像一次。我们使用load(),我们通过图像读取,使像素访问速度更快。
  4. color_separator() 返回一个图像字典,以图像中的每个唯一颜色为键。

为了使它更快,您可以load()对中的每个图像使用colors_dict,但您可能需要小心一点,因为如果图像有很多颜色并且很大,它可能会消耗大量内存。如果这不是问题,则添加(在创建之后colors_dict):

fast_colors = dict((key, value.load()) for key, value in colors_dict.items())
Run Code Online (Sandbox Code Playgroud)

并交换:

colors_dict[pix[j,i]].putpixel((j,i), pix[j,i])
Run Code Online (Sandbox Code Playgroud)

为了:

fast_colors[pix[j,i]][j,i] = pix[j,i]
Run Code Online (Sandbox Code Playgroud)

22色图像: 在此处输入图片说明

22 色隔离图像:

在此处输入图片说明 在此处输入图片说明 在此处输入图片说明 在此处输入图片说明 在此处输入图片说明 在此处输入图片说明 在此处输入图片说明 在此处输入图片说明 在此处输入图片说明 在此处输入图片说明 在此处输入图片说明 在此处输入图片说明 在此处输入图片说明 在此处输入图片说明 在此处输入图片说明 在此处输入图片说明 在此处输入图片说明 在此处输入图片说明 在此处输入图片说明 在此处输入图片说明 在此处输入图片说明 在此处输入图片说明