本来相对较简单,而且网络上能找到的,我都不是很想写,必定我也忙,而且那些基础的东西还比较多,我也不可能全写出来,这样耗用的时间太多。但是关于图像处理这一块,有人跟我说,把简单的这些也写一写吧,网络资源比较少。我接受朋友的建议,简单的写了一些。
边缘检测:原理和算法结构,数字图像处理的书上都有写。这里看来没办法上传文件。我就这里来一个百度网盘链接。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 中值滤波。还是能找到相关程序的,所以决定中值滤波和图像均衡等,不在发表)
我能力有限,但是我愿意分享的技术,希望各位快速成长。
如果有图像处理,模式识别,数据挖掘的问题,可以直接留言。如果我有兴趣,我会努力帮忙。