最邻近插值、双线性插值、三次卷积插值最通俗入门理论解析,论文材料

如有任何问题,请联系VX:1755337994

前言

图像处理中有三种常用的插值算法:

  • 最邻近插值

  • 双线性插值

  • 双立方(三次卷积)插值

其中效果最好的是双立方(三次卷积)插值,本文介绍它的原理以及使用

如果想先看效果和源码,可以拉到最底部

本文的契机是某次基于canvas做图像处理时,发现canvas自带的缩放功能不尽人意,于是重温了下几种图像插值算法,并整理出来。

为何要进行双立方插值

  • 对图像进行插值的目的是为了获取缩小或放大后的图片

  • 常用的插值算法中,双立方插值效果最好

  • 本文中介绍双立方插值的一些数学理论以及实现

双立方三次卷积只是这个插值算法的两种不同叫法而已,可以自行推导,会发现最终可以将求值转化为卷积公式

另外,像Photoshop等图像处理软件中也有这三种算法的实现

数学理论

双立方插值计算涉及到16个像素点,如下图

简单分析如下:

  • 其中P00代表目标插值图中的某像素点(x, y)在原图中最接近的映射点

    • 譬如映射到原图中的坐标为(1.1, 1.1),那么P00就是(1, 1)
  • 而最终插值后的图像中的(x, y)处的值即为以上16个像素点的权重卷积之和

下图进一步分析

如下是对图的一些简单分析

  • 譬如计算插值图中(distI, distJ)处像素的值

  • 首先计算它映射到原图中的坐标(i + v, j + u)

  • 也就是说,卷积计算时,p00点对应(i, j)坐标

  • 最终,插值后的图(distI, distJ)坐标点对应的值是原图中(i, j)邻近16个像素点的权重卷积之和

    • i, j的范围是[i - 1, i + 2][j - 1, j + 2]

卷积公式

  • 设采样公式为S(x)

  • 原图中每一个(i, j)坐标点的值得表达式为f(i, j)

  • 插值后对应坐标的值为F(i + v, j + u)(这个值会作为(distI, distJ)坐标点的值)

那么公式为:

等价于(可自行推导)

提示

一定要区分本文中v, urow, col的对应关系,v代表行数偏差,u代表列数偏差(如果混淆了,会造成最终的图像偏差很大)

如何理解卷积?

这是大学数学内容,推荐看看这个答案如何通俗易懂的解释卷积-知乎

采样公式

在卷积公式中有一个S(x),它就是关键的卷积插值公式

不同的公式,插值效果会有所差异(会导致加权值不一样)

本文中采用WIKI-Bicubic interpolation中给出的插值公式:

公式中的特点是:

  • S(0) = 1

  • S(n) = 0(当n为整数时)

  • 当x超出范围时,S(x)为0

  • a取不同值时可以用来逼近不同的样条函数(常用值-0.5, -0.75

当a取值为-1

公式如下:

此时,逼近的函数是y = sin(x*PI)/(x*PI),如图

当a取值为-0.5

公式如下:

此时对应三次Hermite样条

不同a的简单对比

推导

可参考:

  • 图像处理(一)bicubic解释推导

  • WIKI-Bicubic interpolation

关于网上的一些推导公式奇怪实现

在网上查找了不少相关资料,发现有不少文章中都用到了以下这个奇怪的公式(譬如百度搜索双立方插值

一般这些文章中都声称这个公式是用来近似y = sin(x*PI)/(x)

但事实上,进过验证,它与y = sin(x*PI)/(x)相差甚远(如上图中是将sin函数缩放到合理系数后比对)

由于类似的文章较多,年代都比较久远,无从得知最初的来源

可能是某文中漏掉了分母的PI,亦或是这个公式只是某文自己实现的一个采样公式,与sin无关,然后被误传了。

这里都无从考据,仅此记录,避免疑惑。

另一种基于系数的实现

可以参考:图像处理(一)bicubic解释推导

像这类的实现就是直接计算最原始的系数,然后通过16个像素点计算不同系数值,最终计算出目标像素

本质是一样的,只不过是没有基于最终的卷积方程计算而已(也就是说在原始理论阶段没有推成插值公式,而是直接解出系数并计算)。

代码实现在github项目中可看到,参考最后的开源项目

代码实现

以下是JavaScript代码实现的插值核心方程

/*** 采样公式的常数A取值,调整锐化与模糊* -0.5 三次Hermite样条* -0.75 常用值之一* -1 逼近y = sin(x*PI)/(x*PI)* -2 常用值之一*/
const A = -0.5;function interpolationCalculate(x) {const absX = x > 0 ? x : -x;const x2 = x * x;const x3 = absX * x2;if (absX <= 1) {return 1 - (A + 3) * x2 + (A + 2) * x3;} else if (absX <= 2) {return -4 * A + 8 * A * absX - 5 * A * x2 + A * x3;}return 0;
}

以上是卷积方程的核心实现。下面则是一套完整的实现

/*** 采样公式的常数A取值,调整锐化与模糊* -0.5 三次Hermite样条* -0.75 常用值之一* -1 逼近y = sin(x*PI)/(x*PI)* -2 常用值之一*/
const A = -1;function interpolationCalculate(x) {const absX = x >= 0 ? x : -x;const x2 = x * x;const x3 = absX * x2;if (absX <= 1) {return 1 - (A + 3) * x2 + (A + 2) * x3;} else if (absX <= 2) {return -4 * A + 8 * A * absX - 5 * A * x2 + A * x3;}return 0;
}function getPixelValue(pixelValue) {let newPixelValue = pixelValue;newPixelValue = Math.min(255, newPixelValue);newPixelValue = Math.max(0, newPixelValue);return newPixelValue;
}/*** 获取某行某列的像素对于的rgba值* @param {Object} data 图像数据* @param {Number} srcWidth 宽度* @param {Number} srcHeight 高度* @param {Number} row 目标像素的行* @param {Number} col 目标像素的列*/
function getRGBAValue(data, srcWidth, srcHeight, row, col) {let newRow = row;let newCol = col;if (newRow >= srcHeight) {newRow = srcHeight - 1;} else if (newRow < 0) {newRow = 0;}if (newCol >= srcWidth) {newCol = srcWidth - 1;} else if (newCol < 0) {newCol = 0;}let newIndex = (newRow * srcWidth) + newCol;newIndex *= 4;return [data[newIndex + 0],data[newIndex + 1],data[newIndex + 2],data[newIndex + 3],];
}function scale(data, width, height, newData, newWidth, newHeight) {const dstData = newData;// 计算压缩后的缩放比const scaleW = newWidth / width;const scaleH = newHeight / height;const filter = (dstCol, dstRow) => {// 源图像中的坐标(可能是一个浮点)const srcCol = Math.min(width - 1, dstCol / scaleW);const srcRow = Math.min(height - 1, dstRow / scaleH);const intCol = Math.floor(srcCol);const intRow = Math.floor(srcRow);// 计算u和vconst u = srcCol - intCol;const v = srcRow - intRow;// 真实的index,因为数组是一维的let dstI = (dstRow * newWidth) + dstCol;dstI *= 4;// 存储灰度值的权重卷积和const rgbaData = [0, 0, 0, 0];// 根据数学推导,16个点的f1*f2加起来是趋近于1的(可能会有浮点误差)// 因此就不再单独先加权值,再除了// 16个邻近点for (let m = -1; m <= 2; m += 1) {for (let n = -1; n <= 2; n += 1) {const rgba = getRGBAValue(data,width,height,intRow + m,intCol + n,);// 一定要正确区分 m,n和u,v对应的关系,否则会造成图像严重偏差(譬如出现噪点等)// F(row + m, col + n)S(m - v)S(n - u)const f1 = interpolationCalculate(m - v);const f2 = interpolationCalculate(n - u);const weight = f1 * f2;rgbaData[0] += rgba[0] * weight;rgbaData[1] += rgba[1] * weight;rgbaData[2] += rgba[2] * weight;rgbaData[3] += rgba[3] * weight;}}dstData[dstI + 0] = getPixelValue(rgbaData[0]);dstData[dstI + 1] = getPixelValue(rgbaData[1]);dstData[dstI + 2] = getPixelValue(rgbaData[2]);dstData[dstI + 3] = getPixelValue(rgbaData[3]);};// 区块for (let col = 0; col < newWidth; col += 1) {for (let row = 0; row < newHeight; row += 1) {filter(col, row);}}
}export default function bicubicInterpolation(imgData, newImgData) {scale(imgData.data,imgData.width,imgData.height,newImgData.data,newImgData.width,newImgData.height);return newImgData;
}

运行效果

分别用三种算法对一个图进行放大,可以明显的看出双立方插值效果最好

任何程序错误,以及技术疑问或需要解答的,请添加

 

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

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

相关文章

Spring Boot 最佳实践(二)集成Jsp与生产环境部署

一、简介 提起Java不得不说的一个开发场景就是Web开发&#xff0c;也是Java最热门的开发场景之一&#xff0c;说到Web开发绕不开的一个技术就是JSP&#xff0c;因为目前市面上仍有很多的公司在使用JSP&#xff0c;所以本文就来介绍一下Spring Boot 怎么集成JSP开发&#xff0c…

全网最详细 Python如何读取NIFTI格式图像(.nii文件)和 .npy格式文件和pkl标签文件内容

在医学图像处理中&#xff0c;我们经常使用一种NIFTI格式图像&#xff08;.nii文件&#xff09;&#xff0c;现在我们来看看 什么是.nii文件&#xff1f;该如何读取.nii文件&#xff1f; 1. NIFTI格式图像 什么是NIFTI&#xff08;Neuroimaging Informatics Technology Initia…

Spring Boot 最佳实践(三)模板引擎FreeMarker集成

一、FreeMaker介绍 FreeMarker是一款免费的Java模板引擎&#xff0c;是一种基于模板和数据生成文本&#xff08;HMLT、电子邮件、配置文件、源代码等&#xff09;的工具&#xff0c;它不是面向最终用户的&#xff0c;而是一款程序员使用的组件。 FreeMarker最初设计是用来在M…

Android开发之通过浏览器链接打开任意app页面

老套路先上图&#xff1a; 先说下上面的流程&#xff0c;第一张图是模拟浏览器的网页点击链接打开app,第二张图系统弹框提示是否打开app,第三张图已打开APP&#xff0c;弹出的吐司是打开APP携带的数据 具体实现分为两步&#xff0c;第一步配置你要打开的activity页面如下&…

DVWA下载、安装、使用(漏洞测试环境搭建)教程

DVWA&#xff08;Damn Vulnerable Web Application&#xff09;是一个用来进行安全脆弱性鉴定的PHP/MySQL Web应用&#xff0c;旨在为安全专业人员测试自己的专业技能和工具提供合法的环境&#xff0c;帮助web开发者更好的理解web应用安全防范的过程。 一共有十个模块&#xf…

Spring Boot 最佳实践(四)模板引擎Thymeleaf集成

## 一、Thymeleaf介绍 Thymeleaf是一种Java XML / XHTML / HTML5模板引擎&#xff0c;可以在Web和非Web环境中使用。它更适合在基于MVC的Web应用程序的视图层提供XHTML / HTML5&#xff0c;但即使在脱机环境中&#xff0c;它也可以处理任何XML文件。它提供了完整的Spring Fram…

Centos7安装Postgresql 13 详细步骤(远程连接)

版本信息 CentOS &#xff1a; 7.6 postgresql&#xff1a; 10.012 安装 可以参考官网PostgreSQL: Linux downloads (Red Hat family) &#xff03;安装存储库RPM&#xff1a; sudo yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgd…

mysql复制: 一个master对应1个slave

2019独角兽企业重金招聘Python工程师标准>>> 复制的步骤&#xff1a;1.在主库上开启二进制日志&#xff0c;把数据更改记录到二进制日志(binary log)中. mysql会按照事物提交的顺序而非每条语句的执行顺序来记录二进制日志&#xff0c;在记录二进制日志后&#xff…

python3、sqlmap下载与安装教程

一 、前提 需要安装python3&#xff0c;可以参考其他教程 二 、下载 官网下载http://sqlmap.org/ 三 、安装 将下载的sqlmap.zip解压到文件夹sqlmap中&#xff0c;并拷贝到Python安装路径下 四、 配置 在桌面上创建一个cmd进入python的快捷方式&#xff08;这步可以不做…

Spring Boot 最佳实践(五)Spring Data JPA 操作 MySQL 8

## 一、Spring Data JPA 介绍 JPA&#xff08;Java Persistence API&#xff09;Java持久化API&#xff0c;是 Java 持久化的标准规范&#xff0c;Hibernate是持久化规范的技术实现&#xff0c;而Spring Data JPA是在 Hibernate 基础上封装的一款框架。 开发环境 Spring Boo…

Windows MinGW配置C、C++编译环境

写在前面的前面&#xff1a;这篇文章vscode和cpp插件版本有点老了&#xff0c;仅供大家参考&#xff0c;最新的和最详细的更新见我的另一篇文章&#xff1a;整理&#xff1a;Visual Studio Code (vscode) 配置C、C环境/编写运行C、C&#xff08;主要Windows、简要Linux&#xf…

Burpsuite超详细安装教程

版权声明&#xff1a;本文为博主原创文章&#xff0c;遵循 CC 4.0 BY-SA 版权协议&#xff0c;转载请附上原文出处链接和本声明。 本文转载于链接&#xff1a;https://blog.csdn.net/LUOBIKUN/article/details/87457545 Burpsuite的超详细安装教程 概述工具分享安装一&#xff…

使用Hexo搭建个人博客的终极资料

# 一、前言 Hexo 是一个基于 NodeJs 博客框架&#xff0c;可以快速的帮我们搭建一个博客系统&#xff0c;Hexo使用的是Markdown&#xff08;下文简称MD&#xff09;解析文章的&#xff0c;在几秒内即可利用靓丽的主体生成静态网页。 推荐使用 Hexo 有三大理由&#xff1a; 有…

Linux Ubuntu 安装编译Opencv 3.4.3 C++开发环境

在安装Autoware之前&#xff0c;需要先安装Opencv&#xff0c;之前在Windows下安装了Opencv&#xff0c;挺复杂的。不过&#xff0c;在Ubuntu 16.04环境中配置安装Opencv相对来说&#xff0c;比较简单。 Linux Ubuntu 安装编译Opencv 3.4.3 C开发环境 1.1 下载Opencv 3.4.3 …

bugku web基础$_POST

意思是通过post传入一个参数what&#xff0c;如果what的值等于flag&#xff0c;即打印出flag 这个我们有好几种办法&#xff1a; 第一种方法&#xff1a; 用FireFox的HackBar插件&#xff0c;传入参数whatflag run一下&#xff0c;爆出了flag 第二种方法&#xff1a; 写个…

Windows MinGW cmake 安装编译Opencv 3.4.3 C++开发环境

win10 _64位系统 VSCode&#xff1a;官网地址 Opencv&#xff1a;3.4.5 Cmake&#xff1a;3.9.0 MinGw&#xff1a;MinGW-W64 GCC-8.1.0&#xff08;x86_64-posix-seh&#xff09; MinGW配置&#xff1a; MinGW可以在线安装&#xff0c;也可以直接下载文件后离线解压。 …

Spring Boot (七)MyBatis代码自动生成和辅助插件

一、简介 1.1 MyBatis Generator介绍 MyBatis Generator 是MyBatis 官方出品的一款&#xff0c;用来自动生成MyBatis的 mapper、dao、entity 的框架&#xff0c;让我们省去规律性最强的一部分最基础的代码编写。 1.2 MyBatis Generator使用 MyBatis Generator的使用方式有4…

Android 性能优化提示

原文 http://developer.android.com/guide/practices/design/performance.html 性能优化 Android应用程序运行的移动设备受限于其运算能力&#xff0c;存储空间&#xff0c;及电池续航。由此&#xff0c;它必须是高效的。电池续航可能是一个促使你优化程序的原因&#xff0c;即…

全志A20 刷入Ubuntu/Debian Linux固件 亲测能用

测试盒子&#xff1a;小美盒子&#xff08;好像是杂牌的&#xff09; 有疑问交流可以加微信&#xff1a;1755337994 PCB板号&#xff1a;RM-MPEG-107G VER1.0 20140422 用PhoenixUSBPro刷入就行&#xff0c;要刷500多秒&#xff0c;5124G版本的配置刷完Debian系统里面看还剩1…

Spring Boot (八)MyBatis + Docker + MongoDB 4.x

一、MongoDB简介 1.1 MongoDB介绍 MongoDB是一个强大、灵活&#xff0c;且易于扩展的通用型数据库。MongoDB是C编写的文档型数据库&#xff0c;有着丰富的关系型数据库的功能&#xff0c;并在4.0之后添加了事务支持。 随着存储数据量不断的增加&#xff0c;开发者面临一个困…