Ubuntu系统VScode实现opencv(c++)图像放缩与插值

在图像处理与计算机视觉任务中,图像的尺寸调整(即图像放大与缩小)是一项基础而关键的操作。由于图像在分辨率变化时像素点无法一一对应,必须通过插值方法估算新的像素值,以尽可能保留图像的结构与细节。插值方法的选择直接影响到图像缩放后的质量与计算效率。常见的插值策略包括最近邻插值(Nearest Neighbor)、双线性插值(Bilinear Interpolation)、双三次插值(Bicubic Interpolation)以及基于区域或窗函数的高阶插值方法(如 Lanczos)。其中,不同插值方法在重建精度、边缘保留能力与运算复杂度之间存在权衡,因此需要根据具体应用场景合理选取。

插值方法原理与运算方式

下面是常见插值方法的原理、计算公式和区别:

1. 最近邻插值(Nearest Neighbor)

原理:选择距离目标像素最近的一个原始像素,直接赋值。

公式:

特点:非常快, **图像边缘锯齿明显,**无平滑过渡。

2. 双线性插值(Bilinear Interpolation)

原理:在目标点周围找到2×2个像素点,先在x轴方向线性插值,然后在y轴方向再插一次。

公式:

特点:平滑过渡,速度快,效果一般,常用于视频播放、实时处理等场景。

3. 双三次插值(Bicubic Interpolation)

原理:使用周围 4×4 = 16 个像素点参与计算,使用三次多项式(立方插值)进行加权平均。

公式:三次插值的一般形式:

整体过程:

  • 先在x轴方向上对每一行进行三次插值(得到4个值)。

  • 然后对这4个值在y轴方向再插一次。

特点:效果更细腻,边缘更平滑,计算较慢,常用于图像编辑软件(如PS)。

4. 区域插值(Area)

原理:缩小时,把多个像素平均成一个区域的像素(防止别 aliasing 伪影)。

计算方式:对所有被合并区域的像素求加权平均:

特点:适合缩小图像时使用,保留图像整体亮度和颜色。

5. Lanczos 插值

原理:使用 sinc函数(sin(πx)/(πx)) 的加权和来进行高精度插值(窗口大小通常为3或5)

公式(简化):

特点:质量最好(适合摄影放大),运算最复杂,用于离线处理、高质量图像缩放。

插值方式总结

方法 使用点数 质量 运算复杂度 适合场景
INTER_NEAREST(最近邻) 1 最快 实时预览、图像分割
INTER_LINEAR:双线性(默认) 4 视频处理、通用缩放
INTER_CUBIC:双三次(适合放大) 16 中-慢 图像编辑、照片放大
INTER_AREA:区域插值(适合缩小) 中等 图像缩小
INTER_LANCZOS4:Lanczos 插值 最好 摄影图、医学图像处理

相关函数介绍:

复制代码
void cv::resize(
    InputArray src,
    OutputArray dst,
    Size dsize,
    double fx = 0,
    double fy = 0,
    int interpolation = INTER_LINEAR
);
参数 说明
src 输入图像(cv::Mat 类型)
dst 输出图像(缩放后的图像)
dsize 输出图像的大小(cv::Size(width, height))。若为 (0, 0),则必须提供 fxfy
fx 水平方向缩放因子(相对于原图宽度)
fy 垂直方向缩放因子(相对于原图高度)
interpolation 插值方法,决定如何估算目标图像的像素值(见下方说明)

放缩的方式有两种:

1.指定目标大小缩

Size(width, height),直接指定放缩后的宽高;

2.指定缩放因子

给定fx,fy,即可放缩。

复制代码
void Demo::Resize_Demo(Mat &image) 
{
    Mat zoomin,zoomin1;
    int h = image.rows;
    int w = image.cols;
    cout<<"宽:"<<w<<",高:"<<h<<endl;
    resize(image,zoomin,Size(256,256),0,0,INTER_LINEAR);
    resize(image,zoomin1,Size(),0.5,0.5,INTER_LINEAR);
    imshow("zoomin",zoomin);
    cout<<"zoomin宽:"<<zoomin.cols<<",zoomin高:"<<zoomin.rows<<endl;
    imshow("zoomin1",zoomin1);
    cout<<"zoomin1宽:"<<zoomin1.cols<<",zoomin1高:"<<zoomin1.rows<<endl;
}

这里我们打印一下相应图片的宽高,检验是否放缩正确:

这里采用的是最常规的线性放缩,其他插值方式可以自己比较一下区别。

相关推荐
YXXY3131 小时前
算法练习(C++)---双指针
c++
玖笙&3 小时前
✨WPF编程基础【1.3】:XAML 名称空间
c++·wpf·visual studio
玖笙&3 小时前
✨WPF编程基础【1.4】:类型转换器(含示例及源码)
c++·wpf·visual studio
Min;6 小时前
cesium-kit:让 Cesium 开发像写 UI 组件一样简单
javascript·vscode·计算机视觉·3d·几何学·贴图
yong99907 小时前
安装MariaDB服务器流程介绍在Ubuntu 22.04系统
服务器·ubuntu·mariadb
曾经的三心草7 小时前
OpenCV2-图像基本操作-阈值与平滑处理-形态学-梯度运算
python·opencv
Ling_Ze8 小时前
visual studio快捷键
c++
Stanford_11068 小时前
关于单片机的原理与应用!
c++·单片机·嵌入式硬件·微信小程序·微信公众平台·微信开放平台
雪域迷影8 小时前
C++/C#游戏开发引擎和2D/3D图形库
c++·3d·c#
bing_feilong8 小时前
树莓派4B+ubuntu20.04:不插显示器能不能正常开机?
ubuntu