Opencv 插值方法 总结

一、概括

面试的时候问到了一个图,就是如何将一个算子放缩??我第一反应是resize(),但是后来我转念一想,人家问的是插值方式,今天来总结一下

最邻近插值法原理分析及c++实现_最临近插值法-CSDN博客

我们总常用的插值方式,临近插值 、双线性插值、三次样条插值、拉格朗日插值、多项式、区域插值等

下面我们就一步一步的将其概括出来

二、临近插值

最邻近插值法 : 其核心思想是选取离目标点最近的点作为待插入的新值点

如图:其他的Q12 Q22 Q11  Q21都是已知的像素点,要求插入一个点P

从上图可以看出P到 Q12 最近,那么我就直接将P=Q12

计算两份方向上的缩放后的图像

	int dst_cols = round(src.cols * sx);  // 列  ==xint dst_rows = round(src.rows * sy);  // 行==y

有3*3 --》5*5 ,那么我们可以计算P(3,3)

 sx=5/3

那么 new_i=3/sx=round(9/5)=2;

        new_j=3/sy=round(9/5)=2

P(3,3)=src(2,2)=83

void NearestInterpolation(cv::Mat& src, cv::Mat& dst, float sx, float sy)
{//放大的因子 x,y 方向可能会不一样的// 放缩之后的图像的大小int dst_cols = round(src.cols * sx);  // 列  ==xint dst_rows = round(src.rows * sy);  // 行==ydst = cv::Mat(dst_rows, dst_cols, src.type());//灰度图像处理if (src.channels() == 1){for (int i = 0; i < dst.rows; i++){for (int j = 0; j < dst.cols; j++){//插值计算,取最近值插入到新的图像中int i_new = round(i / sy);int j_new = round(j / sx);if (i_new > src.rows - 1){i_new = src.rows - 1;}if (j_new > src.cols - 1){j_new = src.cols - 1;}dst.at<uchar>(i, j) = src.at<uchar>(i_new, j_new);}}}//彩色图像处理else {for (int i = 0; i < dst.rows; i++){for (int j = 0; j < dst.cols; j++){int i_new = round(i / sy);int j_new = round(j / sx);if (i_new > src.rows - 1){i_new = src.rows - 1;}if (j_new > src.cols - 1){j_new = src.cols - 1;}//Bdst.at<cv::Vec3b>(i, j)[0] = src.at<cv::Vec3b>(i_new, j_new)[0];//Gdst.at<cv::Vec3b>(i, j)[1] = src.at<cv::Vec3b>(i_new, j_new)[1];//Rdst.at<cv::Vec3b>(i, j)[2] = src.at<cv::Vec3b>(i_new, j_new)[2];}}}
}

优点:简单、计算量小。
缺点:效果不好,图像放大后失真现象严重。

三、线性插值 

resize() 函数默认的就是双线性插值,

我们先看线性插值:

线性插值:


然后我们将上面的做个变性,就写成了如下:

 双线性插值原理

顾名思义就是做两次线性插值,但是其实是3次

c++ opencv图像双线性插值的应用方法 - 知乎

案例:

 算法流程:

1、先通过每个方向的缩放因子,计算出我们缩放后的图像的大小

2、计算通过新图像的row_new 和col_new 推算出原图像中的四个点 的位置并获得四个点的灰度值

3、通过上面拿到的公式来计算新插入的值

4、计算边界的特殊值


/// <summary>
/// 双线性插值处理
/// </summary>
/// <param name="src"></param>
/// <param name="scale_x"></param>
/// <param name="scale_y"></param>
/// <param name="dst"></param>
void DoubleLineInterpolate(Mat src, double scale_x,double scale_y, Mat& dst)
{int result_H = static_cast<int>(src.rows * scale_y);int result_W = static_cast<int>(src.cols * scale_x);dst = Mat::zeros(cv::Size(result_W, result_H), src.type());for (int i = 0; i < dst.rows; i++){for (int j = 0; j < dst.cols; j++){// 非常重要的一步就是用新的图像来推算出原来图像的四个像素的位置和灰度值double before_x = double(j + 0.5) / scale_x - 0.5f;double before_y = double(i + 0.5) / scale_y - 0.5;int top_y = static_cast<int>(before_y);int bottom_y = top_y + 1;int left_x = static_cast<int>(before_x);int right_x = left_x + 1;//计算变换前坐标的小数部分double u = before_x - left_x;double v = before_y - top_y;// 如果计算的原始图像的像素大于真实原始图像尺寸if ((top_y >= src.rows - 1) && (left_x >= src.cols - 1)){//右下角dst.at<uchar>(i, j) = (1. - u) * (1. - v) * src.at<uchar>(top_y, left_x);}else if (top_y >= src.rows - 1){//最后一行dst.at<uchar>(i, j)= (1. - u) * (1. - v) * src.at<uchar>(top_y, left_x)+ (1. - v) * u * src.at<uchar>(top_y, right_x);}else if (left_x >= src.cols - 1){dst.at<uchar>(i, j)= (1. - u) * (1. - v) * src.at<uchar>(top_y, left_x)+ (v) * (1. - u) * src.at<uchar>(bottom_y, left_x);}else{dst.at<uchar>(i, j)= (1. - u) * (1. - v) * src.at<uchar>(top_y, left_x)+ (1. - v) * (u)*src.at<uchar>(top_y, right_x)+ (v) * (1. - u) * src.at<uchar>(bottom_y, left_x)+ (u) * (v)*src.at<uchar>(bottom_y, right_x);}}}  
}

三、双三次插值(Bicubic interpolation)

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

样条插值

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

三次样条函数的定义

 https://blog.51cto.com/u_16099178/8790325

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

这个理解很重要 

 

四、区域插值(Area interpolation)


区域插值算法主要分两种情况,缩小图像和放大图像的工作原理并不相同。


·缩小图像


如果图像缩小的比例是整数倍,在调用INTER LINEAR EXACT插值算法时,如果图像的密和高的缩小比例都是2、而且图像的通道数不是2、实际上会调用INTER AREA、在调用INTER LNEAR时,如果图像的亮和高的缩小比例都是2,实际上是会调用INTER AREA。
INTER AREA实际上是个box filter,类似于均值滤波器。


放大图像


如果放大图像的比例是整数倍,与最近邻插值相似。
如果放大的比例不是整数倍,则会采用线性插值。 

五、Lanczos 插值

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/274713.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【数据库】Oracle内存结构与参数调优

Oracle内存结构与参数调优 Oracle 内存结构概览oracle参数配置概览重要参数&#xff08;系统运行前配置&#xff09;:次要参数&#xff08;可在系统运行后再优化调整&#xff09;: Oracle数据库服务器参数如何调整OLTP内存分配操作系统核心参数配置Disabling ASMM&#xff08;禁…

【图文详解】Maven Helper插件解决Maven冲突

文章目录 插件问题解决过程 在面试中解决问题的能力和思路是考察的重点&#xff0c;面试官问会问我们有没有解决过maven冲突。以下造了一个maven冲突&#xff0c;手把手教学如何解决Maven冲突。 插件 插件在idea插件中搜索Maven Helper 问题 解决过程 根据上面日志知道是log…

让生活更加精致的APP?

晚上好&#xff0c;今天博主来介绍几款帮助你条理生活的APP&#xff0c;让你的生活更加精致&#xff0c;充满仪式感。 一&#xff0e;格志日记 一款以“格子”的方式记录日记的APP&#xff0c;非常简单明了&#xff0c;用户可以依据自己的喜好&#xff0c;来自由定义或者删除格…

力扣刷题Days16(js)-67二进制求和

目录 1,题目 2&#xff0c;代码 2.1转换进制数 2.2模拟加法 3&#xff0c;学习与总结 Math.floor() 模拟加法思路回顾 重点复习巩固 模拟加法的思路和学习位运算&#xff1b; 今天没精力了&#xff0c;先休息 1,题目 给你两个二进制字符串 a 和 b &#xff0c;以二进制…

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的手写数字和符号识别(深度学习训练+UI界面+训练数据集)

摘要&#xff1a;开发手写数字和符号识别对于智能交互系统具有关键作用。本篇博客详细介绍了如何运用深度学习构建一个手写数字和符号识别&#xff0c;并提供了完整的实现代码。该系统基于强大的YOLOv8算法&#xff0c;并对比了YOLOv7、YOLOv6、YOLOv5&#xff0c;展示了不同模…

四元数(Quaternion)的一些性质

四元数(Quaternion)是用于三维旋转和定向的四部分组成的超复数&#xff0c;超复数简单理解就是比abi这样的复数更复杂的复数&#xff0c;其中abi这样的复数我们也可以叫做二元数&#xff0c;表示复平面的一点&#xff0c;对于熟悉欧拉公式的朋友就知道&#xff0c;也可以看成是…

LeetCode 每日一题 Day 95-101

2917. 找出数组中的 K-or 值 给你一个整数数组 nums 和一个整数 k 。让我们通过扩展标准的按位或来介绍 K-or 操作。在 K-or 操作中&#xff0c;如果在 nums 中&#xff0c;至少存在 k 个元素的第 i 位值为 1 &#xff0c;那么 K-or 中的第 i 位的值是 1 。 返回 nums 的 K-o…

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的田间杂草检测系统(深度学习模型+UI界面+Python代码+训练数据集)

摘要&#xff1a;开发用于田间杂草识别的系统对提高农业运营效率和提升作物产出至关重要。本篇文章详尽阐述了如何应用深度学习技术开发一个用于田间杂草识别的系统&#xff0c;并附上了完备的代码实现。该系统基于先进的YOLOv8算法&#xff0c;并对比了YOLOv7、YOLOv6、YOLOv5…

【c 语言 】位操作符详解

&#x1f388;个人主页&#xff1a;豌豆射手^ &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 &#x1f917;收录专栏&#xff1a;C语言 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共同学习、交流进步&…

20240312-1-Graph(图)

Graph(图) 在面试的过程中,一般不会考到图相关的问题,因为图相关的问题难,而且描述起来很麻烦. 但是也会问道一下常见的问题,比如,最短路径,最小支撑树,拓扑排序都被问到过. 图常用的表示方法有两种: 分别是邻接矩阵和邻接表. 邻接矩阵是不错的一种图存储结构,对于边数相对顶点…

【机器学习300问】33、决策树是如何进行特征选择的?

还记得我在【机器学习300问】的第28问里谈到的&#xff0c;看决策树的定义不就是if-else语句吗怎么被称为机器学习模型&#xff1f;其中最重要的两点就是决策树算法要能够自己回答下面两问题&#xff1a; 该选哪些特征 特征选择该选哪个阈值 阈值确定 今天这篇文章承接上文&…

学习 考证 帆软 FCP-FineBI V6.0 考试经验

学习背景&#xff1a; 自2024年1月起&#xff0c;大部分时间就在家里度过了&#xff0c;想着还是需要充实一下自己&#xff0c;我是一个充满热情的个体。由于之前公司也和帆软结缘&#xff0c;无论是 Fine-Report 和 Fine-BI 都有接触3年之久&#xff0c;但是主要做为管理者并…

第四弹:Flutter图形渲染性能

目标&#xff1a; 1&#xff09;Flutter图形渲染性能能够媲美原生&#xff1f; 2&#xff09;Flutter性能优于React Native? 一、Flutter图形渲染原理 1.1 Flutter图形渲染原理 Flutter直接调用Skia 1&#xff09;Flutter将一帧录制成SkPicture&#xff08;skp&#xff…

55. 跳跃游戏(力扣LeetCode)

文章目录 55. 跳跃游戏贪心每一次都更新最大的步数 取最大跳跃步数&#xff08;取最大覆盖范围&#xff09; 55. 跳跃游戏 给你一个非负整数数组 nums &#xff0c;你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后…

【案例】IPC 中的WinCC RT Advanced PC项目,如何下载及开机自动启动?

导读&#xff1a;TIA WinCC Advanced (高级版)V17项目如何下载到目标计算机&#xff08;需要运行项目的电脑&#xff09;&#xff1f; 01WinCC RT Adv项目下载 1、在计算机开始菜单中点击“运行”或通过Win键R调出运行窗口&#xff0c;并输入 CMD 然后回车&#xff1a; 打开 W…

漏洞发现-漏扫项目篇NucleiYakitGobyAfrogXrayAwvs联动中转被动

知识点 1、综合类-Burp&Xray&Awvs&Goby 2、特征类-Afrog&Yakit&Nuclei 3、联动类-主动扫描&被动扫描&中转扫描 章节点&#xff1a; 漏洞发现-Web&框架组件&中间件&APP&小程序&系统 扫描项目-综合漏扫&特征漏扫&被动…

LED基础知识分享(一)

大家好&#xff0c;我是砖一。 今天给大家分享一下&#xff0c;LED的基础知识&#xff0c;有照明行业&#xff0c;或者对LED感兴趣的朋友&#xff0c;可以学习一下&#xff0c;希望对你有用~ 一&#xff0c;什么是LED (Light Emitting Diode)? 1&#xff0c;LED是一种发出某…

使用Flask快速搭建轻量级Web应用【第127篇—Flask】

使用Flask快速搭建轻量级Web应用 在Web开发领域&#xff0c;选择适合项目需求的框架至关重要。Flask&#xff0c;一个轻量级的Python Web框架&#xff0c;以其简洁、灵活和易扩展的特性而备受开发者青睐。本文将介绍如何使用Flask迅速搭建一个轻量级的Web应用&#xff0c;并通过…

【测试开发学习历程】Linux用户管理+文件权限管理

目录 一、用户管理 &#xff08;一&#xff09;用户和用户组的基本概念 1.概念 2.设置原因 3.用户与用户组的关系 4.用户类型 &#xff08;二&#xff09;用户的创建、修改属性和删除用户 1.用户信息文件 2.创建用户 3.修改用户密码 4.修改用户信息 5.用户查询 6.…

Hive面经

hive原理 Hive 内部表和外部表的区别Hive 有索引吗运维如何对 Hive 进行调度ORC、Parquet 等列式存储的优点数据建模用的哪些模型&#xff1f;1. 星型模型2. 雪花模型3. 星座模型 为什么要对数据仓库分层&#xff1f;使用过 Hive 解析 JSON 串吗sort by 和 order by 的区别数据…