新聞中心
Unity3D中的線性插值Lerp()函數(shù)解析
插值,從字面意思上看,就是在其間插入一個(gè)數(shù)值,這種理解是否正確呢?我們先從最簡(jiǎn)單的浮點(diǎn)數(shù)插值函數(shù)來(lái)分析:
創(chuàng)新互聯(lián)成立于2013年,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項(xiàng)目成都網(wǎng)站建設(shè)、網(wǎng)站制作網(wǎng)站策劃,項(xiàng)目實(shí)施與項(xiàng)目整合能力。我們以讓每一個(gè)夢(mèng)想脫穎而出為使命,1280元鶴崗做網(wǎng)站,已為上家服務(wù),為鶴崗各地企業(yè)和個(gè)人服務(wù),聯(lián)系電話:028-86922220
Mathf .Lerp 插值
static functionLerp (from : float, to : float, t : float) : float
基于浮點(diǎn)數(shù)t返回a到b之間的插值,t限制在0~1之間。當(dāng)t = 0返回from,當(dāng)t = 1 返回to。當(dāng)t = 0.5 返回from和to的平均值。
有時(shí),我們?cè)谧鲇螒驎r(shí)會(huì)發(fā)現(xiàn)有些跟隨動(dòng)作不夠圓滑或者需要一個(gè)緩沖的效果,這時(shí),一般會(huì)考慮到插值。所以對(duì)插值的理解是必需的。(比如攝像機(jī)跟隨主角)
插值是數(shù)學(xué)上的一個(gè)概念,在這里用公式表示就是:from + (to - from) * t;這也就是Lerp的返回值(用這個(gè)公式分別算出x,y,z)。
static function Lerp (from : Vector3 , to : Vector3 , t : float) : Vector3
from 是起始的位置,to是目標(biāo)位置,按照數(shù)字t在from到to之間插值。
參考
雙線性插值法原理 python實(shí)現(xiàn)
碼字不易,如果此文對(duì)你有所幫助,請(qǐng)幫忙點(diǎn)贊,感謝!
一. 雙線性插值法原理:
? ? ① 何為線性插值?
? ? 插值就是在兩個(gè)數(shù)之間插入一個(gè)數(shù),線性插值原理圖如下:
? ? ② 各種插值法:
? ? 插值法的第一步都是相同的,計(jì)算目標(biāo)圖(dstImage)的坐標(biāo)點(diǎn)對(duì)應(yīng)原圖(srcImage)中哪個(gè)坐標(biāo)點(diǎn)來(lái)填充,計(jì)算公式為:
? ? srcX = dstX * (srcWidth/dstWidth)
? ? srcY = dstY * (srcHeight/dstHeight)
? ? (dstX,dstY)表示目標(biāo)圖像的某個(gè)坐標(biāo)點(diǎn),(srcX,srcY)表示與之對(duì)應(yīng)的原圖像的坐標(biāo)點(diǎn)。srcWidth/dstWidth 和 srcHeight/dstHeight 分別表示寬和高的放縮比。
? ? 那么問(wèn)題來(lái)了,通過(guò)這個(gè)公式算出來(lái)的 srcX, scrY 有可能是小數(shù),但是原圖像坐標(biāo)點(diǎn)是不存在小數(shù)的,都是整數(shù),得想辦法把它轉(zhuǎn)換成整數(shù)才行。
不同插值法的區(qū)別就體現(xiàn)在 srcX, scrY 是小數(shù)時(shí),怎么將其變成整數(shù)去取原圖像中的像素值。
最近鄰插值(Nearest-neighborInterpolation):看名字就很直白,四舍五入選取最接近的整數(shù)。這樣的做法會(huì)導(dǎo)致像素變化不連續(xù),在目標(biāo)圖像中產(chǎn)生鋸齒邊緣。
雙線性插值(Bilinear Interpolation):雙線性就是利用與坐標(biāo)軸平行的兩條直線去把小數(shù)坐標(biāo)分解到相鄰的四個(gè)整數(shù)坐標(biāo)點(diǎn)。權(quán)重與距離成反比。
? ??雙三次插值(Bicubic Interpolation):與雙線性插值類似,只不過(guò)用了相鄰的16個(gè)點(diǎn)。但是需要注意的是,前面兩種方法能保證兩個(gè)方向的坐標(biāo)權(quán)重和為1,但是雙三次插值不能保證這點(diǎn),所以可能出現(xiàn)像素值越界的情況,需要截?cái)唷?/p>
? ? ③ 雙線性插值算法原理
假如我們想得到未知函數(shù) f 在點(diǎn) P = (x, y) 的值,假設(shè)我們已知函數(shù) f 在 Q11 = (x1, y1)、Q12 = (x1, y2), Q21 = (x2, y1) 以及 Q22 = (x2, y2) 四個(gè)點(diǎn)的值。最常見的情況,f就是一個(gè)像素點(diǎn)的像素值。首先在 x 方向進(jìn)行線性插值,然后再在 y 方向上進(jìn)行線性插值,最終得到雙線性插值的結(jié)果。
④ 舉例說(shuō)明
二. python實(shí)現(xiàn)灰度圖像雙線性插值算法:
灰度圖像雙線性插值放大縮小
import numpy as np
import math
import cv2
def double_linear(input_signal, zoom_multiples):
'''
雙線性插值
:param input_signal: 輸入圖像
:param zoom_multiples: 放大倍數(shù)
:return: 雙線性插值后的圖像
'''
input_signal_cp = np.copy(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):
? ? ? ? # 輸出圖片中坐標(biāo) (i,j)對(duì)應(yīng)至輸入圖片中的最近的四個(gè)點(diǎn)點(diǎn)(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()
三. 灰度圖像雙線性插值實(shí)驗(yàn)結(jié)果:
四. 彩色圖像雙線性插值python實(shí)現(xiàn)
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')
五. 彩色圖像雙線性插值實(shí)驗(yàn)結(jié)果:
六. 最近鄰插值算法和雙三次插值算法可參考:
① 最近鄰插值算法:
???
? ? ② 雙三次插值算法:
七. 參考內(nèi)容:
? ??
???
插值的編程使用
matlab中使用插值函數(shù)
插值函數(shù)(the function of interpolation )
interp1
調(diào)用函數(shù)的格式(Syntax)
yi = interp1(x,Y,xi)
yi = interp1(Y,xi)
yi = interp1(x,Y,xi,method)
yi = interp1(x,Y,xi,method,'extrap')
yi = interp1(x,Y,xi,method,extrapval)
pp = interp1(x,Y,method,'pp')
調(diào)用格式說(shuō)明(Description)
yi = interp1(x,Y,xi) 返回矢量X和Y決定的根據(jù)輸入的節(jié)點(diǎn)xi時(shí)對(duì)應(yīng)的y的值.矢量Y是矢量X的一個(gè)函數(shù)映射.
如果Y是一個(gè)矩陣,那么插值結(jié)果是一個(gè)對(duì)應(yīng)的矩陣.
[===================================================
yi = interp1(x,Y,xi) returns vector yi containing elements corresponding to the elements of xi and determined by interpolation within vectors x and Y. The vector x specifies the points at which the data Y is given. If Y is a matrix, then the interpolation is performed for each column of Y and yi is length(xi)-by-size(Y,2).
===================================================]
yi = interp1(x,Y,xi,method)插值中可以使用的方法: 插值方法 說(shuō)明 nearest 臨近的兩點(diǎn)插值 linear 線性插值(默認(rèn)) spline 三次樣條插值 pchip 分段三次Hermite插值多項(xiàng)式插值 cubic (作用于pchip相同) v5cubic 用matlab5版本中斷三次樣條插值 [====================================================
yi = interp1(x,Y,xi,method) interpolates using alternative methods:
methodDescription
nearestNearest neighbor interpolation
linearLinear interpolation (default)
splinesplineCubic spline interpolation
pchipPiecewise cubic Hermite interpolation
cubic(Same as 'pchip')
v5cubicCubic interpolation used in MATLAB 5
======================================================]
簡(jiǎn)單程序示例
x=[0.0 0.1 0.195 0.3 0.401 0.5];
y=[0.39849 0.39695 0.39142 0.38138 0.36812 0.35206];
plot(x,y);
T=interp1(x,y,.25,'linear') %線性插值
(返回結(jié)果T=0.3862)
T=interp1(x,y,.25,'nearest') % 兩點(diǎn)插值
(返回結(jié)果T=0.3814)
T=interp1(x,y,.25,'spline') % 三次樣條插值
(返回結(jié)果T =0.3867)
T=interp1(x,y,.25,'cubic') %三次插值
(返回結(jié)果T =0.3867)
線性插值法的公式是什么?
公式就是:Y=Y1+(Y2-Y1)×(X-X1)/(X2-X1)。
通俗地講,線性內(nèi)插法就是利用相似三角形的原理,來(lái)計(jì)算內(nèi)插點(diǎn)的數(shù)據(jù)。
內(nèi)插法又稱插值法。根據(jù)未知函數(shù)f(x)在某區(qū)間內(nèi)若干點(diǎn)的函數(shù)值,作出在該若干點(diǎn)的函數(shù)值與f(x)值相等的特定函數(shù)來(lái)近似原函數(shù)f(x),進(jìn)而可用此特定函數(shù)算出該區(qū)間內(nèi)其他各點(diǎn)的原函數(shù)f(x)的近似值,這種方法,稱為內(nèi)插法。
按特定函數(shù)的性質(zhì)分,有線性內(nèi)插、非線性內(nèi)插等;按引數(shù)(自變量)個(gè)數(shù)分,有單內(nèi)插、雙內(nèi)插和三內(nèi)插等。
介紹:
線性插值是指插值函數(shù)為一次多項(xiàng)式的插值方式,其在插值節(jié)點(diǎn)上的插值誤差為零。線性插值相比其他插值方式,如拋物線插值,具有簡(jiǎn)單、方便的特點(diǎn)。
線性插值的幾何意義即為概述圖中利用過(guò)A點(diǎn)和B點(diǎn)的直線來(lái)近似表示原函數(shù)。線性插值可以用來(lái)近似代替原函數(shù),也可以用來(lái)計(jì)算得到查表過(guò)程中表中沒有的數(shù)值。
VB中如何修改jpg圖片的dpi
你可以使用二次線形插值的方法:
Public Sub ZoomImage(ByVal OutPutWidth As Long, ByVal OutputHeight As Long)
Dim I As Long
Dim L As Long
Dim X As Long
Dim Y As Long
Dim Xb As Long
Dim Yb As Long
Dim Xe As Long
Dim Ye As Long
Dim M As Integer
Dim N As Integer
Dim CurR As Long
Dim CurG As Long
Dim CurB As Long
Dim NxtR As Integer
Dim NxtG As Integer
Dim NxtB As Integer
Dim DR As Single
Dim DG As Single
Dim DB As Single
Dim DRt As Single
Dim DGt As Single
Dim DBt As Single
Dim Xratio As Single
Dim Yratio As Single
Dim CurStep As Single
Dim NxtStep As Single
Dim NegN As Single
On Error GoTo ErrLine
If Not CanZoom Then Exit Sub
Done = False
OutPutWid = OutPutWidth - 1
OutPutHei = OutputHeight - 1
I = (Bits \ 8) - 1
ReDim ColTmp(I, InPutWid, OutPutHei) '先從Y方向進(jìn)行縮放處理,結(jié)果保存在此中間數(shù)組內(nèi)
ReDim ColOut(I, OutPutWid, OutPutHei)
Xratio = OutPutWid / InPutWid
Yratio = OutPutHei / InPutHei
TimeZoom = timeGetTime
NegN = 1 / Int(Yratio + 1)
For X = 0 To InPutWid
CurR = ColVal(0, X, 0)
CurG = ColVal(1, X, 0)
CurB = ColVal(2, X, 0)
CurStep = 0
NxtStep = 0
For Y = 0 To InPutHei - 1
NxtStep = CurStep + Yratio
Yb = CurStep
Ye = NxtStep
N = Ye - Yb
ColTmp(0, X, Yb) = CurR
ColTmp(1, X, Yb) = CurG
ColTmp(2, X, Yb) = CurB
M = Y + 1
NxtR = ColVal(0, X, M)
NxtG = ColVal(1, X, M)
NxtB = ColVal(2, X, M)
If N 1 Then
DRt = (NxtR - CurR) * NegN
DGt = (NxtG - CurG) * NegN
DBt = (NxtB - CurB) * NegN
DR = 0
DG = 0
DB = 0
For L = Yb + 1 To Ye - 1
DR = DR + DRt
DG = DG + DGt
DB = DB + DBt
ColTmp(0, X, L) = CurR + DR
ColTmp(1, X, L) = CurG + DG
ColTmp(2, X, L) = CurB + DB
Next
End If
CurStep = NxtStep
CurR = NxtR
CurG = NxtG
CurB = NxtB
Next
ColTmp(0, X, OutPutHei) = NxtR
ColTmp(1, X, OutPutHei) = NxtG
ColTmp(2, X, OutPutHei) = NxtB
Next
NegN = 1 / Int(Xratio + 1)
For Y = 0 To OutPutHei
CurR = ColTmp(0, 0, Y)
CurG = ColTmp(1, 0, Y)
CurB = ColTmp(2, 0, Y)
CurStep = 0
NxtStep = 0
For X = 0 To InPutWid - 1
NxtStep = CurStep + Xratio
Xb = CurStep
Xe = NxtStep
N = Xe - Xb
ColOut(0, Xb, Y) = CurR
ColOut(1, Xb, Y) = CurG
ColOut(2, Xb, Y) = CurB
M = X + 1
NxtR = ColTmp(0, M, Y)
NxtG = ColTmp(1, M, Y)
NxtB = ColTmp(2, M, Y)
If N 1 Then
DRt = (NxtR - CurR) * NegN
DGt = (NxtG - CurG) * NegN
DBt = (NxtB - CurB) * NegN
DR = 0
DG = 0
DB = 0
For L = Xb + 1 To Xe - 1
DR = DR + DRt
DG = DG + DGt
DB = DB + DBt
ColOut(0, L, Y) = CurR + DR
ColOut(1, L, Y) = CurG + DG
ColOut(2, L, Y) = CurB + DB
Next
End If
CurStep = NxtStep
CurR = NxtR
CurG = NxtG
CurB = NxtB
Next
ColOut(0, OutPutWid, Y) = NxtR
ColOut(1, OutPutWid, Y) = NxtG
ColOut(2, OutPutWid, Y) = NxtB
Next
Done = True
TimeZoom = timeGetTime - TimeZoom
CanPut = True
Exit Sub
ErrLine:
MsgBox Err.Description
End Sub
全局變量定義:
Dim ColTmp() As Byte '用于保存插值中間變量
Dim OutPutHei As Long '要插值的目標(biāo)高度
Dim OutPutWid As Long '要插值的目標(biāo)寬度
Public TimeZoom As Long '插值運(yùn)算使用的時(shí)間
簡(jiǎn)單解釋一下關(guān)于二次線性插值算法。
(為了說(shuō)明算法本身,我們只計(jì)算這個(gè)圖片的紅色分量,因?yàn)榧t綠藍(lán)三種顏色的計(jì)算方法完全相同)
假設(shè)我們有一個(gè)很簡(jiǎn)單的圖片,圖片只有4個(gè)像素(2*2)
A B
C D
現(xiàn)在我們要把這個(gè)圖片插值到9個(gè)像素:3*3
A ab B
ac abcd bd
C cd D
其中大寫的字母代表原來(lái)的像素,小寫字母代表插值得到的新像素。
想必看到這個(gè)圖,大家心里已經(jīng)有了這個(gè)算法了。
ab=(A+B) / 2
cd=(C+D) / 2
ac=(A+C) / 2
bd=(B+D) / 2
abcd=(ab+cd) / 2=(A+B+C+D) / 4
推導(dǎo):
ab= A + (B-A) / 2
cd=C +(D-C) / 2
...
很簡(jiǎn)單,對(duì)吧,先從一個(gè)方向把只涉及兩個(gè)原始像素的新像素算出來(lái)。我們這里假定先計(jì)算水平方向。而在算垂直方向的插值的時(shí)候,因?yàn)閍b和cd已經(jīng)在前面算好了,所以abcd的計(jì)算也和計(jì)算ac和bd沒有任何區(qū)別了。
有可能為有朋友已經(jīng)想到把原來(lái)的圖像插值到4*4或5*5的方法了。
A ab1 ab2 B
ac1 ab1cd11 ab2cd21 bd1
ac2 ab1cd12 ab2cd22 bd2
C cd1 cd2 D
推導(dǎo):
ab1 = A + (B-A) * 1 / 3
ab2 = A + (B-A) * 2 / 3 =ab1+(B-A) / 3
cd1 = C + (D-C) * 1 / 3
cd1 = C + (D-C) * 2 / 3 =cd1+(D-C) / 3
...
以A和B為例,先求出原始像素的差(A-B)再算出每一步的遞增量(A-B) / 3;然后每一個(gè)新的點(diǎn)就是在前面那個(gè)點(diǎn)的值加上這個(gè)遞增量就是了。
這里我們假設(shè)A=100, B=255 放大倍率為3,水平方向插值;先計(jì)算出原始像素的差:(B-A) = 255-100 =155
再計(jì)算出水平方向每一步的遞增量:(A-B) / 3=155 / 3 = 51.7
這里我們用一個(gè)變量DRt來(lái)記錄這個(gè)遞增量(這里只用紅色來(lái)做例子)
ab1 = A + DRt = 100+51.7 =151
ab2 = ab1 + DRt = 151+51.7 = 202
好了,其實(shí)二次線性算法就是這么一個(gè)東西,并不復(fù)雜?;蛟S有寫朋友會(huì)對(duì)于我給出的代碼產(chǎn)生疑問(wèn)。很簡(jiǎn)單的一個(gè)算法為什么要寫這么多代碼。
其實(shí)答案很簡(jiǎn)單:為了提高速度。
在VB中“+”和“-”永遠(yuǎn)是最快的,“*”要比“/”和“\”快。不論是什么類型的變量都是這樣的。
下面再來(lái)分析一下我的程序。
在我的程序中把兩個(gè)方向的插值分解成了兩個(gè)單獨(dú)的部分。
先把
A B
C D
變成:
A ab1...abN B
C cd1...cdN D
再變成:
A ab1...abN B
ac1 ............. db1
... ............ ...
acN .............. bdN
C cd1...cdN D
這兩個(gè)方向的插值算法完全相同
而Xratio 和Yratio 這兩個(gè)變量則用來(lái)記錄水平方向和垂直方向的放大倍率。所以這個(gè)過(guò)程也能夠讓圖像縮放不按照原始的縱橫比進(jìn)行。
好了,將這個(gè)模塊和全局變量添加到上次建立的工程模塊中。
把按鈕中的代碼改成:
sub command1_click()
With picture1
.ScaleMode=3
.BorderStyle=0
DibGet .hdc ,0 , 0 , .scalewidth , .scaleheight
ZoomImage , .scalewidth * 2 , .scaleheight * 2
End With
picture2.AutoRedraw=True
DibPut picture2.hdc
picture2.refresh
end sub
分享文章:線性插值vbnet 線性插值是什么意思
分享地址:http://fisionsoft.com.cn/article/hpeesd.html