FPGA之旅设计99例之第二十二例----Sobel算法边沿检测

简介: 笔记

一. 简介


本例将在上例的基础上,添加一个简单的图像处理算法—边缘检测(Sobel算法)。串口助手发送图片过来之后,结果边缘检测算法处理之后再输出到VGA进行显示。


边沿检测算法主要是针对灰度图进行处理的,所以模块内部还需要添加个RGB565转灰度的功能。边缘检测算法有很多种,例如Sobel、Canny、Prewitt等等,各有其优缺点。本次选择Sobel进行学习,主要是因为其相对而言比较简单,FPGA易于实现。


二. Sobel算法


Sobel主要是利用图像两个方向的梯度来与阈值进行对比,大于阈值的点,被认为是边缘点。算法步骤大体如下


求x,y方向的梯度dx,dy

求出近似梯度G = dx2 + dy2开根号,也可以近似为 G = |dx| + |dy|,方便FPGA处理

与阈值进行对比,大于阈值则为边缘,将该像素赋值为255,否则为0

可以看出算法的核心是如何计算图像两个方向的梯度。


(一). 梯度计算

梯度计算主要是用到了两个3x3大小的卷积核(如下图)。上图负责x方向,下图负责y方向。

25.png



卷积核在图像上进行移动,每次都会覆盖3x3大小的图像区域。卷积核与图像上对于位置上的元素相乘然后求和(矩阵的内积),就得到该点的梯度值(3x3中心位置的像素点)。


这样又会引入两个问题


计算过程需要使用三行图像数据,如何进行存储

图像边缘位置的像素如何进行处理

(二). 如何缓存三行数据

实际上,只需要存储两行数据即可,第三行为当前输入的那行。具体的实现方式有两种,一种是调用现成IP,另外一种就是自己实现啦。目是要学习Sobel算法,偷个懒直接调用IP也是可以的。在Quartus中可以调用Shift Register IP实现,Vivado中也有,名字忘记了。


IP工作原理如下,该图是缓存了4行数据。第一行输入一个数据,第一行就会输出一个数据,然后第一行输出的数据又会作为第二行的输入,第二行也会输出一个数据,作为第三行的输入,以此类推。一个数据输入,那么将会得到每一行的一个数据,共四个数据。


26.png


IP创建


选择Shift Register

27.png


选择输入数据的位宽,缓存行数,每行的数据个数和时钟使能信号。通过框图可以看出输入的位宽为8bit,缓存的行数为两行(第三行为当前输入,不需要缓存),每一行的个数为480,刚好为图像的列数。28.png



这样缓存三行的问题就得到了解决。


(三). 边缘像素如何处理

如果按照算法流程来的话,处理完成后,图像就会变小一圈,尺寸就变了,这是我们不希望得到了。一般采用的方法为先将图片扩大一圈,扩大一圈对应的像素值可以为0,或者255,也可以图像最外圈的保持一致,这样结果算法处理后,图像大小就和输入的大小保持一致了。但是这样在FPGA中处理不是很方便,考虑到图片边缘一般不会包含重要的信息,同样也是本次将采取的方便,外部输入一个像素,Sobel算法就会输出一个像素,这样边缘像素是否是边缘点,就是一个随机的了,跟初始化的值和上一帧图像有关,这样就大大简化了问题。


三. 算法实现


(1). 图片转灰

这里采用最简单的方法,对图像的三个通道取平均值的方法进行转换。这里采取了两个周期来处理,最终得到灰度值


//计算rgb三个值
always@(posedge clk or negedge rst)
begin
  if(rst == 1'b0)
  begin
  reg_R <= 'd0;
  reg_G <= 'd0;
  reg_B <= 'd0;
  end
  else  if(data_en == 1'b1)
  begin
  reg_R <= {data_in[15:11],3'b0};
  reg_G <= {data_in[10:5],2'b0};
  reg_B <= {data_in[4:0],3'b0};
  end
  else
  begin
  reg_R <= reg_R;
  reg_G <= reg_G;
    reg_B <= reg_B;
  end
end
//计算regR regB  regG之和取平均
always@(posedge clk or negedge rst)
begin
  if(rst == 1'b0)
  reg_RGB <= 'd0;
  else
  reg_RGB <= (reg_R + reg_G + reg_B)/3;  //取平均值
end


(二). Sobel算法实现

本次实现的Sobel算法一共需要花费两个时钟周期完成,


第一个时钟周期主要完成Sobel核与图像的卷积操作将负数和正数分开计算


always@(posedge clk or negedge rst)
begin
  if(rst == 1'b0)
  begin
    Sobel_px <= 'd0;
    Sobel_nx <= 'd0;
  end
  else if(data_en==1'b1)
  begin
    Sobel_nx <= martix_11 + martix_21 + martix_21 + martix_31;
    Sobel_px <= martix_13 + martix_23 + martix_23 + martix_33;
  end
  else
  begin
  Sobel_nx <= 'd0;
  Sobel_px <= 'd0;
  end
end


第二个时钟周期主要完成负数和正数的比较,求得梯度的绝对值,并求和比较输出结果


assign Sobel_data = (Sobel_x + Sobel_y > Sobel_thresh) ? 8'd0 : 8'd255;
always@(posedge clk)
begin
  Sobel_x <= (Sobel_px > Sobel_nx) ? (Sobel_px - Sobel_nx) : (Sobel_nx - Sobel_px);
    Sobel_y <= (Sobel_py > Sobel_ny) ? (Sobel_py - Sobel_ny) : (Sobel_ny - Sobel_py);
end


最终实现效果如图,搞错了图像宽度为640,不是480,所以最右边出现重复,尴尬


回复 FPGA之旅设计99例之第二十二例 获取完整工程 ,Sobel模块放在了sdram_read模块下面。

29.png

公众号:FPGA之旅

目录
相关文章
|
1月前
|
监控 安全 算法
137_安全强化:输入过滤与水印 - 实现输出水印的检测算法与LLM安全防护最佳实践
随着大语言模型(LLM)在各行业的广泛应用,安全问题日益凸显。从提示注入攻击到恶意输出生成,从知识产权保护到内容溯源,LLM安全已成为部署和应用过程中不可忽视的关键环节。在2025年的LLM技术生态中,输入过滤和输出水印已成为两大核心安全技术,它们共同构建了LLM服务的安全防护体系。
|
2月前
|
传感器 资源调度 算法
DDMA-MIMO雷达多子带相干累积目标检测算法——论文阅读
本文提出一种多子带相干累积(MSCA)算法,通过引入空带和子带相干处理,解决DDMA-MIMO雷达的多普勒模糊与能量分散问题。该方法在低信噪比下显著提升检测性能,实测验证可有效恢复目标速度,适用于车载雷达高精度感知。
449 4
DDMA-MIMO雷达多子带相干累积目标检测算法——论文阅读
|
1月前
|
开发框架 算法 .NET
基于ADMM无穷范数检测算法的MIMO通信系统信号检测MATLAB仿真,对比ML,MMSE,ZF以及LAMA
简介:本文介绍基于ADMM的MIMO信号检测算法,结合无穷范数优化与交替方向乘子法,降低计算复杂度并提升检测性能。涵盖MATLAB 2024b实现效果图、核心代码及详细注释,并对比ML、MMSE、ZF、OCD_MMSE与LAMA等算法。重点分析LAMA基于消息传递的低复杂度优势,适用于大规模MIMO系统,为通信系统检测提供理论支持与实践方案。(238字)
|
2月前
|
存储 算法 生物认证
基于Zhang-Suen算法的图像细化处理FPGA实现,包含testbench和matlab验证程序
本项目基于Zhang-Suen算法实现图像细化处理,支持FPGA与MATLAB双平台验证。通过对比,FPGA细化效果与MATLAB一致,可有效减少图像数据量,便于后续识别与矢量化处理。算法适用于字符识别、指纹识别等领域,配套完整仿真代码及操作说明。
|
4月前
|
存储 算法 数据安全/隐私保护
基于FPGA的图像退化算法verilog实现,分别实现横向和纵向运动模糊,包括tb和MATLAB辅助验证
本项目基于FPGA实现图像运动模糊算法,包含横向与纵向模糊处理流程。使用Vivado 2019.2与MATLAB 2022A,通过一维卷积模拟点扩散函数,完成图像退化处理,并可在MATLAB中预览效果。
|
5月前
|
机器学习/深度学习 运维 监控
实时异常检测实战:Flink+PAI 算法模型服务化架构设计
本文深入探讨了基于 Apache Flink 与阿里云 PAI 构建的实时异常检测系统。内容涵盖技术演进、架构设计、核心模块实现及金融、工业等多领域实战案例,解析流处理、模型服务化、状态管理等关键技术,并提供性能优化与高可用方案,助力企业打造高效智能的实时异常检测平台。
452 1
|
4月前
|
存储 监控 算法
基于跳表数据结构的企业局域网监控异常连接实时检测 C++ 算法研究
跳表(Skip List)是一种基于概率的数据结构,适用于企业局域网监控中海量连接记录的高效处理。其通过多层索引机制实现快速查找、插入和删除操作,时间复杂度为 $O(\log n)$,优于链表和平衡树。跳表在异常连接识别、黑名单管理和历史记录溯源等场景中表现出色,具备实现简单、支持范围查询等优势,是企业网络监控中动态数据管理的理想选择。
148 0
|
9月前
|
机器学习/深度学习 算法 数据安全/隐私保护
基于GRU网络的MQAM调制信号检测算法matlab仿真,对比LSTM
本研究基于MATLAB 2022a,使用GRU网络对QAM调制信号进行检测。QAM是一种高效调制技术,广泛应用于现代通信系统。传统方法在复杂环境下性能下降,而GRU通过门控机制有效提取时间序列特征,实现16QAM、32QAM、64QAM、128QAM的准确检测。仿真结果显示,GRU在低SNR下表现优异,且训练速度快,参数少。核心程序包括模型预测、误检率和漏检率计算,并绘制准确率图。
279 65
基于GRU网络的MQAM调制信号检测算法matlab仿真,对比LSTM
|
9月前
|
算法 数据安全/隐私保护 计算机视觉
基于FPGA的图像双线性插值算法verilog实现,包括tb测试文件和MATLAB辅助验证
本项目展示了256×256图像通过双线性插值放大至512×512的效果,无水印展示。使用Matlab 2022a和Vivado 2019.2开发,提供完整代码及详细中文注释、操作视频。核心程序实现图像缩放,并在Matlab中验证效果。双线性插值算法通过FPGA高效实现图像缩放,确保质量。
|
5月前
|
机器学习/深度学习 监控 算法
面向办公室屏幕监控系统的改进型四叉树屏幕变化检测算法研究
本文提出一种改进型四叉树数据结构模型,用于优化办公室屏幕监控系统。通过动态阈值调节、变化优先级索引及增量更新策略,显著降低计算复杂度并提升实时响应能力。实验表明,该算法在典型企业环境中将屏幕变化检测效率提升40%以上,同时减少资源消耗。其应用场景涵盖安全审计、工作效能分析及远程协作优化等,未来可结合深度学习实现更智能化的功能。
114 0