基于FPGA利用SDRAM的屏幕四分 监控视频

背景:经常可以在一些监控系统中看到一种应用,那就是一个显示屏被划分成多个部分,每个部分显示不同的画面,本篇博客就来讲讲基于SDRAM在FPGA开发板上如何来实现这一需求。简单来说我们要实现的功能如下图:

图一:
在这里插入图片描述

图二:
在这里插入图片描述
摄像头正常拍摄的图像如图一所示,我们要实现的功能就如图二所示(图二中间有白条是因为我用的word截图,可以忽略)

要想实现这个功能,首先你应该能调通视频流,并驱动其在VGA上显示,简单地说就是你应该会单屏幕的摄像头视频显示(如果这个有问题可以参考我的上一篇博客)

在你的摄像头能调通之后,我们就要来实现屏幕四分的功能了,在屏幕上四个区域显示四个相同的画面,要实现这个功能我们首先要明确两点内容

1:你的像素点肯定要减少。
我们现在要在一个大小只有整个屏幕1/4的区域显示原来整个屏幕的一幅图,那很显示你的像素要丢掉3/4,但是这个3/4的像素点又不是随便丢掉的,因为左上角那个区域虽然少了3/4个像素点,但是你仍能看到的是整个人,而不是1/4的人吧,明白了这一点那自然也就明白了该怎么合理地丢掉3/4个像素点,那就是一行中隔一个取一个像素点,关于列是隔一列用一列,这样虽然像素点少了,但是整个图的轮廓我们是可以出来的

这里多提一句,我这个做法是最粗暴的,这里相当于把直接取了四个点左上脚那一个点,对其他三个点我们直接舍弃,要是最求图像的精确图最高的话,更合理的做法是对这四个点加权平均按一定的比例算法得到一个像素点。

2:一个像素点要被重复使用四次
这个看图一下就看出来了,但是在硬件上我们知道,摄像头产生的是一个数据流,它的一个像素点只会出现一次,也就是说当我们的VGA时序扫描到右上角那个区域时,我们想要的像素点的数据跟此时摄像头产生的数据肯定是不一样的。知道了问题的所在,我们的解决方法也很简单,当第一个数据来的时候,我们把它保存起来,这样不就可以用四次了吗。那用什么寄存器啦?很显然是外部寄存器例如SDRAM、DDR等,肯定不能是片上寄存器例如ram甚至FIFO等,因为我们至少要缓存半帧的数据。

思路想清楚之后我们就来进行结构模块的划分(这里默认你已经有一个能调通的视频流显示工程,没有可以参考我的上一篇博客),可以大致添加两个模块,一个模块实现数据的刷选,就是上面说的去掉3/4个像素,再一个模块用来实现把每一个像素点写四次,即是上面说的第二点

第一个模块choose_data.v很简单,摄像头的数据流进来之后跳着读实现数据筛选即可

第二个模块应该注意这样几点,
1:每一次写到SDRAM的数据的起始地址是不一样的,要用状态机严格控制好
2:SDRAM的潜伏期,就是说当SDRAM的命令总线收到一条命令,到这条命令被执行,是有几个时钟的潜伏期的,所以这里状态机的时序控制一定要很严格。举个简单的例子,一个数据不是要被写四次吗,但是每次写到SDRAM的初始地址是不一样的,所以最好在这个数据被写到SDRAM之前,它的初始地址已经提前几个时钟就到了。(这个有点类似于setup 建立时间)

整个工程其实就是在前端把数据做一些处理,让数据按照我们想要的时序存储到SDRAM中,后端只需要按照hs_sync, vs_sync的正常时序读取SDRAM即可,就能实现特定的显示需求。

这里我们四个区域的图是一样的,其实我们完全还可以弄成不一样的,比如在前端再加一个算子,得到灰阶图像数据,把这一部分数据存到SDRAM对应的区域2的位置,还可以做二值域处理,实现边沿检测,甚至再加区域连通算法,实现特定物体的识别功能,这样四个区域可以显示同时显示不同的内容。

效果展示(CSDN上不能录制视频,其实效果是视频流的效果)
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/jiyishizhe/article/details/103035207