摘 要:介绍了一种采用CPLD外加SRAM存储芯片,对ITU601格式数字视频信号进行运动检测的方法。在此基础上,给出了一个实现这种检测方法的例子。在这个例子中,用Philips公司的视频处理芯片SAA7113的输出信号作为数字视频源,用Lattice公司的CPLD芯片LC4128V对视频信号进行运动检测。
关键词:运动检测 CPLD 数字视频信号
在数字录像、数字监控等领域内,人们通常只对场景内存在的物体运动感兴趣。在这种情况下,需要对输入的视频信号进行预处理,识别场景中是否存在物体运动,也就是进行运动检测,然后再决定是否做进一步的处理,例如录像、报警等。对于录像系统,通过运动检测,能够避免不必要的数字录像,有效地减少系统所需存储空间;同时可以加快检索速度,提高资料有效性。对于监控系统,运动检测是一种监视场景信息的有效手段。
很多数字视频信号处理系统通常会选用DSP芯片作为主处理芯片。由于DSP对数字信号的处理是通过编程实现各种算法的,只通过软件就可以方便地加入某些功能,因此没有必要添加额外的硬件来完成运动检测。但是有很多系统,由于各种原因需要选用其它芯片来完成视频信号的处理,例如华邦的W9968x系列芯片,由硬件完成信号的处理,其算法已经被固化在芯片的内部电路中,不能随意更改。这一类芯片功能比较单一,但速度快、价格便宜,通常可以作为某些系统的专用芯片。对于这种情况,就需要考虑用另外的方法来实现运动检测。本文介绍的用CPLD进行运动检测的方法就是针对这一类情况的。该方法是通过附加一片CPLD芯片和一片SRAM芯片构成一个低成本的运动检测模块的。
1 运动检测原理
运动检测的实现方法有硬件实现的也有软件实现的,但基本思想大同小异,都是对相隔一定时间的两帧视频数据进行抽样,并对抽样数据进行比较,如果比较结果显示这两帧数据存在比较大的差异,那么就认为数据输入场景中存在物体的运动,反之就认为没有运动存在。
本文介绍的用CPLD实现运动检测的方法也是基于这种思想,但和一般的实现方法有所不同,其实现方法有一定的特色。
通常情况下,在实现上述思想的过程中,需要两个缓存区分别存放两帧抽样数据,然后对这两帧数据进行比较并对比较结果进行统计,最后得出比较结果。这样做需要较大的SRAM作为缓存,而且往往需要单片机或者DSP对CPLD进行控制,并将其作为两帧数据的比较器。这样,运动检测模块的独立性会受到限制,而且CPLD的功能只是一个抽样控制器。
本文提出的方法只对一帧抽样数据进行缓存,在对第二帧数据进行抽样时读取第一帧中与此刻抽样的数据相对应的缓存数据,并将两者进行比较,用一个计数器记录比较结果,如果差值超过阈值,计数器加一,否则不加。当这个计数值超过某一个规定数值的时候,就认为输入视频数据中存在着物体运动。这样做的好处是需要的缓存区较小,而且CPLD可以单独对数据进行处理,提高运动检测模块的独立性,运动检测模块可以单独调试。
2 用CPLD实现运动检测
下面通过实例说明用CPLD实现运动检测的过程,并给出部分VHDL程序。在这个实例中,模拟视频信号从CCD摄像头输入,经过SAA7113芯片预处理后,输出数字视频信号。该信号分作两路:一路输入到CPLD进行运动检测,另一路则输入到芯片W99682,对信号进行JPEG压缩等进一步处理。
示例中用到的CPLD是Lattice公司的LC4128V-75T100C,它具有128个宏单元、7.5ns的延时。SRAM芯片是ISSI公司的63LV1024,其容量为128K×8bit,具有10ns的延时。CPLD检测到运动后,通过中断,要求W99682对信号做进一步处理。其系统结构图如图1(省略了部分与运动检测无关的元件)所示。
2.1 SAA7113的输出信号
SAA7113是Philips公司推出的一款功能强大的视频信号预处理芯片,最基本的功能是模/数转换,输出的数字视频信号符合ITU601标准。ITU601是长宽比为4:3和16:9的数字电视信号标准,它对数字电视信号的各项参数进行了详细的描述和规范。在我国,通常采用的都是4:2:2采样格式、PAL制式、长宽比为4:3的数字电视信号。SAA7113的输出信号就是指这一格式的信号。这种格式信号的主要特征是:
(1)有三个正交分量:亮度分量Y、色度分量Cb和Cr。
(2)25帧/秒的帧率,每帧两场,每帧扫描625行。
(3)对于亮度分量Y,每行抽样864次,对于色度分量Cr和Cb,每行抽样432次。
(4)8bit或者10bit的PCM编码。
(5)量化:0和255用于同步;1到254表示抽样结果的PCM码;对于亮度分量Y,16表示黑色,235表示白色;对于色度分量Cb或者Cr,128表示没有色度。
(6)有三个信号用于同步输出数据:行同步信号SHS(15.6kHz)、场同步信号SVS(50Hz)和象素数据同步信号SPCLK(27MHz)。
包括消隐期在内,每帧数据扫描625行,每行抽样864个象素,因此总的分辨率是864×625。一帧数据分作奇偶两场,从上一帧的624行到本帧的310行是奇场,其中上帧624行到本帧22行是奇场消隐期,从23行到310行是奇场有效行;从本帧311行到623行是偶场,其中311到335行是偶场消隐期,336到623行为偶场有效行。图2是一帧的示意图。
对于帧内的每一行,共有864个象素,其中从第0个到第719个为有效象素,共计720个,从720个到863个为消隐期象素。每个象素都抽取Y分量,每两个象素则抽取一个Cr和一个Cb分量。图3是帧内一行以及象素抽样数据排列格式的示意图。表格第一行是亮度分量Y,第二行是色度分量Cr,第三行是色度分量Cb。
2.2 抽样
从SAA7113视频输出数据格式的介绍可以看到,保存完整的一帧数据(包括消隐期数据在内)需要864×625×2=1.08×106Byte的SRAM,需要1M以上的存储空间,这显然是不可取的,必须对帧数据进行抽样。本文介绍的方法的抽样规则如下:
(1)抽取一帧数据的奇场或者偶场。做比较的两场抽样数据必须取自相同的场次,或者同为奇场或者同为偶场,否则就没有可比性。
(2)对连续的8帧抽取第2帧和第8帧进行比较。被抽样的两帧之间必须有一定的时间间隔,间隔太短或者太长都会影响检测的灵敏度。
(3)对一场数据抽取有效行中的奇数行,从场同步信号有效边沿开始对行同步信号计数,直到下一个场同步信号为止。从23行到310行是有效行,共144个奇数行。
(4)对被抽取的行,取其亮度分量Y。根据图3中象素数据的排列顺序,从象素数据有效开始,偶数的象素数据脉冲同步的是亮度分量Y。
对于以上的抽样规则,有必要说明一下。最终的抽样数据并非全部都是有效数据,其中还包括了一部分消隐期的数据。这样做是可以理解的,因为运动检测的结果是根据两帧被抽样数据的差值来判定的,虽然消隐期的数据是无效的,但是每次消隐期的数据是相同的,两次抽样数据相减结果是零,并不会影响结果的判定。之所以对一场的行进行抽样,主要是为了减小抽样数据量,使数据总量不超过128K SRAM的容量。
如果要保证抽样数据全部都是有效数据,那么必须利用输入的象素数据同步脉冲SPCLK、场同步信号SVS和行同步信号SHS对抽样时刻做严格的同步。这需要消耗额外的CPLD资源,而效果却不一定好。
根据以上规则,实际抽样的数据量为:864×144=124416Byte,需要的SRAM容量为128K。
2.3 程序
下面给出实现以上过程的一部分VHDL程序。
sram_write_control:process(store_field,valid,spclk2,line_counter)
begin
writing<=valid and spclk2 and spclk and store_field and line_counter(0);
end process;
sram_read_control:process(compare_field,valid,spclk2,line_counter)
begin
reading<=valid and compare_field and spclk2 and line_counter(0);
end process;
这两个进程用于控制SRAM的读写信号,reading和writing正好和SRAM的读写信号反相。Valid变量指示当前输入的行是否为需要采样的有效行,spclk是象素数据同步脉冲,spclk2是它的二分频,用于指示当前输入数据是否为亮度分量Y。line_counter(0)=1表示奇数行。store_field和compare_field分别指示本场数据是否需要保存或者需要比较。
update_data_bus:process(store_field,valid,ccd_data)
begin
if(store_field=‘1’and valid=‘1’)then
data_sram<=ccd_data;
else
data_sram<=“ZZZZZZZZ”;
end if;
end process;
在抽样第一帧数据的时候,直接把数字视频信号输入到SRAM的数据总线上,写操作信号由writing控制。其它时候,数据总线上输出高阻。
update_data_reg:process(spclk,ccd_data,spclk2,compare_field,
valid,data_sram)
begin
if(spclk'event and spclk=‘0’)then
if(compare_field=‘1’and valid=‘1’and spclk2=‘1’)then
data_sram_reg<=data_sram;
if(ccd_data<=threshold)then
data_reg1<=“00000000”;
data_reg2<=ccd_data+threshold;
elsif(ccd_data>=255-threshold)then
data_reg1<=ccd_data-threshold;
data_reg2<=“11111111”;
else
data_reg1<=ccd_data-threshold;
data_reg2<=ccd_data+threshold;
end if;
end if;
end if;
end process;
SAA7113的象素同步脉冲的下跳边沿是象素数据的有效边沿,进程在compare_field=1时,一方面把抽样数据读入,用寄存器保存用于比较的数据的上限和下限;另一方面从SRAM读入对应数据存入寄存器data_sram_reg,这两个操作为比较数据做好准备。threshold是一个阈值,这里取16,当前后两次抽样差值超过threshold时就认为这两个抽样数据是不等的。在输入数据接近0或者255的时候,需要做特殊处理,避免整型数溢出,影响比较结果。
compare_data:process(spclk2,valid,compare_field)
begin
if(spclk2'event and spclk2=‘0’)then
if(compare_field=‘0’)then
pixels<=“0000000000”;
elsif(valid='1')then
if(data_sram_reg<=data_reg1 or data_sram_reg>=data_reg2)then
pixels<=pixels+1;
end if;
end if;
end if;
end process;
compare_data进程在抽样的间隔(输入为色度分量Cr或者Cb时)对前后两次抽样的数据进行比较,如果比较结果超过允许值,计数器pixels加1,否则不加。
motion_detect:process(pixels)
begin
if(pixels>max_pixels)then
int0<=‘1’;
else
int0<=‘0’;
end if;
end process;
max_pixels是一个阈值,表示一帧数据中允许出现的不相等抽样数据的最大数目,当计数器pixels超过max_pixels时,就认为检测到了物体运动,CPLD将int0输出管脚置高,向处理器请求中断。这里max_pixels取600,它可以根据需要设置适当的值。
当CCD摄像头前有物体晃动时,CPLD的int0管脚会连续产生高电平脉冲,这说明运动检测模块已经正常工作起来,同时另一路视频信号经过W99682处理后输送到电视屏幕上,以便观察运动的场景。如果晃动摄像头本身,只要微小的晃动就可以看到类似的效果,因此用这种CPLD实现运动检测是可行的。
事实上,还可以利用同样的原理对CMOS摄像头的输入信号进行运动检测。
当然这种检测方法本身也有不足之处,最主要的一点是实际检测到的只是摄像头前光线亮度的变化,不能智能地判断引起这种变化的原因,也不能判别运动物体的形状。另一方面,从实验结果来看,有时候会出现误判;当运动物体离摄像头比较远时,检测的灵敏度也会降低,出现漏判。误判和漏判是一对矛盾,在实际应用中需要根据实际情况反复调试,选出最佳的阈值,减少这两种情况的发生。
参考文献
1 Recommendation ITU-R BT.601-5. ITU Organization,1995
2 SAA7113H 9-bit Video Input Processor. Philips Semiconductors, 1999
3 马小斌,金连文,尹俊勋.利用DSP和CPLD增加数据采集的可扩展性.电子技术应用, 2003;29(3)
4 吴繁红,井新宇.用CPLD/FPGA设计A/D采样控制器.电子工程师, 2002(2)
5 张华春,雷 宏,孙长瑜.基于CPLD的ADSP21060与SDRAM接口设计.信号处理, 2002(6)