基于FPGA:多目标运动检测(手把手教学①)
本算法是针对已经进行了二值化的图像进行目标分割和标记。如帧差法运动目标检测算法,已经进行了帧间差、二值化、腐蚀、膨胀这些算法后得到的二值化图像。分割采样距离判别的方法,标记则采用矩形包围盒。本算法模块应用在新版本的“FPGA帧差法运动目标检测中”,可以直接替换老版本中的包围盒算法模块:find_box模块,接口定义兼容,同时新日两版本的区别也是在于本模块,所以在老版本基础上只需要额外理解本算法模块
目录
日常·唠嗑:
在3月份发表了基于FPGA:运动目标检测(原理图+源码+硬件选择,可用毕设)后反应很强,很多同学表示,希望我们能在运动目标检测的基础上,做多目标运动检测。最近跟其他两个工程师刚好有空,就把就版本的工程做了一次超大升级。
本次工程,花了很多时间,所以整个设计写的都很详细,想学的同学可以慢慢嚼。
一、视频效果
话不多说,直接看效果
FPGA帧差法多运动目标检测(演示)
二、新旧版本比较
本算法是针对已经进行了二值化的图像进行目标分割和标记。如帧差法运动目标检测算法,已经进行了帧间差、二值化、腐蚀、膨胀这些算法后得到的二值化图像。分割采样距离判别的方法,标记则采用矩形包围盒。
本算法模块应用在新版本的“FPGA帧差法运动目标检测中”,可以直接替换老版本中的包围盒算法模块:find_box模块,接口定义兼容,同时新日两版本的区别也是在于本模块,所以在老版本基础上只需要额外理解本算法模块即可理解新版本代码。
三、新版本特色
1、开发环境
硬件环境: DMK301 FPGA开发板(EP4CE10)、AN5640摄像头模组。
软件环境: Quartusii13.1+配套的Modelsim-ase。
2、功能
1、OV5640摄像头采集实时视频
2、对视频进行帧差法运动目标检测算法处理
3、使用包围盒框选出目标,并实时显示在VGA显示屏
4、串口输出信息
3、特点
1、全套实物(含资料)
2、上电即出功能效果
3、最多支持16个目标
4、最大支持目标数量参数化可调
5、包围盒颜色参数化可调
6、串口输出目标位置和目标数量
7、提供源代码工程(Verilog)
8、提供Modelsim仿真
9、提供讲解视频&提供售后答疑
四、工程设计
1、原理说明
1、包装盒定义
将目标所有部分都包含的面积最小的矩形。如下图中所示,图1中的矩形框是符合包围盒定义的,图2中的矩形框虽然包含了目标所有部分但面积不是最小的,图3中的矩形框虽然面积小,但是未包含目标的所有部分。
图1
图2
图3
2、包围盒定位
2.1、单个目标定位
在描述多目标定位原理前,先理解单个目标定位,这将有助于理解多目标的定位原理。
单个目标定位本质上就是找到目标中所有像素点的横、纵坐标的最大和最小值,计为Xmax、Ymax、Xmin、Ymin,则包围盒就是由(XMin,Ymin)为左上角点坐标、(Xmax,Ymax)为右下角点坐标确定的矩形。
实现原理是,在当前输入点灰度为1时,如果当前点的横坐标小于等于Xmin,则把Xmin更新为当前点的横坐标;如果当前点的横坐标大于等于Xmax,则把Xmax更新为当前点的横坐标;以此类推,对Ymax和Ymin也一样。核心代码描述如下:
if( per_img_Y == 1 'b1) begin
if(Ymin > y_cnt) Ymin <= y_cnt ;else
Ymin <= Ymin ;
if(Ymax < y_cnt) Ymax<= y_cnt ;else
Ymax<= Ymax ;
if(xmin > x_cnt) xmin<=x_cnt ;else
xmin <= xmin ;
if(Xmax < x_cnt) Xmax<= x_cnt ;else
Xmax<=Xmax ;
end
2.2、多个目标定位(解释的比较详细,认真看)
定义N组寄存器用于储存N个包围盒的坐标,每个包围盒坐标以(Xmin[i],Ymin[])、(Xmax[],Ymax[1])表示,其中i∈[0,N-1]。图像像素从左上到右下的顺序扫描,依次输入每个像素,根据这一特性,对每一个输入为1的像素进行归属判断,看其属于哪个包围盒的范围,若不属于任何一个已存在的包围盒,则新生成一个包围盒。新生成的包围盒的Xmin和Xmax都赋值为当前点的横坐标,Ymin和Ymax都赋值为当前点的纵坐标。
归属判断根据距离进行,当灰度为1的输入点距离某个包围盒小于设定的阈值时,则认为该点属于此包围盒,根据该点的坐标更新包围盒坐标。判断顺序按照包围盒的序号从小到大的顺序进行,只要该点属于任意一个包围盒则终止判断,即不再判断是否属于后续的包围盒。如图4所示,在A点输入时,原先的包围盒区域是左图中的区域,A点输入后,由于A点距离该包围盒较近即距离小于阈值,所以根据A点的坐标更新包围盒,可以看到Xmin和Ymax得到了更新,Xmin更新为A的横坐标,Ymax更新为A的纵坐标,而Xmax和Ymin则未更新,这是由于A的横坐标小于Xmax,A的纵坐标大于Ymin。这其实就是根据距离来对不同目标进行分割,不过该方法有个瑕疵,就是距离阈值的选取不能太小也不能太大,阈值太小则可能导致同一个目标的不同部分被分割为不同目标,就比如图4中,如果阈值过小,则会在A点输入时判断出A点不属于已存在的任何一个包围盒,从而以A点的坐标生成一个新的包围盒。反之,若阈值太大,可能导致不是同一个目标,但是由于距离较近而被识别成同一个目标。
图4:
3、包围盒绘制
包围盒绘制实际上就是绘制已经定位出的包围盒矩形框,用比较醒目的颜色如红色为包围盒的矩形框着色。理论上包围盒的边框宽度是1,即矩形的4条边都是占用1像素宽度的线段,为了使包围盒更加突出明显,便于人眼观察,可以适当加宽矩形框4条边的宽度。根据输入图像的像素点坐标是否是包围盒的边框,决定该像素输出的像素值是原像素值还是包围盒的颜色,如以下代码描述:这里的2’d3即代表包围盒边框宽度为4,Box_COLOR是定义包围盒颜色的参数,x_min、y_min、x_max、y_max则是包围盒的坐标。
代码:
if( (( (x_cnt+2'd3 >= x_min && x_cnt 〈= x_min) ll (x_cnt 〈= x_max+2'd3 && x_cnt>= x_max)) && y_cnt+2 'd3 >= y_min 8& y_cnt <= y_max+2'd3)ll
(( (y_cnt+2'd3 >= y_min && y_cnt 〈= y_min)ll (y_cnt <= y_max+2'd3 &8 y_cnt>= y_max)) && x_cnt+2'd3 >= x_min && x_cnt <= x_max+2 'd3)
o_data <= Box_COLOR;
elseo_data <= i_data;
上述代码只是针对1个包围盒的绘制,如果需要绘制多个包围盒,则可以例化多个相同的模块,前后串行连接,即先绘制第一个包围盒,再绘制第二个包围盒,类似添加不同的图层,每个模块负责一个图层,经过多个模块叠加绘制后,即可绘制出多个包围盒。
这实际上是流水线操作的思想,每个包围盒绘制模块就负责一级流水线操作,当然这会导致从图像输入到图像输出会存在N个时钟的延迟,这里的N就代表使用几个包围盒绘制模块(这里默认包围盒绘制模块的延迟是1个clk,实际上我们的verilog程序最终实现的结果就是这样的)。
2、模块框图
如图5所示是多目标包围盒算法的模块框图,输入两路视频、输出一路视频。
Video Bin是经过帧间差、二值化、腐蚀、膨胀后得到的二值化图像,其中已包含目标,需要根据Video Bin进行包围盒定位;
Video Org是原始图像,根据包围盒坐标在原始图像上叠加包围盒的矩形框;
Video Output则是在原始图像上叠加过包围盒的结果。
multy_locate模块功能是定位各个目标的包围盒坐标,其包含多个signle_locate模块的串联,每个single_locate模块记录1个包围盒信息,这个信息包括包围盒的坐标位置和包围盒是否生效。
multy_locate模块还包含一个count_1s的模块,这个模块用来统计生效的包围盒个数,其实就是对多bit的数据进行"数1"运算,计算总计有多少个“1”"。
bounding_box_draw模块则是根据1个包围盒坐标,在图像上叠加一个特定颜色的矩形框即画1个包围盒,每个模块最多只画1个(也可能不画,要看该包围盒是否生效)包围盒。
多个bounding_box_draw模块串联,第一个模块画第一个包围盒、第二个模块画第二个包围盒,以此类推,以流水线方式操作直到最后一个模块叠加完成输出Video Output,每个bounding_box_draw模块会导致视频流产生1个时钟的延迟。
图5:
3、手把手教模块
1、bounding_box_top模块:
功能说明:
多目标包围盒算法模块的顶层模块,例化multy_locate模块和bounding_box_draw模块。
参数定义:
接口定义:
—————————————————————————————————
五、未完、待续……
今天就先讲到这里,有兴趣的同学可以关注,后面持续更新~~
需要套件的同学,可以私信我预定,7月20号准时上架,开用竞赛、毕设等。
发货清单:
FPGA开发板(EP4CE10F17C8)
AN5640摄像头模组(OV5640)
USB Blaster下载器
VGA线
USB供电线。资料
工程源码。
设计报告。
开发板原理图。
摄像头模块资料售后服务
本产品提供售后技术支持和答疑服务,但只针对产品本身的相关内容或问题进行答疑,不提供二次开发的技术支持或答疑服务。
后面会继续讲解模块:
模块仿真
multy_locate模块
single_locate模块count_1s模块
bounding_box_draw模块
待续……
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)