1 背景知识
二值图像(Binary Image)是指将图像上的每一个像素只有两种可能的取值或灰度等级状态,人们经常用黑白、B&W、单色图像表示二值图像。二值图像是指在图像中,灰度等级只有两种,也就是说,图像中的任何像素不是0就是1,再无其他过渡的灰度值。
二值图像经常出现在数字图像处理中作为图像掩码或者在图像分割、二值化和dithering的结果中出现。一些输入输出设备,如激光打印机、传真机、单色计算机显示器等都可以处理二值图像。
二值图像经常使用位图格式存储。
二值图像可以解释为二维整数格,图像变形处理领域很大程度上就是受到这个观点启发。
膨胀与腐蚀是形态学滤波的两个基本运算,能实现多种多样的功能,主要功能如下:
(1)消除噪声;
(2)分割出独立的图像元素;
(3)在图像中连接相邻的元素;
(4)寻找图像中明显的极大值和极小值区域;
(5)求出图像的梯度。
图1 具有断裂文字的低分辨率样品文字(见放大的视图)
如图1所示,a为具有断裂文字的低分辨率样品文字(见放大的视图),b为结构元,c为图b对a的膨胀。断裂线段被连接起来了。
2 膨胀算法
在这里我们演示黑色膨胀过程。
图2 膨胀演示
在二值图像的膨胀算法过程中我们使用二值图像3x3图像矩阵,由图1可知,当九个格子中只要出现一个‘0’,经过膨胀算法后(x,y)点的值都会是‘0’。
只有(x,y)点以及相邻的八个点都是‘1’f(x,y)的值才是‘1’。这样就完成了二值图像的膨胀。
3 FPGA膨胀算法实现
图3 二值图像膨胀FPGA模块架构
图3中我们使用串口传图传入的是二值图像。
FPGA源码:
/*
Module name: binary_image_swell.v
Description: binary image swell.
*/
`timescale 1ns/1ps
module binary_image_swell(
input clk, //pixel clk
input rst_n,
input [15:0] data_in,
input data_in_en,
output reg [15:0] data_out,
output data_out_en
);
wire [15:0] line0;
wire [15:0] line1;
wire [15:0] line2;
reg [15:0] line0_data0;
reg [15:0] line0_data1;
reg [15:0] line0_data2;
reg [15:0] line1_data0;
reg [15:0] line1_data1;
reg [15:0] line1_data2;
reg [15:0] line2_data0;
reg [15:0] line2_data1;
reg [15:0] line2_data2;
reg data_out_en0;
reg data_out_en1;
reg data_out_en2;
line3x3 line3x3_inst(
.clken(data_in_en),
.clock(clk),
.shiftin(data_in),
.shiftout(),
.taps0x(line0),
.taps1x(line1),
.taps2x(line2)
);
//----------------------------------------------------------------------------
// Form an image matrix of three multiplied by three
//---------------------------------------------------------------------------
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
line0_data0 <= 16'b0;
line0_data1 <= 16'b0;
line0_data2 <= 16'b0;
line1_data0 <= 16'b0;
line1_data1 <= 16'b0;
line1_data2 <= 16'b0;
line2_data0 <= 16'b0;
line2_data1 <= 16'b0;
line2_data2 <= 16'b0;
data_out_en0 <= 1'b0;
data_out_en1 <= 1'b0;
data_out_en2 <= 1'b0;
end
else if(data_in_en) begin
line0_data0 <= line0;
line0_data1 <= line0_data0;
line0_data2 <= line0_data1;
line1_data0 <= line1;
line1_data1 <= line1_data0;
line1_data2 <= line1_data1;
line2_data0 <= line2;
line2_data1 <= line2_data0;
line2_data2 <= line2_data1;
data_out_en0 <= data_in_en;
data_out_en1 <= data_out_en0;
data_out_en2 <= data_out_en1;
end
end
always @(posedge clk or negedge rst_n) begin
if(!rst_n)
data_out <= 16'h0000;
else if(data_out_en1)
if((line0_data0 == 16'h0000) && (line0_data1 == 16'h0000) && (line0_data2 == 16'h0000) && (line1_data0 == 16'h0000) && (line1_data1 == 16'h0000) && (line1_data2 == 16'h0000) && (line2_data0 == 16'h0000) && (line2_data1 == 16'h0000) && (line2_data2 == 16'h0000))
data_out <= line1_data1;
else if((line0_data0 == 16'hffff) && (line0_data1 == 16'hffff) && (line0_data2 == 16'hffff) && (line1_data0 == 16'hffff) && (line1_data1 == 16'hffff) && (line1_data2 == 16'hffff) && (line2_data0 == 16'hffff) && (line2_data1 == 16'hffff) && (line2_data2 == 16'hffff))
data_out <= line1_data1;
else
data_out <= 16'h0000;
end
endmodule
4实验结果
图4 实验原图
图5 实验原图显示结果图
图6 膨胀后的结果图
结果分析:
由图5和图6来看,明显线条被加粗,膨胀算法实现。
至此,有兴趣的同学可以使用FPGA开发板自己来实验一下下面这个过程,已达到自我的理解和贯通。
RGB图像->sobel算子边缘检测->二值图像的腐蚀->二值图像的膨胀。
评论
查看更多