EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
大侠好,欢迎来到FPGA技术江湖,江湖偌大,相见即是缘分。大侠可以关注FPGA技术江湖,在“闯荡江湖”、"行侠仗义"栏里获取其他感兴趣的资源,或者一起煮酒言欢。3 @2 I6 U3 ?* x* g8 d' V
2 |0 a( G6 u Z5 k: p0 _9 T 今天给大侠带来FPGA设计中用Verilog HDL实现基本的图像滤波处理仿真,话不多说,上货。
6 C4 Z; ~- U/ @7 A/ o+ C" ?, q: T r4 z: }/ h% f
1、用matlab代码,准备好把图片转化成Vivado Simulator识别的格式,即每行一个数据:- B- A- d2 y* F/ C4 {
/ u0 z2 M1 g3 h. v5 |5 F$ X' D" d) V* k
/ I ]( H) _+ B' U* P' t! p
" g; w0 L5 ?/ L J! @* \源码:/ L {. A1 g- i+ h% u
* j1 v3 V5 G' X" s5 E9 s% `3 G% a7 @img = imread('E:\matlab\Images\2016-09-05-211710.jpg');
7 X" @& |# @; C) o if size(img,3)==3
! | ]( c: F9 p) j img = rgb2gray(img); * b0 P# }- u" @2 u- b
end ) c' n* f |, n( Q- k
height = size(img, 1);
5 N, N/ L3 D: z" ~& A7 Y width = size(img, 2); 4 L" @4 a% x, P4 s) j6 j/ M
s = fopen('image2mem.txt','wb'); %opens the output file % l1 r" h( Q; S
cnt = 0;
* u" P; J; }' _" U l' N1 _ for r=1:height
# ]! V. s1 z+ d# G for c=1:width
' F7 j- Q! q2 Q& ] cnt = cnt + 1;
# U7 P: I3 s9 o$ I9 A: G; T3 i; M grey=img(r,c); 9 K& l0 i# k& g% _* W t
greyb = dec2bin(grey,8); . a) _3 e Z- X
Outbyte =greyb(1:8);1 R! M+ U4 P- ~2 V
" e9 {6 ]5 s) W% \0 u/ y2 f
7 |) C% [: y# Q" x$ o" g
M* W7 M- e: l* e$ i if (Outbyte(1:4) == '0000')fprintf(s,'0%X',bin2dec(Outbyte)); 4 f1 [1 [* J! z8 F. i
else fprintf(s,'%X',bin2dec(Outbyte)); end
7 P2 n- l, U4 ^5 Z if (mod(cnt,1) == 0)fprintf(s,'\r\n'); end H. n# L0 H, w4 u, i9 s8 ]
end 5 {! N) o% g T/ V. d
end ; n3 ?/ Z) F" V' Z- ?* }
figure,imshow(img); / T7 p) G' e4 q* p; L/ h2 u
fclose(s);. \3 r1 o) s' H) S4 L' j
) q* J4 W; P6 k, n3 D
- `* A7 `" {2 U* J6 t8 [2、EdgeSobel的Verilog源代码:
' l8 D' D* \# n( ]$ o( ^; J
+ U- r& }# Q( E* p g2 P9 s
' E( e8 N" z8 m& n* t3 {/ N
! \' w! o2 _" ?, ]
源码:
/ N3 c& V, }* O# `, Z5 v" ^`timescale 1ns/1ps
/ B+ M- w( A j0 f* |& 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 |9 G1 L G8 F2 U
parameter shiftRegSize=pixel_depth*((block_height-1)*frame_width+block_width);
O }$ s( W. v# I
reg[shiftRegSize-1:0] shiftReg; wire [block_width*block_height*pixel_depth-1:0] Window;
, W7 V! y ]& Z. t' l$ u6 J
initial begin shiftReg=10264'b0;end always@(posedge clk)if((x<640)&&(y<480))shiftReg<={shiftReg,inData}; ( Q5 ^4 Z, L/ E- b
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
3 S; T% \& n- s# S. M8 b% W5 l
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 ;
& @7 q N8 N J" e
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;
+ V2 D: D1 [: R. z
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; & Q# c( w! t4 a9 c4 j* t
//assign outData = average; //平滑 assign outData = G[9:2]; //边缘检测 endmodule 3 t1 T, f8 f: \# z
3、仿真文件:EdgeSobel_tb.v
+ Y% m7 `* o: p& \8 R+ ]+ Z& |& _0 O" _$ s2 K% A
. e9 h! ?0 M2 n* s' t
4 O8 T& {1 f8 h
" v3 Y# X' l, K$ h3 o' Q1 J. Z
源码:
J, q! r- V7 ?/ c6 j, K`timescale 1ns / 1ps ; f+ ^. \8 p- X. T0 l) _( b
module edgesobel_tb; 3 Q" C! g( Q# S: R! M$ s. d
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;
7 t2 K* M; f& L8 @2 |/ }: V
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
/ o5 H p4 z; U
EdgeSobel u_2 ( .clk(clk), .x(1), .y(1), .inData(inData), .outData(outData) );
f, {6 e3 X$ O) p4 g6 K! h% ?3 w
always #1 clk = ~clk; 0 D, X5 y, c# [
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
5 }' Y6 o a& c* x3 Y
4、把输出的txt文件转化成图片Matlab程序:! ]/ P5 \; a6 I7 O; F
A=importdata('E:\matlab\Vivado\mem2image.txt');
. m$ }. V# n& Z7 U7 i6 j A=A./255;+ T! b+ Z5 ]% m' E
imshow(A);
0 O& M% x5 K" [, K$ `
注意这里的A是double类型的,直接进行imshow会全白,要转化到0-1:A=A./255,或者把double类型转化为整形。
# M. l% S1 k- _6 J$ Y6 F 后续会持续更新,带来Vivado、 ISE、Quartus II 、candence等安装相关设计教程,学习资源、项目资源、好文推荐等,希望大侠持续关注。& L1 X) j- A2 ^# D! n
大侠们,江湖偌大,继续闯荡,愿一切安好,有缘再见!( |# g0 v, V* _. i- a
|