二维噪声图像

本文最初于2012年12月9日发布于http://blog.csdn.net/johnhany/article/details/8273375   转载请注明出处

        将由随机数函数产生的随机序列赋值为二维或三维坐标,就得到了平面上或空间上的噪声。然后,就可以用折线或曲线连接这些点,获得形状不规则的曲线或曲面,以此获得图像。通过这种方法,可以模拟山脉、石块表面、云朵(虽然可以用分形图像来更好地模拟它们,但相对于比较深奥的数学背景,基于随机噪声的方法显然更便于使用),或者绘制贴图(木纹、迷彩等等)。

噪声和插值

        噪声可以由伪随机数发生函数产生,我们可以直接使用rand()库函数,也可以自己编写(关于伪随机数发生函数,请参考我的另一篇文章:《伪随机数生成算法及性能检验》)。

random_points

        有了一系列离散的随机点,我们需要将它们连续化,因为相邻的点高度相差一般比较大,我们需要利用它们来表明图像的特征。如果是模拟石块的表面,只要用折线将随机点依次连接就好了。但是对于像云朵这样的比较光滑的图像,就需要一条贯穿每点的曲线,这就是插值曲线。

fragment_lines

        插值曲线可以基于多项式函数、余弦函数等等,为了提升计算速度,我在这里使用Cubic插值:

        这个函数是用V0,V1,V2,V3四个点的坐标画出V1,V2之间的曲线。参数x取值0-1,取0时落在V1点上,取1时落在V2点上。所以注意在整条曲线的两端是有两个点不在曲线上的。

cubic_curve

        在x,y两个方向上使用Cubic插值,就可以得到一个曲面。

噪声图像

        我们建立一个(M+2)*(N+2)的随机数数组,以此获得一个二维的插值,把高度值缩放到[0,1]的范围内,代表灰度,就得到了一幅噪声图像。

noise_image

        局部放大:

noise_image_zoom

题外话
        其实,如果是自己编写的随机函数而不知道自己的函数性能怎样时,可以利用它产生一幅这样的图像,寻找图像中有没有循环重复的模式。如果你的函数是以时间生成种子,通过观察一段连续时间产生的图像可以发现,你的图像在平移!此时你会更深刻地体会到伪随机数其实是一列看似混乱实则固定的序列。

        为了获得更好的噪声图像,可以使用倍频方法,就是用大小比例不同的噪声图像叠加获得一幅单独的噪声图像。
        我把上面获得的噪声图像放大至2倍、4倍,再与原图像叠加,获得下面的噪声图像:

noise_image_layered

产生其他图像

        如果把上面的图像描述为noise(x,y),则f1(x,y)=noise(x,y)*20-int[noise(x,y)*20]可以绘制类似木纹的图像:

noise_image_wood

        如果对噪声图像的灰度作截断:

        再把具有不同颜色的不同倍频的图像叠加,可以得到类似迷彩的图案:

noise_image_color

        如果将噪声图像沿一个方向拉伸,可以得到类似布料皱褶的图形:

noise_image_cloth

参考资料:

http://freespace.virgin.net/hugo.elias/models/m_perlin.htm(一篇英文的关于柏林噪声的文章)
http://freespace.virgin.net/hugo.elias/models/m_clouds.htm(一篇英文的关于云模拟的文章)

 

您将是第一位评论人!

订阅评论