图形图像处理-之-误差扩散 下篇 - 更快的速度或更好的效果

                         图形图像处理-之-误差扩散 下篇 - 更快的速度或更好的效果
                                
HouSisong@GMail.com   2010.01.05

 

(2010.01.06 补充误差扩散算法并行化的一些探讨 )

 

tag: 误差扩散,真彩色到高彩色转换,色阶,减色,半色调
  
摘要: 在图像的颜色转换过程中,由于颜色值域的不同,转换过程中可能会产生误差;
误差扩散算法通过将误差传递到周围像素而减轻其造成的视觉误差。
上篇:简单实现; 中篇:简单的速度优化; 下篇: 更快的速度或更好的效果.

 

(测试源代码下载: https://github.com/sisong/demoForHssBlog )


正文:
  代码使用C++,编译器:VC2005
  测试平台:(CPU:i7-920(3.44G); 内存:DDR3 1333(三通道); 编译器:VC2005)
  
(请先参看文章的上篇和中篇)

 

A:更快的速度
前面的文章用使用的误差传递系数为:
  * 2
1 1 0    /4
为速度和质量做了折中;而在某些应用场合下,可能希望更快的实时进行误差扩散;
这时可以考虑这样的误差扩散系数:
  * 1
0 1 0    /2
甚至于:
  * 1    /1
这时误差只用传递到右边,实现起来就简单多了:

 

速度测试:
//
//CvsPic32To16_ErrorDiffuse_fast   422.83  FPS
//


效果(比前面的差一些了):


简单改写成MMX实现:

 

速度测试:
//
//CvsPic32To16_ErrorDiffuse_MMX    662.98  FPS
//


效果:


 

B:更好的效果  

为了优化颜色转化效果,一般用半色调技术来优化输出;
这些技术中误差扩散算法一直是效果最好的技术之一;
我们来实现经典的Floyd-Steinberg误差扩散系数,

 

速度测试:
//
//CvsPic32To16_ErrorDiffuse_fs    198.81  FPS
//


看看效果:

 

放大对比这几幅图,注意看看细节;

误差扩散算法还原效果很好,但有一个缺点,就是容易产生局部细纹;

误差扩散形成的一些颗粒组成了某些可见的小纹理(因为固定的扩散模板系数);

要克服这个问题,可以考虑一些改进方案或其组合:

a.随机调整阈值,从而在计算最接近的颜色的时候有一定的随机性;

b.建立一个较大的扩展系数表,根据当前的误差值选择定不同的扩展模板;

c.根据已经处理的颜色的误差情况,动态调整模板系数;比如当前点上面的点误差较大,那么就减小向下面的扩展系数值 (或者把按误差大小逆序);

或者据此做一定的阈值调整;

d.可以考虑一个后处理局部纹理的迭代过程: 先做一遍误差处理,然后对处理完的满足一定的条件的点做一些值反转,从当前值(比如亮度增大了)变成对应的阈值(亮度减小),(可以同时处理两个相邻值,它们一个变亮,一个变暗),反转条件是是否更有利于还原原图像,评价模型可以选择高斯值/梯度等手段(或其他评价模型);

e.有时如果目标颜色色域和当前颜色色域范围差别大,可以考虑先进行一个色域的线性映射,以牺牲颜色还原来维持较好的整体对比度;

f.某些时候如果目标颜色表很小时(比如彩色转成黑白2色),可以先对图片做一些锐化/边缘增强和局部对比度增强,这样得到的效果更好;

g.某些时候,扩散结果,亮度还原/梯度还原/对比度还原等可能比颜色还原更重要;

 

 

一个较复杂算法的处理效果图,请对比这些效果图的整体和放大后的细节:

(用我写的一个简单工具生成的,输出用了其中的555颜色输出模式,这里可以下载该程序:  http://bbs.meizu.com/thread-1440271-1-1.html

该工具用于预处理图片,优化其在不支持真彩色显示的设备上的显示效果; )

 

 

 

 另一个例子,将图片转换到一个较小的固定颜色表:

源图片:

优化的误差扩散,颜色还原优先:

 

考虑视觉模型误差扩散 亮度还原优先 (效果好了很多):

 

把梯度还原作为最优先:  (很有艺术感的图片:),并注意其光滑性!   没有见过其他人实现,应该属于原创)

 

C: 并行误差扩散算法的探讨

    误差扩散一般的算法都是一行一行从上到下依次处理;算法本身是不太适合并行的(除了 * 1  /1 模板支持行之间无影响的并行);   

    有些建议说每个处理核心延迟一下,接着上一个处理核心启动处理下一行,就能满足并行要求了;但实际情况是,CPU并不能按时按量准时完成(多任务操作系统);下一行的核心很可能超过上一行的处理进度,从而处理失败;如果为了保证处理进度,而增加一些锁,也不是很好,代码复杂,而且随着核心越来越多,还可能反而变慢! (而且GPU具有比CPU多得多的的并行核心)

    a.如果对质量要求不高,可以考虑将图片分成很多块交给多个核心并行处理;处理完以后可以考虑对边界做一点特殊的修正处理;

    b.按固定的区块大小将图片分成多个区,这样的话区块间是可以完全并行的;对区块内的各个点设置一个固定的处理顺序和不同的扩散系数方向,

利用处理顺序和系数方向,可以设计出几个批次,每个批次内点的处理顺序无关;  这样就能提够足够的并行性了;

    c.思考中的一个迭代算法,主要用在有很多个核心的系统上(比如GPU上),每个点启动一个核心(最大的并行粒度), 算法将周围点的误差值*系数(可能随迭代变动)+当前值作为输入值,根据某个视觉模型生成最佳的目标值(下次迭代中的当前值)和新的误差值(输入值=目标值+误差值); 几次迭代以后或视觉模型差值小于某阈值以后停止迭代; (该算法没有试验过)

  • 1
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值