首页 > 其他分享 >OpenCV插值运算---记录贴

OpenCV插值运算---记录贴

时间:2025-01-10 11:32:41浏览次数:3  
标签:缩放 插值 线性插值 --- OpenCV 因子 图像 cv

在 Qt 中结合 OpenCV 进行线性插值,并将 3x3 的数据扩展为 15x15 的图像显示,步骤可以分为以下几步:

1. 安装 OpenCV

2. 创建 3x3 数据并进行线性插值

我们可以使用 OpenCV 的 cv::resize 函数来执行线性插值,并且可以选择将数据从 3x3 转换为 15x15。

3. 转换为图像并显示

使用 QImage 将扩展后的数据转换为图像,并通过 QLabel 显示图像。

示例代码:

假设你已经有了一个 3x3 的数据数组,并希望将其扩展到 15x15,然后显示为图像。

#include <QCoreApplication>
#include <QImage>
#include <QLabel>
#include <QPixmap>
#include <opencv2/opencv.hpp>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    // 初始化一个 3x3 的数据(可以是任意数字)
    cv::Mat mat3x3 = (cv::Mat_<float>(3, 3) << 1.0f, 2.0f, 3.0f,
                                              4.0f, 5.0f, 6.0f,
                                              7.0f, 8.0f, 9.0f);

    // 创建一个 15x15 的空矩阵
    cv::Mat mat15x15;

    // 使用 OpenCV 进行线性插值,将 3x3 扩展到 15x15
    cv::resize(mat3x3, mat15x15, cv::Size(15, 15), 0, 0, cv::INTER_LINEAR);

    // 将 OpenCV 的 Mat 转换为 QImage
    // OpenCV 是以 BGR 格式存储图像,QImage 需要 RGB 格式
    // 如果需要将浮动数值转换成图像,通常需要进行适当的缩放和归一化
    mat15x15.convertTo(mat15x15, CV_8UC1, 255.0 / 9.0); // 归一化到 0-255 范围

    // 转换为 QImage(8位灰度图像)
    QImage img(mat15x15.data, mat15x15.cols, mat15x15.rows, mat15x15.step, QImage::Format_Grayscale8);

    // 显示图像
    QLabel label;
    label.setPixmap(QPixmap::fromImage(img));
    label.show();

    return a.exec();
}

代码解析:

  1. 创建 3x3 数据: 我们使用 OpenCV 的 cv::Mat 来创建一个 3x3 的矩阵并填充数据。这里填充的是浮动数值,可以根据需要填充其他数据。
  2. 线性插值扩展到 15x15: 使用 OpenCV 的 cv::resize 函数将 3x3 的矩阵扩展为 15x15,并指定 cv::INTER_LINEAR 方法进行线性插值。
  3. 转换数据为图像:
    • 我们首先将矩阵的值通过 convertTo 函数转换为 8UC1 类型(即 8 位单通道图像)。同时通过 255.0 / 9.0 对数据进行归一化,使得值范围适合显示(假设原始值是 0 到 9)。
    • 然后,将 OpenCV 的 cv::Mat 数据转为 QImage,由于是灰度图,所以格式使用 QImage::Format_Grayscale8
  4. 显示图像: 使用 QLabel 来显示图像,通过 QPixmap::fromImage 将 QImage 转换为 QPixmap,然后显示在 QLabel 上。

显示效果:

当你运行这个程序时,你会看到一个 15x15 的灰度图像,数据通过线性插值从 3x3 的数据扩展而来。

说明:

  • cv::resize: OpenCV 的 resize 函数可以通过指定目标尺寸和插值方法来调整图像的大小。常用的插值方法包括 INTER_LINEAR(线性插值)、INTER_CUBIC(三次插值)等。
  • 数据归一化: 如果你处理的是浮动数据,必须确保在转换为图像之前对数据进行适当的归一化,使其适合于显示(例如,灰度图像的值应该在 0 到 255 之间)。

扩展:

  • 如果你有不同的数据类型(如图像数据),也可以根据需要调整代码,将其扩展为多通道图像(如 RGB 图像)。
  • 你还可以根据需要选择不同的插值方法来获得不同的效果,尤其在图像处理任务中,线性插值、立方插值等方式会影响图像的质量。

除了 线性插值,常见的图像插值方法还有很多。不同的插值方法会产生不同的效果,适用于不同的应用场景。以下是一些常见的插值方法,尤其在图像缩放和变换中经常使用:

1. 最邻近插值(Nearest Neighbor Interpolation)

  • 原理: 这种方法选择离目标像素最近的一个源像素的值来填充目标像素。简单来说,就是复制最近邻的像素值。
  • 优点: 算法简单,计算速度快,适合于快速处理。
  • 缺点: 结果通常会比较粗糙,尤其是图像缩放倍数较大时,可能会出现锯齿状边缘。
  • 使用场景: 当需要非常快速的插值或图像的质量要求不高时(例如二值化图像或一些特殊效果)。

OpenCV实现: cv::INTER_NEAREST

2. 双线性插值(Bilinear Interpolation)

  • 原理: 双线性插值使用周围四个像素的加权平均来计算目标像素值。权重通常基于与目标像素的距离来确定。
  • 优点: 相比最邻近插值,双线性插值会得到更平滑的结果,避免了锯齿状边缘。
  • 缺点: 比最邻近插值稍慢,但在大多数应用中仍然非常快速。
  • 使用场景: 适用于大多数普通的图像处理任务,尤其是图像缩放时。

OpenCV实现: cv::INTER_LINEAR

3. 立方插值(Cubic Interpolation)

  • 原理: 立方插值考虑了目标像素周围16个像素的加权平均,通常使用三次方函数来计算目标像素的值。相较于双线性插值,它可以产生更平滑的插值效果。
  • 优点: 可以产生更平滑和更自然的图像效果,特别是在图像放大时。
  • 缺点: 计算量较大,速度比双线性插值慢一些,但结果质量更好。
  • 使用场景: 在对图像质量有较高要求的场合,特别是在图像放大时,效果更加自然。

OpenCV实现: cv::INTER_CUBIC

4. 拉格朗日插值(Lagrange Interpolation)

  • 原理: 拉格朗日插值是一种基于多项式的插值方法,通常用来从一个已知的数据点集估算出目标值。它在目标点周围的多个已知点之间找到一个最佳拟合的多项式。
  • 优点: 能够精确地通过所有数据点,但计算复杂度较高。
  • 缺点: 在图像处理上不常用,主要用于数值数据插值。
  • 使用场景: 适用于高精度数据插值,但在图像处理中不常见。

5. 双三次插值(Bicubic Interpolation)

  • 原理: 双三次插值是立方插值的一种扩展,考虑了图像目标像素周围16个像素的权重,并且基于三次多项式进行插值。它不仅平滑,还能避免线性插值时可能产生的模糊现象。
  • 优点: 图像质量非常高,能有效避免模糊。
  • 缺点: 计算量大,速度较慢。
  • 使用场景: 适用于需要较高图像质量的场合,比如照片编辑和视觉效果处理。

OpenCV实现: cv::INTER_CUBIC

6. Lanczos 插值

  • 原理: Lanczos 插值基于 sinc 函数(正弦积分函数)。它是高质量的插值方法,特别适合用于缩小图像,同时可以减少高频噪声和模糊。Lanczos 插值使用周围的多个像素进行计算,能够提供非常高的图像质量。
  • 优点: 结果非常清晰,边缘锐利,适合图像的高质量缩放,尤其在图像减小时表现优异。
  • 缺点: 计算量较大,比其他插值方法要慢。
  • 使用场景: 高质量图像缩放,特别是在图像尺寸缩小时。

OpenCV实现: cv::INTER_LANCZOS4(Lanczos-4 插值)

7. 样条插值(Spline Interpolation)

  • 原理: 样条插值使用分段多项式来拟合数据点,它在处理时能确保每个数据段之间的平滑过渡。样条插值可以提供比线性插值更平滑的效果,常用于对数据点进行平滑插值。
  • 优点: 生成非常平滑的结果,特别适合处理光滑变化的数据。
  • 缺点: 对计算的要求较高,速度较慢。
  • 使用场景: 常用于曲线拟合、图像平滑等领域。

8. 高斯插值(Gaussian Interpolation)

  • 原理: 高斯插值使用高斯函数对数据进行平滑处理,可以在保持图像边缘的同时减少噪声。
  • 优点: 适用于平滑数据或图像,减少噪声和细节丢失。
  • 缺点: 可能会模糊图像的细节,特别是当图像包含高频信息时。
  • 使用场景: 图像去噪、平滑处理等。

在 OpenCV 中使用不同插值方法:

OpenCV 提供了多种插值方法,通常在使用 cv::resize 函数时指定插值方式。例如:

cv::resize(src, dst, cv::Size(new_width, new_height), 0, 0, cv::INTER_NEAREST); // 最邻近插值
cv::resize(src, dst, cv::Size(new_width, new_height), 0, 0, cv::INTER_LINEAR); // 双线性插值
cv::resize(src, dst, cv::Size(new_width, new_height), 0, 0, cv::INTER_CUBIC); // 立方插值
cv::resize(src, dst, cv::Size(new_width, new_height), 0, 0, cv::INTER_LANCZOS4); // Lanczos 插值

总结:

  • 最邻近插值:快速,但质量差,适用于低质量需求或实时处理。
  • 线性插值:常用且平滑,适用于大多数应用。
  • 立方插值/双三次插值:高质量插值,适用于对图像质量要求较高的场合。
  • Lanczos 插值:非常高质量,适合图像缩小。
  • 样条插值:主要用于数据拟合,不常用于图像处理。
  • 高斯插值:适合平滑和去噪。

cv::resize 函数中,传参中的两个 0缩放因子,即在 x 轴和 y 轴上的缩放比例。这两个参数通常用于对图像进行缩放时提供相对缩放比例。

具体来说,cv::resize 的函数原型为:

cv::resize(
    cv::InputArray src,          // 输入图像
    cv::OutputArray dst,         // 输出图像
    cv::Size dsize,              // 目标图像大小 (宽度和高度)
    fx,                          // 水平缩放因子 (0 表示不修改)
    fy,                          // 垂直缩放因子 (0 表示不修改)
    interpolation                // 插值方法
);

解释:

  • dsize:目标图像的尺寸 (cv::Size(new_width, new_height)),表示输出图像的宽度和高度。
  • fx:水平缩放因子,表示图像在 x 轴方向上的缩放比例。
  • fy:垂直缩放因子,表示图像在 y 轴方向上的缩放比例。
  • interpolation:插值方法,用于决定图像的重采样方式,譬如 cv::INTER_NEARESTcv::INTER_LINEAR 等。

参数为 0, 0 的含义:

  • 当你将 fx 和 fy 都设置为 0 时,表示 没有指定缩放比例。此时,OpenCV 会根据 dsize 中的目标尺寸来计算对应的缩放比例。
  • 换句话说,0 的意思是“自动计算”,会根据目标尺寸 dsize 和原图像尺寸 src 来确定图像应该如何缩放。

举个例子:

cv::resize(src, dst, cv::Size(new_width, new_height), 0, 0, cv::INTER_NEAREST);
  • src 是输入图像。
  • dst 是输出图像。
  • cv::Size(new_width, new_height) 是目标图像的大小。
  • 0, 0 表示 OpenCV 会根据目标尺寸 cv::Size(new_width, new_height) 自动计算图像的缩放比例(即,水平方向和垂直方向的缩放因子)。
  • cv::INTER_NEAREST 是使用最近邻插值法进行缩放。

总结:

  • 如果传递 0,它们表示“基于目标尺寸自动计算缩放因子”。
  • dsize(目标大小)会作为主输入,fx 和 fy 会被忽略,因此这两个参数可以用来指定一个 固定的目标尺寸,并由 OpenCV 根据源图像的尺寸自动计算缩放比例。

缩放因子的大小对图像插值有显著影响,特别是在图像的 缩放比例较大或较小时,插值的质量和效果会有所不同。具体来说,缩放因子影响以下几个方面:

1. 缩放因子影响图像质量

  • 放大时(缩放因子 > 1):

    • 高缩放因子(例如,放大4倍、8倍或更高)通常会导致图像 模糊 或 失真,尤其在使用简单插值方法时(如最邻近插值)。即使使用高质量的插值方法(如双三次插值或Lanczos插值),也可能会出现细节丢失或图像变得不清晰。
    • 插值算法的作用:插值方法决定了如何在新增的像素位置计算值。例如,双线性插值会考虑相邻像素的加权平均,而双三次插值则会考虑更多像素并生成更平滑的结果。在高缩放因子下,好的插值方法能有效减少模糊和锯齿状的边缘,但计算量也相应增加。
  • 缩小时(缩放因子 < 1):

    • 低缩放因子(例如,缩小到原图的1/2、1/4)通常会导致 图像丢失细节,尤其是当图像被压缩时,细节和纹理可能会丢失。
    • 插值方法的影响:缩小图像时,较好的插值方法(如Lanczos插值)能够较好地保留重要的视觉特征(如边缘和纹理),而使用简单的插值方法(如最邻近插值)会导致图像变得模糊或者细节丢失。

2. 缩放因子与插值方法的关系

  • 低缩放因子

    • 当图像尺寸大幅缩小时(比如缩小到原图的1/4或更小),某些插值方法可能导致图像细节丢失或出现不自然的模糊。例如,最邻近插值在图像缩小时可能会导致边缘粗糙,而双线性或立方插值能够平滑图像。
    • Lanczos插值 是一种非常适合用于图像缩小的插值方法,能够更好地保留图像的细节和结构,尤其在缩小倍数较大的情况下(例如将图像缩小为原始尺寸的1/4或更小)效果更佳。
  • 高缩放因子

    • 当图像被放大时,插值方法对最终结果的影响更加显著。简单的插值方法(如最邻近插值)可能会导致图像产生锯齿状的边缘和块状的失真,而较高级的插值方法(如双三次插值和Lanczos插值)则会提供更平滑的效果。
    • 双三次插值 和 Lanczos插值 通常能在大幅放大图像时获得更好的视觉效果,因为它们会考虑更多周围的像素并平滑图像的细节。

3. 插值方法选择与缩放因子的配合

  • 最邻近插值(Nearest Neighbor):当图像缩放因子较小时(例如缩小图像),最邻近插值可能还算有效,但放大时则容易出现锯齿状的边缘。该方法适用于需要快速处理并且对图像质量要求不高的情况。

  • 双线性插值(Bilinear Interpolation):在大多数情况下,双线性插值能够在缩小或放大时提供比最邻近插值更好的效果。它的计算量适中,结果较平滑。

  • 双三次插值(Bicubic Interpolation):对于较大的缩放因子(无论是放大还是缩小),双三次插值通常能够提供更高质量的结果。它通过考虑更多的邻近像素,使得图像更平滑,细节保持得更好,但计算开销也较大。

  • Lanczos 插值:当图像缩放因子较大时(尤其是缩小时),Lanczos 插值表现尤为优秀。它能够在缩小时更好地保留图像的细节和边缘,同时在放大时也能减少模糊和锯齿问题。

4. 对锯齿状边缘的影响

  • 低缩放因子(如缩小到1/4或更小):使用简单的插值方法(如最邻近插值)时,可能会导致图像边缘出现锯齿状的效果。而使用更精细的插值方法(如双三次插值或Lanczos插值),能够在图像缩小时避免锯齿状边缘。
  • 高缩放因子(如放大4倍或更大):对于图像放大,简单的插值方法(如最邻近插值)会导致图像边缘显得非常不平滑,出现明显的锯齿。采用双线性或双三次插值方法,能够在某种程度上减轻这种锯齿效果。

5. 计算复杂度

  • 低缩放因子时,简单的插值方法(如最邻近插值、双线性插值)计算量较小,适合实时应用。
  • 高缩放因子时,如使用双三次或Lanczos插值时,计算量较大,但在保留图像质量方面具有明显优势。

总结:

  • 缩放因子较大(图像放大时):高质量插值方法(如双三次插值、Lanczos插值)效果更好,能够避免锯齿和模糊。
  • 缩放因子较小(图像缩小时):低缩放因子时,双三次插值和Lanczos插值仍然能提供较好的效果,减少图像细节丢失。
  • 插值方法的选择:如果需要在缩放时保持较高的图像质量,应选择计算量较大的插值方法(如双三次、Lanczos),尤其在图像需要大幅度缩放时(无论是放大还是缩小)。

不同的缩放因子要求根据目标图像的质量需求选择合适的插值方法,以平衡计算复杂度和图像效果。

标签:缩放,插值,线性插值,---,OpenCV,因子,图像,cv
From: https://blog.csdn.net/m0_63482948/article/details/145052626

相关文章

  • go-zero使用自定义模板实现统一格式的 body 响应
    前提go环境的配置、goctl的安装、go-zero的基本使用默认都会需求go-zero框架中,默认使用goctl命令生成的代码并没有统一响应格式,现在使用自定义模板的方式实现统一响应格式:{"code":0,"msg":"OK","data":{}}步骤1、下载模板goctltemplateinit下载完......
  • 攻防世界 - Misc - Level 2 | funny_video
    关注这个靶场的其它相关笔记:攻防世界(XCTF)——靶场笔记合集-CSDN博客0x01:考点速览本题的考察的是MISC中的音频隐写,要想过此关,你需要知道以下知识点:使用MKVToolNix查看非默认声道并导出。(xxx.mp3)使用Audacity查看音频的“频谱图”。0x02:WriteUP将附件从靶......
  • 攻防世界 - Misc - Level 2 | Hear-with-your-Eyes
    关注这个靶场的其它相关笔记:攻防世界(XCTF)——靶场笔记合集-CSDN博客0x01:考点速览本题考察的是Misc中的音频隐写题,通过本关我们可以学习到以下知识点:如何使用Audacity查看音频”频谱图“。0x02:WriteUP将附件从靶场中下载下来,是一个gz格式的文件,其实也就是L......
  • el-table el-table__cell gutter 占位宽度如何修改;滚动条导致表格线条不对齐问题
    实测有效!!!这里display:table-cell,一定不要设置成block,很多博客都写设置成block,实测导致gutter外层占位莫名17px,还找不到地方修改<stylescopedlang="scss">//解决表头固定,出现错位问题/deep/.el-table{th.gutter,colgroup.gutter{//这里一定不要display:block......
  • 机器学习 - 如何理解函数集合中的准确性、召回率、F1分数呢?
    在机器学习中,准确性(Accuracy)、召回率(Recall)、和F1分数是常用的模型性能评价指标,它们从不同的角度衡量模型的表现。要理解它们,首先需要了解它们的定义和适用场景:1.基本概念:分类问题中的混淆矩阵混淆矩阵是分类问题中计算这些指标的基础,它展示了模型预测结果与实际标签之间的......
  • ur3+robotiq ft sensor+robotiq 2f 140配置rviz仿真环境-
    原文地址:ur3+robotiqftsensor+robotiq2f140配置rviz仿真环境ur3+robotiqftsensor+robotiq2f140配置rviz仿真环境搭建环境:ubuntu:20.04ros:Noneticsensor:robotiq_ft300gripper:robotiq_2f_140_gripperUR:UR3在安装sensor和gripper之前,先简单配置一下UR机械臂的......
  • (即插即用模块-Attention部分) 三十四、(2022) FACMA 频率感知跨通道注意力
    文章目录1、Frequency-AwareCross-ModalityAttention2、WeightedCross-ModalityFusionmodule3、代码实现paper:FCMNet:Frequency-awarecross-modalityattentionnetworksforRGB-DsalientobjectdetectionCode:https://github.com/XiaoJinNK/FCMNet1、......
  • (即插即用模块-Attention部分) 三十三、(2021) SPA 显著位置注意力
    文章目录1、SalientPositionsAttention2、代码实现paper:SalientPositionsbasedAttentionNetworkforImageClassificationCode:https://github.com/likyoo/SPANet1、SalientPositionsAttention在现有的自注意力机制中,其建模长距离依赖关系方面表现出色......
  • JS-26 字符串方法_trim()
    trim方法用于去除字符串两端的空格,返回一个新的字符串,不改变源字符串'zifuchuan'.trim()//"helloworld" 该方法去除的不仅仅是空格,还包括制表符(\t、\v)、换行符(\n)和回车符(\r)'\r\zifuchuan\t'.trim()//'zifuchuan' ES6扩展方法,trimEnd和trimStart()方法" zifuchua......
  • 洛谷题单指南-线段树的进阶用法-P3157 [CQOI2011] 动态逆序对
    原题链接:https://www.luogu.com.cn/problem/P3157题意解读:长度为n的序列,序列是1~n的排列,一共m个删除操作,每一个删除之前输出逆序对。解题思路:要计算静态的逆序对,可以通过树状数组、权值线段树等方式,时间复杂度都是O(nlogn)要计算动态的逆序对,算上每一次删除,暴力做法需要O(mnlo......