百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术分析 > 正文

「博文连载」Sobel边缘检测算法的HDL实现

liebian365 2024-10-24 14:30 20 浏览 0 评论

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

cnblog有真oo无双的代码,通过并形乘法、并行相加、平方根来使用,采用各种IP相当的复杂,虽然实现了补码、负数,但看得我都蒙了。为何要把简单的问题复杂化:

http://www.cnblogs.com/oomusou/archive/2008/08/25/verilog_sobel_edge_detector.html

为此Bingo发愤图强(不过oo的博文真的有很好的参考性)!!!!

前面Sobel算子的实现,为了实现FPGA的加速运算,发挥并行流水线的特性,可以划分为4个步骤,解析与实现分别如下:

  1. 计算计算Gx与Gy与模板每行的乘积

  2. 求得3*3模板运算后的Gx、Gy

    为了便于阅读理解,这里(1)与(2),Bingo在同一个always中描述了,但实际上耗费了2个时钟。Gx(Gx_data)与Gy(Gy_data)的计算分别如下:

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

//Sobel Parameter

// Gx Gy Pixel

// [ -1 0 +1 ] [ +1 +2 +1 ] [ P11 P12 P13 ]

// [ -2 0 +2 ] [ 0 0 0 ] [ P21 P22 P23 ]

// [ -1 0 +1 ] [ -1 -2 -1 ] [ P31 P32 P33 ]

//Caculate horizontal Grade with |abs|

//Step 1.1

reg [9:0] Gx_temp1; //postive result

reg [9:0] Gx_temp2; //negetive result

reg [9:0] Gx_data; //Horizontal grade data

always@(posedge clk or negedge rst_n)

begin

if(!rst_n)

begin

Gx_temp1 <= 0;

Gx_temp2 <= 0;

Gx_data <= 0;

end

else

begin

Gx_temp1 <= matrix_p13 + (matrix_p23 << 1) + matrix_p33; //postive result

Gx_temp2 <= matrix_p11 + (matrix_p21 << 1) + matrix_p31; //negetive result

Gx_data <= (Gx_temp1 >= Gx_temp2) ? Gx_temp1 - Gx_temp2 : Gx_temp2 - Gx_temp1;

end

end

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

//Caculate vertical Grade with |abs|

//Step 1.2

reg [9:0] Gy_temp1; //postive result

reg [9:0] Gy_temp2; //negetive result

reg [9:0] Gy_data; //Vertical grade data

always@(posedge clk or negedge rst_n)

begin

if(!rst_n)

begin

Gy_temp1 <= 0;

Gy_temp2 <= 0;

Gy_data <= 0;

end

else

begin

Gy_temp1 <= matrix_p11 + (matrix_p12 << 1) + matrix_p13; //postive result

Gy_temp2 <= matrix_p31 + (matrix_p32 << 1) + matrix_p33; //negetive result

Gy_data <= (Gy_temp1 >= Gy_temp2) ? Gy_temp1 - Gy_temp2 : Gy_temp2 - Gy_temp1;

end

end

具体的实现方式请自行分析代码,Bingo认为这是极简单的……

(3)求得Gx^2+Gy^2的结果,及Gx与Gy的平方和

这一步直接通过HDL中乘法器的描述来实现,综合时会自动布线为片内乘法器,如下:

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

//Caculate the square of distance = (Gx^2 + Gy^2)

//Step 3

reg [20:0] Gxy_square;

always@(posedge clk or negedge rst_n)

begin

if(!rst_n)

Gxy_square <= 0;

else

Gxy_square <= Gx_data * Gx_data + Gy_data * Gy_data;

end

(4)求得Gx^2+Gy^2的平方根

当年Bingo在第一次遇到这个的时候差点崩溃,不过有幸看过无双oo的博文,才知道强大的Altera竟然在LPM中提供了平方根的IP,如下所示:

ALTSQRT的使用非常简单,坦白的说Bingo从来没看到DT。以下直接给出SQRT的例化,从而得到平方根,如下:

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

//Caculate the distance of P5 = (Gx^2 + Gy^2)^0.5

//Step 4

wire [10:0] Dim;

SQRT u_SQRT

(

.radical (Gxy_square),

.q (Dim),

.remainder

);

(5)根据外部输入阀值,判断并实现边缘的检测

简单的判断Dim的大小而已,大于阀值,视为有效,赋1;反之则赋0。这里的Sobel_Threshold由外部输入,暂且认为是60吧。。。

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

//Compare and get the Sobel_data

//Step 5

reg post_img_Bit_r;

always@(posedge clk or negedge rst_n)

begin

if(!rst_n)

post_img_Bit_r <= 1'b0; //Default None

else if(Dim >= Sobel_Threshold)

post_img_Bit_r <= 1'b1; //Edge Flag

else

post_img_Bit_r <= 1'b0; //Not Edge

end

前面从(1)-(5)中,总共消耗了5个时钟,因此最后对行场、像素有效时钟进行5个clock的偏移,如下:

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

//lag 5 clocks signal sync

reg [4:0] per_frame_vsync_r;

reg [4:0] per_frame_href_r;

always@(posedge clk or negedge rst_n)

begin

if(!rst_n)

begin

per_frame_vsync_r <= 0;

per_frame_href_r <= 0;

end

else

begin

per_frame_vsync_r <= {per_frame_vsync_r[3:0], matrix_frame_vsync};

per_frame_href_r <= {per_frame_href_r[3:0], matrix_frame_href};

end

end

assign post_frame_vsync = per_frame_vsync_r[4];

assign post_frame_href = per_frame_href_r[4];

assign post_img_Bit = post_frame_href ? post_img_Bit_r : 1'b0;

这样,便完成了Sobel边缘检测算法的移植。工程目录sim文件夹下包含了VIP的Modelsim工程,波形仿真如下(新架构没有*_clken):

最后,在Video_Image_Processor中例化VIP_Sobel_Edge_Detector模块,并且在Video_Image_Processor信号列表中修改输出与阀值输入,相关如下:

output post_img_Bit, //Processed Image Bit flag outout(1: Value, 0:inValid)

//user interface

input [7:0] Sobel_Threshold //Sobel Threshold for image edge detect

);

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

//Image edge detector with Sobel.

VIP_Sobel_Edge_Detector

#(

.IMG_HDISP (IMG_HDISP), //640*480

.IMG_VDISP (IMG_VDISP)

)

u_VIP_Sobel_Edge_Detector

(

//global clock

.clk (clk), //cmos video pixel clock

.rst_n (rst_n), //global reset

//Image data prepred to be processd

.per_frame_vsync (per_frame_vsync), //Prepared Image data vsync valid signal

.per_frame_href (per_frame_href), //Prepared Image data href vaild signal

.per_img_Y (per_img_Y), //Prepared Image brightness input

//Image data has been processd

.post_frame_vsync (post_frame_vsync), //Processed Image data vsync valid signal

.post_frame_href (post_frame_href), //Processed Image data href vaild signal

.post_img_Bit (post_img_Bit), //Processed Image Bit flag outout(1: Value, 0:inValid)

//User interface

.Sobel_Threshold (Sobel_Threshold) //Sobel Threshold for image edge detect

);

endmodule

VIP的例化从略。全编译,下载sof文件,如下图所示,为Sobel_Threshold=60下的边缘检测图(VGA 和USB一样哦)。

相关推荐

“版本末期”了?下周平衡补丁!国服最强5套牌!上分首选

明天,酒馆战棋就将迎来大更新,也聊了很多天战棋相关的内容了,趁此机会,给兄弟们穿插一篇构筑模式的卡组推荐!老规矩,我们先来看10职业胜率。目前10职业胜率排名与一周前基本类似,没有太多的变化。平衡补丁...

VS2017 C++ 程序报错“error C2065:“M_PI”: 未声明的标识符&quot;

首先,程序中头文件的选择,要选择头文件,在文件中是没有对M_PI的定义的。选择:项目——>”XXX属性"——>配置属性——>C/C++——>预处理器——>预处理器定义,...

东营交警实名曝光一批酒驾人员名单 88人受处罚

齐鲁网·闪电新闻5月24日讯酒后驾驶是对自己和他人生命安全极不负责的行为,为守护大家的平安出行路,东营交警一直将酒驾作为重点打击对象。5月23日,东营交警公布最新一批饮酒、醉酒名单。对以下驾驶人醉酒...

Qt界面——搭配QCustomPlot(qt platform)

这是我第一个使用QCustomPlot控件的上位机,通过串口精确的5ms发送一次数据,再将读取的数据绘制到图表中。界面方面,尝试卡片式设计,外加QSS简单的配了个色。QCustomPlot官网:Qt...

大话西游2分享赢取种族坐骑手办!PK趣闻录由你书写

老友相聚,仗剑江湖!《大话西游2》2021全民PK季4月激燃打响,各PK玩法鏖战齐开,零门槛参与热情高涨。PK季期间,不仅各种玩法奖励丰厚,参与PK趣闻录活动,投稿自己在PK季遇到的趣事,还有机会带走...

测试谷歌VS Code AI 编程插件 Gemini Code Assist

用ClaudeSonnet3.7的天气测试编码,让谷歌VSCodeAI编程插件GeminiCodeAssist自动编程。生成的文件在浏览器中的效果如下:(附源代码)VSCode...

顾爷想知道第4.5期 国服便利性到底需优化啥?

前段时间DNF国服推出了名为“阿拉德B计划”的系列改版计划,截至目前我们已经看到了两项实装。不过关于便利性上,国服似乎还有很多路要走。自从顾爷回归DNF以来,几乎每天都在跟我抱怨关于DNF里面各种各样...

掌握Visual Studio项目配置【基础篇】

1.前言VisualStudio是Windows上最常用的C++集成开发环境之一,简称VS。VS功能十分强大,对应的,其配置系统较为复杂。不管是对于初学者还是有一定开发经验的开发者来说,捋清楚VS...

还嫌LED驱动设计套路深?那就来看看这篇文章吧

随着LED在各个领域的不同应用需求,LED驱动电路也在不断进步和发展。本文从LED的特性入手,推导出适合LED的电源驱动类型,再进一步介绍各类LED驱动设计。设计必读:LED四个关键特性特性一:非线...

Visual Studio Community 2022(VS2022)安装图文方法

直接上步骤:1,首先可以下载安装一个VisualStudio安装器,叫做VisualStudioinstaller。这个安装文件很小,很快就安装完成了。2,打开VisualStudioins...

Qt添加MSVC构建套件的方法(qt添加c++11)

前言有些时候,在Windows下因为某些需求需要使用MSVC编译器对程序进行编译,假设我们安装Qt的时候又只是安装了MingW构建套件,那么此时我们该如何给现有的Qt添加一个MSVC构建套件呢?本文以...

Qt为什么站稳c++GUI的top1(qt c)

为什么现在QT越来越成为c++界面编程的第一选择,从事QT编程多年,在这之前做C++界面都是基于MFC。当时为什么会从MFC转到QT?主要原因是MFC开发界面想做得好看一些十分困难,引用第三方基于MF...

qt开发IDE应该选择VS还是qt creator

如果一个公司选择了qt来开发自己的产品,在面临IDE的选择时会出现vs或者qtcreator,选择qt的IDE需要结合产品需求、部署平台、项目定位、程序猿本身和公司战略,因为大的软件产品需要明确IDE...

Qt 5.14.2超详细安装教程,不会来打我

Qt简介Qt(官方发音[kju:t],音同cute)是一个跨平台的C++开库,主要用来开发图形用户界面(GraphicalUserInterface,GUI)程序。Qt是纯C++开...

Cygwin配置与使用(四)——VI字体和颜色的配置

简介:VI的操作模式,基本上VI可以分为三种状态,分别是命令模式(commandmode)、插入模式(Insertmode)和底行模式(lastlinemode),各模式的功能区分如下:1)...

取消回复欢迎 发表评论: