最大对比度法自聚焦

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);
 

Guess you like

Origin blog.csdn.net/ccsss22/article/details/121896984