「博文连载」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个步骤,解析与实现分别如下:
计算计算Gx与Gy与模板每行的乘积
求得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”: 未声明的标识符"
-
首先,程序中头文件的选择,要选择头文件,在文件中是没有对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)...
你 发表评论:
欢迎- 一周热门
- 最近发表
-
- “版本末期”了?下周平衡补丁!国服最强5套牌!上分首选
- VS2017 C++ 程序报错“error C2065:“M_PI”: 未声明的标识符"
- 东营交警实名曝光一批酒驾人员名单 88人受处罚
- Qt界面——搭配QCustomPlot(qt platform)
- 大话西游2分享赢取种族坐骑手办!PK趣闻录由你书写
- 测试谷歌VS Code AI 编程插件 Gemini Code Assist
- 顾爷想知道第4.5期 国服便利性到底需优化啥?
- 掌握Visual Studio项目配置【基础篇】
- 还嫌LED驱动设计套路深?那就来看看这篇文章吧
- Visual Studio Community 2022(VS2022)安装图文方法
- 标签列表
-
- wireshark怎么抓包 (75)
- qt sleep (64)
- cs1.6指令代码大全 (55)
- factory-method (60)
- sqlite3_bind_blob (52)
- hibernate update (63)
- c++ base64 (70)
- nc 命令 (52)
- wm_close (51)
- epollin (51)
- sqlca.sqlcode (57)
- lua ipairs (60)
- tv_usec (64)
- 命令行进入文件夹 (53)
- postgresql array (57)
- statfs函数 (57)
- .project文件 (54)
- lua require (56)
- for_each (67)
- c#工厂模式 (57)
- wxsqlite3 (66)
- dmesg -c (58)
- fopen参数 (53)
- tar -zxvf -c (55)
- 速递查询 (52)