FPGA图像处理之边缘检测,中值滤波,图像均衡1。

来源:互联网 发布:免费被加活粉软件2017 编辑:程序博客网 时间:2024/05/06 06:52

                本来相对较简单,而且网络上能找到的,我都不是很想写,必定我也忙,而且那些基础的东西还比较多,我也不可能全写出来,这样耗用的时间太多。但是关于图像处理这一块,有人跟我说,把简单的这些也写一写吧,网络资源比较少。我接受朋友的建议,简单的写了一些。

          边缘检测:原理和算法结构,数字图像处理的书上都有写。这里看来没办法上传文件。我就这里来一个百度网盘链接。http://pan.baidu.com/s/1bnB0aeV(冈萨雷斯的书)。这边书,描述的边缘检测的方法,原理写的都很明白。不多说。但是要注意几点:边缘检测对噪声敏感所以需要先进行滤波处理。边缘检测是求微分或者说求导数的过程。

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,//移位寄存器使能信号
               Prev_row_load,//加载前一行数据到寄存器
               Curr_row_load,//加载当前行数据到寄存器
               Next_row_load,//加载下一行数据到寄存器
               RESULT_row   //运算结果输出
               );


input CLK;
input RSTn;
input[7:0]   DATA_in;
input  SHIFT_en;
input  Prev_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) 
Prev_row<= DATA_in;
    end

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

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


//----------------   计算绝对值函数  -----------------//




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


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

endmodule

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


最后我还是把全套的资料和程序发上来了。又给各位偷懒的机会了。(我刚才去百度了一下Verilog 中值滤波。还是能找到相关程序的,所以决定中值滤波和图像均衡等,不在发表)



微笑我能力有限,但是我愿意分享的技术,希望各位快速成长。

如果有图像处理,模式识别,数据挖掘的问题,可以直接留言。如果我有兴趣,我会努力帮忙


4 0
原创粉丝点击