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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
转——简谈FPGA图像处理之边缘检测,中值滤波
: M6 D! S( d- K4 ?

  M: x" v, q  Z, d# u
7 T' M" N4 ], h0 r  c       本来相对较简单,而且网络上能找到的,我都不是很想写,必定我也忙,而且那些基础的东西还比较多,我也不可能全写出来,这样耗用的时间太多。但是关于图像处理这一块,有人跟我说,把简单的这些也写一写吧,网络资源比较少。我接受朋友的建议,简单的写了一些。3 N1 }' E' f5 @1 p

; ]) d0 D, h. v7 ?( x5 a5 @        边缘检测:原理和算法结构,数字图像处理的书上都有写,冈萨雷斯的书,这本书,描述的边缘检测的方法,原理写的都很明白。不多说。但是要注意几点:边缘检测对噪声敏感。所以需要先进行滤波处理。边缘检测是求微分或者说求导数的过程。
1 ^' Q1 y# V& v2 r' d
! u6 [) E$ k0 w0 X
游客,如果您要查看本帖隐藏内容请回复

: N0 ]$ L. g1 @. C+ ^matlab函数:image_edge = edge(f,'sobel',0.05);%边缘检测函数。看不懂就要自己去百度查了。
# s( g" N/ X8 }+ T8 j* E- W# E' u' M5 |( A
这个非封装的sobel算法。
4 `9 R4 U" V  w' V+ `# J6 K
5 O0 ], v2 a. ~0 e' P5 uclc
6 N2 h: a/ C2 V+ o2 e6 |: r clear
: }, p" t$ O5 J4 [- \/ R  w3 x( S& ]9 [$ cf=imread('Fig8.02(a).jpg'); 
) Q5 L( f; N, h" T  H4 U# Bif ndims(f) == 3  
) X' }$ G( d7 [$ U6 ^7 k. Nf=rgb2gray(f);  1 I5 A& }6 m* C. f& y8 O
end
/ Q- L0 f' C, M9 Jf1 = imresize(f, [256,300]);   5 q* V6 @4 {. w* ]
IMG_Gray = double(f1);    1 O  V' {2 x, a$ C1 Q
imshow(f1)
# H. {2 o$ k# I, y[h w]=size(f1);. M! c( e7 o4 j: l6 Z% J4 w; x3 k7 X
% IMG_Sobel = true(h,w);    %新建一个数据为1的二值矩阵  9 m; l1 |( o: g
THRESHOLD =240;
4 S* b" G$ Z0 A; F! iSobel_X = [-1, 0, 1, -2, 0, 2, -1, 0, 1];   
* P; C# @' V% B& D- h: OSobel_Y = [1, 2, 1, 0, 0, 0, -1, -2, -1];   % sobel_y = sobel_x';取逆也可以完成
# S3 @# B7 u8 f* M  m, bfor i = 2 : h-1     %舍弃了边缘信息2 w( e7 H' H8 h4 J
    for j = 2 : w-11 R* r, \" H3 m' [( v; x+ r# Y
        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 c6 P% d2 r# u# P+ f                Sobel_X(4) * IMG_Gray(i,j-1)    + Sobel_X(5) * IMG_Gray(i,j)    + Sobel_X(6) * IMG_Gray(i,j+1) +...
/ N( n1 ~2 y# U                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);1 f: h# J/ \2 ]% ]' p
        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) +...5 Z& y) V8 u. p% v- E* R# P
                Sobel_Y(4) * IMG_Gray(i,j-1)    + Sobel_Y(5) * IMG_Gray(i,j)    + Sobel_Y(6) * IMG_Gray(i,j+1) +...
" ^. r0 j/ c% p  Q4 Z                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);
% A" V9 Z! Q" {9 s1 _- n* |       % temp3 = sqrt(temp1^2 + temp2^2);+ Z  n5 `6 ?2 t/ u1 y
        temp3 = abs(temp1) + abs(temp2);   %just for speed
' F+ b3 E' m& a2 G$ [3 J        if(temp3 > THRESHOLD)
: G7 K& C$ a" D1 w0 i            IMG_Sobel(i,j) = 0; %Black; Z* S  ?6 B0 W
         else
" B4 A2 }1 {; v) J; d9 v' o             IMG_Sobel(i,j) = 255; %White/ r# ?4 W% X, W- B
         end
+ U) Y+ Y0 @8 o3 d) {* @      %  IMG_Sobel(i,j)=temp3/8;) N( A5 y$ V9 r4 N3 F3 l
    end" q/ g$ ~) P# ^; B* N( e, e  B2 o
end
. V' t& j: _' p, j( B6 Jfigure ,imshow(IMG_Sobel)3 z9 P) x5 \2 d4 U0 n0 F$ `* D
* Y7 Y2 z. T$ ~2 a2 A) Q/ ~
这个也是可以百度的到的
& S$ s9 S3 z8 W
; t; Z6 b. m% P" Z1 i, E下面是FPGA完成。5 `; V! d8 ]; y! z
   
, H' }  c  M7 w! t3 s // synopsys translate_off
1 X4 Y, P4 v+ ~. _, }" _  j% h`timescale 1ns/1ns* W: r1 }5 S. G3 k4 L8 r/ `- S
// synopsys translate_on9 \& f6 c' M* G, }* L! N7 K

$ `- u. R/ r0 U3 n. B+ i. W" Y: A7 ?: L
module compute(
' ~5 p5 `# d# [. a               CLK,
& X% ^9 v  j: e) l& ~6 U2 t- C- e  RSTn,. z# }8 Q' S! U
               DATA_in,//数据总线
/ {! b, h* X: ?               SHIFT_en,//移位寄存器使能信号- c' w5 S* [1 m9 y
              &nbsprev_row_load,//加载前一行数据到寄存器
, J0 G4 X7 q: ^1 C- T1 _               Curr_row_load,//加载当前行数据到寄存器
/ {0 t+ ?$ @+ w  f( o( b               Next_row_load,//加载下一行数据到寄存器6 \* z4 l$ Q2 X. M. N. [9 I
               RESULT_row   //运算结果输出- Q' F8 _9 O, b
               );5 z% h' ^: q7 l! D7 r) |. w

0 Z6 t4 s3 D; B  |% `" J
5 p$ Y  Z0 U& V& g3 ginput CLK;
- b- m; T  \5 L5 i! ^% o- Cinput RSTn;: a/ y. Z: _: K* Q% G1 y
input[7:0]   DATA_in;
& _+ \, k& H4 Z8 i* ninput  SHIFT_en;
; H# L7 Z; d, W) W6 ^input &nbsprev_row_load;: `( _$ }1 s  `) {
input  Curr_row_load;
0 @2 {- @. \9 M' _' finput  Next_row_load;
' G: C* U+ [) T6 Z- Uoutput[7:0]  RESULT_row ;   7 X! \7 |; A6 B' C& L6 j( {7 v
             
* {3 I: ?( q4 G4 s //---------------------   计算数据通路信号   -----------------------//* W+ i" l$ ?$ b
 
' n1 h: W! F. N( R% I3 X0 S//wire signed  [10:0] D;
. v* h  n5 z9 M& Y% m' @6 \reg [7:0] abs_D;
' C/ q( Z' D1 Z1 P; C2 h- xreg [7:0] RESULT_row;
8 J' g/ }2 A/ P9 W) _" g//---------------------Assignment-----------------------//
7 {9 c5 c% w! H& k+ |8 j
, A7 |6 p$ A' W/ h: \- X* k3 C) @$ \5 {* ^
//-----------------         module        ------------//
9 N! u# F( j) _. k% Z- _% u* y. r4 z  t  P  [( F) O. p! \( n% D

! D6 u# `1 C! s; F //----------------   always  ------------//
1 F( r- }0 @6 J3 q+ T: h//the four cycle have one result.# M4 I" @& H2 s; g# T4 P) Z! f
reg [7:0] Prev_row, Curr_row, Next_row;8 v3 @8 Y- z, n6 S" q
 - i8 S, a. D) m6 m1 y$ w5 o) i
always@(posedge CLK or negedge RSTn)  //上一行寄存器- _: F. C. j  `) {
    begin6 q/ A5 ^! j; D. D/ o4 F6 M, g
if (!RSTn)3 X7 c2 I0 V% E8 O$ R) F
Prev_row <= 8'd0;3 a& ~% j2 ]- H; h4 J' k
else
$ T/ B) _: I1 l$ Q2 e3 ]" ^7 ?. gif(Prev_row_load)&nbsp;
8 l  K6 Z, R7 a9 k1 CPrev_row<= DATA_in;
3 \2 _. L- x1 C8 ^/ \! F' q& N&nbsp; &nbsp; end/ X! E8 c% }0 Q3 {4 l0 q* q

% L# j' ?' g& }) lalways@(posedge CLK or negedge RSTn) &nbsp;//当前行寄存器' {5 H# L4 W/ i8 H/ q! \2 a! g; F
&nbsp; &nbsp; begin
% }2 k" c) X8 m: ^, E  ~if (!RSTn)
) e$ ]3 A9 M4 @! J6 aCurr_row <= 8'd0;
* J5 s" r$ ^. c8 ]0 I8 l2 v3 E" {else
7 W& C" ~( C* T8 O' Hif(Curr_row_load)&nbsp;
1 ^2 e; j3 \. D! k0 F+ @4 k" KCurr_row<= DATA_in;' Z, u* b* f+ E1 W
end
. Z5 C+ `3 h- }2 B/ f1 v1 x0 K. j1 _% v3 H$ Y
always@(posedge CLK or negedge RSTn) &nbsp;//下一行寄存器) G4 e1 U9 P! ^' s7 R& z% L5 V$ L" ~
begin. n- O$ h& X# o, C4 W! @
if (!RSTn)7 d( R0 {( J' q: ?5 @  D% D! l. {
&nbsp; &nbsp;Next_row <= 8'd0;9 P9 R" m; G' ~9 _& p9 k
else
1 ~8 \& y2 W  j- Z1 iif(Next_row_load)&nbsp;
  {: b) v( {& q) s, CNext_row<=DATA_in;" ~0 Q8 s6 u+ Z0 R
end2 ^6 r0 D! w4 S9 |
5 z0 ^# Z* Z6 {+ Z3 s
//---------------- &nbsp; 计算绝对值函数 &nbsp;-----------------//
7 w7 L7 I  p! Z0 Y
; F  m+ L$ [" T  m9 _9 f7 V1 bfunction [10:0] abs ( input signed [10:0] x);
3 `' \( x$ E: \1 M7 |abs = x >=0 ? x : -x ;, ]7 `5 ]# o& l4 o( H3 r8 s
endfunction" ?7 a) x4 `2 o2 U6 y- A/ p
  q% R0 o% B% a  l& h; i: {

0 G( D, Q( z% I# N; y& s//---------------- &nbsp; 计算流水线 &nbsp;-----------------//( A' W. j+ r9 W/ q% b
&nbsp;reg [7:0] O[-1:1][-1:1]; &nbsp; &nbsp; // reg signed [7:0] &nbsp;O[-1:1][-1:1];
+ A- D0 `; o. O, p4 O: Z2 c&nbsp;reg signed [10:0]Dx, Dy;
- E& F9 J, Y7 X" L; x% _$ T//assign D = abs(Dx) + abs(Dy);&nbsp;3 g0 J+ _$ s! z/ Z4 y, L3 T
always @(posedge CLK or negedge RSTn)&nbsp;7 b' M) \! s" Q5 B
begin
( F9 q4 S# p$ V  {% ~if (!RSTn): k/ b4 I+ d! M3 @5 R4 a
begin1 c3 W4 h% U4 @- l$ N
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;8 U2 s6 J: C4 O& |4 [
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;- R4 J. ]4 N; ]* g/ @' F3 C9 J5 ?& t
end
* C4 s( M6 q- T$ R. Gelse" d2 T3 e+ [2 P9 a
if ( SHIFT_en )1 V3 L" a' c, S5 V& l0 L1 o
begin, q8 e% h, |. R. |$ ~
//D = abs(Dx) + abs(Dy);6 `+ d9 N( Z+ u' o6 ]: C" M! H  V
abs_D <= (abs(Dx) + abs(Dy))>>3 ; &nbsp; // add 3bit is the bast. &nbsp; &nbsp; &nbsp; abs_D <=(abs(Dx) + abs(Dy)) 1....( Y7 Y5 P% |1 P0 G/ Y
Dx <= -$signed({3'b000, O[-1][-1]})//-1* O[-1][-1]
4 F2 D1 k% A! ~( ~, G8 M. X/ g7 p+$signed({3'b000, O[-1][+1]})//+1* O[-1][+1]
8 L6 z: H8 p! q" O5 [( k-($signed({3'b000, O[ 0][-1]})<<1)//-2* O[ 0][-1]
8 Z2 a# A1 l9 z/ f+($signed({3'b000, O[ 0][+1]})<<1)//+2* O[ 0][+1]- |0 E8 n' v: B% p% Z' C' f
-$signed({3'b000, O[+1][-1]})//-1* O[+1][-1]
. O: i  W- u3 M9 F+$signed({3'b000, O[+1][+1]});//+1* O[+1][+1]
) `! M6 N% a! ^1 ]8 SDy <= $signed({3'b000, O[-1][-1]})//+1* O[-1][-1]7 |/ K5 ^4 l3 Z. n! x7 ^
+($signed({3'b000, O[-1][ 0]}) &nbsp;<<1)//+2* O[-1][0]&nbsp; &nbsp;
& S$ a9 E. i! e9 H+$signed({3'b000, O[-1][+1]})//+1* O[-1][+1]* Z# P( Y2 b6 B# u3 Z! q  |; k
-$signed({3'b000, O[+1][-1]})//-1* O[+1][-1]& w) v1 |3 B; @) x4 s! I5 D
-($signed({3'b000, O[+1][ 0]}) <<1)//-2* O[+1][ 0]
  M9 R6 O/ e. A( s1 B0 i3 Y. X, f-$signed({3'b000, O[+1][+1]});//-1* O[+1][+1]
1 E) y1 y, V( u' g# x# hO[-1][-1] <= O[-1][0]; &nbsp; &nbsp; &nbsp;O[-1][ 0]<=O[-1][+1];O[-1][+1]<=Prev_row;8 F8 c, n. C% G# f6 q
O[ 0][-1] <= O[0][0]; O[ 0][ 0] <= O[0][+1]; O[ 0][+1]<=Curr_row;
- n1 y( G9 \# s1 f% @" a# w/ ?O[+1][-1] <= O[+1][0]; O[+1][ 0] <= O[+1][+1]; O[+1][+1]<=Next_row;6 g7 b  G7 q9 m
end6 n0 w+ F) u) ?
end
, V7 ~+ B3 X9 g0 @. L1 k3 _7 ?//---------------- &nbsp; 结果行寄存器 -----------------//
4 \/ V: q  o/ Ealways @(posedge CLK or negedge RSTn)) W. ?& p# p( h6 F$ M
begin
+ B+ ]# G: X0 C+ ]if (!RSTn)4 ^# \+ t$ d* G, z" e* v
&nbsp;RESULT_row <=8'd0;
+ x; q& [! N/ J( a2 ?7 J6 ]0 Welse
8 L6 }0 k! G% G" Z0 eif(SHIFT_en)
; {8 j2 F7 }& \$ x+ U& @  vbegin) y8 x7 E) j; W) i
&nbsp; if (abs_D>8'd40) &nbsp; //阈值分割,也就是matlab里面的THRESHOLD' h/ j) b/ r/ Y7 n
RESULT_row <= 8'd0; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // &nbsp;RESULT_row <= abs_D[11:2] ; 1....9 c" o) V+ D7 V" N0 D9 j
&nbsp; else
2 r! p8 P2 T, v& I* d&nbsp; &nbsp; &nbsp; &nbsp;RESULT_row<= 8'd255;&nbsp;/ i' s- y, l3 `; W9 ~7 t9 y
end
6 i/ U  C* X, oend% Y, K+ C- U3 D& |4 e

4 s! h0 m% _* H5 l# O6 bendmodule
4 a4 B7 j& y  ^" e5 k0 v; C0 M) L, U1 _: L) `$ l
FPGA程序和MATLAB程序的对于关系应该很明显了。
8 l- `6 B% R* [) S( \5 Q
7 x7 B- m6 n0 ]9 x% j7 R8 l

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-7-29 05:42 , Processed in 0.156250 second(s), 26 queries , Gzip On.

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

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

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