免費學習推薦:js影片教學
介紹
#在網頁中利用canvas進行繪圖時,遇到一個問題,原始的資料解析度很小,圖片要放大到整個網頁,所以需要把資料插值放大。學習了雙線性插值和三次內插法插值,兩種方式實現效果不同,都用js程式碼實現了一下,下面跟大家分享一下雙線性插值
原理
雙線性內插即在x和y兩個方向上,資料各進行一次線性內插。 原始資料的矩陣,即二維數組,大小為a*b,目標矩陣大小為m*n,m、n比a、b可以大(放大),也可以小(縮小),當然比例也可以不一樣, 取決於你插值後的資料需要多大。
基本思想為,遍歷目標矩陣的座標,如x*y這個點,找到這個點在原始矩陣中對應的位置,稱為映射點,然後找到這個映射點P在原始矩陣中周圍的四個點,然後根據映射點P到這個四個點的x和y方向上的座標的距離,進行兩次線性內插,得到映射點的值即可。
如上圖所示,p點為目標矩陣中x*y點在原始矩陣中映射的位置,它周圍最近的有Q12,Q11,Q21,Q22四個點,現在x方向進行線性內插,得到R1和R2兩點的值,再在y方向進行一次線性內插,得到P點的值。
注意:用雙線性內插放大資料後,若放大倍率過大,產生圖片後發現有著明顯的馬賽克現象
實作程式碼參考後面js程式碼
雙三次插值法
原理
雙三次內插又稱立方卷積插值。三次卷積插值是一種更複雜的插值方式。此演算法利用待採樣點周圍16個點的灰階值作三次內插,不僅考慮到4 個直接相鄰點的灰階影響,也考慮到各鄰點間灰階值變化率的影響。具體的原理可參考下面博客:參考這裡的博客
基本原理就是,先找到目標矩陣中點在來源資料矩陣中的映射點P,然後找到P點周圍16個點,然後根據P點座標距離16個點的x和y方向的距離,利用BiCubic函數算出每個點的權重,最後每個點乘以權重後,加起來即可得到P的值。
其中,當a取-0.5時,BiCubic函數有以下形狀:
## 取a= -0.5時,放大的資料挺好,產生的圖片非常平滑,也保留了許多細節。 具體為什麼要用這個函數,我也沒有深入研究,不過利用該方法放大資料後,產生圖片效果很好,沒有馬賽克現象
#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中文網其他相關文章!