白噪声 高斯白噪声

使用2D矢量场的 LIC(line integral convolution ) 算法时,需要使用 白噪声图片 作为输入。查阅了相关资料。整理如下:

1. 白噪声的定义

  白光是所有颜色的光的叠加而成,不同颜色的光本质区别是他们的频率不同(如 红光频率低、紫光频率高)。与白光类似,白噪声功率谱密度上(若以频率为横轴,信号幅度的平方为功率(在纵轴上))分布为常值,即从高频到低频各种频率的噪声都有(从频域上考虑),也即每个时刻出现的噪声幅值都是随机的(从时域上考虑)。

2. 高斯白噪声的定义

高斯分布又名正态分布。(正态分布的概率密度函数曲线图,见 http://zh.wikipedia.org/wiki/File:Normal_distribution_pdf.png )

曲线的形状由两个参数决定:均值 和方差

    a. 均值公式:   。均值决定了曲线的对称中线;

    b.方差公式:。 方差决定曲线的胖瘦,即贴近中线的程度。

概率密度定义了信号出现的频率随幅值的变化情况,以信号幅值为横轴,以出现的频率为纵轴。因此,从概率密度角度来说,高斯白噪声的幅度服从高斯分布。

下面给出了图示说明:

(1) 白噪声

    功率谱:(y轴表示噪声值,已归一化至【0,1】区间。)           概率谱:

      

(2) 高斯白噪声

 功率谱:(未作归一化)                                                      概率谱:

   

参考:http://www.cnblogs.com/YoungHit/archive/2012/03/09/2388230.html

       http://wenku.baidu.com/view/b780020e52ea551810a6879b.html

       http://wenku.baidu.com/view/746669abd1f34693daef3e8c.html

 

代码 1.1. 使用乘同余法  生成 白噪声

/**************************
用乘同余法产生均匀分布白噪声(一串随机序列)。算法及程序实现叙述如下。
1) 在函数之外设定随机种子,随机序列为sequence,长度 n
2)  取 M =2^35,x = (A*x)mod M;e[i]= x/M ; 循环n次,得到均匀分布白噪声序列e[].该伪随机数的循环周期为2^(35-2)。
3) 实际实现中,将 e[i]= x/M ; 替换为 取ei的 小数部分 再赋值给ei+1,循环n次,就得到均匀分布白噪声序列;
*************************/
void whiteNoise(vector<double> &sequence,int n)
{
    int x = rand();
    int A = 3125;
    double M = pow(2.0f,35.0f);
    sequence.resize(n);
    double seed =double(x/M);
    sequence[0]= ( A * seed - int( A * seed ));//取小数部分
    double average = 0,serror=0; //统计均值、方差
    for (int i=1;i<n;++i)
    {
        sequence[i]=( A * sequence[i-1] - int( A * sequence[i-1] ));//取小数部分,获得均匀分布白噪声序列
        average+=sequence[i];
    }
    average/=n;//得到均值
    for(int i=0;i<n;++i)
    {
        serror +=(sequence[i]-average)*(sequence[i]-average);
    }
    serror/=n;//得到方差

    
    counter1.resize(pieceNum);//用vecotr<double> counter 进行概率统计,共分为 pieceNum 份 进行统计
    int max=0;
    for(int i=0;i<n;++i)
    {
        int index = sequence[i]/double(10.0f/pieceNum)+pieceNum/2;
        counter1[index]++;
        if(counter1[index] > max)
            max=counter1[index];
    }
    for(int i=0;i<counter1.size();++i)
    {
        counter1[i]/=(double)max;    //归一化
    }
}

代码 1.2. 使用 迭代取中法  生成 白噪声

/*************************************
 用迭代取中法产生均匀分布白噪声
***************************************/
void MakeWhiteNoise(vector<double> &sequence,int  n)
{        
        sequence.resize(n);
        for(int  j = 0; j < n;  j ++)
        {    
            int  r = rand();
            r = (  (r & 0xff) + ( (r & 0xff00) >> 8 )  ) & 0xff;//截取后8位
            sequence[j] = (unsigned char) r/(double)0xff;//归一化
        }

    counter1.resize(pieceNum);//用vecotr<double> counter 进行概率统计,共分为 pieceNum 份 进行统计
    int max=0;
    for(int i=0;i<n;++i)
    {
        int index = sequence[i]/double(10.0f/pieceNum)+pieceNum/2;
        counter1[index]++;
        if(counter1[index] > max)
            max=counter1[index];
    }
    for(int i=0;i<counter1.size();++i)
    {
        counter1[i]/=(double)max;    //归一化
    }
}

代码 2.1.  使用公式生成 高斯白噪声

/*************************
    先生成两个(0,1)间随机白噪声序列 sq1,sq2,再利用公式: c[i]=serror*(–2*log sq1[i])^0.5*cos(2*pi*sq2[i]) +average 循环n次
   计算得到均值和方差可任意调整的白噪声序列。
*************************/
void guassWhiteNoise(vector<double> &vdGuassSequence,int n,double average,double serror)
{
        //根据均值和方差得到调整后的白噪声序列
    vector<double> sq1,sq2;
    whiteNoise(sq1,n); //使用乘同余法
    whiteNoise(sq2,n);
    /*MakeWhiteNoise(sq1,n); //或使用迭代取中法
    MakeWhiteNoise(sq2,n);*/

    vdGuassSequence.resize(n);
    double average2 = 0,serror2=0;//均值、方差
    for (int i=0;i<n;++i)
    {
        if(sq1[i]!=0)
            vdGuassSequence[i]= serror* sqrt((-2) *log(sq1[i])) * sin( 2*PI* sq2[i])  +average;
        else
            vdGuassSequence[i]= serror* sqrt((-2) *log(0.0000001)) * sin( 2*PI* sq2[i])  +average;
        average2+=vdGuassSequence[i];
    }
    average2/=n;//得到均值
    for(int i=0;i<n;++i)
    {
        serror2 +=(vdGuassSequence[i]-average2)*(vdGuassSequence[i]-average2);
    }
    serror2/=n;//得到方差

    counter2.resize(pieceNum+1);//用vecotr<double> counter2 进行概率统计,共分为 pieceNum 份 进行统计
    int max=0;
    for(int i=0;i<n;++i)
    {
        int index = vdGuassSequence[i]/double(20.0f/pieceNum)+pieceNum/2;
        counter2[index]++;
        if(counter2[index] > max)
            max=counter2[index];
    }
    for(int i=0;i<counter2.size();++i)
    {
        counter2[i]/=(double)max;    //归一化
    }
}

posted on 2012-07-06 21:11  没有什么能够阻挡  阅读(3774)  评论(0编辑  收藏  举报

导航