基于ov5640的摄像头运动目标检测verilog代码Quartus,CX401开发板
摄像头:ov5640
代码语言:verilog
软件:quartusII
开发板:CX401,可移植到其他开发板
演示视频
https://www.bilibili.com/video/BV1VQsUzuEsG/
代码讲解视频:
https://www.bilibili.com/video/BV15SsUz6EbJ/
本系统将硬件控制器设计,图像处理算法设计两大部分有机地进行结合使之能够完成运动目标检测。在图像存入SDRAM前需要将图像格式由RGB转换为YCbCr。运动目标检测实现系统整体框架如图所示。

图像处理算法及硬件驱动
在SDRAM中存储两帧相邻灰度图像的数据,使用VGA驱动程序将两帧数据同时从SDRAM中取出。使用中值滤波算法将两帧数据分别进行滤波平滑噪声,对图像信息进行差分。差分后的二值化像素群使用膨胀算法拓展边界,稳定检测效果,通过最小包围盒模块确定二值化图像边界,画出包围盒方框。将方框叠加在原图像上并输出即可完成对运动目标的检测。

帧间差分法的核心是对两帧相邻图像进行存储,根据数据存储的位置大致可以分为三类,第一类是上一帧图像与下一帧图像分别位于两段不同的存储空间中。第二类是将两帧图像数据交叉存储于同一段存储空间中。第三类是将两帧图像存储于同一存储空间的高低位上如图所示。

帧图像存储于同一存储空间示意图
与前两种存储方式相比,将两帧图像数据存储于同一地址存储空间中取出时序更加简单。两帧图像在取出时拥有相同的行场同步信号时序,数据也自然对齐,有利于后续图像算法的进行。
一般地,对于同一地址空间写入两次数据,第一次写入的数据将会被第二次的数据覆盖。为了解决这个问题,一般的存储器都会提供数据掩码功能。通过掩码屏蔽特定位置的数据写入便可防止数据覆盖。SDRAM提供了数据掩码引脚DQM[1:0],DQM真值表如表所示,当DQML引脚为高电平时屏蔽低字节数据的写,当DQMH为高电平时屏蔽高字节数据的写入。
DQM真值表

本设计使用的SDRAM芯片存储数据位宽为16比特。而从摄像头采集的RGB565格式数据为16比特,SDRAM不能同时将两帧RGB图像存储。因此在存入SDRAM前先将RGB格式转换为YCbCr格式并提取亮度分量作为灰度图像,这时图像数据的位宽为8比特可以将两帧图像存于SDRAM高低位中。对于图像数据此时应该存放于高位还是低位可以通过对图像场同步信号的监测来实现。当检测到场同步信号的下降沿时说明本帧显示结束即将开始下一帧显示。因此可以使用帧标志信号,每一帧画面结束时对帧标志信号进行翻转。通过帧标志信号就能够准确的计算本帧数据存放在低位还是高位。SDRAM掩码及帧标志控制关系如表所示。
SDRAM掩码及帧标志控制关系表

基于灰度的帧间差分法
帧间差分法是通过两帧相邻图像间做差并选取合适的阈值对图像进行二值化从而选取出运动的物体,算法流程,f(x, y)为灰度差分图像,D(x, y)为帧间差分图像,gk(x, y)、gk-1(x, y)为相邻两帧灰度图像,差分阈值为T。

将两帧相邻图像对应像素进行差分并取绝对值获得灰度差分图像,将灰度差分图像与预设阈值作比较,将大于阈值的像素划分为运动物体。
代码仿真图如下:



开发板验证图:


部分代码展示:
//camera power on timing requirement module power_on_delay(clk_50M,reset_n,camera_rstn,camera_pwnd,initial_en); input clk_50M; input reset_n; output camera_rstn; output camera_pwnd; output initial_en; reg [18:0]cnt1; reg [15:0]cnt2; reg [19:0]cnt3; reg initial_en; reg camera_rstn_reg; reg camera_pwnd_reg; assign camera_rstn=camera_rstn_reg; assign camera_pwnd=camera_pwnd_reg; //5ms, delay from sensor power up stable to Pwdn pull down always@(posedge clk_50M) begin if(reset_n==1'b0) begin cnt1<=0; camera_pwnd_reg<=1'b1; end else if(cnt1<19'h40000) begin cnt1<=cnt1+1'b1; camera_pwnd_reg<=1'b1; end else camera_pwnd_reg<=1'b0; end //1.3ms, delay from pwdn low to resetb pull up always@(posedge clk_50M) begin if(camera_pwnd_reg==1) begin cnt2<=0; camera_rstn_reg<=1'b0; end else if(cnt2<16'hffff) begin cnt2<=cnt2+1'b1; camera_rstn_reg<=1'b0; end else camera_rstn_reg<=1'b1; end //21ms, delay from resetb pul high to SCCB initialization always@(posedge clk_50M) begin if(camera_rstn_reg==0) begin cnt3<=0; initial_en<=1'b0; end else if(cnt3<20'hfffff) begin cnt3<=cnt3+1'b1; initial_en<=1'b0; end else initial_en<=1'b1; end endmodule
代码下载(付费下载):
1480