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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

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

+ \1 }0 l# H3 M# T' p5 z
9 T% z5 d0 K- W; x% o" f' N- {, ?+ e% `2 r# t( l6 y
       本来相对较简单,而且网络上能找到的,我都不是很想写,必定我也忙,而且那些基础的东西还比较多,我也不可能全写出来,这样耗用的时间太多。但是关于图像处理这一块,有人跟我说,把简单的这些也写一写吧,网络资源比较少。我接受朋友的建议,简单的写了一些。) q! s6 s* g( c4 o9 K6 i: G
) i6 h; \3 a8 H
        边缘检测:原理和算法结构,数字图像处理的书上都有写,冈萨雷斯的书,这本书,描述的边缘检测的方法,原理写的都很明白。不多说。但是要注意几点:边缘检测对噪声敏感。所以需要先进行滤波处理。边缘检测是求微分或者说求导数的过程。% G$ a# F: a9 {" T6 A

- q$ R) d- `* L
游客,如果您要查看本帖隐藏内容请回复
4 G5 z, f- K; L
matlab函数:image_edge = edge(f,'sobel',0.05);%边缘检测函数。看不懂就要自己去百度查了。
# c) M+ C* O4 e0 b- h1 c0 W6 y+ T8 q8 L
这个非封装的sobel算法。
) h% x% A0 v" {0 ~/ |2 V' @3 b8 i; A; i2 S) C
clc! T4 V+ |6 H4 o9 M0 u: P/ L+ I" i. Y
 clear
3 [: M2 a6 @/ ~3 _+ l; N2 Kf=imread('Fig8.02(a).jpg'); 
, [* M" O8 _& L! @' U+ p5 |if ndims(f) == 3  
$ G# \( Q0 N% C: |f=rgb2gray(f);    x5 d5 R. l. }1 r! Y/ I" c, ~+ N
end
7 [6 f! C$ M) }# Sf1 = imresize(f, [256,300]);   . }; D2 E# h& U% ~4 `
IMG_Gray = double(f1);    
3 K2 |( u  z, S2 o  \imshow(f1)
6 Q, S& ?0 l: L7 @1 u; E- V[h w]=size(f1);
7 P. V3 B2 L! b; V  i% IMG_Sobel = true(h,w);    %新建一个数据为1的二值矩阵  
1 m7 G$ e& E7 ]# d4 m, f. @# B" gTHRESHOLD =240;. x0 Q+ d+ n( r2 n+ Q; V
Sobel_X = [-1, 0, 1, -2, 0, 2, -1, 0, 1];   
; `1 d! t  N. P0 b' E2 T- W  r* LSobel_Y = [1, 2, 1, 0, 0, 0, -1, -2, -1];   % sobel_y = sobel_x';取逆也可以完成* ]) `* N3 C: p0 h  T  Z2 E4 W
for i = 2 : h-1     %舍弃了边缘信息# ]6 ?1 k* n' e5 T  T# c
    for j = 2 : w-1* S& R! x* T) T& d8 R! G
        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) +...
2 [8 h: C. R1 Q                Sobel_X(4) * IMG_Gray(i,j-1)    + Sobel_X(5) * IMG_Gray(i,j)    + Sobel_X(6) * IMG_Gray(i,j+1) +...
$ j7 K* J! G3 M* F5 O                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);
( g  L" B- W* P1 Z) h4 |; u8 Z% J        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) +...% M' ]. j4 W( A& q' V- f, [- I0 c
                Sobel_Y(4) * IMG_Gray(i,j-1)    + Sobel_Y(5) * IMG_Gray(i,j)    + Sobel_Y(6) * IMG_Gray(i,j+1) +...9 ~8 j7 L  m7 L7 p
                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);
, A9 x1 }- y( Q$ W3 a       % temp3 = sqrt(temp1^2 + temp2^2);
" Y/ |: C; o4 d        temp3 = abs(temp1) + abs(temp2);   %just for speed
/ r, F  ]: u7 _        if(temp3 > THRESHOLD)
! J7 \; Y" m1 M2 I7 ?+ b) V8 @            IMG_Sobel(i,j) = 0; %Black
, s* i( q" Y* T8 z$ r) h) B. f0 k         else* r/ l" R0 ?* G, o  |$ h
             IMG_Sobel(i,j) = 255; %White
3 c. K3 O- U; ^. q         end7 ?) V$ u: ~, Y6 O2 a
      %  IMG_Sobel(i,j)=temp3/8;9 b1 f# x) {3 o6 U+ i1 u
    end# u. \0 a1 M9 g  ^( k) D& @9 {  F
end
$ t8 X& i8 K8 w3 o  p* kfigure ,imshow(IMG_Sobel)' {1 C9 j% u8 B
& p) X0 b1 j8 W
这个也是可以百度的到的
' h1 g' B3 X% V" W7 d) d; ~! J, T
下面是FPGA完成。
1 b) g5 u  Z7 g  a   
7 ?0 i- A0 V9 M' X // synopsys translate_off
8 p7 n  E$ x0 ]/ z+ j, d`timescale 1ns/1ns
& Y: U5 a) L. j// synopsys translate_on3 a. h9 `4 L& A6 X9 R7 \
# p$ ~8 H% [( D  k
( v; o. d# h! s5 q& w
module compute(
6 B& M  ]/ \# _' }: |               CLK,; U& Z2 B5 N6 V7 v9 ~: t
  RSTn,/ {8 @- M. @& B, A& X
               DATA_in,//数据总线
- }9 C. x' L0 G               SHIFT_en,//移位寄存器使能信号
. u( @/ @( ]  c0 ]' k" N              &nbsprev_row_load,//加载前一行数据到寄存器
. @, z9 ^1 y. S: d3 G3 Z% l% P  }               Curr_row_load,//加载当前行数据到寄存器; y( f3 X$ S! r
               Next_row_load,//加载下一行数据到寄存器
% W6 g( o. H. G* n1 W& q               RESULT_row   //运算结果输出
. f& e1 b, E5 ~# z! s( }8 g$ ^& s               );" V' k4 F4 ~6 r

8 z. A( h1 h( E. R
* g( q7 p$ i6 j) oinput CLK;
+ y8 R7 S& a: c6 l* a" Binput RSTn;2 g2 ?0 m; P5 [
input[7:0]   DATA_in;
" ^' `! j2 b: }/ ]input  SHIFT_en;# ^, _' s) F/ J5 v# b; A3 k, N
input &nbsprev_row_load;' w* T7 Z" e4 p) c  ~
input  Curr_row_load;. }  _. Q- {  H8 h' Q& A( q, y
input  Next_row_load;
, m* E8 ^* R. f8 Q% `output[7:0]  RESULT_row ;   
/ Z" }0 j& t$ r, K7 C* A8 b             
( Z7 F1 a" A7 s4 _% r5 I //---------------------   计算数据通路信号   -----------------------//4 Y/ b: h( U* C6 [
 
) y! x) x6 k* \) w4 h- g0 U//wire signed  [10:0] D;$ q4 c7 U' Z1 I: O+ ~$ R- X
reg [7:0] abs_D;
' [) [& @, X/ G1 T" ?/ greg [7:0] RESULT_row;
; o) l/ p) v0 H//---------------------Assignment-----------------------//* V6 s2 q* A# D

! s3 ]% H8 Z5 _# q9 @1 Y' Q1 a3 Z  o, y5 H* o* G0 b# }
//-----------------         module        ------------//
; k; X3 j" f# p4 O' m( Z9 e4 V+ i* }5 r& {' K, _
2 V$ w% I9 m' L" U" b
 //----------------   always  ------------//; x9 m' T1 H& G! D) }* [9 u
//the four cycle have one result.
; d1 j# e+ c$ n& Dreg [7:0] Prev_row, Curr_row, Next_row;
5 z! P8 I7 G$ w4 f8 _. X. K$ u& F 
/ z  N0 a3 p/ M- p/ V& H% Calways@(posedge CLK or negedge RSTn)  //上一行寄存器$ Y* K2 j/ p5 e; R- S
    begin. b) X& J5 P1 ?2 r" ]
if (!RSTn)
* [  r1 i* b2 a& cPrev_row <= 8'd0;
' Z( k6 F. F) w2 m" lelse
. k. u: R$ ?! z5 ?% pif(Prev_row_load)&nbsp;. v: b1 y) u8 A, W& U0 m
Prev_row<= DATA_in;
2 y5 \3 J6 ~# f  T% j6 U% A&nbsp; &nbsp; end
8 n2 L, _: w. Q/ \! c
5 L! P: P7 M2 Q' M8 ^# u7 e" O: w" zalways@(posedge CLK or negedge RSTn) &nbsp;//当前行寄存器$ Z( J  I' D' x: F0 v  i, \
&nbsp; &nbsp; begin
! t+ \% p) v7 m) r* Y2 k" rif (!RSTn)/ Y2 j) `5 I) a: j
Curr_row <= 8'd0;
1 G* M/ K/ ^- k4 l( m) selse
3 }" U1 Z3 h+ V/ y; Wif(Curr_row_load)&nbsp;& C  Y; u5 E  J9 s' R& t+ F! u
Curr_row<= DATA_in;, _/ _& B* l9 j2 W% X( ~8 c
end
( ?5 s9 u) f" r$ O! i; B/ W- r9 U+ d, D3 k0 A) }
always@(posedge CLK or negedge RSTn) &nbsp;//下一行寄存器6 O8 a6 {5 [% |1 ^. Y9 z
begin
( L, X0 S( a. R1 zif (!RSTn)
( p# y: p' ]! K+ t&nbsp; &nbsp;Next_row <= 8'd0;
. x. o. b+ O0 H! c$ ^% U/ velse  m* y! j4 ?. G  s3 a
if(Next_row_load)&nbsp;
- k7 F" _$ f% o( i2 w* ?Next_row<=DATA_in;9 ~) {# o/ }. y, ]& B; A6 z
end
! f/ b5 h2 U8 p8 e: \' k3 j' K3 t) R( H+ @
//---------------- &nbsp; 计算绝对值函数 &nbsp;-----------------//
' {& s* \4 ]+ B
% M6 e, Z" `) q/ \function [10:0] abs ( input signed [10:0] x);
8 H( J0 ^" e- H3 K# X% gabs = x >=0 ? x : -x ;
0 _9 V; f% Q1 x1 Fendfunction
4 L" u4 y6 R  I! O# l
6 v/ f, M4 B1 [# u
9 Y+ h2 a; K" o, V" Y//---------------- &nbsp; 计算流水线 &nbsp;-----------------//
3 P+ M0 [6 Z5 O: d+ K&nbsp;reg [7:0] O[-1:1][-1:1]; &nbsp; &nbsp; // reg signed [7:0] &nbsp;O[-1:1][-1:1];
2 w) U8 ]3 W3 X& u9 y- J&nbsp;reg signed [10:0]Dx, Dy;2 h9 w% @8 H' Q# I$ q9 O% [
//assign D = abs(Dx) + abs(Dy);&nbsp;
! k* @& U, n: C* j6 t. b: _always @(posedge CLK or negedge RSTn)&nbsp;) _! v6 ]5 P& b% [
begin
4 F8 D) I& z! G2 {if (!RSTn)
2 X" d( T  d! [$ I' X* |0 H& jbegin
8 f2 [1 f$ u7 h) w2 T) Kabs_D<=8'd0; Dx<=8'd0; Dy<=8'd0;O[-1][-1]<=8'd0;O[-1][ 0]<=8'd0;O[-1][+1]<=8'd0;
; F$ Z/ {' B9 |* m; PO[ 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;
. v. j# @9 w& B5 _2 I+ @end$ D* ^% g+ y, h3 W# f. N! w) x
else
; O1 Q, J! Z( Aif ( SHIFT_en )' q, S/ `6 B* o1 d
begin/ V, y& ]* H: `; ]/ @
//D = abs(Dx) + abs(Dy);$ ?4 l! y, G# L$ L8 o& z5 N' [
abs_D <= (abs(Dx) + abs(Dy))>>3 ; &nbsp; // add 3bit is the bast. &nbsp; &nbsp; &nbsp; abs_D <=(abs(Dx) + abs(Dy)) 1....
" e! R% M$ h! w6 v6 U/ a3 fDx <= -$signed({3'b000, O[-1][-1]})//-1* O[-1][-1]
9 k1 E$ n; j9 w$ P7 B2 n4 O+$signed({3'b000, O[-1][+1]})//+1* O[-1][+1]& y" f) o" e6 q( t+ j. Q3 w
-($signed({3'b000, O[ 0][-1]})<<1)//-2* O[ 0][-1]
! B: m8 c1 }5 k( f6 ]' Z# `0 \+($signed({3'b000, O[ 0][+1]})<<1)//+2* O[ 0][+1]
0 v2 b. ], [7 ~# P0 W* p. R/ }& L-$signed({3'b000, O[+1][-1]})//-1* O[+1][-1]' f2 Z, D/ K/ Y; a% N, V
+$signed({3'b000, O[+1][+1]});//+1* O[+1][+1]
. {, x0 d8 C$ o# S. yDy <= $signed({3'b000, O[-1][-1]})//+1* O[-1][-1]+ {1 w- i+ a4 l5 |; M/ n
+($signed({3'b000, O[-1][ 0]}) &nbsp;<<1)//+2* O[-1][0]&nbsp; &nbsp;* A( s& a% i& R
+$signed({3'b000, O[-1][+1]})//+1* O[-1][+1], W5 _$ ~7 S! j- K- ^- b; E
-$signed({3'b000, O[+1][-1]})//-1* O[+1][-1]8 r& S; k8 L2 Y+ B( B! z/ U! ?
-($signed({3'b000, O[+1][ 0]}) <<1)//-2* O[+1][ 0]. B+ p0 A+ ?  E# i+ ~) ]
-$signed({3'b000, O[+1][+1]});//-1* O[+1][+1]
7 A7 h  d2 ^" d5 i/ H5 ?O[-1][-1] <= O[-1][0]; &nbsp; &nbsp; &nbsp;O[-1][ 0]<=O[-1][+1];O[-1][+1]<=Prev_row;0 l6 {5 G; |7 ?+ i6 Y# e
O[ 0][-1] <= O[0][0]; O[ 0][ 0] <= O[0][+1]; O[ 0][+1]<=Curr_row;
: g/ b# y* V4 d8 f* e9 eO[+1][-1] <= O[+1][0]; O[+1][ 0] <= O[+1][+1]; O[+1][+1]<=Next_row;( u2 ^1 \0 K8 l) r
end
/ c' K* Q3 U7 W, p2 _9 h7 Iend& k7 G4 T/ N6 k5 U1 P
//---------------- &nbsp; 结果行寄存器 -----------------//7 q. {$ ~( Q1 z8 Z& A4 j% \
always @(posedge CLK or negedge RSTn)
9 ~' R  [' a4 B% ybegin9 e& \. X, h/ o, A7 B0 r
if (!RSTn)
' }. K5 j: P; s2 R; z/ j' D&nbsp;RESULT_row <=8'd0;
" r: G2 e, z9 r2 |. Xelse3 U1 n% m" a( N8 z6 F* q
if(SHIFT_en) + ?* J! @, B5 K4 T+ _
begin
, F; R/ ~8 E, ]. t/ u&nbsp; if (abs_D>8'd40) &nbsp; //阈值分割,也就是matlab里面的THRESHOLD4 v& q9 U" Z" T9 M) w/ h2 d
RESULT_row <= 8'd0; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // &nbsp;RESULT_row <= abs_D[11:2] ; 1....) B( B( D) a1 {, ^( R
&nbsp; else
5 ]& q7 x7 E1 s4 A; `) ~/ ~&nbsp; &nbsp; &nbsp; &nbsp;RESULT_row<= 8'd255;&nbsp;) O& C* t" ^& i4 S, P$ M
end& B+ j$ q; @$ \, q9 `+ O+ E
end% Q" q, N& ]$ r: ^" l

- b' ^5 E+ s6 C" P7 U1 Q0 t, y! Qendmodule
4 I3 m& v- }# V! w4 ?+ Q' ?# d6 b( a, E
FPGA程序和MATLAB程序的对于关系应该很明显了。
9 f' ^' R+ W; C5 b2 M, B8 l8 S$ y# u8 G

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-10-8 20:35 , Processed in 0.140625 second(s), 26 queries , Gzip On.

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

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

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