2012-02-10 64 views
2

我有一个RGBA图像,我需要在保持平滑的同时高档。在Python中的2D数组上滑动窗口中计算模式的最有效方法是什么?

问题是,我需要保持颜色完全按照它们的样子(背景:我正在调整省份颜色编码的地图的大小),所以我不能只用双三次插值执行调整大小,因为那样也会在平滑时内插像素颜色。因此,为了获得平滑的边缘,我希望使用最近的邻居(给予我的阶梯图案)进行高档放大,然后用目标图像中的每个像素替换最常出现在一定半径,一拉这样:

from PIL import Image, ImageFilter 
amount=3 
image=Image.open(<file>) 
image=image.filter(ImageFilter.ModeFilter(amount)) 

这就完成相当快,但它不工作,为国际私法的ImageFilters每个通道上分别操作。 甩头拳头

我试图诉诸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] 

注意,蒸馏水和源这里是相同的形状XxYx4阵列,因此必要的整形和转换成元组。
理论上这可以工作,但需要12小时才能完成8200万像素我正在操作的图像。我推断这主要是由于铸造和重塑不必要的开销。

什么是在Python中这样做的适当方式?

我准备抛出我的手并编写一个C++模块来完成这项任务。
任何引导我远离这条道路的东西将非常感谢!

+0

你见过这个吗?我之前不得不求助于内嵌的C++进行类似的图像处理任务,如果您正在寻找8200万像素的像素,这听起来像是一些C++繁重工作的优秀人选。 [PerformancePython](HTTP://www.scipy。org/PerformancePython) – Ancallan 2012-02-10 08:37:00

+1

通常,当我不得不加速对numpy数组的操作时,我试图找到一个聪明的方法让numpy处理所有的工作,或者使用python迭代器。我很难弄清楚你的第二个代码段中发生了什么。你能提供一个更小的数组的简单例子吗? – user545424 2012-02-10 18:26:42

+0

@Ancallan那个链接让人大开眼界。我将一些C放在一起并将其内联,实现了x500的加速。如果你的评论是一个解决方案,我会接受它。仍然有一个问题,我不得不依赖于有权访问scipy和编译器的人,但我想我可以忍受这一点! – megawidget 2012-02-12 10:08:37

回答

1

如果您关心图像中一组固定的颜色,“调色板”图像模式可能会更合适(至少,如果您的地图中没有超过256种颜色)。

我建议先将图像转换为“P”模式(由于我对PIL不是很熟悉,我不太确定,这很容易,也许你必须明确地构造调色板首先?),然后应用模式过滤器。

我想到的另一种解决方案是在升级后简单地使用双三次插值,然后使用从原始图像派生的调色板转换为调色板图像。这可能会产生比您目前的方法更好的结果(并且更容易实施)。

+0

唉,我有超过2000种颜色。 否则这个解决方案会很棒。 – megawidget 2012-02-10 19:26:25

-1

Image_scaling中描述的EPX没有引入新的颜色。 Scale 2x这样做:

A --\ 1 2 
C P B --/ 3 4 
    D 

IF C==A => 1=A 
IF A==B => 2=B 
... 

和scale3x也在那里描述。
除此之外,我同意“直奔C” - 取决于你所知道的。 有没有人用过np_inline

相关问题