python-3.x - 如何从颜色字典中快速更改图像中的像素?
问题描述
我有一张图像,我想从颜色图中更改图像中的所有颜色,例如。{(10,20,212) : (60,40,112)...}
目前,我正在读取图像 OpenCV,然后遍历图像数组并更改每个像素,但这非常慢。
有什么办法可以让我做得更快吗?
解决方案
对于这个问题,我提供了两个答案。这个答案更多基于 PIL/Pillow ,另一个更多基于OpenCV。结合我的其他答案阅读此答案,并可能混合搭配。
您可以使用调色板来完成。如果您不熟悉调色板图像,而不是在每个像素位置都有一个 RGB 值,您可以在多达 256 种颜色的调色板中使用一个简单的 8 位索引。
因此,我们可以做的是将您的图像加载为 PIL 图像,并将其量化为您拥有的输入颜色集。然后每个像素都会有你地图中颜色的索引。然后只需将调色板替换为您想要映射到的颜色。
#!/usr/bin/env python3
import numpy as np
from PIL import Image
def QuantizeToGivenPalette(im, palette):
"""Quantize image to a given palette.
The input image is expected to be a PIL Image.
The palette is expected to be a list of no more than 256 R,G,B values."""
e = len(palette)
assert e>0, "Palette unexpectedly short"
assert e<=768, "Palette unexpectedly long"
assert e%3==0, "Palette not multiple of 3, so not RGB"
# Make tiny, 1x1 new palette image
p = Image.new("P", (1,1))
# Zero-pad the palette to 256 RGB colours, i.e. 768 values and apply to image
palette += (768-e)*[0]
p.putpalette(palette)
# Now quantize input image to the same palette as our little image
return im.convert("RGB").quantize(palette=p)
# Open input image and palettise to "inPalette" so each pixel is replaced by palette index
# ... so all black pixels become 0, all red pixels become 1, all green pixels become 2...
im = Image.open('image.png').convert('RGB')
inPalette = [
0,0,0, # black
255,0,0, # red
0,255,0, # green
0,0,255, # blue
255,255,255 # white
]
r = QuantizeToGivenPalette(im,inPalette)
# Now simply replace the palette leaving the indices unchanged
newPalette = [
255,255,255, # white
0,255,255, # cyan
255,0,255, # magenta
255,255,0, # yellow
0,0,0 # black
]
# Zero-pad the palette to 256 RGB colours, i.e. 768 values
newPalette += (768-len(newPalette))*[0]
# And finally replace the palette with the new one
r.putpalette(newPalette)
# Save result
r.save('result.png')
输入图像
输出图像
因此,要使用将旧颜色值映射到新颜色值的字典来专门执行您所要求的操作,您需要初始化字典oldPalette
的键和字典newPalette
的值。
关键字:Python、PIL、枕头、图像、图像处理、量化、量化、特定调色板、给定调色板、指定调色板、已知调色板、重新映射、重新映射、颜色映射、映射。
推荐阅读
- c++ - 使用 set/multiset 查找以 's' 开头的单词
- python - 从某个类中获取所有文本,仅当它是另一个类的孩子时
- r - 如何将点与R中散点图中的一条线连接起来
- python - RuntimeError:无法在需要 grad 的变量上调用 numpy()。改用 var.detach().numpy()
- javascript - 一个处理完成后打开多个jQuery确认框
- java - 如何将多个图像的 downloadUrl 存储到 Firebase Firestore ?无法在 Firestore 文档内的多个字段中创建和存储
- regex - 查找不在另一个文本字符串中的文本?
- javascript - 比较嵌套的对象数组
- hadoop - Hadoop Namenode 和 Secondary Namenode 不以 PDSH 退出代码 1 开头
- algorithm - 如何通过图像处理方法提取分水岭的标记?