FPGA图像处理HLS实现sobel边沿检测,提供HLS工程和vivado工程源码

一、sobel边沿检测原理

所谓边缘是指其周围像素灰度急剧变化的那些象素的集合,它是图像最基本的特征。边缘存在于目标、背景和区域之间,所以,它是图像分割所依赖的最重要的依据。由于边缘是位置的标志,对灰度的变化不敏感,因此,边缘也是图像匹配的重要的特征。
边缘检测和区域划分是图像分割的两种不同的方法,二者具有相互补充的特点。在边缘检测中,是提取图像中不连续部分的特征,根据闭合的边缘确定区域。而在区域划分中,是把图像分割成特征相同的区域,区域之间的边界就是边缘。由于边缘检测方法不需要将图像逐个像素地分割,因此更适合大图像的分割。边缘大致可以分为两种,一种是阶跃状边缘,边缘两边像素的灰度值明显不同;另一种为屋顶状边缘,边缘处于灰度值由小到大再到小的变化转折点处。边缘检测的主要工具是边缘检测模板。边缘检测的有很多,典型的有索贝尔算子、普里维特算子、罗伯茨交叉边缘检测等边缘检测技术,在设计中采用的是索贝尔算子。
索贝尔算子(Sobel operator)主要用作边缘检测,在技术上,它是一离散性差分算子,用来运算图像亮度函数的灰度之近似值。在图像的任何一点使用此算子,将会产生对应的灰度矢量或是其法矢量。Sobel 卷积因子为:
在这里插入图片描述
该算子包含两组 3x3 的矩阵,分别为横向及纵向,将之与图像作平面卷积,即可分别得出横向及纵向
的亮度差分近似值。如果以 A 代表原始图像,Gx 及 Gy 分别代表经横向及纵向边缘检测的图像灰度值,
其公式如下:
在这里插入图片描述
图像的每一个像素的横向及纵向灰度值通过以下公式结合,来计算该点灰度的大小:
在这里插入图片描述
通常,为了提高效率 使用不开平方的近似值,但这样做会损失精度,迫不得已的时候可以如下这样子:
在这里插入图片描述
如果梯度 G 大于某一阀值,则认为该点(x,y)为边缘点。

二、HLS方案实现sobel边沿检测

在前面的sobel边沿检测原理中详细介绍了sobel边沿检测的算法公式,看起来很复杂很NB对吧?
然并卵!!!!!!!
然并卵!!!!!!!
然并卵!!!!!!!
因为对于HLS来说,干这活儿只需要一句话一行代码即可实现;
因为Xilinx早就帮你做好了sobel边沿检测的库,并且可以综合,既然如此,我还需要去管他怎么实现的,算法公式是怎样的吗?这就是HLS的NB之处。。。
HLS工程如下:
在这里插入图片描述
综合后的延时、资源占用等性能参数如下:
在这里插入图片描述
在这里插入图片描述
头文件如下:

#ifndef _HELAI_HLS_SOBEL_H
#define _HELAI_HLS_SOBEL_H

#include "hls_video.h"

#define MAX_HEIGHT 1080    //图像最大高度
#define MAX_WIDTH  1920    //图像最大宽度

#define INPUT_IMAGE        "luoli.jpg"
#define OUTPUT_IMAGE       "luoli_hls.jpg"

typedef hls::stream<ap_axiu<24,1,1,1> > AXI_STREAM;
typedef hls::Mat<MAX_HEIGHT,MAX_WIDTH,HLS_8UC3> RGB_IMAGE;
typedef hls::Mat<MAX_HEIGHT,MAX_WIDTH,HLS_8UC1> GRAY_IMAGE;

void helai_hls_sobel(AXI_STREAM&INPUT_STREAM,AXI_STREAM&OUTPUT_STREAM,int rows,int cols);
#endif

源文件的核心代码如下:

hls::Sobel<1,0,3>(img_1,img_2);	//将灰度数据与Sobel算子卷积	

核心代码就一句话,BN吧?呵呵。。。。。。

三、HLS在线仿真并导出IP

仿真源文件如下:

#include "helai_hls_sobel.h"
#include "hls_opencv.h"

int main(void)
{
	//获取图像数据
	IplImage* src = cvLoadImage(INPUT_IMAGE);
	IplImage* dst = cvCreateImage(cvGetSize(src),src->depth,src->nChannels);

	//使用HLS库进行处理
	AXI_STREAM src_axi,dst_axi;
	IplImage2AXIvideo(src,src_axi);
	helai_hls_sobel(src_axi,dst_axi,src->height,src->width);
	AXIvideo2IplImage(dst_axi,dst);

	//保存图像
	cvSaveImage(OUTPUT_IMAGE,dst);

	//显示图像
	cvShowImage(INPUT_IMAGE,src);
	cvShowImage(OUTPUT_IMAGE,dst);

	//等待用户按下键盘上的任一按键
	cv::waitKey(0);
}

话不多说直接看HLS仿真结果:
在这里插入图片描述
在这里插入图片描述
仿真完整成功后即可综合再导出IP:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

四、Kintex7开发板vivado工程验证

开发板:Xilinx Kintex7开发板;
开发环境:HLS2019.1;vivado2019.1;
输入:OV5640摄像头,输入分辨率1280x720;
输出:HDMI,输出分辨率1920x1080;
工程BD如下:
在这里插入图片描述
生成顶层RTL如下:
在这里插入图片描述
SDK主函数源码如下:

#include <stdio.h>
#include "xgpio.h"
#include "oak_iic.h"
#include "unistd.h"
#include "helai_vdma.h"
#include "helai_color_back.h"
#include "helai_hls_sobel.h"

XGpio_Config *XGpioCfg;
XGpio led_gpio;

#define	AXI_GPIO_DEVICE_ID	XPAR_GPIO_0_DEVICE_ID

int main(){
	XGpioCfg = XGpio_LookupConfig(AXI_GPIO_DEVICE_ID);
	XGpio_CfgInitialize(&led_gpio, XGpioCfg, XGpioCfg->BaseAddress);
	XGpio_SetDataDirection(&led_gpio, 1, 0);	//output
	XGpio_DiscreteWrite(&led_gpio, 1, 0);
	oak_i2c_init(OV5640_IIC_BASEADDR, 1000000, 0x78>>1, IIC_REG_LEN16, IIC_DATA_LEN8);
	OV5640_Init(OV5640_IIC_BASEADDR,1280,720);
	helai_hls_sobel(720,1280);
	helai_vdma();
	while(1){
		usleep(500000);
		XGpio_DiscreteWrite(&led_gpio, 1, 1);
		usleep(500000);
		XGpio_DiscreteWrite(&led_gpio, 1, 0);
	}
}

五、zynq7100开发板vivado工程验证

开发板:Xilinx zynq7100开发板;
开发环境:HLS2019.1;vivado2019.1;
输入:OV5640摄像头,输入分辨率1280x720;
输出:HDMI,输出分辨率1920x1080;
工程BD如下:
在这里插入图片描述
生成顶层RTL如下:
在这里插入图片描述
SDK主函数源码如下:

#include "I2C_16bit.h"
#include "xiicps.h"
#include "xil_io.h"
#include "xparameters.h"
#include "helai_vdma.h"
#include "helai_hls_sobel.h"

void main()
{
	// Initialize OV5640 regesiter
	I2C_config_init();
	helai_hls_sobel(720,1280);
	helai_vdma();
	while (1) ;
}

六、板级调试验证

K7开发板和zynq开发板实物连接如下:图中K7为连接状态
在这里插入图片描述
运行结果静态展示:
在这里插入图片描述
下载程序后运行结果如下:以K7开发板为例,持续运行48小时无问题

HLS图像处理sobel

七、福利:工程源码获取

福利:工程代码的获取
代码太大,无法邮箱发送,以某度网盘链接方式发送,
工程源码下载链接:https://download.csdn.net/download/qq_41667729/87391204
K7开发板网盘资料如下:
在这里插入图片描述
zynq开发板网盘资料如下:
在这里插入图片描述

  • 0
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

9527华安

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值