当前位置: 首页 > news >正文

【图像处理】常见图像插值算法与应用

参考文章:
https://blog.csdn.net/Datawhale/article/details/105697264

一、常见插值算法

1.1 最近邻插值算法

原理简介

将目标图像像素映射到原图像后,取距离最近的整数坐标像素值作为该像素的输出值。

例如:目标图像某点投影到原图像的位置为P,与P距离最近的点为Q11,则该点像素值 f(P) = f(Q11)

最近邻插值原理

例子说明

将3×3原图像(用f(x,y)表示)放大到4×4目标图像(用h(x,y)表示),映射公式如下:

最近邻插值映射公式

最近邻插值示例

缺点
  • 放大图像会出现明显马赛克/块状效应
  • 缩小图像会产生严重失真

本质是目标像素仅由原图像单个像素决定,未考虑周围像素的影响。

1.2 双线性插值算法

双线性插值是线性插值在二维空间的推广,通过3次线性插值(X方向2次、Y方向1次),用周围4个像素的加权值确定目标像素,效果更平滑。

1. 线性插值基础

线性插值通过连接两个已知量的直线,计算两者之间未知量的值,公式如下:

f(x)=a1x+a0f(x) = a_1x+a_0 f(x)=a1x+a0

线性插值示意图

线性插值多项式:

线性插值多项式

插值余项(误差):

线性插值余项

函数曲率越大,插值误差越大。

2. 双线性插值步骤

假设已知原图像中4个点 f(x0,y0)、f(x1,y1)、f(x0,y1)、f(x1,y0) 的值,目标是计算这4个点构成的矩形内任意点 f(x,y) 的值:

  1. X方向两次线性插值:分别计算y0和y1行上x处的插值结果
    X方向插值公式

  2. Y方向一次线性插值:用X方向的两个结果计算y处的最终值
    Y方向插值公式

综合公式:

双线性插值综合公式

若4个点为单位正方形顶点(坐标(0,0)、(0,1)、(1,0)、(1,1)),公式可简化为:

简化双线性插值公式

3. 原图像与目标图像的几何中心对齐

直接映射会导致原图像部分像素未参与计算(如9×9缩小到3×3时,右下角像素未被使用),需添加调节因子使两者中心对齐,OpenCV默认采用此方式。

  • 普通映射公式:
    普通映射公式

  • 中心对齐映射公式(添加调节因子 0.5*(src_width/dst_width - 1)):
    中心对齐映射公式

中心对齐前后对比

中心对齐效果

4. OpenCV中cv.resize()的计算逻辑

根据目标像素在原图像中的位置,分三种情况处理:

  • 中间点:正常双线性插值(取周围4个点)
  • 边界点(非顶点):线性插值(如目标点映射到原图像外时,取最近两个点)
  • 四个顶点:最近邻插值(直接取原图像顶点值)

计算示例(3×3原图像放大到4×4):

  • 中间点公式:

中间点双线性插值

  • 边界点公式:
    边界点线性插值

  • 顶点公式:
    顶点最近邻插值

cv.resize()计算示例

2.3 三次样条插值算法

三次样条插值通过分段三次多项式拟合原图像像素,满足“连续可导”条件,插值效果更平滑,但计算复杂度更高。

核心思想

给定n+1个点 a=x0<x1<...<xn=b 及对应函数值 f(xi),在每个区间 [xi, xi+1] 构造三次多项式 Si(x) = aix³ + bix² + cix + di,需满足4n个条件:

  1. 插值条件:Si(xi) = f(xi)Si(xi+1) = f(xi+1)(共2n个)
  2. 连续可导条件:Si'(xi+1) = Si+1'(xi+1)Si''(xi+1) = Si+1''(xi+1)(共2n-2个)
  3. 边界条件(3选1):
    • 自然边界:S0''(x0) = 0Sn-1''(xn) = 0
    • 一阶导数已知:S0'(x0) = f'(x0)Sn-1'(xn) = f'(xn)
    • 周期边界:S0'(x0) = Sn-1'(xn)S0''(x0) = Sn-1''(xn)

通过求解4n个方程组,得到每个多项式的系数,最终计算目标像素值。

三、两种映射方法

图像几何变换的本质是像素坐标映射,分为向前映射和向后映射两种方式。

3.1 向前映射(像素移交映射)

过程
  1. 坐标变换:由原图像像素坐标 (x,y) 推算其在目标图像的坐标 (x',y')(通常为非整数)。
  2. 像素分配:将原图像像素值按权重分配给目标图像中 (x',y') 周围的4个整数坐标点。
缺点
  • 目标图像像素值需叠加多个原图像像素的分配权重,需额外记录权重总和并归一化。
  • 可能出现目标图像“漏点”(部分像素未被分配到值)。

3.2 向后映射(像素填充算法)

过程
  1. 坐标变换:由目标图像像素坐标 (x',y') 反推其在原图像的坐标 (x,y)(通常为非整数)。
  2. 插值计算:通过最近邻、双线性等插值算法,用原图像中 (x,y) 周围的像素值计算目标像素值。
优点
  • 每个目标像素仅需一次插值计算,无需遍历所有原图像像素。
  • 无“漏点”问题,是主流的映射方式(前文插值算法均基于向后映射)。

四、动手实现(基于OpenCV)

OpenCV的cv.resize()函数支持多种插值方式,可直接用于图像缩放,以下是C++和Python的实现示例。

4.1 C++实现

1. cv.resize()函数原型

void cv::resize(InputArray src, OutputArray dst, Size dsize, double fx=0, double fy=0, int interpolation=INTER_LINEAR);

参数说明:

参数含义
src输入原图像
dst输出目标图像
dsize目标图像尺寸(Size(cols, rows),cols为列数,rows为行数)
fx/fy水平/垂直方向的缩放因子(dsize为None时生效)
interpolation插值方式(默认双线性插值INTER_LINEAR)

2. 常用插值方式

插值方式说明适用场景
INTER_NEAREST最近邻插值速度快,对精度要求低的场景
INTER_LINEAR双线性插值(默认)放大/缩小,平衡速度与效果
INTER_CUBIC三次样条插值放大图像,追求高平滑度
INTER_AREA区域插值缩小图像,减少失真

3. 完整代码

#include <opencv2/opencv.hpp>
#include <iostream>using namespace cv;
using namespace std;int main(int argc, char* argv[])
{// 读取原图像(需替换为你的图像路径)Mat img = imread("C:/Users/94890/Desktop/picture/luelue.jpg");if (img.empty()){cout << "无法读取图像" << endl;return 0;}// 获取原图像尺寸int height = img.rows;  // 行数(垂直方向)int width = img.cols;   // 列数(水平方向)// 1. 缩小图像(0.2倍,双线性插值)Size dsize_shrink = Size(round(0.2 * width), round(0.2 * height));Mat shrink;resize(img, shrink, dsize_shrink, 0, 0, INTER_LINEAR);// 2. 放大图像(在缩小图像基础上放大1.5倍,对比两种插值)float fx = 1.5, fy = 1.5;Mat enlarge_nearest, enlarge_linear;resize(shrink, enlarge_nearest, Size(), fx, fy, INTER_NEAREST);  // 最近邻插值resize(shrink, enlarge_linear, Size(), fx, fy, INTER_LINEAR);    // 双线性插值// 显示图像imshow("原图像", img);imshow("0.2倍缩小(双线性)", shrink);imshow("1.5倍放大(最近邻)", enlarge_nearest);imshow("1.5倍放大(双线性)", enlarge_linear);// 保存图像imwrite("C:/Users/94890/Desktop/picture/shrink2.jpg", shrink);imwrite("C:/Users/94890/Desktop/picture/INTER_NEAREST2.jpg", enlarge_nearest);imwrite("C:/Users/94890/Desktop/picture/INTER_LINEAR2.jpg", enlarge_linear);waitKey(0);  // 等待按键关闭窗口destroyAllWindows();return 0;
}

4. 实验结果

  • 原图像:

在这里插入图片描述

  • 0.2倍缩小(双线性):

在这里插入图片描述

  • 1.5倍放大(最近邻):

在这里插入图片描述

  • 1.5倍放大(双线性):

在这里插入图片描述

更多资料:https://github.com/0voice

http://www.dtcms.com/a/499714.html

相关文章:

  • Python爬虫入门:从零到数据采集
  • 免费创建app网站网站推广的基本方法是哪四个
  • 建设网站需要的资金清单建设银行网站会员怎么用
  • 深度学习——YOLO 原理与各版本演化
  • 实验室安全准入考试答案
  • 设计网络网站郑州专业公司网站建设公司
  • 17做网店一样的网站html投票代码
  • 网站建设与维护薪资网页版梦幻西游答题器
  • Form表单._表单元素(本文为个人学习笔记,内容整理自哔哩哔哩UP主【非学者勿扰】的公开课程。 > 所有知识点归属原作者,仅作非商业用途分享)
  • 合肥企业做网站wap游戏中心
  • React 02
  • 营销网站定制深圳设计展2022
  • MPLS技术详解3:LDP实验与配置实践
  • 上海网站seo设计百度地图电脑版网页
  • 建设 政务数据共享网站网页搜索功能怎么实现
  • 手写Spring第4弹: Spring框架进化论:15年技术变迁:从XML配置到响应式编程的演进之路
  • [优选算法专题四.前缀和——NO.26二维前缀和]
  • 青岛做网站皆赴青岛博网站建设方案论文1500
  • SQL入门:同环比计算法全解析
  • 基于51单片机的12路病房呼叫系统设计与实现
  • Netty面试重点-2
  • 手机网站报价表贵州省住房和城乡建设部网站
  • 网站建设名深圳市seo上词多少钱
  • Vue+element ui导入组件封装——超级优雅版
  • Orleans StreamInstruments 作用分析
  • 全虚拟化、半虚拟化和SR-IOV直通-三种I/O虚拟化技术的核心差异
  • 《打造国漫唐风沉浸感:角色衣袂物理模拟的场景化技术方案》
  • 【三维分割】LangSplatV2:高维的语言3DGS,快到450+FPS
  • Kubernetes(k8s) —— 简介
  • 雅安工程交易建设网站建高级网站