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

当前背景噪声的计算方法

执行一次数据采集,以进行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 }

附截图

时间: 2024-11-05 16:30:30

动态计算背景噪声算法的实现讨论的相关文章

万年历算法的实现(C语言--gcc编译)

/** cal.c * * 现行的格里历是从儒略历演化而来的.儒略历每4年一个润年,润年366天,平年365天.* 如果从公元1年算的话,那么凡是能够被4整除的都是润年.从天文角度看,儒略历这种 * 历法是有误差的,到16世纪误差已经达到了10天.1582年,罗马教皇对儒略历进行了 * 一次校定,该年的10-5到10-14这10天被抹掉,并规定凡不能被400整除的世纪年不再 * 算为润年,校定之后的儒略历即为现行的格里历. * * 但是英国直到1752年才开始使用格里历,此时时间误差已经达到了1

探讨排序算法的实现

排序算法是我们工作中使用最普遍的算法,常见的语言库中基本都会有排序算法的实现,比如c标准库的qsort,stl的sort函数等.本文首先介绍直接插入排序,归并排序,堆排序,快速排序和基数排序等比较排序算法,然后介绍计数排序,基数排序等具有线性时间的排序算法.本文主要讨论算法的实现方法,并不会过多介绍基本理论. 评价一个排序算法优劣适用与否,一般需要从三个方面来分析 时间复杂度.用比较操作和移动操作数的最高次项表示,由于在实际应用中最在乎的是运行时间的上限,所以一般取输入最坏情况的下的运行时间作为

动态计算UITableViewCell高度详解 (转)

感觉挺有用的一篇文章,分析了4种解决方案.回头测试之.如果有别的方案,我会在后面补上. 原文地址:http://www.ifun.cc/blog/2014/02/21/dong-tai-ji-suan-uitableviewcellgao-du-xiang-jie/ 不知道大家有没有发现,在iOS APP开发过程中,UITableView是我们显示内容常见的控件,本人觉得它是UIKit中最复杂的一个控件.今天要向大家介绍的就是如何动态计算UITableViewCell高度的一经验与技巧,在此做一

Bug2算法的实现(RobotBASIC环境中仿真)

移动机器人智能的一个重要标志就是自主导航,而实现机器人自主导航有个基本要求--避障.之前简单介绍过Bug避障算法,但仅仅了解大致理论而不亲自动手实现一遍很难有深刻的印象,只能说似懂非懂.我不是天才,不能看几遍就理解理论中的奥妙,只能在别人大谈XX理论XX算法的时候,自己一个人苦逼的面对错误的程序问为什么... 下面开始动手来实现一下简单的Bug2避障算法.由于算法中涉及到机器人与外界环境的交互,因此需要选择一个仿真软件.常用的移动机器人仿真软件主要有Gazebo.V-rep.Webots.MRD

Canny边缘检测算法的实现

Canny原理 Canny的原理就不细说了,冈萨雷斯的<数字图像处理>(第三版)P463~465讲解的比较清楚,主要就四个步骤: 1. 对图像进行高斯滤波 2. 计算梯度大小和梯度方向 3. 对梯度幅值图像进行非极大抑制 4. 双阈值处理和连接性分析(通常这一步与非极大抑制并行,详见下面的代码) 下面重点说一下非极大抑制. 非极大抑制 对一幅图像计算梯度大小和梯度方向后,需要进行非极大抑制,一般都是通过计算梯度方向,沿着梯度方向,判断该像素点的梯度大小是否是极大值.这里主要说一下方向的判断.

数组正负元素前后移动算法的实现(以0为分界线)

mnesia在频繁操作数据的过程可能会报错:** WARNING ** Mnesia is overloaded: {dump_log, write_threshold},可以看出,mnesia应该是过载了.这个警告在mnesia dump操作会发生这个问题,表类型为disc_only_copies .disc_copies都可能会发生. 如何重现这个问题,例子的场景是多个进程同时在不断地mnesia:dirty_write/2 mnesia过载分析 1.抛出警告是在mnesia 增加dump

通用固定长度编码格式的字符串查找算法的实现

通用固定长度编码格式的字符串查找算法的实现 字符串的查找是数据库应用中必不可少的操作,而且每种数据库产品(ORACLE.DB2.SYBASE.MS SQL SERVER.MYSQL等等)也都提供了对应的字符串处理函数,比如DB2的LOCATE函数. 但在实际的工作中,还是会遇到一些特殊情况的处理,这使得直接使用字符串查找函数,得到的结果可能是错误的,比如本文中提到的固定长度编码格式的字符串的查找.值得注意的是,本文提出的算法可以稍加修改即移植到其它关系数据库系统或者前端开发工具中. 在实际数据库

还能输入多少字?(JS动态计算)

<div class="m-form ovh"> <div class="hd"> <span class="fr" id="message">还能输入200个字</span> 我要说: <select name="select" id="select"> <option value="12">北

最小生成树之Prim算法的实现

Prim算法的思想是,首先从任意一个节点出发,逐渐生成,直至该树覆盖了所有的V中的节点. 如下图: 图中的黑色的边即是最小生成树中的边. 实现Prim算法的关键便是,如何选择一条 "权值较小并且对于已有生成树中的点集合S来说是安全的边",此处的安全指的是: 加入该边e之后,S仍然是一个树. 于是:对于图 G = (V, E) Prim的执行步骤大致为: 1   从任意节点r开始,因此将原来的顶点集合分为两部分: S = {r}, T = V-{s}, 2   计算T中的节点到S中的节点