生活随笔
收集整理的這篇文章主要介紹了
FPGA学习笔记_图像处理3_FPGA实现中值滤波算法
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
FPGA學習筆記
圖像處理算法
1. 中值濾波算法1.1 原理1.2 FPGA實現中值濾波算法
2. 應用MATLAB給圖片加椒鹽噪聲
3. 項目結果
1. 中值濾波算法
1.1 原理
- 將每一像素點的灰度值設置為該點的某領域窗口內的所有像素點灰度值的中值。
- 特點:有效抑制噪聲,保護圖像邊緣信息,是經典的平滑噪聲方法,可用作處理RGB圖像格式。
方法:
將數據按大小排序,然后根據有序的數字序列找中值,排序算法:冒泡排序,二等分排序等軟件算法,適合硬件的排序算法比較少。
- 分別對三行像素進行排序
- 分別對三行像素中的3個最大,3個中間,3個最小分別進行排序
- 對最大的最小,中間的中間,最小的最大進行排序得到中值
1.2 FPGA實現中值濾波算法
-
項目目標:
將椒鹽噪聲圖片,通過中值濾波算法,進行去噪處理,并通過FPGA顯示到TFT顯示屏上。
-
項目工具:
① 硬件:Intel Cyclone IV E系列FPGA開發板,5寸(800*480)TFT電容觸摸顯示屏;
② 軟件:Quartus軟件,Picture2Hex軟件,MATLAB;
-
項目組成模塊:
① pll: 產生項目所需時鐘:1. SDRAM控制器時鐘;2. SDRAM時鐘信號;3. TFT屏控制器時鐘
② uart串口協議(uart_rx, uart_tx)
③ 讀FIFO
④ 寫FIFO
⑤ SDRAM控制模塊
⑥ TFT屏控制模塊
⑦ 中值濾波模塊
-
Verilog代碼
module
median_filter_r0(input clk
, input rst_n
,input
[15:0] data_in
, input data_in_en
,input hs_in
,input vs_in
,output wire
[15:0] data_out
,output wire data_out_en
,output wire hs_out
,output wire vs_out
);
reg hs_reg0
;reg hs_reg1
;reg hs_reg2
;reg vs_reg0
;reg vs_reg1
;reg vs_reg2
;reg de_reg0
;reg de_reg1
;reg de_reg2
;wire
[15:0] row0
;wire
[15:0] row1
;wire
[15:0] row2
;reg
[15:0] r0_c0
;reg
[15:0] r0_c1
;reg
[15:0] r0_c2
;reg
[15:0] r1_c0
;reg
[15:0] r1_c1
;reg
[15:0] r1_c2
;reg
[15:0] r2_c0
;reg
[15:0] r2_c1
;reg
[15:0] r2_c2
;reg
[15:0] r0_max
;reg
[15:0] r0_mid
;reg
[15:0] r0_min
;reg
[15:0] r1_max
;reg
[15:0] r1_mid
;reg
[15:0] r1_min
;reg
[15:0] r2_max
;reg
[15:0] r2_mid
;reg
[15:0] r2_min
;reg
[15:0] max_max
;reg
[15:0] max_mid
;reg
[15:0] max_min
;reg
[15:0] mid_max
;reg
[15:0] mid_mid
;reg
[15:0] mid_min
;reg
[15:0] min_max
;reg
[15:0] min_mid
;reg
[15:0] min_min
;reg
[15:0] mid
;
shifter3_3
shifter3_3(.clken(data_in_en
),.clock(clk
),.shiftin(data_in
),.shiftout(),.taps0x(row0
),.taps1x(row1
),.taps2x(row2
));always@
(posedge clk or negedge rst_n
)begin
if(!rst_n
)beginhs_reg0
<= 1'd0
;hs_reg1
<= 1'd0
;hs_reg2
<= 1'd0
;vs_reg0
<= 1'd0
;vs_reg1
<= 1'd0
;vs_reg2
<= 1'd0
;de_reg0
<= 1'd0
;de_reg1
<= 1'd0
;de_reg2
<= 1'd0
;end
else if(data_in_en
)beginhs_reg0
<= hs_in
;hs_reg1
<= hs_reg0
;hs_reg2
<= hs_reg1
;vs_reg0
<= vs_in
;vs_reg1
<= vs_reg0
;vs_reg2
<= vs_reg1
;de_reg0
<= data_in_en
;de_reg1
<= de_reg0
;de_reg2
<= de_reg1
;endend
always@
(posedge clk or negedge rst_n
)begin
if(!rst_n
)beginr0_c0
<= 16'd0
;r0_c1
<= 16'd0
;r0_c2
<= 16'd0
;r1_c0
<= 16'd0
;r1_c1
<= 16'd0
;r1_c2
<= 16'd0
;r2_c0
<= 16'd0
;r2_c1
<= 16'd0
;r2_c2
<= 16'd0
; end
else if(data_in_en
)beginr0_c0
<= row0
;r0_c1
<= r0_c0
;r0_c2
<= r0_c1
;r1_c0
<= row1
;r1_c1
<= r1_c0
;r1_c2
<= r1_c1
;r2_c0
<= row2
;r2_c1
<= r2_c0
;r2_c2
<= r2_c1
;end
end
always@
(posedge clk or negedge rst_n
)begin
if(!rst_n
)beginr0_max
<= 16'd0
;r0_mid
<= 16'd0
;r0_min
<= 16'd0
; end
else if(data_in_en
)begin
if((r0_c0
>=r0_c1
)&&(r0_c0
>=r0_c2
))beginr0_max
<= r0_c0
;if(r0_c1
>=r0_c2
)beginr0_mid
<= r0_c1
;r0_min
<= r0_c2
; end
else beginr0_mid
<= r0_c2
;r0_min
<= r0_c1
; endend
else if((r0_c1
>=r0_c0
)&&(r0_c1
>=r0_c2
))beginr0_max
<= r0_c1
;if(r0_c0
>=r0_c2
)beginr0_mid
<= r0_c0
;r0_min
<= r0_c2
; end
else beginr0_mid
<= r0_c2
;r0_min
<= r0_c0
; endend
else if((r0_c2
>=r0_c0
)&&(r0_c2
>=r0_c1
))beginr0_max
<= r0_c2
;if(r0_c0
>=r0_c1
)beginr0_mid
<= r0_c0
;r0_min
<= r0_c1
; end
else beginr0_mid
<= r0_c1
;r0_min
<= r0_c0
; endendendend
always@
(posedge clk or negedge rst_n
)begin
if(!rst_n
)beginr1_max
<= 16'd0
;r1_mid
<= 16'd0
;r1_min
<= 16'd0
; end
else if(data_in_en
)begin
if((r1_c0
>=r1_c1
)&&(r1_c0
>=r1_c2
))beginr1_max
<= r1_c0
;if(r1_c1
>=r1_c2
)beginr1_mid
<= r1_c1
;r1_min
<= r1_c2
; end
else beginr1_mid
<= r1_c2
;r1_min
<= r1_c1
; endend
else if((r1_c1
>=r1_c0
)&&(r1_c1
>=r1_c2
))beginr1_max
<= r1_c1
;if(r1_c0
>=r1_c2
)beginr1_mid
<= r1_c0
;r1_min
<= r1_c2
; end
else beginr1_mid
<= r1_c2
;r1_min
<= r1_c0
; endend
else if((r1_c2
>=r1_c0
)&&(r1_c2
>=r1_c1
))beginr1_max
<= r1_c2
;if(r1_c0
>=r1_c1
)beginr1_mid
<= r1_c0
;r1_min
<= r1_c1
; end
else beginr1_mid
<= r1_c1
;r1_min
<= r1_c0
; endendendend
always@
(posedge clk or negedge rst_n
)begin
if(!rst_n
)beginr2_max
<= 16'd0
;r2_mid
<= 16'd0
;r2_min
<= 16'd0
; end
else if(data_in_en
)begin
if((r2_c0
>=r2_c1
)&&(r2_c0
>=r2_c2
))beginr2_max
<= r2_c0
;if(r2_c1
>=r2_c2
)beginr2_mid
<= r2_c1
;r2_min
<= r2_c2
; end
else beginr2_mid
<= r2_c2
;r2_min
<= r2_c1
; endend
else if((r2_c1
>=r2_c0
)&&(r2_c1
>=r2_c2
))beginr2_max
<= r2_c1
;if(r2_c0
>=r2_c2
)beginr2_mid
<= r2_c0
;r2_min
<= r2_c2
; end
else beginr2_mid
<= r2_c2
;r2_min
<= r2_c0
; endend
else if((r2_c2
>=r2_c0
)&&(r2_c2
>=r2_c1
))beginr2_max
<= r2_c2
;if(r2_c0
>=r2_c1
)beginr2_mid
<= r2_c0
;r2_min
<= r2_c1
; end
else beginr2_mid
<= r2_c1
;r2_min
<= r2_c0
; endendendend
always@
(posedge clk or negedge rst_n
)begin
if(!rst_n
)beginmax_max
<= 16'd0
;max_mid
<= 16'd0
;max_min
<= 16'd0
; end
else if(data_in_en
)begin
if((r0_max
>= r1_max
)&&(r0_max
>= r2_max
))beginmax_max
<= r0_max
;if((r1_max
>= r2_max
))beginmax_mid
<= r1_max
;max_min
<= r2_max
; end
else beginmax_mid
<= r2_max
;max_min
<= r1_max
; end end
else if((r1_max
>= r0_max
)&&(r1_max
>= r2_max
))beginmax_max
<= r1_max
;if((r0_max
>= r2_max
))beginmax_mid
<= r0_max
;max_min
<= r2_max
; end
else beginmax_mid
<= r2_max
;max_min
<= r0_max
; end end
else if((r2_max
>= r0_max
)&&(r2_max
>= r1_max
))beginmax_max
<= r2_max
;if((r0_max
>= r1_max
))beginmax_mid
<= r0_max
;max_min
<= r1_max
; end
else beginmax_mid
<= r1_max
;max_min
<= r0_max
; end endendend
always@
(posedge clk or negedge rst_n
)begin
if(!rst_n
)beginmid_max
<= 16'd0
;mid_mid
<= 16'd0
;mid_min
<= 16'd0
; end
else if(data_in_en
)begin
if((r0_mid
>= r1_mid
)&&(r0_mid
>= r2_mid
))beginmid_max
<= r0_mid
;if((r1_mid
>= r2_mid
))beginmid_mid
<= r1_mid
;mid_min
<= r2_mid
; end
else beginmid_mid
<= r2_mid
;mid_min
<= r1_mid
; end end
else if((r1_mid
>= r0_mid
)&&(r1_mid
>= r2_mid
))beginmid_max
<= r1_mid
;if((r0_mid
>= r2_mid
))beginmid_mid
<= r0_mid
;mid_min
<= r2_mid
; end
else beginmid_mid
<= r2_mid
;mid_min
<= r0_mid
; end end
else if((r2_mid
>= r0_mid
)&&(r2_mid
>= r1_mid
))beginmid_max
<= r2_mid
;if((r0_mid
>= r1_mid
))beginmid_mid
<= r0_mid
;mid_min
<= r1_mid
; end
else beginmid_mid
<= r1_mid
;mid_min
<= r0_mid
; end endendendalways@
(posedge clk or negedge rst_n
)begin
if(!rst_n
)beginmin_max
<= 16'd0
;min_mid
<= 16'd0
;min_min
<= 16'd0
; end
else if(data_in_en
)begin
if((r0_min
>= r1_min
)&&(r0_min
>= r2_min
))beginmin_max
<= r0_min
;if((r1_min
>= r2_min
))beginmin_mid
<= r1_min
;min_min
<= r2_min
; end
else beginmin_mid
<= r2_min
;min_min
<= r1_min
; end end
else if((r1_min
>= r0_min
)&&(r1_min
>= r2_min
))beginmin_max
<= r1_min
;if((r0_min
>= r2_min
))beginmin_mid
<= r0_min
;min_min
<= r2_min
; end
else beginmin_mid
<= r2_min
;min_min
<= r0_min
; end end
else if((r2_min
>= r0_min
)&&(r2_min
>= r1_min
))beginmin_max
<= r2_min
;if((r0_min
>= r1_min
))beginmin_mid
<= r0_min
;min_min
<= r1_min
; end
else beginmin_mid
<= r1_min
;min_min
<= r0_min
; end endendend
always@
(posedge clk or negedge rst_n
)begin
if(!rst_n
)mid
<= 16'd0
; else if(data_in_en
)begin
if(((max_min
>= mid_mid
)&&(max_min
< min_max
))||((max_min
< mid_mid
)&&(max_min
>= min_max
)) )mid
<= max_min
;else if(((mid_mid
>= max_min
)&&(mid_mid
< min_max
))||((mid_mid
< max_min
)&&(mid_mid
>= min_max
)) )mid
<= mid_mid
;else if(((min_max
>= max_min
)&&(min_max
< mid_mid
))||((min_max
< max_min
)&&(min_max
>= mid_mid
)) )mid
<= min_max
;else;end
else;end
assign data_out
= mid
;assign data_out_en
= de_reg2
;assign hs_out
= hs_reg2
;assign vs_out
= vs_reg2
;
endmodule
2. 應用MATLAB給圖片加椒鹽噪聲:
close all
;clear all
;clc
;%清除L
= imread('C:\Users\GloriaHuo\Desktop\0001.jpg'); % 在指定路徑讀取圖像
J
= imnoise(L
,'salt & pepper', 0.1); %Salt
&pepper 噪聲密度
=0.1figure(1);
imshow(L
); % 顯示原圖
figure(2);
imshow(J
); %立即彈出窗口,顯示加了加椒鹽噪聲后的圖片
hold on
;imwrite(J
,'C:\Users\GloriaHuo\Desktop\0001_saltpepper.jpg');%把加入噪聲的圖像保存起來
3. 項目結果
5寸TFT電容觸摸顯示屏
圖像:800*480像素
(1). (易烊千璽^^)網絡原圖:
(2). FPGA顯示原圖:
(3). 加入椒鹽噪聲圖:
-
Salt&pepper 噪聲密度=0.1
(4). FPGA中值濾波處理圖:
-
Salt&pepper 噪聲密度=0.1
項目結果分析:
-
對比圖3與圖4可以發現,中值濾波算法可以有效地去除椒鹽噪聲;
參考資料:《FPGA系統設計與驗證實戰指南》
【注】:個人學習筆記,如有錯誤,望不吝賜教,這廂有禮了~~~
總結
以上是生活随笔為你收集整理的FPGA学习笔记_图像处理3_FPGA实现中值滤波算法的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。