首頁  >  文章  >  web前端  >  實作js的雙線性插值和雙三次插值法

實作js的雙線性插值和雙三次插值法

coldplay.xixi
coldplay.xixi轉載
2021-01-25 09:39:232545瀏覽

實作js的雙線性插值和雙三次插值法

免費學習推薦:js影片教學

    ##介紹
  • 雙線性內插
    • 原理
  • #雙三次內插法
    • 原理
  • js實作

介紹

#在網頁中利用canvas進行繪圖時,遇到一個問題,原始的資料解析度很小,圖片要放大到整個網頁,所以需要把資料插值放大。學習了雙線性插值和三次內插法插值,兩種方式實現效果不同,都用js程式碼實現了一下,下面跟大家分享一下

雙線性插值

原理

雙線性內插即在x和y兩個方向上,資料各進行一次線性內插。

原始資料的矩陣,即二維數組,大小為a*b,目標矩陣大小為m*n,m、n比a、b可以大(放大),也可以小(縮小),當然比例也可以不一樣, 取決於你插值後的資料需要多大。
基本思想為,遍歷目標矩陣的座標,如x*y這個點,找到這個點在原始矩陣中對應的位置,稱為映射點,然後找到這個映射點P在原始矩陣中周圍的四個點,然後根據映射點P到這個四個點的x和y方向上的座標的距離,進行兩次線性內插,得到映射點的值即可。

實作js的雙線性插值和雙三次插值法 如上圖所示,p點為目標矩陣中x*y點在原始矩陣中映射的位置,它周圍最近的有Q12,Q11,Q21,Q22四個點,現在x方向進行線性內插,得到R1和R2兩點的值,再在y方向進行一次線性內插,得到P點的值。
注意:用雙線性內插放大資料後,若放大倍率過大,產生圖片後發現有著明顯的馬賽克現象
實作程式碼參考後面js程式碼

雙三次插值法

原理

雙三次內插又稱立方卷積插值。三次卷積插值是一種更複雜的插值方式。此演算法利用待採樣點周圍16個點的灰階值作三次內插,不僅考慮到4 個直接相鄰點的灰階影響,也考慮到各鄰點間灰階值變化率的影響。具體的原理可參考下面博客:

參考這裡的博客
基本原理就是,先找到目標矩陣中點在來源資料矩陣中的映射點P,然後找到P點周圍16個點,然後根據P點座標距離16個點的x和y方向的距離,利用BiCubic函數算出每個點的權重,最後每個點乘以權重後,加起來即可得到P的值。

實作js的雙線性插值和雙三次插值法

BiCubic函數:


實作js的雙線性插值和雙三次插值法 其中,當a取-0.5時,BiCubic函數有以下形狀:

## 取a= -0.5時,放大的資料挺好,產生的圖片非常平滑,也保留了許多細節。 實作js的雙線性插值和雙三次插值法 具體為什麼要用這個函數,我也沒有深入研究,不過利用該方法放大資料後,產生圖片效果很好,沒有馬賽克現象

#js實作

/**
 * 数据处理工具类(也可以自己直接定义方法,不用class)
 */class DataUtil {
	constructor() {}}/**
 * 数据插值
 * @param w 目标矩阵宽度
 * @param h 目标矩阵高度
 * @param data 源数据矩阵(二维数组)
 * @param type 插值方式,1:双线性插值,2:双三次插值法
 */DataUtil.scaleData = function(w, h, data, type = 2) {
	let t1 = new Date().getTime();
	let dw = data[0].length;
	let dh = data.length;
	
	let resData = new Array(h);
	
	for (let j = 0; j  h - 1 ? h - 1 : py;
		for (let i = 0; i  w - 1 ? w - 1 : px;
			// 该点的值
			let dv = data[py][px];
			// 该点的权重
			let w_x = wx[i];
			let w_y = wy[j];
			// 根据加权加起来
			val += (dv * w_x * w_y);
		}
	}
	
	return val;}/**
 * 双三次插值法中,基于BiCubic基函数,计算源坐标v,最近的4*4的坐标和坐标对应的权重
 * @param v 目标矩阵中坐标对应在源矩阵中坐标值
 */DataUtil.getCubicWeight = function (v){
	let a = -0.5;
	
	// 取整
	let nv = Math.floor(v);
	
	// 坐标差值集合
	let xList = new Array(4);
	// 坐标集合
	let xs = new Array(4);
	
	// 最近的4个坐标差值
	xList[0] = nv - v - 1;
	xList[1] = nv - v
	xList[2] = nv - v + 1;
	xList[3] = nv - v + 2;
	// 
	xs[0] = nv - 1;
	xs[1] = nv;
	xs[2] = nv + 1;
	xs[3] = nv + 2;
	
	// 计算权重
	let ws = new Array(4);
	for (let i = 0; i <p></p>相關免費學習推薦:<p><strong></strong>javascript<a href="https://www.php.cn/course/list/17.html" target="_blank" textvalue="javascript"><strong></strong>(影片)</a><strong></strong></p>

以上是實作js的雙線性插值和雙三次插值法的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:csdn.net。如有侵權,請聯絡admin@php.cn刪除