FPGA图像处理(六)------ 图像腐蚀and图像膨胀
默认迭代次数为1,只进行一次腐蚀、膨胀
一、图像腐蚀
1.相关定义
2.图像腐蚀效果图
3.fpga实现
彩色图像灰度化,灰度图像二值化,图像缓存生成滤波模块(3*3),图像腐蚀算法
`timescale 1ns / 1ps
//
// Description: 图像腐蚀 (前景色是黑色(0),背景色是白色(1) 腐蚀黑色)
//
module image_erode(input wire clk ,input wire reset ,input wire [10:0] img_width ,input wire [9:0] img_height ,input wire valid_i ,input wire [23:0] last_line_data ,input wire [23:0] cur_line_data ,input wire [23:0] next_line_data ,output reg valid_o ,output reg [23:0] img_data_o
);//常量声明parameter N = 3; //窗口大小//结构系数模版为{1,1,1,// 1,1,1,// 1,1,1}//变量声明reg valid_d1;reg [23:0] last_line_data_d1, last_line_data_d2;reg [23:0] cur_line_data_d1 , cur_line_data_d2 ;reg [23:0] next_line_data_d1, next_line_data_d2;//中心点位置,为cur_line_data_d1always@(posedge clk or posedge reset) beginif(reset) beginvalid_d1 <= 0;{last_line_data_d1, last_line_data_d2} <= 0;{cur_line_data_d1 , cur_line_data_d2 } <= 0;{next_line_data_d1, next_line_data_d2} <= 0;end else beginvalid_d1 <= valid_i;last_line_data_d1 <= last_line_data;last_line_data_d2 <= last_line_data_d1;cur_line_data_d1 <= cur_line_data;cur_line_data_d2 <= cur_line_data_d1;next_line_data_d1 <= next_line_data;next_line_data_d2 <= next_line_data_d1;endend//模板窗口范围内判断,前景色是黑色,背景色是白色,腐蚀处理就是前景色黑色减少//简单理解也就是,3*3窗口中所有像素值都是0时,才能将当前像素值为0输出always@(posedge clk or posedge reset) beginif(reset) beginvalid_o <= 0;img_data_o <= 0;end else if(valid_d1) beginif({last_line_data_d2, last_line_data_d1, last_line_data,cur_line_data_d2 , cur_line_data_d1 , cur_line_data ,next_line_data_d2, next_line_data_d1, next_line_data} == {27{8'd0}}) beginimg_data_o <= cur_line_data_d1;end else beginimg_data_o <= {3{8'd255}}; endvalid_o <= 1'b1;end else beginvalid_o <= 0;img_data_o <= 0;endendendmodule
明显可以看书汉字部分,经过腐蚀运算之后,白色字体变宽了(要是清晰显示文字,应该腐蚀白色,效果可能更好一点)
二、图像膨胀
1.相关定义
2.图像膨胀与图像腐蚀的联系
3.FPGA实现
`timescale 1ns / 1ps
//
// Description: 图像膨胀 (前景色是黑色,背景色是白色 只要覆盖区域有前景色则膨胀黑色)
//
module image_dilate(input wire clk ,input wire reset ,input wire [10:0] img_width ,input wire [9:0] img_height ,input wire valid_i ,input wire [23:0] last_line_data ,input wire [23:0] cur_line_data ,input wire [23:0] next_line_data , output reg valid_o ,output reg [23:0] img_data_o
);//常量声明parameter N = 3; //窗口大小//结构系数模版为{1,1,1,1,1,1,1,1,1}//变量声明reg valid_d1;reg [23:0] last_line_data_d1, last_line_data_d2;reg [23:0] cur_line_data_d1 , cur_line_data_d2 ;reg [23:0] next_line_data_d1, next_line_data_d2;//中心点位置,为cur_line_data_d1always@(posedge clk or posedge reset) beginif(reset) beginvalid_d1 <= 0;{last_line_data_d1, last_line_data_d2} <= 0;{cur_line_data_d1 , cur_line_data_d2 } <= 0;{next_line_data_d1, next_line_data_d2} <= 0;end else beginvalid_d1 <= valid_i;last_line_data_d1 <= last_line_data;last_line_data_d2 <= last_line_data_d1;cur_line_data_d1 <= cur_line_data;cur_line_data_d2 <= cur_line_data_d1;next_line_data_d1 <= next_line_data;next_line_data_d2 <= next_line_data;endend//模板窗口范围内判断,前景色是黑色,背景色是白色,膨胀处理就是前景色黑色扩张//简单理解也就是,3*3窗口中所有像素值都是255(白)时,才能将当前像素值为255输出always@(posedge clk or posedge reset) beginif(reset) beginvalid_o <= 0;img_data_o <= 0;end else if(valid_d1) beginif({last_line_data_d2, last_line_data_d1, last_line_data,cur_line_data_d2 , cur_line_data_d1 , cur_line_data ,next_line_data_d2, next_line_data_d1, next_line_data} == {27{8'd255}}) beginimg_data_o <= cur_line_data_d1;end else beginimg_data_o <= 0; endvalid_o <= 1'b1;end else beginvalid_o <= 0;img_data_o <= 0;endendendmodule
三、图像处理的开运算,闭运算和梯度运算
1.相关定义
2.fpga实现
开运算:
闭运算 :
梯度运算:
module image_process_top(input wire clk,input wire reset,input wire [10:0] img_width,input wire [9:0] img_height,input wire valid_i,input wire [23:0] img_data_i,output wire valid_o,output wire [23:0] img_data_o);//参数定义wire rgb2gray_valid;wire [23:0] rgb2gray_data;wire binary_valid;wire [23:0] binary_data;wire line_valid;wire [23:0] last_line_data, cur_line_data, next_line_data;wire erode_valid;wire [23:0] erode_data;wire dilate_valid;wire [23:0] dilate_data;wire line1_valid;wire [23:0] last_line1_data, cur_line1_data, next_line1_data;//灰度化处理image_rgb2gray u_image_rgb2gray(.clk ( clk ),.reset ( reset ),.valid_i ( valid_i ),.img_data_i ( img_data_i ),.valid_o ( rgb2gray_valid ),.img_data_o ( rgb2gray_data ));//二值化处理image_binary u_image_binary(.clk ( clk ),.reset ( reset ),.valid_i ( rgb2gray_valid ),.img_data_i ( rgb2gray_data ),.valid_o ( binary_valid ),.img_data_o ( binary_data ));//开运算
/*//3行缓存image_line_buffer u_image_line_buffer(.clk ( clk ),.reset ( reset ),.img_width ( img_width ),.img_height ( img_height ),.valid_i ( binary_valid ),.img_data_i ( binary_data ),.valid_o ( line_valid ),.last_line_data ( last_line_data ),.cur_line_data ( cur_line_data ),.next_line_data ( next_line_data ));//图像腐蚀image_erode u_image_erode(.clk ( clk ),.reset ( reset ),.img_width ( img_width ),.img_height ( img_height ),.valid_i ( line_valid ),.last_line_data ( last_line_data ),.cur_line_data ( cur_line_data ),.next_line_data ( next_line_data ),.valid_o ( erode_valid ),.img_data_o ( erode_data ));//3行缓存image_line_buffer u_image_line_buffer1(.clk ( clk ),.reset ( reset ),.img_width ( img_width ),.img_height ( img_height ),.valid_i ( erode_valid ),.img_data_i ( erode_data ),.valid_o ( line1_valid ),.last_line_data ( last_line1_data ),.cur_line_data ( cur_line1_data ),.next_line_data ( next_line1_data ));//图像膨胀image_dilate u_image_dilate(.clk ( clk ),.reset ( reset ),.img_width ( img_width ),.img_height ( img_height ),.valid_i ( line1_valid ),.last_line_data ( last_line1_data ),.cur_line_data ( cur_line1_data ),.next_line_data ( next_line1_data ),.valid_o ( valid_o ),.img_data_o ( img_data_o ));
*///闭运算
/*//3行缓存image_line_buffer u_image_line_buffer(.clk ( clk ),.reset ( reset ),.img_width ( img_width ),.img_height ( img_height ),.valid_i ( binary_valid ),.img_data_i ( binary_data ),.valid_o ( line_valid ),.last_line_data ( last_line_data ),.cur_line_data ( cur_line_data ),.next_line_data ( next_line_data ));//图像膨胀image_dilate u_image_dilate(.clk ( clk ),.reset ( reset ),.img_width ( img_width ),.img_height ( img_height ),.valid_i ( line_valid ),.last_line_data ( last_line_data ),.cur_line_data ( cur_line_data ),.next_line_data ( next_line_data ),.valid_o ( dilate_valid ),.img_data_o ( dilate_data ));//3行缓存image_line_buffer u_image_line_buffer1(.clk ( clk ),.reset ( reset ),.img_width ( img_width ),.img_height ( img_height ),.valid_i ( dilate_valid ),.img_data_i ( dilate_data ),.valid_o ( line1_valid ),.last_line_data ( last_line1_data ),.cur_line_data ( cur_line1_data ),.next_line_data ( next_line1_data ));//图像腐蚀image_erode u_image_erode(.clk ( clk ),.reset ( reset ),.img_width ( img_width ),.img_height ( img_height ),.valid_i ( line1_valid ),.last_line_data ( last_line1_data ),.cur_line_data ( cur_line1_data ),.next_line_data ( next_line1_data ),.valid_o ( valid_o ),.img_data_o ( img_data_o ));
*///梯度运算//3行缓存image_line_buffer u_image_line_buffer(.clk ( clk ),.reset ( reset ),.img_width ( img_width ),.img_height ( img_height ),.valid_i ( binary_valid ),.img_data_i ( binary_data ),.valid_o ( line_valid ),.last_line_data ( last_line_data ),.cur_line_data ( cur_line_data ),.next_line_data ( next_line_data ));//图像膨胀image_dilate u_image_dilate(.clk ( clk ),.reset ( reset ),.img_width ( img_width ),.img_height ( img_height ),.valid_i ( line_valid ),.last_line_data ( last_line_data ),.cur_line_data ( cur_line_data ),.next_line_data ( next_line_data ),.valid_o ( dilate_valid ),.img_data_o ( dilate_data ));//图像腐蚀image_erode u_image_erode(.clk ( clk ),.reset ( reset ),.img_width ( img_width ),.img_height ( img_height ),.valid_i ( line_valid ),.last_line_data ( last_line_data ),.cur_line_data ( cur_line_data ),.next_line_data ( next_line_data ),.valid_o ( erode_valid ),.img_data_o ( erode_data ));assign valid_o = dilate_valid;assign img_data_o = (dilate_data == 0)&&(erode_data == {3{8'd255}}) ? 0 : {3{8'd255}};endmodule