插值演算法史
⑴ 線性插值法計算公式是什麼
線性插值法計算公式:Y=Y1+(Y2-Y1)×(X-X1)/(X2-X1)。其中Y2>Y1,X2>X>X1。線性插值是指插值函數為一次多項式的插值方式,其在插值節點上的插值誤差為零。線性插值相比其他插值方式,如拋物線插值,具有簡單、方便的特點。線性插值可以用來近似代替原函數,也可以用來計算得到查表過程中表中沒有的數值。
線性插值使用的原因
目前,線性插值演算法使用比較廣泛。在很多場合我們都可以使用線性插值。其中,最具代表性的使用方法是變數之間的對應關系沒有明確的對應關系,無法使用公式來描述兩個變數之間的對應關系,在這種情況下使用線性插值是比較好的解決辦法。可以在變數的變化區間上取若干個離散的點,以及對應的輸出值,然後將對應關系分成若干段,當計算某個輸入對應的輸出時,可以進行分段線性插值。
⑵ 雙線性插值法原理 python實現
碼字不易,如果此文對你有所幫助,請幫忙點贊,感謝!
一. 雙線性插值法原理:
① 何為線性插值?
插值就是在兩個數之間插入一個數,線性插值原理圖如下:
② 各種插值法:
插值法的第一步都是相同的,計算目標圖(dstImage)的坐標點對應原圖(srcImage)中哪個坐標點來填充,計算公式為:
srcX = dstX * (srcWidth/dstWidth)
srcY = dstY * (srcHeight/dstHeight)
(dstX,dstY)表示目標圖像的某個坐標點,(srcX,srcY)表示與之對應的原圖像的坐標點。srcWidth/dstWidth 和 srcHeight/dstHeight 分別表示寬和高的放縮比。
那麼問題來了,通過這個公式算出來的 srcX, scrY 有可能是小數,但是原圖像坐標點是不存在小數的,都是整數,得想辦法把它轉換成整數才行。
不同插值法的區別就體現在 srcX, scrY 是小數時,怎麼將其變成整數去取原圖像中的像素值。
最近鄰插值(Nearest-neighborInterpolation):看名字就很直白,四捨五入選取最接近的整數。這樣的做法會導致像素變化不連續,在目標圖像中產生鋸齒邊緣。
雙線性插值(Bilinear Interpolation):雙線性就是利用與坐標軸平行的兩條直線去把小數坐標分解到相鄰的四個整數坐標點。權重與距離成反比。
雙三次插值(Bicubic Interpolation):與雙線性插值類似,只不過用了相鄰的16個點。但是需要注意的是,前面兩種方法能保證兩個方向的坐標權重和為1,但是雙三次插值不能保證這點,所以可能出現像素值越界的情況,需要截斷。
③ 雙線性插值演算法原理
假如我們想得到未知函數 f 在點 P = (x, y) 的值,假設我們已知函數 f 在 Q11 = (x1, y1)、Q12 = (x1, y2), Q21 = (x2, y1) 以及 Q22 = (x2, y2) 四個點的值。最常見的情況,f就是一個像素點的像素值。首先在 x 方向進行線性插值,然後再在 y 方向上進行線性插值,最終得到雙線性插值的結果。
④ 舉例說明
二. python實現灰度圖像雙線性插值演算法:
灰度圖像雙線性插值放大縮小
import numpy as np
import math
import cv2
def double_linear(input_signal, zoom_multiples):
'''
雙線性插值
:param input_signal: 輸入圖像
:param zoom_multiples: 放大倍數
:return: 雙線性插值後的圖像
'''
input_signal_cp = np.(input_signal) # 輸入圖像的副本
input_row, input_col = input_signal_cp.shape # 輸入圖像的尺寸(行、列)
# 輸出圖像的尺寸
output_row = int(input_row * zoom_multiples)
output_col = int(input_col * zoom_multiples)
output_signal = np.zeros((output_row, output_col)) # 輸出圖片
for i in range(output_row):
for j in range(output_col):
# 輸出圖片中坐標 (i,j)對應至輸入圖片中的最近的四個點點(x1,y1)(x2, y2),(x3, y3),(x4,y4)的均值
temp_x = i / output_row * input_row
temp_y = j / output_col * input_col
x1 = int(temp_x)
y1 = int(temp_y)
x2 = x1
y2 = y1 + 1
x3 = x1 + 1
y3 = y1
x4 = x1 + 1
y4 = y1 + 1
u = temp_x - x1
v = temp_y - y1
# 防止越界
if x4 >= input_row:
x4 = input_row - 1
x2 = x4
x1 = x4 - 1
x3 = x4 - 1
if y4 >= input_col:
y4 = input_col - 1
y3 = y4
y1 = y4 - 1
y2 = y4 - 1
# 插值
output_signal[i, j] = (1-u)*(1-v)*int(input_signal_cp[x1, y1]) + (1-u)*v*int(input_signal_cp[x2, y2]) + u*(1-v)*int(input_signal_cp[x3, y3]) + u*v*int(input_signal_cp[x4, y4])
return output_signal
# Read image
img = cv2.imread("../paojie_g.jpg",0).astype(np.float)
out = double_linear(img,2).astype(np.uint8)
# Save result
cv2.imshow("result", out)
cv2.imwrite("out.jpg", out)
cv2.waitKey(0)
cv2.destroyAllWindows()
三. 灰度圖像雙線性插值實驗結果:
四. 彩色圖像雙線性插值python實現
def BiLinear_interpolation(img,dstH,dstW):
scrH,scrW,_=img.shape
img=np.pad(img,((0,1),(0,1),(0,0)),'constant')
retimg=np.zeros((dstH,dstW,3),dtype=np.uint8)
for i in range(dstH-1):
for j in range(dstW-1):
scrx=(i+1)*(scrH/dstH)
scry=(j+1)*(scrW/dstW)
x=math.floor(scrx)
y=math.floor(scry)
u=scrx-x
v=scry-y
retimg[i,j]=(1-u)*(1-v)*img[x,y]+u*(1-v)*img[x+1,y]+(1-u)*v*img[x,y+1]+u*v*img[x+1,y+1]
return retimg
im_path='../paojie.jpg'
image=np.array(Image.open(im_path))
image2=BiLinear_interpolation(image,image.shape[0]*2,image.shape[1]*2)
image2=Image.fromarray(image2.astype('uint8')).convert('RGB')
image2.save('3.png')
五. 彩色圖像雙線性插值實驗結果:
六. 最近鄰插值演算法和雙三次插值演算法可參考:
① 最近鄰插值演算法: https://www.cnblogs.com/wojianxin/p/12515061.html
https://blog.csdn.net/Ibelievesunshine/article/details/104936006
② 雙三次插值演算法: https://www.cnblogs.com/wojianxin/p/12516762.html
https://blog.csdn.net/Ibelievesunshine/article/details/104942406
七. 參考內容:
https://www.cnblogs.com/wojianxin/p/12515061.html
https://blog.csdn.net/Ibelievesunshine/article/details/104939936
⑶ 什麼是插值演算法
插值法又稱「內插法」,是利用函數f (x)在某區間中插入若干點的函數值,作出適當的特定函數,在這些點上取已知值,在區間的其他點上用這特定函數的值作為函數f (x)的近似值,這種方法稱為插值法。如果這特定函數是多項式,就稱它為插值多項式。
1、Lagrange插值:
Lagrange插值是n次多項式插值,其成功地用構造插值基函數的 方法解決了求n次多項式插值函數問題;
★基本思想將待求的n次多項式插值函數pn(x)改寫成另一種表示方式,再利 用插值條件⑴確定其中的待定函數,從而求出插值多項式。
2、Newton插值:
Newton插值也是n次多項式插值,它提出另一種構造插值多項式的方法,與Lagrange插值相比,具有承襲性和易於變動節點的特點;
★基本思想將待求的n次插值多項式Pn(x)改寫為具有承襲性的形式,然後利用插值條件⑴確定Pn(x)的待定系數,以求出所要的插值函數。
3、Hermite插值:
Hermite插值是利用未知函數f(x)在插值節點上的函數值及導數值來構造插值多項式的,其提法為:給定n+1個互異的節點x0,x1,……,xn上的函數值和導數值
求一個2n+1次多項式H2n+1(x)滿足插值條件
H2n+1(xk)=yk
H'2n+1(xk)=y'k k=0,1,2,……,n ⒀
如上求出的H2n+1(x)稱為2n+1次Hermite插值函數,它與被插函數
一般有更好的密合度;
★基本思想
利用Lagrange插值函數的構造方法,先設定函數形式,再利
用插值條件⒀求出插值函數.
4、分段插值:
插值多項式余項公式說明插值節點越多,誤差越小,函數逐近越好,但後來人們發現,事實並非如此,例如:取被插函數,在[-5,5]上的n+1個等距節點:計算出f(xk)後得到Lagrange插值多項式Ln(x),考慮[-5,5]上的一點x=5-5/n,分別取n=2,6,10,14,18計算f(x),Ln(x)及對應的誤差Rn(x),得下表
從表中可知,隨節點個數n的增加,誤差lRn(x)l不但沒減小,反而不斷的增大.這個例子最早是由Runge研究,後來人們把這種節點加密但誤差增大的現象稱為Runge現象.出現Runge現象的原因主要是當節點n較大時,對應
的是高次插值多項式,此差得積累"淹沒"了增加節點減少的精度.Runge現象否定了用高次插值公式提高逼近精度的想法,本節的分段插值就是克服Runge現象引入的一種插值方法.
分段多項式插值的定義為
定義2: a=x0<x1<…<xn=b: 取[a,b]上n+1個節點 並給定在這些節點 上的函數值f(xR)=yR R=0,1,…,n
如果函數Φ(x)滿足條件
i) Φ(x)在[a,b]上連續
ii) Φ(xr)=yR,R =0,1,…,n
iii) Φ(x)zai 每個小區間[xR,xR+1]是m次多項式,
R=0,1,…,n-1則稱Φ(x)為f(x)在[a,b]上的分段m次插值多項式
實用中,常用次數不超過5的底次分段插值多項式,本節只介紹分段線性插值和分段三次Hermite插值,其中分段三次Hermite插值還額外要求分段插值函數Φ(x)
在節點上與被插值函數f(x)有相同的導數值,即
★基本思想將被插值函數f〔x〕的插值節點 由小到大 排序,然後每對相鄰的兩個節點為端點的區間上用m 次多項式去近似f〔x〕.
例題
例1 已知f(x)=ln(x)的函數表為:
試用線性插值和拋物線插值分別計算f(3.27)的近似值並估計相應的誤差。
解:線性插值需要兩個節點,內插比外插好因為3.27 (3.2,3.3),故選x0=3.2,x1=3.3,由n=1的lagrange插值公式,有
所以有,為保證內插對拋物線插值,選取三個節點為x0=3.2,x1=3.3,x2=3.4,由n=2的lagrange插值公式有
故有
所以線性插值計算ln3.27的誤差估計為
故拋物線插值計算ln3.27的誤差估計為:
顯然拋物線插值比線性插值精確;
5、樣條插值:
樣條插值是一種改進的分段插值。
定義 若函數在區間〖a,b〗上給定節點a=x0<x1<;…<xn=b及其函數值yj,若函數S(x)滿足
⒈ S(xj)=yj,j=0,1,2,…,n;
插值法主要用於道路橋梁,機械設計,電子信息工程等 很多工科領域的優化方法。
⑷ 圖像雙三次插值演算法原理及python實現
一. 圖像雙三次插值演算法原理:
假設源圖像 A 大小為 m*n ,縮放後的目標圖像 B 的大小為 M*N 。那麼根據比例我們可以得到 B(X,Y) 在 A 上的對應坐標為 A(x,y) = A( X*(m/M), Y*(n/N) ) 。在雙線性插值法中,我們選取 A(x,y) 的最近四個點。而在雙立方插值法中,我們選取的是最近的16個像素點作為計算目標圖像 B(X,Y) 處像素值的參數。如圖所示:
如圖所示 P 點就是目標圖像 B 在 (X,Y) 處對應於源圖像中的位置,P 的坐標位置會出現小數部分,所以我們假設 P 的坐標為 P(x+u,y+v),其中 x,y 分別表示整數部分,u,v 分別表示小數部分。那麼我們就可以得到如圖所示的最近 16 個像素的位置,在這里用 a(i,j)(i,j=0,1,2,3) 來表示。
雙立方插值的目的就是通過找到一種關系,或者說系數,可以把這 16 個像素對於 P 處像素值的影響因子找出來,從而根據這個影響因子來獲得目標圖像對應點的像素值,達到圖像縮放的目的。
BiCubic基函數形式如下:
二. python實現雙三次插值演算法
from PIL import Image
import numpy as np
import math
# 產生16個像素點不同的權重
def BiBubic(x):
x=abs(x)
if x<=1:
return 1-2*(x**2)+(x**3)
elif x<2:
return 4-8*x+5*(x**2)-(x**3)
else:
return 0
# 雙三次插值演算法
# dstH為目標圖像的高,dstW為目標圖像的寬
def BiCubic_interpolation(img,dstH,dstW):
scrH,scrW,_=img.shape
#img=np.pad(img,((1,3),(1,3),(0,0)),'constant')
retimg=np.zeros((dstH,dstW,3),dtype=np.uint8)
for i in range(dstH):
for j in range(dstW):
scrx=i*(scrH/dstH)
scry=j*(scrW/dstW)
x=math.floor(scrx)
y=math.floor(scry)
u=scrx-x
v=scry-y
tmp=0
for ii in range(-1,2):
for jj in range(-1,2):
if x+ii<0 or y+jj<0 or x+ii>=scrH or y+jj>=scrW:
continue
tmp+=img[x+ii,y+jj]*BiBubic(ii-u)*BiBubic(jj-v)
retimg[i,j]=np.clip(tmp,0,255)
return retimg
im_path='../paojie.jpg'
image=np.array(Image.open(im_path))
image2=BiCubic_interpolation(image,image.shape[0]*2,image.shape[1]*2)
image2=Image.fromarray(image2.astype('uint8')).convert('RGB')
image2.save('BiCubic_interpolation.jpg')
三. 實驗結果:
四. 參考內容:
https://www.cnblogs.com/wojianxin/p/12516762.html
https://blog.csdn.net/Ibelievesunshine/article/details/104942406