水波纹效果

  最近花了点时间,把以前没做好的事情仔细整理了一下。一看时间,隔了有半年之久。惭愧惭愧。。。。其实以前都没有仔细考虑清楚到底是怎么样的事情,只是照着别人的思路把程序写下来而已,这几天重新做了几个实验,仔细考虑了一番。

  一、以前的BUG

  以前的结果中,图片中有一条横线,效果也感觉不对,其实是程序中的BUG。是在我的插值函数中:

1     uchar *data1 = imageWater.data + y[0]*imageWater.step + x[0]*imageChannels;
2     uchar *data2 = imageWater.data + y[0]*imageWater.step + x[1]*imageChannels;
3     uchar *data3 = imageWater.data + y[1]*imageWater.step + x[0]*imageChannels;
4     uchar *data4 = imageWater.data + y[1]*imageWater.step + x[1]*imageChannels;

  我是在imageInfo中存储原图片的数据,imageWater中用来存储变换过后的图片。显然在插值过程中,目标点周围四个整数点应该是取原图中的数据。所以应该将上述代码中的imageWater.data全部替换成 imageInfo.data。这次的效果图如下:

  

   这一次就没有中间那一条线,效果也比上一篇文章中的效果好多了。

   二、新的问题

  仔细观察右图你会发现,尤其是右下角,你会发现一些扭曲的纹路(其实是老师发现的),这是怎么产生的?其实我自己也不知道是不是应该出现这种情况。我开始的想法是:

  r' = r + a*sin(b*r) a,b 是合适的常数,r是当前点的半径。对于不同的r, 显然a*sin(b*r)的值是不一样的 。所以算出来的新图片中,有些点会比较密集,有些点会比较稀疏。

  接下来,我做了一张网格图,然后就会出现如下的效果:

  

 

  这个样子有点吓人,怎么会是这样?网格图比较复杂,那我就去做一张全部是半径的图,来看看效果:


  

  现在看起来,右图中的现象好像可以解释了,方框中的几个地方明显可以看出,点稠密和点稀疏的地方,直线最外面都断开了。那么中间的圆圈是怎么回事,是因为,越到圆心,每条直线之间的间隔就越来越小,有些点稠密的地方就连在了一起,形成一个圈。我最开始的想法看来是没有什么大问题的。

  那么那个网格图是怎么回事情呢?应该用下面的图说明问题比较好。

  

  最下面的点是圆心,A点距离圆心比较远,B点距离圆心比较近,假设在ra' = ra + a*sin(b*ra) 中 a*sin(b*ra)为正, ra'  >   ra,同理,rb' < rb。于是,原本是直线,经运算过后,变成了曲线。在网格图中,横向的直线跟纵向的直线叠加在一起,就造成了那样的效果。如果只存在纵向的直线,效果如下:

  

  为什么会出现这样的曲线,我觉得应该弄清楚了。

  三、总结

  之后,我再sin()函数里加了一个变量,制作出很多帧图片,合成一个视频。(优酷应该压缩了,与第一组图片对比,看着很模糊,将就看吧。)

  

  视频中,看起来有水波纹的样子,但是感觉效果还是不太好。

  其实,我把整个问题搞反了。正确的思考方式应该是,思考水波纹的图片是由原图怎么来得到的。思考每一个像素点应该怎么样移动,并由此推出一个公式,再来验证结果。也就是说,对于那样的网格图,我们应该先思考,怎么样才能变成水波纹的样子,然后推导出一个公式,来移动像素点,最后再来验证得到的是不是你想要的结果。

  对于上文的第二组网格图片,原图和结果图应该都是已知的,然后根据这两张图片,思考怎么样构造一个公式,将原图变成结果图。

  而现在重要的问题是,水波纹的结果图究竟应该是一个什么样子?然后我们才能下一步谈这么变换。对于这个问题,我表示不知道怎么下手。也许要去查阅物理知识,才能得到一个好的结果。

posted @ 2013-08-10 16:14  细胞核  阅读(3300)  评论(2编辑  收藏  举报