图像处理模块:
我的图像处理模块是将一个rgb565的视频或者图片转化为rgb888格式的,通过灰度化减少运算量,并且通过高斯滤波,对图像进行平滑处理,以减少图像中的噪声和细节,并模糊图像的细节,再将其二值化,简化图像,分割图像,凸显图像的特征,再根据sobel算子,求出物体的轮廓从而得到物体的边缘
1、灰度化(后面进行补充)(减少运算量)
1、首先将输入的rgb565格式的颜色,转变为rgb888的
red <= {din_pixel[15: 11] , din_pixel[13: 11] } ; // 带补偿的
green <= {din_pixel[10: 5], din_pixel[6: 5] } ;
blue <= {din_pixel[4: 0], din_pixel[2: 0] } ;
把rgb565低位的数值通过拼接补齐到rgb888
2、再根据灰度转换(加权平均法) rgb888 - gray
gray = R*0.299 + G*0.587 + B*0.114
= (306(九位) * R + 601(十位) * G + 117(七位) * B)/1024;
由于verilog中处理小数比较麻烦,这里把加权平均法的各项同时扩大了1024倍,也就是左移了10位,把其系数转为整数,算出来的和再向右移十位(或者取其第十位往后的8位亦可)
// 代码放最后
2、高斯滤波(后面进行补充)(减少噪声)
1、将从灰度化处理后的数值放入移位寄存器寄存(quartus ip核生成),从而生成3*3的矩阵来进行高斯滤波
2、这里我用了一个高斯滤波的模板
高斯滤波系数,加权平均
1 2 1
2 4 2
1 2 1
将每一项和系数相乘,然后得到每一行的数据之和,再将所得的和再进行相加,最终的结果除以滤波系数之和,则为经过高斯滤波处理后的数据
3、二值化
二值化将像素点的灰度值设置为0或25 5,要得到二值化图像,必须首先将图像灰度化,然后将256个亮度等级的灰度图像通过适当的阈值进行分割,灰度值大于或等于阈值的被分割成255(1 ),否则被分割为0
4、Sobel算子(求出物体的轮廓)
···································································
这几天会更新完关于边缘检测这方面的verilog实现
关于rgb转gray:
module rgb2gray
(
input clk ,
input rst_n ,
//capture
input din_sop ,
input din_eop ,
input din_vld ,
input [15: 0]din_pixel , // rgb565 ov5640 是16位深
//输出给gs_filter
output dout_sop ,
output dout_eop ,
output dout_vld ,
output [7: 0] dout_gray //灰度输出
);
//parameters
//signal
reg [7: 0] red ;
reg [7: 0] green ;
reg [7: 0] blue ;
reg [3:0]data_sop ;
reg [3:0]data_eop ;
reg [3:0]data_vld ;
reg [20:0]rgb_sum ;
reg [17:0]red_mult ;
reg [17:0]green_mult ;
reg [17:0]blue_mult ;
//三级打拍
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
data_sop <= 0;
data_eop <= 0;
data_vld <= 0;
end
else begin
data_sop <= {data_sop[2:0], din_sop} ;
data_eop <= {data_eop[2:0], din_eop} ;
data_vld <= {data_vld[2:0], din_vld} ;
end
end
// 将565的颜色格式 转换为 888,将rgb其中的低位分别补齐至8位
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
red <= 8'b0 ;
green <= 8'b0 ;
blue <= 8'b0 ;
end
else if (data_vld[1]) begin
red <= {din_pixel[15: 11] , din_pixel[13: 11] } ; // 带补偿的
green <= {din_pixel[10: 5], din_pixel[6: 5] } ;
blue <= {din_pixel[4: 0], din_pixel[2: 0] } ;
end
end
/************** 注释 ****************
灰度转换:RGB888-->Gray 加权平均法
gray = R*0.299 + G*0.587 + B*0.114
= (306(九位) * R + 601(十位) * G + 117(七位) * B)/1024;
****************************************/
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
red_mult <= 0 ;
green_mult<= 0 ;
blue_mult <= 0 ;
end
else if (data_vld[2]) begin
red_mult <= 306 * red ;
green_mult <= 601 * green ;
blue_mult <= 117 * blue ;
end
end
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
rgb_sum <= 0 ;
end
else if( data_vld[3] )begin
rgb_sum <= red_mult + green_mult + blue_mult ;
end
end
assign dout_gray = (data_vld[3]) ?( rgb_sum >> 10 ): 1'b0 ;
assign dout_sop = data_sop[3] ;
assign dout_eop = data_eop[3] ;
assign dout_vld = data_vld[3] ;
endmodule
二值化 --