赛灵思“安富利杯”LX9开发板使用征文
--基于LX9的图像直方图均衡化处理
xie0jing0
对于开发板,在我的印象中,就是一个大大的电路板,可能还有其他对插的小板子,配上笨重的电源,再加上下载器,另外不可避免的就是一大堆导线。可是LX9这个小套件改变了我的想法。在手指大小的空间里就集成了FPGA、SDRAM、FLASh,供电与下载都由一个USB口实现,特别适合在家中学习和实验。别看他小,可是LED、按键、UART、Ethernet样样都行,随着套件配备了各个功能的开发例程,让我们学起来上手特别快。板子也特意留出了扩展IO,让我们更能随心所欲的发挥。
Microblaze嵌入式系统开发是这个小板子的强项,也是安富利设计其的用意所在。Spartan6的强大也在此深有体现。既然是以嵌入式CPU为主题,那么拿到板子做什么好呢?首先进入脑海的就是图像处理。FPGA在图像处理领域具有非常重要的地位。它凭借处理速度快,大规模并行处理,应用灵活,时序控制精准的特点,常常被需要高速海量数据处理的图像采集处理模块所应用。但FPGA也有其致命的弱点,就在于运算能力较弱,应对图像数据复杂的分析处理就显得力不从心了。这时,往往要加上一片DSP完成数字信号处理。使得整个电路复杂庞大。而现在,Microblaze就给我们展示了另一种解决方案。FPGA完成外围控制与数据传输的功能而应用嵌入式CPU替代DSP完成数据运算处理,克服的FPGA+DSP模式的不足,使得设计简单紧凑,时序性更好,会有很好的发展前景。
之后就来说说我的试用之旅吧。首先确定方向是做图像处理,具体就做个最基础的图像直方图均值化吧。大概的体系设想是这样:首先,通过UART将图像数据由电脑传输至电路板,并存储,然后统计图像直方图,进行对比度分析处理,最后将处理后的数据再通过UART传回电脑,以验证算法。有了大体的思路,就开始动手了。
软件用的是ISE12.4的版本。第一步,参照Avnet_S6_LX9_Microboard_Configuration_Guide将UART、JTAG等相关的驱动安装好,对板子进行了初步的测试。前面的博客有不少都做了详细的说明,在这就不多说了。经过小半天的折腾,终于调通了,看着板上的流水灯一闪闪的,心里的尽头更足了。
第二步,就是照着J800_AvtS6LX9MicroBoard_MBHP_Create来实现一个自己定制的硬件平台。在这里得感谢第一批试用的朋友们,我在网上没下到LX9的XBD文件,还是他们给我传过来的,谢谢啦!按照MBHP_Create一步一步的走,其中也根据自己项目的特点稍作了更改,将CPU的内存容量扩大到了8K,去掉了Ethernet_MAC、SPI_FLASH等暂时不需要的模块,最后产生的资源如下图所示。
经过漫长的编译,终于完成了硬件平台的搭建,下一步就是灵活的软件设计了。
第三步,软件设计。首先,是参照AvtS6LX9MicroBoard_SW101_Hello_World_12_4_01文档走了一遍,对软件设计流程有了了解。编译好文件,连好电路,烧写程序,果然稍等片刻,在串口调试助手上出现了Hello World的字样!再接再厉。
下一步,开始调试各个应用模块。首当其冲的是UART。UART协议简单,硬件要求低,应用十分广泛,我也采用它作为数据传输的媒介。在ISE的安装目录下有各个IP核的说明文档和例程。我找到了UART的examples文件夹,重点学习了xuartlite_low_level_example.c和xuartlite_selftest_example.c。有人建议要仔细看看相关的API文档,个人觉得可以偷个懒,Xilinx的例程里注释写的很详细,学习学习examples,简单的应用就能上手了。下面是我写的基于查询方式的UART应用代码,程序自动将接收来的数据再发送出去。经过在电路上的验证,证明代码还是可行的。下图是串口调试助手收发数的情况。
#include <stdio.h>
#include "platform.h"
#include "xparameters.h"
#include "xuartlite.h"
#define TEST_BUFFER_SIZE 16
XUartLite ptrUart;
Xuint8 SendBuffer[TEST_BUFFER_SIZE]; /* Buffer for Transmitting Data */
Xuint8 RecvBuffer[TEST_BUFFER_SIZE]; /* Buffer for Receiving Data */
int main()
{
init_platform();
XUartLite_Initialize(&ptrUart, XPAR_USB_UART_DEVICE_ID);
while(1)
{
if(XUartLite_Recv(&ptrUart,RecvBuffer,1)==1)
{
*SendBuffer = *RecvBuffer;
XUartLite_Send(&ptrUart,SendBuffer,1);
}
}
print("Hello World\n\r");
cleanup_platform();
return 0;
}
一个要注意的地方就是在线烧写软件时,不要勾选Connect STDIO to Console,否则会出现串口使用冲突的问题。然后,又发现串口调试助手不能直接读入txt文件的数据,却可以识别bin文件。于是,自己动手写了MATLAB程序,将图像数据转换成了bin数据文件备用。程序如下:
function gen_data
I = imread('pout_s.tif');
fid = fopen('picdata_s.bin','wb')
fwrite(fid,I,'uint8');
串口调好了再试试GPIO。因为拨码开关实在太小了,就不实验IO输入了,直接上LED输出。也是参考了Xilinx的example。在UART基础上修改,得到如下代码,完成了闪烁灯。
#include <stdio.h>
#include "platform.h"
#include "xparameters.h"
#include "xuartlite.h"
#include "xgpio.h"
#define TEST_BUFFER_SIZE 16
XUartLite ptrUart;
Xuint8 SendBuffer[TEST_BUFFER_SIZE]; /* Buffer for Transmitting Data */
Xuint8 RecvBuffer[TEST_BUFFER_SIZE]; /* Buffer for Receiving Data */
#define LED_DELAY 500000
XGpio ptrGpio;
int main()
{
volatile int Delay;
u8 LedData = 1;
init_platform();
XUartLite_Initialize(&ptrUart, XPAR_USB_UART_DEVICE_ID);
XGpio_Initialize(&ptrGpio,XPAR_LEDS_4BITS_DEVICE_ID);
XGpio_SetDataDirection (&ptrGpio,1,0);
while(1)
{
if(XUartLite_Recv(&ptrUart,RecvBuffer,1)==1)
{
*SendBuffer = *RecvBuffer;
XUartLite_Send(&ptrUart,SendBuffer,1);
}
if (LedData==1)
{
LedData = 0;
XGpio_DiscreteWrite(&ptrGpio, 1, LedData);
}
else
{
LedData =1;
XGpio_DiscreteWrite(&ptrGpio, 1, LedData);
}
for (Delay = 0; Delay < LED_DELAY; Delay++);
}
print("Hello World\n\r");
cleanup_platform();
return 0;
}
下一步本该是mpmc的调试。可惜的是左看example,又看API介绍,还是没有头绪,小试了几回也不尽人意,向百度求救还是无果。由于想了个不太高明的办法先绕过这个坎,等以后时间充裕再回头调。办法就是:将图像数据第一次下穿进开发板,进行统计图像直方图,所有数据传输过后,直方图统计完毕,再将数据二次载入开发板,根据先前的统计结果直接进行灰度转换。这样就避免了数据存储的困难,呵呵。
之后就是对图像的处理算法的编写了。因为对MATLAB比较熟,还是先在MATLAB上写个程序验证下思路。图像直方图均衡化也有多种处理手段。其目的就是在于增加图像的对比度,使图像更清楚显著。我借鉴的方法是MATLAB的imadjust算法,实现简单,在忠于原图的基础上最大程度的把对比度不好的图像变清晰。测试m文件如下。运行结果如下图,从图可见,这个小程序确实能使图像像质变好不少。
function mypic_adjust
I = imread('pout.bmp');
figure, imshow(I),
[n,m]=size (I);
k=n*m/1000; %70
h=zeros(256,1);
for i=1:n
for j=1:m
h(I(i,j)) = h(I(i,j))+1;
end
end
fs=0;fe=0;
for i=1:256
if ( h(i) >= k && fs==0)
Ns=i;fs=1;
end
end
for i=256:(-1):1
if ( h(i) >= k && fe==0)
Ne=i;fe=1;
end
end
I_just=double(I);
for i=1:n
for j=1:m
if ( I(i,j)<= Ns )
I_just(i,j) = 0;
elseif ( I(i,j)>= Ne )
I_just(i,j) = 255;
else
I_just(i,j) = round( 256/(Ne-Ns+1)*((I(i,j)- Ns)) );
end
end
end
I_just=uint8(I_just);
figure, imshow(I_just)
imwrite(I_just,'pout_1.bmp');
图像对应的直方图如下图,可见处理的图像直方图分布更均匀,图像对比度更好。
本视频基于Xilinx公司的Artix-7FPGA器件以及各种丰富的入门和进阶外设,提供了一些典型的工程实例,帮助读者从FPGA基础知识、逻辑设计概念
本课程为“从零开始大战FPGA”系列课程的基础篇。课程通俗易懂、逻辑性强、示例丰富,课程中尤其强调在设计过程中对“时序”和“逻辑”的把控,以及硬件描述语言与硬件电路相对应的“
课程中首先会给大家讲解在企业中一般数字电路从算法到流片这整个过程中会涉及到哪些流程,都分别使用什么工具,以及其中每个流程都分别做了
@2003-2020 中国电子顶级开发网