直接撸代码前先搞懂双线性插值的核心逻辑——四个相邻像素按距离分配权重。想象把新图像的每个像素点反向映射到原图坐标系,这时候大概率会落在原图四个真实像素之间

直接撸代码前先搞懂双线性插值的核心逻辑——四个相邻像素按距离分配权重。想象把新图像的每个像素点反向映射到原图坐标系,这时候大概率会落在原图四个真实像素之间 #MATLAB编写双线性插值用于缩放图像程序均为自己编写供学习使用。 #程序包含详细注释本人在2020a版本均可运行。先看坐标映射部分的关键代码% 计算目标图像坐标对应到原图的浮点位置 src_x (col - 0.5) * (src_width/dst_width) 0.5; src_y (row - 0.5) * (src_height/dst_height) 0.5;这里有个容易踩坑的点坐标偏移量处理。减0.5是为了将像素坐标系转换为笛卡尔坐标系避免放大时边缘像素被重复采样。这个操作直接影响后续插值的准确性试过不加的话缩放后图像边缘会有明显锯齿。取整数部分和小数部分的操作很关键x1 floor(src_x); y1 floor(src_y); x2 x1 1; y2 y1 1; dx src_x - x1; dy src_y - y1;这里dx和dy就是权重分配的比例系数。注意边界处理——当映射到原图边缘时x2或y2可能超出范围需要做clamp操作x2 min(x2, src_width); y2 min(y2, src_height);这个min函数看起来简单但实测发现漏掉的话缩放某些尺寸的图片时会直接报数组越界错误。调试时遇到过因为忽略边界处理导致程序随机崩溃排查了半小时才定位到问题。#MATLAB编写双线性插值用于缩放图像程序均为自己编写供学习使用。 #程序包含详细注释本人在2020a版本均可运行。核心插值计算部分% 四个角点的像素值注意转换为double类型做运算 v11 double(original_img(y1, x1, :)); v12 double(original_img(y1, x2, :)); v21 double(original_img(y2, x1, :)); v22 double(original_img(y2, x2, :)); % 双线性插值公式 interp_val (1-dx)*(1-dy)*v11 dx*(1-dy)*v12 ... (1-dx)*dy*v21 dx*dy*v22;这里的维度顺序要注意MATLAB图像数据是行在前所以访问原图时坐标是(y,x)。彩色图像需要单独处理每个颜色通道但得益于MATLAB的矩阵运算特性冒号操作符能直接处理三维数组。完整函数封装示例function output_img bilinear_interp(original_img, new_size) % 获取原始尺寸 [src_height, src_width, channels] size(original_img); dst_height new_size(1); dst_width new_size(2); % 初始化输出图像 output_img zeros(dst_height, dst_width, channels, uint8); % 遍历目标图像每个像素 for row 1:dst_height for col 1:dst_width % 坐标映射核心代码块 src_x (col - 0.5) * (src_width/dst_width) 0.5; src_y (row - 0.5) * (src_height/dst_height) 0.5; % 边界保护 x1 max(1, floor(src_x)); y1 max(1, floor(src_y)); x2 min(x11, src_width); y2 min(y11, src_height); % 权重计算 dx src_x - x1; dy src_y - y1; % 四邻域采样 v11 double(original_img(y1, x1, :)); v12 double(original_img(y1, x2, :)); v21 double(original_img(y2, x1, :)); v22 double(original_img(y2, x2, :)); % 混合计算 interp_val (1-dx)*(1-dy)*v11 dx*(1-dy)*v12 ... (1-dx)*dy*v21 dx*dy*v22; % 写入结果 output_img(row, col, :) uint8(round(interp_val)); end end end测试时发现几个有趣现象缩小图像时双线性比最近邻明显更平滑但放大到400%以上时还是能看出模糊。和imresize对比边缘处理有些微差异主要因为MATLAB内置函数可能有更复杂的边界处理机制。运行示例img imread(lena.jpg); resized_img bilinear_interp(img, [800 800]); imshow(resized_img);注意原图尺寸最好是整数倍变化否则缩放比例非整数时需要更复杂的处理。实际测试时用512x512缩到768x768效果最佳而缩到素数尺寸如701x709时也能正常工作说明算法具有普适性。