一、二值图像
对于腐蚀膨胀,输入必须是二值图像。 二值图像就是指图像上的每一个像素只有两种可能的取值或灰度等级状态,即只有0和1(黑和白),当然也可以设置成0和255,反正只有两种状态就行。
二、形态学滤波
形态学滤波有四种,分别是腐蚀、膨胀、开运算、闭运算。
1、腐蚀:是一种消除边界点,使边界向内部收缩的过程。可以用来消除小且无意义的物体。
腐蚀就是用该3*3窗口遍历二值图像上的每个像素,将窗口内的9个像素进行与运算 。P=P11&P12&P13&P21&P22&P23&P31&P32&P33(1代表白色,0代表黑色)
2、膨胀:是将与物体接触的所有背景点合并到该物体中,使边界向外部扩张的过程。可以用来填补物体中的空洞。
膨胀就是进行或运算。P=P11∣P12∣P13∣P21∣P22∣P23∣P31∣P32∣P33
3、开运算: 先腐蚀后膨胀。
4、闭运算:先膨胀后腐蚀。
三、腐蚀(先二值化再腐蚀)
1、代码
以下是二值化代码
module binary
(
input wire clk , //时钟
input wire rst_n , //复位
input wire gray_hs_out , //行同步
input wire gray_vs_out , //场同步
input wire [ 7:0] gray , //数据
input wire oValid , //数据使能
input wire [ 7:0] value , //阈值
output wire bina_hsync , //二值行同步
output wire bina_vsync , //二值场同步
output wire [ 7:0] bina_data , //二值数据
output wire bina_de //二值数据使能
);
//==========================================================================
//== 代码
//==========================================================================
assign bina_hsync = gray_hs_out;
assign bina_vsync = gray_vs_out;
assign bina_de = oValid;
assign bina_data = (gray > 127) ? 8'hff : 8'h00;
endmodule
以下是腐蚀代码:
module erode
(
input wire clk , //时钟
input wire rst_n , //复位
//input ---------------------------------------------
input wire bina_hsync , //bina分量行同步
input wire bina_vsync , //bina分量场同步
input wire [ 7:0] bina_data , //bina分量数据
input wire bina_de , //bina分量数据使能
//output --------------------------------------------
output wire erode_hsync , //erode行同步
output wire erode_vsync , //erode场同步
output wire [ 7:0] erode_data , //erode数据
output wire erode_de //erode数据使能
);
wire [7:0] filter_11,filter_12,filter_13;
wire [7:0] filter_21,filter_22,filter_23;
wire [7:0] filter_31,filter_32,filter_33;
reg [ 2:0] bina_de_r ; //使能打拍
reg [ 2:0] bina_hsync_r ; //行同步打拍
reg [ 2:0] bina_vsync_r ; //场同步打拍
reg erode_1 ;
reg erode_2 ;
reg erode_3 ;
reg erode ;
//==========================================================================
//== 模块例化,耗费1clk
//==========================================================================
filter_3x3 filter_3x3_inst(
.clk (clk ),
.rst_n (rst_n ),
.gray_de (bina_de ),
.iData (bina_data),
.oData_11 (filter_11), .oData_12 (filter_12), .oData_13 (filter_13),
.oData_21 (filter_21), .oData_22 (filter_22), .oData_23 (filter_23),
.oData_31 (filter_31), .oData_32 (filter_32), .oData_33 (filter_33)
);
//==============================================================================
//== 腐蚀,耗费2clk
//==============================================================================
//clk1,三行各自相与
//---------------------------------------------------
always @ (posedge clk or negedge rst_n)begin
if(!rst_n)begin
erode_1 <= 'd0;
erode_2 <= 'd0;
erode_3 <= 'd0;
end
else begin
erode_1 <= filter_11 && filter_12 && filter_13;
erode_2 <= filter_21 && filter_22 && filter_23;
erode_3 <= filter_31 && filter_32 && filter_33;
end
end
//clk2,全部相与
//---------------------------------------------------
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
erode <= 'd0;
end
else begin
erode <= erode_1 && erode_2 && erode_3;
end
end
//==========================================================================
//== 信号值输出
//==========================================================================
assign erode_data = erode ? 8'hff : 8'h00;
//==========================================================================
//== 信号同步(打三拍)
//==========================================================================
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
bina_de_r <= 3'b0;
bina_hsync_r <= 3'b0;
bina_vsync_r <= 3'b0;
end
else begin
bina_de_r <= {bina_de_r[1:0], bina_de};
bina_hsync_r <= {bina_hsync_r[1:0], bina_hsync};
bina_vsync_r <= {bina_vsync_r[1:0], bina_vsync};
end
end
assign erode_de = bina_de_r[2];
assign erode_hsync = bina_hsync_r[2];
assign erode_vsync = bina_vsync_r[2];
endmodule
2、效果图
原图:
FPGA二值化图:
FPGA二值化后的腐蚀图:
FPGA腐蚀图(上板)
MATLAB二值化后的腐蚀图
FPGA与MATLAB的效果一致,都把一些白色的明亮区域给腐蚀掉啦,实验成功。
四、膨胀
1、代码
二值化代码同上,稍微改下端口名就可
以下是膨胀代码:
module dilate
(
input wire clk , //时钟
input wire rst_n , //复位
//input ---------------------------------------------
input wire bina_hsync , //bina分量行同步
input wire bina_vsync , //bina分量场同步
input wire [ 7:0] bina_data , //bina分量数据
input wire bina_de , //bina分量数据使能
//output --------------------------------------------
output wire dilate_hsync , //dilate行同步
output wire dilate_vsync , //dilate场同步
output wire [ 7:0] dilate_data , //dilate数据
output wire dilate_de //dilate数据使能
);
wire [7:0] filter_11,filter_12,filter_13;
wire [7:0] filter_21,filter_22,filter_23;
wire [7:0] filter_31,filter_32,filter_33;
reg [ 2:0] bina_de_r ; //使能打拍
reg [ 2:0] bina_hsync_r ; //行同步打拍
reg [ 2:0] bina_vsync_r ; //场同步打拍
reg dilate_1 ;
reg dilate_2 ;
reg dilate_3 ;
reg dilate ;
//==========================================================================
//== 模块例化,耗费1clk
//==========================================================================
filter_3x3 filter_3x3_inst(
.clk (clk ),
.rst_n (rst_n ),
.gray_de (bina_de ),
.iData (bina_data),
.oData_11 (filter_11), .oData_12 (filter_12), .oData_13 (filter_13),
.oData_21 (filter_21), .oData_22 (filter_22), .oData_23 (filter_23),
.oData_31 (filter_31), .oData_32 (filter_32), .oData_33 (filter_33)
);
//==============================================================================
//== 腐蚀,耗费2clk
//==============================================================================
//clk1,三行各自相与
//---------------------------------------------------
always @ (posedge clk or negedge rst_n)begin
if(!rst_n)begin
dilate_1 <= 'd0;
dilate_2 <= 'd0;
dilate_3 <= 'd0;
end
else begin
dilate_1 <= filter_11 || filter_12 || filter_13;
dilate_2 <= filter_21 || filter_22 || filter_23;
dilate_3 <= filter_31 || filter_32 || filter_33;
end
end
//clk2,全部相与
//---------------------------------------------------
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
dilate <= 'd0;
end
else begin
dilate <= dilate_1 || dilate_2 || dilate_3;
end
end
//==========================================================================
//== 信号值输出
//==========================================================================
assign dilate_data = dilate ? 8'hff : 8'h00;
//==========================================================================
//== 信号同步(打三拍)
//==========================================================================
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
bina_de_r <= 3'b0;
bina_hsync_r <= 3'b0;
bina_vsync_r <= 3'b0;
end
else begin
bina_de_r <= {bina_de_r[1:0], bina_de};
bina_hsync_r <= {bina_hsync_r[1:0], bina_hsync};
bina_vsync_r <= {bina_vsync_r[1:0], bina_vsync};
end
end
assign dilate_de = bina_de_r[2];
assign dilate_hsync = bina_hsync_r[2];
assign dilate_vsync = bina_vsync_r[2];
endmodule
2、效果图
原图:
二值化图:
膨胀图:
MATLAB膨胀图:
FPGA与MATLAB的效果一致,都把一些白色的明亮区域给膨胀啦,实验成功。