0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

FPGA图像处理的Sobel边缘检测

FPGA之家 来源:似猿非猿的FPGA 作者:似猿非猿的FPGA 2021-03-22 09:45 次阅读

Sobel边缘检测

Sobel边缘检测原理教材网上一大堆,核心为卷积处理。

Sobel卷积因子为:

587a489a-8924-11eb-8b86-12bb97331649.png

该算子包含两组3x3的矩阵,分别为横向及纵向,将之与图像作平面卷积,即可分别得出横向及纵向的亮度差分近似值。如果以A代表原始图像,Gx及Gy分别代表经横向及纵向边缘检测的图像灰度值,其公式如下:

589be176-8924-11eb-8b86-12bb97331649.png

图像的每一个像素的横向及纵向灰度值通过以下公式结合,来计算该点灰度的大小:

58c78876-8924-11eb-8b86-12bb97331649.png

通常,为了提高效率 使用不开平方的近似值:

5903a144-8924-11eb-8b86-12bb97331649.png

最后,当计算出来的值大于某一阈值时即认为为边缘像素点。

归结起来,Sobel边缘检测分为三大步:卷积计算、灰度计算、阈值比较处理。结合上文实现的bufWindow,在SpinalHDL里实现Sobel边缘检测也就几行代码的事情(如果是写Verilog我还是拒绝的)。

卷积计算

通过bufWindow,我们可以得到一个3x3的矩阵窗口,拿到结果第一步即是计算卷积,由于卷积因子是带符号的,而在做卷积时又需要考虑位宽扩展的事情,在写Verilog时还是需要小心的设计下的,而在SpinalHDL里,两行代码:

val Gx=(windowbuf.io.dataOut.payload(0)(2).expand.asSInt-^windowbuf.io.dataOut.payload(0)(0).expand.asSInt)+| ((windowbuf.io.dataOut.payload(1)(2).expand.asSInt-^windowbuf.io.dataOut.payload(1)(0).expand.asSInt)《《1)+| (windowbuf.io.dataOut.payload(2)(2).expand.asSInt-^windowbuf.io.dataOut.payload(2)(0).expand.asSInt)val Gy=(windowbuf.io.dataOut.payload(0)(0).expand.asSInt-^windowbuf.io.dataOut.payload(2)(0).expand.asSInt)+| ((windowbuf.io.dataOut.payload(0)(1).expand.asSInt-^windowbuf.io.dataOut.payload(2)(1).expand.asSInt)《《1)+| (windowbuf.io.dataOut.payload(0)(2).expand.asSInt-^windowbuf.io.dataOut.payload(2)(2).expand.asSInt)

首先将bufWindow输出的窗口矩阵值扩展一位位宽转换为有符号值,然后进行计算卷积。计算卷积运用了两个运算符“-^”,“+|”来处理加减运算时的位宽处理(可参照SpinalHDL手册或本公众号的《SpinalHDL—数据类型:UInt/SIn》)。最终得到Gx、Gy。

灰度计算

灰度计算这里采用近似值,通过取绝对值的方式进行实现,在SpinalHDL里也就一行代码的事情:

sobelResult.payload:= (sobelConv.payload(0).abs+| sobelConv.payload(1).abs).fixTo(cfg.dataWidth-1 downto 0,RoundType.ROUNDUP)

由于在卷积计算时有扩展位宽,这里计算最后调用fixTo进行高位饱和处理。最终得到位宽与输入保持一致(想想你在Veirlog里实现这一步要做多少事情,少年)。

阈值比较

阈值比较就很简单了,比较两个值大小取两个极端:

when(sobelResult.payload》io.thresholdValue){ io.dataOut.payload:=(default-》true) }otherwise{ io.dataOut.payload:=(default-》false) }

最终实现Sobel边缘检测代码如下:

case class sobelProc(cfg:lineBufferCfg) extends Component{ require(cfg.lineNum==3) val io=new Bundle{ val thresholdValue =in UInt(cfg.dataWidth bits) val dataIn=slave Flow(UInt(cfg.dataWidth bits)) val dataOut=master Flow(UInt(cfg.dataWidth bits)) dataOut.valid.setAsReg().init(False) dataOut.payload.setAsReg().init(0) } noIoPrefix() val sobel=new Area{ val windowbuf=bufWindow(cfg) val sobelConv=Reg(Flow(Vec(SInt(),2))) val sobelResult=Reg(Flow(UInt(cfg.dataWidth bits))) sobelConv.valid.init(False) sobelResult.valid.init(False) io.dataIn《》windowbuf.io.dataIn val Gx=(windowbuf.io.dataOut.payload

(0)(2).expand.asSInt-^windowbuf.io.dataOut.payload(0)(0).expand.asSInt)+| ((windowbuf.io.dataOut.payload(1)(2).expand.asSInt-^windowbuf.io.dataOut.payload(1)(0).expand.asSInt)《《1)+| (windowbuf.io.dataOut.payload(2)(2).expand.asSInt-^windowbuf.io.dataOut.payload(2)(0).expand.asSInt) val Gy=(windowbuf.io.dataOut.payload(0)(0).expand.asSInt-^windowbuf.io.dataOut.payload(2)(0).expand.asSInt)+| ((windowbuf.io.dataOut.payload

(0)(1).expand.asSInt-^windowbuf.io.dataOut.payload(2)(1).expand.asSInt)《《1)+| (windowbuf.io.dataOut.payload(0)(2).expand.asSInt-^windowbuf.io.dataOut.payload(2)(2).expand.asSInt) sobelConv.valid:=windowbuf.io.dataOut.valid sobelConv.payload(0):=Gx sobelConv.payload(1):=Gy sobelResult.valid:=sobelConv.valid sobelResult.payload:= (sobelConv.payload(0).abs+| sobelConv.payload(1).abs).fixTo(cfg.dataWidth-1 downto 0,RoundType.ROUNDUP) io.dataOut.valid:=sobelResult.valid when(sobelResult.payload》io.thresholdValue){ io.dataOut.payload:=(default-》true) }otherwise{ io.dataOut.payload:=(default-》false) } }}

区区不到四十行代码,简洁而优雅,基本上就是描述算法,出错概率应该很小吧!

仿真

做图像处理的小伙伴想想在做仿真验证时需要怎么搞,matlab生成灰度图像二进制数据放在文件里,然后仿真时再导入,仿真完成后将结果保存到文件里,最后再在matlab里做对比。 太麻烦。SpinalHDL提供了仿真支持,而SpinalHDL是基于Scala的,可以完美实现整个仿真验证流程:从图片直接获取数据,然后进行仿真验证,仿真结果直接再次生成图片。

原文标题:FPGA图像处理——老戏新说

文章出处:【微信公众号:FPGA之家】欢迎添加关注!文章转载请注明出处。

责任编辑:haq

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • FPGA
    +关注

    关注

    1601

    文章

    21296

    浏览量

    593036
  • 仿真
    +关注

    关注

    50

    文章

    3872

    浏览量

    132143

原文标题:FPGA图像处理——老戏新说

文章出处:【微信号:zhuyandz,微信公众号:FPGA之家】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    算法系列:基于 FPGA图像边缘检测系统设计(sobel算法)

    今天给大侠带来基于 FPGA图像边缘检测设计,话不多说,上货。 设计流程如下:mif文件的制作→ 调用 ip 核生成rom以及仿真注意问题→ 灰度
    发表于 03-26 16:40

    FPGA图像处理方法

    图像细节。 FPGA 图像处理方法 1、图像增强 两大方法:空间域方法和时间域方法(以后再详述) 2、
    的头像 发表于 12-02 13:15 587次阅读

    图像处理算法——边缘检测

    基于边缘检测的分析不易受整体光照强度变化的影响,同时利用边缘信息容易凸显目标信息和达到简化处理的目的,因此很多图像理解方法都以
    的头像 发表于 11-30 16:56 422次阅读
    <b class='flag-5'>图像</b><b class='flag-5'>处理</b>算法——<b class='flag-5'>边缘</b><b class='flag-5'>检测</b>

    Canny双阈值边缘检测和弱边缘连接详解

    在上一篇FPGA图像处理--Canny边缘检测(一)里介绍了Canny边缘
    的头像 发表于 11-18 17:07 987次阅读

    FPGA图像处理之Canny边缘检测

    边缘检测算法里面Sobel是比较简单的一个算法,但是其检测出来的边缘往往是比较粗的,效果不是很好,因为我们最理想的
    的头像 发表于 11-17 09:10 757次阅读
    <b class='flag-5'>FPGA</b><b class='flag-5'>图像</b><b class='flag-5'>处理</b>之Canny<b class='flag-5'>边缘</b><b class='flag-5'>检测</b>

    OpenCV图像处理图像梯度+Canny边缘检测

    了解了Sobel和Scharr高通滤波器的内核,我们再来看看cv.Sobel()和cv.Scharr()函数的参数,cv.Sobel(img,cv.CV_64F,dx,dy,ksize)函数需要传递
    的头像 发表于 11-14 15:54 268次阅读
    OpenCV<b class='flag-5'>图像</b><b class='flag-5'>处理</b>之<b class='flag-5'>图像</b>梯度+Canny<b class='flag-5'>边缘</b><b class='flag-5'>检测</b>

    【紫光同创PGL50H】小眼睛科技盘古50K开发板试用体验之图像Sobel边缘检测

    和Gy使用以下公式结合,便得到边缘信息的图像。 由于Sobel算子是平面图像的滑动卷积,使用FPGA实现是相对容易的,且具有高效率。
    发表于 10-12 20:14

    迅为RK3568开发板Scharr滤波器算子边缘检测

    ()函数展示 x 方向梯度边缘检测计算之后的图像 8 scharry = cv2.Scharr(img,cv2.CV_64F,0,1) #使用 Sobel 算子进行
    发表于 10-09 11:03

    迅为iTOP-RK3568开发板Sobel 算子边缘检测

    (索贝尔)算子是计算机视觉领域的一种重要处理方法。主要用于获得数字图像的一阶梯度,常见的应用和物理意义是边缘检测。 索贝尔算子把图像中每个
    发表于 09-18 10:27

    图像锐化的Sobel、Laplacian算子基础知识介绍

    Sobel 算子是一种用于边缘检测的离散微分算子,它结合了高斯平滑和微分求导
    的头像 发表于 09-13 09:52 779次阅读
    <b class='flag-5'>图像</b>锐化的<b class='flag-5'>Sobel</b>、Laplacian算子基础知识介绍

    FPGA图像处理-Sobel边缘检测原理

    因为在做3*3卷积的时候,图像大小会变小,具体计算公式如下
    发表于 07-30 17:28 542次阅读
    <b class='flag-5'>FPGA</b><b class='flag-5'>图像</b><b class='flag-5'>处理</b>-<b class='flag-5'>Sobel</b><b class='flag-5'>边缘</b><b class='flag-5'>检测</b>原理

    FPGA相机边缘检测开源分享

    电子发烧友网站提供《FPGA相机边缘检测开源分享.zip》资料免费下载
    发表于 07-10 09:39 0次下载
    <b class='flag-5'>FPGA</b>相机<b class='flag-5'>边缘</b><b class='flag-5'>检测</b>开源分享

    基于FPGA的实时图像边缘检测系统设计(附代码)

    设计(中)基于FPGA的实时图像边缘检测系统设计(下) 导读 随着科学技术的高速发展,FPGA在系统结构上为数字
    发表于 06-21 18:47

    如何进行图像边缘检测

      本期我们一起看看如何进行图像边缘检测边缘检测通常用于理解图像中的对象,帮助机器做出更好的
    的头像 发表于 06-20 15:14 723次阅读
    如何进行<b class='flag-5'>图像</b><b class='flag-5'>边缘</b>的<b class='flag-5'>检测</b>

    荐读:FPGA设计经验之图像处理

    系列:基于 FPGA图像边缘检测系统设计(sobel算法) FPGA设计中 Verilog
    发表于 06-08 15:55