当前位置:首页 > 嵌入式 > 嵌入式教程
[导读]此项目旨在对一个目标捕获系统的图像处理算法进行严格的硬件验证.我们将用分别用硬件设计和多核软件设计来分别实现这个算法,并比较这两种实现方式.在创建多核软件设计的过程中我们还将对OpenFire软核进行改进以搭建起这个多核网络。

摘要

此项目旨在对一个目标捕获系统的图像处理算法进行严格的硬件验证.我们将用分别用硬件设计和多核软件设计来分别实现这个算法,并比较这两种实现方式.在创建多核软件设计的过程中我们还将对OpenFire软核进行改进以搭建起这个多核网络.

这个目标捕获系统的图像处理算法的硬件实现方式和多核软件实现方式将在一个基于FPGA试验板上进行比较.以此证明通过合理配置和编程多核软件实现同样很容易达到和硬件实现一样的低功耗性能,并只有非常低的面积消耗.

引言

随着现代高速处理器的迅猛发展,图像处理技术也日益成熟。其中,移动目标的视频检测与跟踪是图像处理、分析应用的一个重要领域,是当前相关领域的研究前沿。移动目标视频检测与跟踪技术,在机器人视觉、交通监测、可视预警、机器导航等民用领域有着广泛的应用.基于FPGA为核心器件构成的视频识别和跟踪装置,实现图像跟踪各项功能。此项目提出的跟踪算法与设计的跟踪装置可在一定程度上解决视频跟踪精度低、处理速度慢的问题,同时本视频跟踪装置也可作为进一步研究图像处理与跟踪控制的平台。该系统体积小,灵活性高,易于升级,可应用于无人值守的智能监控系统,如银行,金库,仓库等重地。当发现异常情况出现时,该系统能够自动报警或采取其它相应的措施,从而更有效、可靠地实现了安全防范,同时也在很大程度上减少了监视人员的工作量和疲劳度,大大提高了工作效率。

此项目旨在对一个目标捕获系统的图像处理算法进行严格的硬件验证.我们将用分别用硬件设计和多核软件设计来分别实现这个算法,并比较这两种实现方式.在创建多核软件设计的过程中我们还将对OpenFire软核进行改进以搭建起这个多核网络.

这个目标捕获系统的图像处理算法的硬件实现方式和多核软件实现方式将在一个基于FPGA试验板上进行比较.以此证明通过合理配置和编程多核软件实现同样很容易达到和硬件实现一样的低功耗性能,并只有非常低的面积消耗.


目标捕获系统流程及系统架构

图一 目标捕获系统流程图

图二 本项目系统架构图

FPGA的实现

1 算法简介

(1)背景差分法算法背景差分[6]是利用当前图像与背景图像差分来检测出运动区域的一种技术,一般能提供最完全的特征数据,但对于动态场景的变化,如光照等事件的干扰特别敏感。考虑到摄像机移动缓慢,背景图像变化比较迟缓,而运动对象相对于背景变化较快,这样相对于变化较慢的背景图像来说,可把运动对象看作是一个对背景图像的随机扰动。针对本装置的设计要求,我们应用Kalman滤波器[4]在零均值白噪声的退化公式即渐消记忆递归最小二乘法,来更新和重建背景图像,得到时域渐消递归最小二乘法的递归式

(2) 颜色滤波去阴影算法

如果图像中具有运动阴影和分割碎块,分割所得的图像往往与实际目标不符,产生欠分割或过分割的现象。由于阴影象素的灰度值在一个局部领域中变化不是很大,所以颜色滤波主要是构造一个包含阴影的模板,再用这个模板与差分结果做逻辑与的操作,从而检出阴影。本算法比较简单,执行速度快,处理中不需要区分阴影和半阴影,而且可以将移动阴影和背景中的阴影都检出来,只是模板中的参数要根据现实情况和经验来定。由于静止物体的阴影也是不动的,所以静止目标可以归入背景中

(3)形心跟踪算法

形心跟踪是将整个跟踪波门内的图像二值化,用求目标形心的办法获得目标位置参量。由于形心值是相对于目标面积归一化的值,因此形心值不受目标面积、形状以及灰度分布细节的限制。同时,形心跟踪的计算颇为简便。但是,形心跟踪器受目标的剧烈运动或目标被遮挡的影响较为严重,瞄准点漂移是远距离跟踪系统的主要误差之一。这也是我们采用目标轨迹拟合算法来外推运动目标位置,并与相关跟踪法并行工作的原因。由于形心算法比较普及,本跟踪装置直接采用了改进的形心跟踪算法,用目标峰值自适应检测算法使系统的计算可靠性和实时性达到最佳结合值。

2 算法的实现

1 差分机模型

图三 差分机模型

从图中可以看出 差分机分4步对比计算每个像素和颜色的差别,输入这个模型的是红绿蓝的像素值 和 红绿蓝的颜色值以及阈值.当阈值为16bits 宽的时候 那么每个输入像素的值就是8bits宽.

二进制的数据流作为此差分机的输出用于构建差分图形.

四openfire 软核架构

系统采用四个OpenFire core 作为自己的软核 .Openfire是一个开源的软核, 这种开放源码的处理器和Xilinx的Microblaze 兼容,甚至可以使用大多数Xilinx EDK提供的工具 。Openfire在cache和FSL总线等方面和Microblaze有着相同的配置 , 但是openfire允许改变数据通过的字节宽度,这正是我们目标捕捉图像处理算法所需要的.

图四 四 OpenFire 软核 架构

图五 改进后的openfire处理器顶层图

图六 Openfire OPB 状态机

图七 Open fire OPB memory 系统图

图八 Open fire IOPB memory 系统图

图九 改进OenFire FSL 数据 I/O

部分代码

1 FSL loopback test code

// This code is used by an OpenFire with all eight of its FSL ports connected

// in loopback to ensure that all ports are functional.

#include "fsl.h"

bool test_fsls(void);

int main(void) {

test_fsls();

while(1);

}

bool test_fsls(void) {

int data = 0;

putfsl(data+1,0);

getfsl(data,0);

putfsl(data+1,1);

getfsl(data,1);

putfsl(data+1,2);

getfsl(data,2);

putfsl(data+1,3);

getfsl(data,3);

putfsl(data+1,4);

getfsl(data,4);

putfsl(data+1,5);

getfsl(data,5);

putfsl(data+1,6);

getfsl(data,6);

putfsl(data+1,7);

getfsl(data,7);

return(data == 8);

}

2 IOPB / DOPB test code

#include "microblaze_0/include/xparameters.h"

#include "microblaze_0/include/xuartlite_l.h"

#include "microblaze_0/include/fsl.h"

extern void xil_printf(const char*, ...);

void outbyte(char c)

{

XUartLite_SendByte(STDOUT_BASEADDRESS, c);

}

char inbyte(void)

{

return XUartLite_RecvByte(STDIN_BASEADDRESS);

}

volatile unsigned int * timer = (unsigned int *)0x40060008;

volatile unsigned int * ddr = (unsigned int *)0x30000000;

unsigned int (*moved_summer)(const unsigned int * values, const int numvals);

unsigned int summer(const unsigned int * values, const int numvals)

{

int ctr;

unsigned int sum = 0;

for(ctr=0;ctr<numvals;ctr++)

sum += values[ctr];

return sum;

}

int main(void)

{

unsigned int starttime;

unsigned int endtime;

unsigned int timetaken;

int test_ctr;

int num_tests = 16;

int num_shifts = 4; // num_shifts = log2(num_tests)

int array_sz = 16;

int array_ctr;

int num_instructions = 100;

int instr_ctr;

unsigned int retval;

for(array_ctr = 0; array_ctr < array_sz; array_ctr++)

ddr[array_ctr] = array_ctr;

xil_printf("-- Starting Test (BRAM) --rn");

retval = 0;

timetaken = 0;

for(test_ctr=0;test_ctr<num_tests;test_ctr++)

{

starttime = timer[0];

retval = summer(ddr,array_sz);

endtime = timer[0];

timetaken += endtime - starttime;

}

xil_printf("-- Test Finished --rn");

xil_printf("RtVal: %drn", retval);

xil_printf("Taken: %drn", timetaken);

xil_printf("#Runs: %drn", num_tests);

for(test_ctr=0;test_ctr<num_shifts;test_ctr++) timetaken >>= 1;

xil_printf("Avg: %drn", timetaken);

((unsigned int *)moved_summer) = ddr + 0x1000;

for(instr_ctr=0; instr_ctr<num_instructions; instr_ctr++)

((unsigned int *)moved_summer)[instr_ctr] = ((unsigned int *)summer)[instr_ctr];

xil_printf("-- Starting Test (DDR) --rn");

retval = 0;

timetaken = 0;

for(test_ctr=0;test_ctr<num_tests;test_ctr++)

{

starttime = timer[0];

retval = moved_summer(ddr,array_sz);

endtime = timer[0];

timetaken += endtime - starttime;

}

xil_printf("-- Test Finished --rn");

xil_printf("RtVal: %drn", retval);

xil_printf("Taken: %drn", timetaken);

xil_printf("#Runs: %drn", num_tests);

for(test_ctr=0;test_ctr<num_shifts;test_ctr++) timetaken >>= 1;

xil_printf("Avg: %drn", timetaken);

while(1);

return(0);

}

3 OpenFire#1 C Code

unsigned mostly_colors;

unsigned thresh_desired;

unsigned char * rdes = &(((unsigned char *)&mostly_colors)[0]);

unsigned char * r = &(((unsigned char *)&mostly_colors)[1]);

unsigned char * g = &(((unsigned char *)&mostly_colors)[2]);

unsigned char * b = &(((unsigned char *)&mostly_colors)[3]);

unsigned short * thresh = &(((unsigned short *)&thresh_desired)[0]);

unsigned char * gdes = &(((unsigned char *)&thresh_desired)[2]);

unsigned char * bdes = &(((unsigned char *)&thresh_desired)[3]);

unsigned yx_data, sum;

while(1)

{

getfsl(mostly_colors,0);

getfsl(thresh_desired,1);

getfsl(yx_data,2);

sum = ((*r) - (*rdes)) * ((*r) - (*rdes)) +

((*g) - (*gdes)) * ((*g) - (*gdes)) +

((*b) - (*bdes)) * ((*b) - (*bdes));

if(sum < (*thresh))

{

putfsl(yx_data,0);

putfsl(yx_data,1);

}

else

{

putfsl(0,0);

putfsl(0,1);

}

}

需要的开发平台

硬件平台

软件平台

PC机

Linux

QT

Virtex-II Pro开发板

Matlab

ISE

ModelSim

EDK

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: 驱动电源

在工业自动化蓬勃发展的当下,工业电机作为核心动力设备,其驱动电源的性能直接关系到整个系统的稳定性和可靠性。其中,反电动势抑制与过流保护是驱动电源设计中至关重要的两个环节,集成化方案的设计成为提升电机驱动性能的关键。

关键字: 工业电机 驱动电源

LED 驱动电源作为 LED 照明系统的 “心脏”,其稳定性直接决定了整个照明设备的使用寿命。然而,在实际应用中,LED 驱动电源易损坏的问题却十分常见,不仅增加了维护成本,还影响了用户体验。要解决这一问题,需从设计、生...

关键字: 驱动电源 照明系统 散热

根据LED驱动电源的公式,电感内电流波动大小和电感值成反比,输出纹波和输出电容值成反比。所以加大电感值和输出电容值可以减小纹波。

关键字: LED 设计 驱动电源

电动汽车(EV)作为新能源汽车的重要代表,正逐渐成为全球汽车产业的重要发展方向。电动汽车的核心技术之一是电机驱动控制系统,而绝缘栅双极型晶体管(IGBT)作为电机驱动系统中的关键元件,其性能直接影响到电动汽车的动力性能和...

关键字: 电动汽车 新能源 驱动电源

在现代城市建设中,街道及停车场照明作为基础设施的重要组成部分,其质量和效率直接关系到城市的公共安全、居民生活质量和能源利用效率。随着科技的进步,高亮度白光发光二极管(LED)因其独特的优势逐渐取代传统光源,成为大功率区域...

关键字: 发光二极管 驱动电源 LED

LED通用照明设计工程师会遇到许多挑战,如功率密度、功率因数校正(PFC)、空间受限和可靠性等。

关键字: LED 驱动电源 功率因数校正

在LED照明技术日益普及的今天,LED驱动电源的电磁干扰(EMI)问题成为了一个不可忽视的挑战。电磁干扰不仅会影响LED灯具的正常工作,还可能对周围电子设备造成不利影响,甚至引发系统故障。因此,采取有效的硬件措施来解决L...

关键字: LED照明技术 电磁干扰 驱动电源

开关电源具有效率高的特性,而且开关电源的变压器体积比串联稳压型电源的要小得多,电源电路比较整洁,整机重量也有所下降,所以,现在的LED驱动电源

关键字: LED 驱动电源 开关电源

LED驱动电源是把电源供应转换为特定的电压电流以驱动LED发光的电压转换器,通常情况下:LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: LED 隧道灯 驱动电源
关闭