我有一个 RGBA 图像,我需要在保持平滑的同时进行升级。
要注意的是,我需要将颜色保持原样(背景:我正在调整各省用颜色编码的 map 的大小),所以我不能只使用双三次插值来执行调整大小,因为那样会还在平滑的同时插入像素颜色。
因此,为了获得平滑的边缘,我希望使用最近的邻居进行放大(给我阶梯图案),然后通过将目标图像中的每个像素替换为特定区域中最常出现的像素颜色来修整边缘半径,所以:
from PIL import Image, ImageFilter
amount=3
image=Image.open(<file>)
image=image.filter(ImageFilter.ModeFilter(amount))
这很快就完成了,只是它不起作用,因为 PIL 的 ImageFilters 在每个 channel 上单独运行。 握拳
我尝试求助于 numpy 数组并在循环中执行以下操作:
dest[x,y]=Counter([tuple(e) for e in reshape(source[max(x-r,0):x+r+1,max(y-r,0):y+r+1],(-1,4))]).most_common()[0][0]
请注意,这里的 dest 和 source 是相同形状的 XxYx4 数组,因此需要重新整形并转换为元组。
理论上这可行,但对于我正在操作的 8200 万像素 图像,需要 12 个小时才能完成。我推断这主要是由于不必要的类型转换和 reshape 开销。
在 Python 中执行此操作的合适方法是什么?
我正准备放弃并编写一个 C++ 模块来完成这项任务。
任何能引导我远离这条道路的东西都将不胜感激!
请您参考如下方法:
如果您关心图像中的一组固定颜色,“调色板”图像模式可能更合适(至少,如果您的 map 中的颜色不超过 256 种)。
我建议首先将您的图像转换为“P”模式(因为我不太熟悉 PIL,所以我不确定这有多容易。也许您必须先明确构建调色板?),然后应用模式过滤器。
我想到的另一个解决方案是在放大时简单地使用双三次插值,然后使用从原始图像派生的调色板转换为调色板图像。这可能会比您当前的方法产生更好的结果(并且更容易实现)。
