目录
1.最大对比度法自聚焦基本原理
最大对比度法(Maximum Contrast Method)是一种自动对焦技术,通常用于数字图像处理和计算机视觉应用中。它的原理是寻找图像中具有最大对比度的区域,从而确定焦距的最佳位置。以下是最大对比度法的原理和相关公式:
原理: 自聚焦是通过分析图像的焦平面位置以获得最佳对焦的过程。最大对比度法基于以下原理:
-
图像对比度:图像对比度是描述图像中亮度变化程度的指标。对比度高的区域通常包含清晰的细节信息,而对比度低的区域则通常模糊或缺乏细节。因此,对比度高的区域可能对焦距的选择更为敏感。
-
对焦平面:当焦距与图像场景的焦距匹配时,图像中的细节会变得更加清晰和明确。焦距不匹配时,图像会变得模糊。
最大对比度法通过移动焦距,评估每个焦距位置下的图像对比度,然后选择具有最大对比度的位置作为最佳焦距。
最大对比度法的关键步骤是计算每个焦距位置下的图像对比度。通常,可以使用以下公式来计算图像的对比度:
在实际应用中,为了减少计算复杂度,可以选择一些图像区域进行对比度计算,而不是对整个图像执行此操作。通常,对比度的计算也会结合滤波器来平滑图像以减少噪声的影响。
2.核心matlab程序
function fdr = AutoFocusing_Contrast(InputRealFile, InputImagFile, Range, Azimuth, FocusDepthPoint, INITIAL_STEP, MAX_ITERATIVE_NUM, FINAL_STEP, fdr0,f_prf)
%----------------------------最大对比度法自聚焦-----------------------------------%
% 输入:距离压缩后转角存储的I/Q两路数据文件
% 输出:按聚焦深度估计出的多普勒调频率
% 算法:最大对比度法
% 准则:选取每个聚焦深度内对比度最大的距离门为参考信号,搜索使该距离门信号成像结果聚焦比最大的fdr作为估计结果
% 调用本模块需要设定的参数详见源代码
% tic;
ta = (0 : Azimuth-1)*(1/f_prf) ;
T_max = Azimuth*(1/f_prf);
%--------------------------------进行方位压缩,选取参考信号-------------------------------%
Ndepth = ceil(Range / FocusDepthPoint); % 测绘带内的聚焦深度数
% 打开距离压缩后转角存储的I/Q两路数据文件
FidReadReal = fopen(InputRealFile,'r');
FidReadImag = fopen(InputImagFile,'r');
if((Range - FocusDepthPoint * Ndepth) ~= 0)
temp_shy = 1;
else
temp_shy = 0;
end
max_value = zeros(1,Ndepth);
max_pos = zeros(1,Ndepth);
for i = 1 : Ndepth
AzimuthRef = conj(exp(j*pi*fdr0(i)* ( ta -T_max/2 ).^2 ));
if((temp_shy == 1) && (i == Ndepth))
m_stop = Range - FocusDepthPoint * (Ndepth - 1);
else
m_stop = FocusDepthPoint;
end
focus_rate = zeros(1,m_stop);
% 取每个聚焦深度内聚焦比最大的距离门作为参考信号
for m = 1 : m_stop
TempRe = fread(FidReadReal, Azimuth, 'float32');
TempIm = fread(FidReadImag, Azimuth, 'float32');
Temp = (TempRe + j*TempIm).';
Hout = Temp .* AzimuthRef;
out_effective = abs(fft(Hout));
% 计算聚焦比
focus_rate(m) = var(out_effective) / mean(out_effective);
end
[max_value(i), max_pos(i)] = max(focus_rate);
end
%-----------------------------------最大对比度法自聚焦-----------------------------------%
first_validfdr_pos = -1; % 存放第一个自聚焦成功的聚焦深度,是测绘带内的第几个聚焦深度
update_step = 0; % 清除步长更新标识
fdr_step = INITIAL_STEP; % 设定自聚焦估计的初始搜索步长;注意:fdr的步长是在初始步长的基础上,每次减小一倍,直到步长不大于1Hz;
% 因此,如果初始步长是2的整数次幂,则fdr的估计精度为1Hz
iterative_num = 1; % 初始化迭代次数标识
autofocusing_over = 0; % 初始化自聚焦结束表示
autofocusing_fail = 0; % 初始化自聚焦失败标识
fdr = zeros(1, Ndepth);
focus_rate_current_fdr = zeros(1,3);
for i = 1 : Ndepth
% 当前聚焦深度的fdr初值
current_fdr = fdr0(i);
% 读入当前聚焦深度的参考信号
fseek(FidReadReal, ((i - 1) * FocusDepthPoint + max_pos(i) - 1) * Azimuth * 4, -1);
fseek(FidReadImag, ((i - 1) * FocusDepthPoint + max_pos(i) - 1) * Azimuth * 4, -1);
% 得到参考信号频谱
TempRe = fread(FidReadReal, Azimuth, 'float32');
TempIm = fread(FidReadImag, Azimuth, 'float32');
Temp = (TempRe + j*TempIm).';
% % % % % HTemp = fft(Temp);
% 反复迭代,直到估计出当前聚焦深度的fdr
while(autofocusing_over ~= 1)
% 反复迭代,直到在当前搜索步长下估计出fdr
while(update_step ~= 1)
% 判断当前搜索步长是否为初始步长
if(fdr_step == INITIAL_STEP)
% 判断是否为基于初始步长的第一次迭代
% 是,则需要计算三个聚焦比,即:current_fdr-fdr_step、current_fdr、current_fdr+fdr_step
if(iterative_num == 1)
leftpos_fdr = -1;
rightpos_fdr = 1;
m_step = 1;
% 否,则需要计算一个聚焦比,即:current_fdr-fdr_step或current_fdr+fdr_step
else
leftpos_fdr = current_peak - 2;
rightpos_fdr = current_peak - 2;
m_step = 1;
end
% 不是初始步长则不需要迭代,而且需要计算两个聚焦比,即:current_fdr-fdr_step、current_fdr+fdr_step
else
leftpos_fdr = -1;
rightpos_fdr = 1;
m_step = 2;
end
for m = leftpos_fdr : m_step : rightpos_fdr
% 利用上一次迭代结果,更新方位向参考函数
AzimuthRef = conj(rectpuls( ta -T_max/2 ,T_max).*exp(j*pi*(current_fdr + m*fdr_step)* ( ta - T_max/2 ).^2 ));
Hout = Temp .* AzimuthRef;
out_effective = abs(fft(Hout));
% 计算聚焦比 ???????为什么不是标准差比均值了
mean_value = mean(out_effective);
[max1, pos1] = max(out_effective);
out_effective(pos1) = 0;
[max2, pos2] = max(out_effective);
out_effective(pos2) = 0;
[max3, pos3] = max(out_effective);
max_value = (max1 + max2 + max3) / 3;
focus_rate_current_fdr(m + 2) = max_value / mean_value;
end
% 寻找相邻三个fdr中,所成图像聚焦比最大的那个fdr
[current_max_value, current_peak] = max(focus_rate_current_fdr);
% 判断是否中间的fdr所成的图像聚焦比最大
if(current_peak == 2)
% 判断当前步长是否足够小,是的话结束当前聚焦深度的自聚焦
if(fdr_step <= FINAL_STEP)
update_step = 1;
autofocusing_over = 1;
% 否则更新步长继续进行自聚焦
else
update_step = 1;
fdr_step = fdr_step / 2;
end
% 如果是边上的fdr所成的图像聚焦比最大,则要做两件事情
else
% 1、判断当前步长是否为初始步长,以决定是否需要更新步长
if fdr_step == INITIAL_STEP
iterative_num = iterative_num + 1;
current_fdr = current_fdr + (current_peak - 2) * fdr_step;
else
current_fdr = current_fdr + (current_peak - 2) * fdr_step;
fdr_step = fdr_step / 2;
update_step = 1;
end
% 2、更新存放聚焦比的数组focus_rate_current_fdr
if(current_peak == 1)
focus_rate_current_fdr(3) = focus_rate_current_fdr(2);
focus_rate_current_fdr(2) = focus_rate_current_fdr(1);
else
focus_rate_current_fdr(1) = focus_rate_current_fdr(2);
focus_rate_current_fdr(2) = focus_rate_current_fdr(3);
end
end
% 在初始搜索步长下,如果迭代次数超出允许的最大次数,则当前聚焦深度的自聚焦处理失败
if(iterative_num > MAX_ITERATIVE_NUM)
update_step = 1;
autofocusing_over = 1;
autofocusing_fail = 1;
end
end % end of while(update_step ~= 1),
% 清除步长更新标识
update_step = 0;
end % end of while(autofocusing_over ~= 1),
% 迭代步长恢复初始搜索步长
fdr_step = INITIAL_STEP;
% 迭代次数归一
iterative_num = 1;
% 存储估得的当前聚焦深度的fdr值
if autofocusing_fail == 0
fdr(i) = current_fdr;
% 记录第一个自聚焦成功的聚焦深度的位置
if(first_validfdr_pos == -1)
first_validfdr_pos = i;
end
else
fdr(i) = 12345678;
end
% 清除自聚焦结束标识
autofocusing_over = 0;
% 清除自聚焦失败标识
autofocusing_fail = 0;
end % end of for i = 1 : Ndepth
% 判断是否所有聚焦深度的自聚焦都失败
if(first_validfdr_pos == -1)
autofocusing_fail_total = 1;
% 不是彻底失败的话,令第一个聚焦深度的fdr值等于第一个自聚焦成功的聚焦深度的fdr值
else
autofocusing_fail_total = 0;
fdr(1) = fdr(first_validfdr_pos);
end
% 计算自聚焦失败的聚焦深度的fdr值,两种方法:
% 1、如果后一个聚焦深度自聚焦成功,取前后两个聚焦深度的fdr值的平均;
% 2、否则令当前聚焦深度的fdr值等于前一个聚焦深度的fdr值
if(autofocusing_fail_total ~= 1)
for i = 2 : 1 : Ndepth
if(fdr(i) == 12345678)
if(i ~= Ndepth)
if(fdr(i + 1) ~= 12345678)
fdr(i) = (fdr(i - 1) + fdr(i + 1)) / 2;
else
fdr(i) = fdr(i - 1);
end
else
fdr(i) = fdr(i - 1);
end
end
end
end
fclose(FidReadReal);
fclose(FidReadImag);