完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
1)实验平台:正点原子领航者ZYNQ开发板
2)平台购买地址:https://item.taobao.com/item.htm?&id=606160108761 3)全套实验源码+手册+视频下载地址:http://www.openedv.com/docs/boards/FPGA/zdyz_linhanz.html 4)对正点原子FPGA感兴趣的同学可以加群讨论:876744900 5)关注正点原子公众号,获取最新资料 第七章OV5640摄像头Sobel边缘检测 边缘检测是图像处理和计算机视觉中的基本问题,边缘检测的目的是标识数字图像中亮度变化明显的点。在本章我们将通过OV5640摄像头Sobel边缘检测实验,来学习如何使用Vivado HLS工具生成实现Sobel边缘检测算法的IP核,以及在Vivado中对综合结果进行验证的流程。 本章包括以下几个部分: 77.1Sobel边缘检测简介 7.2实验任务 7.3HLS设计 7.4IP验证 7.5下载验证 7.1Sobel边缘检测简介 所谓边缘是指其周围像素灰度急剧变化的那些象素的集合,它是图像最基本的特征。边缘存在于目标、背景和区域之间,所以,它是图像分割所依赖的最重要的依据。由于边缘是位置的标志,对灰度的变化不敏感,因此,边缘也是图像匹配的重要的特征。 边缘检测和区域划分是图像分割的两种不同的方法,二者具有相互补充的特点。在边缘检测中,是提取图像中不连续部分的特征,根据闭合的边缘确定区域。而在区域划分中,是把图像分割成特征相同的区域,区域之间的边界就是边缘。由于边缘检测方法不需要将图像逐个像素地分割,因此更适合大图像的分割。边缘大致可以分为两种,一种是阶跃状边缘,边缘两边像素的灰度值明显不同;另一种为屋顶状边缘,边缘处于灰度值由小到大再到小的变化转折点处。边缘检测的主要工具是边缘检测模板。边缘检测的有很多,典型的有索贝尔算子、普里维特算子、罗伯茨交叉边缘检测等边缘检测技术,在本章设计中采用的是索贝尔算子。 索贝尔算子算法简介: 索贝尔算子(Sobel operator)主要用作边缘检测,在技术上,它是一离散性差分算子,用来运算图像亮度函数的灰度之近似值。在图像的任何一点使用此算子,将会产生对应的灰度矢量或是其法矢量。 Sobel卷积因子为: 图 7.1.1 Sobel卷积因子 该算子包含两组 3x3 的矩阵,分别为横向及纵向,将之与图像作平面卷积,即可分别得出横向及纵向的亮度差分近似值。如果以 A 代表原始图像, Gx 及 Gy 分别代表经横向及纵向边缘检测的图像灰度值,其公式如下: 图 7.1.2 横向及纵向的图像灰度值计算公式 图像的每一个像素的横向及纵向灰度值通过以下公式结合,来计算该点灰度的大小: 图 7.1.3 像素的灰度值计算公式 通常,为了提高效率 使用不开平方的近似值,但这样做会损失精度,迫不得已的时候可以如下这样子: 图 7.1.4 像素灰度值的近似计算公式 如果梯度G大于某一阀值,则认为该点(x,y)为边缘点。 7.2实验任务 本节的实验任务是使用Vivado HLS工具设计实现Sobel边缘检测算法的IP核,并在Vivado中对设计出来的IP核进行验证。 7.3HLS设计 我们在电脑中的“F:ZYNQHigh_Level_Synthesis”目录下新建一个名为ov5640_sobel的文件夹,作为本次实验的工程目录。然后打开Vivado HLS工具,创建一个新的工程。设置工程名为“ov5640_sobel”,选择工程路径为刚刚创建的文件夹。需要注意的是,工程名以及路径只能由英文字母、数字和下划线组成,不能包含中文、空格以及其他特殊字符。如下图所示: 图 7.3.1 工程配置界面 设置好工程名及路径之后,点击“Next”,进入如下界面设置顶层函数: 图 7.3.2 设置顶层函数 工程创建完成后,在工程面板中的“source”目录上点击右键,然后在打开的列表中选择“New File”新建源文件,在弹出的对话框中输入源文件的名称“ov5640_sobel.cpp”,如图1.3.3所示。源文件默认的保存路径为HLS工程目录,为方便源文件的管理,我们在工程目录下新建一个名为“src”的文件下,将源文件保存在src目录下。 图 7.3.3 输入源文件名 我们输入的源文件的后缀名为“.cpp”,即使用C++语言进行设计。这是因为我们要使用Vivado HLS视频库,那么就只能使用C++来进行设计。 “ov5640_sobel.cpp”文件源代码如下:
本章实验的实验代码与《领航者ZYNQ之HLS开发指南》第5章“OV5640摄像头灰度显示实验”类似,不同之处是本章实验代码增加了一个边缘检测函数“Sobel”。代码的其他部分可以参考《领航者ZYNQ之HLS开发指南》第5章“OV5640摄像头灰度显示实验”。 在代码的第29行调用HLS命名空间中的“Sobel”函数,这个函数在UG902中的介绍如下图所示: 图 7.3.4 sobel函数 图中的“Synopsis”是概要的意思。从图中可以看出Vivado HLS视频库中定义了两个Soebl函数,这个是C++中函数重载的概念,编译器根据函数模板输入参数的不同,选择调用相应的函数。图中的“template”是函数模板的概念,它通过将类型作为参数传递给模板,可使编译器生成该类型的函数。图中的“XORDER”和“YORDER”这两个参数可以设置采用水平方向或垂直方向的Sobel算子,Vivado HLS只支持“XORDER=1,YORDER=0”(指采用水平方向的Sobel算子)或者“XORDER=0,YORDER=1”(指采用垂直方向的Sobel算子)的设置。在本章实验中我们设置“XORDER=1,YORDER=0”表示采用水平方向的Sobel算子进行X轴方向的边缘检测。图中的“SIZE”表示设置Sobel算子模板的大小,Vivado HLS支持设置Sobel算子的大小为3、5、7。本章实验我们设置Sobel算法的大小为3,表示采用3*3的Sobel算子模板。图中的“BORDERMODE”表示设置边界的类型,由于本章我们没有传入边界类型的参数,所以编译器调用了第二个Sobel函数。图中的“SRC_T”表示输入图像的类型,图中的“DST_T”表示输出图像的类型,这里输入和输出图像都是8位无符号单通道数据类型。图中的“ROWS”和“COLS”表示输入图像像素的行和列,图中的“DROWS”和“DCOLS”表示输出图像像素的行和列。 “ov5640_sobel.h”头文件代码如下:
在代码的第1行和第2行是为了防止头文件的重复定义。在代码的第4行引入了“hls_opencv.h”头文件是为了使用Vivado HLS工具给我们提供的数据类型。在代码的第6行和代码的第7行定义了图像的最大高度和宽度。在代码的第9行定义了输入图像是“lena.jpg”,在代码的第10行定义了输出图像是“lena_sobel.jpg”。在代码的第12行定义了AXI_STREAM格式的数据类型,第一个参数24表示我们采用的数据是24位宽。在代码的第13行和第14行分别定义了“RGB_IMAGE”和“GRAY_IMAGE”格式的数据类型。在代码的第16行“ov5640_sobel”是函数的声明。 当工程比较复杂的时候,可以进行C代码仿真。C代码仿真的步骤如下:在工程面板中的“Test Bench”目录上点击右键,在打开的列表中选择“New File”新建源文件,然后在弹出的对话框中输入测试文件的名称“ov5640_sobel_tb.cpp”,为方便测试文件的管理我们将测试文件保存在src目录下,如下图所示: 图 7.3.5 测试文件目录 “ov5640_sobel_tb.cpp”程序如下所示:
在代码的第2行引入了“hls_opencv.h”,这个头文件里面包含了opencv库。在代码的第4行定义了main函数,在代码的第7行调用“cvLoadImage”函数来载入输入图像。在代码的第8行调用“cvCreateImage”来创建输出图像,参数“cvGetSize(src)”表示创建和输入图像一样大小的输出图像,参数“src->channel”表示创建的输出图像的通道和输入图像一样也是三通道的。在代码的第11行定义了两个变量“src_axi”和“dst_axi”,这两个变量的数据类型是AXI_STREAM格式。在代码的第12行通过调用IplImage2AXIvideo函数来将opencv中的IplImage格式的图像数据类型转换成AXI4-Stream格式的图像数据流从而可以利用FPGA进行数据处理。在代码的第13行调用“ov5640_sobel”函数来将对图像进行sobel边缘处理。在代码的第14行调用AXIvideo2IplImage将Sobel边缘处理后的图像转换成opencv可以处理的数据类型。在代码的第17行通过调用cvSaveImage来保存Sobel边缘处理后的图像。在代码的第20行和第21行通过调用cvShowImage来显示原图像和边缘处理后的图像。在代码的第24行通过调用waitKey这个函数来等待用户输入,从而避免程序运行完成,图像一闪而过。 下面进行C仿真,将“lena.jpg”图像加入到测试平台,在工程面板中的“Test bench”目录上点击右键,然后在打开的列表中选择“New File”新建源文件,为方便测试文件的管理我们将“lena.jpg”保存在src目录下,如下图所示: 图 7.3.6 lena图片目录 点击“Run C Simulation”按钮,如下图所示: 图 7.3.7 C仿真 上图中左边红框标出来的就是我们加入的输入图像,右边红框即为C仿真按钮。仿真结果如下图所示: 图 7.3.8 仿真结果 从仿真结果中可以看出我们实现了X轴方向的Sobel边缘检测。 接下来点击工具栏中向右的绿色三角形对C代码进行综合,如下图所示: 图 7.3.7 运行C综合 综合完成后,会自动打开综合结果(solution)的报告,综合报告中给出了设计的性能评估、资源评估以及接口等信息。本次实验中,我们重点关注综合工具为我们生成的接口信息,如下图所示: 图 7.3.8 接口信息 从图中可以看出,设计综合出了一个“AXI4-Lite”从接口和两个“AXI4-Stream”接口(一个输入,一个输出)。其中“AX4-Lite”总线接口用于控制视频处理的分辨率,而两个“AXI4-Stream”总线接口分别用于输入待处理的视频以及输出处理之后的视频流。 在综合结果正确的情况下,在工具栏中点击黄色的“田”字按钮,导出RTL。 在导出RTL结束之后,我们到工程目录所指向的文件夹中可以看到以ZIP压缩文件形式存在的IP核,如下图所示: 图 7.3.9 将设计导出成IP HLS设计结束之后,我们将在Vivado中对导出的IP核进行验证。 7.4IP验证 在IP验证环节,我们会使用Vivado工具的IP集成器将生成的IP核添加到Block Design中,然后完成设计后将程序下载到领航者开发板上进行验证。 用于IP验证的底层硬件可以在《领航者ZYNQ之HLS开发指南》第5章“OV5640 摄像头灰度显示”实验的基础上进行。打开该实验所对应的Vivado工程“ov5640_rgb2gray_ip_test”,将其另存为“ov5640_sobel_ip_test”工程。为了方便工程管理,我们将Vivado工程的目录与HLS工程目录保持一致,如下图所示: 图 7.4.1 创建Vivado工程 在通过“另存为”的方式保存工程之后,还要将原来工程中的IP库(名为ip_repo的文件夹)复制到新的Vivado工程目录下, 然后将HLS设计过程中导出的IP核拷贝到“ip_repo”目录下并解压,解压完成后如下图所示: 图 7.4.2 拷贝并解压IP 在Vivado中重新将当前工程目录下的ip_repo文件夹添加到工程的IP库中,然后将HLS生成的IP核Ov5640_sobel添加到Block Design中,并将其STREAM接口分别连接到Video In to AXI4-Stream模块的video_out接口与VDMA模块的S_AXIS_S2MM接口上。最后点击上图中左上角的“Run Connection Automation”,让工具自动连接该IP核的其他端口,包括时钟、复位以及AXI-Lite从接口,最终完成的设计如下图所示: 图 7.4.4 完成后的Block Design 到这里我们的Block Design就设计完成了,在Diagram窗口空白处右击,然后选择“Validate Design”验证设计。验证完成后弹出对话框提示“Validation Successful”表明设计无误,点击“OK”确认。最后按快捷键“Ctrl + S”保存设计。 接下来在Source窗口中右键点击Block Design设计文件“system.bd”,然后依次执行“Generate Output Products”和“Create HDL Wrapper”。 最后在左侧Flow Navigator导航栏中找到PROGRAM AND DEBUG,点击该选项中的“Generate Bitstream”,对设计进行综合、实现、并生成Bitstream文件。 在生成 Bitstream 之后,在菜单栏中选择 File > Export > Export hardware 导出硬件,并在弹出的对话框 中,勾选“Include bitstream”。然后在菜单栏选择 File > Launch SDK,启动 SDK 软件。 在Vivado SDK中新建空的应用工程,工程名为“ov5640_sobel_lcd”。 然后找到《领航者ZYNQ之嵌入式开发指南》第二十三章“OV5640 摄像头 LCD 显示”实验的Vivado工程目录,将“21_ov7725_lcdov7725_lcd.sdkov7725_lcd”目录下的src文件夹拷贝到新建的应用工程目录下。 在SDK中刷新src目录,然后将“main.c”的代码修改为如下所示:
在代码的第14行引入了“xov5640_sobel.h”头文件,这个头文件是Vivado HLS工具生成的,里面声明了灰度转换IP核的驱动函数。首先在代码的34行定义了边缘检测IP核的驱动实例sobel_inst,该变量会在后面对IP核进行配置时用到。然后在代码的第112行通过“XOv5640_sobel_Initialize()”函数来初始化Vivado HLS生成的边缘检测IP核;在代码的第116行通过传入“vd_mode.height”形参来设置灰度转换IP核的行数,在代码的第114行通过传入“vd_mode.width”形参来设置列数。这些数据类型和函数在“xlcd_rgb_color.h”头文件中均有声明。 7.5下载验证 编译完工程之后我们就可以开始下载程序了。将 OV5640 摄像头模块插在领航者 Zynq 开发板的“OLED/CAMERA”插座上,并将 LCD 的排线接头插入开发板上的 LCD 接线座。将下载器一端连电脑,另一端与开发板上的 JTAG 端口连接,连接电源线并打开电源开关。 在 SDK 软件下方的 SDK Terminal 窗口中点击右上角的加号设置并连接串口。然后下载本次实验硬件设计过程中所生成的 BIT 文件,来对 PL 进行配置。最后下载软件程序,下载完成后在LCD上就可以看到摄像头采集的彩色图像被转换成了X方向的灰度图像,如下图所示: 图 7.5.1 Sobel边缘检测 |
|
相关推荐
|
|
该问题是用APP给芯海科技的CST92F25芯片发指令是出现的
860 浏览 1 评论
546 浏览 0 评论
1176 浏览 1 评论
1886 浏览 1 评论
飞凌嵌入式ElfBoard ELF 1板卡-spi编程示例之spi编写程序
1138 浏览 0 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-17 02:22 , Processed in 0.637239 second(s), Total 66, Slave 48 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号