总目录:http://blog.csdn.net/iloveas2014/article/details/38304477
4.5.7 卷积矩阵的高级技巧及其原理
很多图形学教程或者书籍都习惯于在给出矩阵公式以后就直接列出几个常用的,并且看起来比较有趣的滤镜效果,这是“授之以鱼”的做法,而笔者更倾向于“授之以渔”,所以,我不打算沿用他们的套路,而是打算通过介绍算法技巧使笔者在阅读完本节之后可以学以致用,举一反三。
网上那些老掉牙的例子都比较倾向于用方阵,所以此处笔者打算先制作一个行数和列数不等的阵来制作效果,比如下面的代码就创建了一个15*1的模糊矩阵:
var con:COnvolutionFilter= new ConvolutionFilter(15, 1, [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], 15, 0, false);
这个卷积滤镜的运行结果如图 4.73所示,它只在x方向上模糊。可以看到比较明显的振铃现象。
图 4.73 15*1的矩阵
虽然它对于模糊来说并不友好,但这并不代表它一无是处,而且有时我们还更加希望振铃的感觉更加明显。
我们已经知道,振铃是模糊区域过大,轮廓出现交叉所致,那么,我们可以利用这一点加强这种振荡的效果:
var con:COnvolutionFilter= new ConvolutionFilter(15, 1, [1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1], 8, 0, false);
交叉读取周边像素,会使像素的交互产生跳跃式的融合,振铃现象得到进一步的增强,就像弹簧片或者橡皮条在振动一样(图 4.74)。
图 4.74 交叉融合的矩阵
这样的图虽然没啥美观度可言,但您可以把它放到一些趣味百科的专题网站,论坛或者微薄上给网民们普及振铃方面的知识,因为这张静态图可以使肉眼产生振动的错觉,有一定的奇妙之处。
言归正传,振动只引起x方向的模糊显得有点不自然,我们希望y方向也有一定程度的模糊,比如上下1像素,这时候我们就可以在现有基础上将其扩展为15*3的矩阵:
var con:COnvolutionFilter= new ConvolutionFilter(45, 1,
[1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
24, 0, false);
但可惜我们并没有如愿实现y方向模糊的效果,取而代之的是色彩的变淡(图 4.75)。
图 4.75 y方向扩展到3
原因很好找,就是因为中间像素点与左上方,右下方等位置的像素也进行了融合,所以结果显示出来会比原来模糊,但不设置上下方的像素,又无法在y方向上进行模糊,怎么办?
遇到这种两者相互冲突的情况,笔者最喜欢做的事情就是尽可能地把两个行为进行分离,避免让它们之间直接接触,此处我继续沿用此法,具体的实现自然就是多定义一个纵向的卷积滤镜了。
var con:COnvolutionFilter= new ConvolutionFilter(15, 1, [1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1], 9, 0, false);
var con2:COnvolutionFilter= new ConvolutionFilter(1, 3, [1, 1, 1], 3, 0, false);
main_txt.filters = [bev, con, con2];
得到的结果非常干净,如图 4.76所示。
图 4.76 将纵横两方向分离
如果觉得纵向模糊幅度太小,就可以将第二个卷积滤镜的高度调大一些,比如9:
var con2:COnvolutionFilter= new ConvolutionFilter(1, 5, [1, 1, 1, 1, 1], 5, 0, false);
得到的效果如图 4.77所示。
图 4.77 y方向继续拉长
矩阵的乘法将单像素通道间的数据有机结合在一起,而卷积更是充分调度了像素间的数据交互,增强了程序对色彩的可控性,给设计者提供了更广阔的发展空间,矩阵数学的艺术性再次得到了充分的体现。
ActionScript3游戏中的图像编程(连载九十三,第4章完)