【2021集创赛】Arm杯一等奖作品—基于 Cortex-M3 内核 SOC 的动目标检测与跟踪系统

本作品介绍参与极术社区的有奖征集|秀出你的集创赛作品风采,免费电子产品等你拿~

团队介绍

参赛单位:北京理工大学
队伍名称:飞虎队
指导老师:李彬
参赛杯赛:Arm杯
参赛人员:余裕鑫 胡涵谦 刘鹏昀
获奖情况:全国总决赛一等奖,华北赛区一等奖

1.项目简介

视频目标跟踪是计算机视觉领域的重要热点研究方向之一,它在军事领域和民用领域都具有较高的实用价值,如成像制导、智能交通、智能监控、人机交互、医学诊断等方向,但多数相关算法计算量较大,导致实时性较差,所以实时实现目标的检测与跟踪已成为重点研究方向之一。

本系统基于Xilinx Artix XC7A100T平台,在其基础上搭载Cortex-M3内核,AMBA总线,总线上外挂GPIO,LCD,OV5640,DDR3和HDMI等外设模块,基于混合高斯建模及Meanshift等相关算法,实现了对摄像头输入图像的动目标检测与实时跟踪功能,高效运行智能算法,使系统具备了无人实时运行,高效智能化处理任务的能力。

2.系统运行流程介绍

a.系统上电后,对系统的各项外设进行初始化。如配置OV5640摄像头的图像尺寸,曝光时间等各项参数。
b.当系统的检测与跟踪功能关闭时,图像信号通过DDR缓存后,通过HDMI实时显示,可作为一般性的监控功能使用。
c.当系统的检测与跟踪功能打开时,系统会在DDR缓存完两帧图像后,在1ms左右的时间内检测出其中的动目标的位置与大小,而后通过跟踪模块,在不影响图像在HDMI显示的基础上,实时跟踪目标所在的位置,采用红色方框的方式在HDMI实时标记目标所在位置,并通过LCD屏幕实时显示目标所在的位置。
d.同时,系统还配备了正常工作指示信号灯,通过LED定时闪烁的机制实时反馈系统运行状态。

3.系统架构

3.1架构简介

本系统的架构如下图3.1所示。处理器内核采用比赛官方指定的Cortex-M3评估版内核。系统总线采用AMBA总线,总线层数为两层,第一层AHB总线,用于对系统空间进行一个总体的划分;第二层包括一个AHB总线和APB总线,其中AHB用于挂载速度较快的外设,例如OV5640,HDMI等,第二层总线APB由转接模块连接到AHB,用于挂载速度较慢的外设,如Timer,GPIO等。
在这里插入图片描述

 图3.1 整体系统架构图

由OV5640中得到的RGB图像信号是系统处理的主要数据信号,该信号在系统中的流通情况如下图3.2所示,根据下图易知,本系统采用的是通道加速器的形式实现了目标的检测和跟踪功能,其优点的简单易实现,对新手比较友好,同时可以大大加快系统开发效率,缺点是模块的通用性查,针对不同的系统,需要对模块进行大量的修改,通用性较差。针对以上问题,后续将采用加速器IP的形式,提高加速器的通用性。
在这里插入图片描述

图3.2 系统数据流简图

3.2软硬件功能划分

为了充分发挥FPGA的实时性优势,本作品的大部分功能模块在FPGA端实现,如OV5640相关驱动模块、HDMI显示模块、DDR3模块以及加速器模块;ARM端为每个需要触发控制的外设配置一个c和h头文件,用于相关参数的配置,以及对应中断事件的唤醒,如在OV5640模块中,我们通过软件端设置摄像头的图像尺寸,最大曝光帧率等参数。

4.外设挂载

4.1 GPIO外设

本系统在APB总线上挂接GPIO外设,可实时观察系统运行情况,并可通过相应按键进行系统的动态调试。

4.2 LCD外设

本系统采用在APB总线上挂接LCD外设,系统外接LCD外设主要用于实时显示运动目标物体的具体位置,LCD屏幕实时显示的参数共有四个,目标物体左上角的x,y坐标以及目标物体的宽和高。

4.3 OV5640摄像头外设

本设计采用OmniVision公司的OV5640型摄像头。如图4.1为摄像头模块详细框图。
在这里插入图片描述

图4.1 摄像头模块
摄像头模块在成功将一帧图像写入DDR内后向Cortex-M3处理器及加速器模块发送发送帧传输完成中断信号,将Cortex-M3处理器及加速器模块从待机状态唤醒。前两帧图像存储完成后Cortex-M3处理器将图像采集模块暂时关闭,加速器模块开始运行目标检测单元。得到检测结果后Cortex-M3处理器再向图像采集模块发出采集新图像的请求,并开启加速器模块中的目标跟踪单元,执行目标跟踪。

4.4 DDR3存储外设

由于DDR3时序十分复杂,若直接编写DDR3的控制代码,工作量十分大,且性能难以保证,因此我们Xilinx公司提供的MIG IP核来实现DDR的读写。
本设计DDR控制模块框图如图4.2。
在这里插入图片描述

图 4.2 DDR控制模块
如框图所示,DDR读写单元负责与MIG模块进行命令和地址的交互,根据FIFO调度单元中FIFO的剩余数量来切换DDR3的读写命令和地址;FIFO调度单元负责对输入和输出的数据进行时钟域的切换和位宽的转换。

4.5 HDMI显示外设

本系统采用HDMI接口,模块架构如图4.5所示。
图像数据通过DDR输送到HDMI后,先经过视频驱动模块,生成对应图像分辨率的场同步,行同步信号,去除行前后沿,场前后沿,得到需要显示的图像数据;而后将图像数据经过DVI直流平衡编码;再使用五倍的时钟,将图像数据串并转换,最终得到10倍像素速率的串行数据;最后再进行TMDS差分输出,得到显示信号。
在这里插入图片描述

图4.5 HDMI驱动模块

5.加速器设计

如图5.1,我们团队加速器模块由目标检测单元及目标跟踪单元构成,目标检测单元采用混合高斯建模算法,目标跟踪单元采用MeanShift算法。
在这里插入图片描述

图5.1 加速器整体框架
当摄像头完成前两帧数据采集后开启目标检测单元,加速器模块与DDR交换数据并计算相关参数,检测完成后将目标进行框选,开始运行目标跟踪算法。

5.1 混合高斯建模算法

我们团队采用混合高斯背景建模的方法获得背景,以抑制上述环境中噪声对背景消除法的影响,并弥补帧差法的不足。混合高斯背景建模算法假设各个像素点各自完全独立,独立像素点的值的变化在时间上面基本符合高斯分布,利用各像素点值的概率分布,判断其是否属于背景像素点。详细框图如图5.2。

首先初始化预先定义的两个高斯模型,对高斯模型中的参数(像素高斯均值(mean)、方差(sd)、权重(w)、像素与高斯均值的绝对距离(udiff)及匹配标志(match))进行初始化,并求出将要用到的参数。其次,对于每一帧中的每一个像素进行处理,计算其是否匹配某个模型,若匹配,则将其归入该模型中,并对该模型根据新的像素值进行新,若不匹配,则以该像素建立一个高斯模型,初始化参数,代替原有模型中最不可能的模型。最后选择前面几个最有可能的模型作为背景模型,进行腐蚀及膨胀等形态学滤波后提取目标。
在这里插入图片描述

图5.2 检测单元详细框架

5.2 Meanshift目标跟踪算法

运用传统的MeanShift 算法进行目标跟踪。首先是对目标跟踪的初始化,可通过目标检测方法得到需要跟踪的初始目标的外接矩形框,也可以通过鼠标手工选取的方式。本系统中使用的初始目标的矩形的位置及大小根据检测加速器检测得到。然后计算权值矩阵加权下的搜索窗口的直方图分布,用同样的方法计算第N帧对应窗口的直方图分布;以两个目标模板分布的相似性最大为原则,使搜索窗口沿密度增加最大的方向移动,得到目标的真实位置。

MeanShit算法跟踪步骤如下:
1. 计算目标模板的概率密度 ,目标被估计位置 与核窗宽h;
2. 用 初始化当前帧的目标位置,计算候选目标模板 ;
3. 计算当前窗口内各点的权重值;
4. 计算目标的新位置。
经研究,使用YUV像素格式中的Y,即图像亮度来计算图像概率密度 可以得到较好的结果,即系统中在对图像目标进行跟踪时所采用的是RGB转YUV后的数据。
在这里插入图片描述

图5.3 跟踪单元状态转换示意图

6.模块及系统仿真

6.1检测模块仿真

混合高斯建模状态机共由11个状态完成,由于状态较多,且100MHZ时钟下在状态跳转时可能会出现状态跳转错误的情况,为避免此类事件发生,状态参数采用格雷码形式,状态编码如下:IDLE(4’b0000),W_INIT(4’b0001),SD_INIT (4’b0011),UDIFF_MEAN (4’b0010),U_M_2(4’b0110),P_UPDATE(4’b0111),P_UP_2(4’b0101),MODEL_UP(4’b0100),FRAME_JUG(4’b1100),PIXEL_TF (4’b1101)以及M_DONE(4’b1111)。状态机仿真如图6.1所示。
在这里插入图片描述
图6.1 混合高斯建模算法状态机跳转仿真
处理完成标志仿真结果如图6.2所示。
在这里插入图片描述

图6.2 处理完成标志信号仿真结果

6.2 跟踪模块仿真

通过Modelsim仿真后将系统跟踪数据导出,由Matlab采集相应数据画图,如图6.3所示。

在这里插入图片描述
图6.3 Modelsim仿真结果

7.系统整体测试结果

系统整体测试效果如视频所示,可以看到,系统效果较好,另也有较为复杂背景下的演示,欢迎感兴趣的同学与我们交流。

8.参赛体会

通过本次比赛我们对基于ARM Cortex-M3内核的SOC设计有了一定的认识并基本掌握相关设计流程,进一步提高了自己的专业知识水平,同时也感受到了大赛紧张的气氛,很荣幸可以与全国各地200余所高校参赛队伍共同努力。
通过比赛期间的宣讲,我们也更加了解到国内集成电路行业的发展现状。非常感谢赛事组委会的老师和工作人员在本次大赛中的辛苦付出!

作品内容来源于飞虎队,非开源,转载请标明出处。
欢迎大家参加极术社区组织的有奖征集|秀出你的集创赛作品风采,免费电子产品等你拿~活动,10月1日截止~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/175700.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux查看端口占用情况

lsof命令 lsof(list open files)命令可以列出当前系统中打开的所有文件,包括网络端口。可以使用lsof命令查看某个端口被哪个进程占用。 具体的命令为:sudo lsof -i :端口号,其中端口号为需要查询的端口号。 netstat命令 使用netstat命令&a…

3DMAX如何渲染室内效果图?

这可能不是最好的教程,但对于3dmax初学者来说,它具有一定的学习价值和启示意义。 任何在建筑或室内设计领域工作并需要室内或外部空间“艺术家渲染”的人都会熟悉行业巨头Autodesk发布的3ds Max。 3ds Max是此类工作的默认标准,不是因为它在其他3D程序中无法完成,而是因为它…

MATLAB|科研绘图|山脊图

效果图 山脊图介绍 山脊图(Ridge Plot),也被称为Joy Plot,是一种用于可视化数据分布的图表,特别是用于显示多个组的分布情况。在这种图表中,每个组的数据分布都通过平滑的密度曲线来表示,这些曲…

LeetCode | 225. 用队列实现栈

LeetCode | 225. 用队列实现栈 OJ链接 此题可以用两个队列去实现一个栈,每次始终保持一个队列为空, 入栈操作相当于给非空队列进行入队操作 入数据,把不为空的队列入 出数据,把不为空的队列数据导入为空,直到最后一…

代号:408 —— 1000道精心打磨的计算机考研题

文章目录 📋前言🎯计算机科学与技术专业介绍(14年发布)🧩培养目标🧩毕业生应具备的知识和能力🧩主要课程 🎯代号:408🔥文末送书🧩有什么优势&…

golang中context使用总结

一、context使用注意事项 在使用context时,有一些需要注意的事项,以及一些与性能优化相关的建议: 避免滥用context传递数据:context的主要目的是传递请求范围的数据和取消信号,而不是用于传递全局状态或大量数据。滥用…

RedisDesktopManager连接不上redis的解决方法

RedisDesktopManager连接不上redis的解决方法 RedisDesktopManager是一款连接redis数据库的客户端。 当连接不上redis的时候,解决方案: 第一步:在自己的本机外面试下,能不能连接上虚拟机 打开cmd,使用ping 虚拟机ip地址。如果…

[文件读取]webgrind 文件读取 (CVE-2018-12909)

1.1漏洞描述 漏洞编号CVE-2018-12909漏洞类型文件读取漏洞等级⭐⭐⭐漏洞环境VULFOCUS攻击方式 1.2漏洞等级 高危 1.3影响版本 Webgrind 1.5版本 1.4漏洞复现 1.4.1.基础环境 1.4.2.前提 网站后台地址: 后台管理账密: 后台登录地址 1.5深度利用 …

基于opencv+tensorflow+神经网络的智能银行卡卡号识别系统——深度学习算法应用(含python、模型源码)+数据集(一)

目录 前言总体设计系统整体结构图系统流程图 运行环境Python环境TensorFlow 环境OpenCV环境 相关其它博客工程源代码下载其它资料下载 前言 本项目基于从网络获取的多种银行卡数据集,采用OpenCV库的函数进行图像处理,并通过神经网络进行模型训练。最终实…

13. 高精度延时

13. 高精度延时 GPT 定时器简介GPT 定时器结构GPT 定时器工作模式 GPT 定时器相关寄存器GPTx_CRGPTx_PRGPTx_SRGPTx_CNTGPTx_OCR GPT 配置步骤程序编写bsp_delay.hbsp_delay.cmain GPT 定时器简介 GPT 定时器是一个 32 位向上定时器,也就是从0x00000000 开始向上递…

学【Java多态】-- 写高质量代码

多态的实现条件 在java中要实现,必须要满足如下几个条件,缺一不可。 1.必须在继承体系下2.子类必须要对父类中的方法进行重写3.通过父类的引用调用冲写的方法。 想要真正的学好多态需要去学习一些前置知识,那我们直接开始吧! …

Day30力扣打卡

打卡记录 最长回文子序列(区间DP) 链接 class Solution:def longestPalindromeSubseq(self, s: str) -> int:n len(s)f [[0] * n for _ in range(n)]max lambda x, y: x if x > y else yfor i in range(n - 1, -1, -1):f[i][i] 1for j in ra…