| 
				 从技术上讲,为了得到类似于图1a中降雪效果,我们需要构造三层雪花图像,并且每一层的雪花数量、雪花大小、雪花的模糊程度都应该有所不同。雪花数量可以通过交互式参数进行设定,雪花大小可以通过随机函数进行随机分配,而雪花的模糊可以通过高斯模糊或者圆盘模糊算子进行滤波获得。此外,尽管在图1中几乎所有的雪花都是垂直于地面降落,这可能是因为当时没有刮风。但是,在风力的作用下雪花呈一定角度降落更常见。为了模拟这种效果,可以考虑使用动态模糊算子进行滤波。为了将高斯模糊及圆盘模糊和动态模糊区分开,我们称前两类模糊为静态模糊。 
有了上述考虑,我们就可以提出如下的飞雪场景合成算法: 
Step1:将一副不含飞雪的原始图像读入到内存中; 
Step2:为三个和原始图像大小相同的掩膜图像分配内存空间,这三个掩膜图像每一个分别对应着一层雪花图像,并且初始化为全0值。 
Step3:交互式为每一层雪花图像指定雪花点数、雪花大小、模糊半径、模糊方差、动态大小、运动方向等参数。其中雪花点数和雪花大小将用于控制雪花的密集度,模糊半径和模糊方差将用于控制雪花静态模糊的程度,动态大小和运动方向一方面控制雪花运动的方向,另一方面也控制雪花的动态模糊程度。 
Step4:根据Step3指定的雪花点数、雪花大小,对每一层内的每一朵雪花的位置和大小进行随机确定,然后根据模糊半径、模糊方差,通过使用高斯或者圆盘模糊算子进行滤波以获得静态模糊效果,最后根据动态大小、运动方向,通过使用动态模糊算子进行滤波以获得动态滤波效果。 
Step5:将三层雪花图像和原始图像进行融合,以得到最后的合成图像。 
在上述5个步骤中,Step1、2、3和5涉及到程序的界面编程,而Step4是飞雪场景合成算法的核心,它涉及到两个关键子程序,而这两个子程序都将被Step5中被调用。此外,在Step5中也有一个图像两两合成子程序。因此我们先介绍这三个核心子程序,然后在第3节结合界面编程技术一起介绍Step1、2、3和5。 
如Step4所述,首先应该对雪花团的位置和大小进行随机分配。为此,我们可以用随机函数rand来随机分配每个雪花团的中心点(row,col)位置和雪花团所占方形像素区域的半长xsize,然后将方形局部区域(row – xsize:row + xsize,col – xsize:col + xsize)设置为最大亮度值255,即可得到随机雪花团的初始图像。参考代码段1: 
%--------------------------------------------------------------------------------------------------------------------------------------- 
%代码段1 
function [maskImage] = sub_makeRandPoints(height,width,pointNumber,pointSize) 
%函数功能: 
%   对雪花的位置和大小进行初始分配,产生和原始图像大小相等的随机雪花团的初始图像 
%参数说明: 
%   输入参数: 
%     height:原始图像的高等 
%     width:原始图像的宽度 
%     pointNumber:用于控制雪花团的密集程度,值越大,雪花团越密集 
%     pointSize:最大雪花团的半长,和随机函数rand一起决定每个具体雪花团的大小 
%   输出参数: 
%     maskImage:保存随机雪花团的初始图像 
%-------------------------------------------------------------------------- 
    %生成一个和原始图像大小相等的雪花团初始图像,初始值全为0 
    maskImage = zeros(height,width); 
%对每个雪花团的中心点随机分配其行坐标和列坐标的位置。由于rand函数产生的随机数都是归一化 
%的,也即只产生[0,1]之间的随机数,因此在后面应该乘上高度或者宽度才能得到真正的行列坐标。 
    rowLocation = rand(1,pointNumber); 
    colLocation = rand(1,pointNumber); 
%对每个雪花团随机分配其团的大小,该值也是归一化的,在后面应该乘以pointSize以确定每个具体 
%雪花团的大小 
    rsize = rand(1,pointNumber); 
     
    %初始化for循环中的变量,以满足matlab使用JIT技术进行for循环加速 
    row = 0;%临时保存每个雪花团中心点的行坐标 
    col = 0;%临时保存每个雪花团中心点的列坐标 
    xsize = 1;%临时保存每个雪花团的半长 
    pointIter = 1;%for循环的迭代计数器 
    startRow = 0;%和stopRow一起确定每个雪花团的行坐标区域 
    stopRow = 0; 
    startCol = 0;%和stopCol一起确定每个雪花团的列坐标区域     stopCol = 0;			
				 |