【博文连载】动态Sobel阀值的HDL实现

完美是没有极限的,前面我们已经实现了固定阀值下,图像的边缘检测结果。不过如何能手动输入,或者控制阀值的大小,那其实更完美一点点。

既然我们能够在努力一点点,为何要放弃???

OK,Bingo这里打算教大家使用VIP Mini开发板上的2个按键来,来实现阀值的增大与减小!

首先在HDL-Logic中已经详细的介绍过按键检测的模块key_counter_scan。这里直接调用该模块,获取key_flag与key_value信号。新建Sobel_Threshold_Adj模块,信号列表如下所示:

`timescale 1ns/1ns

module Sobel_Threshold_Adj

(

//global clock

input               clk,        //100MHz

input               rst_n,      //global reset

//user interface

input               key_flag,       //key down flag

input       [1:0]   key_value,      //key control data

output  reg [3:0]   Sobel_Grade,    //Sobel Grade output

output  reg [7:0]   Sobel_Threshold //lcd pwn signal, l:valid

);

刚好板卡有2个按键,K1控制Sobel_Threshold的增加,而K2控制Sobel_Threshold的减小。阀值的级别我们设定16级,因此K1、K2控制Sobel_Grade这个变量的增减,如下:

//---------------------------------

//Sobel Threshold adjust with key.

always@(posedge clk or negedge rst_n)

begin

if(!rst_n)

Sobel_Grade <= 4'd8;

else if(key_flag)

begin

case(key_value) //{Sobel_Threshold--, Sobel_Threshold++}

2'b10:  Sobel_Grade <= (Sobel_Grade == 4'd0)  ? 4'd0  : Sobel_Grade - 1'b1;

2'b01:  Sobel_Grade <= (Sobel_Grade == 4'd15) ? 4'd15 : Sobel_Grade + 1'b1;

default:;

endcase

end

else

Sobel_Grade <= Sobel_Grade;

End

最后,分配每个阀值级的Sobel_Threshold大小,如下所示,从20~90:

//---------------------------------

//Sobel Grade Mapping with Sobel Threshold

always@(posedge clk or negedge rst_n)

begin

if(!rst_n)

Sobel_Threshold <= 55;

else

case(Sobel_Grade)

4'h0:   Sobel_Threshold <= 20;

4'h1:   Sobel_Threshold <= 25;

4'h2:   Sobel_Threshold <= 30;

4'h3:   Sobel_Threshold <= 35;

4'h5:   Sobel_Threshold <= 40;

4'h6:   Sobel_Threshold <= 45;

4'h7:   Sobel_Threshold <= 50;

4'h8:   Sobel_Threshold <= 55;

4'h9:   Sobel_Threshold <= 60;

4'ha:   Sobel_Threshold <= 65;

4'hb:   Sobel_Threshold <= 70;

4'hc:   Sobel_Threshold <= 75;

4'hd:   Sobel_Threshold <= 80;

4'he:   Sobel_Threshold <= 85;

4'hf:   Sobel_Threshold <= 90;

default:;

endcase

end

在工程顶层模块中例化相关模块,如下所示:

//Key scan with jitter detect

wire          key_flag;

wire  [1:0]   key_value;

key_counter_scan

#(

.KEY_WIDTH  (2)

)

u_key_counter_scan

(

//global

.clk                (clk_ref),

.rst_n              (rst_n),

//key interface

.key_data           (key_data),

//user interface

.key_flag           (key_flag),

.key_value          (key_value)

);

//------------------------------------

//Sobel Threshold adjust with key.

wire  [3:0]   Sobel_Grade;

wire  [7:0]   Sobel_Threshold;

Sobel_Threshold_Adj   u_Sobel_Threshold_Adj

(

//global clock

.clk                (clk_ref),       //100MHz

.rst_n              (sys_rst_n),            //global reset

//user interface

.key_flag           (key_flag),         //key down flag

.key_value          (key_value),        //key control data

.Sobel_Grade        (Sobel_Grade),      //Sobel Grade output

.Sobel_Threshold    (Sobel_Threshold)   //Sobel Threshold

);

//---------------------------

//The driver of 74HC595

led_74595_driver  u_led_74595_driver

(

//global clock

.clk                (clk_ref),

.rst_n              (sys_rst_n),

//74hc595 interface

.led595_dout        (led595_dout),  //74hc595 serial data input

.led595_clk         (led595_clk),   //74hc595 shift clock (rising edge)

.led595_latch       (led595_latch), //74hc595 latch clock (risign edge)

//user interface

.led_data           ({4'd0, Sobel_Grade})       //led data input

);

从代码分析,可见Bingo将Sobel_Grade发送到了LED显示模块,作为阀值大小的直观显示。

最后,还是全编译,生成并下载sof文件,重启后用USB_VIP_Panel或者VGA测试测试。调节K2,如下图所示,为Sobel_Threshold=30时的边缘检测结果,此时LED显示10,可见我们得到了更多的边缘细节。

调节K1,如下图所谓为Sobel_Threshold=90时的边缘检测结果,此时LED显示1111,可见我们得到了更细腻的边缘检测结果。

Sobel_Threshold的键控方法,不仅仅适用于Sobel边缘检测。在用户设计实现对比度、亮度,以及其他一些需要阀值的算法时,该模块能够很好的进行调试,以获取当前背景光下的最佳选择!

本节作为在均值/中值滤波的基础上,进一步的VIP图像处理,是本教程中相对复杂度较高的算法,当然仅限于本教程的难度。在视频的跟踪、识别中,边缘检测具有极其重要的作用。通过FPGA硬件加速实现边缘检测视频,获得边缘检测的图像源,势必在VIP领域有极大的作用,请读者掌握这一节的内容。

备注:之前版本提供的代码中,Sobel一开始并没有在中值滤波之后进行处理,这里还是脑补下,在中值滤波前或者后进行Sobel边检检测

上图左为灰度→Sobel算法后的图像,上图右为灰度→中值滤波→Sobel算法后的图像。由于图像源的问题,效果不是很明朗,但可以从细节观察出右图的早上比左图要少,同时边缘相对要均匀一些。若是要用与某些模式识别等算法中,在中值滤波后的边缘检测结果,由于图像质量的改变,能让结果更令人满意。

 

(0)

相关推荐

  • 基于FPGA的数字电路实验7:流水灯的实现

    原创 Daniel收录于话题#数字电路9个继年前介绍的时序逻辑电路之时钟分频后,今天我们来介绍第7讲:流水灯.流水灯,有时候也叫跑马灯,是一个简单.有趣又经典的实验,基本所有单片机的玩家们在初期学习的 ...

  • 史上最全的LED点灯程序,你都掌握了吗?

    干货福利,第一时间送达! 摘要:你点亮过多少板子的LED灯呢?有很多小伙伴留言说讲一下STM32.FPGA.Liunx他们之间有什么不同.不同点很多,口说无凭,今天就来点亮一下STM32.FPGA和L ...

  • Gowin(高云)IDE探索

    快速导航页面 我觉得学习一个软件,自我探索这个环节是必不可少的,软件又用不坏,戳戳点点认识基本功能是极好的.闲话不多说,我们开始~ 首先必须建立一个新项目 可以拉长这个对话框 然后就是写项目名字以及项 ...

  • 【博文连载】Sobel边缘检测算法的HDL实现

    FPGA中针对以上矩阵进行算法移植.由于直接计算会因为负值而得到错误的结果,用补码表示比较繁琐,需要用到unsigned 以及signed类型,不适合FPGA的运算. cnblog有真oo无双的代码, ...

  • 【博文连载】DDR3中的ODT动态模式详解

    首先举一个例子: 早期的DDR(注:DDR2开始支持ODT功能),当向内存写入数据时,如果只有一条内存,那么这条内存就自己进行信号的终结,终结电阻等效为150Ω.如果为两条内存,那么他们会交错的进行信 ...

  • 【博文连载】Median_Filter均值滤波算法的实现

    ChinaAET<电子应用技术>出版过一篇值得参考的<基于FPGA的实时中值滤波器的硬件实现>,该文采用FPGA+SRAM实现了实时中值滤波,思维值得参考(当然Bingo认为实 ...

  • 【博文连载】边缘检测算法介绍

    所谓边缘是指其周围像素灰度急剧变化的那些象素的集合,它是图像最基本的特征.边缘存在于目标.背景和区域之间,所以,它是图像分割所依赖的最重要的依据.由于边缘是位置的标志,对灰度的变化不敏感,,因此,边缘 ...

  • 【博文连载】中值滤波算法的介绍

    言归正传,我们先挑一个相对最简单的滤波算法(其实均值滤波更简单,但是它对边缘的保持太差,那就稍微努力点用中值滤波吧).进行中值滤波不仅可以去除孤点噪声,而且可以保持图像的边缘特性,不会使图像产生显著的 ...

  • 【博文连载】【VGA+USB】灰度图像的均值滤波算法实现

    图像处理算法可以在RGB域处理,也可以在灰度域处理,牛逼的还可以在Bayer处理.但是大部分目标识别.跟踪.检测等图像处理算法,都是灰度域处理的,因为灰度除了没有色度,以及包含了基本图像处理所需的信息 ...

  • 【博文连载】Bingo版HDL-VIP时序约定

    在6.3节中Bayer恢复RGB,其实我们已经或多或少的接触到Bingo设计的VIP模块了.并且我们通过CMOS_RGB565_Capture模块(当然RAW.YCbCr模式的采集,接口不变),已经得 ...

  • 【博文连载】PCIe扫盲——关于PCIe参考时钟的讨论

    本文来聊一聊PCIe系统中的参考时钟,主要参考资料为PCIe Base Spec和CEM Spec.在1.0a和1.1版本的PCIe Base Spec中并没有详细的关于参考时钟的描述,而是在与之对应 ...

  • 【博文连载】CY7C68013同步FIFO配置

    在VIP Mini开发板资料包08_USB_Keil_Project目录下,Bingo提供了CY7C68013的同步FIFO配置工程,以及其他的一些功能.软件版本为Keil UVision 4.73. ...