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




