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),则必须提供 fx 和 fy。
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;
}

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

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

相关推荐
richard_yuu13 小时前
OpenCV 实战第 9 篇:Template Matching vs 特征匹配,ROI 定位该选哪个
opencv
golang学习记13 小时前
VSCode多光标迎来重大更新
ide·vscode·编辑器
lank_M13 小时前
截图OCR预处理在普通屏上翻车,Retina截图却没事
图像处理·人工智能·计算机视觉·ocr
sm_9267870514 小时前
RFID 标签打印的技术实现要点与二次开发实践
java·大数据·前端·c++·编辑器
by2099914 小时前
C++ 多态:同一个基类接口,调用不同的函数
开发语言·c++·经验分享·多态
一木 之林14 小时前
Dify学习笔记 01 · 平台入门与实战:部署、五类应用、RAG与MCP(第1-16集)
人工智能·笔记·学习·计算机视觉
colinu14 小时前
C++ 异步任务与线程生命周期:`std::async`、`future`、`thread`、`jthread` 与协作式退出
java·jvm·c++
wuminyu15 小时前
ForkJoinPool窃取线程在扫描其他WorkQueue时的随机采样算法与Phase线程挂起唤醒机制解析
java·linux·c语言·jvm·c++
longlongzihan15 小时前
链表找环:Floyd 判圈算法(LeetCode 141 & 142 )
c++·算法·leetcode·链表
专业程序开发源15 小时前
flask家电故障预测系统92491-计算机课程设计/毕业设计
vscode·python·sql·算法·flask·课程设计