網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
在對(duì)二維數(shù)據(jù)進(jìn)行 resize / mapping / 坐標(biāo)轉(zhuǎn)換等操作時(shí),經(jīng)常會(huì)將原本的整數(shù)坐標(biāo)變換為小數(shù)坐標(biāo),對(duì)于非整數(shù)的坐標(biāo)值一種直觀有效的插值方式為雙線性插值。
插值簡(jiǎn)介
雙線性插值,又稱為雙線性內(nèi)插。在數(shù)學(xué)上,雙線性插值是有兩個(gè)變量的插值函數(shù)的線性插值擴(kuò)展,其核心思想是在兩個(gè)方向分別進(jìn)行一次線性插值。
雙線性插值作為數(shù)值分析中的一種插值算法,廣泛應(yīng)用在信號(hào)處理,數(shù)字圖像和視頻處理等方面。
假設(shè)我們出現(xiàn)了需要在四個(gè)相鄰正方形整數(shù)點(diǎn)(A,B,C,D)坐標(biāo)中間(正方形范圍內(nèi))選擇一個(gè)點(diǎn)(a,b)取近似值的情形。
此時(shí)我們已知的是四個(gè)點(diǎn)的數(shù)值VA?,VB?,VC?,VD?,給定小數(shù)坐標(biāo)E(a,b),0≤a,b≤1,如何插值求解E點(diǎn)的數(shù)值呢,解決類似問(wèn)題的方法統(tǒng)稱為插值,上圖展示公式為雙線性插值的計(jì)算方法。
最近鄰法 (Nearest Interpolation)
一種最簡(jiǎn)便的方法為最近鄰法,直接取與當(dāng)前點(diǎn)距離最近的點(diǎn)的值作為插值結(jié)果:
其中 roundroundround 為四舍五入的取整操作,方法簡(jiǎn)便速度極快,但往往不夠精細(xì)
雙三次插值 (Bicubic interpolation)
雙三次插值是用原圖像中16(4*4)個(gè)點(diǎn)計(jì)算新圖像中1個(gè)點(diǎn),效果比較好,但是計(jì)算代價(jià)過(guò)大。
雙線性插值 (Bilinear Interpolation)
使用一個(gè)點(diǎn)進(jìn)行插值過(guò)于粗暴,16個(gè)點(diǎn)又過(guò)于繁瑣,那就使用EEE?點(diǎn)周圍4個(gè)點(diǎn)的數(shù)值來(lái)近似求解,這是一種平衡了計(jì)算代價(jià)和插值效果的折中方案,也是各大變換庫(kù)的默認(rèn)插值操作。
雙線性插值
通過(guò)觀察上述動(dòng)圖(可以動(dòng)手挪一挪)可以清晰地看到,雙線性插值本質(zhì)就是把四個(gè)角落的數(shù)值按照正方形面積的比例線性加權(quán)后的結(jié)果。
好吧一句話已經(jīng)把數(shù)學(xué)的核心部分講完了
那么既然理解了本質(zhì),數(shù)學(xué)公式就好寫(xiě)了:
python實(shí)現(xiàn)
在實(shí)現(xiàn)時(shí)當(dāng)然 for 循環(huán)大法可以解決一切問(wèn)題,但總歸是不太優(yōu)雅,我們嘗試使用 numpy 操作完成雙線性插值
假設(shè)原始圖像 image
,變換后的小數(shù)坐標(biāo) X 矩陣 x_grid
,Y 矩陣 y_grid
,那么可以使用如下的 bilinear_by_meshgrid
函數(shù)快速雙線性插值,已經(jīng)處理好了邊界,可以放心使用。
def bilinear_by_meshgrid(image, x_grid, y_grid): # Ia, Wd Ic, Wb # (floor_x, floor_y) (ceil_x, floor_y) # # (x, y) # # Ib , Wc Id, Wa # (floor_x, ceil_y) (ceil_x, ceil_y) # assert image.shape == x_grid.shape == y_grid.shape assert image.ndim == 2 H, W = image.shape[:2] floor_x_grid = np.floor(x_grid).astype('int32') floor_y_grid = np.floor(y_grid).astype('int32') ceil_x_grid = floor_x_grid + 1 ceil_y_grid = floor_y_grid + 1 if np.max(ceil_x_grid) > W -1 or np.max(ceil_y_grid) > H -1 or np.min(floor_x_grid) < 0 or np.min(floor_y_grid) < 0: print("Warning: index value out of original matrix, a crop operation will be applied.") floor_x_grid = np.clip(floor_x_grid, 0, W-1).astype('int32') ceil_x_grid = np.clip(ceil_x_grid, 0, W-1).astype('int32') floor_y_grid = np.clip(floor_y_grid, 0, H-1).astype('int32') ceil_y_grid = np.clip(ceil_y_grid, 0, H-1).astype('int32') Ia = image[ floor_y_grid, floor_x_grid ] Ib = image[ ceil_y_grid, floor_x_grid ] Ic = image[ floor_y_grid, ceil_x_grid ] Id = image[ ceil_y_grid, ceil_x_grid ] wa = (ceil_x_grid - x_grid) * (ceil_y_grid - y_grid) wb = (ceil_x_grid - x_grid) * (y_grid - floor_y_grid) wc = (x_grid - floor_x_grid) * (ceil_y_grid - y_grid) wd = (x_grid - floor_x_grid) * (y_grid - floor_y_grid) assert np.min(wa) >=0 and np.min(wb) >=0 and np.min(wc) >=0 and np.min(wd) >=0 W = wa + wb + wc + wd assert np.sum(W[:, -1]) + np.sum(W[-1, :]) == 0 wa[:-1, -1] = ceil_y_grid[:-1, -1] - y_grid[:-1, -1] wb[:-1, -1] = y_grid[:-1, -1] - floor_y_grid[:-1, -1] wb[-1, :-1] = ceil_x_grid[-1, :-1] - x_grid[-1, :-1] wd[-1, :-1] = x_grid[-1, :-1] - floor_x_grid[-1, :-1] wd[-1, -1] = 1 W = wa + wb + wc + wd assert np.max(W) == np.min(W) == 1 res_image = wa*Ia + wb*Ib + wc*Ic + wd*Id return res_image
該函數(shù)集成在我自己的python庫(kù) mtutils
中,可以通過(guò):
pip install mtutils
直接安裝,之后可以直接引用:
from mtutils import bilinear_by_meshgrid
原文鏈接:https://juejin.cn/post/7107479950084538376
相關(guān)推薦
- 2023-01-14 Go庫(kù)text與template包使用示例詳解_Golang
- 2022-12-10 C++中使用正則匹配問(wèn)題_C 語(yǔ)言
- 2022-12-09 Oracle遞歸查詢簡(jiǎn)單示例_oracle
- 2022-09-04 Go語(yǔ)言簡(jiǎn)介和環(huán)境配置_Golang
- 2022-03-15 3 Segmentation fault (core dumped) ./a.out Exited
- 2023-06-03 React實(shí)現(xiàn)一個(gè)倒計(jì)時(shí)hook組件實(shí)戰(zhàn)示例_React
- 2022-07-16 MyBatis查詢時(shí)數(shù)據(jù)表字段名與實(shí)體類屬性名不一致
- 2023-02-14 C#實(shí)現(xiàn)ComboBox變色的示例代碼_C#教程
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過(guò)濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支