首页 > 代码库 > 动态计算背景噪声算法的实现讨论

动态计算背景噪声算法的实现讨论

当前背景噪声的计算方法

执行一次数据采集,以进行FFT计算和相关目标检测及航迹处理的过程,称为一次完整的数据处理过程,相应的数据称为一帧.这里讨论动态计算每一帧中某一点的背景噪声的计算方法及执行效率.

参考下图进行解释说明.当前想要计算第9个点(关注数据点)附近的背景噪声,背景保护单元宽度为2(图中的第7-8, 10-11点),背景计算单元为5(图中的第2-6,12-16点).

技术分享

第9个点的背景噪声值将由第2-6点,12-16点这左右对称的两组数据计算出来,例如取这两组数据之和的均值,或者取左右两组数据均值的较小值(或较大值).

背景保护单元内的数据将不用于计算被关注数据点的背景噪声,背景保护单元的大小受到产品的波形,配置参数,目标大小等多个因素的影响.

如果关注数据点较小,它左侧用于计算的背景单元数量不足指定的数据量时,仅依据它右侧的背景数据计算背景值;关注数据点较大,当它右侧用于计算的背景单元数量不足指定的数据量时,仅依据它左侧的背景数据计算背景值.

算法实现及改进

现有的实现方式

当计算某一个关注点的背景噪声时,分别求取它左侧和右侧的背景值的和,按照相关逻辑取得背景噪声值.例如想要计算第9个点的背景噪声,那么取一个变量,它等于第2~6点的数据值之和,取另一个变量,它等于第12~16点的数据值之和.然后这两个值之和除以10,即得到第9点的背景噪声值.

该方法的缺点是:每一个点的噪声值计算时,都需要在关注数据点的左右两侧分别做求和运算,求和的次数等于背景计算单元的宽度(例如这里等于5).一般我们需要按照顺序依次将所有的点作为关注数据点,设背景计算单元个数为BGCNT,数据总长度为DATAN,则总的求和次数大约为:

ADD_TIMES = 2×BGCNT×DATAN.

当BGCNT较大时(例如16/32),求和次数将按照线性递增.

改进的实现方式

系统维持两个变量,分别记录当前关注数据点的左侧背景噪声之和与右侧背景噪声之和.当向右移动关注数据点时,这两个背景噪声分别减去他们左侧已有的背景数据,增加右侧新的背景数据.相当于在数据排列的轴向上,指定的关注数据点两侧放置两个滑动窗口,这两个背景噪声和将依据窗口的滑动而增加或减少窗口内的边界噪声.

例如当前关注数据点为9,系统已经存有左侧窗口之和(2~6点数据噪声之和),和右侧窗口之和(12~16点数据噪声之和),现在想要改变关注数据点为10,那么它的左侧窗口之和将减去第2点的数据值,增加第7点的噪声值,它的右侧窗口之和将减去第12点的数据值,增加17点的数据值.这样就求得了第10点的左右噪声值.总的求和次数(含减法计算)大约为:

ADD_TIMES = 2×2×DATAN.

总的求和次数不会随背景单元个数而变化.

缺点:由于系统需要维护左右两个窗口的噪声值,所以不能随意指定关注数据点.一般的,按照顺序依次计算各个数据点的背景噪声,可完全满足现在的需求.

性能对比

使用以上两种方式分别对DATAN=512的浮点型数据(往往他们是原始AD数据经FFT处理之后的,这里是取随机数得到的)依次计算各个数据点的背景噪声,执行10000遍(在VS2010平台仿真).依据不同的背景单元个数,他们的耗时时长可绘制如下曲线:

 技术分享

 技术分享

由以上曲线可知,使用旧的实现方式,在背景单元个数小于4时,执行效率更高;大于等于4后,新的实现方式优势明显,且背景计算单元越多,优势约明显.

结论

一般的,背景单元个数达到或超过4个,采用新的实现方式,可提高执行效率,尤其在背景单元个数超过10个之后,新的实现方式优势巨大.当特殊情形下,我们设定的背景单元个数小于4个,那么可选择旧的实现方式.

附(代码) 

  1 /*----------------------------------------------------------------------------------------------------
  2 ----------------------------------------------------------------------------------------------------*/
  3 #define FFTN 512
  4 int MC_bg_cnt_wid=6; //背景单元个数.
  5 #define MC_bg_prot_wid 3 //背景保护单元个数.
  6 float dbuf[FFTN]={0.0};
  7 
  8 typedef struct{
  9     int cursn;
 10     float lsum;//left sum val;
 11     float rsum;//right sum val;
 12 }ST_BG;
 13 ST_BG g_bg={0, 0.0, 0.0};
 14 
 15 /*----------------------------------------------------------------------------------------------------
 16 使用新的方法计算背景噪声.
 17 ----------------------------------------------------------------------------------------------------*/
 18 float ComputeBg(int sn, float *datain)
 19 {
 20     int i, j, k, cursn, index;
 21     float ret;
 22     
 23     if(sn >= FFTN)
 24     {    return 0.0; // err!
 25     }
 26     if(0 == sn)
 27     {
 28         g_bg.cursn = 0;
 29         g_bg.lsum = 0.0;
 30         g_bg.rsum = 0.0;
 31         
 32         for(i=1; i<=MC_bg_cnt_wid; i++)
 33         {
 34             g_bg.rsum += datain[MC_bg_prot_wid+i];
 35         }
 36     }
 37 
 38     while(g_bg.cursn < sn)
 39     {
 40         cursn = g_bg.cursn+1;
 41         
 42         index = cursn-MC_bg_prot_wid-MC_bg_cnt_wid-1;
 43         if(index>=0)
 44         {    g_bg.lsum -= datain[index];
 45         }
 46 
 47         index = cursn-MC_bg_prot_wid-1;
 48         if((index<FFTN)&&(index>=0))
 49         {    g_bg.lsum += datain[index];
 50         }
 51 
 52         index = cursn+MC_bg_prot_wid;
 53         if(index < FFTN)
 54         {    g_bg.rsum -= datain[cursn+MC_bg_prot_wid];
 55         }
 56 
 57         index = cursn+MC_bg_prot_wid+MC_bg_cnt_wid;
 58         if(index < FFTN)
 59         {    g_bg.rsum += datain[index];
 60         }
 61         g_bg.cursn ++;
 62 }
 63     
 64     if(sn < MC_bg_prot_wid+MC_bg_cnt_wid)
 65     {//关注数据点较小,仅取右侧噪声.
 66         ret = g_bg.rsum/MC_bg_cnt_wid;
 67     }
 68     else if(sn < FFTN-(MC_bg_prot_wid+MC_bg_cnt_wid))
 69     {
 70         ret = (g_bg.lsum+g_bg.rsum)/(2*MC_bg_cnt_wid);
 71     }
 72     else if(sn < FFTN)
 73     {//关注数据点较大,仅取左侧噪声.
 74         ret = g_bg.lsum/MC_bg_cnt_wid;
 75     }
 76     else 
 77     {    ret = 0.0;
 78     }
 79     return ret;
 80 }
 81 
 82 /*----------------------------------------------------------------------------------------------------
 83 使用旧的方式计算背景噪声.
 84 ----------------------------------------------------------------------------------------------------*/
 85 float ComputeBg_old(int sn, float *datain)
 86 {
 87     int i, j, k;
 88     float lsum=0.0, rsum=0.0;
 89     float ret;
 90     
 91     if(sn >= FFTN)
 92     {
 93         return 0.0; // err!
 94     }
 95 
 96     if(sn < MC_bg_prot_wid+MC_bg_cnt_wid)
 97     {//仅计算右侧背景噪声.
 98         for(i=0; i<MC_bg_cnt_wid; i++)
 99         {
100             rsum += datain[sn+MC_bg_prot_wid+i+1];
101         }
102         ret = g_bg.rsum/MC_bg_cnt_wid;
103     }
104     else if(sn < FFTN-(MC_bg_prot_wid+MC_bg_cnt_wid))
105     {
106         for(i=0; i<MC_bg_cnt_wid; i++)
107         {
108             rsum += datain[sn+MC_bg_prot_wid+i+1];
109             lsum += datain[sn-MC_bg_prot_wid-MC_bg_cnt_wid+i];
110         }
111         ret = (lsum+rsum)/(2*MC_bg_cnt_wid);
112     }
113     else if(sn < FFTN)
114     {//仅计算左侧背景噪声.
115         for(i=0; i<MC_bg_cnt_wid; i++)
116         {
117             lsum += datain[sn-MC_bg_prot_wid-MC_bg_cnt_wid+i];
118         }
119         ret = (lsum)/(MC_bg_cnt_wid);
120     }
121     else 
122     {    ret = 0.0;
123     }
124     return ret;
125 }
126 #define REDOTIMES 10000 //重复执行次数.
127 /*----------------------------------------------------------------------------------------------------
128 ----------------------------------------------------------------------------------------------------*/
129 void CTestvc1Dlg::OnBnClickedButton1()
130 {
131     int i, j, k=0;
132     float fv, fv2;
133     long timespan;
134     time_t time0,time1, time2;
135 
136     UpdateData(true);//MFC工程更新输入的变量
137     MC_bg_cnt_wid = m_edit_bg_cnt;//用户通过MFC编辑框指定背景单元个数.
138 
139     time0 = GetTickCount();
140     srand(time0&0xffff); //随机数种子
141     for(i=0; i<FFTN; i++)
142     {
143         dbuf[i] = ((float)rand())/100.0;//获取随机数.
144     }
145     time0 = GetTickCount();
146     for(j=0; j<REDOTIMES; j++)
147     {
148         for(i=0; i<FFTN; i++)
149         {
150             fv = ComputeBg(i, dbuf); //使用新方法计算背景噪声.
151         }
152     }
153     time1 = GetTickCount();
154     for(j=0; j<REDOTIMES; j++)
155     {
156         for(i=0; i<FFTN; i++)
157         {
158             fv2 = ComputeBg_old(i, dbuf);//使用旧方法计算背景噪声.
159         }
160     }
161     time2 = GetTickCount();
162 m_edit_new_time = (long)(time1-time0);//新方法耗时时长.
163     m_edit_old_time = (long)(time2-time1);//旧方法耗时时长.
164     fv  = ((float)(time1-time0))/((float)(time2-time1));
165     m_edit_n = (int)(fv*100);//新方法耗时相对于旧方法的百分比.
166     m_edit_cnt++;
167     UpdateData(false);
168 }

附截图

技术分享

 

动态计算背景噪声算法的实现讨论