基于Sobel算法的边缘检测设计与实现(一张图绝杀必懂)
1、边缘检测
针对的时灰度图像,顾名思义,检测图像的边缘,是针对图像像素点的一种计算,目的时标识数字图像中灰度变化明显的点,图像的边缘检测,在保留了图像的重要结构信息的同时,剔除了可以认为不相关的信息,大幅度减少了数据量,便于图像的传输和处理;
边缘检查的方法大致可以分为两类:基于查找的一类,通过寻找图像一阶导数中最大值和最小值来检测边界,包括Sobel算法、Roberts Cross算法等;基于零穿越的一类,通过寻找图像二阶导数零穿越来寻找边界,包括Canny算法,Laplacian算法等。
Sobel算法:准确率比较低,但是效率比较高;
详细见下面网址:
https://blog.csdn.net/great_yzl/article/details/119709699
Soble算法的核心就是Sobel算子,该算子包含两组3x3的矩阵;
对于图像而言,取3行3列的图像数据,将图像数据与对应位置的算子的值相乘再相加,得到x方向的Gx,和y方向的Gy,将得到的Gx和Gy,平方后相加,再取算术平方根,得到Gxy,近似值为Gx和Gy绝对值之和,将计算得到的Gxy与我们设定的阈值相比较,Gxy如果大于阈值,表示该点为边界点,此点显示黑点,否则显示白点。
2、实验设计
我们将Sobel算法在图像边缘检查中的实现分为4步,第1步,通过Gx、Gy的计算公式结合FIFO求和算法求取Gx、Gy的值;第2步,求得Gx、Gy的绝对值;第3步,将Gx、Gy带入Gxy计算公式,求得Gxy的值;第4步,将求得的Gxy与设定的阈值相比较,当Gxy大于等于阈值,赋值rgb为黑色,否则, rgb赋值为白色。
图片正在经过Sobel算法之后,输出的图片相比于输入时的图片会少2行2列数据,这是因为在求取Gx、Gy时,要使用FIFO求和算法,该算法只有在第2行或第2列数据输入时才开始执行,第0、1行或第0、1列不会进行求和运算,更无数据输出,所以会缺失的2行2列。
2.1 实验目标
实验目标:使用Matlab软件将图片转换为灰度图像,并且将灰度图像的高 3 位取出存放为txt 文本 ,PC机通过串口RS232传输图片数据给FPGA,FPGA通过Sobel算法检测出图片的边缘轮廓,将处理后的图片在VGA显示器上显示出来。
实验要求:VGA显示模式:640x480@60;传入图片分辨率大小100x100。
2.2 图片预处理
在进行Sobel算法之前,先要将图片进行一下预处理,将彩色图片转换成灰度图像,并且将灰度图像的高 3 位取出存放为txt 文本,图解和代码;
matlab代码:
clc; %清理命令行窗口clear all; %清理工作区image = imread('D:\FPGA\FPGA_Basic_Pro\sobel\matalb\curry_logo.bmp'); %使用imread函数读取图片数据figure;imshow(image); %窗口显示图片
R = image(:,:,1); %提取图片中的红色层生成灰度图像figure;imshow(R); %窗口显示灰色图像[ROW,COL] = size(R); %灰色图像大小参数data = zeros(1,ROW*COL); %定义一个初值为0的数组,存储转换后的图片数据for r = 1:ROWfor c = 1 : COLdata((r-1)*COL+c) = bitshift(R(r,c),-5); %红色层数据右移5位end
endfid = fopen('D:\FPGA\FPGA_Basic_Pro\sobel\matalb\logo.txt','w+'); %打开或新建一个txt文件for i = 1:ROW*COLfprintf(fid,'%02x' ,data(i)); %写入图片数据
end
fclose(fid);
2.3 模块框图
模块名称 | 功能描述 |
---|---|
sobel | 顶层模块 |
clk_gen | 时钟生成模块 |
uart_rx | 串口数据接收模块 |
uart_tx | 串口数据发送模块 |
sobel_ctrl | 数据求和模块 |
vga | vga显示顶层模块 |
vga_pic | 图像数据生成模块 |
vga_ctrl | vga显示驱动模块 |
数据求和模块sobel_ctrl是本实验工程的核心模块,负责Sobel算法的实现,模块包含4路输入信号和2路输出信号,内部还调用了2个fifo,参与sobel运算。
输入信号中除了输入系统时钟sys_clk和系统复位信号sys_rst_n,还有自uart_rx模块输入的数据信号pi_data和与之对应的数据标志信号pi_flag,数据输入后通过sobel运算后得出Gx、Gy,进而求出Gxy,求出结果与阈值比较,根据比较结果给输出信号po_data赋值,输出信号除了po_data之外还有与之同步的数据标志信号po_flag。 sobel_ctrl模块框图,具体见图:
· | 位宽 | 类型 | 功能描述 |
---|---|---|---|
sys_clk | 1Bit | Input | 工作时钟,频率50MHz |
sys_rst_n | 1Bit | Input | 复位信号,低电平有效 |
pi_flag | 1Bit | Input | 输入数据标志信号 |
pi_data | 8Bit | Input | 输入拼接后的图像数据 |
po_flag | 1Bit | Output | 输出数据标志信号 |
po_data | 8Bit | Output | 输出经sobel算法处理后的图像数据 |
下面的这张手绘图将带你绝杀sobel_ctrl模块:
在sobel_ctrl模块中,主要的数据处理就是利用两个fifo作为数据缓冲池,存储两行像素数据,在两行像素数据写入fifo,后面将pi_data读入fifo2,此时fifo2也将读出一个数据写入fifo1,利用两个FIFO存储行像素数据,并进行读写流转,在两个FIFO都成功读出两个数据之后,即可实现每个始终周期有三行(fifo1_out fifo2_out和pi_data)三列数据赋值给算子 (a1~c3)九个数据,然后进行Gx和Gy的计算,达到阈值输出像素数据为全黑色,否则为白色;
什么时候计算Gx和Gy?设置读使能计数器,控制计算。如下图
家人们 是不是豁然开朗?