sle*_*nja 19 c c++ image-manipulation image image-processing
什么是我可以用来将图像分成原始大小一半的最佳重采样算法.速度是最重要的,但它不应该降低质量太差.我基本上试图生成图像金字塔.
我本来打算跳过像素.这是最好的方式吗?从我所看到的,像素跳过产生的图像太尖锐了.有人试过这个评论.我的图片包含这样的地图数据.
Mar*_*som 29
跳过像素将导致混叠,其中高频变化(例如交替的亮/暗带)将转换为低频(例如恒定亮或暗).
在没有混叠的情况下缩小到一半的最快方法是将2x2像素平均为单个像素.使用更复杂的还原内核可以获得更好的结果,但它们将以牺牲速度为代价.
编辑:以下是目前讨论的技术的一些例子.
跳过所有其他像素 - 通过查看左侧的图例,您可以看到结果不是很好.这几乎是不可读的:

平均每2x2网格 - 文本现在清晰可读:

高斯模糊,正如R.所暗示的那样- 有点模糊,但更具可读性.可以调整模糊量以产生不同的结果:

R.对于影响结果的Gamma曲线也是正确的,但这应该只在最苛刻的应用中可见.我的例子没有伽马校正.
对于缩小尺寸,区域平均(参见Mark的答案)接近您将获得的最佳值.
主要的另一个竞争者是高斯,半径略大.这会稍微增加模糊,这可能被视为一个缺点,但会使模糊更均匀,而不是依赖于像素mod 2的对齐.
如果我不清楚我的意思,请考虑像素模式0,0,2,2,0,0和0,0,0,2,2,0.通过面积平均,它们分别缩小到0,2,0和0,1,1 - 也就是说,一个将是锐利和明亮的,而另一个将是模糊和暗淡的.使用更长的过滤器,两者都会模糊,但它们看起来会更相似,这对人类观察者来说很重要.
需要考虑的另一个问题是伽玛.除非伽马是线性的,否则两个强度像素的k总强度将比单个强度像素小得多2*k.如果你的过滤器表现出足够的模糊,那么它可能并不重要,但是使用普通的区域平均过滤器可能是一个主要问题.我知道的唯一解决方法是在缩放之前和之后应用和反转伽马曲线......
如果速度是一个问题,如上所述,我建议采用 2x2 块并计算平均值作为结果像素。质量不是可以达到的最好,而是接近。您可以激发此算法以显示其弱点,但在大多数图像上,您不会看到可以证明计算时间高很多倍的差异。您也没有任何内存开销。如果每个通道的颜色分辨率可以降低到 6 位,那么这里有一种非常快速的方法可以防止您分解 ARGB 通道(这里假设为 32 位 ARGB):
destPixel[x,y] = ((sourcePixel[2*x ,2*y ]>>2)&0x3f3f3f3f) +
((sourcePixel[2*x+1,2*y ]>>2)&0x3f3f3f3f) +
((sourcePixel[2*x ,2*y+1]>>2)&0x3f3f3f3f) +
((sourcePixel[2*x+1,2*y+1]>>2)&0x3f3f3f3f);
Run Code Online (Sandbox Code Playgroud)
这种算法的副作用是,如果保存为 PNG,文件大小会变小。这是它的样子:
