EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
大侠好,欢迎来到FPGA技术江湖,江湖偌大,相见即是缘分。大侠可以关注FPGA技术江湖,在“闯荡江湖”、"行侠仗义"栏里获取其他感兴趣的资源,或者一起煮酒言欢。
- o' Y/ i% u) f: @+ Y& B; g+ }3 Q) s. L; k
今天给大侠带来FPGA设计中用Verilog HDL实现基本的图像滤波处理仿真,话不多说,上货。
; ^' k2 K6 F/ P. {! [0 S6 a4 S4 \
4 y' ~7 k5 b9 ?1、用matlab代码,准备好把图片转化成Vivado Simulator识别的格式,即每行一个数据:! e3 ?9 B- s8 J5 F) a
0 Q7 m: U) ~7 x" D0 d+ A
2 \5 m0 a3 w* ~
0 E0 |( T/ r9 Y* C) I- N" e5 c4 U" _1 k8 K
源码:
6 H0 H3 i7 P8 ~6 u( V; W
( @- X# Z* }9 x1 f7 jimg = imread('E:\matlab\Images\2016-09-05-211710.jpg');
, {/ q- A9 s0 d if size(img,3)==3
1 [' ^" d8 s# W4 \ img = rgb2gray(img);
$ A( r0 D: f0 b2 s end
. D6 |3 j* A* z# M height = size(img, 1);
8 N7 O6 @! k. d/ k+ i# {/ e! I width = size(img, 2); : S8 k1 U# A$ e/ u! ~5 Z
s = fopen('image2mem.txt','wb'); %opens the output file
" d4 h! o5 H$ V' W cnt = 0;
: l% G: N }8 V9 _ for r=1:height
- b9 }! v/ w' _$ u: |/ H) x9 P for c=1:width ' B( ]; s4 ^& g0 V% ~4 C+ [$ m
cnt = cnt + 1; 8 z8 P+ p- _: W5 y' |7 _2 r& j
grey=img(r,c);
8 }$ I$ G$ f+ L/ S greyb = dec2bin(grey,8);
0 M* Q9 b1 }; t Outbyte =greyb(1:8);
) F: b8 A8 Q7 T" p- Q& N6 N" W0 e6 H
7 g6 }& c2 g) p t! a# y
! D, I7 C- A! F% }/ C7 s7 g; k if (Outbyte(1:4) == '0000')fprintf(s,'0%X',bin2dec(Outbyte)); - f9 t. h7 i2 E( I
else fprintf(s,'%X',bin2dec(Outbyte)); end
, k" P2 U, d b' B4 C. B" J6 i if (mod(cnt,1) == 0)fprintf(s,'\r\n'); end
& q' ?& f a& [8 ?; | end
' O; o2 y6 o( w- Y3 g% m6 M* V end
: u- \# D, J9 I* K7 _ figure,imshow(img); & e/ Z2 _5 G! S# L$ D! ` ^
fclose(s);
1 [3 Q: k( Q, n1 a6 S3 C) v; W1 v+ R% i
( }3 l/ U; R& t( {, o! N$ Y6 x) x+ k2、EdgeSobel的Verilog源代码:
. K% B4 W9 v) X& Y
, q5 E8 G y0 m
7 ~- F4 f# Z# n. G
" o- s$ |6 P% q4 L- l. ^2 u: b" {源码:
' P) U9 V. I) I# M7 r`timescale 1ns/1ps
) R }! d& U& V) S
module EdgeSobel( input clk, input [7:0] inData, input [11:0]x, input [11:0]y, output [7:0] outData ); parameter pixel_depth=8; parameter frame_width=640; parameter block_width=3; parameter block_height=3;
2 z6 ~; |$ v$ \4 b" l( U
parameter shiftRegSize=pixel_depth*((block_height-1)*frame_width+block_width); 8 A- R( I: G( q
reg[shiftRegSize-1:0] shiftReg; wire [block_width*block_height*pixel_depth-1:0] Window;
; u) j" ^* L( K) i5 e) v
initial begin shiftReg=10264'b0;end always@(posedge clk)if((x<640)&&(y<480))shiftReg<={shiftReg,inData}; 9 @3 \/ \# }% p. O
genvar i,j; generate for(i = 0; i < block_height; i = i + 1) begin : array for(j = 0; j < block_width; j = j + 1) begin : vector assign Window[pixel_depth*(i * block_width + j)+:pixel_depth] =shiftReg[pixel_depth*(i*frame_width+j)+:pixel_depth]; end end endgenerate ' O2 u4 A2 _! _7 h) F" h, q9 ^
wire [7:0] average; assign average = (Window[7:0]+Window[15:8]+Window[23:16]+ //Window[31:24]+Window[39:32]+Window[47:40]+ Window[31:24]+Window[39:32]+Window[47:40]+ Window[55:48]+Window[63:56]+Window[71:64])/9 ;
4 t$ e& D: {7 P2 s/ A
wire signed [pixel_depth+1:0] Gx; wire signed [pixel_depth+1:0] Gy; wire [pixel_depth+1:0] Gxabs; wire [pixel_depth+1:0] Gyabs; wire [pixel_depth+1:0] G;
+ Z! w R' r1 N1 R
assign Gx = shiftReg[pixel_depth*(0*frame_width+2)+:pixel_depth] +2*shiftReg[pixel_depth*(1*frame_width+2)+:pixel_depth] + shiftReg[pixel_depth*(2*frame_width+2)+:pixel_depth] - shiftReg[pixel_depth*(0*frame_width+0)+:pixel_depth] -2*shiftReg[pixel_depth*(1*frame_width+0)+:pixel_depth] - shiftReg[pixel_depth*(2*frame_width+0)+:pixel_depth]; assign Gy = shiftReg[pixel_depth*(2*frame_width+0)+:pixel_depth] +2*shiftReg[pixel_depth*(2*frame_width+1)+:pixel_depth] + shiftReg[pixel_depth*(2*frame_width+2)+:pixel_depth] - shiftReg[pixel_depth*(0*frame_width+0)+:pixel_depth] -2*shiftReg[pixel_depth*(0*frame_width+1)+:pixel_depth] - shiftReg[pixel_depth*(0*frame_width+2)+:pixel_depth]; assign Gxabs = (Gx>0)?Gx-Gx); assign Gyabs = (Gy>0)?Gy-Gy); assign G = Gxabs+Gyabs; 9 q6 z* G/ B& k; ~( d6 {- T2 y+ U3 P! z
//assign outData = average; //平滑 assign outData = G[9:2]; //边缘检测 endmodule
0 w/ H7 g+ w. h/ l3、仿真文件:EdgeSobel_tb.v# s& q: v8 t( F
$ ]5 B' n4 N; g- I$ s
: W ]( y3 w9 o
* }8 J8 f& s+ ^3 x4 `. B5 ^. |" \5 n
源码:
: F% w5 M( Z* n3 M- @, R`timescale 1ns / 1ps # h4 S# { q* c8 [* h6 R
module edgesobel_tb; 9 ]+ L7 |$ o- C8 y; R7 k/ J3 o5 Q
reg clk; reg [7:0] inData; reg [19:0] cnt; reg [9:0] row; wire [7:0] outData; reg [7:0] image [307199:0]; integer file_id; reg [4:0] frame_cnt; ' B/ `. T* O$ K$ B. v6 W
initial begin $readmemh("E:/matlab/Vivado/image2mem.txt", image); file_id = $fopen("E:/matlab/Vivado/mem2image.txt","w"); clk = 0; cnt = 0; row = 0; frame_cnt = 0; end 6 I; \! B- L& z% B8 G* f: T/ k
EdgeSobel u_2 ( .clk(clk), .x(1), .y(1), .inData(inData), .outData(outData) ); 4 }' k! u* Z/ v% ^7 S
always #1 clk = ~clk;
5 F" G4 y+ }1 {* d6 D
always@(posedge clk) begin if(cnt == 307200) begin cnt = 0; row = 0; frame_cnt = frame_cnt + 1; end else inData = image[cnt]; cnt = cnt+1; if(frame_cnt==1) begin $fwrite(file_id, "%d ", outData); if(((cnt % 640)==0) &&(cnt>0)) begin $fwrite(file_id,"\r\n"); row = row + 1; end; end end endmodule
0 K6 F' c- \# \5 O" U# X
4、把输出的txt文件转化成图片Matlab程序:+ o3 t" Z3 l2 n" j& F
A=importdata('E:\matlab\Vivado\mem2image.txt');6 R- ^0 }. o- P& Q
A=A./255;
. g4 m5 d3 o) C) D imshow(A); * @1 z5 K) h& c' G/ ]6 L. S
注意这里的A是double类型的,直接进行imshow会全白,要转化到0-1:A=A./255,或者把double类型转化为整形。 3 N; r) P8 \7 D
后续会持续更新,带来Vivado、 ISE、Quartus II 、candence等安装相关设计教程,学习资源、项目资源、好文推荐等,希望大侠持续关注。
# h$ H" q4 _1 y大侠们,江湖偌大,继续闯荡,愿一切安好,有缘再见!
" F- e K& j. `* Q3 L! `8 Y4 f |