FPGA study notes
Image processing algorithm
1. sobel算子边缘检测算法
1.1 原理
1.2 FPGA实现 sobel算子边缘检测算法
1. Sobel operator edge detection algorithm
1.1 Principle
- Edge detection : Identifies the points that have obvious changes in the digital image.
- The results show : 1. Discontinuity in depth. 2. Discontinuity in surface direction. 3. Changes in material properties. 4. Changes in scene lighting.
- Application : image processing and computer vision
- Edge detection operators :
1st order: roberts cross operator, prewitt operator, sobel operator, kirch operator, compass operator
2nd order: canny operator, laplacian operator - Sobel operator:
Discrete, 1st order, difference operator, used to calculate the approximate value (gradient vector, normal vector) of 1 step of the image brightness function, with directivity, and can detect vertical/vertical/all.
Advantages and disadvantages: efficiency is higher than canny edge detection, but the edge is not as accurate as canny detection.
1.2 FPGA implementation of gray-scale image mean filtering algorithm
- FPGA implementation steps :
- Gx=P*Sobelx (the original image is convolved with the sobel operator in the X direction)
- Gy=P*Sobely (the original image is convolved with the sobel operator in the Y direction)
- G= sqrt(G^2 x+G^2 y)
- Threshold comparison forms a binary image after edge search.
-
FPGA implementation method :
Project tools:
① Hardware: Intel Cyclone IV E series FPGA development board, 5-inch (800*480) TFT capacitive touch screen,
② Software: Quartus software, Picture2Hex software
project component modules:
① pll: where the project is generated Need clock: 1. SDRAM controller clock; 2. SDRAM clock signal; 3. TFT screen controller clock
② uart serial protocol (uart_rx, uart_tx)
③ read FIFO
④ write FIFO
⑤ SDRAM control module
⑥ TFT screen control module
⑦ sobel calculation Sub-edge detection module -
Verilog code
module sobel_r0(
input clk,
input rst_n,
input data_in_en,
input [9:0] data_in,
input [7:0] threshold,
output wire [9:0] data_out,
output wire data_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;
reg de_reg0;
reg de_reg1;
reg de_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
- Project result
5 inch TFT capacitive touch screen
Image: 800*480 pixels
(1). (Yiyangqianxi^^) Original network image:
(2). FPGA display original image:
(3). FPGA sobel operator edge detection diagram:
-
Threshold=3:
-
Threshold=5:
-
Threshold=7:
Project result analysis: -
Comparing the three images of Threshold = 3, 5, 7 we can find that the image after the edge detection of the sobel operator, with the increase of the threshold, the details of the image become less and less;
Reference materials: "FPGA System Design and Verification Practical Guide"
[Note]: Personal study notes, if there are mistakes, please feel free to enlighten me, this is polite~~~