找回密码
 注册
关于网站域名变更的通知
查看: 354|回复: 1
打印 上一主题 下一主题

转——简谈FPGA图像处理之边缘检测,中值滤波

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2019-3-18 07:30 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

EDA365欢迎您登录!

您需要 登录 才可以下载或查看,没有帐号?注册

x
转——简谈FPGA图像处理之边缘检测,中值滤波
/ f* h* d# T4 n( y6 O5 y6 ?

' \3 m4 P/ t) o; q' `+ C" ^
% a& t1 ^8 ~# g       本来相对较简单,而且网络上能找到的,我都不是很想写,必定我也忙,而且那些基础的东西还比较多,我也不可能全写出来,这样耗用的时间太多。但是关于图像处理这一块,有人跟我说,把简单的这些也写一写吧,网络资源比较少。我接受朋友的建议,简单的写了一些。: E4 T  b- p) f( \

' [- T5 V, o& ?( A        边缘检测:原理和算法结构,数字图像处理的书上都有写,冈萨雷斯的书,这本书,描述的边缘检测的方法,原理写的都很明白。不多说。但是要注意几点:边缘检测对噪声敏感。所以需要先进行滤波处理。边缘检测是求微分或者说求导数的过程。: s. O  a$ w& U7 Y2 e
- U; A  N7 W0 Z
游客,如果您要查看本帖隐藏内容请回复
5 p( N& s6 S$ M" D+ o$ t
matlab函数:image_edge = edge(f,'sobel',0.05);%边缘检测函数。看不懂就要自己去百度查了。
; T# v6 _" x1 T  Z; O9 R- V0 O! }  a7 g4 ^& @0 n
这个非封装的sobel算法。
0 K+ F" d+ u* B# d; q( ^! n$ G7 c, L- Z7 ]/ l: H2 |+ B$ k. U
clc$ E  a9 [4 Y2 f% q
 clear1 i$ }  {! e5 o# x
f=imread('Fig8.02(a).jpg'); 
: b7 @* g0 J9 W( v" B1 Tif ndims(f) == 3  
5 T0 `! }2 V& |" R& P' {f=rgb2gray(f);  
  f3 i. Z9 }9 }4 cend# \2 g( D" j1 @+ l  m) D: W
f1 = imresize(f, [256,300]);   3 I$ H4 N/ }7 |
IMG_Gray = double(f1);    
% r% C# |+ I+ O. Zimshow(f1)
4 `6 r$ q8 |$ N4 B[h w]=size(f1);3 ?  G! K' S4 i
% IMG_Sobel = true(h,w);    %新建一个数据为1的二值矩阵  % _7 z; M( i0 S% r8 d. {  e& V; ]& n
THRESHOLD =240;0 f/ r- u$ m6 J, P% L  v
Sobel_X = [-1, 0, 1, -2, 0, 2, -1, 0, 1];   % I; x1 x0 q3 s  Q3 n
Sobel_Y = [1, 2, 1, 0, 0, 0, -1, -2, -1];   % sobel_y = sobel_x';取逆也可以完成
( ?" _2 o& y  H# K: h, Qfor i = 2 : h-1     %舍弃了边缘信息. {" b" P: P. N$ O
    for j = 2 : w-1
0 }6 U8 C0 p" t2 a3 H        temp1 = Sobel_X(1) * IMG_Gray(i-1,j-1)  + Sobel_X(2) * IMG_Gray(i-1,j)  + Sobel_X(3) * IMG_Gray(i-1,j+1) +...3 x/ p7 b* I: }/ c2 p" A2 F
                Sobel_X(4) * IMG_Gray(i,j-1)    + Sobel_X(5) * IMG_Gray(i,j)    + Sobel_X(6) * IMG_Gray(i,j+1) +...) ]) j" c+ @8 y! T) f% L
                Sobel_X(7) * IMG_Gray(i+1,j-1)  + Sobel_X(8) * IMG_Gray(i+1,j)  + Sobel_X(9) * IMG_Gray(i+1,j+1);% ^" {- Q/ v. M
        temp2 = Sobel_Y(1) * IMG_Gray(i-1,j-1)  + Sobel_Y(2) * IMG_Gray(i-1,j)  + Sobel_Y(3) * IMG_Gray(i-1,j+1) +...' U1 @" }% ?, p) U. o' O
                Sobel_Y(4) * IMG_Gray(i,j-1)    + Sobel_Y(5) * IMG_Gray(i,j)    + Sobel_Y(6) * IMG_Gray(i,j+1) +...
6 i. Z! U! g3 b$ w9 {2 F5 D                Sobel_Y(7) * IMG_Gray(i+1,j-1)  + Sobel_Y(8) * IMG_Gray(i+1,j)  + Sobel_Y(9) * IMG_Gray(i+1,j+1);. k9 Q* ^5 m6 y5 r: T% X
       % temp3 = sqrt(temp1^2 + temp2^2);
  F" A9 j* J; q  J: p( Z' R        temp3 = abs(temp1) + abs(temp2);   %just for speed' }0 w3 u8 a0 y! U
        if(temp3 > THRESHOLD)4 g! E* d' W3 G
            IMG_Sobel(i,j) = 0; %Black- m0 G% \, C% d2 ^" ]
         else* b+ h# p4 Y1 B% e
             IMG_Sobel(i,j) = 255; %White
9 f9 W( E* L4 ]$ g  C  A7 X         end
1 A2 Z6 f  b7 @3 K6 T+ p      %  IMG_Sobel(i,j)=temp3/8;
" ~, k1 T4 z4 J% [7 N0 r4 |    end& x) _* J# g7 T5 q8 A! S. l$ {- e
end: T; C; `  t2 J3 G! i. c
figure ,imshow(IMG_Sobel)
. ~; y9 p. G7 B( t
3 l1 o0 N, M4 w- r) J7 W2 y/ o6 @这个也是可以百度的到的
: I$ P2 p( J+ D4 b3 n7 h2 \
- |( Z; M, X# Z8 Q' {下面是FPGA完成。' T3 c( \3 J. m( H- c
   
  j  p7 b" H/ ^8 S' O // synopsys translate_off
8 B3 ]$ R) g2 Q6 D$ x`timescale 1ns/1ns9 ^0 a3 Q  q" h5 s' N
// synopsys translate_on
) N+ t) j+ N- u8 s; j. O6 F% E# W: l2 b9 s( K3 ^, m
& H; s& [( ?! f  z4 U
module compute(% R$ T6 g  Y1 x2 |' g9 }1 Y/ Q
               CLK,: D$ ]1 s/ h+ R
  RSTn,0 u. E8 a9 J6 @5 }
               DATA_in,//数据总线) X2 N- `2 h8 i- a, D3 D
               SHIFT_en,//移位寄存器使能信号& \8 D: X5 w" r6 K
              &nbsprev_row_load,//加载前一行数据到寄存器! C4 S3 M/ |4 X) f
               Curr_row_load,//加载当前行数据到寄存器
: H9 w) P. \2 W5 F! C8 z               Next_row_load,//加载下一行数据到寄存器* |6 {: m4 t% M. f4 ^5 Y, c
               RESULT_row   //运算结果输出
8 f9 ]/ W* g! ^% p. k               );
$ }. Q2 `% d1 n. `) ^& {0 c
: A: n5 k8 J$ F4 ?+ h) g3 k+ j4 F4 ^' Z' k" P
input CLK;( Q) d6 ?6 g' w# G- J
input RSTn;
) Y9 R; z' S+ `3 Sinput[7:0]   DATA_in;
& ]$ G9 O6 V! W3 q3 einput  SHIFT_en;
2 J3 V  S/ M+ ~" C  V8 _input &nbsprev_row_load;
! \+ C! S* w+ |& cinput  Curr_row_load;3 J4 |( |7 G" \, a1 S$ L3 I
input  Next_row_load;- P, y7 a) E1 V* F
output[7:0]  RESULT_row ;   ( g9 O1 y* ^2 A
              $ b  Y3 e, s6 Y0 W, }, p2 c, v" n
 //---------------------   计算数据通路信号   -----------------------//
  M' ^0 y0 P+ {3 Q; a7 \ 8 q$ \5 i9 [4 K- i3 a- ]
//wire signed  [10:0] D;3 ], T( p+ O+ r! o7 Q" N
reg [7:0] abs_D;
4 t% T0 k# b% ~* }& @( Hreg [7:0] RESULT_row;! T  @# h4 ^1 F9 m0 Z$ \
//---------------------Assignment-----------------------//
/ C$ J8 L) X  i4 N( N+ b' L7 B: n5 W3 n: V4 Q1 [5 m& Q" \

, l+ C% p& Z  c. J/ C% k//-----------------         module        ------------//0 ]% N$ N9 N" V0 u1 A

. w2 Q, w: \/ m, {. m5 m5 U/ x0 ?$ C2 L  B8 H# j
 //----------------   always  ------------//' p2 ^6 W% |  p& X# B
//the four cycle have one result.
  E+ b* Z5 a6 T6 H5 h' qreg [7:0] Prev_row, Curr_row, Next_row;
$ g# c2 f* x2 ]. c 8 Y3 W, D. T' y
always@(posedge CLK or negedge RSTn)  //上一行寄存器: @( ]0 M( D( M1 v% ~( t
    begin- [0 Q# q( S1 G  ~
if (!RSTn)& x! {0 P3 H3 m7 e2 g  f
Prev_row <= 8'd0;
1 P- T& L6 K" i; belse* H4 ?' E" j% |
if(Prev_row_load)&nbsp;: [$ ?) s, N; Y5 m
Prev_row<= DATA_in;
0 _8 n0 V+ c9 z# i&nbsp; &nbsp; end
4 ]( R- M- ?9 ^/ t" ?4 f! f
0 ~" }7 K; E& ]9 ?4 Y" e- halways@(posedge CLK or negedge RSTn) &nbsp;//当前行寄存器
& z* j3 u+ T9 i% {; p&nbsp; &nbsp; begin2 b% ~9 A8 N" F; Z* r+ \
if (!RSTn)
: Z) l" |# y! vCurr_row <= 8'd0;
/ S; c( X) F+ w) _; I$ e; K, Melse4 Z- o. w" b" K5 h6 [! x" \
if(Curr_row_load)&nbsp;7 H" k' H! ^0 e$ A7 V$ U
Curr_row<= DATA_in;
' T% I- D4 F# bend. M! M" I; u5 u. s

* F3 s1 H% K: w/ Ealways@(posedge CLK or negedge RSTn) &nbsp;//下一行寄存器
' S" G2 B, W6 C# E+ M. a/ Dbegin
% y+ Q  _/ m( a' [0 F1 Sif (!RSTn)# E/ N# h1 `' P2 Q# K
&nbsp; &nbsp;Next_row <= 8'd0;, E% E' Q) O9 [, v; [+ K; f
else  r4 o: D, h/ Q* w  A2 @
if(Next_row_load)&nbsp;2 F" Q+ |  J( O" U+ o) E
Next_row<=DATA_in;% j0 e  ~2 O1 ?, b. W  e
end
: w- j' h- H# T3 X. e7 t  x1 S
//---------------- &nbsp; 计算绝对值函数 &nbsp;-----------------//
5 ]# w( M: E6 z+ U  s  l: ?$ F4 ]- R
function [10:0] abs ( input signed [10:0] x);
& O9 P( ^6 {; k" Gabs = x >=0 ? x : -x ;
# o! f7 Q7 z- Z1 Oendfunction* p+ ]! J1 z9 F0 V2 z. Q; f. o

- |: U7 P$ B, l- X9 y& l& p2 t+ t8 |0 i2 }, D
//---------------- &nbsp; 计算流水线 &nbsp;-----------------//
) I) e2 l/ ^, r: W3 K$ c&nbsp;reg [7:0] O[-1:1][-1:1]; &nbsp; &nbsp; // reg signed [7:0] &nbsp;O[-1:1][-1:1];
; T& D% Y( i+ Z+ h0 t; ?+ `+ Z&nbsp;reg signed [10:0]Dx, Dy;7 n" P2 k6 f- o6 m6 Z1 @
//assign D = abs(Dx) + abs(Dy);&nbsp;
8 H3 X2 V7 I. o0 Z. p/ xalways @(posedge CLK or negedge RSTn)&nbsp;5 x+ `) \/ |9 H+ A# G
begin
, X1 m0 E, d4 X" n- w) _# Y; ^: hif (!RSTn)
$ _1 q: R6 `; O+ gbegin; K% P* Y5 b2 p% C- ~6 G
abs_D<=8'd0; Dx<=8'd0; Dy<=8'd0;O[-1][-1]<=8'd0;O[-1][ 0]<=8'd0;O[-1][+1]<=8'd0;
( ^9 r* {0 l& N% ?O[ 0][-1]<=8'd0; &nbsp;O[ 0][ 0]<=8'd0; &nbsp;O[ 0][+1]<=8'd0; &nbsp;O[+1][-1]<=8'd0; &nbsp;O[+1][ 0]<=8'd0; &nbsp;O[+1][+1]<=8'd0;
" E* ~2 f5 c$ X, a" S" K. Send
* j7 k, I/ T3 ~) Q: oelse
0 T8 u+ Y9 p7 w5 ~0 V# L. R* iif ( SHIFT_en )& Z+ t2 P9 _' d4 _# b) L
begin
* S: s: j% {' O0 P( N# h7 d2 `1 B//D = abs(Dx) + abs(Dy);) W+ k% }" h7 }5 {
abs_D <= (abs(Dx) + abs(Dy))>>3 ; &nbsp; // add 3bit is the bast. &nbsp; &nbsp; &nbsp; abs_D <=(abs(Dx) + abs(Dy)) 1....+ R2 v3 U0 F; [
Dx <= -$signed({3'b000, O[-1][-1]})//-1* O[-1][-1]  e- Q* s+ @. U$ u
+$signed({3'b000, O[-1][+1]})//+1* O[-1][+1]8 B6 G) p& H6 |/ ]7 y
-($signed({3'b000, O[ 0][-1]})<<1)//-2* O[ 0][-1]
4 l9 b, ]0 }5 a" F/ p5 n& @0 e5 F+($signed({3'b000, O[ 0][+1]})<<1)//+2* O[ 0][+1]
+ U1 w3 }% q1 c( `-$signed({3'b000, O[+1][-1]})//-1* O[+1][-1]
; S& t, M, I. B) t" q; ^: z9 e+$signed({3'b000, O[+1][+1]});//+1* O[+1][+1]' g! m2 d6 M+ L$ O
Dy <= $signed({3'b000, O[-1][-1]})//+1* O[-1][-1]: g! E' j+ c6 N5 c' A
+($signed({3'b000, O[-1][ 0]}) &nbsp;<<1)//+2* O[-1][0]&nbsp; &nbsp;. j8 ~: X/ ~. M5 R+ h
+$signed({3'b000, O[-1][+1]})//+1* O[-1][+1]
& l; o# X: ^: R7 @-$signed({3'b000, O[+1][-1]})//-1* O[+1][-1]
. u5 B& [% e  S7 J$ M% R-($signed({3'b000, O[+1][ 0]}) <<1)//-2* O[+1][ 0]
2 f9 j6 Q' d/ d4 }-$signed({3'b000, O[+1][+1]});//-1* O[+1][+1]9 a% K  @) P2 B* O8 B' C
O[-1][-1] <= O[-1][0]; &nbsp; &nbsp; &nbsp;O[-1][ 0]<=O[-1][+1];O[-1][+1]<=Prev_row;
0 Q# `* f% D" Q. T. P( vO[ 0][-1] <= O[0][0]; O[ 0][ 0] <= O[0][+1]; O[ 0][+1]<=Curr_row;
* a, r  L$ t, E5 D$ q: G) Y7 D$ ?O[+1][-1] <= O[+1][0]; O[+1][ 0] <= O[+1][+1]; O[+1][+1]<=Next_row;
! j" }$ H6 p. {end
4 n- W2 [% r. b3 pend
# t4 R% ?! T. L! B//---------------- &nbsp; 结果行寄存器 -----------------//
4 ?+ c0 n( b  d: }& \1 I" z$ aalways @(posedge CLK or negedge RSTn)
/ P& J% k. n8 D# v. P; R" |4 tbegin
: i% I' f& y  s+ Y% U% r- Z, jif (!RSTn)
2 e  V0 V* A. v, `3 s0 M- a5 t&nbsp;RESULT_row <=8'd0;
2 |( }. `- r2 Pelse
: G  ?, V1 N9 e- X/ T# u7 C! Q- Aif(SHIFT_en)
* i! n. o: ^) _  g, G# o) f3 \9 Ubegin; t1 e9 R: G( p# \
&nbsp; if (abs_D>8'd40) &nbsp; //阈值分割,也就是matlab里面的THRESHOLD1 {  G0 k; E, W& [$ M
RESULT_row <= 8'd0; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // &nbsp;RESULT_row <= abs_D[11:2] ; 1...." t' E0 W8 t( z. ~' w# u
&nbsp; else! Z0 D- E% e% {- t
&nbsp; &nbsp; &nbsp; &nbsp;RESULT_row<= 8'd255;&nbsp;
( D8 O: w( W5 j; c" \2 iend% x# i! Y( u8 _8 y  H, y
end
7 l( Z0 ?( j' t. L. O% |# |9 u+ @2 |- u
endmodule
4 b0 x. p+ C$ m( `
1 c; x* C- E$ mFPGA程序和MATLAB程序的对于关系应该很明显了。3 }1 _8 R0 w* N7 {3 \& J0 ^

5 D5 ^8 u" w  v& \) P1 P9 j* r

该用户从未签到

2#
发表于 2019-3-18 18:50 | 只看该作者
看看隐藏内容
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

推荐内容上一条 /1 下一条

EDA365公众号

关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

GMT+8, 2025-7-28 14:12 , Processed in 0.140625 second(s), 26 queries , Gzip On.

深圳市墨知创新科技有限公司

地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

快速回复 返回顶部 返回列表