codebook码本算法

opencv学习笔记(四)——codebook算法

codebook算法从原理上讲仍然属于背景差分。他的背景建模有聚类的思想,他是用一个码本(codebook)cb来描述一个像素p,cb中包含着若干码元(code element)ce,这些ce就是该像素点p的一个聚类,码本算法背景建模的过程就是要构建像素的一个个聚类,即码本。

数据结构

typedef struct
{
code_element **cb;//码元的指针数组
int num_Enterties;//记录有多少个码元
int t;//记录该像素的当前时间
}code
_book;
typedef struct ce 
{
uchar learnHigh[NCHANNELS];//学习阀值
uchar learnLow[NCHANNELS];
uchar max[NCHANNELS];//码元吸收的像素点中最大像素值
uchar min[NCHANNELS];//同上,这两个阀值用于最后判断前景背景时使用
int t_last_update;//最后更新时间
int stale;//多久没有更新
int updated;
int f;//频数
}code_element;
(代码是learning opencv中的代码)

背景建模过程

码本算法的背景建模过程是一个统计的过程,即它会在建模阶段将某点出现的可能的像素值进行统计,根据其出现的某种特征属性,设定阀值进行判断,符合条件的像素值即可作为背景像素。
例如,要进行建模的帧数为5帧(为举例方便,一般建模应该在一秒以上,30帧左右,当然不是建模所用的帧数越多越好),在这5帧中相同的某点p(x,y),像素取值依次是pi =  {135,140,200,145,135}(此处假设所建模的对象是单通道的灰度图),那么在建模过程中,当第一帧像素值135到来时,由于p点对应像素值的码本没有码元,那么久新建一个码元,并为该码元赋值,设定code_element的各项属性值,第二帧到来后,140像素值会和已有的第一个码元进行匹配比较,在码元中有一对属性值learn_high和learn_low,这对属性值规定了该码元能“融合”的像素值范围,当满足条件135-learn_low < 140 < 135+learn_high时,即可将140像素融合,若不满足则为140像素新建一个码元,此处假设learn_high和learn_low均为10,那么可融合140,融合后更新该码元的一些数据,例如出现频数f要加1,stale最久未更新时间,他是最后更新时间t_last_update和当前时间t的差值,同理之后的第3、4、5帧按此过程,被融合或者新建码元,会发现只有像素200没有被融合,自己新建了一个码元。当匹配完后,就要进入下一个阶段——剔除噪声码元,剔除的依据是设定合理的阀值,若不满足条件则认为是噪声,剔除依据的属性可以使频数f或者最久未更新时间stale,或者是二者的组合条件,具体使用什么样的剔除方法,要根据自己想要的结果进行选择,此处设立条件为f > t/2,即如果一个码元的更新频数如果小于一半建模帧数就认为它是噪声,将其删除,即认为该码元出现的次数太少,不认为他是长时间保持稳定不变的背景像素。那么,经过剔除的码元即是可以合理描述背景的码元。
其他位置的像素点也是依照上述的方法,建立起合理的背景码元模型。

识别前景物体

差分背景。其实这一步,和建立背景模型中的匹配码元是一样的。将要检测的帧的像素和对应位置的背景模型的像素码元进行匹配,如果匹配则说明该点是背景点,如果不匹配则说明改点是前景点,就这么简单!


(learning opencv源码中有一处内存泄露的问题,还有一个剔除不适合码元规则选用不当的问题,希望正在学习的小伙伴多多交流!)















你可能感兴趣的:(目标检测,opencv,背景分离,codebook)