EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
大侠好,欢迎来到FPGA技术江湖,江湖偌大,相见即是缘分。大侠可以关注FPGA技术江湖,在“闯荡江湖”、"行侠仗义"栏里获取其他感兴趣的资源,或者一起煮酒言欢。
! z! g( `" j2 J* }% Y
8 O0 y+ f: ^+ \, |" ? 今天给大侠带来FPGA设计中用Verilog HDL实现基本的图像滤波处理仿真,话不多说,上货。
& M/ A2 h9 [$ M- ^" A. g4 v% |9 J& S9 N6 G
1、用matlab代码,准备好把图片转化成Vivado Simulator识别的格式,即每行一个数据:
8 D' V- n; c% Y. o- y/ ^
6 d7 P% m% K- ^' n* r9 j4 t1 ]' e: g- q, ]) n
; p% v$ H+ G& P [, |9 Z1 d, H+ Z. r, E5 W$ h* u$ u4 X6 z
源码:
t4 P5 u+ q, @ N( g+ e& Q8 u0 b" P9 P# X' ?+ y
img = imread('E:\matlab\Images\2016-09-05-211710.jpg'); " ?* s- G/ u, J6 O" Z8 e
if size(img,3)==3
6 u4 y1 K# O: J8 F( h3 [ img = rgb2gray(img);
3 q& n0 k9 A0 n, r- \ end e& M1 N* a; o* m8 i
height = size(img, 1); 2 L# ?0 D- I/ S; o# K
width = size(img, 2); 4 {" B7 \6 W/ `% I
s = fopen('image2mem.txt','wb'); %opens the output file 3 V' ?6 h0 h& W" H8 ]4 _
cnt = 0; & k. p8 a! t* ~
for r=1:height
' M8 t4 D8 f, `$ O# z5 V; h! G for c=1:width ; r S0 U+ D( n% ~# u
cnt = cnt + 1; 4 r- E' ~0 C6 M
grey=img(r,c);
* s4 B6 E1 @0 S, @( c greyb = dec2bin(grey,8);
+ I( z, v% Q- B6 ?$ v Outbyte =greyb(1:8);" P# [& C, J! m# z+ s: d8 i
/ w) r/ \ ^$ g4 P# a/ `/ a
9 T0 f' P2 Z! K
! g) X8 h7 m. y if (Outbyte(1:4) == '0000')fprintf(s,'0%X',bin2dec(Outbyte)); & \) b+ m" C5 v+ g) v6 Y, E
else fprintf(s,'%X',bin2dec(Outbyte)); end
& |! q+ S1 K% P6 w0 X* [0 G if (mod(cnt,1) == 0)fprintf(s,'\r\n'); end & V8 ~7 G7 Y2 m9 ]+ L
end 3 c+ G8 B! X- h" @) [
end
& Z* a5 ~' {) t3 c2 s- T: P figure,imshow(img); 3 p+ _: g p. ^7 q5 S- h# k* m/ N
fclose(s);
1 z/ S& B; O* J, ?
2 L, S. Y% J+ g h% w3 X% q
9 @# K' P% d, X2 c* o2、EdgeSobel的Verilog源代码:
7 _+ k% H" u9 z# ^5 _" |# Y$ U9 J, g
& R1 u6 T, X9 b5 `
0 _. x3 `! H( z$ l6 \% b8 J
4 [5 I q3 p( e8 ^* R2 J# q源码:
8 o" ~$ S- z8 Q" L# @`timescale 1ns/1ps
3 Y7 W9 U- K# @! O) n/ z/ X
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;
) k3 p( j, n4 k: Z
parameter shiftRegSize=pixel_depth*((block_height-1)*frame_width+block_width); ; q2 ?: e( o/ [4 g0 u
reg[shiftRegSize-1:0] shiftReg; wire [block_width*block_height*pixel_depth-1:0] Window;
?3 c7 T& ~' v3 m
initial begin shiftReg=10264'b0;end always@(posedge clk)if((x<640)&&(y<480))shiftReg<={shiftReg,inData}; % N# Y) p. K% L, f7 w- v' G
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
2 ^( n; z9 ?; ^4 }- |+ V; P" ~
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 ;
! ?; P# x Y2 Y- |3 x
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; ' ]& ~1 Z) C p# z! @) Q7 K9 ~) ^6 K7 f
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;
6 Z- H1 J8 b/ R8 w
//assign outData = average; //平滑 assign outData = G[9:2]; //边缘检测 endmodule
- @0 l" s E- z" p3、仿真文件:EdgeSobel_tb.v2 k2 H; `. p* z8 U0 k5 H( Y- |
8 O8 s! R7 _ G
( I* ^4 Z' x7 i# E* B8 |
$ d; E: Y4 l7 _9 ~
4 R) @/ X( a2 U' F/ O1 W) J源码:
3 t* q, G1 ` h& ]7 G$ ~`timescale 1ns / 1ps
& [; q7 r: O8 o' E5 H( n
module edgesobel_tb;
! J& _* ^" e3 h& O# @
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;
. x" a1 f5 w) G, V: Z# s
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 + s. m5 ?4 A& r- t( M1 `4 Q- T
EdgeSobel u_2 ( .clk(clk), .x(1), .y(1), .inData(inData), .outData(outData) ); + w0 X% n% {- V8 y# J
always #1 clk = ~clk; , F# q0 v. _# k- b: J
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 , I S& i! G" z! M/ v$ a( O
4、把输出的txt文件转化成图片Matlab程序:/ Q) ^. ^0 E' ` G
A=importdata('E:\matlab\Vivado\mem2image.txt');( ^; t" b- ^% P6 A8 \) a* g
A=A./255;
; m' {, x+ c+ i3 G$ O+ Y; X imshow(A); $ Q8 o B. x" @, G `, Y
注意这里的A是double类型的,直接进行imshow会全白,要转化到0-1:A=A./255,或者把double类型转化为整形。
h6 \, Q: E& B+ B4 M, H 后续会持续更新,带来Vivado、 ISE、Quartus II 、candence等安装相关设计教程,学习资源、项目资源、好文推荐等,希望大侠持续关注。# i8 {$ ]) w- x* M5 I
大侠们,江湖偌大,继续闯荡,愿一切安好,有缘再见!
1 A/ K3 ^" V E* B4 ]- N |