1.背景
目前用到的国产红外探测器普遍均匀度较差、且存在较多坏点,为了不影响最终的成像质量一般都会对探测器输出的图像先进行均匀性矫正和坏点去除。
2.基本原理
坏点去除原理很简单就是用周围的像素值来代替坏点的像素值。首先需要判断一张图像中坏点的位置,用待标定红外相机拍摄不同温度的黑体图像,坏点对温度的响应明显区别于正常的像素点,将这些点坐标标记出来。坏点替换时一般根据实际情况用3*3或者5*5或者更大的开窗的像素平均值来替换中心坏点的值。在实际操作时用均值替换的效果不如用周围像素的中值替换,因为很多红外探测器坏点喜欢集中出现,一个坏点周围可能还有坏点,用中值替换可以减少周围坏点对替换后效果的影响。
3.FPGA实现
坏点替换算法和中值滤波或者均值滤波算法很相似,坏点算法仅对标记为坏点的开窗计算均值或中值进行替换,而中值滤波或是均值滤波则对整幅图都计算中值或均值进行替换。所以实现坏点算法的过程和滤波算法极为相似
首先建立3*3开窗的寄存器,将图像视频流用移位寄存器ip核缓存两行,这样三行图像就实现了并行输出了,和当前行输出一起缓存三次就形成了3*3开窗。注意这里缓存行的长度包含了行空闲,如果一行长度超出了移位寄存器(shift ram ip)的最大长度就用两个寄存器。FPGA的图像处理实现基本都建立在开窗基础之上。
将坏点标记和对应的图像像素一起缓存,中间的那行的中间像素若标记为1则代表当前开窗为坏点开窗,进行中值或均值替换,若不为1则不进行替换。
1.下面是以中值滤波为基础的坏点替换算法:
开窗建立顶层:
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2022/07/19 14:08:30
// Design Name:
// Module Name: mid_wave
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module mid_wave(
input I_clk,
input I_reset,
input I_clk_test,
input I_frame_valid,
input I_line_valid,
input[31:0] I_par_Q,
input[15:0] I_video_in,
output wire O_frame_valid,
output wire O_line_valid,
output wire[15:0] O_video_out,
output O_hblank,
output O_vblank
);
reg [18:0] S_temp0_r0;
reg [18:0] S_temp0_r1;
reg [18:0] S_temp0_r2;
reg [18:0] S_temp1_r0;
reg [18:0] S_temp1_r1;
reg [18:0] S_temp1_r2;
reg [18:0] S_temp2_r0;
reg [18:0] S_temp2_r1;
reg [18:0] S_temp2_r2;
wire[18:0] S_fifo0;
wire[18:0] S_fifo1;
wire[18:0] S_fifo0_1;
wire[18:0] S_fifo1_1;
wire[18:0] S_video_in;
wire[15:0] S_video_out;
wire S_blind_sig;
assign S_video_in = {I_frame_valid,I_line_valid,S_blind_sig,I_video_in};
assign O_hblank = (~O_line_valid) & O_frame_valid;
assign O_vblank = ~O_frame_valid;
assign S_blind_sig = I_par_Q[28];
c_shift_ram_0 c_shift_ram_0_0(
.D(S_video_in),
.CLK(I_clk),
.Q(S_fifo0_1)
);
c_shift_ram_0 c_shift_ram_0_1(
.D(S_fifo0_1),
.CLK(I_clk),
.Q(S_fifo0)
);
c_shift_ram_0 c_shift_ram_0_2(
.D(S_fifo0),
.CLK(I_clk),
.Q(S_fifo1_1)
);
c_shift_ram_0 c_shift_ram_0_3(
.D(S_fifo1_1),
.CLK(I_clk),
.Q(S_fifo1)
);
mid_data mid_data_i(
//System Interfaces
.sclk(I_clk) ,
.rst_n(I_reset) ,
.mat_row1(S_video_in) ,
.mat_row2(S_fifo0) ,
.mat_row3(S_fifo1) ,
.O_frame(O_frame_valid) ,
.O_line(O_line_valid) ,
.O_data(O_video_out)
);
///
endmodule
I_par_Q为坏点标记因为是matlab计算的浮点数所以是32位也可以只用1位来表示坏点。将坏点标记和行同步帧同步一起加到数据的高3位,再一起进行缓存便于最后输出。这里是640*512 16位红外图像,每一行加上行空闲一共有700多个像素时钟周期超出移位寄存器ip最大设置,所以每一行用了2个移位寄存器ip。
中值计算
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2022/07/19 14:24:10
// Design Name:
// Module Name: mid_data
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
m