OpenCV 笔记(23):图像的缩放——图像的缩放——立方插值、Lanczos 插值算法

这篇具有很好参考价值的文章主要介绍了OpenCV 笔记(23):图像的缩放——图像的缩放——立方插值、Lanczos 插值算法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1.  立方插值

立方插值算法也被称为双三次、双立方插值算法。

1.1 三次插值 (Cubic Interpolation)

先介绍一下三次插值算法,它是一种使用三次多项式拟合一组数据的插值方法。三次插值通常用于图像缩放和重采样。

三次插值的实现方式有很多种,例如牛顿多项式插值、拉格朗日多项式插值、Hermite 三次多项式插值、三次样条插值,每种方式都有其自身的优点和复杂性。

插值多项式的形式

  • 牛顿多项式插值: 使用差商形式来构造插值多项式。

  • 拉格朗日多项式插值: 使用乘积形式来构造插值多项式。

  • Hermite 三次多项式插值: 使用分段三次多项式来构造插值多项式,每个分段多项式满足插值点处的函数值和一阶导数值。

  • 三次样条插值: 也使用分段三次多项式来表示插值多项式,将插值区间划分为多个子区间,在每个子区间上使用三次多项式插值,并要求相邻子区间插值函数在连接处的一阶导数和二阶导数连续。

适用范围

  • 牛顿多项式插值: 适用于数据量较小、插值精度要求不高的场景,如数据拟合、数值计算等。

  • 拉格朗日多项式插值: 适用于理论分析、教学演示等场景。

  • Hermite 三次多项式插值: 适用于需要高精度插值和光滑曲线的场景,如计算机图形学、曲线拟合等。

  • 三次样条插值: 适用于数据量较大、要求插值精度和曲线光滑的场景,如图像处理、工程设计等。

1.2 三次样条插值 (Cubic Spline Interpolation)

我们以三次样条插值为例进行详细说明。

在数值分析这个数学分支中,样条插值是使用一种名为样条的特殊分段多项式进行插值的形式。由于样条插值可以使用低阶多项式样条实现较小的插值误差,这样就避免了使用高阶多项式所出现的龙格现象,所以样条插值得到了流行。

三次样条函数的定义:

函数 ,且在每个小区间 [,] 上是三次多项式,其中 a= < < . . . < = b是给定节点,则称 S(x) 是节点 , , . . . , 上的三次样条函数。

三次样条函数满足:

  • 在每个分段小区间 [, ] 上,,且是一个三次方程

  • 满足插值条件,(i=0,1,...,n)

  • S(x) 曲线是光滑的,S(x)、S'(x)、S''(x) 在[a,b] 是连续的

lanczos插值,opencv,笔记,算法,人工智能,计算机视觉
三次样条函数.png

要求出 S(x),在每个小区间 [, ] 上要确定 4 个待定系数,共有 n 个区间,共 4n 个参数要构建 4n 个方程。

  • 根据插值条件,在节点 (i=1,2,...n-1) 处满足:

以及第一个和最后一个端点分别满足三次方程,总共 2n 个方程

  • 根据 S(x) 在 [a,b] 上一阶导和二阶导数连续,在节点 (i=1,2,...n-1) 处满足连续条件:

n-1 个内部点的一阶导数应该是连续的,即在第 i 区间的末点和第 i+1 区间的起点是同一个点,它们的一阶导数也相等,即:$$S'i(x{i+1}) = S'{i+1}(x{i+1})$$

同理:

总共 2n-2 个方程。

加起来一共 4n-2 个方程,还需再加上 2 个方程就可以确定 S(x)。通常可在区间 [a,b] 端点 a = , b = 处各加一个条件(称为边界条件),可根据实际问题的要求给定。常见有以下三种:

  • 固定边界(Clamped):已知两端的一阶导数值 A 和 B

  • 自然边界(Natural):已知两端的二阶导数为 0

  • 非扭结边界(Not-A-Knot): 强制第一个插值点的三阶导数值等于第二个点的三阶导数值,最后第一个点的三阶导数值等于倒数第二个点的三阶导数值。

1.3 双三次样条插值 (Bicubic Spline Interpolation)

双三次样条插值是在二维空间中使用三次样条函数对图像进行插值。它将图像划分为一个网格,并在每个网格点处使用一个三次样条函数来拟合图像数据。在未知点处,通过对相邻网格点的三次样条函数进行插值来获得插值值。

lanczos插值,opencv,笔记,算法,人工智能,计算机视觉
各种插值函数的对比.png

构造 Bicubic 函数:

对待插值的像素点(x,y),取其附近的 4*4 邻域点(,) (i,j=0,1,2,3)。其插值公式如下:

  1. Lanczos 插值 (Lanczos Interpolation)

Lanczos 插值使用 Lanczos 核函数来计算插值后的像素值。Lanczos 核函数是一种低通滤波器,可以消除缩放过程中产生的混叠现象。

Lanczos 核函数定义如下:

其中,sinc(x) = sin(πx) / (πx),a 是核函数的宽度。

Lanczos 插值的过程如下:

  1. 确定插值点的位置。

  2. 以插值点为中心,在原图像中取一个窗口。

  3. 对窗口中的每个像素,使用 Lanczos 核函数计算其权重。

  4. 将窗口中所有像素的权重和插值值相乘,得到插值点的最终值。

Lanczos 插值公式:

Lanczos 插值的优点

  • 与其他插值方法相比,Lanczos 插值可以产生更清晰、更平滑的图像。

  • Lanczos 插值可以有效地抑制混叠现象,尤其是在图像缩小的情况下。

Lanczos 插值的缺点

  • 与其他的插值方法相比,Lanczos 插值的计算量更大。

  • Lanczos 插值可能会产生轻微的振铃效应,尤其是在图像放大边缘处。

3.  OpenCV 中的 resize() 函数使用示例

OpenCV 封装好了很多图像缩放方法的算法。在 OpenCV C++ 中的 resize() 函数用于调整图像大小,它可以根据指定的尺寸和插值方法对图像进行缩放。

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

第四个参数 fx: 缩放比例,沿 x 轴的缩放因子。 

第五个参数 fx: 缩放比例,沿 y 轴的缩放因子。 

第六个参数 interpolation: 插值方法,常用的插值方法包括:

  • INTER_NEAREST: 最近邻插值

  • INTER_LINEAR: 双线性插值

  • INTER_CUBIC: 4*4 邻域双三次样条插值

  • INTER_AREA: 区域插值

  • INTER_LANCZOS4: 8*8 邻域 Lanczos 插值

下面的例子使用四种插值方法分别对图像进行缩放:

#include <chrono>
#include <opencv2/opencv.hpp>
#define  millisecond 1000000
#define DEBUG_PRINT(...)  printf( __VA_ARGS__); printf("\n")
#define DEBUG_TIME(time_) auto time_ =std::chrono::high_resolution_clock::now()
#define RUN_TIME(time_)  (double)(time_).count()/millisecond

using namespace std;
using namespace cv;

int main() {
    Mat src = imread(".../grass.jpg");
    imshow("src", src);

    Mat nearest,linear,cubic,lanczos;
    double scale = 1.5;
    DEBUG_PRINT("image size[%d,%d],scale=%3.1f", src.rows,src.cols, scale);

    DEBUG_TIME(T0);
    cv::resize(src, nearest, Size(), scale, scale, cv::INTER_NEAREST);//最近邻插值
    DEBUG_TIME(T1);

    cv::resize(src, linear, Size(), scale, scale, cv::INTER_LINEAR); //双线性插值(默认)
    DEBUG_TIME(T2);

    cv::resize(src, cubic, cv::Size(), scale, scale, cv::INTER_CUBIC); //双三次样条插值
    DEBUG_TIME(T3);

    cv::resize(src, lanczos, cv::Size(), scale, scale, cv::INTER_LANCZOS4); //Lanczos 插值
    DEBUG_TIME(T4);

    DEBUG_PRINT("INTER_NEAREST :%3.3fms", RUN_TIME(T1 - T0));
    DEBUG_PRINT("INTER_LINEAR  :%3.3fms", RUN_TIME(T2 - T1));
    DEBUG_PRINT("INTER_CUBIC   :%3.3fms", RUN_TIME(T3 - T2));
    DEBUG_PRINT("INTER_LANCZOS4:%3.3fms", RUN_TIME(T4 - T3));

    imshow("nearest",nearest);
    imshow("linear",linear);
    imshow("cubic",cubic);
    imshow("lanczos",lanczos);

    waitKey(0);
    return 0;
}

执行结果:

image size[427,640],scale=1.5
INTER_NEAREST :0.567ms
INTER_LINEAR  :0.582ms
INTER_CUBIC   :1.433ms
INTER_LANCZOS4:2.002ms
lanczos插值,opencv,笔记,算法,人工智能,计算机视觉
原图和最近邻插值.png
lanczos插值,opencv,笔记,算法,人工智能,计算机视觉
原图和双线性插值.png
lanczos插值,opencv,笔记,算法,人工智能,计算机视觉
原图和双三次样条插值.png
lanczos插值,opencv,笔记,算法,人工智能,计算机视觉
原图和Lanczos插值.png

4.  总结

三次样条插值、双三次样条插值和 Lanczos 插值都是常用的图像缩放插值方法。

三次样条插值是一种分段插值方法,在每个分段内使用三次多项式进行插值。它具有较高的插值精度,但计算量较大。双三次样条插值是三次样条插值的二维扩展,在两个方向上都使用三次样条进行插值,它具有更高的插值精度和计算量。Lanczos 插值是一种基于 Lanczos 滤波器的插值方法,它使用 Lanczos 滤波器对图像进行卷积,从而获得更平滑、更清晰的插值结果。

三种方法各有优缺点,选择哪种方法取决于实际应用场景和需求。

Java与Android技术栈】公众号

关注 Java/Kotlin 服务端、桌面端 、Android 、机器学习、端侧智能

更多精彩内容请关注:文章来源地址https://www.toymoban.com/news/detail-858362.html

到了这里,关于OpenCV 笔记(23):图像的缩放——图像的缩放——立方插值、Lanczos 插值算法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • opencv图像放缩与插值-resize函数

    在OpenCV中,resize函数用于对图像进行尺寸调整(放大或缩小),这个过程中通常需要用到插值方法来计算新尺寸下图像像素的值。插值方法对于放缩的质量有着直接影响。 src:输入图像。 dst:输出图像。尺寸由dsize指定,或者通过fx和fy与源图像的相对关系确定。 dsize:输出

    2024年02月22日
    浏览(36)
  • 【OpenCV • c++】图像几何变换 | 图像缩放

    🚀 个人简介:CSDN「 博客新星 」TOP 10 , C/C++ 领域新星创作者 💟 作    者: 锡兰_CC ❣️ 📝 专    栏: 【OpenCV • c++】计算机视觉 🌈 若有帮助,还请 关注➕点赞➕收藏 ,不行的话我再努努力💪💪💪

    2024年02月16日
    浏览(42)
  • <图像处理> 图像插值算法

    图像插值在图像处理中常用于调整图像尺寸或变形,其目标是根据给定像素点周围像素点的信息来预测该像素点的值。 常见的图像插值算法可以分为两类:自适应和非自适应。自适应的方法可以根据插值内容的特点来进行调整,而非自适应的方法对所有像素点都进行相同的处

    2024年02月07日
    浏览(34)
  • (opencv)图像几何变换——缩放

    图像缩放是指将图像的尺寸变小或变大的过程,也就是减少或增加源图像数据的像素个数。图像缩放一定程度上会造成信息的丢失,因此需要考虑适宜的方法进行操作。 下面介绍两种常用的图像缩放方法的原理及实现 1.基于等间隔提取图像缩放 等间隔提取图像缩放是通过对

    2024年02月16日
    浏览(27)
  • Python Opencv实践 - 图像缩放

         

    2024年02月13日
    浏览(35)
  • 通过opencv实现图像的旋转、缩放

    用opencv来实现图像的旋转与缩放,代码如下: #include iostream #include opencv2/opencv.hpp using namespace cv; //#include opencv.hpp /*** (1). implementing Bilinear Interpolation ***/ bool BilinearInterpolation(     IplImage* pSrcImg,   //@pSrcImg : input gray image     IplImage* pDstImg,  //@pDstImg : output scaled gray image     

    2024年02月22日
    浏览(31)
  • 【OpenCV】图像变换(缩放、平移、旋转、仿射)

    图像变换是指通过对图像进行缩放、平移、旋转、仿射、透视等变换来改变图像的形状和大小。在本篇博客中,我们将详细介绍OpenCV中的图像变换函数,并提供示例代码以帮助读者更好地理解这些函数的使用方法。 缩放变换是指通过改变图像的大小来改变图像的形状。在Op

    2024年02月07日
    浏览(39)
  • 学习笔记:Opencv实现图像特征提取算法SIFT

    2023.8.19 为了在暑假内实现深度学习的进阶学习,特意学习一下传统算法,分享学习心得,记录学习日常 SIFT的百科: SIFT = Scale Invariant Feature Transform, 尺度不变特征转换 全网最详细SIFT算法原理实现_ssift算法_Tc.小浩的博客-CSDN博客 在环境配置中要配置opencv: pip install opencv-c

    2024年02月12日
    浏览(33)
  • 学习笔记:Opencv实现拉普拉斯图像锐化算法

    2023.8.19 为了在暑假内实现深度学习的进阶学习,Copy大神的代码,记录学习日常 图像锐化的百科: 图像锐化算法-sharpen_lemonHe_的博客-CSDN博客 在环境配置中要配置opencv: pip install opencv-contrib-python Code and lena.png:注意你是否在data下由lena.png   附上lena.png  效果所示(解读):

    2024年02月12日
    浏览(32)
  • OpenCV图像的仿射变换、旋转和缩放

    以下是对代码的逐行解释:

    2024年02月13日
    浏览(31)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包