步达硬件头像
关注
【Matlab】类RTL图像处理代码库封面图

【Matlab】类RTL图像处理代码库

1 线性插值

2 双线性插值

3 空间插值

out=in*Gain/Div,Gain通过网格绑点设定插值得到。
在这里插入图片描述

function o_img = PositionGainSpread(i_img, grid_Gain, gain_div, grid_V, grid_H)
% PositionGainSpread - 根据网格增益调整图像局部亮度(RTL对齐,分步向0取整)
% 
% =========================================================================
% 调用方法:
%   o_img = PositionGainSpread(i_img, grid_Gain, gain_div, grid_V, grid_H)
% 
% =========================================================================
% 输入参数:
%   i_img     - 输入图像(V×H×C),uint8/uint16/double
%   grid_Gain - a×b 增益矩阵(原始整数值)
%   gain_div  - 增益除数(如 2^8 = 256)
%   grid_V    - 垂直方向绑点间隔(如 270)
%   grid_H    - 水平方向绑点间隔(如 320)
% 
% =========================================================================
% 输出参数:
%   o_img     - 调整后的图像(V×H×C)
% 
% =========================================================================
% 绑点分布规则:
%   第一个绑点在 (1, 1)     ← 左上角
%   绑点间隔为 grid_V, grid_H
%   最后一个绑点固定在 (V, H) ← 右下角边界
% 
% 空间线性插值说明:
%   对图像中每个像素 (i,j),在 grid_Gain 中查找其所在的 2×2 邻域
%   使用双线性插值计算该点的 gain 值
%   gain = fix((dv2*R1 + dv1*R2) / step_v)
%   其中 R1 = fix((dh2*Q11 + dh1*Q21) / step_h)
%        R2 = fix((dh2*Q12 + dh1*Q22) / step_h)
% 
% 计算公式(每步向0取整,与RTL一致):
%   gain = 双线性插值(grid_Gain)
%   output = fix(input * gain / gain_div)

    % ---- 参数检查 ----
    if nargin < 3
        error('至少需要输入 i_img, grid_Gain, gain_div!');
    end
    
    [V, H, C] = size(i_img);
    [a, b] = size(grid_Gain);
    
    if a < 2 || b < 2
        error('grid_Gain 至少为 2×2!');
    end
    
    if nargin < 4 || isempty(grid_V)
        grid_V = fix(V / a);
    end
    if nargin < 5 || isempty(grid_H)
        grid_H = fix(H / b);
    end
    
    % ---- 绑点位置:固定间隔 + 最后一个在边界 ----
    grid_V_pos = zeros(1, a);
    for i = 1:a-1
        grid_V_pos(i) = 1 + (i-1) * grid_V;
    end
    grid_V_pos(a) = V;   % 最后一个固定在边界
    
    grid_H_pos = zeros(1, b);
    for j = 1:b-1
        grid_H_pos(j) = 1 + (j-1) * grid_H;
    end
    grid_H_pos(b) = H;   % 最后一个固定在边界
    
    % ---- 记录原始数据类型 ----
    input_class = class(i_img);
    
    % ---- 初始化输出 ----
    o_img = zeros(V, H, C);
    
    % ---- 逐像素计算(空间线性插值) ----
    for c = 1:C
        for i = 1:V
            for j = 1:H
                % ---- Step1: 查找垂直方向区间 ----
                if i <= grid_V_pos(1)
                    idx_v = 1;
                    v1 = grid_V_pos(1);
                    v2 = grid_V_pos(2);
                elseif i >= grid_V_pos(end)
                    idx_v = a - 1;
                    v1 = grid_V_pos(end-1);
                    v2 = grid_V_pos(end);
                else
                    idx_v = 1;
                    for k = 1:a-1
                        if i >= grid_V_pos(k) && i <= grid_V_pos(k+1)
                            idx_v = k;
                            break;
                        end
                    end
                    v1 = grid_V_pos(idx_v);
                    v2 = grid_V_pos(idx_v + 1);
                end
                
                % ---- Step2: 查找水平方向区间 ----
                if j <= grid_H_pos(1)
                    idx_h = 1;
                    h1 = grid_H_pos(1);
                    h2 = grid_H_pos(2);
                elseif j >= grid_H_pos(end)
                    idx_h = b - 1;
                    h1 = grid_H_pos(end-1);
                    h2 = grid_H_pos(end);
                else
                    idx_h = 1;
                    for k = 1:b-1
                        if j >= grid_H_pos(k) && j <= grid_H_pos(k+1)
                            idx_h = k;
                            break;
                        end
                    end
                    h1 = grid_H_pos(idx_h);
                    h2 = grid_H_pos(idx_h + 1);
                end
                
                % ---- Step3: 获取 2×2 邻域的四个角点 ----
                Q11 = grid_Gain(idx_v, idx_h);
                Q12 = grid_Gain(idx_v + 1, idx_h);
                Q21 = grid_Gain(idx_v, idx_h + 1);
                Q22 = grid_Gain(idx_v + 1, idx_h + 1);
                
                % ---- Step4: 距离权重(向0取整) ----
                dv1 = fix(i - v1);
                dv2 = fix(v2 - i);
                dh1 = fix(j - h1);
                dh2 = fix(h2 - j);
                step_v = fix(v2 - v1);
                step_h = fix(h2 - h1);
                
                if step_h == 0, step_h = 1; end
                if step_v == 0, step_v = 1; end
                
                % ---- Step5: 水平方向线性插值(向0取整) ----
                % R1 = (dh2 * Q11 + dh1 * Q21) / step_h
                temp1 = fix(fix(dh2 * Q11) + fix(dh1 * Q21));
                R1 = fix(temp1 / step_h);
                
                % R2 = (dh2 * Q12 + dh1 * Q22) / step_h
                temp2 = fix(fix(dh2 * Q12) + fix(dh1 * Q22));
                R2 = fix(temp2 / step_h);
                
                % ---- Step6: 垂直方向线性插值(向0取整) ----
                % gain = (dv2 * R1 + dv1 * R2) / step_v
                temp3 = fix(fix(dv2 * R1) + fix(dv1 * R2));
                gain = fix(temp3 / step_v);
                
                % ---- Step7: 应用增益 ----
                % output = fix(input * gain / gain_div)
                input_val = double(i_img(i, j, c));
                o_img(i, j, c) = fix(input_val * gain / gain_div);
            end
        end
    end
    
    % ---- 裁剪到有效范围并转回原类型 ----
    switch input_class
        case 'uint8'
            o_img = uint8(min(max(o_img, 0), 255));
        case 'uint16'
            o_img = uint16(min(max(o_img, 0), 65535));
        case 'int16'
            o_img = int16(min(max(o_img, -32768), 32767));
        case 'double'
            % 保持 double
        otherwise
            o_img = cast(o_img, input_class);
    end
    
end

转载自 CSDN-专业IT技术社区

原文链接:https://blog.csdn.net/zhh1749621866/article/details/166483604

文章来源转载

评论

赞0

评论列表

微信小程序
QQ小程序

关于作者

点赞数:0
关注数:0
粉丝:0
文章:0
关注标签:0
加入于:--