博主是一个年初刚刚接触FPGA的新人,说实话觉得自己还是挺水的。上年的12月份刚刚了解了什么是FPGA,然后就参加了一个叫全国大学生集成电路创新大赛的比赛,里面的robei杯(当然可以后续和我交流一下这个杯赛的要求和看法),现在比赛结束了,华南赛区二等,虽然跟大佬比起来差距很大,但还是比较满意了。
题目大概是不规定你做什么,但要体现出机器人。阴差阳错的向指导老师请教了一下,做一个火焰识别的系统。网上找了很多算法,感觉比较容易实现的就是帧差了,就基于老师给的米联客的zynq7020做了一个基于帧差的运动目标检测系统。因为我自己做的时候找这方面的资料很多都是付费的,所以想在这里分享一下思路(我只是一个二本的学生,很水很菜,勿喷),可以在评论区和我交流一下
用到的了米联客自己开发的fdma和fdma的控制器,然后参考了朽月这位fpga博主还有咸鱼fpga的一些算法。
先放上一个自己写的系统框图。
大概的系统框图就是这个样子的,我用的是ov5640这一款的传感器,是基于米联客的驱动ov5640缓存到ddr的demo写的,有兴趣的同学可以寻找一下米联客的demo例程。在demo当中只用到了一个FDMA和一个FDMA控制器,因为要做一个帧差处理,我加多了一个FDMA(在BD文件中)和FDMA控制器,将第一个FDMA的读信号作为第二个FDMA的写信号,将第一个FDMA的读数据作为第二个FDMA的写数据其他,信号不变,再进行帧差的处理。
图像处理里面我没有在这个框图中细分,
大概分为先对进入的俩路rgb数据进行灰度化(这部分有很多教程,我建议是进行流水线级别的操作,不要用组合逻辑进行灰度化,这样有利于时钟的打拍),可以去搜一下关于rgb转ycbcr的算法,其中的y分量就是我们要取得灰度值了。
灰度化取绝对值再相减(这一部分我们要注意取绝对值,其实就是先比较俩个数据的大小,让他们去减小的就ok了)得出来的数据我们设置一个阈值和它进行比较,就可以得出一个二值图像(一开始做调试的时候我建议阈值的数值写一个按键来让他增加或者减少,方便我们上屏幕观察)
核心代码如下:
always @(posedge clk or negedge rst_n) begin
if(!rst_n)
imgPixel_out <= 8'b0;
else if(rgb_data_gray1 >= rgb_data_gray2 && vga_de)
imgPixel_out <= (rgb_data_gray1 - rgb_data_gray2 > threshold) ? 8'hff : 8'b0;
else if(rgb_data_gray1 < rgb_data_gray2 && vga_de)
imgPixel_out <= (rgb_data_gray2 - rgb_data_gray1 > threshold) ? 8'hff : 8'b0;
end
得出二值图像之后,我们就需要做一个最小包围盒的代码来让他被框出来了,毕竟是物体的检测嘛,这一部分可以参考一下咸鱼fpga的人脸识别那一部分的内容,有比较详细的介绍。
接下来就是在屏幕上显示出来了,我们把方框叠在我们摄像头拍到的图像上,在hdmi上进行显示,核心代码如下:
assign data_out =(right_en||left_en||bottom_en||top_en)?24'b11111111_00000000_00000000:background;
大概的思路就是这个样子,其实这个框图中每一个过程网上都有许多例程和教程,推荐大家区看一下咸鱼fpga对运动目标检测的一篇博客,还有朽月这一位fpga博主写的关于腐蚀和膨胀的算法。了解一个基本的过程。作为一个fpga小白,分享的东西干货也许不多,希望大家一起加油!一起努力!