news 2026/7/14 13:39:58

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

作者头像

张小明

前端开发工程师

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

#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(x1+1, src_width); y2 = min(y1+1, 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时也能正常工作,说明算法具有普适性。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/14 13:39:55

从SMS网格到FVCOM:.grd与.2dm文件结构解析与海洋建模实战

1. 从SMS网格到FVCOM模型的基础认知 第一次接触海洋数值模拟时,我被各种网格文件格式搞得晕头转向。直到在项目实践中反复使用SMS和FVCOM,才真正理解.grd和.2dm文件的价值。这两个看似简单的文本文件,实际上承载着整个海洋模型的空间骨架。 S…

作者头像 李华
网站建设 2026/7/14 13:39:57

从键盘到显示屏:给STM32F4计算器加个OLED界面(I2C驱动教程)

从键盘到显示屏:给STM32F4计算器加个OLED界面(I2C驱动教程) 在嵌入式开发中,将计算结果从串口输出到PC端调试助手只是交互的第一步。当我们需要打造一个独立运行的设备时,为其添加本地显示屏就成为刚需。本文将带您从零…

作者头像 李华
网站建设 2026/7/14 13:39:56

智慧无人机城市植被绿化巡检数据集 无人机树木分割 无人机草地识别 城郊植被覆盖度监测 生态环境评估 城市绿化规划 遥感影像语义解析 yolo分割数据集第10591期

埔里居住区-郊区 语义分割数据集文档数据集核心信息表项目内容类别数量3类中文类别树、草地、低植被图像数量260数据集格式YOLO核心应用价值城郊植被覆盖度监测、生态环境评估、城市绿化规划、遥感影像语义解析 数据集概述类别设计 聚焦城郊居住区植被场景,划分树、…

作者头像 李华
网站建设 2026/7/14 13:40:14

手把手教你用OS-AIGC API接入ERNIE和GPT模型(附加密传输实战)

开发者实战:基于OS-AIGC协议实现ERNIE与GPT模型的加密接入 当企业需要同时调用国内外多个大语言模型时,往往会面临接口不统一、传输安全风险等痛点。OS-AIGC协议的出现为开发者提供了一种标准化解决方案,本文将深入解析如何通过该协议实现ERN…

作者头像 李华
网站建设 2026/7/14 13:40:15

GDS Decompiler:Godot引擎逆向工程工具深度解析

GDS Decompiler:Godot引擎逆向工程工具深度解析 【免费下载链接】gdsdecomp Godot reverse engineering tools 项目地址: https://gitcode.com/GitHub_Trending/gd/gdsdecomp 引言:Godot资源逆向工程的必要性 在游戏开发与分析领域,对…

作者头像 李华