|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
FPGA Verilog实现基本的图像滤波处理仿真
4 _+ l& O2 H( G ]% _2 y w4 M# M# J6 ^& `* x. D- f( S$ @- V: W H
1、用matlab代码,准备好把图片转化成Vivado Simulator识别的格式,即每行一个数据:6 B' e/ p. T7 C) `" U
img = imread('E:\matlab\Images\2016-09-05-211710.jpg');
+ H% ]5 h4 C5 x3 eif size(img,3)==3. \3 A. J. l6 z5 b! t9 `/ i
img = rgb2gray(img);2 H6 e$ Y. `% r- z. f
end
' ^& _1 u$ K* D, I% ~7 ^height = size(img, 1);
' l# |4 q8 P5 vwidth = size(img, 2);- A, w1 J- z1 f7 S1 T
s = fopen('image2mem.txt','wb'); %opens the output file! j( V% s1 w+ i; ]" r S& j1 B: l
cnt = 0;
# q; K( t! a* }# T% k, mfor r=1:height
* |6 e; [3 }7 K/ V4 z( }2 s7 A for c=1:width( h4 B# q e- ]5 C
cnt = cnt + 1;% C4 m# [+ a @1 B+ a
grey=img(r,c);9 E6 N8 d: t" V( U8 R
greyb = dec2bin(grey,8);7 n$ b1 y& H' B
Outbyte =greyb(1:8);' |5 }# ?$ }! [0 `/ J# N) H' j
6 B ?8 `8 p W1 X, Z
if (Outbyte(1:4) == '0000')fprintf(s,'0%X',bin2dec(Outbyte));- L7 ~0 }0 Q6 o. n+ @( [" R8 ]
else fprintf(s,'%X',bin2dec(Outbyte)); end
8 }' H# o+ i% u* e if (mod(cnt,1) == 0)fprintf(s,'\r\n'); end
- I+ y5 x& n+ | end0 t" K g. }7 F3 M) g s9 {# H
end: x- I3 q n0 m4 s) k2 o, ^
figure,imshow(img);
, t( _, C% }4 o3 ` e* R3 L- Dfclose(s);
) y0 k5 F( w. T u4 ^- \: D8 z- ~, X* j: J. p" k0 ~! T4 N
2、EdgeSobel的Verilog源代码:1 _: N5 h( ]2 [- D% S: y
`timescale 1ns / 1ps- ?$ r `# W! K2 w2 ]. s
/ L0 n; j- O2 r2 n: Z
module EdgeSobel
) H7 p0 h5 V% m$ G( L (
9 B4 u; A3 G/ } input clk,
; K+ i1 w/ D- O7 i' T input [7:0] inData," v- Z3 s# {4 j0 |! @$ @
input [11:0]x,
; i l+ p# A. y1 J/ C input [11:0]y,: v( n) i2 |+ u0 i
output [7:0] outData
0 Z6 k. \! m n+ v7 s; s ); " @" G; O3 X/ I: l: g$ Y$ K4 N) ]
parameter pixel_depth=8;" z$ g% i ?) x2 P6 k6 Y3 G' c+ ]2 R
parameter frame_width=640;
- a* u5 u, p A9 n. d9 j parameter block_width=3;
6 Y- N, f0 V5 j- x3 T parameter block_height=3;
9 A/ ?% H+ ^9 l& e# J7 U- ^: V* j" e
parameter shiftRegSize=pixel_depth*((block_height-1)*frame_width+block_width);4 F) {. a3 }* E) k
) n0 X! d3 E% ~ reg[shiftRegSize-1:0] shiftReg;
1 x2 x9 L; d; x+ z wire [block_width*block_height*pixel_depth-1:0] Window; / s1 ?2 L4 A6 G% J) |% y9 `
; O: J/ k5 M% T3 G7 k6 s
initial begin shiftReg=10264'b0;end
$ u1 \( r( S5 O9 }/ C
; K- K! v9 P- K always@(posedge clk)if((x<640)&&(y<480))shiftReg<={shiftReg,inData};
1 |6 g6 {0 O" @" \! I
9 a2 l8 v3 v8 @8 J: h: W0 b genvar i,j;
5 U L" X- f; e& F generate" k0 Q% f; B) L$ |5 r% c& x& }
for(i = 0; i < block_height; i = i + 1) begin : array! F4 a/ w) J& k8 R
for(j = 0; j < block_width; j = j + 1) begin : vector7 Z" Q/ l$ T$ H# c
assign Window[pixel_depth*(i * block_width + j)+:pixel_depth] =shiftReg[pixel_depth*(i*frame_width+j)+:pixel_depth];" `. l3 H8 h1 k
end
* r0 X2 _3 G1 P! U+ d$ d end( s( j) A+ ?: X2 Z; Q9 V
endgenerate
" r; T5 |/ t+ X+ B1 ?
/ y: c( O! K- \; Z* s" a wire [7:0] average;
) r$ L9 U) x! ~8 X+ s( [ assign average =
3 o) D3 s( n9 j5 u (Window[7:0]+Window[15:8]+Window[23:16]+- z; N( H# E' d5 T
//Window[31:24]+Window[39:32]+Window[47:40]+; \7 T4 Q! u- D- q9 G( ^
Window[31:24]+Window[39:32]+Window[47:40]+
, ]& O9 b6 u3 e0 B Window[55:48]+Window[63:56]+Window[71:64])/9 ;
5 _4 m1 y; w& E# }
- k$ Y0 i! {# n: s5 a6 g2 G# l9 _ wire signed [pixel_depth+1:0] Gx;+ c9 a4 V& q7 m. l) x; K: {
wire signed [pixel_depth+1:0] Gy;
& v/ G8 m3 }. H wire [pixel_depth+1:0] Gxabs;% d& I* {! P& H3 L8 W2 x, s8 p: D0 i% i
wire [pixel_depth+1:0] Gyabs;/ ?+ T3 D5 q1 O. V- U$ e; V
wire [pixel_depth+1:0] G;
/ x3 T7 @% ~0 O- I# V! m3 m
. ]" z, K2 K3 G! n assign Gx = shiftReg[pixel_depth*(0*frame_width+2)+:pixel_depth]8 [ C3 E# L! p. s7 \) D; @7 P, o' r
+2*shiftReg[pixel_depth*(1*frame_width+2)+:pixel_depth]
) l# z: n. X- {$ P( X: B4 X4 L + shiftReg[pixel_depth*(2*frame_width+2)+:pixel_depth]' O2 k {7 i, o
- shiftReg[pixel_depth*(0*frame_width+0)+:pixel_depth]
8 m7 }) K! c8 y, p -2*shiftReg[pixel_depth*(1*frame_width+0)+:pixel_depth]7 d6 i4 i4 ~' n l. ^
- shiftReg[pixel_depth*(2*frame_width+0)+:pixel_depth];
0 @$ v+ S, Y" E5 l1 C$ B* n8 e2 v assign Gy = shiftReg[pixel_depth*(2*frame_width+0)+:pixel_depth]
% x. Z8 u. F4 O +2*shiftReg[pixel_depth*(2*frame_width+1)+:pixel_depth]5 p( V) `, Q' k* U3 t- U
+ shiftReg[pixel_depth*(2*frame_width+2)+:pixel_depth]
* f5 a( F; `; d - shiftReg[pixel_depth*(0*frame_width+0)+:pixel_depth]
: }" ^, f0 g" O) P$ d0 r' {% B# P -2*shiftReg[pixel_depth*(0*frame_width+1)+:pixel_depth]1 W0 {3 I2 e, c2 C& q
- shiftReg[pixel_depth*(0*frame_width+2)+:pixel_depth];
7 y s# [& W: K. c6 p$ ?* y+ ` assign Gxabs = (Gx>0)?Gx -Gx);
1 E) [, B" P" o, r assign Gyabs = (Gy>0)?Gy -Gy);
# i: C9 ?* j0 t% C7 [, T: r assign G = Gxabs+Gyabs;' {' J+ V9 p, k3 |! d" E. p/ ^" {
. e/ w6 b& n# V {$ H8 l4 f9 Z3 S
//assign outData = average; //平滑
6 y& `4 z' j7 t3 ?9 l. g assign outData = G[9:2]; //边缘检测0 L _- D2 e( ? L, w
endmodule
0 X& h d( C7 B
5 p. R; F" e6 ]2 `$ {: l3、仿真文件:tb_EdgeSobel.v
# l2 R" w" S/ a1 L2 |: A5 z`timescale 1ns / 1ps
- L1 y* D8 Z, A8 I$ Z$ p# X0 J
" U, E' q9 r' m1 r, I, L9 tmodule tb_edgesobel;
9 X" `" L, d# k7 T8 B& L; I
3 Y1 v7 K5 K6 L reg clk;
- T3 k/ n W$ |7 l+ z reg [7:0] inData;( F! V5 @5 p+ |4 k! q" `! Z% Y
reg [19:0] cnt;
5 k1 Y& t& D; e( Q8 Z. H1 o& E reg [9:0] row;$ y+ ~& J, j+ y0 i
wire [7:0] outData;/ v4 U) j( K/ c; i, ^0 r
reg [7:0] image [307199:0];
4 l( c0 A3 T+ f6 W8 U( t integer file_id;
1 V0 M1 L% _+ f N6 J0 j reg [4:0] frame_cnt;
N0 I, G1 z; a1 v1 q2 b2 a- |9 `$ h' u; _, I5 V" } D
7 A9 Y4 \! U; A: h! | initial
4 w9 n& D0 w2 ]5 C& b begin
( f' E) E" l' [8 b S4 p' k* u $readmemh("E:/matlab/Vivado/image2mem.txt", image);: |5 X" M! }- `8 M
file_id = $fopen("E:/matlab/Vivado/mem2image.txt","w");
J/ H: O8 d- [6 y9 N clk = 0;8 K* d3 D1 I, _: u) m, A' D
cnt = 0;
9 r( F" ?7 f; N. V' U' W z6 ?% i row = 0;2 A* B* h" N3 e% s$ i
frame_cnt = 0;/ _' C& Z& b) F C
end+ v& m- G7 o6 W; C3 R$ T9 z, ^
6 C# s/ U# X% N/ i
EdgeSobel u_2
, w a7 A S+ M1 B: G O+ a2 E& H6 m (
1 D8 ~: {) m$ }6 V .clk(clk),0 {$ g1 ?# N" _) f. t+ i
.x(1),
* r3 P* a) [+ q$ } .y(1),7 p# e$ P3 d: c( C" E! M
.inData(inData),
; U8 N+ f4 W8 }) h4 t- O .outData(outData)
- c- [) ?! s: f, \# t0 ~- l );: M: k& w& X. G7 o- m# G
, z% @% q0 ?7 N3 s ^ always #1 clk = ~clk;
. \ s& T- e: ^
8 Q9 e) k- p# X always@(posedge clk)4 k: V- D8 N1 Q
begin9 A1 g9 ^4 x3 a* x+ e3 A! u
if(cnt == 307200)
7 Q" h+ G3 S- _1 y* r begin' n* D: ^# y' n4 a4 _3 |
cnt = 0;
: Z8 @: B4 l) B& ?+ r* H row = 0;# y2 [4 P0 w" X' l2 | n+ o
frame_cnt = frame_cnt + 1;
4 |$ r$ }4 h& p# w: e% T end
2 a* t0 e1 I3 Y2 \ else 7 z% s) S7 W; T o( n' j
inData = image[cnt];2 j/ L" d0 u. d; `3 D" g
cnt = cnt+1;
7 ?! A% z. \9 A if(frame_cnt==1)6 }: ^7 W9 F/ _, R
begin8 N6 `& F: v' `1 q5 B: U4 K
$fwrite(file_id, "%d ", outData);+ I; j$ f5 f- c
if(((cnt % 640)==0) &&(cnt>0))
) ]/ I4 `5 N' t1 R# [4 L begin
) Y# ? D: w* n% B $fwrite(file_id,"\r\n");
; j* x0 v' D1 S5 T! H, w+ m4 d0 Q row = row + 1;8 S2 ?1 Z! y( _9 r. R
end;
# d# e# ~+ L7 s: M* B$ z end
& a3 b* f/ f" V end% w J: B$ c8 K! ]0 o
endmodule
. S4 P# s/ R4 S# }' b
/ X# {$ M8 Y! o4、把输出的txt文件转化成图片Matlab程序:7 f9 o& j+ t" J
A=importdata('E:\matlab\Vivado\mem2image.txt');9 X" | d! y/ }- m8 O" s( o
A=A./255;
0 d, v3 X5 V% r7 }8 t: N; V8 Mimshow(A);
9 b, }+ M! ?' S8 [" _
: `+ m6 U/ q' T3 U: T6 w0 [2 ]# R注意这里的A是double类型的,直接进行imshow会全白,要转化到0-1:A=A./255,或者把double类型转化为整形。 | 6 _% l' c' ^" R5 K7 J: ~
|
|