雙線性演算法
① 雙線性插值法原理 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
② 什麼是雙線性插值法 雙線性插值法是什麼
1、雙線彎好性插值,又稱為雙線性內插。在數學上,雙線性插值是有兩個變數的插值函數的線性插值擴展,其核心思想是在兩個方向分別進行一次線性插段鬧斗值。
2、雙線性插值作為數值分析中的一種插值演算法,廣泛應用在信號處握磨理,數字圖像和視頻處理等方面。
③ 如何用MATLAB編寫一個雙線性插值的演算法,用來放大縮小圖象
%% 4.圖像的縮放
% 思路:雙線性插值
kV = 0.5; % 垂直縮放系數
kH = 0.5; % 水平縮放系數
% 讀入圖像
I = imread('D:\lena.bmp'); % 注意修改文件路徑
II = double(I);
[m, n, r]=size(II);
OI=zeros(m*kV,n*kH, r);
rot=[kV 0 0;0 kH 0;0 0 1]; % 變換矩陣
for k=1:r
for i=1:m*kV
for j=1:n*kH
pix=[i j 1]/rot;
Y =pix(1)-floor(pix(1));
X =pix(2)-floor(pix(2));
% 邊界處理
if pix(1) < 1
pix(1) = 1;
end
if pix(1) > m
pix(1) = m;
end
if pix(2) < 1
pix(2) = 1;
end
if pix(2) > n
pix(2) =n;
end
% 四個鄰點
pix1 = [floor(pix(1))floor(pix(2))];
pix2 = [floor(pix(1))ceil(pix(2))];
pix3 = [ceil(pix(1))floor(pix(2))];
pix4 = [ceil(pix(1))ceil(pix(2))];
% 計算臨近四個點的權重
w1 = (1-X)*(1-Y);
w2 = X*(1-Y);
w3 = (1-X)*Y;
w4 = X*Y;
% 按權重進行雙線性插值
OI(i,j,k)=...
w1*II(pix1(1),pix1(2),k)+ ...
w2*II(pix2(1),pix2(2),k)+ ...
w3*II(pix3(1),pix3(2),k)+ ...
w4*II(pix4(1),pix4(2),k);
end
end
end
figure, imshow(uint8(II)), title('原圖')
figure, imshow(uint8(OI)), title('縮放後')
④ 雙線性插值原理的原理
雙線性插值原理,是一種數學原理。
原理
簡單來說
原來的數值序列:0,10,20,30,40
線性插值一次為:0,5,10,15,20,25,30,35,40
即認為其變化(增減)是線形的,可以在坐標圖上畫出一條直線
在數碼相機技術中,這些數值可以代表組成一張照片的不同像素點的色彩、色度等指標。
為了方便理解,先考慮一維情況下的線性插值
對於一個數列c,我們假設c[a]到c[a+1]之間是線性變化的
那麼對於浮點數x(a<=x<a+1),c(x)=c[a+1]*(x-a)+c[a]*(1+a-x);
雙線性插值
雙線性插值作為數值分析中的一種插值演算法,廣泛應用在信號處理,數字圖像和視頻處理等方面。
把這種插值方式擴展到二維情況。
對於一個二維數組c,我們假設對於任意一個浮點數i,c(a,i)到c(a+1,i)之間是線性變化的,c(i,b)到c(i,b+1)之間也是線性變化的(a,b都是整數)
那麼對於浮點數的坐標(x,y)滿足(a<=x<a+1,b<=y<b+1),我們可以先分別求出c(x,b)和c(x,b+1):
c(x,b) = c[a+1][b]*(x-a)+c[a][b]*(1+a-x);
c(x,b+1) = c[a+1][b+1]*(x-a)+c[a][b+1]*(1+a-x);
好,現在已經知道c(x,b)和c(x,b+1)了,而根據假設c(x,b)到c(x,b+1)也是線性變化的,所以:
c(x,y) = c(x,b+1)*(y-b)+c(x,b)*(1+b-y)
這就是雙線性插值。
⑤ 對圖像進行雙線性插值演算法後,圖像出現塊效應怎麼解決
interpolation 插值方法,類似於 CV_INTER_NN 方法。當圖像放大時,dst 輸出圖像,該方法可以避免波紋出現。當圖像縮小時候;
src 輸入圖像,
CV_INTER_LINEAR - 雙線性插值 (預設使用)
CV_INTER_AREA - 使用象素關系重采樣.
該方法就是用於將圖像改變為dst定義的大小..
CV_INTER_CUBIC - 立方插值, CvArr* dstvoid cvResize( const CvArr* src,然後根據你選擇的插值方法進行插值, int interpolation=CV_INTER_LINEAR ):
CV_INTER_NN - 最近鄰插值.
⑥ 圖像處理中的雙線性插值演算法的原理
何東健的《數字圖像處理》光碟第六章有前兩種的程序
完整程序已發你郵箱
核心代碼如下:
for(y = 0; y < nNewHeight; y++)
{
//指向新圖像第y行
//注意此處寬度和高度是新圖像的寬度和高度
pNewTemp = pNewBits;
pNewTemp += (nNewHeight - 1 - y) * nNewWidthBytes;
//針對圖像每列進行操作
for(x = 0; x < nNewWidth; x++)
{
//計算該像素在源圖像中的坐標
int y0 = (long) (y / fYZoomRatio + 0.5);
int x0 = (long) (x / fXZoomRatio + 0.5);
//判斷是否在源圖范圍內
if( (x0 >= 0) && (x0 < nOldWidth) &&
(y0 >= 0) && (y0 < nOldHeight))
{
//用雙線性插值
if(bBilinear)
{
unsigned char *pTemp = Interpolation (nOldWidth, nOldHeight,
(float)x0, (float)y0,
nOldWidthBytes, nMovedBits, pOldBits);
//復制像素
memcpy(pNewTemp, pTemp, nMovedBits);
delete [] pTemp ;
}
else
//最近鄰插值
{
//指向源圖像第y0行,第x0個像素
//注意此處寬度和高度應該互換
pOldTemp = pOldBits;
pOldTemp += (nOldHeight - 1 - y0) * nOldWidthBytes;
pOldTemp += x0 * nMovedBits;
//復制像素
memcpy(pNewTemp, pOldTemp, nMovedBits);
}
}
pNewTemp += nMovedBits;
}
}
⑦ 如何使用Matlab實現雙線性插值演算法
提問前建議先自行網路 關鍵詞 「matlab」+ 「雙線性插值」
首先需要了解什麼是雙線性插值:
如果選擇一個坐標系統使得 的四個已知點坐標分別為 (0, 0)、(0, 1)、(1, 0) 和 (1, 1),那麼插值公式就可以化簡為 f(x,y)=f(0,0)(1-x)(1-y)+f(0,1)(1-x)y+f(1,1)xy+f(1,0)x(1-y)
相應進行matlab程序編寫即可