红外芯片由于工艺问题存在严重的分均匀性,所以非均匀矫正一直是影响红外图像质量的第一因素。分均匀矫正的算法也是红外图像处理研究的重点区域,建立了一些矫正的方式方法。其中最常用最简单的就应该算是两点温度定标算法。
应用两点法校正有两个前提条件,第一,探测器的响应在所关注的温度范围内是线性变化的,第二,探测器的响应具有时间的稳定性,并且其受随机噪声的影响较小,则非均匀性引入固定模式的乘性和加性噪声。
% 生成nuc校正系数, 保存参数到bin文件
% parameter :
% Change Logs :
% Date - Author - version - Notes
% 2022.04.21 - Y.L - 1.0.0 -
%**************************************************************************************
close all; clc; clear; warning off all; feature jit off;
cols = 1280; % 图像宽度
rows = 1024; % 图像高度
nums = 350; % 参数非均匀校正帧数
PATH_H = 'E:\02_InfraredISP\01_非均匀校正\T20231109_nuc\Th\'; %高温图像
PATH_L = 'E:\02_InfraredISP\01_非均匀校正\T20231109_nuc\Tl\'; %低温图像
PATH_S = 'E:\02_InfraredISP\01_非均匀校正\T20231109_nuc\'; %未校正原始图像
% 进行非均匀校正,生成校正系数
[imgGain, imgBias] = fnuc_nuc(PATH_H, PATH_L, rows, cols, nums);
% 保存非均匀校正表到mat中
eval(['save ', PATH_S, 'nuctable.mat imgGain imgBias']); % 保存校正表到mat中
eval(['load ', PATH_S, 'nuctable.mat']); % 加载mat中校正表
% 读取未进行校正的图像,验证校正表是否生效
fid_img = fopen([PATH_S, 'Pipe0_1280x1024_Raw16_1_1_11.raw'], 'r');
temp_imgl(:, :) = transpose(fread(fid_img, [cols, rows], 'uint16'));
fclose(fid_img);
dstImg = temp_imgl .* imgGain + imgBias;
dstmean = mean(mean(uint16(dstImg)));
figure, imshow(dstImg, [dstmean-300 dstmean+300]);
disp(['info > ', 'Calculation of non-uniform correction table completed']);
eval(['save ', PATH_S, 'dstImg.mat dstImg']); % 将校正后图像保存到mat中
% 保存校正表到bin文件中(用于烧写FALSH)
func_saveflash(PATH_S, 'nuctable.mat', 'flash_cfg.bin', rows, cols);
function [imgGain,imgBias] = fnuc_nuc(path_h,path_l,row,col,nFrame)
% Nonuniform correction by two-point method
% Parameters:
% path_h ,path_l : 高低温图像的路径
% pixel_y,pixel_x : 图像的高度、宽度
% PDepth : 像素的位宽
% numFrame : 用于非均匀校正的图像帧数
% outpath : 输出增益、偏置两个校正表
% Example:
% [imgGain, imgBias] = F_nuc(FILEPATH_H, FILEPATH_L, row, col, 10, FILEPATH_O);
% Reading raw files
% Notes:
% The first 8 lines of the acquired image are invalid data, and the middle area of
% the data is used for correction
%% Loading image
function [] = func_saveflash(path_file, nucname, savefile, rows, cols)
% 保存校正表到bin文件中, bin用于烧写FLASH
% 加载校正表文件
eval(['load ', path_file, nucname]) % 加载校正表
% 读取OOC文件(OOC以图像形式存在)
imag_ooc = uint8(zeros(cols * 2, rows / 2)); % 后期需要实际的OOC配置文件
% 读取G文件(增益取值扩大1024倍)
imag_g_temp = uint16(round(imgGain .* 1024));
imag_g_temp(imag_g_temp < 0) = 0;
imag_g = imag_g_temp;
% 读取B文件
imag_b_temp = round(imgBias);
imag_b_temp(imag_b_temp > 16383) = 16383;
imag_b_temp(imag_b_temp < -16383) = -16383;
imag_b_temp(imag_b_temp < 0) = abs(imag_b_temp(imag_b_temp < 0)) + 32768; %负数在b的最高位(1表示负数、0表示正数)
imag_b = imag_b_temp;
% 生成flash烧写文件
dummy = zeros(4, 2560);
fid_flash = fopen([path_file, savefile], 'wb');
fwrite(fid_flash, imag_ooc', 'uint8'); % 1280*1024 = 140000H
fwrite(fid_flash, dummy', 'uint8');
fwrite(fid_flash, imag_g', 'uint16', 'ieee-be'); % 1032 142800 1280*1024*2 = 280000
fwrite(fid_flash, dummy', 'uint8'); % 145000 1341440
fwrite(fid_flash, dummy', 'uint8'); % 3C5000
fwrite(fid_flash, imag_b', 'uint16', 'ieee-be'); % 1032 3C7800
fwrite(fid_flash, dummy', 'uint8'); % 647800
fwrite(fid_flash, dummy', 'uint8'); %
fclose(fid_flash);
% Write to a single file
fid_two = fopen([path_file, 'two.bin'], 'wb');
fwrite(fid_two, imag_g', 'uint16', 'ieee-be'); % 1032 142800 1280*1024*2 = 280000
fclose(fid_two);
fid_one = fopen([path_file, 'one.bin'], 'wb');
fwrite(fid_one, imag_b', 'uint16', 'ieee-be'); % 1032 142800 1280*1024*2 = 280000
fclose(fid_one);
disp(['info > ', 'The FLASH file is generated and written done']);