FPGA学习笔记 【FPGA学习笔记|FPGA学习笔记_图像处理6_FPGA实现 sobel算子边缘检测算法】图像处理算法
1.sobel算子边缘检测算法
1.1 原理
1.2 FPGA实现 sobel算子边缘检测算法
1. sobel算子边缘检测算法
1.1 原理
- 边缘检测:标识数字图像中变化明显那的点。
- 结果体现:1. 深度上的不连续. 2. 表面方向不连续. 3. 物质属性变化. 4.场景照明变化.
- 应用:图像处理和计算机视觉
- 边缘检测算子:
1阶:roberts cross算子, prewitt算子,sobel算子,kirch算子,罗盘算子
2阶:canny算子,laplacian算子 - Sobel算子:
离散,1阶,差分算子,用于计算图像亮度函数的1阶梯度的近似值(梯度矢量,法矢量),具有方向性,可以检测竖直/垂直/全部。
优缺点:效率比canny边缘检测高,但是边缘不如canny检测准确.
文章图片
- FPGA实现步骤:
- Gx=P*Sobelx (原始图像与sobel算子X方向卷积)
- Gy=P*Sobely(原始图像与sobel算子Y方向卷积)
- G= sqrt(G^2 x+G^2 y)
- 阈值比较形成边缘查找后的二值图像。
- FPGA实现方法:
项目工具:
① 硬件:Intel Cyclone IV E系列FPGA开发板,5寸(800*480)TFT电容触摸显示屏,
② 软件:Quartus软件,Picture2Hex软件
文章图片
项目组成模块:
① pll: 产生项目所需时钟:1. SDRAM控制器时钟;2. SDRAM时钟信号;3. TFT屏控制器时钟
② uart串口协议(uart_rx, uart_tx)
③ 读FIFO
④ 写FIFO
⑤ SDRAM控制模块
⑥ TFT屏控制模块
⑦ sobel算子边缘检测模块
- Verilog代码
module sobel_r0(
inputclk,
inputrst_n,
inputdata_in_en,
input[9:0]data_in,
input[7:0]threshold,
outputwire [9:0]data_out,
output wiredata_out_en
);
wire [7:0]r0;
wire [7:0]r1;
wire [7:0]r2;
reg [17:0] Gx1;
reg [17:0] Gx3;
reg [17:0] Gy1;
reg [17:0] Gy3;
wire [17:0] Gx;
wire [17:0] Gy;
wire [15:0] G_final;
regde_reg0;
regde_reg1;
regde_reg2;
reg [7:0] r0_c0;
reg [7:0] r0_c1;
reg [7:0] r0_c2;
reg [7:0] r1_c0;
reg [7:0] r1_c1;
reg [7:0] r1_c2;
reg [7:0] r2_c0;
reg [7:0] r2_c1;
reg [7:0] r2_c2;
//----3*3 matrix pixels---------------------
shifter3_3 shifter3_3 (
.clken(data_in_en),
.clock(clk),
.shiftin(data_in[9:2]),
.shiftout(),
.taps0x(r0),
.taps1x(r1),
.taps2x(r2)
);
/*
|r0_c0,r0_c1,r0_c2|
|r1_c0,r1_c1,r1_c2|
|r2_c0,r2_c1,r2_c2|
*/
always@(posedge clk or negedge rst_n)begin
if(!rst_n)begin
r0_c0 <= 8'd0;
r0_c1 <= 8'd0;
r0_c2 <= 8'd0;
r1_c0 <= 8'd0;
r1_c1 <= 8'd0;
r1_c2 <= 8'd0;
r2_c0 <= 8'd0;
r2_c1 <= 8'd0;
r2_c2 <= 8'd0;
end
else if(data_in_en)begin
r0_c0 <= r0;
r0_c1 <= r0_c0;
r0_c2 <= r0_c1;
r1_c0 <= r1;
r1_c1 <= r1_c0;
r1_c2 <= r1_c1;
r2_c0 <= r2;
r2_c1 <= r2_c0;
r2_c2 <= r2_c1;
end
end
//------------------------------------------
//----Gx = P * sobelx,Gy = P * sobely-------
----mask x---------------------------
///*
// |x11 x12 x13||-1,0,1|
// |x21 x22 x23| <-->|-2,0,2|
// |x31 x32 x33||-1,0,1|
//*/----mask y---------------------------
///*
// |y11 y12 y13|| 1, 2, 1|
// |y21 y22 y23| <-->| 0, 0, 0|
// |y31 y32 y33||-1,-2,-1|
//*/
always@(posedge clk or negedge rst_n)begin
if(!rst_n)begin
Gx1 <= 8'd0;
Gx3 <= 8'd0;
Gy1 <= 8'd0;
Gy3 <= 8'd0;
end
else if(data_in_en)begin
Gx1 <= r0_c0 + (r1_c0<<1) + r2_c0;
//负数
Gx3 <= r0_c2 + (r1_c2<<1) + r2_c2;
//正数Gy1 <= r0_c0 + (r0_c1<<1) + r0_c2;
//正数
Gy3 <= r2_c2 + (r2_c1<<1) + r2_c2;
//负数
end
end
assign Gx = (Gx1>Gx3)?(Gx1-Gx3):(Gx3-Gx1);
assign Gy = (Gy1>Gy3)?(Gy1-Gy3):(Gy3-Gy1);
//--------------------------------------------
//----sqrt(Gx*Gx+Gy*Gy)-----------------------
sqrt sqrt (
.clk(clk),
.radical(Gx*Gx+Gy*Gy),
.q(G_final),
.remainder()
);
//------------------------------------------
//----阈值比较-------------------------------
assign data_out = (G_final>threshold)?10'd0:10'b11_1111_1111;
//----timing---------------------------------
always@(posedge clk or negedge rst_n)begin
if(!rst_n)begin
de_reg0 <= 1'b0;
de_reg1 <= 1'b0;
de_reg2 <= 1'b0;
end
else if(data_in_en)begin
de_reg0 <= data_in_en;
de_reg1 <= de_reg0;
de_reg2 <= de_reg1;
end
end
assign data_out_en = de_reg2;
//---------------------------------------------
endmodule
- 项目结果
5寸TFT电容触摸显示屏
图像:800*480像素
(1). (易烊千玺^^)网络原图:
文章图片
(2). FPGA显示原图:
文章图片
- Threshold(阈值)=3:
文章图片
- Threshold(阈值)=5:
文章图片
- Threshold(阈值)=7:
文章图片
项目结果分析:
- 对比 Threshold(阈值) = 3,5,7 三幅图可以发现,经过sobel算子边缘检测后的图像,随着阈值的增加,图像的细节越来越少;
【注】:个人学习笔记,如有错误,望不吝赐教,这厢有礼了~~~
推荐阅读
- C++|算法-栈和队列(用栈实现队列)
- 机器学习|机器学习(七)过拟合问题与正则化
- 玩转算法系列–图论精讲 面试升职必备(Java版)含源码ppt无mi分xiang
- 排序算法|归并排序(c语言)
- Verilog|Verilog task 任务
- verilog|Verilog function 函数
- OpenCV|【opencv】最近邻插值、双线性插值、双三次插值(三次样条插值)
- 经典网络学习|【迁移学习】Transfer Learning
- #|【DataLoader】pytorch中DataLoader的num_workers参数详解与设置大小建议