集成电路技术分享

 找回密码
 我要注册

QQ登录

只需一步,快速开始

搜索
查看: 2196|回复: 6

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

[复制链接]
晓灰灰 发表于 2018-10-23 13:05:26 | 显示全部楼层 |阅读模式
        本来相对较简单,而且网络上能找到的,我都不是很想写,必定我也忙,而且那些基础的东西还比较多,我也不可能全写出来,这样耗用的时间太多。但是关于图像处理这一块,有人跟我说,把简单的这些也写一写吧,网络资源比较少。我接受朋友的建议,简单的写了一些。

        边缘检测:原理和算法结构,数字图像处理的书上都有写,冈萨雷斯的书,附件有。这本书,描述的边缘检测的方法,原理写的都很明白。不多说。但是要注意几点:边缘检测对噪声敏感。所以需要先进行滤波处理。边缘检测是求微分或者说求导数的过程。

matlab函数:image_edge = edge(f,'sobel',0.05);%边缘检测函数。看不懂就要自己去百度查了。

这个非封装的sobel算法。

clc
 clear
f=imread('Fig8.02(a).jpg'); 
if ndims(f) == 3  
f=rgb2gray(f);  
end
f1 = imresize(f, [256,300]);   
IMG_Gray = double(f1);    
imshow(f1)
[h w]=size(f1);
% IMG_Sobel = true(h,w);    %新建一个数据为1的二值矩阵  
THRESHOLD =240;
Sobel_X = [-1, 0, 1, -2, 0, 2, -1, 0, 1];   
Sobel_Y = [1, 2, 1, 0, 0, 0, -1, -2, -1];   % sobel_y = sobel_x';取逆也可以完成
for i = 2 : h-1     %舍弃了边缘信息
    for j = 2 : w-1
        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) +...
                Sobel_X(4) * IMG_Gray(i,j-1)    + Sobel_X(5) * IMG_Gray(i,j)    + Sobel_X(6) * IMG_Gray(i,j+1) +...
                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);
        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) +...
                Sobel_Y(4) * IMG_Gray(i,j-1)    + Sobel_Y(5) * IMG_Gray(i,j)    + Sobel_Y(6) * IMG_Gray(i,j+1) +...
                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);
       % temp3 = sqrt(temp1^2 + temp2^2);
        temp3 = abs(temp1) + abs(temp2);   %just for speed
        if(temp3 > THRESHOLD)
            IMG_Sobel(i,j) = 0; %Black
         else
             IMG_Sobel(i,j) = 255; %White
         end
      %  IMG_Sobel(i,j)=temp3/8;
    end
end
figure ,imshow(IMG_Sobel)

这个也是可以百度的到的

下面是FPGA完成。
   
 // synopsys translate_off
`timescale 1ns/1ns
// synopsys translate_on


module compute(
               CLK,
  RSTn,
               DATA_in,//数据总线
               SHIFT_en,//移位寄存器使能信号
              &nbsprev_row_load,//加载前一行数据到寄存器
               Curr_row_load,//加载当前行数据到寄存器
               Next_row_load,//加载下一行数据到寄存器
               RESULT_row   //运算结果输出
               );


input CLK;
input RSTn;
input[7:0]   DATA_in;
input  SHIFT_en;
input &nbsprev_row_load;
input  Curr_row_load;
input  Next_row_load;
output[7:0]  RESULT_row ;   
             
 //---------------------   计算数据通路信号   -----------------------//
 
//wire signed  [10:0] D;
reg [7:0] abs_D;
reg [7:0] RESULT_row;
//---------------------Assignment-----------------------//


//-----------------         module        ------------//


 //----------------   always  ------------//
//the four cycle have one result.
reg [7:0] Prev_row, Curr_row, Next_row;
 
always@(posedge CLK or negedge RSTn)  //上一行寄存器
    begin
if (!RSTn)
Prev_row <= 8'd0;
else
if(Prev_row_load)&nbsp;
Prev_row<= DATA_in;
&nbsp; &nbsp; end

always@(posedge CLK or negedge RSTn) &nbsp;//当前行寄存器
&nbsp; &nbsp; begin
if (!RSTn)
Curr_row <= 8'd0;
else
if(Curr_row_load)&nbsp;
Curr_row<= DATA_in;
end

always@(posedge CLK or negedge RSTn) &nbsp;//下一行寄存器
begin
if (!RSTn)
&nbsp; &nbsp;Next_row <= 8'd0;
else
if(Next_row_load)&nbsp;
Next_row<=DATA_in;
end

//---------------- &nbsp; 计算绝对值函数 &nbsp;-----------------//

function [10:0] abs ( input signed [10:0] x);
abs = x >=0 ? x : -x ;
endfunction


//---------------- &nbsp; 计算流水线 &nbsp;-----------------//
&nbsp;reg [7:0] O[-1:1][-1:1]; &nbsp; &nbsp; // reg signed [7:0] &nbsp;O[-1:1][-1:1];
&nbsp;reg signed [10:0]Dx, Dy;
//assign D = abs(Dx) + abs(Dy);&nbsp;
always @(posedge CLK or negedge RSTn)&nbsp;
begin
if (!RSTn)
begin
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;
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;
end
else
if ( SHIFT_en )
begin
//D = abs(Dx) + abs(Dy);
abs_D <= (abs(Dx) + abs(Dy))>>3 ; &nbsp; // add 3bit is the bast. &nbsp; &nbsp; &nbsp; abs_D <=(abs(Dx) + abs(Dy)) 1....
Dx <= -$signed({3'b000, O[-1][-1]})//-1* O[-1][-1]
+$signed({3'b000, O[-1][+1]})//+1* O[-1][+1]
-($signed({3'b000, O[ 0][-1]})<<1)//-2* O[ 0][-1]
+($signed({3'b000, O[ 0][+1]})<<1)//+2* O[ 0][+1]
-$signed({3'b000, O[+1][-1]})//-1* O[+1][-1]
+$signed({3'b000, O[+1][+1]});//+1* O[+1][+1]
Dy <= $signed({3'b000, O[-1][-1]})//+1* O[-1][-1]
+($signed({3'b000, O[-1][ 0]}) &nbsp;<<1)//+2* O[-1][0]&nbsp; &nbsp;
+$signed({3'b000, O[-1][+1]})//+1* O[-1][+1]
-$signed({3'b000, O[+1][-1]})//-1* O[+1][-1]
-($signed({3'b000, O[+1][ 0]}) <<1)//-2* O[+1][ 0]
-$signed({3'b000, O[+1][+1]});//-1* O[+1][+1]
O[-1][-1] <= O[-1][0]; &nbsp; &nbsp; &nbsp;O[-1][ 0]<=O[-1][+1];O[-1][+1]<=Prev_row;
O[ 0][-1] <= O[0][0]; O[ 0][ 0] <= O[0][+1]; O[ 0][+1]<=Curr_row;
O[+1][-1] <= O[+1][0]; O[+1][ 0] <= O[+1][+1]; O[+1][+1]<=Next_row;
end
end
//---------------- &nbsp; 结果行寄存器 -----------------//
always @(posedge CLK or negedge RSTn)
begin
if (!RSTn)
&nbsp;RESULT_row <=8'd0;
else
if(SHIFT_en)
begin
&nbsp; if (abs_D>8'd40) &nbsp; //阈值分割,也就是matlab里面的THRESHOLD
RESULT_row <= 8'd0; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // &nbsp;RESULT_row <= abs_D[11:2] ; 1....
&nbsp; else
&nbsp; &nbsp; &nbsp; &nbsp;RESULT_row<= 8'd255;&nbsp;
end
end

endmodule

FPGA程序和MATLAB程序的对于关系应该很明显了。




本帖子中包含更多资源

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

x
 楼主| 晓灰灰 发表于 2018-10-23 13:06:28 | 显示全部楼层
简谈FPGA图像处理之边缘检测,中值滤波
zhangyukun 发表于 2018-10-24 09:35:03 | 显示全部楼层
简谈FPGA图像处理之边缘检测,中值滤波
Sunlife 发表于 2018-10-24 17:25:58 | 显示全部楼层
            
 楼主| 晓灰灰 发表于 2018-10-26 10:53:59 | 显示全部楼层






简谈FPGA图像处理之边缘检测,中值滤波
 楼主| 晓灰灰 发表于 2018-11-29 20:24:59 | 显示全部楼层
简谈FPGA图像处理之边缘检测,中值滤波
 楼主| 晓灰灰 发表于 2018-12-3 09:51:50 | 显示全部楼层
简谈FPGA图像处理之边缘检测,中值滤波
您需要登录后才可以回帖 登录 | 我要注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

QQ|小黑屋|手机版|Archiver|fpga论坛|fpga设计论坛 ( 京ICP备20003123号-1 )

GMT+8, 2025-5-1 06:49 , Processed in 0.070256 second(s), 20 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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